diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000000000000000000000000000000000000..24a8e87939aa53cdd833f6be7610cb4972e063ad
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1 @@
+*.png filter=lfs diff=lfs merge=lfs -text
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000000000000000000000000000000000000..6a3879812420e3b323d56af034bb1d1fd54e530a
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,22 @@
+*__pycache__*
+*.ipynb
+*.pyc
+*.pyo
+*.pyd
+*.pkl
+*.pkl.gz
+*.h5
+*.hdf5
+*.csv
+*.log
+experiments/
+wandb/
+ckpt/
+.ipynb_checkpoints/
+lightning_logs/*
+lightning_logs/
+datasets
+Notebooks/
+embeddings/
+figures/
+ft_results/
\ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..37cecf2c5550dfbcab6811edf3d68d5dd39b86ce
--- /dev/null
+++ b/README.md
@@ -0,0 +1,69 @@
+# SleepMaMi
+This is the code respository for **SleepMaMi: A Universal Sleep Foundation Model for Integrating Macro- and Micro-structures**
+
+## Abstract
+>While the shift toward unified foundation models has revolutionized many deep learning domains, sleep medicine remains largely restricted to task-specific models that focus on localized micro-structure features. These approaches often neglect the rich, multi-modal context of Polysomnography (PSG) and fail to capture the global macro-structure of a full night's sleep. To address this, we introduce SleepMaMi, a Sleep Foundation Model engineered to master both hour-long sleep architectures and fine-grained signal morphologies. Our framework utilizes a hierarchical dual-encoder design: a Macro-Encoder to model full-night temporal dependencies and a Micro-Encoder to capture short-term characteristics from biosignals. Macro-Encoder is trained via Demographic-Guided Contrastive Learning, which aligns overnight sleep patterns with objective subject metadata, such as age and sex, to refine global representations. Micro-Encoder is optimized via a hybrid Masked Autoencoder (MAE) and multi-modal contrastive objective. Pre-trained on a massive corpus of >20,000 PSG recordings (15.8K hours), SleepMaMi outperforms existing foundation models across a diverse suite of downstream tasks, demonstrating superior generalizability and label-efficient adaptation for clinical sleep analysis.
+
+
+## Prerequisites
+```
+conda create -n sleepmami python==3.9
+conda activate sleepmami
+pip install -r requirements.txt
+
+# conda install -c "nvidia/label/cuda-12.1.1" cuda-nvcc cuda-cudart-dev libcublas-dev libcurand-dev # if necessary
+pip install flash-attn==2.7.4.post1 --no-build-isolation --cache-dir /tmp/pip_cache
+apt update
+apt install libgl1-mesa-glx
+pip install mamba-ssm==2.2.3.post2 --no-build-isolation
+```
+
+
+## Data preprocessing
+Please prepare pretraining and finetuning data, following [README](data/README.md) in `data` directory.
+
+## Pretraining
+### Micro-Encoder pretraining
+After pretraining dataset is prepared, prepare a config file(`*.yaml`) in `configs` directory.
+
+Example config files are provided in `configs` directory.
+
+Use the following command to start pretraining:
+```
+python pretrain.py --config PT_6mod_9ds_CL
+```
+
+
+### Macro-Encoder pretraining
+Similar to Micro-Encoder pretraining, prepare a config file in `configs` directory.
+
+Then use the following command to start Macro-Encoder pretraining
+```
+python pretrain_seq.py --config PTseq_6mod_9ds_CL_full_night
+```
+
+
+### Downstream tasks
+After pretraining is completed, finetuning on downstream tasks can be done with the following command:
+```
+python finetune.py --config FT_6mod_CL
+```
+The config file should be located in `configs` directory. `ft_task` variable should be set to specify the finetuning task (e.g. sleep_staging, apnea_seg, diag, etc.)
+
+
+### Pretrained checkpoints and Inference
+To be completed.
+
+
+## BibTeX
+Please use the below bibtex when you reference our work!
+```
+@inproceedings{
+park2026sleepmami,
+title={SleepMaMi: A Universal Sleep Foundation Model for Integrating Macro- and Micro-structures},
+author={Park, Keondo and Na, Younghoon and Choi, You Rim and Ryu, Hyunwoo and Shin, Hyun-Woo and Kim, Hyung-Sin},
+booktitle={Forty-third International Conference on Machine Learning},
+year={2026},
+url={https://openreview.net/forum?id=e9hvlHlUas}
+}
+```
\ No newline at end of file
diff --git a/configs/Eval_6mod_CL_full_night.yaml b/configs/Eval_6mod_CL_full_night.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..62d7bd55c04cd4a85ebb807284f72ff74bf927dd
--- /dev/null
+++ b/configs/Eval_6mod_CL_full_night.yaml
@@ -0,0 +1,34 @@
+project_name: ConvMAE1d_FT
+experiment_name: Eval_PTseq_p50_6mod_9ds_kissFix_diag_micro
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: diagnosis
+patch_size: 50
+num_classes: 6
+num_workers: 6
+loss: coxph
+batch_size_v: 32
+proportion_v: 1.0
+gpus: [0]
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_kissFix_diag_micro-final.ckpt # PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP","EMG","SaO2"
+]
+sig_len_target: 30
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_lstm: False
+use_micro: True
+save_results: True
+save_emb: False
\ No newline at end of file
diff --git a/configs/Eval_6mod_CL_full_night_measure.yaml b/configs/Eval_6mod_CL_full_night_measure.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ec43a8025349329556c70a95a3750b9b62d2a855
--- /dev/null
+++ b/configs/Eval_6mod_CL_full_night_measure.yaml
@@ -0,0 +1,34 @@
+project_name: ConvMAE1d_FT
+experiment_name: Eval_PTseq_p50_6mod_9ds_kissFix
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+loss: wce
+batch_size_v: 8
+proportion_v: 1.0
+gpus: [0]
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_kissFix-final.ckpt # PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP","EMG","SaO2"
+]
+sig_len_target: 30
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_lstm: False
+use_micro: False
+save_results: False
+save_emb: False
\ No newline at end of file
diff --git a/configs/FT_6mod.yaml b/configs/FT_6mod.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c2b0eb93def7d4474b9bb5f1f363f4300cc16f54
--- /dev/null
+++ b/configs/FT_6mod.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_p100_10_6mod_cat
+data_root: datasets
+dataset: ['phy']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi
+ft_task: sleep_staging
+patch_sizes: [10,100]
+num_classes: 5
+num_workers: 6
+lr: 0.002
+layer_decay: 1.0
+weight_decay: 0.05
+num_epochs: 3
+loss: wce
+batch_size_t: 512
+batch_size_v: 512
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p100_10_6mod-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","EMG","ECG","AIRFLOW","ABD"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
diff --git a/configs/FT_6mod_CL.yaml b/configs/FT_6mod_CL.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..3c5f267bfde81e2072a8b120dda5b41ee92f7ec8
--- /dev/null
+++ b/configs/FT_6mod_CL.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_p50_6mod_CL_shhs_CLonly_cat
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.004
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 512
+batch_size_v: 512
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_CL_shhs_CLonly_cat-final.ckpt #p50_6mod_6ds_CL5-final.ckpt #p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix5-final.ckpt # p25_6mod_hier_2_2_4_lgonly_5ds_CL_nonmix6-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
diff --git a/configs/FT_6mod_CL_abl1.yaml b/configs/FT_6mod_CL_abl1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..356c915ee32ef0e184f01f1c9172800d1c57c462
--- /dev/null
+++ b/configs/FT_6mod_CL_abl1.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_p50_6mod_noshared_shhs
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.004
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 512
+batch_size_v: 512
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_noshared_shhs-final.ckpt #p50_6mod_6ds_CL5-final.ckpt #p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix5-final.ckpt # p25_6mod_hier_2_2_4_lgonly_5ds_CL_nonmix6-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
diff --git a/configs/FT_6mod_CL_abl2.yaml b/configs/FT_6mod_CL_abl2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..aa42d19181da5673ae4819e52331512ab0cbb508
--- /dev/null
+++ b/configs/FT_6mod_CL_abl2.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_p50_6mod_MAEonly_shhs
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.004
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 512
+batch_size_v: 512
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_MAEonly_shhs-final.ckpt #p50_6mod_6ds_CL5-final.ckpt #p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix5-final.ckpt # p25_6mod_hier_2_2_4_lgonly_5ds_CL_nonmix6-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
diff --git a/configs/FT_6mod_CL_abl3.yaml b/configs/FT_6mod_CL_abl3.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..50c27667f053db08d999bde379d4e0b0049eca2e
--- /dev/null
+++ b/configs/FT_6mod_CL_abl3.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_p50_6mod_MAEonly_noMoE_shhs
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.004
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 512
+batch_size_v: 512
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_MAEonly_noMoE_shhs-final.ckpt #p50_6mod_6ds_CL5-final.ckpt #p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix5-final.ckpt # p25_6mod_hier_2_2_4_lgonly_5ds_CL_nonmix6-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
diff --git a/configs/FT_6mod_CL_abl4.yaml b/configs/FT_6mod_CL_abl4.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b2de4733c23d540aa13692681158daf31c6bd3f6
--- /dev/null
+++ b/configs/FT_6mod_CL_abl4.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_p50_6mod_CL_shhs
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.004
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 512
+batch_size_v: 512
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_CL_shhs-final.ckpt #p50_6mod_6ds_CL5-final.ckpt #p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix5-final.ckpt # p25_6mod_hier_2_2_4_lgonly_5ds_CL_nonmix6-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
diff --git a/configs/FT_6mod_CL_ah.yaml b/configs/FT_6mod_CL_ah.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..917005e1d0a80d6588fb2fef1158bd7d0571f18a
--- /dev/null
+++ b/configs/FT_6mod_CL_ah.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_p50_6mod_9ds_kissFix_ah_sof
+data_root: datasets
+datasets: ['sof']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi
+ft_task: apnea_seg
+patch_size: 50
+num_classes: 2
+num_workers: 6
+lr: 0.004
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 1024
+batch_size_v: 1024
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_9ds_kissFix-final.ckpt # p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix2-final.ckpt # p25_6mod_hier_2_2_4_lgonly_5ds_CL_nonmix6-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG", "SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
diff --git a/configs/FT_6mod_CL_fewshot_ah.yaml b/configs/FT_6mod_CL_fewshot_ah.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..b10a6ffe00c801d595312b375883630a6fa9d5f0
--- /dev/null
+++ b/configs/FT_6mod_CL_fewshot_ah.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_p50_6mod_9ds_kissFix_ah_cfs_1_e20
+data_root: datasets
+datasets: ['cfs_1'] #['isruc_sg1_1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi
+ft_task: apnea_seg
+patch_size: 50
+num_classes: 2
+num_workers: 6
+lr: 0.004
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 20
+loss: wce
+batch_size_t: 1024
+batch_size_v: 1024
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_9ds_kissFix-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
diff --git a/configs/FT_6mod_CL_full_night.yaml b/configs/FT_6mod_CL_full_night.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e35cf46cffe6a85515e191fec088f31f6a55e445
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_kissFix
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.01
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 4
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_kissFix-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_micro: False
+use_lstm: False
\ No newline at end of file
diff --git a/configs/FT_6mod_CL_full_night_abl1.yaml b/configs/FT_6mod_CL_full_night_abl1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..cd5f6342a2a48c2f2806367f9688816c05d83e2e
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_abl1.yaml
@@ -0,0 +1,39 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_CL_w_1_improve_shhs_bmi2
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.01
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 4
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_CL_w_1_improve_shhs_bmi2-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
diff --git a/configs/FT_6mod_CL_full_night_abl2.yaml b/configs/FT_6mod_CL_full_night_abl2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..521a53b52df4fe4755cceadbbfeb2a825902e1c6
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_abl2.yaml
@@ -0,0 +1,39 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_CL_w_1_improve_shhs_age2
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.01
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 4
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_CL_w_1_improve_shhs_age2-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
diff --git a/configs/FT_6mod_CL_full_night_abl3.yaml b/configs/FT_6mod_CL_full_night_abl3.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6ae70cd054eabdb108038e3f021a9b1910038320
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_abl3.yaml
@@ -0,0 +1,39 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_CL_w_1_shhs_sex
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.01
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 4
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_CL_w_1_shhs_sex-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
diff --git a/configs/FT_6mod_CL_full_night_abl4.yaml b/configs/FT_6mod_CL_full_night_abl4.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ed06efc91a4478f2988ad4fda197dccef6ec932b
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_abl4.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_kissFix_shhs_mamba_uni
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.01
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 32
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_kissFix_shhs_mamba_uni-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_transformer: False
+bidi: False
diff --git a/configs/FT_6mod_CL_full_night_age.yaml b/configs/FT_6mod_CL_full_night_age.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..8eb373649c9a7d7a481c0ed1f0a7fc8f9f5008ab
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_age.yaml
@@ -0,0 +1,40 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_CL_w_1_improve2_age
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: age
+patch_size: 50
+num_classes: 1
+num_workers: 6
+lr: 0.004
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: mae
+batch_size_t: 16
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_CL_w_1_improve2-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_micro: False
diff --git a/configs/FT_6mod_CL_full_night_ahi.yaml b/configs/FT_6mod_CL_full_night_ahi.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..720f58f055a350ab9152ccb367a08bfecd9cf83e
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_ahi.yaml
@@ -0,0 +1,40 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_CL_w_1_improve2_ahi_micro
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: ahi
+patch_size: 50
+num_classes: 1
+num_workers: 6
+lr: 0.004
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: mae
+batch_size_t: 16
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_CL_w_1_improve2-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_micro: False
diff --git a/configs/FT_6mod_CL_full_night_dino.yaml b/configs/FT_6mod_CL_full_night_dino.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..90b3cf4c3c393c544b093a7852ac2e7bca7646d3
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_dino.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_kissFix_dino
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.01
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 4
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_kissFix_dino-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_micro: False
+use_lstm: False
\ No newline at end of file
diff --git a/configs/FT_6mod_CL_full_night_fewshot.yaml b/configs/FT_6mod_CL_full_night_fewshot.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..6ccb18f2ab2a00a1b99cf5280cc9ca68f047f331
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_fewshot.yaml
@@ -0,0 +1,39 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_kissFix_cfs_100_e20
+data_root: datasets
+datasets: ['cfs_100'] #['isruc_sg1_1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.01
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 20
+loss: wce
+batch_size_t: 5
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_kissFix-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
diff --git a/configs/FT_6mod_CL_full_night_lstm.yaml b/configs/FT_6mod_CL_full_night_lstm.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..34f62a1819985e75d63eabefc08c46250ac9cebb
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_lstm.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_kissFix_cfs_lstm
+data_root: datasets
+datasets: ['cfs']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.001
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 20
+loss: wce
+batch_size_t: 4
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_kissFix-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_micro: False
+use_lstm: True
\ No newline at end of file
diff --git a/configs/FT_6mod_CL_full_night_sex.yaml b/configs/FT_6mod_CL_full_night_sex.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9c06ab4f49c9fb3e807266e6365ed65ea96f3860
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_sex.yaml
@@ -0,0 +1,40 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_CL_w_1_improve2_sex
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sex
+patch_size: 50
+num_classes: 2
+num_workers: 6
+lr: 0.004
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: ce
+batch_size_t: 8
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_CL_w_1_improve2-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_micro: False
diff --git a/configs/FT_6mod_CL_full_night_simclr.yaml b/configs/FT_6mod_CL_full_night_simclr.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..85eb555857e0223609d943d1ed516b22a18a23f2
--- /dev/null
+++ b/configs/FT_6mod_CL_full_night_simclr.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_FT
+experiment_name: FT_PTseq_p50_6mod_9ds_kissFix_simclr2
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: sleep_staging
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.01
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: wce
+batch_size_t: 4
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_kissFix_simclr2-final.ckpt # PTseq_p50_6mod_6ds_CL5_5ds-epoch=00-train_loss=10.93.ckpt ## PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_micro: False
+use_lstm: False
\ No newline at end of file
diff --git a/configs/FT_6mod_diag.yaml b/configs/FT_6mod_diag.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e3a0608f41d70e8b3cca4285f77c7eb9c0238e1c
--- /dev/null
+++ b/configs/FT_6mod_diag.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_FT
+experiment_name: PTseq_p50_6mod_9ds_CL_w_1_improve_diag
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+ft_task: diagnosis
+patch_size: 50
+num_classes: 6
+num_workers: 6
+lr: 0.01
+layer_decay: 1.0
+weight_decay: 0.0001
+num_epochs: 3
+loss: coxph
+batch_size_t: 4
+batch_size_v: 32
+proportion_t: 1.0
+proportion_v: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: PTseq_p50_6mod_9ds_CL_w_1_improve-final.ckpt # PTseq_p50_4mod_hier_2_2_lgonly_4ds_CL_koelo_full_night-final.ckpt # p50_4mod_hier_2_2_lgonly_4ds_CL_koelo-final.ckpt #
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP","EMG","SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+from_seq_pretrain: True
+seq_truncate: False
+use_lstm: False
+use_micro: False
\ No newline at end of file
diff --git a/configs/PT_6mod_5ds_CL_test.yaml b/configs/PT_6mod_5ds_CL_test.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ec7856afddbeeed32863b884b0d73448015cc62f
--- /dev/null
+++ b/configs/PT_6mod_5ds_CL_test.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_3
+experiment_name: p50_6mod_kiss_CL_w_1_test
+data_root: datasets
+datasets: ['kiss'] #['phy-tr','phy-te','shhs1','shhs2','kiss','kvss','mros1','mros1-val','mros1-te','mros2','mros2-val','mros2-te','mesa','mesa-val','mesa-te']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: convmae1d_multi
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.0005
+weight_decay: 0.05
+num_epochs: 1
+batch_size_t: 1
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+previous_run_id: null
+previous_checkpoint: null
+pretrained: null #experiments/p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix8-final.ckpt
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+lg_ratio: 1.0
+sig_len_target: 60
+use_shared: True
+use_moe: True
+use_revin: True
+loss: MSE
+loss_weights: {
+ 'mae': 1.0,
+ 'moe': 0.001,
+ 'ortho': 0.0,
+ 'contrastive': 0.1,
+ 'koleo': 0.01
+}
diff --git a/configs/PT_6mod_9ds_CL.yaml b/configs/PT_6mod_9ds_CL.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..e5699708cff2ecd89070b44696dcc2977e04c803
--- /dev/null
+++ b/configs/PT_6mod_9ds_CL.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_3
+experiment_name: p50_6mod_9ds_kissFix
+data_root: datasets
+datasets: ['phy-tr','phy-te','shhs1','shhs2','kiss','kvss','mros1','mros1-val','mros1-te','mros2','mros2-val','mros2-te','mesa','mesa-val','mesa-te']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: convmae1d_multi
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.0005
+weight_decay: 0.05
+num_epochs: 2
+batch_size_t: 512
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+previous_run_id: null
+previous_checkpoint: null
+pretrained: null #experiments/p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix8-final.ckpt
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+lg_ratio: 1.0
+sig_len_target: 60
+use_shared: True
+use_moe: True
+use_revin: True
+loss: MSE
+loss_weights: {
+ 'mae': 1.0,
+ 'moe': 0.001,
+ 'ortho': 0.0,
+ 'contrastive': 0.1,
+ 'koleo': 0.01
+}
diff --git a/configs/PT_6mod_9ds_CL_abl1.yaml b/configs/PT_6mod_9ds_CL_abl1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..fdbf30ca597a1b3ab2d40e8828100482a10354d7
--- /dev/null
+++ b/configs/PT_6mod_9ds_CL_abl1.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_3
+experiment_name: p50_6mod_noshared_shhs
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: convmae1d_multi
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.0005
+weight_decay: 0.05
+num_epochs: 2
+batch_size_t: 512
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+previous_run_id: null
+previous_checkpoint: null
+pretrained: null #experiments/p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix8-final.ckpt
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+lg_ratio: 1.0
+sig_len_target: 60
+use_shared: False
+use_moe: False
+use_revin: True
+loss: MSE
+loss_weights: {
+ 'mae': 1.0,
+ 'moe': 0.0,
+ 'ortho': 0.0,
+ 'contrastive': 0.0,
+ 'koleo': 0.0
+}
diff --git a/configs/PT_6mod_9ds_CL_abl2.yaml b/configs/PT_6mod_9ds_CL_abl2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..84afd467e70229bfa8935b5e9b5076c1e5aee4dc
--- /dev/null
+++ b/configs/PT_6mod_9ds_CL_abl2.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_3
+experiment_name: p50_6mod_MAEonly_shhs
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: convmae1d_multi
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.0005
+weight_decay: 0.05
+num_epochs: 2
+batch_size_t: 512
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+previous_run_id: null
+previous_checkpoint: null
+pretrained: null #experiments/p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix8-final.ckpt
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+lg_ratio: 1.0
+sig_len_target: 60
+use_shared: True
+use_moe: True
+use_revin: True
+loss: MSE
+loss_weights: {
+ 'mae': 1.0,
+ 'moe': 0.001,
+ 'ortho': 0.0,
+ 'contrastive': 0.0,
+ 'koleo': 0.0
+}
diff --git a/configs/PT_6mod_9ds_CL_abl3.yaml b/configs/PT_6mod_9ds_CL_abl3.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..96fbda474d65508bb91f15a74c4d772c0aba2307
--- /dev/null
+++ b/configs/PT_6mod_9ds_CL_abl3.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_3
+experiment_name: p50_6mod_MAEonly_noMoE_shhs
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: convmae1d_multi
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.0005
+weight_decay: 0.05
+num_epochs: 2
+batch_size_t: 512
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+previous_run_id: null
+previous_checkpoint: null
+pretrained: null #experiments/p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix8-final.ckpt
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+lg_ratio: 1.0
+sig_len_target: 60
+use_shared: True
+use_moe: False
+use_revin: True
+loss: MSE
+loss_weights: {
+ 'mae': 1.0,
+ 'moe': 0.0,
+ 'ortho': 0.0,
+ 'contrastive': 0.0,
+ 'koleo': 0.0
+}
diff --git a/configs/PT_6mod_9ds_CL_abl4.yaml b/configs/PT_6mod_9ds_CL_abl4.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..5c94aae61ac61d65d8b8795529ac854bcdc82f4c
--- /dev/null
+++ b/configs/PT_6mod_9ds_CL_abl4.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_3
+experiment_name: p50_6mod_CL_shhs
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: convmae1d_multi
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.0005
+weight_decay: 0.05
+num_epochs: 2
+batch_size_t: 512
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+previous_run_id: null
+previous_checkpoint: null
+pretrained: null #experiments/p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix8-final.ckpt
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+lg_ratio: 1.0
+sig_len_target: 60
+use_shared: True
+use_moe: True
+use_revin: True
+loss: MSE
+loss_weights: {
+ 'mae': 1.0,
+ 'moe': 0.001,
+ 'ortho': 0.0,
+ 'contrastive': 0.1,
+ 'koleo': 0.01
+}
diff --git a/configs/PT_6mod_9ds_CL_abl5.yaml b/configs/PT_6mod_9ds_CL_abl5.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..4c6867e6275e6a0be17c69c28e2f0c563fb77a4e
--- /dev/null
+++ b/configs/PT_6mod_9ds_CL_abl5.yaml
@@ -0,0 +1,41 @@
+project_name: ConvMAE1d_3
+experiment_name: p50_6mod_CL_shhs_w3
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: convmae1d_multi
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.0005
+weight_decay: 0.05
+num_epochs: 2
+batch_size_t: 512
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+previous_run_id: null
+previous_checkpoint: null
+pretrained: null #experiments/p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix8-final.ckpt
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+lg_ratio: 1.0
+sig_len_target: 60
+use_shared: True
+use_moe: True
+use_revin: True
+loss: MSE
+loss_weights: {
+ 'mae': 1.0,
+ 'moe': 0.001,
+ 'ortho': 0.0,
+ 'contrastive': 0.3,
+ 'koleo': 0.01
+}
diff --git a/configs/PT_6mod_9ds_CL_abl6.yaml b/configs/PT_6mod_9ds_CL_abl6.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..bcba4d6640d87387d9c3855b2b2297035adf338a
--- /dev/null
+++ b/configs/PT_6mod_9ds_CL_abl6.yaml
@@ -0,0 +1,42 @@
+project_name: ConvMAE1d_3
+experiment_name: p50_6mod_CL_shhs_CLonly_cat
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: convmae1d_multi
+patch_size: 50
+num_classes: 5
+num_workers: 6
+lr: 0.0005
+weight_decay: 0.05
+num_epochs: 2
+batch_size_t: 512
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+previous_run_id: null
+previous_checkpoint: null
+pretrained: null #experiments/p50_6mod_hier_2_2_lgonly_5ds_CL_nonmix8-final.ckpt
+scheduler_name: CosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+lg_ratio: 1.0
+sig_len_target: 60
+use_shared: True
+use_moe: True
+use_revin: True
+loss: MSE
+loss_weights: {
+ 'mae': 0.0,
+ 'moe': 0.001,
+ 'ortho': 0.0,
+ 'contrastive': 1.0,
+ 'koleo': 0.1
+}
+mask_ratio: 0.0
\ No newline at end of file
diff --git a/configs/PTseq_6mod_CL_full_night.yaml b/configs/PTseq_6mod_CL_full_night.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..7b7a250292111e3aa97f5d06f93ff791d510a245
--- /dev/null
+++ b/configs/PTseq_6mod_CL_full_night.yaml
@@ -0,0 +1,37 @@
+project_name: ConvMAE1d_PTseq
+experiment_name: PTseq_p50_6mod_9ds_kissFix
+data_root: datasets
+datasets: ['shhs1','shhs2','kiss','kvss','mesa','mesa-val','mesa-te','mros1','mros1-val','mros1-te','mros2','mros2-val','mros2-te'] #'phy-te','mros1'] #
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+patch_size: 50
+num_classes: 5
+num_workers: 8
+lr: 0.0001
+layer_decay: 1.0
+weight_decay: 0.05
+num_epochs: 4
+batch_size_t: 40
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_9ds_kissFix-final.ckpt #p50_6mod_6ds_CL_w_1-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: WarmupCosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+seq_truncate: True
+demo_keys: ['age','sex','bmi']
+cycle_len: 180
+use_transformer: False
\ No newline at end of file
diff --git a/configs/PTseq_6mod_CL_full_night_abl1.yaml b/configs/PTseq_6mod_CL_full_night_abl1.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..686497a9bc823b4f93a76262dc4f1c473edb4030
--- /dev/null
+++ b/configs/PTseq_6mod_CL_full_night_abl1.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_PTseq
+experiment_name: PTseq_p50_6mod_9ds_CL_w_1_improve_shhs_bmi2
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+patch_size: 50
+num_classes: 5
+num_workers: 8
+lr: 0.0001
+layer_decay: 1.0
+weight_decay: 0.05
+num_epochs: 4
+batch_size_t: 40
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_9ds_CL_w_1-final.ckpt #p50_6mod_6ds_CL_w_1-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: WarmupCosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+seq_truncate: True
+demo_keys: ['age','sex','bmi']
+cycle_len: 180
diff --git a/configs/PTseq_6mod_CL_full_night_abl2.yaml b/configs/PTseq_6mod_CL_full_night_abl2.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..30f1a7a5a21007d41ace7e9b8f74f35ea86ee1ce
--- /dev/null
+++ b/configs/PTseq_6mod_CL_full_night_abl2.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_PTseq
+experiment_name: PTseq_p50_6mod_9ds_CL_w_1_improve_shhs_age2
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+patch_size: 50
+num_classes: 5
+num_workers: 8
+lr: 0.0001
+layer_decay: 1.0
+weight_decay: 0.05
+num_epochs: 4
+batch_size_t: 40
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_9ds_CL_w_1-final.ckpt #p50_6mod_6ds_CL_w_1-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: WarmupCosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+seq_truncate: True
+demo_keys: ['age','sex','bmi']
+cycle_len: 180
diff --git a/configs/PTseq_6mod_CL_full_night_abl3.yaml b/configs/PTseq_6mod_CL_full_night_abl3.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..9d23ca8bcad81ed49a65965ba25261b55c60a087
--- /dev/null
+++ b/configs/PTseq_6mod_CL_full_night_abl3.yaml
@@ -0,0 +1,36 @@
+project_name: ConvMAE1d_PTseq
+experiment_name: PTseq_p50_6mod_9ds_kissFix_shhs_cycle1080
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+patch_size: 50
+num_classes: 5
+num_workers: 8
+lr: 0.0001
+layer_decay: 1.0
+weight_decay: 0.05
+num_epochs: 4
+batch_size_t: 40
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_9ds_kissFix-final.ckpt #p50_6mod_6ds_CL_w_1-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: WarmupCosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+seq_truncate: True
+demo_keys: ['age','sex','bmi']
+cycle_len: 1080
diff --git a/configs/PTseq_6mod_CL_full_night_abl4.yaml b/configs/PTseq_6mod_CL_full_night_abl4.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..c2441cafa8982ceac8a89f50fd656d6e63f9a957
--- /dev/null
+++ b/configs/PTseq_6mod_CL_full_night_abl4.yaml
@@ -0,0 +1,38 @@
+project_name: ConvMAE1d_PTseq
+experiment_name: PTseq_p50_6mod_9ds_kissFix_shhs_mamba_uni
+data_root: datasets
+datasets: ['shhs1']
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+patch_size: 50
+num_classes: 5
+num_workers: 8
+lr: 0.0001
+layer_decay: 1.0
+weight_decay: 0.05
+num_epochs: 4
+batch_size_t: 32
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_9ds_kissFix-final.ckpt #p50_6mod_6ds_CL_w_1-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: WarmupCosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+seq_truncate: True
+demo_keys: ['age','sex','bmi']
+cycle_len: 180
+use_transformer: False
+bidi: False
diff --git a/configs/PTseq_6mod_CL_full_night_dino.yaml b/configs/PTseq_6mod_CL_full_night_dino.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..246e1bfcbfb9db446876006032baa29e7b3176f9
--- /dev/null
+++ b/configs/PTseq_6mod_CL_full_night_dino.yaml
@@ -0,0 +1,39 @@
+project_name: ConvMAE1d_PTseq
+experiment_name: PTseq_p50_6mod_9ds_kissFix_dino
+data_root: datasets
+datasets: ['shhs1','shhs2','kiss','kvss','mesa','mesa-val','mesa-te','mros1','mros1-val','mros1-te','mros2','mros2-val','mros2-te'] #'phy-te','mros1'] #
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+patch_size: 50
+num_classes: 5
+num_workers: 8
+lr: 0.0001
+layer_decay: 1.0
+weight_decay: 0.05
+num_epochs: 4
+batch_size_t: 24
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_9ds_kissFix-final.ckpt #p50_6mod_6ds_CL_w_1-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: WarmupCosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+seq_truncate: True
+demo_keys: ['age','sex','bmi']
+cycle_len: 180
+use_transformer: False
+simclr: False
+dino: True
\ No newline at end of file
diff --git a/configs/PTseq_6mod_CL_full_night_simclr.yaml b/configs/PTseq_6mod_CL_full_night_simclr.yaml
new file mode 100644
index 0000000000000000000000000000000000000000..ef6d1d430aebfd74c2460d8981d9fed0eb5498d6
--- /dev/null
+++ b/configs/PTseq_6mod_CL_full_night_simclr.yaml
@@ -0,0 +1,38 @@
+project_name: ConvMAE1d_PTseq
+experiment_name: PTseq_p50_6mod_9ds_kissFix_simclr2
+data_root: datasets
+datasets: ['shhs1','shhs2','kiss','kvss','mesa','mesa-val','mesa-te','mros1','mros1-val','mros1-te','mros2','mros2-val','mros2-te'] #'phy-te','mros1'] #
+config_save_path: experiments
+results_save_path: experiments
+ckpt_save_path: experiments
+model_name: classification_multi_full_night
+patch_size: 50
+num_classes: 5
+num_workers: 8
+lr: 0.0001
+layer_decay: 1.0
+weight_decay: 0.05
+num_epochs: 4
+batch_size_t: 24
+proportion_t: 1.0
+optimizer_name: AdamW
+gpus: [0,1]
+accumulate_grad_batches: 1
+num_experts: 4
+num_experts_per: 2
+pretrain_checkpoint: p50_6mod_9ds_kissFix-final.ckpt #p50_6mod_6ds_CL_w_1-final.ckpt
+previous_run_id: null
+previous_checkpoint: null
+scheduler_name: WarmupCosineAnnealingLR
+modalities: [
+ "EEG","EOG","ECG","RESP", "EMG" ,"SaO2"
+]
+sig_len_target: 30
+full_finetune: False
+use_revin: True
+full_night: True
+seq_truncate: True
+demo_keys: ['age','sex','bmi']
+cycle_len: 180
+use_transformer: False
+simclr: True
\ No newline at end of file
diff --git a/configs/global_cfg.py b/configs/global_cfg.py
new file mode 100644
index 0000000000000000000000000000000000000000..0f907fec3fdacb9a2cb10f89c2927c403a73323d
--- /dev/null
+++ b/configs/global_cfg.py
@@ -0,0 +1,73 @@
+TARGET_RESAMPLE=100
+EPOCH_LEN_MAX=1080
+EPOCH_LEN_MIN=360
+DATASET_PATH = {
+ 'phy-tr': 'physionet_2018/mmap_signals_MAE_processed',
+ 'phy-te': 'physionet_test/mmap_signals_MAE_processed',
+ 'shhs1': 'shhs1/mmap_signals_MAE_processed',
+ 'shhs2': 'shhs2/mmap_signals_MAE_processed',
+ 'kiss': 'kiss/mmap_signals_MAE_processed',
+ 'kvss': 'kvss/mmap_signals_MAE_processed',
+ 'mros1': 'mros1/mmap_signals_MAE_processed',
+ 'mros2': 'mros2/mmap_signals_MAE_processed',
+ 'mesa': 'mesa/mmap_signals_MAE_processed',
+ 'mros1-val': 'mros1_val',
+ 'mros1-te': 'mros1_te',
+ 'mros2-val': 'mros2_val',
+ 'mros2-te': 'mros2_te',
+ 'mesa-val': 'mesa_val',
+ 'mesa-te': 'mesa_te',
+ 'isruc_sg1': 'isruc_all/mmap_signals_MAE_processed',
+ 'isruc_sg1_1': 'isruc_all/mmap_signals_MAE_processed_train1',
+ 'isruc_sg1_5': 'isruc_all/mmap_signals_MAE_processed_train5',
+ 'isruc_sg1_10': 'isruc_all/mmap_signals_MAE_processed_train10',
+ 'isruc_sg1_20': 'isruc_all/mmap_signals_MAE_processed_train20',
+ 'isruc_sg1_30': 'isruc_all/mmap_signals_MAE_processed_train30',
+ 'isruc_sg1_50': 'isruc_all/mmap_signals_MAE_processed_train50',
+ 'cfs': 'cfs/mmap_signals_MAE_processed',
+ 'cfs_1': 'cfs/mmap_signals_MAE_processed_train1',
+ 'cfs_5': 'cfs/mmap_signals_MAE_processed_train5',
+ 'cfs_10': 'cfs/mmap_signals_MAE_processed_train10',
+ 'cfs_30': 'cfs/mmap_signals_MAE_processed_train30',
+ 'cfs_100': 'cfs/mmap_signals_MAE_processed_train100',
+ 'sof': 'sof/mmap_signals_MAE_processed',
+
+}
+LABELS_PATH = {
+ 'sleep_staging': {
+ 'phy-tr': 'physionet_2018/annotations',
+ 'shhs1': 'shhs1/annotations_split',
+ 'kiss': 'kiss/annotations_split',
+ 'isruc_sg1': 'isruc_all/annotations',
+ 'isruc_sg1_1': 'isruc_all/annotations',
+ 'isruc_sg1_5': 'isruc_all/annotations',
+ 'isruc_sg1_10': 'isruc_all/annotations',
+ 'isruc_sg1_20': 'isruc_all/annotations',
+ 'isruc_sg1_30': 'isruc_all/annotations',
+ 'isruc_sg1_50': 'isruc_all/annotations',
+ 'cfs': 'cfs/annotations_split',
+ 'cfs_1': 'cfs/annotations',
+ 'cfs_5': 'cfs/annotations',
+ 'cfs_10': 'cfs/annotations',
+ 'cfs_30': 'cfs/annotations',
+ 'cfs_100': 'cfs/annotations',
+ 'sof': 'sof/annotations',
+ },
+ 'apnea_seg': {
+ 'phy-tr': 'physionet_2018/ah_labels',
+ 'kiss': 'kiss/ah_labels_split',
+ 'shhs1': 'shhs1/ah_labels_split',
+ 'cfs': 'cfs/ah_labels_split',
+ 'cfs_1': 'cfs/ah_labels',
+ 'cfs_5': 'cfs/ah_labels',
+ 'cfs_10': 'cfs/ah_labels',
+ 'cfs_30': 'cfs/ah_labels',
+ 'cfs_100': 'cfs/ah_labels',
+ 'sof': 'sof/ah_labels',
+
+ }
+}
+
+
+CLASSIFICATION_TASKS = ['sleep_staging', 'apnea_seg', 'sex']
+REGRESSION_TASKS = ['age', 'ahi']
\ No newline at end of file
diff --git a/data/README.md b/data/README.md
new file mode 100644
index 0000000000000000000000000000000000000000..239cdf2411614dd393c04fc1868f7c3b25f0385c
--- /dev/null
+++ b/data/README.md
@@ -0,0 +1,63 @@
+# Data Preprocessing
+
+This directory contains the preprocessing pipeline for several sleep study datasets, including **Physionet 2018, SHHS1/2, KISS/KVSS, MrOS1/2, and MESA**.
+
+---
+
+## 1. Raw Data Extraction
+### `{dataset_name}_process_rawdata.py`
+
+This script extracts signals and labels from raw data (e.g., `.edf` files) and saves them in `.npy` format.
+
+* **Channel Selection:** Extracts specific required channels: `EEG`, `EOG`, `EMG`, `ECG`, `ABD`, `CHEST`, `AIRFLOW`, and `SaO2`.
+* **Label Alignment:** * Synchronizes sleep staging labels with signal timeframes.
+ * Adjusts staging formats (e.g., converting **R&K** to **AASM** standards).
+ * Excludes error cases or undefined stages (e.g., "Unknown").
+* **Respiratory Events:** Extracts Apnea-Hypopnea labels where applicable (Apnea: 2, Hypopnea: 1).
+* **Wake Trimming:** If excessive "Wake" periods exist at the beginning or end of a recording, they are trimmed to a maximum of 30 minutes.
+* **Sampling Rate:** The original sampling rate is preserved during this step.
+* **Note:** For KISS/KVSS, the extraction logic is stored in a dedicated sub-folder.
+
+**Output Paths:**
+* `datasets/{dataset_name}/signals_MAE/{CHN_GRP}/{CHN}`: Raw biosignals.
+* `datasets/{dataset_name}/annotations`: Sleep staging labels.
+* `datasets/{dataset_name}/ah_labels`: Apnea-Hypopnea labels.
+
+---
+
+## 2. Signal Refinement & Memory Mapping
+### `{dataset_name}_preprocess.py`
+
+This script processes the `.npy` files (filtering, resampling) and saves them as memory-mapped (`.mmap`) files for efficient data loading.
+
+### Filtering Specifications
+
+| Signal Type | Filtering Parameters |
+| :--- | :--- |
+| **EEG, EOG** | Notch: 60 Hz \| Bandpass: 0.3–40 Hz |
+| **ECG** | Notch: 60 Hz \| Bandpass: 0.3–60 Hz \| Peak-based inversion correction |
+| **EMG** | Notch: 60 Hz \| Highpass: 10 Hz |
+| **AIRFLOW, ABD, CHEST** | Lowpass: 15 Hz |
+
+* **Resampling:** All signals are unified to a sampling rate of **100 Hz**.
+* **Metadata Generation:** A `.pickle` file is created for each biosignal to manage the global `.mmap` file. It includes:
+ * **Indices:** Start and end positions for each case within the combined `.mmap`.
+ * **Statistics:** Sum and square sum per case (used later for **Standardization**).
+ * **Shape:** The total dimensions of the `.mmap` file.
+* **Data Splitting:** Automatically performs the **Train/Val/Test** split (Only for finetuning datasets - SHHS1 and KISS).
+
+**Output Paths:**
+* `datasets/{dataset_name}/mmap_signals_MAE_processed/{split}/{CHN_GRP}/{CHN}`: `.mmap` and `.pickle` files.
+* `datasets/{dataset_name}/annotations_split/{split}`: Split sleep staging labels.
+* `datasets/{dataset_name}/ah_labels_split/{split}`: Split Apnea-Hypopnea labels.
+
+---
+
+## 3. Patient Demographics
+### `get_demographics.py`
+
+This script extracts and aggregates patient-level information into a structured format.
+
+* **Data Points:** Collects **Sex, Age, BMI, and AHI** (Apnea-Hypopnea Index).
+* **Handling Missing Values:** If a specific metric was not collected for a patient, it is ignored/skipped.
+* **Output Path:** `datasets/demographics/{dataset_name}_demographics.pkl`
diff --git a/data/cfs_meta_data/split_data.py b/data/cfs_meta_data/split_data.py
new file mode 100644
index 0000000000000000000000000000000000000000..84a7901abc3e9f069bb3f08ff29d64fc1c2fca11
--- /dev/null
+++ b/data/cfs_meta_data/split_data.py
@@ -0,0 +1,51 @@
+# Create a script to split the dataset into train, validation, and test sets
+# The filenames are from BASE_PATH/cfs/signals_MAE/EEG/C3-M2/*.npy
+import os
+import random
+import numpy as np
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'datasets')
+SEED = 42
+random.seed(SEED)
+np.random.seed(SEED)
+
+def split_data(data_dir, output_dir, train_ratio=0.7, val_num=50, test_ratio=0.3):
+ # Get all the filenames in the data directory
+ all_files = []
+ for root, dirs, files in os.walk(data_dir):
+ for file in files:
+ if file.endswith('.npy'):
+ pid = file.split('.')[0] # Assuming filename format is PID_XXX.npy
+ all_files.append(pid)
+
+ # Shuffle the filenames
+ random.shuffle(all_files)
+
+ # Split the data into train, validation, and test sets
+ total_files = len(all_files)
+ train_end = int(total_files * train_ratio) - val_num
+ val_end = train_end + val_num
+
+ train_files = all_files[:train_end]
+ val_files = all_files[train_end:val_end]
+ test_files = all_files[val_end:]
+
+ # Save the splits to output directory
+ os.makedirs(output_dir, exist_ok=True)
+
+ with open(os.path.join(output_dir, 'train.txt'), 'w') as f:
+ for file in train_files:
+ f.write(file + '\n')
+
+ with open(os.path.join(output_dir, 'val.txt'), 'w') as f:
+ for file in val_files:
+ f.write(file + '\n')
+
+ with open(os.path.join(output_dir, 'test.txt'), 'w') as f:
+ for file in test_files:
+ f.write(file + '\n')
+
+if __name__ == "__main__":
+ data_dir = os.path.join(BASE_PATH, 'cfs', 'signals_MAE', 'EEG', 'C3-M2')
+ output_dir = '.'
+ split_data(data_dir, output_dir)
\ No newline at end of file
diff --git a/data/cfs_meta_data/test.txt b/data/cfs_meta_data/test.txt
new file mode 100644
index 0000000000000000000000000000000000000000..e2c2325f4e5766ce1c411569911a08f590b3665e
--- /dev/null
+++ b/data/cfs_meta_data/test.txt
@@ -0,0 +1,201 @@
+cfs-visit5-800900
+cfs-visit5-802451
+cfs-visit5-802745
+cfs-visit5-802201
+cfs-visit5-801900
+cfs-visit5-800048
+cfs-visit5-800891
+cfs-visit5-800195
+cfs-visit5-801220
+cfs-visit5-800680
+cfs-visit5-802110
+cfs-visit5-802180
+cfs-visit5-800412
+cfs-visit5-800688
+cfs-visit5-801645
+cfs-visit5-801942
+cfs-visit5-802065
+cfs-visit5-801782
+cfs-visit5-800916
+cfs-visit5-800690
+cfs-visit5-801677
+cfs-visit5-801945
+cfs-visit5-800038
+cfs-visit5-800544
+cfs-visit5-802104
+cfs-visit5-801602
+cfs-visit5-801773
+cfs-visit5-801814
+cfs-visit5-800375
+cfs-visit5-802242
+cfs-visit5-801035
+cfs-visit5-800968
+cfs-visit5-802385
+cfs-visit5-801323
+cfs-visit5-800604
+cfs-visit5-801651
+cfs-visit5-802380
+cfs-visit5-801126
+cfs-visit5-800780
+cfs-visit5-800113
+cfs-visit5-800170
+cfs-visit5-800365
+cfs-visit5-800908
+cfs-visit5-801770
+cfs-visit5-800705
+cfs-visit5-801085
+cfs-visit5-800697
+cfs-visit5-802335
+cfs-visit5-801337
+cfs-visit5-801788
+cfs-visit5-802449
+cfs-visit5-802303
+cfs-visit5-802228
+cfs-visit5-800861
+cfs-visit5-801162
+cfs-visit5-800194
+cfs-visit5-800985
+cfs-visit5-801735
+cfs-visit5-800021
+cfs-visit5-800980
+cfs-visit5-802482
+cfs-visit5-800078
+cfs-visit5-802185
+cfs-visit5-802171
+cfs-visit5-802691
+cfs-visit5-801396
+cfs-visit5-800769
+cfs-visit5-801576
+cfs-visit5-801794
+cfs-visit5-801762
+cfs-visit5-800926
+cfs-visit5-801432
+cfs-visit5-802038
+cfs-visit5-801058
+cfs-visit5-802460
+cfs-visit5-800247
+cfs-visit5-800271
+cfs-visit5-802075
+cfs-visit5-801454
+cfs-visit5-802010
+cfs-visit5-800226
+cfs-visit5-800672
+cfs-visit5-801445
+cfs-visit5-800197
+cfs-visit5-802533
+cfs-visit5-800313
+cfs-visit5-801225
+cfs-visit5-802716
+cfs-visit5-801299
+cfs-visit5-800847
+cfs-visit5-800122
+cfs-visit5-802593
+cfs-visit5-802573
+cfs-visit5-801037
+cfs-visit5-801638
+cfs-visit5-801719
+cfs-visit5-801246
+cfs-visit5-801325
+cfs-visit5-801587
+cfs-visit5-801438
+cfs-visit5-801291
+cfs-visit5-801393
+cfs-visit5-801540
+cfs-visit5-800716
+cfs-visit5-801152
+cfs-visit5-800229
+cfs-visit5-802612
+cfs-visit5-800490
+cfs-visit5-801311
+cfs-visit5-801528
+cfs-visit5-802072
+cfs-visit5-801675
+cfs-visit5-801101
+cfs-visit5-800617
+cfs-visit5-802005
+cfs-visit5-801080
+cfs-visit5-800203
+cfs-visit5-802252
+cfs-visit5-802549
+cfs-visit5-801352
+cfs-visit5-800665
+cfs-visit5-802658
+cfs-visit5-801144
+cfs-visit5-800434
+cfs-visit5-801902
+cfs-visit5-801806
+cfs-visit5-801559
+cfs-visit5-800841
+cfs-visit5-801150
+cfs-visit5-801685
+cfs-visit5-801335
+cfs-visit5-800658
+cfs-visit5-801159
+cfs-visit5-800136
+cfs-visit5-801497
+cfs-visit5-800719
+cfs-visit5-802724
+cfs-visit5-801458
+cfs-visit5-802678
+cfs-visit5-800105
+cfs-visit5-802475
+cfs-visit5-800449
+cfs-visit5-800326
+cfs-visit5-801650
+cfs-visit5-800380
+cfs-visit5-801446
+cfs-visit5-801859
+cfs-visit5-800236
+cfs-visit5-800953
+cfs-visit5-800049
+cfs-visit5-802637
+cfs-visit5-800971
+cfs-visit5-802487
+cfs-visit5-802648
+cfs-visit5-801833
+cfs-visit5-800321
+cfs-visit5-800494
+cfs-visit5-801381
+cfs-visit5-801264
+cfs-visit5-800395
+cfs-visit5-802717
+cfs-visit5-801270
+cfs-visit5-802368
+cfs-visit5-801747
+cfs-visit5-801166
+cfs-visit5-800440
+cfs-visit5-800311
+cfs-visit5-802123
+cfs-visit5-800811
+cfs-visit5-801137
+cfs-visit5-801294
+cfs-visit5-800545
+cfs-visit5-801095
+cfs-visit5-801724
+cfs-visit5-800512
+cfs-visit5-802498
+cfs-visit5-802125
+cfs-visit5-802753
+cfs-visit5-801278
+cfs-visit5-801501
+cfs-visit5-800594
+cfs-visit5-802154
+cfs-visit5-801662
+cfs-visit5-800011
+cfs-visit5-800905
+cfs-visit5-800017
+cfs-visit5-801706
+cfs-visit5-800329
+cfs-visit5-801855
+cfs-visit5-801231
+cfs-visit5-802295
+cfs-visit5-801732
+cfs-visit5-801019
+cfs-visit5-801526
+cfs-visit5-802268
+cfs-visit5-801110
+cfs-visit5-800211
+cfs-visit5-800851
+cfs-visit5-802537
+cfs-visit5-800471
+cfs-visit5-801809
diff --git a/data/cfs_meta_data/train.txt b/data/cfs_meta_data/train.txt
new file mode 100644
index 0000000000000000000000000000000000000000..ed98b1a11b1e0e8353766441bb416cbd93222965
--- /dev/null
+++ b/data/cfs_meta_data/train.txt
@@ -0,0 +1,418 @@
+cfs-visit5-800238
+cfs-visit5-801487
+cfs-visit5-801341
+cfs-visit5-801427
+cfs-visit5-802462
+cfs-visit5-800733
+cfs-visit5-802346
+cfs-visit5-802467
+cfs-visit5-800914
+cfs-visit5-801181
+cfs-visit5-802435
+cfs-visit5-801850
+cfs-visit5-800325
+cfs-visit5-801660
+cfs-visit5-800099
+cfs-visit5-800801
+cfs-visit5-800805
+cfs-visit5-800854
+cfs-visit5-802247
+cfs-visit5-800565
+cfs-visit5-802273
+cfs-visit5-802398
+cfs-visit5-801005
+cfs-visit5-801173
+cfs-visit5-800173
+cfs-visit5-801267
+cfs-visit5-800522
+cfs-visit5-802408
+cfs-visit5-802711
+cfs-visit5-801928
+cfs-visit5-800946
+cfs-visit5-800860
+cfs-visit5-801300
+cfs-visit5-800220
+cfs-visit5-801457
+cfs-visit5-800722
+cfs-visit5-802183
+cfs-visit5-801350
+cfs-visit5-801452
+cfs-visit5-801282
+cfs-visit5-800640
+cfs-visit5-801800
+cfs-visit5-801252
+cfs-visit5-800151
+cfs-visit5-801122
+cfs-visit5-802233
+cfs-visit5-801917
+cfs-visit5-801263
+cfs-visit5-802302
+cfs-visit5-801312
+cfs-visit5-802078
+cfs-visit5-802272
+cfs-visit5-801027
+cfs-visit5-800316
+cfs-visit5-800341
+cfs-visit5-800346
+cfs-visit5-800047
+cfs-visit5-801734
+cfs-visit5-802195
+cfs-visit5-802676
+cfs-visit5-801222
+cfs-visit5-801052
+cfs-visit5-800299
+cfs-visit5-801521
+cfs-visit5-802294
+cfs-visit5-801183
+cfs-visit5-801125
+cfs-visit5-801867
+cfs-visit5-800086
+cfs-visit5-801346
+cfs-visit5-801377
+cfs-visit5-800344
+cfs-visit5-801631
+cfs-visit5-801416
+cfs-visit5-800492
+cfs-visit5-802491
+cfs-visit5-800371
+cfs-visit5-800109
+cfs-visit5-802003
+cfs-visit5-801013
+cfs-visit5-800937
+cfs-visit5-801449
+cfs-visit5-800198
+cfs-visit5-800285
+cfs-visit5-801656
+cfs-visit5-800427
+cfs-visit5-800714
+cfs-visit5-802235
+cfs-visit5-800390
+cfs-visit5-801488
+cfs-visit5-802308
+cfs-visit5-800359
+cfs-visit5-800161
+cfs-visit5-801609
+cfs-visit5-800426
+cfs-visit5-802509
+cfs-visit5-800177
+cfs-visit5-800939
+cfs-visit5-800575
+cfs-visit5-802400
+cfs-visit5-801212
+cfs-visit5-800506
+cfs-visit5-800138
+cfs-visit5-802466
+cfs-visit5-800118
+cfs-visit5-800973
+cfs-visit5-802340
+cfs-visit5-801790
+cfs-visit5-801366
+cfs-visit5-802366
+cfs-visit5-800110
+cfs-visit5-800799
+cfs-visit5-802726
+cfs-visit5-801139
+cfs-visit5-802094
+cfs-visit5-802042
+cfs-visit5-800757
+cfs-visit5-801453
+cfs-visit5-800280
+cfs-visit5-800187
+cfs-visit5-800509
+cfs-visit5-800576
+cfs-visit5-800081
+cfs-visit5-801158
+cfs-visit5-801289
+cfs-visit5-800216
+cfs-visit5-801849
+cfs-visit5-801780
+cfs-visit5-802474
+cfs-visit5-801530
+cfs-visit5-802386
+cfs-visit5-801610
+cfs-visit5-800347
+cfs-visit5-802182
+cfs-visit5-802073
+cfs-visit5-801813
+cfs-visit5-802106
+cfs-visit5-802500
+cfs-visit5-802459
+cfs-visit5-800228
+cfs-visit5-801909
+cfs-visit5-801199
+cfs-visit5-800659
+cfs-visit5-801848
+cfs-visit5-801012
+cfs-visit5-802529
+cfs-visit5-801448
+cfs-visit5-801206
+cfs-visit5-800421
+cfs-visit5-801474
+cfs-visit5-800618
+cfs-visit5-801998
+cfs-visit5-801912
+cfs-visit5-802211
+cfs-visit5-801585
+cfs-visit5-802060
+cfs-visit5-801357
+cfs-visit5-801792
+cfs-visit5-801785
+cfs-visit5-802503
+cfs-visit5-801021
+cfs-visit5-801355
+cfs-visit5-800227
+cfs-visit5-800032
+cfs-visit5-801590
+cfs-visit5-802731
+cfs-visit5-801919
+cfs-visit5-802555
+cfs-visit5-802103
+cfs-visit5-802205
+cfs-visit5-802734
+cfs-visit5-801591
+cfs-visit5-800364
+cfs-visit5-801319
+cfs-visit5-802004
+cfs-visit5-801112
+cfs-visit5-801376
+cfs-visit5-801825
+cfs-visit5-800072
+cfs-visit5-801491
+cfs-visit5-802424
+cfs-visit5-800159
+cfs-visit5-801707
+cfs-visit5-800404
+cfs-visit5-800630
+cfs-visit5-801038
+cfs-visit5-801858
+cfs-visit5-801936
+cfs-visit5-801064
+cfs-visit5-802109
+cfs-visit5-801340
+cfs-visit5-801864
+cfs-visit5-801373
+cfs-visit5-802659
+cfs-visit5-801389
+cfs-visit5-801444
+cfs-visit5-800400
+cfs-visit5-800911
+cfs-visit5-801133
+cfs-visit5-800666
+cfs-visit5-802626
+cfs-visit5-800505
+cfs-visit5-800393
+cfs-visit5-802619
+cfs-visit5-801331
+cfs-visit5-802427
+cfs-visit5-801326
+cfs-visit5-800883
+cfs-visit5-801569
+cfs-visit5-800148
+cfs-visit5-802206
+cfs-visit5-800527
+cfs-visit5-801731
+cfs-visit5-800928
+cfs-visit5-802011
+cfs-visit5-800114
+cfs-visit5-802634
+cfs-visit5-800949
+cfs-visit5-801213
+cfs-visit5-800643
+cfs-visit5-800024
+cfs-visit5-802218
+cfs-visit5-800737
+cfs-visit5-801666
+cfs-visit5-801370
+cfs-visit5-800962
+cfs-visit5-801233
+cfs-visit5-801983
+cfs-visit5-802322
+cfs-visit5-801421
+cfs-visit5-801771
+cfs-visit5-801982
+cfs-visit5-802523
+cfs-visit5-800917
+cfs-visit5-802495
+cfs-visit5-801633
+cfs-visit5-800349
+cfs-visit5-801380
+cfs-visit5-801078
+cfs-visit5-800821
+cfs-visit5-800557
+cfs-visit5-800551
+cfs-visit5-800657
+cfs-visit5-801838
+cfs-visit5-800996
+cfs-visit5-801461
+cfs-visit5-802578
+cfs-visit5-801963
+cfs-visit5-801514
+cfs-visit5-800461
+cfs-visit5-800340
+cfs-visit5-801177
+cfs-visit5-800312
+cfs-visit5-802718
+cfs-visit5-800528
+cfs-visit5-800221
+cfs-visit5-802465
+cfs-visit5-801916
+cfs-visit5-801757
+cfs-visit5-800531
+cfs-visit5-801805
+cfs-visit5-802300
+cfs-visit5-801248
+cfs-visit5-802522
+cfs-visit5-802018
+cfs-visit5-801517
+cfs-visit5-800839
+cfs-visit5-800798
+cfs-visit5-802315
+cfs-visit5-802257
+cfs-visit5-801420
+cfs-visit5-800002
+cfs-visit5-801310
+cfs-visit5-801243
+cfs-visit5-801831
+cfs-visit5-800616
+cfs-visit5-800410
+cfs-visit5-802421
+cfs-visit5-801075
+cfs-visit5-801494
+cfs-visit5-802113
+cfs-visit5-800129
+cfs-visit5-802610
+cfs-visit5-800890
+cfs-visit5-801554
+cfs-visit5-800411
+cfs-visit5-800392
+cfs-visit5-802382
+cfs-visit5-800613
+cfs-visit5-800693
+cfs-visit5-801996
+cfs-visit5-802720
+cfs-visit5-800183
+cfs-visit5-801502
+cfs-visit5-802587
+cfs-visit5-801001
+cfs-visit5-800037
+cfs-visit5-801933
+cfs-visit5-801463
+cfs-visit5-800279
+cfs-visit5-802099
+cfs-visit5-800923
+cfs-visit5-802721
+cfs-visit5-802101
+cfs-visit5-802196
+cfs-visit5-802132
+cfs-visit5-802595
+cfs-visit5-800853
+cfs-visit5-800825
+cfs-visit5-801196
+cfs-visit5-802021
+cfs-visit5-801841
+cfs-visit5-801425
+cfs-visit5-802144
+cfs-visit5-802081
+cfs-visit5-802635
+cfs-visit5-802041
+cfs-visit5-800363
+cfs-visit5-802654
+cfs-visit5-800912
+cfs-visit5-800498
+cfs-visit5-802438
+cfs-visit5-800451
+cfs-visit5-802298
+cfs-visit5-800597
+cfs-visit5-801307
+cfs-visit5-800027
+cfs-visit5-802355
+cfs-visit5-801193
+cfs-visit5-800104
+cfs-visit5-800537
+cfs-visit5-801658
+cfs-visit5-802213
+cfs-visit5-801966
+cfs-visit5-800115
+cfs-visit5-801835
+cfs-visit5-800718
+cfs-visit5-801668
+cfs-visit5-800789
+cfs-visit5-802502
+cfs-visit5-800625
+cfs-visit5-801147
+cfs-visit5-800040
+cfs-visit5-802086
+cfs-visit5-802330
+cfs-visit5-800356
+cfs-visit5-802076
+cfs-visit5-801157
+cfs-visit5-802056
+cfs-visit5-800249
+cfs-visit5-802401
+cfs-visit5-801674
+cfs-visit5-802388
+cfs-visit5-802739
+cfs-visit5-802301
+cfs-visit5-801413
+cfs-visit5-802709
+cfs-visit5-801034
+cfs-visit5-802579
+cfs-visit5-800334
+cfs-visit5-800960
+cfs-visit5-801811
+cfs-visit5-801563
+cfs-visit5-802675
+cfs-visit5-800212
+cfs-visit5-800385
+cfs-visit5-800230
+cfs-visit5-800179
+cfs-visit5-802348
+cfs-visit5-801224
+cfs-visit5-800092
+cfs-visit5-801033
+cfs-visit5-800975
+cfs-visit5-801387
+cfs-visit5-801121
+cfs-visit5-800045
+cfs-visit5-800535
+cfs-visit5-802219
+cfs-visit5-801041
+cfs-visit5-800820
+cfs-visit5-801907
+cfs-visit5-802627
+cfs-visit5-800927
+cfs-visit5-800199
+cfs-visit5-800331
+cfs-visit5-800232
+cfs-visit5-801228
+cfs-visit5-802223
+cfs-visit5-800243
+cfs-visit5-800176
+cfs-visit5-801532
+cfs-visit5-800647
+cfs-visit5-800272
+cfs-visit5-800990
+cfs-visit5-800715
+cfs-visit5-800606
+cfs-visit5-802483
+cfs-visit5-801414
+cfs-visit5-802748
+cfs-visit5-800035
+cfs-visit5-801226
+cfs-visit5-800501
+cfs-visit5-800389
+cfs-visit5-801922
+cfs-visit5-800481
+cfs-visit5-802176
+cfs-visit5-800464
+cfs-visit5-801827
+cfs-visit5-801596
+cfs-visit5-802645
+cfs-visit5-801161
+cfs-visit5-802283
+cfs-visit5-801713
+cfs-visit5-801873
+cfs-visit5-800554
+cfs-visit5-801044
+cfs-visit5-802643
+cfs-visit5-800276
diff --git a/data/cfs_meta_data/val.txt b/data/cfs_meta_data/val.txt
new file mode 100644
index 0000000000000000000000000000000000000000..8e48291401771000a4004ab4fdd69e1b9c0d16cb
--- /dev/null
+++ b/data/cfs_meta_data/val.txt
@@ -0,0 +1,50 @@
+cfs-visit5-800202
+cfs-visit5-800184
+cfs-visit5-800702
+cfs-visit5-800071
+cfs-visit5-801071
+cfs-visit5-800367
+cfs-visit5-801960
+cfs-visit5-801764
+cfs-visit5-802304
+cfs-visit5-802001
+cfs-visit5-800130
+cfs-visit5-801320
+cfs-visit5-801689
+cfs-visit5-801131
+cfs-visit5-801149
+cfs-visit5-800337
+cfs-visit5-800246
+cfs-visit5-801273
+cfs-visit5-800174
+cfs-visit5-802628
+cfs-visit5-800474
+cfs-visit5-800945
+cfs-visit5-800010
+cfs-visit5-800182
+cfs-visit5-800667
+cfs-visit5-800785
+cfs-visit5-800967
+cfs-visit5-800497
+cfs-visit5-801077
+cfs-visit5-800065
+cfs-visit5-801760
+cfs-visit5-802454
+cfs-visit5-800355
+cfs-visit5-802332
+cfs-visit5-800051
+cfs-visit5-801988
+cfs-visit5-802471
+cfs-visit5-802279
+cfs-visit5-801949
+cfs-visit5-801908
+cfs-visit5-801553
+cfs-visit5-801435
+cfs-visit5-800596
+cfs-visit5-802664
+cfs-visit5-802177
+cfs-visit5-801868
+cfs-visit5-800407
+cfs-visit5-800901
+cfs-visit5-800577
+cfs-visit5-800373
diff --git a/data/cfs_preprocess.py b/data/cfs_preprocess.py
new file mode 100644
index 0000000000000000000000000000000000000000..e35708aba4f11fc79548b8eb149b2f9365c22358
--- /dev/null
+++ b/data/cfs_preprocess.py
@@ -0,0 +1,372 @@
+import os
+import shutil
+import numpy as np
+import matplotlib.pyplot as plt
+from tqdm import tqdm
+import shutil
+import librosa
+
+from scipy.signal import iirnotch, lfilter
+from data_utils import butter_bandpass_filter, correct_ecg_inversion
+import pickle
+import pandas as pd
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+NOTCH_FREQ = 60
+EEG_LOWCUT = 0.3
+EEG_HIGHCUT = 40
+EMG_LOWCUT = 10
+EMG_HIGHCUT = 1000
+ECG_LOWCUT = 0.3
+ECG_HIGHCUT = 60
+FLOW_LOWCUT = 0
+FLOW_HIGHCUT = 15
+
+NUM_PROCESS = 4
+
+import argparse
+import multiprocessing
+
+TARGET_RESAMPLE = 100
+
+
+
+def process_ecg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, ECG_LOWCUT, ECG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ filtered = filtered.reshape(-1, sampling_rate*30)
+ # filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered_epochs = []
+
+ for epoch in filtered:
+ inv_epoch, _ = correct_ecg_inversion(epoch, TARGET_RESAMPLE)
+ filtered_epochs.append(inv_epoch)
+
+ filtered = np.stack(filtered_epochs, axis=0)
+
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = np.reshape(filtered, (-1,1))
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+
+def process_eeg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EEG_LOWCUT, EEG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_emg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EMG_LOWCUT, EMG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_flow(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, FLOW_LOWCUT, FLOW_HIGHCUT, sampling_rate)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ # median filter?
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def save_mmap(results, sig_list, chn_grp, chn, split='train'):
+ signame_list = [sig.split('.')[0] for sig in sig_list]
+ epoch_lengths = [sig.shape[0] for sig in results]
+ metadata = dict()
+ sig_info = dict()
+ start, end = 0, 0
+ for signame, sig in zip(signame_list, results):
+ length = sig.shape[0]
+ end = start + length
+ info = dict()
+ info['pos'] = (start, end)
+ info['stats'] = {'sum': float(np.sum(sig)), 'sumsq': float(np.sum(sig ** 2))}
+ sig_info[signame] = info
+ start = end
+
+
+ mmap_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ signals_cat = np.concatenate(results, axis=0).astype(np.float32)
+ os.makedirs(os.path.dirname(mmap_path), exist_ok=True)
+ data = np.memmap(mmap_path, dtype=np.float32, mode='w+', shape=signals_cat.shape)
+ data[:] = signals_cat
+ data.flush()
+
+ metadata['sig_info'] = sig_info
+ metadata['data_shape'] = signals_cat.shape
+ info_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ with open(info_path, 'wb') as f:
+ pickle.dump(metadata, f)
+
+
+def preprocess(sig_list, chn_grp=None, chn=None, split='train'):
+ def _process(sig_list, chn_grp, chn, split):
+
+ print(f"Processing {chn_grp}/{chn}")
+ # if not (chn == "C4-A1" or chn == "AIRFLOW"): continue
+
+ if chn_grp in ['EEG','EOG']:
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_eeg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['EMG']:
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_emg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['ECG']:
+
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_ecg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_flow, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+
+ else:
+ results = []
+ # for sig in tqdm(sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))):
+ for sig in tqdm(sig_list):
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ if sampling_rate != TARGET_RESAMPLE or chn == 'SaO2':
+ # assuming 30s epochs
+ data = data.reshape(-1, 1)
+ if chn == 'SaO2':
+ data = librosa.resample(data, orig_sr=sampling_rate, target_sr=1, axis=0, res_type='soxr_qq')
+ print(np.min(data), np.max(data))
+ data = data / 1e8 # data range 0 to 1e8
+ if np.max(data) > 1 or np.min(data) < 0:
+ print(f"Warning: SaO2 values out of range: {sig} with min {np.min(data)} and max {np.max(data)}")
+ data = data.reshape(-1, 1*30)
+ else:
+ data = librosa.resample(data, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ data = data.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, data)
+ elif cfg.save_type == 'mmap':
+ results.append(data)
+
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+
+ if chn_grp is not None and chn is not None:
+ _process(sig_list, chn_grp, chn, split)
+ return
+ else:
+ for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ continue
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)):
+ continue
+ _process(sig_list, chn_grp, chn, split)
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default='cfs/signals_MAE', help='SHHS raw data location')
+parser.add_argument('--output_dir', default='cfs/mmap_signals_MAE_processed', help='SHHS processed data location')
+parser.add_argument('--ann_split', action='store_true', help='To split annotation files into train/val/test')
+parser.add_argument('--save_type', default='mmap', help='Which data type to save. "npy" or "mmap"')
+parser.add_argument('--chn_grp', default=None, help='If specified, only preprocess this channel group')
+parser.add_argument('--chn', default=None, help='If specified, only preprocess this channel')
+parser.add_argument('--num_train', type=int, default=50, help='Number of training samples')
+
+cfg = parser.parse_args()
+
+if __name__ == '__main__':
+
+ skip_val, skip_test = False, False
+ if cfg.num_train <= 100:
+ if os.path.exists(os.path.join(BASE_PATH, cfg.output_dir, 'val')):
+ skip_val = True
+ if os.path.exists(os.path.join(BASE_PATH, cfg.output_dir, 'test')):
+ skip_test = True
+ cfg.output_dir += f"_train{cfg.num_train}"
+
+
+ def get_cfs_lists(cfs_split_file):
+ ids = pd.read_csv(os.path.join("cfs_meta_data", cfs_split_file), header=None, names=['a'])
+ ids = ids['a'].values.tolist()
+ return [id + ".npy" for id in ids]
+
+ list_files_train = get_cfs_lists("train.txt")
+ list_files_val = get_cfs_lists("val.txt")
+ list_files_test = get_cfs_lists("test.txt")
+
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, "EEG", "C3-M2")))
+
+ list_files_train = sorted(list(set(list_files_train).intersection(set(sig_list))))
+ list_files_val = list(set(list_files_val).intersection(set(sig_list)))
+ list_files_test = list(set(list_files_test).intersection(set(sig_list)))
+
+ if cfg.num_train <= 100:
+ list_files_train = list_files_train[:cfg.num_train]
+
+ print("Number of records in training set:", len(list_files_train))
+ print("Number of records in validation set:", len(list_files_val))
+ print("Number of records in test set:", len(list_files_test))
+
+ print("Processing training set...")
+ preprocess(list_files_train, cfg.chn_grp, cfg.chn, split='train')
+
+ if skip_val:
+ val_output_dir = cfg.output_dir
+ val_output_dir = val_output_dir.replace(f"_train{cfg.num_train}","")
+ os.symlink(os.path.join(BASE_PATH, val_output_dir, 'val'), os.path.join(BASE_PATH, cfg.output_dir, 'val'))
+ else:
+ print("Processing evaluation set...")
+ preprocess(list_files_val, cfg.chn_grp, cfg.chn, split='val')
+
+ if skip_test:
+ test_output_dir = cfg.output_dir
+ test_output_dir = test_output_dir.replace(f"_train{cfg.num_train}","")
+ os.symlink(os.path.join(BASE_PATH, test_output_dir, 'test'), os.path.join(BASE_PATH, cfg.output_dir, 'test'))
+ else:
+ print("Processing test set...")
+ preprocess(list_files_test, cfg.chn_grp, cfg.chn, split='test')
+
+
+ # Reorganize annotations files
+ # ANN_PATH = os.path.join(BASE_PATH, 'shhs1/annotations')
+ if cfg.ann_split:
+ ANN_PATH = os.path.join(os.path.dirname(os.path.join(BASE_PATH, cfg.data_dir)), 'annotations')
+ NEW_ANN_PATH = ANN_PATH.replace('annotations', 'annotations_split')
+ os.makedirs(NEW_ANN_PATH, exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'train'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'val'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'test'), exist_ok=True)
+
+ for fname in tqdm(list_files_train):
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'train', ann_fname))
+ for fname in tqdm(list_files_val):
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'val', ann_fname))
+ for fname in tqdm(list_files_test):
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'test', ann_fname))
+
+ AH_PATH = os.path.join(os.path.dirname(os.path.join(BASE_PATH, cfg.data_dir)), 'ah_labels')
+ NEW_AH_PATH = AH_PATH.replace('ah_labels', 'ah_labels_split')
+ os.makedirs(NEW_AH_PATH, exist_ok=True)
+ os.makedirs(os.path.join(NEW_AH_PATH,'train'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_AH_PATH,'val'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_AH_PATH,'test'), exist_ok=True)
+ for fname in tqdm(list_files_train):
+ ann_fname = fname.replace('.npy', '_ah.npy')
+ shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'train', ann_fname))
+ for fname in tqdm(list_files_val):
+ ann_fname = fname.replace('.npy', '_ah.npy')
+ shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'val', ann_fname))
+ for fname in tqdm(list_files_test):
+ ann_fname = fname.replace('.npy', '_ah.npy')
+ shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'test', ann_fname))
+
+
+ for split in ['train', 'val', 'test']:
+ # create link files to respiratory channels
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP'), exist_ok=True)
+ for chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ chns = [f.split('.')[0] for f in os.listdir(os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp))]
+ for chn in chns:
+ src_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ src_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ dst_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.mmap')
+ dst_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.pickle')
+ if not os.path.exists(dst_mmap):
+ os.symlink(src_mmap, dst_mmap)
+ if not os.path.exists(dst_pickle):
+ os.symlink(src_pickle, dst_pickle)
+
diff --git a/data/cfs_process_rawdata.py b/data/cfs_process_rawdata.py
new file mode 100644
index 0000000000000000000000000000000000000000..f0ffb9798962b5400edce715e24ba1a5d48eb6f0
--- /dev/null
+++ b/data/cfs_process_rawdata.py
@@ -0,0 +1,291 @@
+import os
+import scipy
+import numpy as np
+#!pip install wfdb
+import pandas as pd
+from mne.io import concatenate_raws, read_raw_edf
+import xml.etree.ElementTree as ET
+import multiprocessing
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+# BASE_PATH = 'datasets'
+EPOCH_SEC_SIZE = 30
+
+# AIRFLOW_NAMES = ["NEW AIR", "NEWAIR", "AIRFLOW", "AIRFLOW-0", "airflow", "new A/F", "New Air", "AUX"]
+# EEG2_NAMES = ["EEG2", "EEG 2", "EEG(sec)", "EEG sec", "EEG(SEC)"]
+SELECT_CHNS = ['SaO2', 'SpO2','ECG1', 'EMG1', 'LOC', 'ROC', 'C3', 'C4', 'M1', 'M2', 'A1','A2', 'ABDO EFFORT', 'THOR EFFORT', 'AIRFLOW']
+CHN_SAVE_DICT = {
+ 'SaO2': ('SaO2','SaO2'),
+ 'SpO2': ('SaO2','SaO2'),
+ 'ECG1': ('ECG', 'ECG'),
+ 'EMG1': ('EMG', 'EMG'),
+ 'LOC': ('EOG', 'EOG-Diff'),
+ 'ROC': ('EOG', 'EOG-Diff'),
+ 'C3': ('EEG', 'C3-M2'),
+ 'C4': ('EEG', 'C4-M1'),
+ 'M1': ('EEG', 'C4-M1'),
+ 'M2': ('EEG', 'C3-M2'),
+ 'A1': ('EEG', 'A1-M2'),
+ 'A2': ('EEG', 'A2-M1'),
+ 'ABDO EFFORT': ('ABD', 'ABD'),
+ 'THOR EFFORT': ('CHEST', 'CHEST'),
+ 'AIRFLOW': ('AIRFLOW', 'AIRFLOW')
+}
+
+
+
+import argparse
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default="CFS_raw/polysomnography/edfs", help='CFS raw data location')
+parser.add_argument('--output_dir', default='cfs/signals_MAE', help='CFS processed data location')
+parser.add_argument('--annotation_dir', default='CFS_raw/polysomnography/annotations-events-profusion', help='CFS annotations location')
+parser.add_argument('--ah_dir', default='CFS_raw/polysomnography/annotations-events-nsrr', help='CFS apnea/hypopnea labels location')
+parser.add_argument('--demographics_file', default='CFS_raw/datasets/cfs-visit5-harmonized-dataset-0.7.0.csv', help='CFS demographics file location')
+
+cfg = parser.parse_args()
+
+from tqdm.auto import tqdm
+
+def process_signal(raw, select_idx, chns, fname):
+ # sampling rate from instance
+ raw_sampling_rate = int(raw.info['sfreq'])
+ raw_df = raw.to_data_frame()
+ # print(raw_df.head())
+ print(raw_df.columns)
+ for chn in chns:
+ if chn == "LOC":
+ raw_df['EOG-Diff'] = raw_df['LOC'] - raw_df['ROC']
+ raw_ch_df = raw_df['EOG-Diff']
+ elif chn == "ROC":
+ continue
+ elif chn == 'C3':
+ if 'M2' in raw_df.columns:
+ raw_df['C3-M2'] = raw_df['C3'] - raw_df['M2']
+ else:
+ raw_df['C3-M2'] = raw_df['C3'] - raw_df['A2']
+ raw_ch_df = raw_df['C3-M2']
+ elif chn == 'C4':
+ if 'M1' in raw_df.columns:
+ raw_df['C4-M1'] = raw_df['C4'] - raw_df['M1']
+ else:
+ raw_df['C4-M1'] = raw_df['C4'] - raw_df['A1']
+ raw_ch_df = raw_df['C4-M1']
+ elif chn in ['M1', 'M2', 'A1', 'A2']:
+ continue
+ elif chn in ['SaO2', 'SpO2']:
+ if 'SaO2' in raw_df.columns:
+ raw_ch_df = raw_df['SaO2']
+ else:
+ raw_ch_df = raw_df['SpO2']
+ else:
+ raw_ch_df = raw_df[chn]
+ raw_ch_df = raw_ch_df.to_frame()
+ raw_ch_df.set_index(np.arange(len(raw_ch_df)))
+
+ # Remove movement and unknown stages if any
+ raw_ch = raw_ch_df.values
+
+ # Verify that we can split into 30-s epochs
+ if len(raw_ch) % (EPOCH_SEC_SIZE * raw_sampling_rate) != 0:
+ print(f"Length of raw channel ({len(raw_ch)}) \
+ is not multiple of raw sampling rate and epoch size ({EPOCH_SEC_SIZE} * {raw_sampling_rate})")
+ return np.array([])
+
+ # get (# of epochs) = (# of datapoints) / (30sec * 100Hz)
+ n_epochs = len(raw_ch) / (EPOCH_SEC_SIZE * raw_sampling_rate)
+
+ # Get epochs and their corresponding labels
+ x = np.asarray(np.split(raw_ch, n_epochs)).astype(np.float32) # split epochs
+
+ x = x[select_idx]
+ x = x.reshape((-1, EPOCH_SEC_SIZE * raw_sampling_rate))
+
+ chn_grp, chn_rename = CHN_SAVE_DICT[chn]
+ # chn_grp = CHN_SAVE_DICT[chn][0] if chn not in AIRFLOW_NAMES else 'AIRFLOW'
+ # chn_rename = CHN_SAVE_DICT[chn][1] if chn not in AIRFLOW_NAMES else 'AIRFLOW'
+ # print(chn_grp, chn_rename)
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn_rename), exist_ok=True)
+ np.save(os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn_rename, f"{fname}.npy"), x)
+
+def process_data(args):
+
+ ann_fname, ah_fname, edf_fname, file_id = args
+ print(args)
+
+ ann_filename = os.path.basename(edf_fname).replace(".edf", "_ann.npy")
+ # if os.path.exists(os.path.join(BASE_PATH, cfg.output_dir, "annotations", ann_filename)):
+ # return
+
+ labels = []
+
+ # Read annotation and its header
+ t = ET.parse(ann_fname)
+
+ r = t.getroot()
+ faulty_File = 0
+
+ for i in range(len(r[4])):
+ lbl = int(r[4][i].text)
+ # print(lbl)
+ if lbl == 4: # make stages N3, N4 same as N3
+ labels.append(3)
+ elif lbl == 5: # Assign label 4 for REM stage
+ labels.append(4)
+ else:
+ labels.append(lbl)
+ if lbl > 5: # some files may contain labels > 5 BUT not the selected ones.
+ faulty_File = 1
+
+ if faulty_File == 1:
+ print("Faulty labels found!!")
+ return -1
+
+ labels = np.asarray(labels) # label list to npaprray
+
+ # corresponding labels
+ y = labels.astype(np.int32)
+
+ # Select on sleep periods
+ w_edge_mins = 30
+ # get index of first not WAKE
+ nw_idx = np.where(y != 0)[0]
+ # start from 30min before first WAKE
+ start_idx = nw_idx[0] - (w_edge_mins * 2)
+ # end at 30min after first WAKE
+ end_idx = nw_idx[-1] + (w_edge_mins * 2)
+ if start_idx < 0:
+ start_idx = 0
+ if end_idx >= len(y):
+ end_idx = len(y) - 1
+
+ select_idx = np.arange(start_idx, end_idx + 1)
+
+ # only selected labels
+ y = y[select_idx]
+
+ # get RawEDF instance
+ # !!!!!!!!!!!!!!!!!! 12~13 sec
+ raw = read_raw_edf(edf_fname, preload=True, stim_channel=None, verbose=None)
+ process_signal(raw, select_idx, SELECT_CHNS, os.path.basename(edf_fname).split('.')[0])
+
+ ann_dir = os.path.join(BASE_PATH, 'cfs', 'annotations')
+ os.makedirs(ann_dir, exist_ok=True)
+ np.save(os.path.join(ann_dir, ann_filename), arr=y)
+
+ tree = ET.parse(ah_fname)
+ root = tree.getroot()
+ events = root.findall('.//ScoredEvent')
+
+ total_seconds = 0
+
+ for event in events:
+ if event.find('EventConcept').text == 'Recording Start Time':
+ duration = float(event.find('Duration').text)
+ total_seconds = int(np.ceil(duration))
+ break
+
+ # 만약 Recording Start Time을 못 찾았을 경우 (예외 처리), 기존 방식대로 마지막 이벤트 시간으로 계산
+ if total_seconds == 0:
+ print("예외처리로 인한 Start time ~ End time 계산")
+ max_time = 0
+ for event in events:
+ try:
+ start = float(event.find('Start').text)
+ dur = float(event.find('Duration').text)
+ if start + dur > max_time:
+ max_time = start + dur
+ except:
+ continue
+ total_seconds = int(np.ceil(max_time))
+
+ # 2. 라벨 어레이 생성
+ ah_labels = np.zeros(total_seconds, dtype=int)
+
+
+ # 3. 호흡 이벤트 파싱 및 라벨링
+ for event in events:
+ try:
+ event_type = event.find('EventType').text
+
+ if event_type != 'Respiratory|Respiratory': continue # 호흡 이벤트가 아니면 스킵
+
+ concept = event.find('EventConcept').text
+ start = float(event.find('Start').text)
+ duration = float(event.find('Duration').text)
+
+ start_idx = int(round(start))
+ end_idx = start_idx + int(round(duration))
+
+ # 인덱스 범위 보정
+ if end_idx > total_seconds:
+ end_idx = total_seconds
+
+ # 라벨링 (Hypopnea=1, Apnea=2)
+ if 'Hypopnea' in concept:
+ mask = ah_labels[start_idx:end_idx] != 2
+ ah_labels[start_idx:end_idx][mask] = 1
+
+ elif any(x in concept for x in ['Obstructive', 'Central', 'Mixed']):
+ ah_labels[start_idx:end_idx] = 2
+
+ except AttributeError:
+ continue
+
+ ah_labels = np.reshape(ah_labels, (-1, 30))
+ ah_labels = ah_labels[select_idx]
+ assert len(ah_labels) == len(y), f"Length of ah_labels ({len(ah_labels)}) does not match length of sleep stage labels ({len(y)})"
+
+ ah_labels = np.reshape(ah_labels, (-1,))
+
+ ah_dir = os.path.join(BASE_PATH, 'cfs', 'ah_labels')
+ ah_filename = os.path.basename(edf_fname).replace(".edf", "_ah.npy")
+ os.makedirs(ah_dir, exist_ok=True)
+ np.save(os.path.join(ah_dir, ah_filename), arr=ah_labels)
+
+
+if __name__ == '__main__':
+
+ # data_dir = '/tf/00_data/kdpark/physionet_2018/physionet_rawdata'
+ file_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir))
+
+ demo = pd.read_csv(os.path.join(BASE_PATH, cfg.demographics_file))
+ def get_nsrrid(filename):
+ nsrrid = filename.split('-')[-1].replace('.edf', '')
+ return int(nsrrid)
+
+ age_filtered_df = demo[demo['nsrr_age'] > 13]
+
+ file_list = [filename for filename in file_list if get_nsrrid(filename) in age_filtered_df['nsrrid'].values]
+ print(f"Number of files after filtering by age > 13: {len(file_list)}")
+
+ filenames_edf = [filename for filename in file_list if filename.endswith('.edf')]
+ filenames_ann = [filename.replace('.edf', '-profusion.xml') for filename in filenames_edf]
+ filenames_ah = [filename.replace('.edf', '-nsrr.xml') for filename in filenames_edf]
+
+
+ edf_fnames = [os.path.join(BASE_PATH, cfg.data_dir, filename_edf) for filename_edf in filenames_edf]
+ ann_fnames = [os.path.join(BASE_PATH, cfg.annotation_dir, filename_ann) for filename_ann in filenames_ann]
+ ah_fnames = [os.path.join(BASE_PATH, cfg.ah_dir, filename_ah) for filename_ah in filenames_ah]
+
+ edf_fnames.sort() # sort edf file names list
+ ann_fnames.sort() # sort ann file names list
+ ah_fnames.sort() # sort ah file names list
+
+ input_list = zip(ann_fnames, ah_fnames, edf_fnames, range(len(ann_fnames)))
+
+
+ # redo_list = ['shhs1-203353.npy', 'shhs1-203171.npy', 'shhs1-203301.npy', 'shhs1-203011.npy', 'shhs1-203300.npy', 'shhs1-203419.npy', 'shhs1-203286.npy', 'shhs1-203375.npy','shhs1-201820.npy']
+ # input_list = [args for args in input_list if os.path.basename(args[1]).replace('.edf', '.npy') in redo_list]
+ # print(len(input_list))
+ # exit(0)
+
+ # for args in input_list:
+ # ann_fname, edf_fname, file_id = args
+ # if 'shhs1-201820' in edf_fname:
+ # process_data(args)
+ # break
+
+ with multiprocessing.Pool(8) as pool:
+ list(tqdm(pool.imap(process_data, input_list), total=len(ann_fnames)))
+
+
diff --git a/data/data_augments.py b/data/data_augments.py
new file mode 100644
index 0000000000000000000000000000000000000000..2e5f769266184b84ea86e3101da78d6f54341b62
--- /dev/null
+++ b/data/data_augments.py
@@ -0,0 +1,318 @@
+import torch
+import random
+import numpy as np
+import torch.nn.functional as F
+"""
+Functions for Video Data augmentation.
+Transforms are applied to the tensor frames of shape (frames_per_slide, height, width).
+"""
+class TensorRandomFlip:
+ """Randomly flips the tensor horizontally or vertically."""
+ def __init__(self, horizontal=True, vertical=False, p=0.5):
+ self.horizontal = horizontal
+ self.vertical = vertical
+ self.p = p
+
+ def __call__(self, frames):
+ # Get 2 random numbers for horizontal and vertical flips
+ rands = np.random.rand(2)
+ if rands[0] < self.p and self.horizontal:
+ frames = torch.flip(frames, dims=[2])
+ if rands[1] < self.p and self.vertical:
+ frames = torch.flip(frames, dims=[1])
+ return frames
+
+
+class TensorNormalize01:
+ """Normalizes the tensor into 0 and 1"""
+ def __init__(self):
+ pass
+
+ def __call__(self, frames):
+ return frames / 255.0
+
+
+class TensorNormalize:
+ """Normalizes the tensor with the given mean and std.
+ Mean and std not calculated yet.
+ """
+ def __init__(self, mean=0.5, std=0.5):
+ self.mean = mean
+ self.std = std
+
+ def __call__(self, frames):
+ # return (frames/255.0 - self.mean) / self.std
+ for i in range(len(frames.shape) - 1):
+ m = torch.tensor(self.mean, dtype=torch.float32).unsqueeze(0)
+ s = torch.tensor(self.std, dtype=torch.float32).unsqueeze(0)
+
+ return (frames - m) / s
+
+class TensorRandomScaling:
+ """Randomly scales the tensor (image) within a specified range."""
+ def __init__(self, scale_range=(0.8, 1.2)):
+ """
+ Args:
+ scale_range (tuple): A tuple (min_scale, max_scale) specifying the range for scaling.
+ """
+ assert len(scale_range) == 2, "scale_range must be a tuple with (min_scale, max_scale)."
+ assert scale_range[0] > 0 and scale_range[1] > 0, "Scaling factors must be positive."
+ self.scale_range = scale_range
+
+ def __call__(self, frames):
+ """
+ Args:
+ frames (torch.Tensor): Tensor of shape (batch_size, height, width).
+
+ Returns:
+ torch.Tensor: Scaled tensor of the same shape.
+ """
+ frames_per_slide, height, width = frames.shape
+
+ # Randomly choose a scaling factor
+ scale = random.uniform(*self.scale_range)
+
+ # New height and width after scaling
+ new_height = int(height * scale)
+ new_width = int(width * scale)
+
+ # Add channel dimension
+ frames = frames.unsqueeze(1).float()
+
+ # Resize the tensor
+ resized_frames = F.interpolate(
+ frames, # Add channel dimension: (frames_per_slide, 1, height, width)
+ size=(new_height, new_width),
+ mode='bilinear',
+ align_corners=False
+ ).squeeze(1) # Remove channel dimension: (frames_per_slide, new_height, new_width)
+
+ # Center-crop or pad to return to original size
+ if scale > 1.0: # Scale up: Center crop
+ start_y = (new_height - height) // 2
+ start_x = (new_width - width) // 2
+ scaled_frames = resized_frames[:, start_y:start_y + height, start_x:start_x + width]
+ else: # Scale down: Pad
+ pad_y = (height - new_height) // 2
+ pad_x = (width - new_width) // 2
+ padding = (pad_x, width - new_width - pad_x, pad_y, height - new_height - pad_y)
+ scaled_frames = F.pad(resized_frames, padding, mode='constant', value=0)
+
+ return scaled_frames.squeeze(1).type_as(frames)
+
+
+class TensorCenterCrop:
+ """Center crop the tensor (image) within a specified range."""
+ def __init__(self, crop_size=(112,112)):
+ """
+ Args:
+ crop_size (tuple): A tuple (height, width) specifying image size after crop.
+ """
+ assert len(crop_size) == 2, "Target size must be a tuple with (height, width)."
+ self.crop_size = crop_size
+
+ def __call__(self, frames):
+ """
+ Args:
+ frames (torch.Tensor): Tensor of shape (batch_size, height, width).
+
+ Returns:
+ torch.Tensor: Scaled tensor of the same shape.
+ """
+ frames_per_slide, height, width = frames.shape
+
+ crop_height = self.crop_size[0]
+ crop_width = self.crop_size[1]
+ # Randomly choose a scaling factor
+ start_y = (height - crop_height) // 2
+ start_x = (width - crop_width) // 2
+ cropped_frames = frames[:, start_y:start_y + crop_height, start_x:start_x + crop_width]
+
+
+ return cropped_frames.type_as(frames)
+
+class TensorRandomCrop:
+ """Center crop the tensor (image) within a specified range."""
+ def __init__(self, crop_size=(112,112)):
+ """
+ Args:
+ crop_size (tuple): A tuple (height, width) specifying image size after crop.
+ """
+ assert len(crop_size) == 2, "Target size must be a tuple with (height, width)."
+ self.crop_size = crop_size
+
+ def __call__(self, frames):
+ """
+ Args:
+ frames (torch.Tensor): Tensor of shape (batch_size, height, width).
+
+ Returns:
+ torch.Tensor: Scaled tensor of the same shape.
+ """
+ frames_per_slide, height, width = frames.shape
+
+ crop_height = self.crop_size[0]
+ crop_width = self.crop_size[1]
+
+
+ start_y = random.randint(0, height - crop_height)
+ start_x = random.randint(0, width - crop_width)
+
+ cropped_frames = frames[:, start_y:start_y + crop_height, start_x:start_x + crop_width]
+
+
+ return cropped_frames.type_as(frames)
+
+
+class TensorResize:
+ """Resizes the tensor (image)"""
+ def __init__(self, target_size=(112,112)):
+ """
+ Args:
+ target_size (tuple): A tuple (height, width) specifying image size after resize.
+ """
+ assert len(target_size) == 2, "scale_range must be a tuple with (min_scale, max_scale)."
+ self.target_size = target_size
+
+ def __call__(self, frames):
+ """
+ Args:
+ frames (torch.Tensor): Tensor of shape (batch_size, height, width).
+
+ Returns:
+ torch.Tensor: Resized tensor of the same shape.
+ """
+ frames_per_slide, height, width = frames.shape
+
+
+ # New height and width after scaling
+ new_height = self.target_size[0]
+ new_width = self.target_size[1]
+
+ # Add channel dimension
+ frames = frames.unsqueeze(1).float()
+
+ # Resize the tensor
+ resized_frames = F.interpolate(
+ frames, # Add channel dimension: (frames_per_slide, 1, height, width)
+ size=(new_height, new_width),
+ mode='bilinear',
+ align_corners=False
+ ).squeeze(1) # Remove channel dimension: (frames_per_slide, new_height, new_width)
+
+ return resized_frames.squeeze(1).type_as(frames)
+
+
+
+# TransformRotation
+# [N, H, W] shape의 video tensor를 입력으로 받아서, angle 을 범위 내에서 랜덤하게 선택하고, angle로 모든 frame을 회전시킨다.
+# torchvision.transforms.RandomRotation을 활용하면 될 것 같다.
+import torchvision.transforms.functional as TF
+
+class TensorRandomRotation:
+ """Randomly rotates the tensor (image) within a specified angle range."""
+ def __init__(self, degrees):
+ """
+ Args:
+ degrees (sequence or float or int): Range of degrees to select from. If degrees is a number instead of sequence like (min, max), the range of degrees will be (-degrees, +degrees).
+ """
+ if isinstance(degrees, (int, float)):
+ if degrees < 0:
+ raise ValueError("If degrees is a single number, it must be positive.")
+ self.degrees = (-degrees, degrees)
+ else:
+ self.degrees = degrees
+
+ def __call__(self, frames):
+ """
+ Args:
+ frames (torch.Tensor): Tensor of shape (frames_per_slide, height, width).
+
+ Returns:
+ torch.Tensor: Rotated tensor of the same shape.
+ """
+ # Randomly choose an angle
+ angle = random.uniform(self.degrees[0], self.degrees[1])
+
+ # Add channel dimension for each frame
+ frames = frames.unsqueeze(1) # Shape becomes [N, 1, H, W]
+
+ # Rotate all frames at once
+ rotated_frames = TF.rotate(frames, angle)
+
+ # Remove channel dimension
+ return rotated_frames.squeeze(1)
+
+class TensorRandomRotation90:
+ """Randomly rotates the tensor (image) within a specified angle range."""
+ def __init__(self):
+ pass
+
+ def __call__(self, frames):
+ """
+ Args:
+ frames (torch.Tensor): Tensor of shape (frames_per_slide, height, width).
+
+ Returns:
+ torch.Tensor: Rotated tensor of the same shape.
+ """
+ # Randomly choose an angle
+ p = random.uniform(0, 1)
+
+ if p < 0.5:
+ return frames
+ else:
+ p2 = random.uniform(0, 1)
+ if p2 < 0.5:
+ angle = 90
+ else:
+ angle = -90
+
+ # Add channel dimension for each frame
+ frames = frames.unsqueeze(1) # Shape becomes [N, 1, H, W]
+
+ # Rotate all frames at once
+ rotated_frames = TF.rotate(frames, angle)
+
+ # Remove channel dimension
+ return rotated_frames.squeeze(1)
+
+class TensorRandomShift:
+ """Randomly shifts the tensor (image) within a specified range."""
+ def __init__(self, shift_range=(0.1, 0.1)):
+ """
+ Args:
+ shift_range (tuple): A tuple (shift_x, shift_y) specifying the range for shifting.
+ """
+ assert len(shift_range) == 2, "shift_range must be a tuple with (shift_x, shift_y)."
+ self.shift_range = shift_range
+
+ def __call__(self, frames):
+ """
+ Args:
+ frames (torch.Tensor): Tensor of shape (batch_size, height, width).
+
+ Returns:
+ torch.Tensor: Shifted tensor of the same shape.
+ """
+ batch_size, height, width = frames.shape
+
+ # Randomly choose shift values
+ shift_x = random.uniform(-self.shift_range[0], self.shift_range[0])
+ shift_y = random.uniform(-self.shift_range[1], self.shift_range[1])
+
+ # Add channel dimension
+ frames = frames.unsqueeze(1).float()
+
+ # Create the affine transformation matrix
+ theta = torch.tensor([[1.0, 0.0, shift_x], [0.0, 1.0, shift_y]], dtype=torch.float)
+ theta = theta.unsqueeze(0).repeat(batch_size, 1, 1)
+
+ # Create the grid
+ grid = F.affine_grid(theta, frames.size(), align_corners=False)
+
+ # Apply the grid to the frames
+ shifted_frames = F.grid_sample(frames, grid, align_corners=False)
+
+ # Remove channel dimension
+ return shifted_frames.squeeze(1)
\ No newline at end of file
diff --git a/data/data_loader.py b/data/data_loader.py
new file mode 100644
index 0000000000000000000000000000000000000000..bf273c4a44ebfe7d0887cf08e21bebc79356e938
--- /dev/null
+++ b/data/data_loader.py
@@ -0,0 +1,1076 @@
+
+import h5py
+import os, sys
+import numpy as np
+import json
+import torch
+from torch.utils.data import Dataset, DataLoader, RandomSampler, SequentialSampler
+import pandas as pd
+import matplotlib.pyplot as plt
+from collections import Counter, defaultdict
+import cv2
+from multiprocessing import Manager
+import random
+from scipy.signal import find_peaks
+import librosa
+import pickle
+from tqdm import tqdm
+import math
+
+sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+from configs.global_cfg import TARGET_RESAMPLE, DATASET_PATH, LABELS_PATH, EPOCH_LEN_MAX, EPOCH_LEN_MIN
+
+CHNGRP_PICK = {
+ 'EEG': ['C3-M2','C3-A2'],
+ 'EOG': ['E1-M2','EOG-Diff','Left-A2'],
+ 'ECG': ['ECG'],
+ 'AIRFLOW': ['AIRFLOW'],
+ 'EMG': ['EMG','Chin1-Chin2'],
+ 'SaO2': ['SaO2'],
+ 'ABD': ['ABD'],
+ 'RESP': ['AIRFLOW'],
+}
+
+
+class Pretrain_Dataset(Dataset):
+ def __init__(self,
+ data_root,
+ data_list,
+ transforms=None,
+ split='train',
+ mode=None,
+ num_classes=5,
+ modalities=["EEG"],
+ sig_len_target=60,
+ ):
+
+ super().__init__()
+ """
+ Args:
+ video_path : path to the h5 file
+ labels_path : path to the labels
+ signals_path : path to the signals
+ transforms : transforms to be applied on the frames in list format
+ mode (string) : 'subject' or 'epochs' or 'sliding_window' or 'frames_sampled'
+ data : h5 file object, frames : (epochs, num_frames_per_epoch, height, width), labels : (epochs)
+
+ Returns:
+ frames : (num_frames_per_epoch, height, width) in tensor format
+ label : (1) in tensor format
+ subject_info : (subject_name, epoch) in tuple format
+ """
+ self.data_root = data_root
+ self.transforms = transforms
+ self.split = split
+ if mode is None:
+ self.mode = split
+ else:
+ self.mode = mode
+ #self.data_list = sorted(os.listdir(data_path))
+ self.data_list = data_list
+ self.total_num_epochs = 0
+ self.total_num_subjects = len(self.data_list)
+
+ self.subject_epoch_dict = {}
+ self.all_labels = []
+ self.modalities = modalities
+ self.sig_len_target = sig_len_target
+ self.datasets = []
+
+ # for dataset, subject_name in self.data_list:
+ # label_path = os.path.join(self.data_root, LABELS_PATH[dataset], f'{subject_name}_ann.npy')
+ # labels = np.load(label_path).astype(np.int64) # (num_epochs, 1)
+ # self.total_num_epochs += len(labels)
+
+ # self.total_num_epochs += subject_data['num_epochs'][()]
+ # self.subject_epoch_dict[subject_name] = (dataset, labels)
+ # self.all_labels.append(labels)
+ # self.datasets.append(dataset)
+
+ # self.datasets = set(self.datasets)
+ # What datasets are used? phy, kiss, shhs1,...
+ self.datasets = set([d[0] for d in self.data_list])
+
+ # self.all_labels = np.reshape(np.concatenate(self.all_labels, axis=0), -1)
+ # # if num_classes : 4, labels : {0,1,2,3,4}->{0,1,1,2,3}
+ # self.all_labels = np.array([self.label_change[label] for label in self.all_labels])
+
+ self.data_dict = {}
+ self.stats = {}
+ self.sig_info_dict = {}
+ self.chn_grp_map = dict()
+
+
+ for dataset in self.datasets:
+ for m in self.modalities:
+ chn_grp_dir = os.path.join(self.data_root, DATASET_PATH[dataset], m)
+ if not os.path.exists(chn_grp_dir):
+ chn_grp_dir = os.path.join(self.data_root, DATASET_PATH[dataset], self.split, m)
+ chns = [f.split('.')[0] for f in os.listdir(chn_grp_dir) if f.endswith('mmap')]
+ self.chn_grp_map[f'{dataset}/{m}'] = chns
+ # self.chn_grp_map[f'{dataset}/{m}'] = CHNGRP_MAP[f'{dataset}/{m}']
+ for chn in chns:
+ info_path = os.path.join(chn_grp_dir, f'{chn}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ self.sig_info_dict[f'{dataset}/{m}/{chn}'] = sig_info
+ sum_mu, sum_musq, cnt = 0.0, 0.0, 0.0
+ for k, v in sig_info['sig_info'].items():
+ # if k != 'data_shape':
+ # k : subject name, v : {'pos': (start, end), 'stats': {'mean': , 'meansq': , 'std': }}
+
+ if (dataset, k) in self.data_list:
+ start, end = v['pos']
+ mu, musq = v['stats']['sum'], v['stats']['sumsq']
+ sum_mu += mu
+ sum_musq += musq
+ cnt += (end - start)
+ # if end - start > EPOCH_LEN_MAX:
+ # print(f"Warning: cnt exceeded EPOCH_LEN_MAX for {dataset}, {k}. Epochs counted: {end - start}")
+ # length = max(length, end)
+
+ self.data_dict[f'{dataset}/{m}/{chn}'] = np.memmap(os.path.join(chn_grp_dir, f'{chn}.mmap'), dtype="float32",
+ mode="r",
+ shape=sig_info['data_shape'])
+ sig_len = sig_info['data_shape'][1] # Assume signal shape (sum(num_epochs), sig_len_epoch)
+ self.stats[f'{dataset}/{m}/{chn}'] = {'mean': sum_mu / cnt / sig_len if cnt > 0 else 0,
+ 'std': np.sqrt(sum_musq / cnt / sig_len - (sum_mu / cnt / sig_len) ** 2) if cnt > 0 else 1.0}
+
+ self.index_map = self.create_index()
+
+ def __len__(self):
+ return self.total_num_epochs
+ def __repr__(self):
+ return "Video_Frames_Dataset : Total Subjects : {}, Total Epochs : {}".format(self.total_num_subjects, self.total_num_epochs)
+
+ def create_index(self):
+ '''
+ Create index for the dataset
+ '''
+ index_map = []
+
+ for dataset, subject_name in self.data_list:
+ m = self.modalities[0]
+ chn = self.chn_grp_map[f'{dataset}/{m}'][0]
+ sig_info = self.sig_info_dict[f'{dataset}/{m}/{chn}']
+ num_epochs = sig_info['sig_info'][subject_name]['pos'][1] - sig_info['sig_info'][subject_name]['pos'][0]
+ # if num_epochs <= EPOCH_LEN_MIN:
+ # print(f"Warning: num_epochs less than EPOCH_LEN_MIN for {dataset}, {subject_name}. Num_epochs: {num_epochs}, skip this row")
+ # continue
+ for epoch in range(num_epochs):
+ index_map.append((dataset, subject_name, epoch))
+
+ self.total_num_epochs = len(index_map)
+
+ # for subject_name, (dataset, labels) in self.subject_epoch_dict.items():
+ # for epoch, label in enumerate(labels):
+ # index_map.append((dataset, subject_name, epoch, label))
+ return index_map
+
+ def __getitem__(self, idx, modalities_override=None):
+
+ # Return frames, label, (subject_name, epoch)
+ dataset, subject_name, epoch = self.index_map[idx]
+
+ inputs = dict()
+ modalities_to_use = modalities_override if modalities_override is not None else self.modalities
+
+
+ shift_max = self.sig_len_target - 30
+ if shift_max > 0:
+ shift = np.random.randint(0, shift_max) # (in seconds)
+ elif shift_max == 0:
+ shift = 0
+ else:
+ shift = np.random.randint(shift_max, 0) # (in seconds)
+
+ # inputs["label"] = torch.tensor(label, dtype=torch.long)
+ for i, m in enumerate(modalities_to_use):
+
+ chn_grp_dir = os.path.join(self.data_root, DATASET_PATH[dataset], m)
+ if not os.path.exists(chn_grp_dir):
+ chn_grp_dir = os.path.join(self.data_root, DATASET_PATH[dataset], self.split, m)
+ chns = self.chn_grp_map[f'{dataset}/{m}']
+
+ if self.mode == 'train':
+ chn = random.choice(chns)
+ else:
+ for chn_ in chns:
+ if chn_ in CHNGRP_PICK[m]:
+ chn = chn_
+ break
+
+ sig_info = self.sig_info_dict[f'{dataset}/{m}/{chn}']
+
+ sub_start, sub_end = sig_info['sig_info'][subject_name]['pos']
+ signals = self.data_dict[f'{dataset}/{m}/{chn}'][sub_start:sub_end]
+ ## READ MMAP DATA ##
+
+ sig_len_epoch = signals.shape[1] # Assume signal shape (num_epochs, sig_len_epoch, 1)
+ Hz = sig_len_epoch // 30 # Assuming 30 seconds per epoch
+ signals_reshape = np.reshape(signals, (-1,1))
+ start = max(0, sig_len_epoch * epoch - shift * Hz)
+ end = start + self.sig_len_target * Hz
+
+ if signals_reshape.shape[0] < end:
+ end = signals_reshape.shape[0] # Adjust end if it exceeds the length of the signal
+ start = end - self.sig_len_target * Hz # Adjust start accordingly
+
+ signal_epoch = signals_reshape[start:end]
+
+
+ if m == 'SaO2':
+ resampled = signal_epoch
+ target_signal = torch.tensor(resampled, dtype=torch.float32)
+ if Hz != TARGET_RESAMPLE:
+ target_signal = target_signal.repeat_interleave(TARGET_RESAMPLE, dim=0)
+ # target_signal = torch.clamp(target_signal, 0.0, 1.0)
+ target_signal = (torch.clamp(target_signal, 0.7, 1.0) - 0.7) / 0.3
+
+ else:
+ std = self.stats[f'{dataset}/{m}/{chn}']['std']
+ signal_epoch = signal_epoch * 1 / std
+ # if dataset in ['kiss', 'kvss']:
+ # signal_epoch = signal_epoch * 1e4
+ if Hz != TARGET_RESAMPLE:
+ resampled = librosa.resample(signal_epoch, orig_sr=sig_len_epoch//30, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ else:
+ resampled = signal_epoch
+ target_signal = torch.tensor(resampled, dtype=torch.float32)
+
+ inputs[m] = target_signal
+
+ return inputs
+
+
+
+
+
+
+class SFT_Dataset(Pretrain_Dataset):
+ def __init__(self,
+ data_root,
+ data_list,
+ ft_task='sleep_staging',
+ transforms=None,
+ split='train',
+ mode=None,
+ num_classes=5,
+ modalities=["EEG"],
+ sig_len_target=30
+ ):
+ super().__init__(data_root, data_list, transforms, split, mode, num_classes, modalities, sig_len_target)
+ self.ft_task = ft_task
+ self.num_classes = num_classes
+
+ # if self.ft_task == 'sleep_staging' and self.num_classes == 4:
+ # self.label_change = {0:0, 1:1, 2:1, 3:2, 4:3}
+
+ if self.ft_task == 'apnea_seg' and self.num_classes == 2:
+ self.label_change = {0:0, 1:1, 2:1}
+
+ self.get_labels()
+
+ def __len__(self):
+ return self.total_num_epochs
+
+
+ def get_labels(self):
+ self.all_labels = []
+ shift = (self.sig_len_target - 30) // 2
+ prev_subject_name = ''
+
+ for dataset, subject_name, epoch in tqdm(self.index_map):
+ if not subject_name == prev_subject_name:
+ suffix = 'ah' if self.ft_task == 'apnea_seg' else 'ann'
+ label_dir = os.path.join(self.data_root, LABELS_PATH[self.ft_task][dataset])
+ label_path = os.path.join(label_dir, f'{subject_name}_{suffix}.npy')
+ if not os.path.exists(label_path):
+ label_path = os.path.join(label_dir, self.split, f'{subject_name}_{suffix}.npy')
+ labels = np.load(label_path).astype(np.int64) # (num_epochs, 1)
+
+ if self.ft_task == 'apnea_seg':
+ labels = labels.reshape(-1,)
+ # start = epoch*30 - shift
+ # end = start + self.sig_len_target
+ # if end > len(labels):
+ # end = len(labels)
+ # labels_slice = np.concatenate([labels[start:], labels[-shift:]], axis=0)
+ # elif start < 0:
+ # labels_slice = np.concatenate([labels[:-start], labels[:end]], axis=0)
+ # else:
+ # labels_slice = labels[start:end]
+ labels_slice = labels[epoch*30 : (epoch+1)*30]
+
+ if self.num_classes == 2:
+ labels_slice = np.array([self.label_change[lbl] for lbl in labels_slice])
+
+ self.all_labels.append(labels_slice)
+
+ else:
+ self.all_labels.append(labels[epoch])
+ prev_subject_name = subject_name
+
+ def get_all_labels(self):
+ return self.all_labels
+
+
+ def __getitem__(self, idx, modalities_override=None):
+ # Return frames, label, (subject_name, epoch)
+
+
+ dataset, subject_name, epoch = self.index_map[idx]
+ label = self.all_labels[idx]
+
+ inputs = dict()
+ modalities_to_use = modalities_override if modalities_override is not None else self.modalities
+
+
+
+ shift = (self.sig_len_target - 30) // 2
+
+ for m in modalities_to_use:
+ # chn_grp_dir = os.path.join(self.data_root, DATASET_PATH[dataset], m)
+ # if not os.path.exists(chn_grp_dir):
+ # chn_grp_dir = os.path.join(self.data_root, DATASET_PATH[dataset], self.mode, m)
+ chns = self.chn_grp_map[f'{dataset}/{m}']
+ if self.mode == 'train':
+ chn = random.choice(chns)
+ else:
+ for chn_ in chns:
+ if chn_ in CHNGRP_PICK[m]:
+ chn = chn_
+ break
+
+ # signals = np.load(os.path.join(self.signals_path, m, chn, f'{subject_name}.npy')) # (num_epochs, sampling rate * duration, # channles)
+ ## READ MMAP DATA ##
+ signals = self.data_dict[f'{dataset}/{m}/{chn}']
+ # info_path = os.path.join(self.data_root, DATASET_PATH[dataset], m, f'{chn}.pickle')
+ sig_info = self.sig_info_dict[f'{dataset}/{m}/{chn}']
+
+ sub_start, sub_end = sig_info['sig_info'][subject_name]['pos']
+ sub_epochs = sub_end - sub_start
+ ## READ MMAP DATA ##
+
+
+ sig_len_epoch = signals.shape[1] # Assume signal shape (num_epochs, sig_len_epoch, 1)
+ Hz = sig_len_epoch // 30 # Assuming 30 seconds per epoch
+
+ signals = signals[sub_start:sub_end]
+ signals_reshape = np.reshape(signals, (-1,1))
+ start = max(0, sig_len_epoch * epoch - shift * Hz)
+ end = start + self.sig_len_target * Hz
+
+ if signals_reshape.shape[0] < end:
+ end = signals_reshape.shape[0] # Adjust end if it exceeds the length of the signal
+ start = end - self.sig_len_target * Hz # Adjust start accordingly
+
+ signal_epoch = signals_reshape[start:end]
+
+ if m == 'SaO2':
+ resampled = signal_epoch
+ target_signal = torch.tensor(resampled, dtype=torch.float32)
+ if Hz != TARGET_RESAMPLE:
+ target_signal = target_signal.repeat_interleave(TARGET_RESAMPLE, dim=0)
+ # target_signal = torch.clamp(target_signal, 0.0, 1.0)
+ target_signal = (torch.clamp(target_signal, 0.7, 1.0) - 0.7) / 0.3
+
+ else:
+ # if dataset in ['kiss', 'kvss']:
+ # signal_epoch = signal_epoch * 1e4
+ std = self.stats[f'{dataset}/{m}/{chn}']['std']
+ signal_epoch = signal_epoch * 1 / std
+ if Hz != TARGET_RESAMPLE:
+ resampled = librosa.resample(signal_epoch, orig_sr=sig_len_epoch//30, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ else:
+ resampled = signal_epoch
+ target_signal = torch.tensor(resampled, dtype=torch.float32)
+
+
+ inputs[m] = target_signal
+
+ # Return an empty boolean tensor for mask so default_collate can batch samples.
+ # Downstream training code treats an empty tensor as 'no mask'.
+ return inputs, torch.tensor(label, dtype=torch.long), torch.tensor([], dtype=torch.bool), torch.tensor([], dtype=torch.bool), subject_name # No mask
+
+
+class Seq_Dataset(Pretrain_Dataset):
+ def __init__(self,
+ data_root,
+ data_list,
+ transforms=None,
+ split='train',
+ mode=None,
+ num_classes=5,
+ modalities=["EEG"],
+ sig_len_target=30,
+ pretrain_macro=False,
+ seq_truncate=False,
+ ft_task='sleep_staging',
+ dual_views=False,
+ ):
+ super().__init__(data_root, data_list, transforms, split, mode, num_classes, modalities, sig_len_target)
+
+
+ self.num_classes = num_classes
+ self.get_demographics()
+ self.epoch_accum = 0
+ self.seq_truncate = seq_truncate
+ self.max_num_epochs = EPOCH_LEN_MAX if seq_truncate else 1440 # Will be updated in create_index_full if seq_truncate is False
+ self.min_num_epochs = EPOCH_LEN_MIN if seq_truncate else 0
+ self.pretrain_macro = pretrain_macro
+ self.dual_views = dual_views
+ self.create_index_full()
+ print("Max length:", self.max_num_epochs)
+
+ if not self.pretrain_macro:
+ self.ft_task = ft_task
+ self.get_labels()
+
+ def reshuffle_full_night_index(self):
+ """
+ Reshuffle the full night index. Call this at the start of each epoch
+ to get a different ordering of samples.
+ """
+ self.epoch_accum += 1
+ self.create_index_full()
+ if not self.pretrain_macro:
+ self.get_labels()
+
+ def create_index_full(self):
+ '''
+ Create index for the dataset
+ '''
+
+ index_map, len_map, ages, bmis = [], [], [], []
+
+ for dataset, subject_name in self.data_list:
+ index_map_subject = []
+ m = self.modalities[0]
+ chn = self.chn_grp_map[f'{dataset}/{m}'][0]
+ sig_info = self.sig_info_dict[f'{dataset}/{m}/{chn}']
+ num_epochs = sig_info['sig_info'][subject_name]['pos'][1] - sig_info['sig_info'][subject_name]['pos'][0]
+ if not self.seq_truncate:
+ self.max_num_epochs = max(num_epochs, self.max_num_epochs)
+
+
+ if num_epochs <= self.min_num_epochs:
+ print(f"Warning: Sequence length less than EPOCH_LEN_MIN for {dataset}, {subject_name}. \
+ Num_epochs: {num_epochs}, skip this subject")
+ continue
+ # if num_epochs > self.max_num_epochs:
+ # print(f"Warning: No wake length exceeded EPOCH_LEN_MAX for {dataset}, {subject_name}.")
+ # if 'AHI' in self.demographics[f'{dataset}/{subject_name}'] and self.demographics[f'{dataset}/{subject_name}']['AHI'] > 15:
+ # continue
+ if not self.pretrain_macro:
+ index_map.append((dataset, subject_name))
+ continue
+
+ age = self.demographics[f'{dataset}/{subject_name}'].get('Age', None)
+ sex = self.demographics[f'{dataset}/{subject_name}'].get('Sex', None)
+ bmi = self.demographics[f'{dataset}/{subject_name}'].get('BMI', None)
+ # ahi = self.demographics[f'{dataset}/{subject_name}'].get('AHI', None)
+
+ if age is None or math.isnan(age):
+ print (f"Warning: Age is None for {dataset}, {subject_name}. Skip this subject")
+ continue
+ if sex is None:
+ print (f"Warning: Sex is None for {dataset}, {subject_name}. Skip this subject")
+ continue
+
+ if bmi is None:
+ print (f"Warning: BMI is None or NaN for {dataset}, {subject_name}. Skip this subject")
+ continue
+
+ if not isinstance(bmi, (int, float)):
+ try:
+ bmi = float(bmi)
+ except:
+ print (f"Warning: BMI is not a number for {dataset}, {subject_name}. Skip this subject")
+ continue
+ if math.isnan(bmi):
+ print (f"Warning: BMI is NaN for {dataset}, {subject_name}. Skip this subject")
+ continue
+
+
+
+ ages.append(age)
+ bmis.append(bmi)
+ len_map.append(num_epochs)
+ index_map.append((dataset, subject_name))
+
+ # For supervised finetuning, no indexing required.
+ if not self.pretrain_macro:
+ self.index_map = index_map
+ self.total_subjects = len(index_map)
+ return
+
+ zipped_pairs = zip(index_map, len_map, ages, bmis)
+ if self.epoch_accum % 2 == 0:
+ # Sort by bmi ascending
+ sorted_pairs = sorted(zipped_pairs, key=lambda x: x[3])
+ else:
+ # Sort by age ascending
+ sorted_pairs = sorted(zipped_pairs, key=lambda x: x[2])
+ index_map = [pair[0] for pair in sorted_pairs] # Sorted by age
+ len_map = [pair[1] for pair in sorted_pairs] # Sorted by age
+
+ self.total_subjects = len(index_map)
+
+ num_age_grp = 4
+
+ age_grp_size = self.total_subjects // num_age_grp
+ age_groups = []
+ residuals = []
+ for i in range(num_age_grp):
+ start_idx = i * age_grp_size
+ # if i == num_age_grp - 1:
+ # end_idx = self.total_subjects
+ # else:
+ end_idx = (i + 1) * age_grp_size
+ index_map_grp = index_map[start_idx:end_idx]
+ len_map_grp = len_map[start_idx:end_idx]
+ if self.epoch_accum % 4 == 1 or self.epoch_accum % 4 == 2:
+ # Sort by length ascending
+ index_map_grp_sorted = [pair[0] for pair in sorted(zip(index_map_grp, len_map_grp), key=lambda x: x[1])]
+
+ elif self.epoch_accum % 4 == 0 or self.epoch_accum % 4 == 3:
+ # Sort by length descending
+ index_map_grp_sorted = [pair[0] for pair in sorted(zip(index_map_grp, len_map_grp), key=lambda x: x[1], reverse=True)]
+
+ # Group by 4 subjects
+ len_sub4 = len(index_map_grp_sorted) // 4
+ sub4 = [index_map_grp_sorted[4*k:4*(k+1)] for k in range(len_sub4)]
+ age_groups.append(sub4)
+ residuals.extend(index_map_grp_sorted[4*len_sub4:])
+
+ if i == num_age_grp - 1 and end_idx < self.total_subjects:
+ residuals.extend(index_map[end_idx:])
+
+
+
+ final_index_map = []
+ for items in zip(*age_groups):
+ flattend = [item for sublist in items for item in sublist]
+ final_index_map.extend(flattend)
+
+ # if not self.pretrain_macro:
+ final_index_map.extend(residuals)
+ assert len(final_index_map) == self.total_subjects, f"The length of final_index_map does not match total_subjects, {len(final_index_map)} vs {self.total_subjects}"
+
+ # if self.total_subjects % num_age_grp != 0:
+ # final_index_map.extend(age_groups[-1][-(self.total_subjects % num_age_grp):])
+ # assert len(final_index_map) == self.total_subjects, f"The length of final_index_map does not match total_subjects, {len(final_index_map)} vs {self.total_subjects}"
+
+ self.index_map = final_index_map
+ self.total_subjects = len(self.index_map)
+
+
+ def __len__(self):
+ return self.total_subjects
+
+ def get_demographics(self):
+ self.demographics = dict()
+ dataset_list = list(set([d[0] for d in self.data_list]))
+ for dataset in tqdm(dataset_list):
+ if 'isruc' in dataset or 'cfs' in dataset or 'sof' in dataset:
+ # Skip isrucs demographics for now
+ continue
+ elif dataset in ['phy-tr','phy-te']:
+ demo_path = os.path.join(self.data_root, 'demographics', 'phy_demographics.pkl')
+ elif dataset in ['mros1','mros1-val','mros1-te']:
+ demo_path = os.path.join(self.data_root, 'demographics', 'mros1_demographics.pkl')
+ elif dataset in ['mros2','mros2-val','mros2-te']:
+ demo_path = os.path.join(self.data_root, 'demographics', 'mros2_demographics.pkl')
+ elif dataset in ['mesa','mesa-val','mesa-te']:
+ demo_path = os.path.join(self.data_root, 'demographics', 'mesa_demographics.pkl')
+ else:
+ demo_path = os.path.join(self.data_root, 'demographics', f'{dataset}_demographics.pkl')
+
+ with open(demo_path, 'rb') as f:
+ demo_data = pickle.load(f)
+ for pid, demo in demo_data.items():
+ if dataset == 'shhs1' or dataset == 'shhs2':
+ pid = f'{dataset}-{pid}'
+ elif dataset in ['mros1','mros1-val','mros1-te']:
+ pid = f'mros-visit1-{pid.lower()}'
+ elif dataset in ['mros2','mros2-val','mros2-te']:
+ pid = f'mros-visit2-{pid.lower()}'
+ elif dataset in ['mesa','mesa-val','mesa-te']:
+ pid = f"mesa-sleep-{pid:04d}"
+ elif dataset == 'cfs':
+ pid = f'{dataset}-visit5-{pid}'
+ self.demographics[f'{dataset}/{pid}'] = demo
+
+ def get_labels(self):
+ self.all_labels = []
+ shift = (self.sig_len_target - 30) // 2
+ prev_subject_name = ''
+
+ if self.ft_task == 'diagnosis':
+ # Disease prediction
+ events_csv = 'datasets/#_SHHS/datasets/shhs-cvd-summary-dataset-0.20.0.csv'
+ event_df = pd.read_csv(events_csv)
+
+ is_event_cols = ['angina','cvd_death','chf','chd_death','mi','stroke']
+ event_time_cols = ['ang_date','cvd_dthdt','chf_date','chd_dthdt','mi_date','stk_date']
+
+ # 1. 데이터 병합 (censdate 포함)
+ # 날짜 보정을 위해 'censdate' 열을 함께 가져옵니다.
+ df_filtered = pd.concat([
+ event_df[['nsrrid', 'censdate']],
+ event_df[is_event_cols],
+ event_df[event_time_cols]
+ ], axis=1).set_index('nsrrid')
+
+ # 2. 정합성 검사 및 보정
+ for event_col, time_col in zip(is_event_cols, event_time_cols):
+ # 조건 A: 이벤트가 1 이상인데 날짜가 NaN이거나 0인 경우
+ # 이 경우 이벤트를 0으로 변경하고 날짜는 censdate를 참조하게 함
+ invalid_mask = (df_filtered[event_col] >= 1) & (df_filtered[time_col].isna() | (df_filtered[time_col] == 0))
+ # invalid_mask = (df_filtered[event_col] >= 1) & ((df_filtered[time_col] == 0))
+ df_filtered.loc[invalid_mask, event_col] = 0
+
+ # 조건 B: 날짜열의 값이 없거나(NaN) 0인 모든 경우에 대해 'censdate' 값으로 채움
+ # fillna를 사용하여 NaN을 채우고, 0인 값은 replace를 통해 처리할 수 있습니다.
+ df_filtered[time_col] = df_filtered[time_col].fillna(df_filtered['censdate'])
+ df_filtered.loc[df_filtered[time_col] == 0, time_col] = df_filtered['censdate']
+
+ # 3. 최종 결측치 처리 (censdate마저 없는 경우를 대비한 방어 코드)
+ df_filtered[is_event_cols] = df_filtered[is_event_cols].fillna(0)
+ # 만약 censdate도 NaN이라서 여전히 결측치라면 1e6으로 최종 처리
+ df_filtered[event_time_cols] = df_filtered[event_time_cols].fillna(365*6)
+
+ # df_filtered[is_event_cols] = np.minimum(df_filtered[is_event_cols], 1)
+
+ study_ids = set(df_filtered.index)
+
+ # labels_dict = {}
+ # for study_id in study_ids:
+ # is_event_row = list(df_filtered.loc[study_id][is_event_cols])
+ # event_time_row = list(df_filtered.loc[study_id][event_time_cols])
+ # labels_dict[str(study_id)] = {
+ # "is_event": is_event_row,
+ # "event_time": event_time_row
+ # }
+
+ labels_dict = {}
+ for study_id in study_ids:
+ row = df_filtered.loc[study_id]
+
+ # 중복 ID가 있을 경우를 대비해 첫 번째 행 선택
+ if isinstance(row, pd.DataFrame):
+ row = row.iloc[0]
+
+ is_event_row = [int(val) for val in row[is_event_cols]]
+ event_time_row = [float(val) for val in row[event_time_cols]]
+
+ labels_dict[str(study_id)] = {
+ "is_event": is_event_row,
+ "event_time": event_time_row
+ }
+ # # Disease prediction
+ # events_csv = 'datasets/#_SHHS/datasets/shhs-cvd-summary-dataset-0.20.0.csv'
+ # event_df = pd.read_csv(events_csv) # []'nsrrid', 'event', 'stk_type', 'fstk_type', 'event_dt', 'pptidr', 'visitnumber', 'gender', 'race', 'age_s1']
+
+ # is_event_cols = ['angina','cvd_death','chf','chd_death','mi','stroke']
+ # event_time_cols = ['ang_date','cvd_dthdt','chf_date','chd_dthdt','mi_date','stk_date']
+
+ # # 1. 데이터 병합 (결측치 처리는 뒤에서 정밀하게 수행하기 위해 원본을 먼저 활용)
+ # df_filtered = pd.concat([
+ # event_df[['nsrrid']],
+ # event_df[is_event_cols],
+ # event_df[event_time_cols]
+ # ], axis=1).set_index('nsrrid')
+
+ # # 2. 정합성 검사 및 보정
+ # # zip을 사용하여 이벤트 열과 날짜 열을 1:1로 매칭하여 처리합니다.
+ # for event_col, time_col in zip(is_event_cols, event_time_cols):
+ # # 조건: 이벤트가 1 이상인데 날짜가 NaN인 경우를 찾아 이벤트를 0으로 변경
+ # invalid_mask = (df_filtered[event_col] >= 1) & (df_filtered[time_col].isna() | df_filtered[time_col] == 0)
+ # df_filtered.loc[invalid_mask, event_col] = 0
+
+ # # 3. 최종 결측치 처리
+ # # 보정 후, 이벤트 열은 0으로, 날짜 열은 요청하신 대로 1e6(매우 큰 값)으로 채웁니다.
+ # df_filtered[is_event_cols] = df_filtered[is_event_cols].fillna(0)
+ # df_filtered[event_time_cols] = df_filtered[event_time_cols].fillna(1e6)
+
+ # study_ids = set(df_filtered.index)
+
+ # labels_dict = {}
+ # for study_id in study_ids:
+ # is_event_row = list(df_filtered.loc[study_id][is_event_cols])
+ # event_time_row = list(df_filtered.loc[study_id][event_time_cols])
+ # labels_dict[str(study_id)] = {
+ # "is_event": is_event_row,
+ # "event_time": event_time_row
+ # }
+
+ for sub_info in tqdm(self.index_map):
+
+ dataset, subject = sub_info
+
+ if self.ft_task == 'diagnosis':
+ if not dataset == 'shhs1':
+ raise NotImplementedError("Diagnosis task is only implemented for shhs1 dataset.")
+ study_id = subject.split('-')[1]
+ self.all_labels.append(labels_dict[study_id])
+
+ else:
+ suffix = 'ah' if self.ft_task == 'apnea_seg' else 'ann'
+ if self.ft_task in ['age','sex','ahi']:
+ ft_task = 'sleep_staging'
+ else:
+ ft_task = self.ft_task
+ label_dir = os.path.join(self.data_root, LABELS_PATH[ft_task][dataset])
+ label_path = os.path.join(label_dir, f'{subject}_{suffix}.npy')
+ if not os.path.exists(label_path):
+ label_path = os.path.join(label_dir, self.split, f'{subject}_{suffix}.npy')
+ labels = np.load(label_path).astype(np.int64) # (num_epochs, 1)
+ labels = labels.reshape(-1,)
+ self.all_labels.append(labels)
+
+
+ def get_all_labels(self):
+ return self.all_labels
+
+
+ def __getitem__(self, idx, modalities_override=None):
+ # Return frames, label, (subject_name, epoch)
+
+ dataset, subject_name = self.index_map[idx]
+
+ inputs = dict()
+ demo = dict()
+ modalities_to_use = modalities_override if modalities_override is not None else self.modalities
+
+ if self.pretrain_macro:
+ age = self.demographics[f'{dataset}/{subject_name}']['Age']
+ sex = self.demographics[f'{dataset}/{subject_name}']['Sex']
+ bmi = self.demographics[f'{dataset}/{subject_name}']['BMI']
+
+ demo['age'] = float(age)
+ demo['sex'] = sex
+ demo['bmi'] = float(bmi)
+
+ if not self.pretrain_macro:
+ label = self.all_labels[idx]
+ demo_key = f'{dataset}/{subject_name}'
+ age, bmi, ahi, sex = None, None, None, None
+ if demo_key in self.demographics:
+ demo_values = self.demographics[demo_key]
+ age = demo_values.get('Age', None)
+ sex = demo_values.get('Sex', None)
+ bmi = demo_values.get('BMI', None)
+ ahi = demo_values.get('AHI', None)
+
+ if age is None or math.isnan(age):
+ age = -1
+ if bmi is None or math.isnan(bmi):
+ bmi = -1
+ if ahi is None or math.isnan(ahi):
+ ahi = -1
+ if sex is None:
+ sex = -1
+
+ demo['age'] = float(age)
+ demo['sex'] = sex
+ demo['bmi'] = float(bmi)
+ demo['ahi'] = float(ahi)
+
+ if self.ft_task == 'diagnosis':
+ event_time = label["event_time"]
+ is_event = label["is_event"]
+ event_time = torch.tensor(event_time, dtype=torch.float32)
+ is_event = torch.tensor(is_event)
+
+ if self.dual_views:
+ shift_epochs_1 = np.random.randint(0, 60)
+ shift_fwd_1 = np.random.rand() > 0.5
+ shift_epochs_2 = np.random.randint(0, 60)
+ shift_fwd_2 = np.random.rand() > 0.5
+
+ zero_modalities = np.random.choice(len(modalities_to_use), 6, replace=False)
+ k1 = np.random.randint(6)
+ # k2 = np.random.randint(3)
+ zero_modalities_1 = zero_modalities[:k1]
+ zero_modalities_2 = zero_modalities[k1:]
+
+ inputs_view1 = {}
+ inputs_view2 = {}
+
+ def shift_signals(signals, shift_epochs, shift_fwd):
+ if shift_epochs == 0:
+ return signals
+ if shift_fwd:
+ return np.concatenate([signals[shift_epochs:], signals[-shift_epochs:]])
+ return np.concatenate([signals[:shift_epochs], signals[:-shift_epochs]])
+
+ def pad_signals(signals, sub_epochs):
+ if sub_epochs >= self.max_num_epochs:
+ return signals[:self.max_num_epochs]
+ pad_len = self.max_num_epochs - sub_epochs
+ padding = np.zeros_like(signals[-1:]).repeat(pad_len, axis=0)
+ return np.concatenate([signals, padding], axis=0)
+
+ for i, m in enumerate(modalities_to_use):
+
+ chns = self.chn_grp_map[f'{dataset}/{m}']
+ if self.mode == 'train':
+ chn = random.choice(chns)
+ else:
+ for chn_ in chns:
+ if chn_ in CHNGRP_PICK[m]:
+ chn = chn_
+ break
+
+ ## READ MMAP DATA ##
+ signals = self.data_dict[f'{dataset}/{m}/{chn}']
+ sig_info = self.sig_info_dict[f'{dataset}/{m}/{chn}']
+
+ sub_start, sub_end = sig_info['sig_info'][subject_name]['pos']
+ sub_epochs = sub_end - sub_start
+ ## READ MMAP DATA ##
+
+ sig_len_epoch = signals.shape[1] # Assume signal shape (num_epochs, sig_len_epoch, 1)
+ Hz = sig_len_epoch // 30 # Assuming 30 seconds per epoch
+
+ signals = signals[sub_start:sub_end]
+
+ if i == 0:
+ if sub_epochs >= self.max_num_epochs:
+ if not self.pretrain_macro and self.ft_task in ['age','sex','ahi','sleep_staging']:
+ label = label[:self.max_num_epochs]
+ mask = torch.zeros(self.max_num_epochs, dtype=torch.bool)
+ mask[:self.max_num_epochs] = True
+ else:
+ if not self.pretrain_macro and self.ft_task in ['age','sex','ahi','sleep_staging']:
+ padded_label = np.concatenate([label, label[-1:].repeat(self.max_num_epochs - sub_epochs, axis=0)], axis=0)
+ label = padded_label
+ mask = torch.zeros(self.max_num_epochs, dtype=torch.bool)
+ mask[:sub_epochs] = True
+
+ def to_target(signal_epochs):
+ signals_reshape = np.reshape(signal_epochs, (-1,1))
+ if m == 'SaO2':
+ resampled = signals_reshape
+ target_signal = torch.tensor(resampled, dtype=torch.float32)
+ if Hz != TARGET_RESAMPLE:
+ target_signal = target_signal.repeat_interleave(TARGET_RESAMPLE, dim=0)
+ target_signal = (torch.clamp(target_signal, 0.7, 1.0) - 0.7) / 0.3
+ else:
+ std = self.stats[f'{dataset}/{m}/{chn}']['std']
+ signals_reshape = signals_reshape * 1 / std
+ if Hz != TARGET_RESAMPLE:
+ resampled = librosa.resample(signals_reshape, orig_sr=sig_len_epoch//30, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ else:
+ resampled = signals_reshape
+ target_signal = torch.tensor(resampled, dtype=torch.float32)
+ return target_signal
+
+ if self.dual_views:
+ signals_v1 = shift_signals(signals, shift_epochs_1, shift_fwd_1)
+ signals_v2 = shift_signals(signals, shift_epochs_2, shift_fwd_2)
+
+
+ signals_v1 = np.zeros_like(signals_v1) if i in zero_modalities_1 else signals_v1
+ signals_v2 = np.zeros_like(signals_v2) if i in zero_modalities_2 else signals_v2
+
+ signals_v1 = pad_signals(signals_v1, sub_epochs)
+ signals_v2 = pad_signals(signals_v2, sub_epochs)
+
+ inputs_view1[m] = to_target(signals_v1)
+ inputs_view2[m] = to_target(signals_v2)
+ else:
+ signals = pad_signals(signals, sub_epochs)
+ inputs[m] = to_target(signals)
+
+ if self.dual_views:
+ inputs_out = (inputs_view1, inputs_view2)
+ else:
+ inputs_out = inputs
+
+ if self.pretrain_macro:
+ return inputs_out, torch.tensor([], dtype=torch.long), mask, demo, subject_name
+ elif self.ft_task == 'diagnosis':
+ return inputs_out, is_event, event_time, mask, demo, subject_name
+ else:
+ return inputs_out, torch.tensor(label, dtype=torch.long), mask, demo, subject_name
+
+
+
+
+
+def collate_fn_random_modalities(batch_indices, dataset):
+ # Randomly select two modalities for this batch
+ all_modalities = dataset.modalities
+ selected_modalities = sorted(random.sample(all_modalities, 2))
+ # selected_modalities = all_modalities # Use all modalities for now
+ # Fetch data for each index with the selected modalities
+ batch = [dataset.__getitem__(idx, modalities_override=selected_modalities) for idx in batch_indices]
+ # inputs = zip(*batch)
+ inputs = batch
+ inputs_ = {m: [] for m in selected_modalities}
+ for m in selected_modalities:
+ for item in inputs:
+ inputs_[m].append(item[m])
+ inputs = {m: torch.stack(inputs_[m], dim=0) for m in selected_modalities}
+ return inputs
+
+class Pretrain_Dataset_Wrapper(Dataset):
+ def __init__(self, dataset):
+ self.dataset = dataset
+ def __len__(self):
+ return len(self.dataset)
+ def __getitem__(self, idx):
+ return idx # Just return the index
+
+# build loader with sample
+def build_loader(data_root,
+ data_list=None,
+ batch_size=1,
+ shuffle=True,
+ transforms=None,
+ sampler='weighted',
+ num_workers=8,
+ proportion = 1.0,
+ split='train',
+ mode=None,
+ num_classes=5,
+ modalities=["EEG"],
+ pretrain_micro=False,
+ pretrain_macro=False,
+ sig_len_target=30,
+ ft_task='sleep_staging',
+ full_night=False,
+ seq_truncate=False,
+ dual_views=False,
+ ):
+ """_summary_
+
+ Args:
+ data_path (_type_): _description_
+ mode (str, optional): _description_. Defaults to 'epochs'.
+ batch_size (int, optional): _description_. Defaults to 1.
+ shuffle (bool, optional): _description_. Defaults to True.
+ transforms (_type_, optional): _description_. Defaults to None.
+ sampler (str, optional): _description_. Defaults to 'weighted'.
+ train (bool, optional): _description_. Defaults to True.
+
+ Returns:
+ _type_: _description_
+ """
+ if pretrain_micro:
+ # Create dataset
+ print("Using Pretrain Dataset")
+ dataset = Pretrain_Dataset(data_root,
+ data_list,
+ transforms,
+ mode=mode,
+ split=split,
+ num_classes=num_classes,
+ modalities=modalities,
+ sig_len_target=sig_len_target
+ )
+
+ print("Dataset created")
+ loader = DataLoader(dataset,
+ batch_size=batch_size,
+ num_workers=num_workers,
+ shuffle=shuffle,
+ # collate_fn=lambda batch_indices: collate_fn_random_modalities(batch_indices, dataset),
+ prefetch_factor=2)
+
+ else:
+ if full_night:
+ print("Using sequence dataset")
+ dataset = Seq_Dataset(data_root,
+ data_list,
+ transforms=transforms,
+ split=split,
+ mode=mode,
+ num_classes=num_classes,
+ modalities=modalities,
+ sig_len_target=sig_len_target,
+ ft_task=ft_task,
+ pretrain_macro=pretrain_macro,
+ seq_truncate=seq_truncate,
+ dual_views=dual_views
+ )
+ else:
+ print("Using Epoch-level Fine-tuning Dataset. Task:", ft_task)
+ dataset = SFT_Dataset(data_root,
+ data_list,
+ ft_task=ft_task,
+ transforms=transforms,
+ split=split,
+ mode=mode,
+ num_classes=num_classes,
+ modalities=modalities,
+ sig_len_target=sig_len_target
+ )
+
+ print("Dataset created")
+
+ if sampler=='weighted':
+ # Balanced Sampler
+ labels = dataset.get_all_labels()
+
+ # class_count = Counter(labels)
+ class_count = np.zeros(num_classes, dtype=np.int64)
+ unique, counts = np.unique(labels, return_counts=True)
+ for i, cnt in zip(unique, counts):
+ class_count[i] += cnt
+ print("Class count:", class_count)
+
+ class_weights = 1.0 / torch.tensor(class_count, dtype=torch.float)
+ # Length : min(class_count)
+ sample_weights = [class_weights[i] for i in labels]
+ sample_weights = torch.tensor(sample_weights, dtype=torch.float)
+ print("Class weights:", sample_weights)
+ # Length : min(class_count)
+ sampler = torch.utils.data.sampler.WeightedRandomSampler(sample_weights, int(len(labels)*proportion), replacement=True)
+ loader = DataLoader(dataset, batch_size=batch_size, sampler=sampler, num_workers=num_workers, prefetch_factor=2)
+
+ elif sampler == 'random':
+ # print("Random sampler, num_samples : ", int(len(dataset)*proportion), "Length dataset", len(dataset))
+ # Proportion does not look effective....
+ # sampler = RandomSampler(dataset, replacement=True, num_samples=int(len(dataset)*proportion))
+ labels = dataset.get_all_labels()
+
+ class_count = np.zeros(num_classes, dtype=np.int64)
+ unique, counts = np.unique(labels, return_counts=True)
+ for i, cnt in zip(unique, counts):
+ class_count[i] += cnt
+ print("Class count:", class_count)
+
+ # class_weights = torch.tensor(class_count, dtype=torch.float)
+ class_weights = torch.ones(num_classes, dtype=torch.float) / num_classes
+ sample_weights = [1.0 for i in labels]
+ sampler = torch.utils.data.sampler.WeightedRandomSampler(sample_weights, int(len(labels)*proportion), replacement=True)
+ # loader = DataLoader(dataset, batch_size=batch_size, sampler=sampler, num_workers=num_workers, prefetch_factor=2)
+ loader = DataLoader(dataset,
+ batch_size=batch_size,
+ sampler=sampler,
+ num_workers=num_workers,
+ collate_fn=lambda batch_indices: collate_fn_random_modalities(batch_indices, dataset),
+ prefetch_factor=2)
+ elif sampler == 'distributed':
+ from torch.utils.data import DistributedSampler
+ # 2. Manually create the DistributedSampler with shuffle=False
+ sampler = DistributedSampler(
+ dataset,
+ shuffle=shuffle # <--- The key override
+ )
+ loader = DataLoader(dataset, batch_size=batch_size, sampler=sampler, num_workers=num_workers, prefetch_factor=2, drop_last=True)
+
+ elif sampler is None:
+ loader = DataLoader(dataset, batch_size=batch_size, shuffle=shuffle, num_workers=num_workers, prefetch_factor=2)
+ else:
+ assert False, "Not Implemented loader"
+ return loader
+
+
+
+
diff --git a/data/data_utils.py b/data/data_utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..c00f9c2d7d444fd275a84fc2a2f729d5f34212a5
--- /dev/null
+++ b/data/data_utils.py
@@ -0,0 +1,68 @@
+import os
+import numpy as np
+from scipy.signal import butter, sosfilt, lfilter, iirnotch
+from scipy.signal import find_peaks
+
+def butter_bandpass(lowcut, highcut, fs, order=8):
+ low = lowcut
+ high = highcut
+ sos = butter(order, [low, high], btype='band', fs=fs, output='sos', analog=False)
+ return sos
+
+def butter_highpass(lowcut, fs, order=8):
+ low = lowcut
+ sos = butter(order, low, btype='highpass', fs=fs, output='sos', analog=False)
+ return sos
+
+def butter_lowpass(highcut, fs, order=8):
+ high = highcut
+ sos = butter(order, high, btype='lowpass', fs=fs, output='sos', analog=False)
+ return sos
+
+def butter_bandpass_filter(data, lowcut, highcut, fs, order=8):
+ if highcut > fs/2:
+ sos = butter_highpass(lowcut, fs, order=order)
+ elif lowcut <= 0:
+ sos = butter_lowpass(highcut, fs, order=order)
+ else:
+ sos = butter_bandpass(lowcut, highcut, fs, order=order)
+ #y = lfilter(b, a, data)
+ y = sosfilt(sos, data)
+ return y
+
+def correct_ecg_inversion(ecg_signal, sampling_rate):
+ """
+ ECG 신호가 뒤집혔는지 감지하고 올바르게 수정합니다.
+
+ Args:
+ ecg_signal (np.array): ECG 신호 데이터.
+ sampling_rate (int): 샘플링 주파수 (Hz).
+
+ Returns:
+ np.array: 수정된 ECG 신호.
+ bool: 뒤집힘이 감지되었는지 여부.
+ """
+ # QRS군의 R파를 찾기 위해 신호의 양수 피크를 찾음
+ # prominence: 피크가 주변보다 얼마나 튀어나왔는지, distance: 피크 간 최소 거리
+ positive_peaks, _ = find_peaks(ecg_signal, prominence=0.1, distance=0.3 * sampling_rate)
+
+ # QRS군의 S파(뒤집힌 R파)를 찾기 위해 신호를 뒤집어서 피크를 찾음
+ negative_peaks, _ = find_peaks(-ecg_signal, prominence=0.1, distance=0.3 * sampling_rate)
+
+ # 피크가 하나도 감지되지 않으면 원본 신호 반환
+ if len(positive_peaks) == 0 and len(negative_peaks) == 0:
+ return ecg_signal, False
+
+ # 양수 피크와 음수 피크의 평균 진폭 계산
+ mean_pos_amp = np.mean(ecg_signal[positive_peaks]) if len(positive_peaks) > 0 else 0
+ mean_neg_amp = np.mean(ecg_signal[negative_peaks]) if len(negative_peaks) > 0 else 0
+
+ # 만약 음수 피크의 절대값이 양수 피크보다 크면 뒤집힌 것으로 판단
+ is_inverted = abs(mean_neg_amp) > abs(mean_pos_amp)
+
+ if is_inverted:
+ # print("💡 ECG 신호가 뒤집힌 것을 감지하여 수정합니다.")
+ return ecg_signal * -1, True
+ else:
+ # print("✅ ECG 신호가 정상 방향입니다.")
+ return ecg_signal, False
\ No newline at end of file
diff --git a/data/get_demographics.py b/data/get_demographics.py
new file mode 100644
index 0000000000000000000000000000000000000000..48fa6cba4f3b187bc843d1147ce062613d2db407
--- /dev/null
+++ b/data/get_demographics.py
@@ -0,0 +1,201 @@
+import argparse
+import pickle
+import pandas as pd
+from pathlib import Path
+import os
+import json
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+
+def get_shhs1_demographics(data_path, output_path):
+ """Extract demographics from SHHS1 dataset."""
+ # Assuming SHHS1 has a CSV file with demographics
+
+ demo_file = Path(data_path) / 'shhs1-dataset-0.20.0.csv'
+ output_file = Path(output_path) / 'shhs1_demographics.pkl'
+ df = pd.read_csv(demo_file)
+
+ demographics = {}
+ for _, row in df.iterrows():
+ patient_id = row['nsrrid'] # Adjust column name as needed
+ demographics[patient_id] = {
+ 'Age': row['age_s1'], # Adjust column names as needed
+ 'Sex': row['gender'], # 1 or 2
+ 'BMI': row['bmi_s1'],
+ 'AHI': row['ahi_a0h3']
+ }
+
+
+ with open(output_file, 'wb') as f:
+ pickle.dump(demographics, f)
+ print(f"SHHS1 demographics saved to {output_file}")
+
+def get_shhs2_demographics(data_path, output_path):
+ """Extract demographics from SHHS2 dataset."""
+ # Assuming SHHS2 has a CSV file with demographics
+
+ demo_file = Path(data_path) / 'shhs2-dataset-0.20.0.csv'
+ output_file = Path(output_path) / 'shhs2_demographics.pkl'
+ df = pd.read_csv(demo_file, encoding='cp1252')
+
+ demographics = {}
+ for _, row in df.iterrows():
+ patient_id = row['nsrrid'] # Adjust column name as needed
+ demographics[patient_id] = {
+ 'Age': row['age_s2'], # Adjust column names as needed
+ 'Sex': row['gender'], # 1 or 2
+ 'BMI': row['bmi_s2'],
+ 'AHI': row['ahi_a0h3']
+ }
+
+
+ with open(output_file, 'wb') as f:
+ pickle.dump(demographics, f)
+ print(f"SHHS2 demographics saved to {output_file}")
+
+def get_cfs_demographics(data_path, output_path):
+ """Extract demographics from CFS dataset."""
+ # Assuming CFS has a CSV file with demographics
+
+ demo_file = Path(data_path) / 'cfs-visit5-harmonized-dataset-0.7.0.csv'
+ output_file = Path(output_path) / 'cfs_demographics.pkl'
+ df = pd.read_csv(demo_file)
+
+ demographics = {}
+ for _, row in df.iterrows():
+ patient_id = row['nsrrid'] # Adjust column name as needed
+ demographics[patient_id] = {
+ 'Age': row['nsrr_age'], # Adjust column names as needed
+ 'Sex': 1 if row['nsrr_sex'] == 'male' else 2, # 1 or 2
+ 'BMI': row['nsrr_bmi']
+ }
+
+ demo_file2 = Path(data_path) / 'cfs-visit5-dataset-0.7.0.csv'
+ df2 = pd.read_csv(demo_file2)
+ for _, row in df2.iterrows():
+ patient_id = row['nsrrid'] # Adjust column name as needed
+ demographics[patient_id]['AHI'] = row['ahi_a0h3'] # Update AHI if available in the second file
+
+ print(demographics)
+
+
+ with open(output_file, 'wb') as f:
+ pickle.dump(demographics, f)
+ print(f"CFS demographics saved to {output_file}")
+
+def get_kiss_demographics(data_path, output_path):
+ """Extract demographics from KISS dataset."""
+ # KISS has a single JSON file that includes all subjects info
+ demo_file = Path(data_path) / '1_PSG_210426.json'
+ # df = pd.read_csv(demo_file)
+ with open (demo_file, 'r') as f:
+ ann = json.load(f)
+
+ demographics = {}
+ for patient_info in ann['Patient']:
+ patient_id = patient_info['Report']['Patient Serial Number']
+ demographics[patient_id] = {
+ 'Age': patient_info['Report']['Age'],
+ 'Sex': 1 if patient_info['Report']['Sex'] == 'Male' else 2,
+ 'BMI': patient_info['Report']['BMI'],
+ 'AHI': patient_info['Report']['AHI'],
+
+ }
+ # for _, row in df.iterrows():
+ # patient_id = row['patient_id'] # Adjust column name as needed
+ # demographics[patient_id] = {
+ # 'Age': row['age'], # Adjust column names as needed
+ # 'Sex': row['sex'],
+ # 'BMI': row['bmi']
+ # }
+
+ output_file = Path(output_path) / 'kiss_demographics.pkl'
+ with open(output_file, 'wb') as f:
+ pickle.dump(demographics, f)
+ print(f"KISS demographics saved to {output_file}")
+
+def get_kvss_demographics(data_path, output_path):
+ """Extract demographics from KVSS dataset."""
+
+ data_dirs = os.listdir(data_path)
+ demographics = {}
+ for patient_snum in data_dirs:
+ json_path = os.path.join(data_path, patient_snum, patient_snum + "_annotation.json")
+ with open(json_path, "r") as f:
+ annotations = json.load(f)
+
+ demographics[patient_snum] = {
+ 'Age': annotations['Report']['Age'],
+ 'Sex': 1 if annotations['Report']['Sex'] == 'Male' else 2,
+ 'BMI': annotations['Report']['BMI'],
+ 'AHI': annotations['Report']['AHI'],
+
+ }
+
+ output_file = Path(output_path) / 'kvss_demographics.pkl'
+ with open(output_file, 'wb') as f:
+ pickle.dump(demographics, f)
+ print(f"KVSS demographics saved to {output_file}")
+
+
+def get_phy_demographics(data_path, output_path):
+ """Extract demographics from Physionet dataset."""
+ # Assuming Physionet has a CSV file with demographics
+ demo_file = Path(data_path) / 'age-sex.csv'
+ df = pd.read_csv(demo_file)
+
+ demographics = {}
+ for _, row in df.iterrows():
+ patient_id = row['Record'] # Adjust column name as needed
+ demographics[patient_id] = {
+ 'Age': row['Age'], # Adjust column names as needed
+ 'Sex': 1 if row['Sex'] == 'M' else 2, # 1 or 2
+ }
+
+ output_file = Path(output_path) / 'phy_demographics.pkl'
+ with open(output_file, 'wb') as f:
+ pickle.dump(demographics, f)
+ print(f"PHY demographics saved to {output_file}")
+
+def main():
+ parser = argparse.ArgumentParser(description='Collect demographics from sleep study datasets')
+ parser.add_argument('--dataset', type=str, required=True,
+ choices=['shhs1', 'shhs2', 'kiss', 'kvss', 'phy', 'cfs', 'all'],
+ help='Dataset to process (shhs1, shhs2, kiss, phy, or all)')
+ # parser.add_argument('--data_path', type=str, required=True,
+ # help='Path to the dataset directory')
+ parser.add_argument('--output_path', type=str, default='../datasets/demographics/',
+ help='Path to save demographics pickle files')
+
+ args = parser.parse_args()
+
+ # Create output directory if it doesn't exist
+ Path(args.output_path).mkdir(parents=True, exist_ok=True)
+
+ if args.dataset == 'shhs1' or args.dataset == 'all':
+ data_path = os.path.join(BASE_PATH, "#_SHHS/datasets")
+ get_shhs1_demographics(data_path, args.output_path)
+
+ if args.dataset == 'shhs2' or args.dataset == 'all':
+ data_path = os.path.join(BASE_PATH, "#_SHHS/datasets")
+ get_shhs2_demographics(data_path, args.output_path)
+
+ if args.dataset == 'kiss' or args.dataset == 'all':
+ data_path = os.path.join(BASE_PATH, "#_2020_Sleep_Quality")
+ get_kiss_demographics(data_path, args.output_path)
+
+ if args.dataset == 'kvss' or args.dataset == 'all':
+ data_path = os.path.join(BASE_PATH, "#_2021_Sleep_Video")
+ get_kvss_demographics(data_path, args.output_path)
+
+ if args.dataset == 'phy' or args.dataset == 'all':
+ data_path = os.path.join(BASE_PATH, "physionet.org/files/challenge-2018/1.0.0")
+ get_phy_demographics(data_path, args.output_path)
+
+ if args.dataset == 'cfs' or args.dataset == 'all':
+ data_path = os.path.join(BASE_PATH, "CFS_raw/datasets")
+ get_cfs_demographics(data_path, args.output_path)
+
+
+if __name__ == '__main__':
+ main()
\ No newline at end of file
diff --git a/data/isruc_gather.py b/data/isruc_gather.py
new file mode 100644
index 0000000000000000000000000000000000000000..8b57a1704ba5c4604d7a6d0ae429513f453faf0d
--- /dev/null
+++ b/data/isruc_gather.py
@@ -0,0 +1,52 @@
+import os
+from tqdm import tqdm
+import numpy as np
+import shutil
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'datasets')
+
+ISRUC_SG1_DIR = os.path.join(BASE_PATH, 'isruc_sg1')
+ISRUC_SG2_DIR = os.path.join(BASE_PATH, 'isruc_sg2')
+ISRUC_SG3_DIR = os.path.join(BASE_PATH, 'isruc_sg3')
+
+ISRUC_GATHER_DIR = os.path.join(BASE_PATH, 'isruc_all')
+
+os.makedirs(ISRUC_GATHER_DIR, exist_ok=True)
+os.makedirs(os.path.join(ISRUC_GATHER_DIR, 'annotations'), exist_ok=True)
+
+
+def gather_isruc(prefix='sg1'):
+ source_dir = ISRUC_SG1_DIR if prefix == 'sg1' else ISRUC_SG2_DIR if prefix == 'sg2' else ISRUC_SG3_DIR
+ for ann_file in os.listdir(os.path.join(source_dir, 'annotations')):
+ new_name = f"{prefix}_{ann_file}"
+ if not os.path.exists(os.path.join(ISRUC_GATHER_DIR, 'annotations', new_name)):
+ os.symlink(os.path.join(source_dir, 'annotations', ann_file),
+ os.path.join(ISRUC_GATHER_DIR, 'annotations', new_name))
+
+ source_dir = os.path.join(source_dir, 'signals_MAE')
+
+ for chn_grp in os.listdir(source_dir):
+ for chn in os.listdir(os.path.join(source_dir, chn_grp)):
+ os.makedirs(os.path.join(ISRUC_GATHER_DIR, 'signals_MAE', chn_grp), exist_ok=True)
+ os.makedirs(os.path.join(ISRUC_GATHER_DIR, 'signals_MAE', chn_grp), exist_ok=True)
+ os.makedirs(os.path.join(ISRUC_GATHER_DIR, 'signals_MAE', chn_grp, chn), exist_ok=True)
+ for subj_file in os.listdir(os.path.join(source_dir, chn_grp, chn)):
+ new_name = f"{prefix}_{subj_file}"
+ if not os.path.exists(os.path.join(ISRUC_GATHER_DIR, 'signals_MAE', chn_grp, chn, new_name)):
+ os.symlink(os.path.join(source_dir, chn_grp, chn, subj_file),
+ os.path.join(ISRUC_GATHER_DIR, 'signals_MAE', chn_grp, chn, new_name))
+
+
+
+
+
+if __name__ == "__main__":
+ print("Gathering ISRUC SG1 datasets into a single directory...")
+ gather_isruc('sg1')
+ print("Gathering ISRUC SG2 datasets into a single directory...")
+ gather_isruc('sg2')
+ print("Gathering ISRUC SG3 datasets into a single directory...")
+ gather_isruc('sg3')
+
+
+
diff --git a/data/isruc_preprocess.py b/data/isruc_preprocess.py
new file mode 100644
index 0000000000000000000000000000000000000000..06b707fa2f484b4311d9c47a982df1ec8d978468
--- /dev/null
+++ b/data/isruc_preprocess.py
@@ -0,0 +1,381 @@
+import os
+import shutil
+import numpy as np
+import pandas as pd
+
+from scipy.signal import iirnotch, lfilter
+from data_utils import butter_bandpass_filter, correct_ecg_inversion
+
+import matplotlib.pyplot as plt
+from tqdm import tqdm
+import shutil
+import librosa
+import pickle
+import gc
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+SAMPLING_RATE = 200
+TARGET_RESAMPLE = 100
+NOTCH_FREQ = 60
+EEG_LOWCUT = 0.3
+EEG_HIGHCUT = 40
+EMG_LOWCUT = 10
+EMG_HIGHCUT = 1000
+ECG_LOWCUT = 0.3
+ECG_HIGHCUT = 70
+FLOW_LOWCUT = 0
+FLOW_HIGHCUT = 15
+
+do_resample = (SAMPLING_RATE != TARGET_RESAMPLE)
+
+NUM_PROCESS = 4
+
+import argparse
+import multiprocessing
+
+def process_ecg(args):
+ sig, chn_grp, chn, split = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, ECG_LOWCUT, ECG_HIGHCUT, SAMPLING_RATE)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, SAMPLING_RATE)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ filtered = filtered.reshape(-1, SAMPLING_RATE*30)
+
+ filtered_epochs = []
+
+ for epoch in filtered:
+ inv_epoch, _ = correct_ecg_inversion(epoch, SAMPLING_RATE)
+ filtered_epochs.append(inv_epoch)
+
+ filtered = np.stack(filtered_epochs, axis=0)
+
+ if do_resample:
+ filtered = np.reshape(filtered, (-1,1))
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+
+def process_eeg(args):
+ sig, chn_grp, chn, split = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EEG_LOWCUT, EEG_HIGHCUT, SAMPLING_RATE)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, SAMPLING_RATE)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ if do_resample:
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_emg(args):
+ sig, chn_grp, chn, split = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EMG_LOWCUT, EMG_HIGHCUT, SAMPLING_RATE)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, SAMPLING_RATE)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ if do_resample:
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_flow(args):
+ sig, chn_grp, chn, split = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, FLOW_LOWCUT, FLOW_HIGHCUT, SAMPLING_RATE)
+
+ # median filter?
+
+ if do_resample:
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def save_mmap(results, sig_list, chn_grp, chn, split='train'):
+ signame_list = [sig.split('.')[0] for sig in sig_list]
+ epoch_lengths = [sig.shape[0] for sig in results]
+ metadata = dict()
+ sig_info = dict()
+ start, end = 0, 0
+ for signame, sig in zip(signame_list, results):
+ length = sig.shape[0]
+ end = start + length
+ info = dict()
+ info['pos'] = (start, end)
+ info['stats'] = {'sum': float(np.sum(sig)), 'sumsq': float(np.sum(sig ** 2))}
+ sig_info[signame] = info
+ start = end
+
+
+ mmap_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ signals_cat = np.concatenate(results, axis=0).astype(np.float32)
+ os.makedirs(os.path.dirname(mmap_path), exist_ok=True)
+ data = np.memmap(mmap_path, dtype=np.float32, mode='w+', shape=signals_cat.shape)
+ data[:] = signals_cat
+ data.flush()
+
+ metadata['sig_info'] = sig_info
+ metadata['data_shape'] = signals_cat.shape
+ info_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ with open(info_path, 'wb') as f:
+ pickle.dump(metadata, f)
+
+ del data
+
+
+
+
+
+def preprocess(sig_list, chn_grp=None, chn=None, split='train'):
+ def _process(sig_list, chn_grp, chn, split):
+ print(f"Processing {chn_grp}/{chn}")
+ if chn_grp in ['EEG','EOG']:
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn, split) for sig in sig_list]
+
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_eeg, input_list), total=len(input_list)))
+
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ del results
+
+ elif chn_grp in ['EMG']:
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn, split) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_emg, input_list), total=len(input_list)))
+
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ del results
+
+ elif chn_grp in ['ECG']:
+
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn, split) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_ecg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ del results
+
+ elif chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn, split) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_flow, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ del results
+ else:
+ results = []
+ for sig in tqdm(sig_list):
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ if do_resample or chn == 'SaO2':
+ data = data.reshape(-1, 1)
+ if chn == 'SaO2':
+ data = librosa.resample(data, orig_sr=SAMPLING_RATE, target_sr=1, axis=0, res_type='soxr_qq')
+ data = data / 1e8
+ if round(np.max(data)) > 1 or round(np.min(data)) < 0:
+ print(f"Warning: SaO2 values out of range: {sig} with min {np.min(data)} and max {np.max(data)}")
+ data = data.reshape(-1, 1*30)
+ else:
+ data = librosa.resample(data, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ data = data.reshape(-1, TARGET_RESAMPLE*30)
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # shutil.copy(sig_path, output_path)
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, data)
+ elif cfg.save_type == 'mmap':
+ results.append(data)
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ del results
+ gc.collect()
+
+
+ if chn_grp is not None and chn is not None:
+ _process(sig_list, chn_grp, chn, split)
+ return
+ else:
+ for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ continue
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)):
+ continue
+ _process(sig_list, chn_grp, chn, split)
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default='isruc_all/signals_MAE', help='Physionet 2018 raw data location')
+parser.add_argument('--output_dir', default='isruc_all/mmap_signals_MAE_processed', help='Physionet 2018 processed data location')
+parser.add_argument('--save_type', default='mmap', help='Which data type to save. "npy" or "mmap"')
+parser.add_argument('--chn_grp', default=None, help='If specified, only preprocess this channel group')
+parser.add_argument('--chn', default=None, help='If specified, only preprocess this channel')
+parser.add_argument('--ann_split', action='store_true', help='To split annotation files into train/val/test')
+parser.add_argument('--num_train', type=int, default=50, help='Number of training samples')
+
+cfg = parser.parse_args()
+
+def get_isruc_filename(ids, ds_id):
+ if ds_id == 2:
+ return [f"sg{ds_id}_{id:03d}_1.npy" for id in ids] + [f"sg{ds_id}_{id:03d}_2.npy" for id in ids]
+ else:
+ return [f"sg{ds_id}_{id:03d}.npy" for id in ids]
+
+
+if __name__ == "__main__":
+ skip_val, skip_test = False, False
+ if cfg.num_train < 90:
+ if os.path.exists(os.path.join(BASE_PATH, cfg.output_dir, 'val')):
+ skip_val = True
+ if os.path.exists(os.path.join(BASE_PATH, cfg.output_dir, 'test')):
+ skip_test = True
+ cfg.output_dir += f"_train{cfg.num_train}"
+
+
+ list_files_train = sorted(get_isruc_filename(list(range(1,93)), ds_id=1)) # subjet 8, 40 are missing
+ list_files_val = sorted(get_isruc_filename(list(range(93,101)), ds_id=1))
+ list_files_test = sorted(get_isruc_filename(list(range(1,9)), ds_id=2))
+ list_files_test += sorted(get_isruc_filename(list(range(1,11)), ds_id=3))
+
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, "EEG", "C3-A2")))
+
+ for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ # Skip any files that are not directories
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ continue
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ # Skip any files that are not directories
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)):
+ continue
+ sig_list_chn = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ print(f"Number of records in {chn_grp}/{chn}:", len(sig_list_chn))
+ sig_list = list(set(sig_list).intersection(set(sig_list_chn)))
+
+ print(f"Number of records that exist in all chns:", len(sig_list)) # Total 7698 -> 7579 records
+
+ list_files_train = sorted(list(set(list_files_train).intersection(set(sig_list))))
+ list_files_val = sorted(list(set(list_files_val).intersection(set(sig_list))))
+ list_files_test = sorted(list(set(list_files_test).intersection(set(sig_list))))
+
+ # if cfg.num_train < 50:
+ list_files_train = list_files_train[:cfg.num_train]
+
+ print("Number of records in training set:", len(list_files_train))
+ print("Number of records in validation set:", len(list_files_val))
+ print("Number of records in test set:", len(list_files_test))
+
+
+ print("Processing training set...")
+ preprocess(list_files_train, cfg.chn_grp, cfg.chn, split='train')
+
+ if skip_val:
+ val_output_dir = cfg.output_dir
+ val_output_dir = val_output_dir.replace(f"_train{cfg.num_train}","")
+ os.symlink(os.path.join(BASE_PATH, val_output_dir, 'val'), os.path.join(BASE_PATH, cfg.output_dir, 'val'))
+ else:
+ print("Processing evaluation set...")
+ preprocess(list_files_val, cfg.chn_grp, cfg.chn, split='val')
+
+ if skip_test:
+ test_output_dir = cfg.output_dir
+ test_output_dir = test_output_dir.replace(f"_train{cfg.num_train}","")
+ os.symlink(os.path.join(BASE_PATH, test_output_dir, 'test'), os.path.join(BASE_PATH, cfg.output_dir, 'test'))
+ else:
+ print("Processing test set...")
+ preprocess(list_files_test, cfg.chn_grp, cfg.chn, split='test')
+
+ if cfg.ann_split:
+ # Reorganize annotations files
+ ANN_PATH = os.path.join(BASE_PATH, 'ISRUC_SG1/annotations')
+ NEW_ANN_PATH = os.path.join(BASE_PATH, 'ISRUC_SG1/annotations_split')
+ os.makedirs(NEW_ANN_PATH, exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'train'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'val'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'test'), exist_ok=True)
+
+ for fname in list_files_train:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'train', ann_fname))
+ for fname in list_files_val:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'val', ann_fname))
+ for fname in list_files_test:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'test', ann_fname))
+
+
+ for split in ['train', 'val', 'test']:
+ # create link files to respiratory channels
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP'), exist_ok=True)
+ for chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ chns = [f.split('.')[0] for f in os.listdir(os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp))]
+ for chn in chns:
+ src_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ src_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ dst_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.mmap')
+ dst_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.pickle')
+ if not os.path.exists(dst_mmap):
+ os.symlink(src_mmap, dst_mmap)
+ if not os.path.exists(dst_pickle):
+ os.symlink(src_pickle, dst_pickle)
\ No newline at end of file
diff --git a/data/isruc_process_rawdata.py b/data/isruc_process_rawdata.py
new file mode 100644
index 0000000000000000000000000000000000000000..2b3c0fa4d1a86d21256e68443523e64f09c749c9
--- /dev/null
+++ b/data/isruc_process_rawdata.py
@@ -0,0 +1,176 @@
+import scipy.io
+import os
+from tqdm import tqdm
+import numpy as np
+import mne
+import shutil
+
+CHN_SAVE_DICT = {
+ 'C3-A2': ('EEG', 'C3-A2'),
+ 'C4-A1': ('EEG', 'C4-A1'),
+ 'F3-A2': ('EEG', 'F3-A2'),
+ 'F4-A1': ('EEG', 'F4-A1'),
+ 'O1-A2': ('EEG', 'O1-A2'),
+ 'O2-A1': ('EEG', 'O2-A1'),
+ 'C3-M2': ('EEG', 'C3-A2'),
+ 'C4-M1': ('EEG', 'C4-A1'),
+ 'F3-M2': ('EEG', 'F3-A2'),
+ 'F4-M1': ('EEG', 'F4-A1'),
+ 'O1-M2': ('EEG', 'O1-A2'),
+ 'O2-M1': ('EEG', 'O2-A1'),
+ 'LOC-A2': ('EOG', 'Left-A2'),
+ 'ROC-A1': ('EOG', 'Right-A1'),
+ 'E1-M2': ('EOG', 'Left-A2'),
+ 'E2-M1': ('EOG', 'Right-A1'),
+ 'X1': ('EMG', 'EMG'),
+ 'X2': ('ECG', 'ECG'),
+ 'X6': ('AIRFLOW', 'AIRFLOW'),
+ 'X7': ('CHEST', 'CHEST'),
+ 'X8': ('ABD', 'ABD'),
+ '24': ('EMG', 'EMG'),
+ '25': ('ECG', 'ECG'),
+ '29': ('AIRFLOW', 'AIRFLOW'),
+ '30': ('CHEST', 'CHEST'),
+ '31': ('ABD', 'ABD'),
+ 'SpO2': ('SaO2', 'SaO2'),
+ 'SaO2': ('SaO2', 'SaO2')
+}
+SELECT_CHNS1 = ['F3-A2', 'F4-A1', 'C3-A2', 'C4-A1', 'O1-A2', 'O2-A1', 'LOC-A2', 'ROC-A1', 'X1', 'X2', 'X6', 'X7', 'X8', 'SaO2']
+SELECT_CHNS2 = ['F3-M2', 'F4-M1', 'C3-M2', 'C4-M1', 'O1-M2', 'O2-M1', 'E1-M2', 'E2-M1', '24', '25', '29', '30', '31', 'SpO2']
+
+
+# def match_channel_group(chn):
+# """
+# Find the group of the channel.
+# """
+# chn_group = {
+# 'EEG': ['F3-A2', 'F4-A1', 'C3-A2', 'C4-A1', 'O1-A2', 'O2-A1'],
+# 'EOG': ['LOC-A2', 'ROC-A1'],
+# 'EMG': ['X1'],
+# 'ABD': ['X8'],
+# 'CHEST': ['X7'],
+# 'AIRFLOW': ['X6'],
+# 'SaO2': ['SaO2'],
+# 'ECG': ['X2']
+# }
+# for k, v in chn_group.items():
+# if chn in v:
+# return k
+# return None
+
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))), 'datasets')
+
+import argparse
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default='ISRUC', help='ISRUC raw data location')
+parser.add_argument('--output_dir', default='ISRUC', help='ISRUC processed data location')
+parser.add_argument('--annotation_dir', default='ISRUC', help='ISRUC annotations location')
+cfg = parser.parse_args()
+
+
+def read_ann(ann_path):
+ # Annotation
+ with open(ann_path, 'r') as f:
+ ann = f.readlines()
+ ann = np.array([line.strip() for line in ann if line.strip()]).astype(np.int64)
+ ann = np.where(ann==5, 4, ann)
+ return ann
+
+# Example usage
+
+raw_sampling_rate = 200
+EPOCH_SEC_SIZE = 30
+
+for ds_id in [1,2,3]:
+ if ds_id == 1:
+ num_subject = 100
+ elif ds_id == 2:
+ num_subject = 8
+ else:
+ num_subject = 10
+ num_session = 2 if ds_id == 2 else 1
+
+ for i in tqdm(range(1, num_subject+1)):
+ for j in range(1, num_session+1):
+ data_dir_full = os.path.join(BASE_PATH, cfg.data_dir, f'SG{ds_id}', f'{i}',f'{i}')
+ if ds_id == 2:
+ file_path = os.path.join(data_dir_full, f'{j}', f'{j}.edf')
+ ann_path = os.path.join(data_dir_full, f'{j}', f'{j}_1.txt')
+ if not os.path.exists(file_path):
+ rarpath = os.path.join(data_dir_full, f'{j}', f'{j}.rec')
+ shutil.copy(rarpath, file_path)
+ else:
+ file_path = os.path.join(data_dir_full,f'{i}.edf')
+ ann_path = os.path.join(data_dir_full,f'{i}_1.txt')
+ if not os.path.exists(file_path):
+ rarpath = os.path.join(data_dir_full, f'{i}.rec')
+ shutil.copy(rarpath, file_path)
+
+ ann = read_ann(ann_path)
+
+ raw = mne.io.read_raw_edf(file_path, preload=True)
+ raw_df = raw.to_data_frame()
+
+ if not len(raw_df) == len(ann) * EPOCH_SEC_SIZE * raw_sampling_rate:
+ print(f"Warning: {i} signal length and annotation length mismatched")
+
+ # Try to use the second annotator's scoring
+ if ds_id == 2:
+ ann_path = os.path.join(data_dir_full, f'{j}', f'{j}_2.txt')
+ else:
+ ann_path = os.path.join(data_dir_full,f'{i}_2.txt')
+ ann = read_ann(ann_path)
+ if not len(raw_df) == len(ann) * EPOCH_SEC_SIZE * raw_sampling_rate:
+ print(f"Error both annotations mismatch signal length, skip this record. " , "Dataset id:", ds_id, "Subject id:", i)
+ continue
+
+ ann_dir = os.path.join(BASE_PATH, f'{cfg.output_dir}_SG{ds_id}', 'annotations')
+ os.makedirs(ann_dir, exist_ok=True)
+
+ fname = f'{i:03}_{j}' if ds_id == 2 else f'{i:03}'
+ ann_name = f'{i:03}_{j}_ann' if ds_id == 2 else f'{i:03}_ann'
+ np.save(os.path.join(ann_dir, ann_name), ann)
+
+ for chn in SELECT_CHNS1:
+ # chn_grp = match_channel_group(chn)
+ if chn in raw_df.columns:
+ raw_ch_df = raw_df[chn]
+ chn_grp, chn_rename = CHN_SAVE_DICT[chn]
+
+ else:
+ idx = SELECT_CHNS1.index(chn)
+ chn = SELECT_CHNS2[idx]
+
+ if chn in raw_df.columns:
+ raw_ch_df = raw_df[chn]
+ chn_grp, chn_rename = CHN_SAVE_DICT[chn]
+ else:
+ print(f"Channel {chn} not found in {file_path}, skip this channel.")
+ print(raw_df.columns)
+ continue
+
+ raw_ch_df = raw_ch_df.to_frame()
+ raw_ch_df.set_index(np.arange(len(raw_ch_df)))
+
+ # Remove movement and unknown stages if any
+ raw_ch = raw_ch_df.values
+
+ # Verify that we can split into 30-s epochs
+ if len(raw_ch_df) % (EPOCH_SEC_SIZE * raw_sampling_rate) != 0:
+ print(f"Length of raw channel ({len(raw_ch)}) \
+ is not multiple of raw sampling rate and epoch size ({EPOCH_SEC_SIZE} * {raw_sampling_rate})")
+
+
+ # get (# of epochs) = (# of datapoints) / (30sec * 100Hz)
+ n_epochs = len(raw_ch) / (EPOCH_SEC_SIZE * raw_sampling_rate)
+
+ # Get epochs and their corresponding labels
+ x = np.asarray(np.split(raw_ch, n_epochs)).astype(np.float32) # split epochs
+
+ # x = x[select_idx]
+ x = x.reshape((-1, EPOCH_SEC_SIZE * raw_sampling_rate))
+
+ os.makedirs(os.path.join(BASE_PATH, f'{cfg.output_dir}_SG{ds_id}', 'signals_MAE', chn_grp, chn_rename), exist_ok=True)
+ np.save(os.path.join(BASE_PATH, f'{cfg.output_dir}_SG{ds_id}', 'signals_MAE', chn_grp, chn_rename, f"{fname}.npy"), x)
+
\ No newline at end of file
diff --git a/data/kiss_meta_data/1_train_patients.txt b/data/kiss_meta_data/1_train_patients.txt
new file mode 100644
index 0000000000000000000000000000000000000000..51faeefb6327f87d016f03a0324815970122b20d
--- /dev/null
+++ b/data/kiss_meta_data/1_train_patients.txt
@@ -0,0 +1,6203 @@
+A2018-NX-01-0132
+A2019-EM-01-0078
+A2019-NX-01-0370
+A2019-NX-01-0816
+A2015-EM-01-0440
+A2018-NX-01-0158
+B2017-EM-01-0094
+A2019-NX-01-0173
+A2020-NX-01-0333
+A2019-NX-01-0718
+D2020-NX-01-0021
+A2017-EM-01-0154
+A2018-EM-01-0452
+A2019-NX-01-0994
+A2015-EM-01-0123
+A2018-EM-01-0459
+A2018-NX-01-0406
+A2015-EM-01-0198
+A2019-NX-01-1604
+C2020-EM-01-0276
+D2020-NX-01-0078
+A2020-NX-01-0442
+B2016-EM-01-0098
+B2018-EM-01-0189
+A2016-EM-01-0285
+A2018-NX-01-0352
+C2020-EM-01-0292
+A2018-EM-01-0847
+A2017-EM-01-0357
+A2015-EM-01-0247
+D2019-NX-01-0127
+A2020-NX-01-0132
+A2017-EM-01-0391
+A2019-NX-01-0445
+A2019-NX-01-1356
+A2019-NX-01-0667
+C2019-EM-01-0069
+C2019-EM-01-0057
+A2019-NX-01-0679
+A2020-NX-01-0102
+B2017-EM-01-0102
+A2015-EM-01-0324
+A2015-EM-01-0422
+A2018-NX-01-0298
+A2018-NX-01-0450
+A2018-EM-01-0962
+A2019-NX-01-0820
+C2018-EM-01-0289
+A2018-EM-01-0426
+A2019-NX-01-0086
+A2015-EM-01-0206
+A2019-NX-01-0881
+A2018-EM-01-0387
+A2019-EM-01-0240
+A2017-EM-01-0019
+D2019-NX-01-0191
+A2017-EM-01-0325
+A2019-NX-01-1312
+A2020-NX-01-0151
+A2018-NX-01-0169
+A2019-NX-01-0139
+A2019-NX-01-0604
+A2016-EM-01-0037
+A2019-EM-01-0039
+A2019-NX-01-1288
+B2013-EM-01-0030
+B2014-EM-01-0099
+A2020-EM-01-0032
+A2020-NX-01-0225
+B2018-EM-01-0182
+A2018-EM-01-1011
+B2017-EM-01-0062
+A2019-NX-01-1319
+D2020-NX-01-0289
+A2018-EM-01-0421
+A2017-EM-01-0253
+B2014-EM-01-0078
+C2020-EM-01-0012
+A2015-EM-01-0414
+A2018-NX-01-0108
+A2018-EM-01-0184
+A2017-EM-01-0527
+A2018-NX-01-0222
+B2014-EM-01-0114
+A2019-NX-01-1080
+A2018-EM-01-0850
+D2019-NX-01-0008
+A2017-EM-01-0062
+A2019-EM-01-0171
+A2015-EM-01-0383
+B2013-EM-01-0032
+A2015-EM-01-0175
+A2017-EM-01-0032
+A2019-NX-01-0332
+C2019-EM-01-0305
+B2017-EM-01-0084
+A2019-NX-01-0621
+A2020-NX-01-0203
+A2018-EM-01-0346
+A2019-NX-01-1188
+A2019-NX-01-1245
+B2019-EM-01-0057
+A2020-NX-01-0088
+A2017-EM-01-0358
+A2017-EM-01-0436
+A2018-NX-01-0399
+A2019-NX-01-1582
+A2015-EM-01-0277
+A2019-NX-01-0930
+D2020-NX-01-0273
+A2019-NX-01-0911
+C2019-EM-01-0156
+B2016-EM-01-0127
+A2018-EM-01-0964
+A2019-NX-01-1026
+A2018-NX-01-0310
+A2020-NX-01-0104
+B2015-EM-01-0131
+D2019-NX-01-0080
+C2019-EM-01-0208
+C2018-EM-01-0053
+D2020-NX-01-0128
+A2018-EM-01-0943
+A2019-NX-01-1422
+B2013-EM-01-0002
+A2019-NX-01-1512
+A2015-EM-01-0323
+C2019-EM-01-0185
+A2020-NX-01-0170
+A2019-NX-01-1209
+A2017-EM-01-0279
+A2018-NX-01-0409
+A2020-NX-01-0401
+A2016-EM-01-0291
+A2017-EM-01-0545
+A2016-EM-01-0399
+A2020-NX-01-0541
+A2018-EM-01-0600
+A2019-NX-01-1210
+A2019-NX-01-1306
+C2018-EM-01-0278
+D2020-NX-01-0069
+B2015-EM-01-0111
+A2018-EM-01-0596
+A2018-EM-01-0771
+A2015-EM-01-0326
+A2020-EM-01-0059
+A2018-NX-01-0336
+C2020-EM-01-0247
+A2019-NX-01-1627
+A2019-EM-01-0111
+B2018-EM-01-0177
+D2019-NX-01-0114
+A2019-NX-01-0914
+A2016-EM-01-0352
+A2017-EM-01-0044
+A2019-EM-01-0062
+A2018-NX-01-0073
+A2019-NX-01-0251
+B2015-EM-01-0030
+A2019-NX-01-0245
+B2017-EM-01-0013
+A2017-EM-01-0532
+A2018-EM-01-0731
+B2019-EM-01-0040
+C2018-EM-01-0253
+A2020-NX-01-0796
+B2015-EM-01-0148
+A2020-NX-01-0578
+A2019-NX-01-0273
+A2018-NX-01-0011
+A2020-NX-01-0003
+B2015-EM-01-0115
+A2016-EM-01-0013
+A2018-EM-01-0365
+A2020-NX-01-0450
+A2016-EM-01-0223
+A2015-EM-01-0438
+A2020-NX-01-0783
+A2017-EM-01-0517
+A2020-NX-01-0398
+A2019-EM-01-0168
+A2019-NX-01-0076
+A2016-EM-01-0317
+A2016-EM-01-0139
+D2020-NX-01-0241
+A2018-EM-01-0157
+A2016-EM-01-0257
+A2018-EM-01-0763
+C2020-EM-01-0170
+B2018-EM-01-0033
+A2018-EM-01-0889
+A2019-NX-01-0523
+A2020-NX-01-0061
+A2016-EM-01-0409
+A2019-EM-01-0157
+A2018-NX-01-0139
+A2019-NX-01-0789
+A2018-EM-01-0986
+A2017-EM-01-0482
+A2018-EM-01-0116
+B2018-EM-01-0048
+A2019-NX-01-0138
+D2019-NX-01-0232
+A2019-NX-01-0635
+A2019-NX-01-1634
+A2020-EM-01-0008
+A2016-EM-01-0361
+B2018-EM-01-0148
+D2019-NX-01-0057
+A2020-NX-01-0705
+C2018-EM-01-0138
+A2015-EM-01-0266
+C2018-EM-01-0295
+A2019-NX-01-1169
+B2015-EM-01-0106
+A2015-EM-01-0092
+D2019-NX-01-0144
+A2017-EM-01-0278
+A2019-NX-01-0801
+C2019-EM-01-0277
+C2018-EM-01-0112
+C2018-EM-01-0115
+A2018-EM-01-0422
+C2019-EM-01-0337
+A2019-NX-01-0340
+A2016-EM-01-0366
+A2019-EM-01-0069
+C2018-EM-01-0111
+A2018-EM-01-0657
+A2016-EM-01-0290
+A2017-EM-01-0308
+B2019-EM-01-0049
+A2017-EM-01-0277
+A2018-NX-01-0369
+A2018-EM-01-0553
+A2018-NX-01-0215
+A2019-NX-01-1616
+C2018-EM-01-0195
+A2020-NX-01-0474
+A2019-NX-01-1158
+A2019-NX-01-0697
+A2018-EM-01-0287
+A2020-NX-01-0240
+A2019-EM-01-0091
+A2020-NX-01-0355
+A2020-NX-01-0318
+C2019-EM-01-0260
+A2016-EM-01-0157
+B2015-EM-01-0020
+C2020-EM-01-0334
+A2019-NX-01-0172
+A2018-EM-01-0844
+A2019-NX-01-0688
+A2018-EM-01-0500
+A2019-EM-01-0152
+C2020-EM-01-0212
+A2019-NX-01-0404
+C2020-EM-01-0343
+A2019-NX-01-0032
+B2015-EM-01-0025
+C2019-EM-01-0222
+A2017-EM-01-0221
+A2017-EM-01-0126
+A2018-NX-01-0024
+C2018-EM-01-0269
+D2019-NX-01-0201
+C2018-EM-01-0148
+A2018-EM-01-0035
+C2018-EM-01-0219
+A2015-EM-01-0375
+A2019-NX-01-0057
+B2014-EM-01-0055
+B2015-EM-01-0027
+B2014-EM-01-0036
+A2018-EM-01-0635
+A2019-NX-01-0849
+B2018-EM-01-0024
+A2018-EM-01-0341
+A2019-NX-01-1257
+C2019-EM-01-0135
+A2019-EM-01-0262
+A2018-EM-01-0633
+D2019-NX-01-0071
+B2019-EM-01-0055
+B2013-EM-01-0010
+C2018-EM-01-0184
+A2016-EM-01-0255
+B2014-EM-01-0066
+A2018-EM-01-0594
+A2015-EM-01-0044
+A2018-EM-01-0348
+A2020-NX-01-0220
+A2018-EM-01-0667
+B2018-EM-01-0039
+C2020-EM-01-0136
+C2018-EM-01-0037
+A2019-NX-01-1250
+A2019-NX-01-1416
+A2015-EM-01-0211
+A2020-NX-01-0617
+D2019-NX-01-0234
+A2020-NX-01-0553
+C2019-EM-01-0175
+A2019-NX-01-0367
+B2014-EM-01-0049
+D2019-NX-01-0242
+A2019-NX-01-0738
+A2019-NX-01-0116
+B2016-EM-01-0110
+C2020-EM-01-0079
+A2018-EM-01-0391
+C2020-EM-01-0336
+B2016-EM-01-0020
+B2015-EM-01-0129
+D2020-NX-01-0175
+D2020-NX-01-0170
+A2017-EM-01-0458
+D2019-NX-01-0143
+B2015-EM-01-0084
+C2019-EM-01-0037
+C2020-EM-01-0195
+A2017-EM-01-0072
+C2020-EM-01-0141
+C2020-EM-01-0096
+A2018-NX-01-0077
+A2019-NX-01-0540
+D2020-NX-01-0099
+A2017-EM-01-0383
+A2017-EM-01-0554
+A2018-EM-01-0849
+A2015-EM-01-0275
+A2019-NX-01-1276
+A2020-NX-01-0502
+A2018-EM-01-0094
+A2019-NX-01-1107
+B2016-EM-01-0007
+A2016-EM-01-0276
+A2018-EM-01-0373
+D2020-NX-01-0132
+C2019-EM-01-0291
+A2019-NX-01-0341
+A2016-EM-01-0351
+C2020-EM-01-0262
+A2019-NX-01-1326
+A2019-NX-01-0577
+B2016-EM-01-0047
+A2017-EM-01-0244
+A2019-EM-01-0096
+A2017-EM-01-0212
+A2018-NX-01-0265
+A2019-NX-01-1366
+A2019-NX-01-0483
+A2018-NX-01-0165
+A2019-NX-01-1346
+A2015-EM-01-0415
+A2018-EM-01-0012
+C2020-EM-01-0282
+A2015-EM-01-0320
+A2015-EM-01-0087
+A2020-NX-01-0692
+C2019-EM-01-0232
+C2020-EM-01-0144
+A2019-NX-01-0460
+A2018-EM-01-0032
+C2019-EM-01-0205
+A2015-EM-01-0372
+A2018-NX-01-0422
+B2016-EM-01-0090
+B2017-EM-01-0055
+C2018-EM-01-0028
+A2018-NX-01-0270
+C2019-EM-01-0346
+A2019-NX-01-1036
+A2019-NX-01-0234
+A2019-NX-01-0559
+A2018-NX-01-0249
+B2018-EM-01-0188
+B2017-EM-01-0057
+A2019-NX-01-1309
+A2019-NX-01-0302
+A2017-EM-01-0074
+A2019-NX-01-0472
+D2020-NX-01-0220
+A2020-NX-01-0248
+A2018-NX-01-0003
+C2019-EM-01-0322
+D2019-NX-01-0049
+B2014-EM-01-0056
+C2018-EM-01-0355
+A2019-EM-01-0106
+A2019-NX-01-0634
+C2020-EM-01-0320
+C2018-EM-01-0349
+A2019-NX-01-0578
+A2019-NX-01-1379
+B2017-EM-01-0040
+A2018-EM-01-0490
+D2019-NX-01-0098
+A2015-EM-01-0012
+D2019-NX-01-0031
+A2019-NX-01-1564
+A2015-EM-01-0291
+A2018-EM-01-0717
+A2015-EM-01-0361
+A2019-NX-01-1347
+A2015-EM-01-0059
+C2020-EM-01-0018
+A2019-NX-01-0423
+A2019-NX-01-1182
+A2019-NX-01-0047
+A2018-EM-01-0696
+A2017-EM-01-0345
+B2018-EM-01-0097
+A2017-EM-01-0503
+A2018-EM-01-0870
+A2019-NX-01-0256
+B2013-EM-01-0015
+A2018-EM-01-0197
+C2020-EM-01-0305
+A2020-NX-01-0661
+C2018-EM-01-0255
+A2019-NX-01-1223
+A2020-NX-01-0377
+A2020-NX-01-0778
+A2020-NX-01-0683
+A2018-EM-01-0011
+A2018-NX-01-0346
+A2019-NX-01-1467
+A2017-EM-01-0456
+A2017-EM-01-0220
+A2016-EM-01-0097
+A2017-EM-01-0505
+B2018-EM-01-0057
+D2020-NX-01-0257
+C2019-EM-01-0259
+A2016-EM-01-0072
+A2017-EM-01-0095
+C2019-EM-01-0311
+C2020-EM-01-0166
+A2019-NX-01-0476
+A2020-NX-01-0774
+A2019-NX-01-1284
+A2020-NX-01-0613
+A2018-NX-01-0362
+B2018-EM-01-0157
+A2019-NX-01-0940
+D2019-NX-01-0205
+A2016-EM-01-0073
+A2016-EM-01-0331
+D2019-NX-01-0104
+A2015-EM-01-0301
+A2020-NX-01-0521
+A2018-EM-01-0318
+A2017-EM-01-0189
+A2019-NX-01-0850
+A2018-EM-01-0756
+B2018-EM-01-0027
+B2017-EM-01-0082
+A2017-EM-01-0005
+A2017-EM-01-0291
+A2019-NX-01-0883
+C2019-EM-01-0130
+A2018-NX-01-0267
+A2015-EM-01-0218
+A2019-NX-01-1289
+A2019-NX-01-0432
+A2016-EM-01-0298
+A2018-NX-01-0190
+D2019-NX-01-0200
+C2018-EM-01-0117
+A2018-NX-01-0410
+D2019-NX-01-0012
+B2019-NX-01-0063
+A2019-NX-01-0369
+D2020-NX-01-0112
+A2020-NX-01-0684
+A2019-NX-01-0802
+C2019-EM-01-0338
+A2016-EM-01-0320
+A2018-NX-01-0019
+C2019-EM-01-0004
+A2018-EM-01-0888
+A2018-EM-01-0710
+A2020-NX-01-0172
+A2019-NX-01-1429
+A2019-NX-01-1129
+D2019-NX-01-0099
+A2015-EM-01-0288
+A2018-NX-01-0104
+A2020-NX-01-0084
+A2019-NX-01-1636
+A2019-NX-01-1057
+A2019-NX-01-0455
+D2020-NX-01-0285
+A2018-EM-01-0375
+A2018-EM-01-0049
+A2019-NX-01-0355
+A2020-NX-01-0529
+B2013-EM-01-0021
+A2019-NX-01-0735
+B2019-EM-01-0050
+A2016-EM-01-0275
+B2016-EM-01-0088
+A2018-EM-01-0947
+A2018-EM-01-0048
+B2019-NX-01-0023
+A2018-NX-01-0141
+A2018-EM-01-0275
+A2020-NX-01-0562
+A2017-EM-01-0402
+A2020-NX-01-0459
+B2017-EM-01-0014
+B2015-EM-01-0080
+A2016-EM-01-0162
+A2015-EM-01-0413
+C2019-EM-01-0095
+A2016-EM-01-0332
+A2015-EM-01-0286
+A2020-EM-01-0070
+D2019-NX-01-0211
+B2019-EM-01-0053
+B2016-EM-01-0014
+A2016-EM-01-0180
+A2019-NX-01-0796
+A2017-EM-01-0255
+A2018-EM-01-0861
+A2020-NX-01-0590
+A2018-EM-01-0142
+C2019-EM-01-0275
+A2020-NX-01-0794
+A2019-NX-01-0894
+A2018-NX-01-0068
+C2019-EM-01-0191
+A2018-EM-01-0880
+A2019-NX-01-0272
+A2019-NX-01-0632
+A2018-EM-01-0061
+B2019-NX-01-0091
+A2020-EM-01-0084
+A2016-EM-01-0310
+D2020-NX-01-0048
+C2019-EM-01-0326
+B2018-EM-01-0068
+A2015-EM-01-0126
+A2017-EM-01-0234
+A2019-NX-01-0212
+D2019-NX-01-0045
+A2016-EM-01-0213
+C2020-EM-01-0001
+A2020-NX-01-0015
+A2020-NX-01-0627
+A2018-EM-01-0668
+B2018-EM-01-0060
+A2019-NX-01-1538
+B2018-EM-01-0111
+A2020-NX-01-0113
+A2019-NX-01-0976
+A2018-EM-01-0026
+C2018-EM-01-0249
+D2020-NX-01-0038
+C2019-EM-01-0125
+B2019-EM-01-0029
+A2019-EM-01-0072
+A2015-EM-01-0187
+A2020-NX-01-0323
+A2019-NX-01-1382
+A2019-NX-01-0109
+A2019-NX-01-0595
+A2019-NX-01-0037
+A2019-EM-01-0067
+A2019-EM-01-0029
+A2019-NX-01-0646
+A2019-NX-01-1412
+A2019-NX-01-0436
+A2015-EM-01-0319
+A2017-EM-01-0231
+A2020-EM-01-0080
+A2017-EM-01-0225
+A2019-NX-01-0269
+A2019-NX-01-1410
+A2020-EM-01-0071
+A2018-NX-01-0427
+B2016-EM-01-0092
+A2019-NX-01-0924
+A2017-EM-01-0241
+A2020-EM-01-0056
+C2018-EM-01-0064
+A2019-NX-01-0758
+A2019-NX-01-1424
+C2019-EM-01-0246
+A2018-EM-01-0002
+A2019-NX-01-0960
+A2019-NX-01-0207
+A2015-EM-01-0441
+A2019-NX-01-1262
+A2017-EM-01-0526
+A2019-NX-01-0088
+A2019-NX-01-0979
+A2019-NX-01-1065
+C2019-EM-01-0288
+C2020-EM-01-0273
+A2018-EM-01-0845
+A2019-NX-01-0531
+A2019-NX-01-0489
+A2018-EM-01-0090
+A2016-EM-01-0085
+A2018-EM-01-0886
+A2020-NX-01-0059
+A2019-NX-01-1285
+B2019-NX-01-0005
+A2018-EM-01-0221
+A2019-NX-01-1063
+A2020-NX-01-0353
+B2017-EM-01-0070
+A2020-NX-01-0513
+A2019-NX-01-0036
+D2019-NX-01-0147
+A2019-NX-01-1000
+A2015-EM-01-0009
+C2018-EM-01-0130
+A2016-EM-01-0100
+A2018-EM-01-0155
+A2019-NX-01-1118
+A2020-NX-01-0503
+B2019-NX-01-0081
+D2020-NX-01-0059
+C2020-EM-01-0015
+A2018-EM-01-0779
+D2019-NX-01-0001
+A2018-EM-01-0308
+A2019-EM-01-0090
+A2018-NX-01-0293
+A2020-NX-01-0675
+A2018-EM-01-0671
+A2015-EM-01-0313
+B2014-EM-01-0043
+A2019-NX-01-1387
+A2020-NX-01-0298
+C2020-EM-01-0259
+A2020-NX-01-0540
+C2019-EM-01-0241
+A2019-NX-01-1018
+A2019-NX-01-1336
+A2018-NX-01-0033
+D2020-NX-01-0105
+A2019-NX-01-0782
+A2016-EM-01-0349
+A2018-EM-01-0356
+A2016-EM-01-0382
+A2019-NX-01-0351
+A2019-NX-01-1128
+A2019-EM-01-0102
+A2015-EM-01-0032
+A2016-EM-01-0153
+B2014-EM-01-0018
+A2019-NX-01-0941
+A2020-NX-01-0697
+A2017-EM-01-0520
+A2016-EM-01-0273
+D2020-NX-01-0017
+A2020-NX-01-0673
+A2017-EM-01-0249
+A2018-NX-01-0181
+A2019-NX-01-1491
+A2019-NX-01-1644
+B2013-EM-01-0066
+A2019-NX-01-0012
+A2019-NX-01-0953
+C2019-EM-01-0377
+C2019-EM-01-0273
+A2020-EM-01-0048
+A2019-EM-01-0161
+A2020-NX-01-0488
+A2017-EM-01-0076
+A2018-NX-01-0197
+A2020-NX-01-0657
+C2020-EM-01-0299
+B2015-EM-01-0086
+C2019-EM-01-0199
+A2020-NX-01-0284
+A2015-EM-01-0073
+B2013-EM-01-0108
+A2019-NX-01-0700
+D2019-NX-01-0068
+A2019-NX-01-1330
+A2019-NX-01-0800
+A2019-NX-01-1195
+B2014-EM-01-0004
+A2018-EM-01-0628
+A2019-EM-01-0211
+A2018-EM-01-0060
+A2017-EM-01-0444
+A2015-EM-01-0015
+B2017-EM-01-0048
+A2019-NX-01-1114
+A2019-NX-01-0164
+A2018-NX-01-0448
+A2017-EM-01-0273
+B2018-EM-01-0041
+B2013-EM-01-0052
+A2019-NX-01-1386
+A2019-NX-01-0741
+B2013-EM-01-0062
+C2018-EM-01-0319
+A2015-EM-01-0069
+A2019-NX-01-0475
+A2015-EM-01-0029
+A2019-NX-01-1514
+C2019-EM-01-0133
+D2020-NX-01-0139
+A2019-NX-01-0321
+B2015-EM-01-0143
+A2019-NX-01-0760
+A2019-NX-01-0498
+A2017-EM-01-0515
+A2015-EM-01-0260
+A2019-NX-01-0808
+A2019-NX-01-0673
+A2018-EM-01-0641
+C2018-EM-01-0296
+A2020-NX-01-0166
+D2019-NX-01-0189
+C2018-EM-01-0151
+A2020-NX-01-0736
+A2016-EM-01-0378
+A2019-NX-01-0391
+A2016-EM-01-0062
+A2018-EM-01-0377
+B2013-EM-01-0017
+D2019-NX-01-0195
+C2019-EM-01-0089
+A2018-EM-01-0489
+A2019-EM-01-0044
+A2015-EM-01-0236
+A2017-EM-01-0499
+D2019-NX-01-0085
+A2019-NX-01-1120
+B2019-NX-01-0028
+A2019-NX-01-0791
+B2016-EM-01-0038
+A2015-EM-01-0298
+B2017-EM-01-0100
+A2018-EM-01-0697
+B2017-EM-01-0072
+A2018-EM-01-0263
+C2020-EM-01-0122
+A2019-EM-01-0121
+A2018-EM-01-0359
+A2020-NX-01-0747
+A2018-EM-01-0191
+A2018-EM-01-0814
+D2020-NX-01-0015
+A2016-EM-01-0099
+D2020-NX-01-0125
+A2020-NX-01-0547
+A2015-EM-01-0058
+A2015-EM-01-0067
+B2019-EM-01-0013
+C2020-EM-01-0178
+D2020-NX-01-0141
+A2020-NX-01-0154
+C2018-EM-01-0281
+D2020-NX-01-0219
+B2018-EM-01-0130
+A2017-EM-01-0405
+B2018-EM-01-0183
+A2017-EM-01-0236
+A2020-NX-01-0479
+A2015-EM-01-0090
+A2018-EM-01-0134
+A2017-EM-01-0142
+A2016-EM-01-0200
+A2017-EM-01-0349
+D2020-NX-01-0197
+A2018-EM-01-0460
+A2016-EM-01-0173
+A2018-NX-01-0081
+A2019-NX-01-0852
+A2015-EM-01-0404
+B2013-EM-01-0047
+C2020-EM-01-0208
+A2020-EM-01-0082
+A2020-NX-01-0038
+A2019-NX-01-0511
+A2015-EM-01-0381
+B2018-EM-01-0013
+B2016-EM-01-0131
+A2019-NX-01-0722
+B2014-EM-01-0062
+A2019-NX-01-1548
+B2017-EM-01-0038
+A2020-NX-01-0030
+A2018-EM-01-0370
+A2019-NX-01-0978
+C2019-EM-01-0136
+A2018-NX-01-0227
+A2015-EM-01-0199
+A2015-EM-01-0180
+B2019-NX-01-0054
+A2018-EM-01-0743
+A2018-EM-01-0939
+A2017-EM-01-0040
+A2018-EM-01-0590
+A2016-EM-01-0227
+A2017-EM-01-0002
+A2019-NX-01-0698
+B2018-EM-01-0135
+C2020-EM-01-0188
+A2017-EM-01-0063
+D2020-NX-01-0209
+A2019-NX-01-1042
+A2019-NX-01-0481
+B2014-EM-01-0008
+B2014-EM-01-0032
+A2016-EM-01-0269
+A2018-NX-01-0207
+B2019-NX-01-0029
+A2018-NX-01-0294
+B2013-EM-01-0072
+D2019-NX-01-0135
+A2016-EM-01-0400
+A2019-NX-01-0591
+A2020-NX-01-0696
+B2013-EM-01-0033
+A2020-NX-01-0197
+B2018-EM-01-0154
+A2019-NX-01-0204
+A2019-NX-01-1436
+A2018-EM-01-0535
+A2018-EM-01-0446
+B2014-EM-01-0093
+A2018-EM-01-0614
+B2015-EM-01-0042
+B2018-EM-01-0185
+A2018-NX-01-0250
+A2018-NX-01-0280
+A2017-EM-01-0099
+A2019-NX-01-0870
+B2016-EM-01-0042
+A2019-NX-01-0944
+A2018-NX-01-0226
+A2018-EM-01-0774
+A2020-NX-01-0791
+A2016-EM-01-0176
+A2019-EM-01-0099
+D2020-NX-01-0119
+C2020-EM-01-0064
+A2018-EM-01-0482
+A2020-NX-01-0109
+A2018-EM-01-0429
+A2015-EM-01-0207
+A2018-EM-01-0456
+A2018-NX-01-0027
+B2017-EM-01-0058
+B2018-EM-01-0063
+A2018-NX-01-0348
+A2019-NX-01-0097
+A2015-EM-01-0086
+A2018-EM-01-0576
+D2020-NX-01-0142
+A2019-NX-01-1297
+A2015-EM-01-0025
+A2019-NX-01-1180
+A2019-NX-01-0363
+A2019-NX-01-0996
+C2019-EM-01-0198
+A2017-EM-01-0431
+A2020-NX-01-0165
+A2015-EM-01-0265
+C2018-EM-01-0068
+A2019-NX-01-0242
+A2020-NX-01-0798
+A2020-NX-01-0010
+C2019-EM-01-0058
+B2016-EM-01-0030
+A2019-NX-01-0461
+A2020-NX-01-0421
+A2016-EM-01-0111
+A2018-NX-01-0063
+C2018-EM-01-0236
+A2017-EM-01-0265
+D2019-NX-01-0100
+D2020-NX-01-0152
+A2018-EM-01-0121
+A2018-NX-01-0323
+D2020-NX-01-0019
+A2020-EM-01-0021
+A2019-NX-01-0147
+B2015-EM-01-0023
+A2019-EM-01-0040
+A2015-EM-01-0081
+A2017-EM-01-0413
+A2019-NX-01-1126
+A2019-EM-01-0129
+A2015-EM-01-0031
+C2019-EM-01-0171
+C2019-EM-01-0075
+A2016-EM-01-0196
+A2019-NX-01-0609
+A2015-EM-01-0410
+A2018-NX-01-0014
+A2015-EM-01-0008
+A2016-EM-01-0158
+B2015-EM-01-0130
+A2015-EM-01-0264
+D2019-NX-01-0107
+A2019-NX-01-0189
+A2019-EM-01-0247
+A2019-NX-01-0289
+A2018-EM-01-0840
+B2016-EM-01-0097
+B2019-NX-01-0018
+A2019-EM-01-0201
+B2015-EM-01-0119
+A2017-EM-01-0414
+A2017-EM-01-0397
+C2020-EM-01-0130
+A2016-EM-01-0234
+A2019-NX-01-0359
+A2016-EM-01-0135
+A2018-EM-01-0694
+A2019-NX-01-0075
+A2018-EM-01-0418
+D2020-NX-01-0101
+A2016-EM-01-0178
+A2017-EM-01-0139
+A2017-EM-01-0404
+D2020-NX-01-0158
+A2015-EM-01-0379
+A2020-NX-01-0764
+A2018-EM-01-0919
+A2018-EM-01-0282
+A2019-NX-01-1316
+A2020-NX-01-0648
+C2019-EM-01-0278
+A2018-EM-01-0775
+A2018-EM-01-0969
+A2018-EM-01-0127
+B2013-EM-01-0065
+A2019-NX-01-1194
+A2015-EM-01-0141
+A2020-NX-01-0625
+A2018-EM-01-0863
+A2017-EM-01-0155
+B2016-EM-01-0073
+A2018-EM-01-0103
+A2019-NX-01-1647
+B2013-EM-01-0055
+A2018-EM-01-0772
+C2020-EM-01-0009
+A2019-NX-01-0227
+A2017-EM-01-0185
+C2020-EM-01-0157
+A2019-NX-01-0152
+A2018-EM-01-0862
+C2018-EM-01-0272
+A2018-NX-01-0094
+A2018-EM-01-0979
+A2017-EM-01-0442
+A2019-NX-01-0656
+A2019-NX-01-0388
+A2016-EM-01-0096
+A2019-NX-01-1130
+A2018-NX-01-0244
+A2018-NX-01-0388
+A2019-NX-01-0626
+C2018-EM-01-0206
+A2018-EM-01-0885
+B2018-EM-01-0169
+A2015-EM-01-0293
+A2019-NX-01-0710
+B2013-EM-01-0058
+A2019-NX-01-1269
+B2013-EM-01-0056
+A2019-NX-01-1122
+A2019-NX-01-0337
+A2018-EM-01-0455
+A2019-NX-01-1117
+A2016-EM-01-0348
+A2019-NX-01-0135
+B2019-EM-01-0033
+C2018-EM-01-0263
+D2019-NX-01-0137
+A2020-NX-01-0646
+C2020-EM-01-0062
+B2015-EM-01-0035
+A2018-NX-01-0420
+A2018-EM-01-0813
+B2018-EM-01-0053
+A2019-NX-01-0006
+A2020-NX-01-0608
+A2020-NX-01-0294
+C2019-EM-01-0220
+C2019-EM-01-0128
+D2020-NX-01-0288
+C2018-EM-01-0245
+A2016-EM-01-0392
+A2019-NX-01-1256
+A2020-NX-01-0630
+C2020-EM-01-0271
+A2017-EM-01-0188
+B2015-EM-01-0113
+A2019-NX-01-0905
+C2018-EM-01-0060
+D2020-NX-01-0146
+A2019-NX-01-0019
+D2019-NX-01-0152
+B2018-EM-01-0043
+D2019-NX-01-0202
+B2018-EM-01-0076
+C2020-EM-01-0241
+A2017-EM-01-0187
+A2019-NX-01-0029
+A2018-EM-01-0900
+C2020-EM-01-0039
+A2018-NX-01-0194
+A2018-NX-01-0016
+D2020-NX-01-0144
+A2020-NX-01-0108
+A2015-EM-01-0213
+A2018-EM-01-0591
+A2015-EM-01-0163
+C2018-EM-01-0120
+A2019-EM-01-0175
+A2020-NX-01-0429
+A2017-EM-01-0335
+A2015-EM-01-0411
+A2019-NX-01-0237
+A2020-NX-01-0118
+B2013-EM-01-0086
+B2016-EM-01-0015
+A2016-EM-01-0081
+A2016-EM-01-0324
+A2017-EM-01-0341
+A2017-EM-01-0443
+A2020-EM-01-0067
+A2016-EM-01-0089
+A2017-EM-01-0175
+A2018-EM-01-0434
+D2019-NX-01-0268
+B2018-EM-01-0160
+A2018-EM-01-0211
+A2018-EM-01-0029
+A2016-EM-01-0028
+C2020-EM-01-0328
+A2019-NX-01-0240
+A2019-NX-01-1225
+C2019-EM-01-0283
+A2019-NX-01-0821
+A2020-NX-01-0612
+A2019-NX-01-0736
+A2019-NX-01-1125
+A2018-EM-01-0156
+A2015-EM-01-0024
+A2016-EM-01-0225
+A2018-NX-01-0437
+B2018-EM-01-0146
+C2019-EM-01-0167
+B2018-EM-01-0003
+A2018-EM-01-0955
+D2020-NX-01-0114
+A2020-NX-01-0254
+A2015-EM-01-0466
+A2016-EM-01-0177
+B2015-EM-01-0104
+A2020-NX-01-0239
+A2019-NX-01-0670
+A2019-NX-01-0454
+D2020-NX-01-0248
+D2020-NX-01-0233
+A2017-EM-01-0186
+A2017-EM-01-0090
+B2018-EM-01-0022
+A2019-EM-01-0094
+A2018-NX-01-0152
+A2018-NX-01-0072
+A2018-EM-01-0842
+C2019-EM-01-0229
+A2015-EM-01-0348
+A2015-EM-01-0071
+B2013-EM-01-0099
+A2018-EM-01-0119
+C2019-EM-01-0261
+A2019-EM-01-0159
+C2020-EM-01-0111
+D2020-NX-01-0073
+A2020-EM-01-0040
+B2018-EM-01-0075
+A2019-NX-01-1574
+A2018-EM-01-0831
+A2018-EM-01-0386
+A2020-NX-01-0191
+A2020-NX-01-0176
+A2019-EM-01-0198
+A2015-EM-01-0347
+A2019-NX-01-0375
+A2020-NX-01-0552
+A2018-EM-01-0139
+A2018-EM-01-0473
+B2019-EM-01-0059
+A2018-EM-01-0815
+C2020-EM-01-0032
+A2020-NX-01-0601
+A2017-EM-01-0342
+A2019-NX-01-0854
+A2019-NX-01-0641
+A2018-EM-01-0624
+A2015-EM-01-0459
+A2018-EM-01-0632
+A2019-NX-01-0538
+A2019-NX-01-0813
+A2020-NX-01-0734
+A2019-NX-01-1464
+A2018-NX-01-0186
+A2018-EM-01-0417
+A2018-NX-01-0383
+A2017-EM-01-0536
+A2019-NX-01-1112
+D2020-NX-01-0136
+A2018-EM-01-1002
+A2019-NX-01-0907
+A2019-EM-01-0290
+C2018-EM-01-0273
+A2019-NX-01-1585
+B2014-EM-01-0074
+A2020-NX-01-0363
+A2019-NX-01-1111
+B2013-EM-01-0014
+D2019-NX-01-0060
+C2019-EM-01-0042
+A2020-NX-01-0256
+A2019-NX-01-1142
+A2020-NX-01-0563
+A2019-NX-01-0624
+A2019-NX-01-0112
+A2015-EM-01-0350
+A2020-NX-01-0633
+A2019-NX-01-0215
+D2019-NX-01-0159
+A2016-EM-01-0078
+A2019-NX-01-1569
+A2018-EM-01-0310
+D2019-NX-01-0251
+A2016-EM-01-0116
+A2015-EM-01-0182
+B2013-EM-01-0048
+C2019-EM-01-0090
+A2020-NX-01-0190
+A2018-EM-01-0187
+A2017-EM-01-0179
+A2020-NX-01-0019
+A2019-NX-01-0296
+A2018-EM-01-0175
+A2017-EM-01-0449
+A2015-EM-01-0121
+A2018-EM-01-0975
+A2018-NX-01-0178
+A2015-EM-01-0432
+A2020-NX-01-0649
+A2020-NX-01-0100
+A2018-NX-01-0402
+A2017-EM-01-0423
+A2019-NX-01-0902
+A2018-EM-01-0296
+A2019-NX-01-0123
+A2018-NX-01-0069
+D2019-NX-01-0102
+A2018-NX-01-0102
+A2019-EM-01-0064
+C2020-EM-01-0335
+A2018-EM-01-0573
+A2020-EM-01-0025
+A2018-EM-01-0917
+C2018-EM-01-0356
+A2019-NX-01-0982
+B2019-NX-01-0015
+A2020-NX-01-0046
+B2016-EM-01-0004
+A2020-NX-01-0308
+A2019-NX-01-0405
+A2019-NX-01-0428
+A2020-NX-01-0313
+B2017-EM-01-0104
+A2018-EM-01-0627
+C2020-EM-01-0163
+D2019-NX-01-0132
+C2018-EM-01-0326
+D2020-NX-01-0224
+A2017-EM-01-0218
+B2014-EM-01-0090
+A2018-EM-01-0776
+D2019-NX-01-0136
+A2017-EM-01-0039
+A2018-EM-01-0222
+A2017-EM-01-0233
+A2019-NX-01-0350
+A2017-EM-01-0290
+A2017-EM-01-0052
+C2019-EM-01-0330
+A2019-NX-01-0080
+B2015-EM-01-0127
+A2018-NX-01-0093
+C2018-EM-01-0280
+D2020-NX-01-0174
+A2018-EM-01-0538
+A2019-NX-01-0607
+A2017-EM-01-0394
+A2019-NX-01-0324
+C2018-EM-01-0190
+A2018-EM-01-0161
+A2020-EM-01-0074
+A2020-NX-01-0361
+C2019-EM-01-0164
+A2020-NX-01-0262
+A2018-EM-01-0551
+C2019-EM-01-0342
+D2020-NX-01-0290
+C2019-EM-01-0228
+A2018-NX-01-0292
+A2019-NX-01-1338
+B2017-EM-01-0005
+A2018-NX-01-0385
+A2015-EM-01-0088
+A2018-EM-01-0944
+A2019-EM-01-0254
+C2018-EM-01-0063
+A2015-EM-01-0234
+A2018-EM-01-0311
+D2019-NX-01-0043
+A2019-NX-01-0916
+A2019-NX-01-0513
+A2019-NX-01-0783
+A2017-EM-01-0463
+A2019-NX-01-0956
+B2013-EM-01-0041
+B2013-EM-01-0078
+D2019-NX-01-0011
+D2019-NX-01-0004
+C2019-EM-01-0140
+A2018-EM-01-0053
+A2019-NX-01-0615
+C2018-EM-01-0062
+A2019-NX-01-1177
+D2020-NX-01-0016
+A2015-EM-01-0077
+A2018-NX-01-0251
+A2019-NX-01-0403
+A2018-EM-01-0793
+A2020-NX-01-0236
+A2018-EM-01-0481
+A2019-NX-01-1508
+A2019-EM-01-0177
+A2019-NX-01-0243
+A2019-NX-01-1197
+A2016-EM-01-0198
+A2019-NX-01-1119
+A2019-EM-01-0058
+A2019-NX-01-0516
+A2019-NX-01-0182
+A2018-EM-01-0532
+D2020-NX-01-0191
+A2018-EM-01-0261
+A2018-EM-01-0575
+C2020-EM-01-0272
+A2018-EM-01-0182
+D2019-NX-01-0169
+A2020-NX-01-0745
+B2017-EM-01-0074
+A2017-EM-01-0307
+B2016-EM-01-0096
+A2019-NX-01-1185
+A2017-EM-01-0133
+A2015-EM-01-0149
+A2018-EM-01-0913
+A2018-EM-01-0806
+B2013-EM-01-0101
+A2019-NX-01-0462
+B2013-EM-01-0059
+A2015-EM-01-0285
+A2020-NX-01-0279
+A2020-NX-01-0199
+A2018-EM-01-0663
+C2019-EM-01-0307
+A2020-NX-01-0369
+A2020-EM-01-0041
+A2018-EM-01-0770
+A2019-NX-01-1488
+B2013-EM-01-0060
+A2018-NX-01-0150
+A2019-NX-01-1654
+A2019-NX-01-0947
+A2019-NX-01-0969
+A2017-EM-01-0498
+B2015-EM-01-0146
+B2017-EM-01-0047
+B2014-EM-01-0005
+A2019-EM-01-0210
+A2018-EM-01-0992
+B2015-EM-01-0043
+A2018-NX-01-0180
+C2019-EM-01-0182
+C2020-EM-01-0264
+A2019-NX-01-0929
+A2016-EM-01-0309
+A2019-NX-01-1154
+A2017-EM-01-0417
+D2020-NX-01-0185
+A2020-NX-01-0420
+A2020-NX-01-0119
+A2019-NX-01-0392
+A2017-EM-01-0010
+D2020-NX-01-0053
+A2019-NX-01-1077
+A2018-EM-01-0908
+A2019-EM-01-0208
+C2018-EM-01-0036
+A2016-EM-01-0106
+A2019-NX-01-0987
+B2015-EM-01-0045
+A2020-NX-01-0476
+A2019-NX-01-1260
+A2019-NX-01-1642
+A2015-EM-01-0368
+A2018-EM-01-1003
+A2018-NX-01-0128
+A2018-EM-01-0374
+A2018-EM-01-0698
+A2017-EM-01-0379
+A2019-EM-01-0087
+A2020-NX-01-0057
+A2020-NX-01-0086
+A2018-EM-01-0168
+A2018-EM-01-0487
+A2019-NX-01-1171
+A2015-EM-01-0436
+C2019-EM-01-0016
+A2019-NX-01-1279
+C2018-EM-01-0335
+C2019-EM-01-0281
+B2019-NX-01-0014
+A2018-EM-01-0485
+B2019-EM-01-0002
+A2017-EM-01-0263
+A2019-NX-01-0439
+A2019-NX-01-0576
+A2015-EM-01-0079
+A2019-NX-01-0110
+D2020-NX-01-0111
+C2020-EM-01-0326
+D2019-NX-01-0238
+A2019-NX-01-0967
+A2020-NX-01-0300
+C2019-EM-01-0287
+A2019-NX-01-0566
+A2019-EM-01-0018
+A2018-NX-01-0328
+B2017-EM-01-0032
+A2018-NX-01-0394
+C2020-EM-01-0098
+D2019-NX-01-0256
+A2020-NX-01-0663
+A2018-NX-01-0161
+A2019-EM-01-0080
+C2019-EM-01-0101
+C2019-EM-01-0014
+C2020-EM-01-0060
+B2016-EM-01-0027
+A2018-EM-01-0617
+C2019-EM-01-0206
+A2019-NX-01-1073
+A2015-EM-01-0391
+A2019-NX-01-1463
+B2014-EM-01-0079
+A2015-EM-01-0150
+A2019-NX-01-0275
+A2018-EM-01-0648
+A2017-EM-01-0158
+A2019-NX-01-0582
+B2016-EM-01-0124
+C2020-EM-01-0245
+A2017-EM-01-0237
+C2018-EM-01-0298
+A2018-NX-01-0344
+C2020-EM-01-0173
+C2019-EM-01-0333
+A2016-EM-01-0181
+D2019-NX-01-0204
+B2015-EM-01-0123
+A2020-EM-01-0077
+A2018-EM-01-0623
+A2019-NX-01-0070
+D2019-NX-01-0069
+A2019-NX-01-0826
+A2015-EM-01-0203
+A2018-EM-01-0096
+A2019-NX-01-0244
+A2019-EM-01-0030
+A2019-EM-01-0297
+A2018-NX-01-0140
+A2020-NX-01-0229
+A2018-EM-01-0898
+A2018-EM-01-0024
+B2016-EM-01-0006
+A2017-EM-01-0166
+A2019-NX-01-1325
+A2019-NX-01-1324
+A2020-NX-01-0188
+B2017-EM-01-0099
+A2020-NX-01-0475
+A2017-EM-01-0418
+A2018-EM-01-0163
+C2018-EM-01-0052
+A2018-EM-01-0829
+B2014-EM-01-0071
+B2019-NX-01-0051
+C2018-EM-01-0175
+A2019-NX-01-0354
+A2018-EM-01-0579
+C2020-EM-01-0341
+A2018-EM-01-0607
+A2019-EM-01-0036
+A2016-EM-01-0049
+C2019-EM-01-0088
+A2018-EM-01-0084
+A2015-EM-01-0419
+A2018-EM-01-0404
+A2015-EM-01-0209
+A2015-EM-01-0244
+C2020-EM-01-0235
+A2020-NX-01-0331
+B2015-EM-01-0078
+C2020-EM-01-0281
+D2020-NX-01-0060
+A2020-NX-01-0053
+A2020-NX-01-0201
+A2020-EM-01-0001
+D2019-NX-01-0153
+A2019-NX-01-0124
+C2018-EM-01-0158
+A2019-NX-01-0422
+C2019-EM-01-0126
+D2020-NX-01-0044
+A2018-EM-01-0893
+A2020-EM-01-0073
+A2018-EM-01-0101
+D2019-NX-01-0010
+A2020-NX-01-0790
+A2020-NX-01-0082
+D2020-NX-01-0020
+A2015-EM-01-0030
+C2018-EM-01-0215
+A2018-NX-01-0414
+B2015-EM-01-0011
+C2019-EM-01-0117
+A2020-NX-01-0002
+B2018-EM-01-0029
+A2018-EM-01-0445
+A2018-EM-01-0276
+C2019-EM-01-0313
+A2018-NX-01-0116
+A2018-EM-01-0368
+A2019-NX-01-1174
+A2019-NX-01-0131
+B2013-EM-01-0036
+C2020-EM-01-0250
+B2015-EM-01-0073
+A2015-EM-01-0007
+A2019-NX-01-0889
+A2017-EM-01-0534
+A2019-NX-01-0747
+A2019-NX-01-1660
+A2016-EM-01-0077
+C2018-EM-01-0032
+A2019-EM-01-0107
+A2018-EM-01-0416
+D2019-NX-01-0003
+A2019-NX-01-1573
+A2019-NX-01-1513
+D2020-NX-01-0212
+A2020-NX-01-0538
+A2016-EM-01-0011
+D2020-NX-01-0276
+A2019-NX-01-0726
+A2019-NX-01-1113
+A2020-NX-01-0508
+A2015-EM-01-0111
+C2018-EM-01-0342
+A2019-NX-01-1640
+A2017-EM-01-0513
+A2019-NX-01-1131
+C2019-EM-01-0141
+A2020-EM-01-0010
+A2019-NX-01-1556
+A2019-NX-01-0608
+C2020-EM-01-0153
+A2019-NX-01-0059
+A2018-EM-01-0678
+A2020-NX-01-0344
+C2019-EM-01-0225
+C2020-EM-01-0058
+A2020-NX-01-0013
+A2019-NX-01-0901
+A2020-EM-01-0060
+A2019-NX-01-0892
+A2020-NX-01-0667
+D2019-NX-01-0228
+D2020-NX-01-0057
+A2019-EM-01-0232
+A2018-EM-01-0792
+A2018-NX-01-0264
+B2014-EM-01-0016
+D2020-NX-01-0251
+A2020-NX-01-0568
+A2019-NX-01-0335
+B2018-EM-01-0184
+A2018-NX-01-0368
+A2016-EM-01-0021
+A2019-NX-01-0167
+A2019-NX-01-1665
+A2019-EM-01-0214
+A2019-NX-01-0010
+A2018-EM-01-0338
+A2017-EM-01-0215
+A2019-NX-01-1500
+A2019-EM-01-0141
+A2018-NX-01-0327
+A2018-NX-01-0276
+B2018-EM-01-0008
+A2020-NX-01-0700
+A2020-NX-01-0525
+A2017-EM-01-0140
+A2017-EM-01-0377
+A2020-NX-01-0129
+A2015-EM-01-0364
+A2020-EM-01-0083
+A2018-NX-01-0042
+A2018-EM-01-0300
+A2017-EM-01-0446
+A2019-NX-01-0218
+B2013-EM-01-0001
+B2013-EM-01-0031
+A2019-NX-01-0501
+B2017-EM-01-0061
+A2015-EM-01-0322
+A2018-EM-01-0636
+A2019-NX-01-0260
+B2013-EM-01-0025
+A2018-EM-01-0669
+B2017-EM-01-0027
+A2019-NX-01-0364
+A2018-EM-01-0504
+C2019-EM-01-0226
+A2017-EM-01-0152
+A2020-NX-01-0139
+C2020-EM-01-0087
+A2020-EM-01-0006
+A2018-EM-01-0316
+B2016-EM-01-0032
+A2019-NX-01-0867
+D2019-NX-01-0188
+C2019-EM-01-0335
+B2015-EM-01-0153
+A2019-NX-01-1641
+A2019-NX-01-0896
+C2018-EM-01-0300
+C2020-EM-01-0311
+A2018-EM-01-0329
+A2015-EM-01-0304
+A2019-NX-01-0827
+B2016-EM-01-0016
+C2019-EM-01-0115
+A2019-NX-01-0663
+A2019-NX-01-1034
+A2018-EM-01-0380
+A2019-NX-01-1266
+B2018-EM-01-0166
+A2017-EM-01-0190
+B2018-EM-01-0179
+B2016-EM-01-0082
+A2019-NX-01-1258
+A2017-EM-01-0487
+C2020-EM-01-0063
+A2018-EM-01-0521
+D2020-NX-01-0265
+A2020-NX-01-0324
+A2018-EM-01-0242
+A2020-NX-01-0766
+D2020-NX-01-0087
+A2019-NX-01-0192
+C2020-EM-01-0135
+A2018-NX-01-0101
+A2019-EM-01-0167
+A2016-EM-01-0036
+A2019-NX-01-0416
+A2018-EM-01-0173
+A2018-NX-01-0162
+A2018-EM-01-0230
+A2017-EM-01-0055
+A2019-NX-01-1417
+A2015-EM-01-0165
+A2018-EM-01-0463
+A2019-NX-01-0614
+A2020-NX-01-0146
+A2019-NX-01-0365
+A2017-EM-01-0425
+A2017-EM-01-0108
+A2019-EM-01-0051
+A2020-NX-01-0462
+A2015-EM-01-0369
+A2019-NX-01-0719
+D2019-NX-01-0106
+D2019-NX-01-0197
+B2015-EM-01-0041
+A2019-EM-01-0204
+C2019-EM-01-0323
+A2020-NX-01-0643
+D2020-NX-01-0180
+B2014-EM-01-0073
+A2019-NX-01-1625
+C2019-EM-01-0360
+C2018-EM-01-0257
+A2019-NX-01-0187
+A2020-NX-01-0752
+A2018-NX-01-0137
+A2019-NX-01-0919
+A2018-EM-01-0215
+A2020-NX-01-0018
+A2019-NX-01-1361
+A2019-NX-01-1444
+A2019-NX-01-1476
+A2018-NX-01-0007
+A2019-NX-01-0092
+B2013-EM-01-0035
+A2018-EM-01-0471
+A2018-NX-01-0418
+A2019-NX-01-1441
+A2016-EM-01-0235
+C2020-EM-01-0217
+A2019-NX-01-1027
+A2016-EM-01-0142
+A2019-NX-01-1610
+B2018-EM-01-0095
+A2019-NX-01-0555
+B2016-EM-01-0122
+A2019-NX-01-1104
+A2016-EM-01-0368
+A2018-EM-01-0362
+A2016-EM-01-0297
+A2018-EM-01-0167
+A2016-EM-01-0194
+A2019-EM-01-0190
+A2020-NX-01-0761
+A2019-NX-01-1198
+B2015-EM-01-0092
+A2018-EM-01-0039
+A2018-EM-01-0554
+A2017-EM-01-0544
+A2018-EM-01-0233
+A2019-NX-01-1430
+A2017-EM-01-0125
+B2014-EM-01-0059
+C2020-EM-01-0115
+A2020-NX-01-0478
+D2020-NX-01-0088
+D2020-NX-01-0043
+C2019-EM-01-0368
+C2020-EM-01-0158
+A2018-EM-01-0449
+A2019-NX-01-1321
+A2019-NX-01-1008
+A2018-EM-01-0868
+C2018-EM-01-0100
+C2020-EM-01-0340
+A2016-EM-01-0245
+D2019-NX-01-0120
+A2019-NX-01-0689
+A2018-NX-01-0223
+D2019-NX-01-0166
+A2019-NX-01-0105
+B2019-NX-01-0060
+D2020-NX-01-0186
+A2020-NX-01-0535
+A2020-NX-01-0518
+A2019-NX-01-1224
+D2019-NX-01-0081
+A2019-NX-01-0299
+B2018-EM-01-0190
+A2019-EM-01-0061
+A2019-NX-01-1633
+D2020-NX-01-0063
+A2020-NX-01-0599
+C2018-EM-01-0222
+A2019-NX-01-1637
+A2017-EM-01-0021
+C2020-EM-01-0059
+A2019-NX-01-0469
+A2017-EM-01-0117
+A2019-NX-01-0759
+A2018-EM-01-0438
+A2018-NX-01-0056
+D2020-NX-01-0122
+C2020-EM-01-0225
+B2019-NX-01-0040
+A2019-NX-01-0774
+A2015-EM-01-0120
+A2018-NX-01-0153
+C2019-EM-01-0163
+A2017-EM-01-0025
+A2016-EM-01-0075
+B2016-EM-01-0099
+B2018-EM-01-0018
+A2020-NX-01-0073
+D2019-NX-01-0233
+A2016-EM-01-0286
+A2017-EM-01-0119
+D2020-NX-01-0077
+B2016-EM-01-0111
+D2020-NX-01-0275
+A2018-NX-01-0048
+A2019-NX-01-1543
+A2018-EM-01-0143
+A2020-NX-01-0784
+A2018-EM-01-0782
+A2019-NX-01-0492
+A2018-EM-01-0427
+A2017-EM-01-0467
+B2016-EM-01-0103
+A2018-EM-01-0995
+A2017-EM-01-0512
+A2019-NX-01-0868
+A2018-NX-01-0004
+A2019-NX-01-0536
+A2020-NX-01-0492
+A2017-EM-01-0046
+A2018-EM-01-0745
+A2020-EM-01-0033
+A2019-NX-01-0353
+B2018-EM-01-0115
+A2019-NX-01-1179
+A2018-EM-01-0825
+B2014-EM-01-0009
+A2019-NX-01-0217
+A2019-NX-01-0672
+B2015-EM-01-0149
+A2018-EM-01-0442
+A2019-EM-01-0143
+A2019-NX-01-0327
+A2016-EM-01-0005
+C2019-EM-01-0231
+A2017-EM-01-0070
+B2018-EM-01-0127
+A2018-NX-01-0219
+A2019-NX-01-0685
+B2018-EM-01-0045
+B2019-EM-01-0011
+A2019-NX-01-1612
+D2019-NX-01-0067
+A2016-EM-01-0397
+A2019-EM-01-0149
+B2018-EM-01-0118
+A2016-EM-01-0219
+D2020-NX-01-0164
+A2018-NX-01-0113
+A2019-NX-01-1478
+A2019-EM-01-0123
+C2020-EM-01-0052
+B2016-EM-01-0084
+A2019-NX-01-1529
+B2013-EM-01-0049
+C2018-EM-01-0346
+A2020-EM-01-0091
+A2018-EM-01-0583
+A2018-NX-01-0218
+A2019-NX-01-1253
+B2019-NX-01-0043
+A2020-NX-01-0389
+A2017-EM-01-0132
+A2019-NX-01-1004
+A2019-NX-01-1518
+A2016-EM-01-0137
+C2020-EM-01-0031
+A2019-NX-01-1187
+A2018-EM-01-0721
+A2017-EM-01-0364
+B2015-EM-01-0074
+A2015-EM-01-0125
+D2020-NX-01-0192
+A2015-EM-01-0343
+C2020-EM-01-0240
+A2020-NX-01-0651
+A2015-EM-01-0443
+B2015-EM-01-0021
+A2018-EM-01-0659
+A2015-EM-01-0104
+B2018-EM-01-0034
+C2019-EM-01-0019
+A2020-EM-01-0047
+A2020-NX-01-0441
+A2019-NX-01-0859
+A2019-NX-01-1155
+A2018-NX-01-0339
+B2018-EM-01-0058
+A2016-EM-01-0094
+A2015-EM-01-0151
+A2018-EM-01-0247
+C2020-EM-01-0040
+D2020-NX-01-0080
+B2018-EM-01-0030
+A2020-NX-01-0730
+A2018-EM-01-0560
+B2018-EM-01-0138
+A2020-NX-01-0741
+A2019-NX-01-1377
+A2019-NX-01-1029
+B2018-EM-01-0098
+A2019-NX-01-0063
+A2019-NX-01-0101
+A2018-NX-01-0234
+A2018-EM-01-0120
+A2017-EM-01-0359
+C2020-EM-01-0152
+A2015-EM-01-0454
+C2018-EM-01-0201
+C2019-EM-01-0236
+A2018-EM-01-0464
+C2020-EM-01-0016
+A2020-EM-01-0037
+A2017-EM-01-0332
+A2019-NX-01-1098
+A2015-EM-01-0426
+A2017-EM-01-0298
+A2020-NX-01-0216
+A2016-EM-01-0233
+C2018-EM-01-0016
+A2019-NX-01-0130
+A2019-NX-01-1207
+A2016-EM-01-0367
+A2019-NX-01-0701
+D2020-NX-01-0161
+A2017-EM-01-0480
+A2020-NX-01-0489
+A2020-NX-01-0714
+A2018-EM-01-0458
+C2020-EM-01-0134
+A2019-NX-01-1530
+A2020-NX-01-0213
+A2019-EM-01-0197
+A2018-EM-01-0592
+A2018-NX-01-0061
+B2015-EM-01-0017
+A2020-EM-01-0026
+A2015-EM-01-0138
+B2016-EM-01-0056
+D2019-NX-01-0016
+A2019-NX-01-1217
+A2019-NX-01-1562
+B2017-EM-01-0016
+A2019-NX-01-1452
+A2017-EM-01-0012
+A2019-NX-01-0261
+D2020-NX-01-0187
+A2020-NX-01-0122
+A2018-EM-01-0805
+A2018-NX-01-0005
+A2020-NX-01-0430
+A2015-EM-01-0229
+C2020-EM-01-0083
+A2015-EM-01-0428
+B2016-EM-01-0061
+A2018-EM-01-0998
+A2015-EM-01-0273
+A2015-EM-01-0028
+C2020-EM-01-0177
+C2019-EM-01-0067
+A2019-NX-01-1663
+A2019-NX-01-0999
+A2015-EM-01-0133
+D2019-NX-01-0079
+A2018-EM-01-0475
+A2019-EM-01-0265
+B2017-EM-01-0090
+C2020-EM-01-0277
+A2019-NX-01-1055
+A2019-NX-01-0803
+A2020-NX-01-0187
+A2020-NX-01-0607
+A2018-EM-01-0689
+A2017-EM-01-0086
+A2016-EM-01-0133
+A2019-NX-01-0071
+A2019-NX-01-0534
+A2018-NX-01-0205
+C2019-EM-01-0200
+A2018-EM-01-0854
+A2019-EM-01-0285
+A2020-NX-01-0036
+A2018-EM-01-0704
+A2017-EM-01-0460
+A2019-NX-01-0058
+A2017-EM-01-0121
+B2019-NX-01-0090
+A2018-EM-01-0990
+D2020-NX-01-0029
+A2019-EM-01-0287
+A2019-EM-01-0156
+A2019-NX-01-1505
+A2020-NX-01-0473
+C2019-EM-01-0005
+A2020-NX-01-0598
+D2020-NX-01-0160
+A2018-EM-01-0558
+A2020-NX-01-0674
+A2018-EM-01-0274
+A2018-EM-01-0477
+A2018-EM-01-0546
+A2019-NX-01-0069
+B2014-EM-01-0010
+A2020-EM-01-0044
+A2017-EM-01-0276
+A2016-EM-01-0004
+A2020-NX-01-0350
+A2018-NX-01-0110
+A2019-NX-01-1235
+A2020-NX-01-0645
+B2016-EM-01-0107
+C2019-EM-01-0189
+C2018-EM-01-0014
+A2018-EM-01-0754
+C2018-EM-01-0322
+A2018-NX-01-0117
+A2018-EM-01-0909
+A2020-NX-01-0338
+A2019-NX-01-0751
+A2020-NX-01-0273
+B2015-EM-01-0048
+A2016-EM-01-0302
+A2019-NX-01-0985
+A2020-NX-01-0274
+B2015-EM-01-0112
+A2018-NX-01-0261
+A2019-NX-01-1110
+A2018-NX-01-0445
+C2020-EM-01-0348
+A2018-NX-01-0074
+A2016-EM-01-0404
+A2017-EM-01-0042
+A2020-NX-01-0226
+C2020-EM-01-0028
+A2016-EM-01-0195
+A2019-NX-01-1421
+B2016-EM-01-0058
+A2017-EM-01-0401
+C2020-EM-01-0139
+A2018-NX-01-0275
+A2019-NX-01-0584
+A2016-EM-01-0335
+A2019-NX-01-0611
+B2017-EM-01-0101
+B2016-EM-01-0118
+D2019-NX-01-0119
+A2018-EM-01-0884
+A2019-NX-01-0246
+A2019-NX-01-0233
+A2020-NX-01-0192
+A2019-EM-01-0203
+A2020-NX-01-0362
+A2019-NX-01-0208
+A2019-NX-01-1606
+A2015-EM-01-0036
+A2019-NX-01-0374
+A2017-EM-01-0066
+D2020-NX-01-0001
+A2017-EM-01-0300
+C2020-EM-01-0260
+A2017-EM-01-0490
+B2015-EM-01-0099
+C2020-EM-01-0125
+C2019-EM-01-0179
+D2019-NX-01-0096
+A2018-EM-01-0102
+A2019-NX-01-1094
+A2020-NX-01-0727
+A2019-NX-01-0918
+A2016-EM-01-0279
+A2015-EM-01-0075
+A2019-NX-01-0119
+A2019-NX-01-1317
+A2018-EM-01-0172
+B2018-EM-01-0172
+A2019-NX-01-0721
+A2019-NX-01-0255
+B2014-EM-01-0011
+A2019-NX-01-0042
+A2019-NX-01-1078
+A2019-NX-01-1509
+A2018-NX-01-0381
+D2019-NX-01-0213
+A2019-NX-01-0917
+A2020-NX-01-0413
+A2018-NX-01-0357
+A2019-NX-01-1340
+C2020-EM-01-0075
+A2018-EM-01-0366
+A2018-NX-01-0393
+D2019-NX-01-0056
+C2018-EM-01-0217
+A2020-EM-01-0054
+A2018-EM-01-0987
+A2019-NX-01-0276
+A2018-EM-01-0326
+A2015-EM-01-0132
+A2019-NX-01-0300
+B2018-EM-01-0026
+A2019-NX-01-1222
+A2019-NX-01-0583
+A2020-NX-01-0022
+A2015-EM-01-0359
+C2020-EM-01-0100
+D2020-NX-01-0026
+A2019-NX-01-1490
+C2018-EM-01-0204
+A2020-NX-01-0471
+A2019-NX-01-0137
+A2016-EM-01-0263
+A2019-NX-01-0352
+C2019-EM-01-0308
+A2020-NX-01-0408
+A2017-EM-01-0521
+D2019-NX-01-0190
+B2014-EM-01-0042
+C2019-EM-01-0357
+C2020-EM-01-0229
+A2019-NX-01-1259
+A2018-EM-01-0848
+B2015-EM-01-0047
+A2017-EM-01-0247
+A2019-NX-01-1475
+B2013-EM-01-0023
+A2018-NX-01-0378
+A2019-NX-01-0331
+A2020-EM-01-0088
+B2017-EM-01-0003
+B2015-EM-01-0064
+A2018-EM-01-0457
+A2020-NX-01-0758
+A2016-EM-01-0252
+A2017-EM-01-0208
+B2015-EM-01-0093
+A2018-NX-01-0307
+D2020-NX-01-0031
+C2020-EM-01-0029
+A2018-NX-01-0365
+A2019-NX-01-0680
+A2019-NX-01-0433
+A2015-EM-01-0188
+A2020-NX-01-0271
+A2019-NX-01-1044
+A2019-NX-01-0764
+D2019-NX-01-0141
+A2018-EM-01-0091
+A2020-NX-01-0532
+A2019-NX-01-0373
+C2018-EM-01-0083
+A2020-EM-01-0055
+A2019-NX-01-1408
+A2019-NX-01-0291
+D2019-NX-01-0015
+D2019-NX-01-0176
+A2019-EM-01-0173
+A2016-EM-01-0338
+A2019-NX-01-0822
+C2019-EM-01-0355
+A2019-NX-01-1244
+A2017-EM-01-0519
+C2019-EM-01-0172
+A2018-EM-01-0480
+A2017-EM-01-0384
+A2020-NX-01-0026
+A2020-NX-01-0067
+C2019-EM-01-0022
+A2018-EM-01-0662
+B2014-EM-01-0012
+A2019-NX-01-1342
+D2019-NX-01-0175
+A2016-EM-01-0101
+A2018-NX-01-0367
+D2020-NX-01-0118
+C2020-EM-01-0023
+A2020-NX-01-0776
+C2020-EM-01-0275
+A2020-EM-01-0069
+A2020-NX-01-0299
+A2019-NX-01-1172
+A2017-EM-01-0477
+A2018-EM-01-0378
+A2015-EM-01-0242
+C2019-EM-01-0011
+D2019-NX-01-0066
+A2019-NX-01-1403
+A2018-NX-01-0360
+C2018-EM-01-0097
+A2019-NX-01-0765
+A2019-NX-01-1193
+A2016-EM-01-0040
+B2015-EM-01-0120
+A2019-NX-01-1202
+A2020-NX-01-0772
+A2020-NX-01-0374
+A2020-NX-01-0291
+A2016-EM-01-0008
+B2017-EM-01-0036
+A2020-NX-01-0258
+A2019-NX-01-0841
+B2019-NX-01-0035
+A2019-NX-01-0554
+A2017-EM-01-0353
+B2017-EM-01-0021
+A2018-EM-01-0285
+A2020-NX-01-0542
+A2017-EM-01-0054
+A2018-EM-01-0302
+C2019-EM-01-0100
+A2020-NX-01-0231
+A2019-NX-01-0844
+A2020-NX-01-0519
+A2015-EM-01-0353
+B2018-EM-01-0010
+B2015-EM-01-0135
+D2019-NX-01-0088
+A2018-EM-01-0355
+B2018-EM-01-0012
+A2018-EM-01-0812
+A2019-NX-01-0345
+A2019-EM-01-0180
+C2019-EM-01-0253
+A2018-NX-01-0380
+A2020-NX-01-0222
+A2019-NX-01-0699
+A2015-EM-01-0089
+A2019-NX-01-1400
+B2017-EM-01-0064
+B2019-NX-01-0025
+C2020-EM-01-0035
+B2013-EM-01-0063
+A2020-NX-01-0555
+A2018-EM-01-0042
+A2020-EM-01-0093
+A2020-NX-01-0722
+A2018-EM-01-0253
+A2016-EM-01-0387
+A2020-NX-01-0078
+A2019-NX-01-1181
+B2017-EM-01-0028
+A2016-EM-01-0071
+C2020-EM-01-0302
+A2018-NX-01-0050
+A2015-EM-01-0035
+A2020-NX-01-0134
+A2015-EM-01-0219
+A2020-NX-01-0685
+A2019-NX-01-0797
+A2019-NX-01-1087
+A2017-EM-01-0478
+A2017-EM-01-0316
+A2020-EM-01-0018
+A2020-NX-01-0750
+A2017-EM-01-0415
+A2020-NX-01-0317
+A2018-NX-01-0029
+A2019-NX-01-1526
+A2020-NX-01-0534
+A2019-NX-01-1507
+B2015-EM-01-0090
+C2019-EM-01-0103
+B2013-EM-01-0005
+A2018-NX-01-0200
+A2018-EM-01-0506
+D2020-NX-01-0123
+A2019-NX-01-0684
+A2017-EM-01-0485
+A2018-NX-01-0322
+A2020-NX-01-0396
+A2016-EM-01-0105
+A2018-EM-01-0897
+A2018-NX-01-0064
+A2020-NX-01-0467
+A2018-EM-01-0252
+D2019-NX-01-0270
+A2019-NX-01-1528
+A2019-EM-01-0150
+B2015-EM-01-0065
+A2016-EM-01-0009
+A2018-EM-01-0555
+D2020-NX-01-0135
+D2020-NX-01-0004
+A2015-EM-01-0296
+A2017-EM-01-0124
+A2015-EM-01-0101
+A2018-NX-01-0435
+A2019-NX-01-1458
+A2020-NX-01-0214
+A2019-NX-01-0533
+A2019-NX-01-0277
+B2016-EM-01-0089
+A2020-NX-01-0224
+A2017-EM-01-0390
+B2013-EM-01-0011
+A2019-NX-01-0863
+B2014-EM-01-0015
+A2018-EM-01-0170
+A2017-EM-01-0128
+C2020-EM-01-0289
+A2019-EM-01-0272
+A2019-NX-01-0547
+A2019-NX-01-0447
+A2019-NX-01-0048
+A2019-NX-01-0564
+A2017-EM-01-0264
+A2016-EM-01-0197
+A2016-EM-01-0190
+D2019-NX-01-0029
+A2016-EM-01-0385
+B2016-EM-01-0012
+D2020-NX-01-0106
+A2015-EM-01-0360
+A2019-NX-01-0414
+A2018-EM-01-0232
+A2018-NX-01-0135
+A2016-EM-01-0266
+A2020-NX-01-0247
+C2020-EM-01-0342
+A2018-EM-01-0154
+B2015-EM-01-0128
+B2017-EM-01-0006
+A2016-EM-01-0168
+A2020-NX-01-0582
+D2019-NX-01-0154
+A2018-NX-01-0358
+A2018-NX-01-0363
+B2014-EM-01-0037
+A2015-EM-01-0232
+A2019-EM-01-0081
+A2015-EM-01-0251
+A2018-EM-01-0347
+A2018-EM-01-0413
+C2019-EM-01-0032
+C2019-EM-01-0123
+A2015-EM-01-0406
+A2020-NX-01-0050
+A2019-NX-01-0030
+A2020-NX-01-0325
+A2020-NX-01-0550
+C2019-EM-01-0048
+A2020-NX-01-0782
+A2015-EM-01-0382
+A2018-NX-01-0015
+A2020-NX-01-0485
+A2018-EM-01-0264
+A2017-EM-01-0022
+A2017-EM-01-0227
+A2019-NX-01-1495
+A2019-NX-01-0129
+A2020-NX-01-0360
+D2020-NX-01-0005
+A2020-EM-01-0031
+A2018-NX-01-0331
+B2018-EM-01-0139
+C2019-EM-01-0238
+A2019-NX-01-0292
+A2015-EM-01-0045
+A2018-EM-01-0007
+A2016-EM-01-0109
+A2019-NX-01-0430
+A2018-EM-01-0571
+C2018-EM-01-0229
+A2019-NX-01-0599
+A2019-NX-01-1415
+B2013-EM-01-0094
+A2019-EM-01-0100
+B2016-EM-01-0113
+D2020-NX-01-0011
+A2018-NX-01-0031
+D2019-NX-01-0260
+A2018-EM-01-0634
+B2018-EM-01-0120
+A2020-NX-01-0241
+D2020-NX-01-0199
+B2018-EM-01-0181
+C2019-EM-01-0348
+A2019-NX-01-1650
+A2019-NX-01-0180
+B2017-EM-01-0052
+D2019-NX-01-0225
+A2019-NX-01-0294
+D2019-NX-01-0236
+A2016-EM-01-0189
+A2019-NX-01-1601
+A2015-EM-01-0405
+C2018-EM-01-0004
+A2017-EM-01-0495
+B2015-EM-01-0152
+A2017-EM-01-0114
+A2016-EM-01-0389
+C2020-EM-01-0160
+A2019-NX-01-1268
+A2020-NX-01-0410
+A2018-EM-01-0522
+A2020-NX-01-0232
+D2020-NX-01-0268
+A2018-EM-01-0152
+A2020-NX-01-0605
+A2018-NX-01-0155
+A2019-NX-01-1261
+C2020-EM-01-0146
+A2020-NX-01-0481
+A2018-NX-01-0059
+A2018-NX-01-0421
+A2020-NX-01-0493
+C2019-EM-01-0040
+A2017-EM-01-0282
+C2019-EM-01-0176
+C2019-EM-01-0106
+A2020-NX-01-0295
+A2019-NX-01-0716
+A2015-EM-01-0085
+A2018-EM-01-0612
+C2018-EM-01-0049
+C2020-EM-01-0078
+A2020-NX-01-0505
+A2016-EM-01-0415
+A2020-NX-01-0209
+A2019-NX-01-1506
+A2019-EM-01-0277
+A2018-EM-01-0069
+A2019-NX-01-0570
+D2019-NX-01-0110
+C2020-EM-01-0327
+B2015-EM-01-0054
+A2015-EM-01-0412
+A2017-EM-01-0552
+A2020-NX-01-0186
+C2020-EM-01-0297
+D2019-NX-01-0044
+A2019-NX-01-0202
+A2019-NX-01-1599
+A2016-EM-01-0007
+A2015-EM-01-0457
+B2018-EM-01-0094
+A2018-EM-01-0682
+A2018-EM-01-0547
+A2020-NX-01-0738
+B2017-EM-01-0050
+A2015-EM-01-0397
+A2016-EM-01-0248
+A2020-NX-01-0417
+A2018-EM-01-0725
+A2020-EM-01-0022
+C2018-EM-01-0220
+A2019-NX-01-1667
+A2019-NX-01-0183
+A2019-EM-01-0155
+A2019-NX-01-0587
+A2016-EM-01-0121
+B2013-EM-01-0020
+A2015-EM-01-0183
+C2018-EM-01-0128
+A2018-EM-01-0410
+A2020-NX-01-0267
+D2020-NX-01-0039
+C2020-EM-01-0091
+A2018-NX-01-0130
+A2019-NX-01-0412
+A2019-NX-01-0179
+D2019-NX-01-0050
+A2016-EM-01-0313
+A2016-EM-01-0391
+A2019-NX-01-1247
+A2018-EM-01-0072
+A2020-EM-01-0065
+A2017-EM-01-0071
+A2019-NX-01-0817
+A2019-NX-01-1293
+A2019-NX-01-1632
+A2019-NX-01-0872
+D2020-NX-01-0225
+B2013-EM-01-0061
+A2018-NX-01-0006
+A2017-EM-01-0488
+A2017-EM-01-0518
+A2020-NX-01-0211
+A2019-NX-01-1069
+A2020-NX-01-0435
+B2015-EM-01-0124
+C2018-EM-01-0077
+A2016-EM-01-0095
+A2019-NX-01-0961
+B2018-EM-01-0123
+A2015-EM-01-0172
+C2019-EM-01-0366
+D2020-NX-01-0277
+A2019-NX-01-0777
+A2020-EM-01-0003
+A2019-NX-01-0198
+A2018-EM-01-0428
+A2019-NX-01-0671
+B2017-EM-01-0026
+A2018-NX-01-0210
+A2018-NX-01-0439
+A2018-EM-01-0540
+C2019-EM-01-0363
+A2018-NX-01-0196
+A2016-EM-01-0277
+A2019-EM-01-0252
+A2019-NX-01-0830
+A2016-EM-01-0165
+A2018-EM-01-0130
+C2020-EM-01-0022
+C2019-EM-01-0127
+C2019-EM-01-0297
+A2018-EM-01-0206
+A2016-EM-01-0026
+A2017-EM-01-0374
+A2018-EM-01-0735
+A2020-NX-01-0567
+A2018-EM-01-0486
+A2015-EM-01-0129
+D2020-NX-01-0024
+A2017-EM-01-0416
+A2019-NX-01-1115
+A2019-NX-01-0781
+A2015-EM-01-0094
+A2019-NX-01-0645
+A2019-NX-01-1075
+A2017-EM-01-0312
+C2019-EM-01-0078
+A2019-NX-01-1043
+C2018-EM-01-0240
+A2019-EM-01-0257
+A2017-EM-01-0222
+A2019-EM-01-0095
+A2019-NX-01-0068
+A2020-NX-01-0735
+A2017-EM-01-0116
+A2019-NX-01-0121
+B2015-EM-01-0004
+C2019-EM-01-0077
+A2017-EM-01-0437
+A2019-NX-01-0963
+A2020-NX-01-0693
+A2019-NX-01-0734
+A2019-NX-01-0308
+A2016-EM-01-0244
+A2018-EM-01-0402
+C2020-EM-01-0294
+A2018-NX-01-0111
+A2018-EM-01-0604
+A2018-EM-01-0970
+A2018-EM-01-0105
+C2018-EM-01-0364
+D2019-NX-01-0094
+D2020-NX-01-0115
+A2016-EM-01-0023
+A2020-NX-01-0655
+D2019-NX-01-0118
+A2019-EM-01-0003
+A2015-EM-01-0070
+A2019-NX-01-1211
+D2019-NX-01-0249
+A2019-NX-01-0496
+A2017-EM-01-0336
+A2019-EM-01-0110
+B2018-EM-01-0092
+A2017-EM-01-0027
+D2020-NX-01-0177
+B2016-EM-01-0036
+A2019-EM-01-0234
+A2017-EM-01-0258
+A2019-NX-01-1234
+C2020-EM-01-0350
+A2018-EM-01-0896
+C2019-EM-01-0204
+A2019-NX-01-0728
+A2019-NX-01-1127
+A2017-EM-01-0528
+A2017-EM-01-0302
+A2017-EM-01-0197
+C2019-EM-01-0085
+A2019-NX-01-0693
+C2019-EM-01-0086
+A2019-NX-01-0871
+A2019-NX-01-1071
+A2018-EM-01-0747
+A2017-EM-01-0023
+B2015-EM-01-0040
+B2018-EM-01-0082
+C2019-EM-01-0197
+A2019-NX-01-0035
+A2019-NX-01-0480
+A2020-EM-01-0005
+C2019-EM-01-0269
+B2014-EM-01-0082
+B2016-EM-01-0048
+C2020-EM-01-0192
+A2019-NX-01-1432
+A2020-NX-01-0208
+C2019-EM-01-0166
+A2017-EM-01-0511
+C2020-EM-01-0008
+A2019-NX-01-0761
+A2018-NX-01-0053
+A2018-EM-01-0620
+C2018-EM-01-0055
+B2014-EM-01-0026
+A2019-NX-01-1578
+B2017-EM-01-0069
+B2018-EM-01-0158
+A2017-EM-01-0246
+A2016-EM-01-0214
+A2020-NX-01-0334
+A2018-EM-01-0981
+C2019-EM-01-0227
+A2019-EM-01-0023
+C2019-EM-01-0315
+C2019-EM-01-0325
+D2019-NX-01-0265
+C2019-EM-01-0370
+C2020-EM-01-0309
+A2019-NX-01-1555
+C2018-EM-01-0038
+A2019-NX-01-0368
+A2016-EM-01-0295
+A2018-NX-01-0211
+C2019-EM-01-0254
+A2020-NX-01-0591
+B2015-EM-01-0137
+A2018-EM-01-0631
+A2019-NX-01-0714
+A2019-NX-01-0752
+B2017-EM-01-0083
+A2016-EM-01-0092
+A2017-EM-01-0001
+A2019-NX-01-0023
+A2018-EM-01-0585
+A2015-EM-01-0399
+B2013-EM-01-0098
+D2020-NX-01-0269
+D2020-NX-01-0137
+A2018-NX-01-0212
+A2019-NX-01-1060
+A2018-NX-01-0193
+A2019-NX-01-1643
+D2020-NX-01-0171
+A2019-NX-01-0683
+A2020-NX-01-0164
+A2019-NX-01-0033
+A2020-NX-01-0168
+C2018-EM-01-0027
+A2020-NX-01-0074
+A2020-NX-01-0066
+D2020-NX-01-0109
+A2017-EM-01-0354
+A2018-EM-01-0324
+A2018-NX-01-0017
+D2020-NX-01-0034
+A2018-EM-01-0601
+A2020-EM-01-0024
+C2018-EM-01-0282
+A2018-NX-01-0335
+A2020-NX-01-0677
+A2019-NX-01-1547
+A2019-EM-01-0024
+A2019-EM-01-0007
+C2019-EM-01-0345
+A2020-NX-01-0642
+D2019-NX-01-0262
+A2016-EM-01-0053
+A2019-NX-01-0654
+A2018-EM-01-0198
+A2016-EM-01-0059
+B2015-EM-01-0016
+C2020-EM-01-0243
+C2020-EM-01-0316
+A2017-EM-01-0386
+B2016-EM-01-0112
+A2020-EM-01-0035
+A2019-NX-01-0708
+A2018-EM-01-0098
+B2018-EM-01-0084
+A2019-NX-01-0122
+A2019-NX-01-0655
+A2015-EM-01-0356
+A2018-EM-01-0582
+A2019-NX-01-0732
+A2019-NX-01-1062
+A2015-EM-01-0338
+A2018-EM-01-0043
+A2019-NX-01-0874
+A2020-NX-01-0577
+A2018-EM-01-0451
+A2019-NX-01-0811
+A2018-EM-01-0051
+A2020-NX-01-0511
+A2017-EM-01-0309
+A2019-EM-01-0006
+C2020-EM-01-0238
+C2018-EM-01-0090
+A2018-EM-01-0968
+A2017-EM-01-0058
+A2019-NX-01-0945
+C2018-EM-01-0043
+A2017-EM-01-0167
+B2017-EM-01-0080
+A2018-EM-01-0613
+A2018-EM-01-0823
+A2016-EM-01-0088
+A2017-EM-01-0338
+A2019-NX-01-0389
+A2020-NX-01-0432
+A2016-EM-01-0039
+A2020-NX-01-0639
+D2019-NX-01-0070
+A2017-EM-01-0419
+A2019-NX-01-1086
+A2020-NX-01-0434
+A2019-NX-01-0876
+C2019-EM-01-0256
+A2019-NX-01-1305
+A2016-EM-01-0044
+B2016-EM-01-0086
+A2019-NX-01-1047
+A2017-EM-01-0193
+A2019-NX-01-0650
+A2018-EM-01-0645
+A2019-NX-01-0478
+B2014-EM-01-0092
+A2016-EM-01-0201
+B2017-EM-01-0035
+A2020-NX-01-0469
+A2018-EM-01-0371
+A2016-EM-01-0006
+A2016-EM-01-0340
+A2015-EM-01-0370
+A2019-EM-01-0251
+A2018-EM-01-0511
+A2019-NX-01-0356
+A2019-EM-01-0250
+C2020-EM-01-0071
+C2019-EM-01-0188
+A2020-NX-01-0720
+A2020-NX-01-0055
+A2018-EM-01-0334
+A2019-NX-01-0091
+A2018-EM-01-0581
+A2020-NX-01-0042
+A2018-EM-01-0672
+A2017-EM-01-0146
+A2017-EM-01-0313
+A2019-NX-01-0456
+A2019-NX-01-0938
+B2014-EM-01-0040
+B2015-EM-01-0053
+A2020-EM-01-0007
+A2018-EM-01-0327
+A2018-EM-01-0204
+A2019-NX-01-0270
+A2018-NX-01-0043
+C2019-EM-01-0174
+A2018-EM-01-0665
+B2015-EM-01-0140
+A2019-NX-01-0268
+A2020-NX-01-0155
+A2016-EM-01-0393
+A2018-NX-01-0105
+C2020-EM-01-0101
+A2019-NX-01-0548
+A2020-NX-01-0402
+A2019-NX-01-0418
+A2019-NX-01-0898
+B2019-NX-01-0074
+A2019-NX-01-0509
+C2019-EM-01-0327
+A2020-NX-01-0045
+A2018-EM-01-0753
+A2015-EM-01-0420
+A2018-EM-01-0866
+B2018-EM-01-0106
+C2020-EM-01-0210
+B2014-EM-01-0068
+A2018-EM-01-0791
+A2019-EM-01-0220
+A2016-EM-01-0300
+A2020-NX-01-0498
+C2018-EM-01-0187
+D2020-NX-01-0037
+C2019-EM-01-0319
+B2016-EM-01-0033
+A2020-NX-01-0322
+A2015-EM-01-0041
+B2017-EM-01-0024
+A2020-NX-01-0332
+C2020-EM-01-0337
+A2020-NX-01-0433
+B2017-EM-01-0075
+B2019-EM-01-0021
+A2017-EM-01-0348
+A2018-EM-01-0210
+A2019-EM-01-0154
+C2019-EM-01-0036
+A2017-EM-01-0346
+B2014-EM-01-0007
+A2020-NX-01-0153
+A2019-NX-01-0178
+A2019-NX-01-0067
+A2018-EM-01-0289
+C2020-EM-01-0102
+A2015-EM-01-0252
+A2015-EM-01-0416
+A2019-EM-01-0063
+A2018-EM-01-0384
+B2016-EM-01-0129
+A2019-NX-01-1446
+A2019-EM-01-0213
+B2015-EM-01-0133
+A2018-EM-01-0176
+A2019-NX-01-0886
+A2020-NX-01-0694
+B2016-EM-01-0076
+A2016-EM-01-0363
+A2018-NX-01-0065
+A2015-EM-01-0159
+C2020-EM-01-0003
+A2018-EM-01-0781
+A2019-EM-01-0112
+B2014-EM-01-0095
+A2015-EM-01-0308
+A2018-NX-01-0010
+B2013-EM-01-0095
+A2018-EM-01-0646
+B2016-EM-01-0105
+A2020-NX-01-0145
+A2018-EM-01-0967
+A2019-NX-01-1039
+A2019-NX-01-1011
+B2016-EM-01-0041
+A2017-EM-01-0350
+D2020-NX-01-0025
+A2020-NX-01-0157
+A2018-EM-01-0928
+C2018-EM-01-0008
+A2019-NX-01-1353
+C2020-EM-01-0175
+C2020-EM-01-0280
+A2018-EM-01-0722
+A2019-EM-01-0187
+A2018-EM-01-0256
+A2019-EM-01-0144
+A2018-EM-01-0729
+A2019-NX-01-0704
+C2020-EM-01-0112
+A2019-NX-01-1395
+A2018-EM-01-0766
+A2019-NX-01-1409
+A2018-EM-01-0936
+A2019-NX-01-0125
+B2019-EM-01-0006
+A2018-EM-01-0899
+A2015-EM-01-0408
+B2014-EM-01-0014
+A2019-NX-01-0127
+A2019-NX-01-0703
+A2017-EM-01-0340
+A2019-NX-01-0749
+A2018-EM-01-0946
+A2019-NX-01-1189
+A2017-EM-01-0365
+A2016-EM-01-0396
+A2018-EM-01-0078
+A2015-EM-01-0363
+B2018-EM-01-0078
+A2019-NX-01-0238
+D2020-NX-01-0130
+A2019-NX-01-1017
+A2018-EM-01-0804
+A2019-NX-01-1434
+A2018-EM-01-0505
+A2017-EM-01-0004
+A2018-EM-01-0734
+C2020-EM-01-0117
+A2020-NX-01-0676
+A2019-EM-01-0259
+D2020-NX-01-0279
+A2019-NX-01-1175
+A2019-EM-01-0045
+B2018-EM-01-0161
+A2016-EM-01-0041
+A2018-EM-01-0179
+A2015-EM-01-0130
+A2018-EM-01-0498
+A2020-NX-01-0733
+A2018-EM-01-0872
+A2020-NX-01-0085
+C2018-EM-01-0250
+A2019-NX-01-0558
+A2018-NX-01-0355
+A2019-NX-01-0241
+A2018-EM-01-0692
+A2018-NX-01-0324
+A2015-EM-01-0409
+A2020-NX-01-0180
+A2017-EM-01-0122
+A2019-NX-01-0314
+A2017-EM-01-0127
+B2017-EM-01-0033
+A2018-EM-01-0046
+A2020-NX-01-0354
+A2018-EM-01-0491
+B2019-NX-01-0047
+A2018-EM-01-0209
+A2020-NX-01-0452
+A2020-NX-01-0463
+A2019-NX-01-0054
+C2020-EM-01-0042
+A2019-NX-01-0223
+A2020-NX-01-0514
+A2019-NX-01-0888
+B2016-EM-01-0091
+A2019-NX-01-1208
+C2020-EM-01-0319
+A2020-NX-01-0052
+A2019-NX-01-0421
+A2019-NX-01-0873
+D2020-NX-01-0054
+A2019-NX-01-0045
+A2018-NX-01-0319
+A2018-NX-01-0100
+A2020-NX-01-0593
+A2019-NX-01-0317
+A2017-EM-01-0430
+A2018-EM-01-0957
+A2015-EM-01-0385
+B2018-EM-01-0011
+A2019-NX-01-1406
+B2016-EM-01-0109
+A2020-NX-01-0075
+B2019-EM-01-0003
+C2019-EM-01-0131
+C2018-EM-01-0143
+A2020-NX-01-0619
+C2020-EM-01-0021
+C2018-EM-01-0274
+A2019-NX-01-1656
+A2018-EM-01-0807
+A2019-EM-01-0001
+A2020-NX-01-0554
+A2019-NX-01-1229
+A2020-NX-01-0670
+A2017-EM-01-0017
+A2018-NX-01-0291
+A2019-NX-01-0358
+A2019-EM-01-0294
+D2019-NX-01-0022
+D2019-NX-01-0072
+A2019-NX-01-0729
+A2019-EM-01-0145
+A2019-NX-01-1535
+A2019-NX-01-0089
+A2018-NX-01-0342
+A2019-NX-01-0877
+C2019-EM-01-0029
+A2016-EM-01-0262
+A2018-EM-01-0691
+B2015-EM-01-0147
+D2019-NX-01-0252
+A2018-NX-01-0333
+B2015-EM-01-0005
+A2018-NX-01-0287
+D2020-NX-01-0030
+A2018-EM-01-0412
+C2018-EM-01-0137
+A2019-NX-01-0740
+A2020-EM-01-0076
+A2020-NX-01-0357
+A2020-NX-01-0116
+A2017-EM-01-0205
+A2018-EM-01-0820
+A2018-EM-01-0984
+A2020-NX-01-0263
+A2017-EM-01-0285
+A2019-NX-01-1447
+A2020-NX-01-0127
+A2017-EM-01-0281
+A2017-EM-01-0496
+A2015-EM-01-0398
+A2018-EM-01-0291
+D2020-NX-01-0200
+C2020-EM-01-0124
+D2020-NX-01-0074
+A2019-NX-01-1372
+D2020-NX-01-0046
+A2020-EM-01-0043
+A2016-EM-01-0034
+A2018-EM-01-0737
+A2019-NX-01-0814
+C2019-EM-01-0371
+A2019-NX-01-0890
+D2020-NX-01-0090
+B2017-EM-01-0043
+A2015-EM-01-0184
+A2016-EM-01-0143
+A2019-NX-01-0815
+A2018-EM-01-0292
+A2019-NX-01-0579
+A2015-EM-01-0113
+A2018-EM-01-0342
+C2018-EM-01-0005
+A2018-EM-01-0352
+A2015-EM-01-0185
+D2019-NX-01-0155
+A2015-EM-01-0105
+A2017-EM-01-0491
+A2016-EM-01-0091
+A2019-NX-01-0156
+C2020-EM-01-0171
+A2017-EM-01-0378
+A2017-EM-01-0136
+A2020-NX-01-0092
+A2019-NX-01-0106
+A2019-NX-01-1304
+A2018-NX-01-0311
+A2019-EM-01-0133
+C2020-EM-01-0180
+A2017-EM-01-0522
+A2017-EM-01-0541
+A2016-EM-01-0380
+A2018-NX-01-0036
+C2018-EM-01-0332
+A2015-EM-01-0205
+A2018-EM-01-0599
+A2015-EM-01-0109
+A2019-NX-01-1161
+A2020-NX-01-0268
+A2019-NX-01-1466
+A2016-EM-01-0394
+C2019-EM-01-0299
+D2019-NX-01-0230
+A2015-EM-01-0278
+A2018-EM-01-0762
+A2020-NX-01-0580
+C2020-EM-01-0143
+D2020-NX-01-0081
+A2020-NX-01-0147
+A2018-NX-01-0012
+A2016-EM-01-0408
+A2015-EM-01-0033
+A2018-EM-01-0325
+A2018-NX-01-0325
+A2020-NX-01-0614
+D2019-NX-01-0059
+A2016-EM-01-0057
+A2020-NX-01-0522
+B2016-EM-01-0104
+A2019-NX-01-1206
+A2017-EM-01-0219
+A2015-EM-01-0357
+A2020-NX-01-0112
+B2013-EM-01-0106
+A2018-EM-01-0488
+A2018-NX-01-0345
+A2016-EM-01-0403
+A2018-NX-01-0040
+B2019-EM-01-0046
+A2019-NX-01-0592
+A2019-NX-01-0285
+A2015-EM-01-0328
+A2017-EM-01-0036
+A2018-EM-01-0273
+D2020-NX-01-0286
+A2019-NX-01-0988
+A2015-EM-01-0019
+A2019-NX-01-1511
+A2019-NX-01-0077
+A2016-EM-01-0237
+A2019-EM-01-0218
+C2020-EM-01-0233
+A2016-EM-01-0364
+A2019-EM-01-0016
+A2018-EM-01-0853
+A2020-NX-01-0715
+B2014-EM-01-0094
+A2020-NX-01-0141
+B2016-EM-01-0045
+C2018-EM-01-0142
+A2017-EM-01-0089
+B2017-EM-01-0085
+A2019-NX-01-0384
+A2019-NX-01-0199
+B2019-EM-01-0004
+B2014-EM-01-0013
+D2020-NX-01-0218
+A2019-NX-01-1391
+C2019-EM-01-0112
+B2017-EM-01-0010
+B2013-EM-01-0091
+D2020-NX-01-0194
+A2020-NX-01-0702
+A2018-EM-01-0407
+A2018-EM-01-0533
+A2019-NX-01-0724
+C2020-EM-01-0206
+A2018-NX-01-0453
+A2018-NX-01-0382
+A2015-EM-01-0302
+C2020-EM-01-0220
+D2019-NX-01-0198
+A2017-EM-01-0469
+A2018-EM-01-0056
+A2018-EM-01-0732
+D2019-NX-01-0061
+B2017-EM-01-0088
+A2019-NX-01-0002
+A2018-EM-01-0138
+A2018-NX-01-0058
+A2018-EM-01-0260
+A2019-EM-01-0140
+C2018-EM-01-0086
+A2019-EM-01-0008
+A2020-NX-01-0765
+A2019-NX-01-0730
+A2015-EM-01-0137
+A2018-NX-01-0255
+A2018-EM-01-0151
+A2019-NX-01-1357
+A2019-NX-01-1192
+D2020-NX-01-0133
+B2018-EM-01-0191
+A2015-EM-01-0282
+C2019-EM-01-0252
+A2015-EM-01-0097
+B2013-EM-01-0088
+B2018-EM-01-0155
+A2019-NX-01-1489
+D2020-NX-01-0098
+A2019-NX-01-0213
+A2019-NX-01-1053
+C2020-EM-01-0176
+A2019-NX-01-0600
+A2018-EM-01-0867
+A2019-NX-01-0486
+A2020-NX-01-0351
+A2018-EM-01-0166
+C2019-EM-01-0158
+A2020-NX-01-0314
+A2015-EM-01-0046
+A2020-NX-01-0628
+A2020-NX-01-0321
+A2015-EM-01-0112
+A2018-NX-01-0316
+A2018-EM-01-0246
+A2015-EM-01-0093
+C2018-EM-01-0301
+C2019-EM-01-0157
+A2017-EM-01-0328
+B2016-EM-01-0010
+A2019-NX-01-0622
+B2013-EM-01-0093
+D2019-NX-01-0077
+C2018-EM-01-0167
+A2017-EM-01-0555
+A2018-EM-01-0040
+A2020-NX-01-0443
+D2019-NX-01-0264
+D2020-NX-01-0091
+D2020-NX-01-0089
+B2019-EM-01-0020
+A2015-EM-01-0080
+A2019-NX-01-0052
+A2019-NX-01-0420
+A2018-NX-01-0154
+B2018-EM-01-0143
+A2020-NX-01-0237
+A2020-NX-01-0744
+A2019-NX-01-0723
+A2018-NX-01-0449
+A2020-NX-01-0054
+A2016-EM-01-0330
+A2018-EM-01-0749
+D2020-NX-01-0062
+B2014-EM-01-0028
+A2020-NX-01-0585
+C2019-EM-01-0309
+B2015-EM-01-0079
+A2017-EM-01-0412
+C2019-EM-01-0369
+A2017-EM-01-0462
+A2018-EM-01-0832
+A2016-EM-01-0425
+A2020-NX-01-0445
+A2016-EM-01-0240
+A2019-NX-01-0257
+A2019-NX-01-0224
+A2016-EM-01-0003
+A2020-NX-01-0536
+A2015-EM-01-0430
+D2019-NX-01-0046
+A2019-NX-01-0073
+C2020-EM-01-0106
+A2019-EM-01-0239
+A2019-NX-01-1384
+A2019-NX-01-0385
+A2020-NX-01-0406
+C2020-EM-01-0254
+A2020-NX-01-0378
+A2019-EM-01-0114
+A2019-NX-01-0943
+A2020-NX-01-0477
+A2017-EM-01-0529
+A2019-EM-01-0280
+A2017-EM-01-0395
+A2020-NX-01-0561
+C2018-EM-01-0034
+A2016-EM-01-0267
+A2019-NX-01-0410
+A2015-EM-01-0464
+A2018-EM-01-0057
+A2019-NX-01-0840
+A2019-NX-01-1163
+A2019-NX-01-0278
+A2017-EM-01-0184
+A2018-EM-01-0709
+C2020-EM-01-0034
+A2015-EM-01-0114
+A2018-EM-01-0510
+B2018-EM-01-0014
+A2019-NX-01-0366
+C2020-EM-01-0164
+B2013-EM-01-0026
+A2018-EM-01-0688
+A2017-EM-01-0538
+A2020-NX-01-0005
+A2020-EM-01-0072
+D2019-NX-01-0223
+C2018-EM-01-0020
+A2018-NX-01-0208
+C2020-EM-01-0211
+A2019-NX-01-0220
+A2019-NX-01-0936
+A2019-NX-01-0174
+C2019-EM-01-0028
+C2018-EM-01-0248
+D2020-NX-01-0271
+A2018-EM-01-0902
+A2019-NX-01-1418
+A2019-NX-01-0371
+A2018-EM-01-0328
+A2019-NX-01-0975
+C2018-EM-01-0242
+A2019-NX-01-0338
+A2017-EM-01-0306
+B2015-EM-01-0038
+A2015-EM-01-0371
+A2019-NX-01-0376
+A2019-NX-01-1089
+A2018-EM-01-0993
+A2020-NX-01-0062
+C2019-EM-01-0303
+A2019-NX-01-0082
+C2018-EM-01-0247
+A2020-NX-01-0336
+A2019-NX-01-0133
+D2020-NX-01-0182
+A2015-EM-01-0249
+A2019-NX-01-0866
+A2019-NX-01-0647
+A2017-EM-01-0380
+A2019-NX-01-1176
+A2017-EM-01-0082
+A2018-NX-01-0230
+A2019-NX-01-0493
+A2020-NX-01-0610
+A2020-NX-01-0594
+A2017-EM-01-0360
+A2019-NX-01-0831
+A2018-EM-01-0405
+B2019-NX-01-0019
+D2020-NX-01-0278
+D2020-NX-01-0028
+A2019-NX-01-0411
+A2019-NX-01-1638
+A2019-NX-01-0959
+A2018-EM-01-0430
+A2018-EM-01-0183
+A2018-EM-01-0479
+A2019-NX-01-1226
+A2019-NX-01-1281
+A2017-EM-01-0321
+D2020-NX-01-0183
+A2019-NX-01-0661
+B2013-EM-01-0090
+A2018-EM-01-0109
+A2016-EM-01-0413
+A2018-EM-01-0502
+A2018-EM-01-0603
+A2018-EM-01-0379
+A2017-EM-01-0388
+A2019-NX-01-0879
+A2018-EM-01-0073
+A2019-NX-01-1407
+A2015-EM-01-0295
+A2018-NX-01-0086
+B2018-EM-01-0117
+D2019-NX-01-0237
+B2018-EM-01-0152
+C2019-EM-01-0146
+A2020-NX-01-0506
+A2015-EM-01-0100
+A2018-NX-01-0260
+A2019-NX-01-1265
+A2020-NX-01-0549
+A2020-NX-01-0404
+A2019-NX-01-1504
+A2020-NX-01-0206
+A2019-EM-01-0082
+A2018-EM-01-0890
+D2019-NX-01-0024
+C2019-EM-01-0272
+B2015-EM-01-0009
+A2019-NX-01-0575
+A2019-NX-01-0725
+A2015-EM-01-0186
+A2019-EM-01-0035
+A2015-EM-01-0017
+A2020-EM-01-0017
+A2020-NX-01-0631
+A2020-NX-01-0076
+A2020-NX-01-0277
+C2018-EM-01-0239
+B2016-EM-01-0013
+A2018-EM-01-0281
+C2018-EM-01-0019
+B2015-EM-01-0007
+A2019-NX-01-1609
+A2020-NX-01-0407
+C2018-EM-01-0211
+A2019-NX-01-1577
+A2019-NX-01-0664
+A2019-NX-01-0117
+A2019-EM-01-0015
+C2018-EM-01-0039
+A2020-NX-01-0446
+A2017-EM-01-0452
+A2018-NX-01-0423
+C2019-EM-01-0039
+B2017-EM-01-0011
+A2018-EM-01-0240
+A2020-NX-01-0501
+A2019-NX-01-0301
+D2019-NX-01-0101
+B2013-EM-01-0085
+A2015-EM-01-0445
+B2013-EM-01-0070
+A2016-EM-01-0254
+C2019-EM-01-0154
+A2019-NX-01-0755
+C2019-EM-01-0296
+A2018-EM-01-0358
+A2018-EM-01-0922
+A2019-NX-01-1054
+C2018-EM-01-0132
+A2019-NX-01-0530
+B2015-EM-01-0103
+A2019-NX-01-0016
+A2019-NX-01-0630
+A2018-EM-01-0869
+A2017-EM-01-0041
+A2018-EM-01-0496
+C2019-EM-01-0235
+A2019-NX-01-1600
+A2019-NX-01-0505
+A2016-EM-01-0163
+A2017-EM-01-0096
+A2018-EM-01-0385
+A2019-NX-01-0487
+A2018-EM-01-0611
+A2018-EM-01-0800
+A2019-EM-01-0258
+A2018-NX-01-0034
+C2018-EM-01-0183
+C2019-EM-01-0168
+D2019-NX-01-0224
+C2019-EM-01-0247
+A2019-NX-01-0046
+B2015-EM-01-0122
+A2018-NX-01-0088
+A2019-NX-01-0049
+A2020-NX-01-0337
+B2018-EM-01-0028
+A2019-NX-01-0151
+A2019-NX-01-1374
+A2018-EM-01-0615
+A2019-NX-01-1164
+A2019-EM-01-0021
+A2019-NX-01-1431
+A2019-EM-01-0027
+A2019-NX-01-1461
+A2017-EM-01-0060
+A2016-EM-01-0370
+A2016-EM-01-0319
+A2018-EM-01-0382
+A2018-EM-01-0637
+B2016-EM-01-0040
+A2018-EM-01-0738
+A2018-NX-01-0145
+A2018-EM-01-0466
+B2013-EM-01-0043
+A2017-EM-01-0102
+A2015-EM-01-0202
+A2018-EM-01-0865
+A2018-NX-01-0192
+A2019-NX-01-0551
+A2016-EM-01-0327
+A2017-EM-01-0297
+A2017-EM-01-0548
+C2019-EM-01-0059
+B2019-EM-01-0054
+A2019-NX-01-0293
+B2018-EM-01-0042
+A2019-EM-01-0125
+A2019-NX-01-1520
+B2015-EM-01-0105
+C2020-EM-01-0080
+C2020-EM-01-0266
+A2015-EM-01-0220
+A2018-EM-01-0106
+B2015-EM-01-0050
+A2015-EM-01-0417
+A2020-NX-01-0031
+A2018-EM-01-0424
+A2017-EM-01-0385
+A2019-NX-01-1367
+A2016-EM-01-0414
+A2020-NX-01-0504
+A2020-NX-01-0249
+C2018-EM-01-0135
+A2018-NX-01-0054
+A2020-NX-01-0251
+A2015-EM-01-0373
+C2020-EM-01-0013
+A2017-EM-01-0455
+A2018-NX-01-0429
+A2020-NX-01-0040
+A2019-NX-01-0190
+A2019-NX-01-1646
+C2020-EM-01-0236
+A2018-EM-01-0241
+A2020-NX-01-0390
+A2019-NX-01-0623
+A2019-NX-01-0453
+A2015-EM-01-0142
+A2015-EM-01-0258
+A2018-EM-01-0971
+A2019-NX-01-0506
+B2016-EM-01-0126
+D2020-NX-01-0264
+C2019-EM-01-0334
+A2015-EM-01-0261
+A2016-EM-01-0426
+A2019-NX-01-1205
+B2013-EM-01-0028
+A2019-EM-01-0233
+A2015-EM-01-0246
+A2018-EM-01-0115
+A2019-NX-01-0396
+A2019-NX-01-0360
+A2019-NX-01-0638
+C2018-EM-01-0003
+A2019-EM-01-0216
+A2018-NX-01-0089
+A2019-NX-01-0991
+A2015-EM-01-0374
+A2018-NX-01-0025
+A2018-EM-01-0834
+A2019-NX-01-1287
+D2019-NX-01-0121
+A2020-EM-01-0014
+C2019-EM-01-0304
+A2019-NX-01-0677
+A2019-NX-01-0497
+A2019-NX-01-0717
+C2018-EM-01-0234
+A2020-NX-01-0370
+A2019-NX-01-0306
+A2020-NX-01-0400
+C2019-EM-01-0162
+A2017-EM-01-0363
+A2019-NX-01-0757
+A2018-NX-01-0134
+A2019-NX-01-1358
+D2020-NX-01-0014
+D2020-NX-01-0217
+A2018-NX-01-0080
+A2019-NX-01-1220
+A2020-NX-01-0070
+B2013-EM-01-0077
+A2018-NX-01-0129
+B2015-EM-01-0096
+A2017-EM-01-0351
+A2017-EM-01-0396
+C2019-EM-01-0318
+A2016-EM-01-0052
+C2018-EM-01-0325
+A2018-EM-01-0508
+A2017-EM-01-0292
+A2019-NX-01-0522
+B2015-EM-01-0015
+A2019-NX-01-0989
+B2013-EM-01-0080
+A2017-EM-01-0198
+A2019-NX-01-0443
+A2020-NX-01-0419
+A2019-NX-01-0709
+A2018-EM-01-0873
+B2017-EM-01-0001
+A2019-NX-01-0326
+A2019-NX-01-0562
+D2019-NX-01-0097
+A2018-EM-01-0339
+A2020-NX-01-0171
+C2019-EM-01-0150
+A2019-NX-01-0210
+A2019-NX-01-0942
+C2020-EM-01-0190
+A2017-EM-01-0339
+A2019-EM-01-0191
+A2018-EM-01-0839
+B2016-EM-01-0057
+C2018-EM-01-0313
+C2020-EM-01-0310
+A2017-EM-01-0238
+A2017-EM-01-0269
+A2020-NX-01-0177
+A2019-NX-01-0569
+A2018-EM-01-0122
+A2016-EM-01-0216
+A2018-NX-01-0184
+A2018-EM-01-1008
+A2019-NX-01-0344
+C2020-EM-01-0082
+D2019-NX-01-0139
+D2019-NX-01-0074
+A2018-EM-01-0030
+A2019-NX-01-1240
+A2017-EM-01-0362
+A2019-NX-01-0517
+A2019-NX-01-1487
+A2020-NX-01-0385
+A2015-EM-01-0394
+A2020-NX-01-0537
+A2015-EM-01-0013
+A2020-NX-01-0072
+A2016-EM-01-0374
+B2013-EM-01-0071
+A2020-NX-01-0424
+A2019-NX-01-1533
+A2016-EM-01-0232
+A2020-NX-01-0044
+A2020-NX-01-0233
+A2018-NX-01-0188
+A2020-NX-01-0125
+A2020-NX-01-0546
+A2019-NX-01-0767
+A2019-NX-01-0807
+D2020-NX-01-0051
+B2014-EM-01-0006
+A2015-EM-01-0040
+C2020-EM-01-0203
+A2017-EM-01-0057
+A2019-NX-01-1251
+A2016-EM-01-0356
+A2018-EM-01-0846
+C2020-EM-01-0030
+A2017-EM-01-0483
+C2019-EM-01-0104
+A2019-NX-01-0154
+A2019-NX-01-0060
+C2020-EM-01-0278
+A2019-NX-01-1024
+A2019-EM-01-0281
+A2019-NX-01-0463
+A2019-NX-01-0904
+A2017-EM-01-0038
+A2018-NX-01-0386
+A2019-NX-01-1019
+A2018-NX-01-0051
+A2019-NX-01-0926
+A2018-EM-01-0746
+A2019-NX-01-1134
+A2018-EM-01-0945
+A2019-NX-01-0239
+A2016-EM-01-0211
+A2018-NX-01-0166
+A2016-EM-01-0166
+D2019-NX-01-0184
+A2018-EM-01-0081
+A2019-NX-01-1242
+A2020-NX-01-0310
+B2018-EM-01-0071
+A2017-EM-01-0138
+A2020-NX-01-0618
+C2019-EM-01-0374
+A2019-NX-01-0891
+A2018-NX-01-0354
+A2019-NX-01-0842
+C2019-EM-01-0138
+A2019-NX-01-1283
+A2019-NX-01-1274
+A2019-EM-01-0005
+A2015-EM-01-0442
+C2020-EM-01-0242
+B2019-NX-01-0070
+A2020-NX-01-0574
+A2020-NX-01-0379
+D2019-NX-01-0215
+A2019-NX-01-1630
+C2020-EM-01-0073
+A2020-EM-01-0061
+A2018-NX-01-0198
+A2019-NX-01-0686
+C2019-EM-01-0079
+C2019-EM-01-0094
+A2019-NX-01-1451
+A2019-NX-01-1360
+C2018-EM-01-0141
+A2019-EM-01-0083
+B2013-EM-01-0051
+C2018-EM-01-0103
+A2017-EM-01-0111
+A2016-EM-01-0328
+C2020-EM-01-0251
+D2020-NX-01-0108
+A2019-NX-01-0466
+A2020-NX-01-0728
+A2019-NX-01-1492
+D2019-NX-01-0105
+A2016-EM-01-0206
+A2017-EM-01-0303
+A2017-EM-01-0101
+A2018-NX-01-0395
+A2019-NX-01-1373
+C2020-EM-01-0226
+A2020-NX-01-0769
+A2018-EM-01-0821
+A2015-EM-01-0014
+A2020-NX-01-0183
+B2019-NX-01-0079
+A2020-NX-01-0763
+A2017-EM-01-0232
+D2019-NX-01-0171
+A2018-EM-01-0117
+A2019-NX-01-0044
+A2018-EM-01-0010
+B2013-EM-01-0092
+A2015-EM-01-0314
+A2018-EM-01-0643
+D2019-NX-01-0130
+A2018-NX-01-0379
+A2019-NX-01-1064
+A2016-EM-01-0301
+A2019-NX-01-0676
+A2019-NX-01-0799
+A2018-EM-01-0651
+A2019-NX-01-0264
+A2019-NX-01-1435
+B2014-EM-01-0076
+A2015-EM-01-0164
+A2019-NX-01-1433
+A2019-NX-01-0491
+A2017-EM-01-0003
+A2017-EM-01-0091
+D2019-NX-01-0037
+A2017-EM-01-0048
+A2017-EM-01-0311
+C2018-EM-01-0196
+A2019-EM-01-0202
+A2018-EM-01-0306
+A2020-NX-01-0021
+C2019-EM-01-0234
+A2018-NX-01-0175
+A2019-NX-01-1332
+A2016-EM-01-0318
+D2020-NX-01-0052
+A2016-EM-01-0131
+A2018-NX-01-0138
+A2020-NX-01-0094
+A2015-EM-01-0467
+A2019-NX-01-1007
+C2020-EM-01-0024
+A2018-EM-01-0495
+B2016-EM-01-0120
+A2015-EM-01-0434
+A2019-EM-01-0012
+D2019-NX-01-0026
+C2018-EM-01-0079
+C2019-EM-01-0209
+A2019-NX-01-1030
+D2019-NX-01-0087
+A2015-EM-01-0225
+C2019-EM-01-0018
+B2016-EM-01-0081
+D2019-NX-01-0235
+A2018-NX-01-0171
+A2016-EM-01-0306
+A2019-NX-01-1333
+D2020-NX-01-0070
+A2019-NX-01-0250
+A2019-NX-01-0235
+C2019-EM-01-0066
+A2019-NX-01-1101
+B2013-EM-01-0102
+A2019-NX-01-0628
+C2020-EM-01-0067
+A2018-EM-01-0715
+D2020-NX-01-0280
+A2019-NX-01-0001
+C2020-EM-01-0041
+A2019-NX-01-1076
+B2018-EM-01-0132
+A2019-NX-01-0323
+A2015-EM-01-0193
+A2019-NX-01-0336
+A2016-EM-01-0185
+A2016-EM-01-0110
+A2019-EM-01-0109
+A2019-NX-01-1385
+D2019-NX-01-0129
+A2018-EM-01-0409
+A2018-NX-01-0126
+B2017-EM-01-0029
+C2019-EM-01-0317
+A2016-EM-01-0218
+A2020-EM-01-0050
+A2016-EM-01-0333
+A2018-EM-01-0811
+A2019-NX-01-1066
+A2019-NX-01-1586
+A2019-NX-01-0507
+A2019-NX-01-0307
+A2020-NX-01-0311
+A2018-EM-01-0566
+C2018-EM-01-0042
+A2018-EM-01-0219
+A2018-EM-01-0950
+A2019-NX-01-0649
+A2020-NX-01-0381
+C2020-EM-01-0325
+A2019-NX-01-0612
+B2013-EM-01-0046
+A2020-NX-01-0218
+A2015-EM-01-0444
+A2018-NX-01-0090
+A2019-NX-01-0284
+A2019-NX-01-0007
+B2015-EM-01-0150
+B2015-EM-01-0033
+C2019-EM-01-0041
+A2019-NX-01-1523
+A2019-NX-01-0636
+B2016-EM-01-0059
+C2019-EM-01-0249
+A2018-EM-01-0783
+B2019-EM-01-0045
+A2020-NX-01-0093
+A2019-NX-01-0913
+A2017-EM-01-0224
+A2019-NX-01-0339
+A2018-EM-01-0874
+A2019-NX-01-1327
+A2019-NX-01-0572
+A2017-EM-01-0299
+A2015-EM-01-0084
+A2019-NX-01-1010
+A2020-NX-01-0753
+A2020-NX-01-0130
+A2018-EM-01-0760
+A2020-NX-01-0173
+A2015-EM-01-0283
+A2018-EM-01-0686
+C2020-EM-01-0214
+A2016-EM-01-0410
+A2019-NX-01-1454
+A2018-EM-01-0392
+A2018-EM-01-0557
+A2019-NX-01-0342
+C2019-EM-01-0137
+A2019-NX-01-0144
+A2018-EM-01-0001
+A2019-EM-01-0274
+A2015-EM-01-0021
+A2015-EM-01-0239
+A2019-NX-01-0265
+C2020-EM-01-0137
+A2016-EM-01-0083
+D2019-NX-01-0180
+A2020-NX-01-0105
+A2019-NX-01-0471
+A2019-NX-01-0452
+D2019-NX-01-0095
+D2019-NX-01-0255
+B2016-EM-01-0003
+A2019-NX-01-0903
+A2019-NX-01-0093
+C2018-EM-01-0033
+C2018-EM-01-0285
+A2019-NX-01-1106
+A2019-NX-01-0839
+D2019-NX-01-0199
+A2019-NX-01-1294
+C2018-EM-01-0084
+A2018-EM-01-0202
+A2016-EM-01-0209
+A2018-EM-01-0674
+B2015-EM-01-0071
+C2020-EM-01-0186
+A2019-NX-01-1091
+B2013-EM-01-0013
+A2016-EM-01-0070
+C2020-EM-01-0222
+C2019-EM-01-0110
+A2015-EM-01-0230
+A2019-NX-01-1394
+A2018-NX-01-0047
+A2017-EM-01-0295
+B2019-NX-01-0007
+A2020-NX-01-0388
+A2018-EM-01-0462
+C2020-EM-01-0108
+A2015-EM-01-0072
+B2018-EM-01-0163
+A2020-NX-01-0579
+A2020-NX-01-0007
+A2018-EM-01-0935
+A2015-EM-01-0425
+A2019-NX-01-1570
+A2020-NX-01-0261
+A2020-NX-01-0414
+B2015-EM-01-0055
+C2020-EM-01-0147
+A2020-NX-01-0458
+A2018-EM-01-0388
+A2019-NX-01-1474
+A2020-NX-01-0757
+A2019-NX-01-1448
+A2019-NX-01-0589
+C2019-EM-01-0087
+A2017-EM-01-0400
+C2018-EM-01-0171
+A2020-NX-01-0198
+B2016-EM-01-0071
+C2019-EM-01-0049
+A2020-NX-01-0004
+D2019-NX-01-0035
+A2018-NX-01-0235
+C2019-EM-01-0096
+A2015-EM-01-0018
+A2016-EM-01-0046
+A2015-EM-01-0076
+A2015-EM-01-0330
+D2019-NX-01-0167
+A2020-NX-01-0710
+A2017-EM-01-0092
+A2019-NX-01-1537
+A2020-NX-01-0771
+A2020-EM-01-0092
+A2016-EM-01-0280
+A2020-NX-01-0136
+A2017-EM-01-0061
+C2018-EM-01-0078
+C2020-EM-01-0183
+C2019-EM-01-0082
+A2017-EM-01-0137
+A2019-NX-01-1596
+A2019-NX-01-1657
+A2017-EM-01-0172
+A2016-EM-01-0379
+B2013-EM-01-0068
+A2019-NX-01-1239
+D2020-NX-01-0206
+D2019-NX-01-0028
+A2020-NX-01-0009
+B2018-EM-01-0170
+A2019-NX-01-0320
+A2020-NX-01-0517
+A2017-EM-01-0164
+D2020-NX-01-0198
+A2019-EM-01-0182
+A2016-EM-01-0407
+A2020-NX-01-0025
+A2018-EM-01-0718
+A2017-EM-01-0226
+C2020-EM-01-0119
+B2018-EM-01-0021
+A2018-EM-01-0484
+A2019-EM-01-0032
+B2013-EM-01-0042
+A2018-EM-01-0397
+A2019-NX-01-1557
+A2017-EM-01-0078
+A2020-NX-01-0524
+D2020-NX-01-0148
+D2019-NX-01-0212
+A2019-NX-01-0090
+A2020-NX-01-0609
+D2020-NX-01-0259
+A2018-EM-01-0465
+A2018-EM-01-0066
+A2019-NX-01-1025
+B2015-EM-01-0121
+C2019-EM-01-0341
+D2019-NX-01-0226
+A2020-NX-01-0698
+B2019-EM-01-0028
+A2015-EM-01-0245
+B2018-EM-01-0025
+A2020-NX-01-0383
+A2017-EM-01-0106
+A2019-NX-01-0965
+A2019-EM-01-0282
+A2019-NX-01-1502
+C2019-EM-01-0237
+A2020-NX-01-0706
+A2018-EM-01-0543
+A2017-EM-01-0088
+A2017-EM-01-0537
+A2019-NX-01-1337
+A2019-NX-01-0613
+D2020-NX-01-0072
+C2019-EM-01-0021
+A2018-NX-01-0443
+B2018-EM-01-0020
+B2018-EM-01-0017
+A2019-NX-01-1013
+C2020-EM-01-0270
+A2020-NX-01-0255
+A2018-EM-01-0810
+C2019-EM-01-0310
+A2015-EM-01-0366
+A2019-NX-01-0279
+D2019-NX-01-0052
+A2019-NX-01-1668
+A2020-NX-01-0679
+A2019-NX-01-1445
+A2019-NX-01-1184
+A2019-NX-01-0860
+A2015-EM-01-0421
+A2015-EM-01-0065
+A2019-NX-01-0229
+A2019-EM-01-0071
+D2020-NX-01-0151
+A2017-EM-01-0077
+A2019-NX-01-0196
+B2018-EM-01-0051
+A2019-NX-01-0201
+A2019-NX-01-0488
+A2016-EM-01-0398
+A2019-NX-01-1084
+A2019-NX-01-1100
+A2019-NX-01-0165
+C2018-EM-01-0252
+D2019-NX-01-0253
+B2013-EM-01-0069
+A2019-NX-01-1629
+A2016-EM-01-0179
+A2018-NX-01-0398
+C2019-EM-01-0043
+A2018-EM-01-0054
+A2017-EM-01-0324
+A2017-EM-01-0450
+A2018-EM-01-0045
+A2019-EM-01-0184
+B2015-EM-01-0087
+C2018-EM-01-0197
+A2019-NX-01-0560
+B2017-EM-01-0096
+B2018-EM-01-0065
+A2018-EM-01-0181
+A2015-EM-01-0316
+A2016-EM-01-0019
+C2020-EM-01-0047
+A2019-NX-01-0882
+A2015-EM-01-0146
+A2015-EM-01-0177
+A2018-NX-01-0204
+B2018-EM-01-0047
+C2020-EM-01-0050
+C2020-EM-01-0038
+A2019-NX-01-0795
+A2019-NX-01-0895
+C2020-EM-01-0194
+B2018-EM-01-0150
+A2020-NX-01-0732
+A2019-NX-01-0329
+C2019-EM-01-0144
+A2020-NX-01-0749
+A2019-NX-01-0230
+A2015-EM-01-0208
+A2019-NX-01-0377
+B2016-EM-01-0025
+B2018-EM-01-0114
+B2017-EM-01-0076
+D2020-NX-01-0095
+A2018-NX-01-0425
+A2019-NX-01-0542
+A2019-NX-01-1328
+D2020-NX-01-0213
+C2019-EM-01-0223
+C2018-EM-01-0329
+A2020-NX-01-0041
+C2019-EM-01-0134
+A2017-EM-01-0084
+A2018-EM-01-0921
+A2019-EM-01-0002
+B2015-EM-01-0060
+A2017-EM-01-0542
+A2019-NX-01-0494
+D2020-NX-01-0050
+C2018-EM-01-0131
+B2016-EM-01-0008
+A2015-EM-01-0095
+B2017-EM-01-0093
+A2020-NX-01-0786
+C2018-EM-01-0208
+C2020-EM-01-0228
+A2018-EM-01-0005
+C2019-EM-01-0031
+A2016-EM-01-0402
+A2018-EM-01-0444
+A2017-EM-01-0376
+C2020-EM-01-0099
+A2015-EM-01-0290
+A2017-EM-01-0347
+C2019-EM-01-0145
+A2019-NX-01-0102
+C2019-EM-01-0271
+A2019-NX-01-0084
+A2018-EM-01-0640
+A2018-NX-01-0430
+A2019-NX-01-1201
+A2019-NX-01-1277
+B2014-EM-01-0080
+A2017-EM-01-0105
+A2016-EM-01-0152
+A2019-EM-01-0098
+D2020-NX-01-0084
+A2020-NX-01-0167
+D2020-NX-01-0242
+A2016-EM-01-0128
+A2018-EM-01-0589
+C2018-EM-01-0268
+C2019-EM-01-0202
+A2019-NX-01-1085
+A2019-NX-01-1035
+A2019-NX-01-0848
+A2019-NX-01-1378
+A2018-EM-01-0517
+A2019-NX-01-1420
+A2019-NX-01-0039
+D2019-NX-01-0170
+A2019-NX-01-1005
+A2020-NX-01-0056
+A2017-EM-01-0421
+A2019-NX-01-0949
+A2020-NX-01-0384
+D2020-NX-01-0272
+A2015-EM-01-0449
+A2020-NX-01-0528
+A2017-EM-01-0323
+A2017-EM-01-0445
+A2018-NX-01-0067
+A2020-NX-01-0717
+A2017-EM-01-0507
+A2020-EM-01-0045
+D2020-NX-01-0267
+A2020-NX-01-0303
+C2019-EM-01-0233
+B2014-EM-01-0035
+A2019-NX-01-0864
+A2019-NX-01-0400
+B2015-EM-01-0089
+A2017-EM-01-0235
+D2019-NX-01-0247
+C2019-EM-01-0015
+A2018-EM-01-0376
+A2015-EM-01-0148
+A2019-EM-01-0014
+A2019-NX-01-1587
+B2018-EM-01-0089
+B2013-EM-01-0022
+A2015-EM-01-0055
+A2017-EM-01-0141
+D2019-NX-01-0156
+A2016-EM-01-0002
+B2013-EM-01-0006
+A2020-NX-01-0161
+A2018-EM-01-0265
+A2019-NX-01-0878
+C2018-EM-01-0318
+A2017-EM-01-0322
+A2018-NX-01-0415
+B2015-EM-01-0067
+D2020-NX-01-0155
+B2015-EM-01-0010
+C2019-EM-01-0178
+C2018-EM-01-0277
+D2020-NX-01-0138
+B2014-EM-01-0067
+A2019-NX-01-1103
+D2020-NX-01-0202
+A2019-NX-01-0568
+A2017-EM-01-0438
+A2019-NX-01-0446
+A2018-NX-01-0256
+A2016-EM-01-0192
+A2017-EM-01-0093
+B2018-EM-01-0001
+A2019-NX-01-1413
+A2019-EM-01-0236
+A2015-EM-01-0238
+C2020-EM-01-0351
+D2020-NX-01-0157
+A2018-EM-01-0224
+A2019-NX-01-1079
+A2019-NX-01-1480
+D2019-NX-01-0174
+A2018-EM-01-0107
+D2020-NX-01-0252
+C2019-EM-01-0264
+A2018-EM-01-0883
+A2019-NX-01-1661
+A2018-EM-01-0527
+A2018-NX-01-0209
+A2018-EM-01-0383
+A2017-EM-01-0330
+B2018-EM-01-0032
+A2015-EM-01-0456
+A2019-NX-01-1652
+C2020-EM-01-0199
+C2018-EM-01-0315
+A2020-NX-01-0126
+A2019-EM-01-0266
+A2019-NX-01-1221
+A2019-EM-01-0199
+A2015-EM-01-0053
+A2015-EM-01-0083
+B2015-EM-01-0034
+A2020-NX-01-0431
+A2018-EM-01-0450
+A2019-NX-01-1624
+A2019-NX-01-1522
+A2017-EM-01-0549
+A2020-NX-01-0780
+D2019-NX-01-0134
+D2020-NX-01-0195
+B2015-EM-01-0076
+B2015-EM-01-0082
+A2018-EM-01-0877
+A2018-EM-01-0778
+A2017-EM-01-0150
+A2019-NX-01-1009
+C2018-EM-01-0054
+D2020-NX-01-0124
+B2016-EM-01-0066
+C2020-EM-01-0017
+A2020-NX-01-0285
+A2016-EM-01-0048
+B2018-EM-01-0102
+A2018-EM-01-0523
+A2019-NX-01-0065
+A2018-EM-01-0349
+C2020-EM-01-0218
+A2019-NX-01-0115
+A2016-EM-01-0215
+A2015-EM-01-0176
+A2018-NX-01-0306
+A2019-NX-01-0853
+C2019-EM-01-0053
+A2019-NX-01-0869
+A2019-NX-01-0197
+A2020-NX-01-0465
+D2020-NX-01-0023
+A2019-NX-01-0274
+C2020-EM-01-0312
+A2019-NX-01-0020
+A2018-NX-01-0114
+A2020-NX-01-0204
+C2020-EM-01-0344
+A2019-NX-01-1443
+A2015-EM-01-0318
+A2019-NX-01-0823
+A2020-NX-01-0235
+A2017-EM-01-0272
+A2019-EM-01-0059
+C2019-EM-01-0221
+A2018-EM-01-0237
+A2018-NX-01-0364
+A2019-NX-01-1639
+C2020-EM-01-0227
+A2020-NX-01-0415
+A2020-NX-01-0079
+D2019-NX-01-0161
+A2018-NX-01-0317
+A2018-NX-01-0281
+A2018-EM-01-0063
+C2018-EM-01-0214
+A2020-NX-01-0664
+A2016-EM-01-0224
+D2019-NX-01-0263
+A2019-EM-01-0148
+B2019-EM-01-0030
+A2016-EM-01-0287
+A2019-NX-01-1658
+A2016-EM-01-0217
+C2020-EM-01-0204
+B2014-EM-01-0024
+C2018-EM-01-0284
+A2015-EM-01-0402
+A2018-NX-01-0238
+A2019-EM-01-0134
+B2019-EM-01-0047
+A2019-NX-01-0519
+A2015-EM-01-0136
+A2019-EM-01-0174
+B2019-NX-01-0078
+D2019-NX-01-0103
+A2018-EM-01-0223
+B2018-EM-01-0054
+A2019-NX-01-1583
+A2020-EM-01-0015
+C2018-EM-01-0259
+C2019-EM-01-0300
+A2019-NX-01-0142
+A2019-NX-01-0053
+A2018-NX-01-0273
+A2017-EM-01-0183
+C2018-EM-01-0354
+A2019-NX-01-0216
+A2016-EM-01-0055
+A2019-NX-01-1595
+C2018-EM-01-0172
+A2019-EM-01-0221
+A2017-EM-01-0344
+B2019-EM-01-0052
+D2019-NX-01-0246
+A2019-EM-01-0229
+B2016-EM-01-0080
+A2018-EM-01-0864
+B2018-EM-01-0151
+A2020-NX-01-0342
+A2018-EM-01-0565
+A2019-NX-01-1438
+A2019-EM-01-0196
+A2018-EM-01-0009
+A2019-NX-01-1575
+A2018-EM-01-1007
+A2020-NX-01-0773
+A2020-NX-01-0797
+A2020-NX-01-0621
+A2019-NX-01-0627
+B2019-NX-01-0013
+A2015-EM-01-0216
+A2019-NX-01-1626
+B2019-NX-01-0072
+A2019-NX-01-1237
+A2019-NX-01-0692
+A2018-EM-01-0973
+C2019-EM-01-0002
+D2020-NX-01-0250
+D2019-NX-01-0142
+A2018-EM-01-0719
+A2020-NX-01-0011
+A2018-EM-01-0757
+A2018-NX-01-0079
+A2019-EM-01-0057
+A2018-EM-01-0153
+A2019-NX-01-1150
+D2020-NX-01-0027
+B2015-EM-01-0138
+A2016-EM-01-0226
+C2020-EM-01-0025
+A2017-EM-01-0370
+D2020-NX-01-0204
+A2019-NX-01-1664
+A2019-NX-01-0658
+B2016-EM-01-0083
+A2019-NX-01-1302
+A2019-NX-01-1581
+A2019-NX-01-0322
+A2016-EM-01-0359
+A2019-NX-01-0875
+A2019-EM-01-0189
+A2016-EM-01-0230
+D2019-NX-01-0041
+C2018-EM-01-0288
+D2020-NX-01-0232
+A2018-EM-01-0905
+A2019-NX-01-0103
+B2017-EM-01-0095
+A2019-NX-01-0209
+B2018-EM-01-0036
+A2015-EM-01-0160
+A2019-NX-01-0200
+A2019-NX-01-0311
+A2015-EM-01-0068
+A2019-NX-01-0140
+A2018-EM-01-0891
+B2019-EM-01-0010
+A2019-NX-01-0603
+A2017-EM-01-0243
+A2019-NX-01-1178
+A2019-NX-01-0998
+A2019-NX-01-0249
+B2014-EM-01-0106
+A2019-NX-01-1329
+B2017-EM-01-0109
+A2020-NX-01-0412
+A2018-EM-01-0799
+B2015-EM-01-0032
+B2018-EM-01-0131
+C2020-EM-01-0097
+A2017-EM-01-0553
+D2020-NX-01-0018
+A2015-EM-01-0333
+B2016-EM-01-0064
+A2018-EM-01-0544
+A2015-EM-01-0157
+A2018-NX-01-0407
+B2013-EM-01-0104
+A2019-NX-01-0745
+A2020-NX-01-0416
+D2019-NX-01-0039
+D2020-NX-01-0159
+A2015-EM-01-0237
+B2014-EM-01-0003
+A2016-EM-01-0069
+C2019-EM-01-0362
+A2017-EM-01-0024
+C2018-EM-01-0192
+A2019-NX-01-0283
+C2019-EM-01-0026
+A2016-EM-01-0018
+D2019-NX-01-0122
+A2016-EM-01-0112
+C2019-EM-01-0244
+C2018-EM-01-0311
+A2019-EM-01-0135
+B2016-EM-01-0078
+B2015-EM-01-0031
+C2018-EM-01-0153
+C2020-EM-01-0244
+D2020-NX-01-0010
+C2020-EM-01-0145
+A2016-EM-01-0115
+A2016-EM-01-0427
+A2019-EM-01-0103
+A2018-EM-01-0293
+A2019-NX-01-0666
+A2019-NX-01-0295
+A2018-NX-01-0412
+A2020-NX-01-0043
+C2018-EM-01-0305
+A2019-NX-01-1517
+A2019-NX-01-0457
+B2014-EM-01-0101
+A2018-EM-01-0299
+A2020-NX-01-0343
+A2020-EM-01-0019
+A2019-NX-01-0004
+D2019-NX-01-0181
+C2020-EM-01-0193
+C2018-EM-01-0021
+A2018-NX-01-0377
+A2019-NX-01-0399
+A2019-NX-01-0514
+A2018-EM-01-0507
+A2020-NX-01-0023
+A2018-NX-01-0313
+A2017-EM-01-0551
+B2016-EM-01-0132
+A2019-NX-01-0503
+A2018-EM-01-0188
+C2020-EM-01-0213
+C2019-EM-01-0161
+B2015-EM-01-0026
+D2020-NX-01-0266
+A2020-NX-01-0135
+A2018-EM-01-0067
+A2018-EM-01-0003
+A2018-NX-01-0343
+A2020-NX-01-0162
+C2018-EM-01-0230
+A2015-EM-01-0212
+A2019-NX-01-0286
+B2013-EM-01-0038
+A2016-EM-01-0199
+A2020-EM-01-0087
+A2019-NX-01-0409
+A2020-NX-01-0499
+A2019-EM-01-0209
+A2017-EM-01-0468
+B2013-EM-01-0084
+A2019-NX-01-1108
+A2020-NX-01-0137
+A2019-NX-01-1540
+A2020-EM-01-0086
+A2015-EM-01-0344
+C2020-EM-01-0168
+A2017-EM-01-0502
+C2020-EM-01-0011
+D2019-NX-01-0073
+A2016-EM-01-0066
+A2018-EM-01-0562
+A2016-EM-01-0238
+A2020-EM-01-0013
+A2020-NX-01-0348
+A2016-EM-01-0016
+A2020-NX-01-0425
+A2018-EM-01-0089
+A2019-NX-01-0473
+B2015-EM-01-0069
+A2017-EM-01-0288
+C2018-EM-01-0066
+A2018-EM-01-0982
+A2020-NX-01-0048
+B2016-EM-01-0023
+A2016-EM-01-0334
+A2018-NX-01-0009
+C2018-EM-01-0310
+A2018-EM-01-0415
+A2018-EM-01-0855
+B2015-EM-01-0125
+A2018-EM-01-0622
+A2018-EM-01-0147
+A2020-EM-01-0029
+A2018-EM-01-0758
+C2020-EM-01-0116
+A2019-NX-01-0594
+A2018-EM-01-0524
+A2016-EM-01-0264
+A2019-NX-01-1218
+A2018-EM-01-0952
+D2020-NX-01-0022
+A2019-NX-01-0997
+D2019-NX-01-0149
+D2019-NX-01-0192
+A2017-EM-01-0472
+A2016-EM-01-0251
+A2020-NX-01-0640
+A2018-EM-01-0658
+A2019-NX-01-0784
+B2013-EM-01-0109
+A2016-EM-01-0068
+A2019-NX-01-0771
+A2018-EM-01-0493
+A2019-NX-01-1376
+A2019-NX-01-1097
+A2019-NX-01-0450
+A2020-NX-01-0699
+A2016-EM-01-0108
+D2020-NX-01-0097
+A2017-EM-01-0429
+A2018-EM-01-0190
+A2019-NX-01-1315
+A2018-EM-01-0903
+D2020-NX-01-0172
+A2016-EM-01-0314
+A2018-NX-01-0191
+A2018-NX-01-0374
+A2018-NX-01-0239
+A2019-NX-01-0219
+C2020-EM-01-0224
+A2019-NX-01-1138
+A2019-NX-01-0166
+C2019-EM-01-0051
+A2019-NX-01-0750
+C2020-EM-01-0172
+A2020-NX-01-0495
+A2018-NX-01-0099
+A2018-EM-01-0022
+A2018-EM-01-0016
+C2018-EM-01-0119
+A2020-NX-01-0721
+B2016-EM-01-0049
+A2020-EM-01-0052
+A2020-NX-01-0297
+A2019-NX-01-0424
+B2017-EM-01-0004
+C2020-EM-01-0187
+C2019-EM-01-0328
+A2019-NX-01-1149
+C2019-EM-01-0192
+A2020-NX-01-0269
+A2019-NX-01-1160
+A2018-EM-01-0160
+C2018-EM-01-0061
+A2017-EM-01-0256
+D2020-NX-01-0190
+A2019-NX-01-0832
+A2019-NX-01-0402
+A2019-NX-01-0744
+A2016-EM-01-0303
+A2016-EM-01-0384
+C2018-EM-01-0237
+A2015-EM-01-0143
+A2019-NX-01-0720
+B2019-EM-01-0018
+A2015-EM-01-0470
+A2019-NX-01-0193
+A2018-NX-01-0055
+A2015-EM-01-0223
+A2016-EM-01-0191
+A2020-NX-01-0494
+D2020-NX-01-0254
+A2019-EM-01-0070
+D2019-NX-01-0093
+A2018-NX-01-0225
+C2018-EM-01-0098
+A2018-NX-01-0118
+A2019-EM-01-0116
+A2018-EM-01-0608
+C2018-EM-01-0223
+A2019-NX-01-0160
+A2019-NX-01-0390
+B2018-EM-01-0072
+A2018-EM-01-0666
+A2018-NX-01-0326
+A2016-EM-01-0150
+A2017-EM-01-0267
+A2015-EM-01-0272
+A2018-EM-01-0372
+A2020-NX-01-0556
+A2018-EM-01-0271
+A2019-NX-01-0504
+A2020-NX-01-0739
+A2019-NX-01-0437
+A2018-EM-01-0158
+C2019-EM-01-0263
+A2020-NX-01-0691
+A2020-EM-01-0057
+A2018-NX-01-0049
+A2018-NX-01-0269
+A2018-EM-01-0357
+A2017-EM-01-0337
+A2019-NX-01-1584
+A2015-EM-01-0215
+B2015-EM-01-0134
+A2019-NX-01-0657
+A2020-NX-01-0301
+A2016-EM-01-0220
+A2018-EM-01-0759
+A2020-NX-01-0464
+A2020-NX-01-0375
+A2020-NX-01-0392
+D2019-NX-01-0160
+A2020-NX-01-0077
+A2020-NX-01-0212
+D2020-NX-01-0287
+A2019-NX-01-1352
+A2019-NX-01-1191
+A2018-EM-01-0058
+D2019-NX-01-0261
+A2017-EM-01-0075
+A2018-EM-01-0761
+A2019-NX-01-0315
+A2019-NX-01-0754
+A2019-NX-01-1375
+C2018-EM-01-0176
+A2017-EM-01-0213
+A2019-NX-01-0013
+C2020-EM-01-0269
+A2018-EM-01-0882
+A2019-NX-01-1484
+B2016-EM-01-0029
+A2018-EM-01-0231
+A2018-EM-01-0200
+A2018-NX-01-0404
+A2015-EM-01-0345
+B2013-EM-01-0082
+C2018-EM-01-0304
+A2018-NX-01-0237
+B2017-EM-01-0025
+A2018-EM-01-0531
+A2019-NX-01-1649
+D2020-NX-01-0066
+A2018-EM-01-0670
+B2014-EM-01-0084
+A2020-EM-01-0058
+B2018-EM-01-0081
+B2018-EM-01-0037
+A2020-NX-01-0346
+B2018-EM-01-0061
+A2019-EM-01-0097
+A2018-EM-01-0701
+A2020-NX-01-0647
+D2020-NX-01-0244
+C2020-EM-01-0314
+A2019-NX-01-1592
+A2019-NX-01-0546
+A2019-NX-01-1183
+A2015-EM-01-0401
+A2018-NX-01-0456
+A2017-EM-01-0540
+A2018-EM-01-0076
+A2017-EM-01-0148
+A2019-NX-01-0525
+A2018-EM-01-0572
+A2019-NX-01-1335
+A2019-NX-01-0426
+A2015-EM-01-0118
+A2019-NX-01-1272
+A2020-NX-01-0544
+A2019-EM-01-0075
+D2020-NX-01-0071
+A2019-NX-01-0357
+A2016-EM-01-0372
+A2016-EM-01-0421
+A2018-NX-01-0419
+A2018-EM-01-0786
+A2019-NX-01-0159
+A2019-NX-01-1594
+A2019-NX-01-1096
+C2019-EM-01-0194
+A2019-NX-01-0974
+B2018-EM-01-0038
+C2020-EM-01-0284
+B2018-EM-01-0110
+A2020-EM-01-0039
+A2019-NX-01-0561
+A2020-NX-01-0246
+A2015-EM-01-0427
+A2017-EM-01-0387
+A2019-NX-01-1021
+C2018-EM-01-0262
+A2019-NX-01-0934
+A2020-NX-01-0526
+A2018-EM-01-0020
+A2020-NX-01-0658
+C2020-EM-01-0330
+A2019-NX-01-1152
+B2014-EM-01-0065
+A2015-EM-01-0461
+A2017-EM-01-0145
+A2020-NX-01-0595
+D2020-NX-01-0076
+A2018-NX-01-0334
+B2017-EM-01-0008
+A2018-NX-01-0122
+A2019-NX-01-0470
+A2018-EM-01-0716
+C2018-EM-01-0093
+B2018-EM-01-0031
+A2016-EM-01-0350
+A2020-NX-01-0178
+A2019-NX-01-0521
+B2013-EM-01-0081
+A2015-EM-01-0248
+A2019-EM-01-0113
+B2014-EM-01-0061
+A2018-NX-01-0315
+B2015-EM-01-0144
+A2016-EM-01-0323
+B2018-EM-01-0116
+A2019-NX-01-1608
+B2018-EM-01-0005
+D2019-NX-01-0210
+A2017-EM-01-0094
+D2019-NX-01-0168
+A2019-NX-01-1296
+A2018-NX-01-0318
+A2019-NX-01-1590
+A2018-EM-01-0097
+A2016-EM-01-0126
+A2018-EM-01-0286
+A2020-NX-01-0587
+A2020-NX-01-0779
+D2019-NX-01-0017
+A2019-NX-01-1401
+D2020-NX-01-0082
+D2019-NX-01-0083
+A2020-NX-01-0012
+A2018-EM-01-0469
+A2019-NX-01-1519
+B2015-EM-01-0008
+C2019-EM-01-0376
+C2020-EM-01-0069
+A2016-EM-01-0289
+B2014-EM-01-0108
+D2019-NX-01-0259
+A2020-NX-01-0686
+A2019-NX-01-0581
+A2020-NX-01-0718
+B2016-EM-01-0067
+B2018-EM-01-0015
+C2020-EM-01-0109
+A2019-NX-01-0527
+C2020-EM-01-0329
+C2018-EM-01-0011
+B2013-EM-01-0034
+A2018-NX-01-0084
+A2016-EM-01-0315
+C2020-EM-01-0154
+A2019-NX-01-0221
+A2015-EM-01-0128
+A2018-EM-01-0284
+A2019-NX-01-1550
+B2017-EM-01-0078
+A2018-EM-01-0004
+A2018-EM-01-0431
+C2019-EM-01-0217
+A2020-NX-01-0359
+A2018-EM-01-0530
+A2016-EM-01-0355
+B2015-EM-01-0057
+A2018-EM-01-0483
+D2020-NX-01-0215
+A2019-NX-01-1479
+C2019-EM-01-0298
+A2015-EM-01-0197
+A2018-EM-01-0494
+A2018-EM-01-0315
+A2018-NX-01-0332
+A2018-NX-01-0018
+A2018-NX-01-0434
+A2019-NX-01-1231
+A2018-NX-01-0060
+A2018-NX-01-0300
+A2015-EM-01-0386
+A2019-NX-01-0590
+B2015-EM-01-0072
+A2019-NX-01-1031
+C2018-EM-01-0251
+C2020-EM-01-0051
+A2017-EM-01-0081
+A2019-NX-01-1241
+A2019-NX-01-0484
+B2015-EM-01-0062
+D2020-NX-01-0221
+A2019-NX-01-1212
+A2018-NX-01-0008
+B2017-EM-01-0046
+A2019-NX-01-1493
+A2016-EM-01-0193
+A2020-NX-01-0695
+C2020-EM-01-0285
+A2019-NX-01-1083
+A2019-NX-01-0973
+A2015-EM-01-0168
+A2019-NX-01-0394
+A2019-EM-01-0261
+A2019-NX-01-1216
+B2014-EM-01-0053
+A2019-NX-01-0113
+A2019-NX-01-0378
+A2019-NX-01-1286
+A2018-NX-01-0397
+A2019-NX-01-0259
+A2019-NX-01-0748
+A2019-NX-01-1510
+A2020-NX-01-0490
+A2019-NX-01-1015
+A2019-NX-01-0605
+B2016-EM-01-0121
+D2020-NX-01-0145
+A2018-EM-01-0520
+A2018-NX-01-0321
+A2019-NX-01-0222
+A2018-NX-01-0002
+A2020-NX-01-0111
+A2018-EM-01-0192
+C2020-EM-01-0131
+C2020-EM-01-0230
+C2019-EM-01-0265
+A2019-NX-01-1307
+D2020-NX-01-0181
+A2019-NX-01-0150
+A2019-NX-01-1230
+A2020-NX-01-0265
+A2019-NX-01-1383
+A2019-NX-01-0024
+A2018-NX-01-0274
+C2020-EM-01-0167
+A2016-EM-01-0228
+C2020-EM-01-0308
+D2020-NX-01-0292
+A2020-NX-01-0654
+B2015-EM-01-0098
+A2016-EM-01-0212
+A2018-EM-01-0278
+A2018-EM-01-0283
+A2016-EM-01-0061
+A2018-EM-01-0656
+B2016-EM-01-0001
+C2018-EM-01-0243
+A2018-EM-01-0784
+C2019-EM-01-0365
+A2019-EM-01-0009
+A2019-EM-01-0205
+A2019-NX-01-0545
+A2019-EM-01-0120
+A2018-EM-01-0907
+A2019-NX-01-1425
+B2016-EM-01-0128
+A2019-NX-01-0126
+C2019-EM-01-0068
+A2018-EM-01-0185
+A2018-EM-01-0244
+A2017-EM-01-0228
+C2019-EM-01-0262
+A2016-EM-01-0086
+A2019-NX-01-0897
+A2015-EM-01-0389
+A2019-NX-01-0770
+A2018-EM-01-0788
+A2016-EM-01-0308
+B2018-EM-01-0007
+A2018-NX-01-0214
+A2015-EM-01-0056
+C2019-EM-01-0023
+A2019-NX-01-1469
+A2019-NX-01-0500
+C2018-EM-01-0307
+C2019-EM-01-0282
+A2017-EM-01-0271
+A2016-EM-01-0014
+A2018-EM-01-0313
+D2020-NX-01-0229
+A2019-NX-01-0520
+D2019-NX-01-0163
+A2020-NX-01-0230
+A2016-EM-01-0159
+A2018-EM-01-0606
+A2015-EM-01-0469
+A2018-EM-01-0751
+A2020-NX-01-0729
+A2015-EM-01-0339
+A2019-EM-01-0231
+A2019-NX-01-0925
+C2019-EM-01-0242
+D2020-NX-01-0258
+A2019-NX-01-0977
+A2020-NX-01-0174
+A2015-EM-01-0135
+A2019-NX-01-0856
+C2020-EM-01-0216
+D2019-NX-01-0151
+A2019-EM-01-0031
+A2018-NX-01-0037
+C2018-EM-01-0266
+A2019-NX-01-0188
+C2019-EM-01-0284
+A2018-EM-01-0194
+A2018-NX-01-0131
+D2020-NX-01-0120
+B2013-EM-01-0103
+A2020-EM-01-0049
+A2019-NX-01-0051
+B2016-EM-01-0069
+A2020-NX-01-0260
+A2018-EM-01-0629
+A2020-NX-01-0656
+A2016-EM-01-0035
+A2017-EM-01-0251
+A2018-EM-01-0924
+C2020-EM-01-0072
+A2017-EM-01-0333
+A2017-EM-01-0373
+A2019-NX-01-0382
+A2019-EM-01-0260
+D2020-NX-01-0243
+B2019-NX-01-0022
+C2019-EM-01-0183
+A2015-EM-01-0139
+A2015-EM-01-0221
+A2017-EM-01-0206
+A2020-NX-01-0252
+C2020-EM-01-0202
+A2020-NX-01-0309
+A2015-EM-01-0418
+A2019-NX-01-1072
+B2019-NX-01-0050
+A2019-NX-01-0499
+A2019-NX-01-0232
+A2015-EM-01-0255
+A2019-NX-01-0541
+A2018-EM-01-0269
+D2019-NX-01-0182
+D2019-NX-01-0187
+A2015-EM-01-0108
+B2014-EM-01-0111
+A2019-NX-01-1093
+D2019-NX-01-0241
+A2017-EM-01-0535
+A2015-EM-01-0190
+A2019-NX-01-0662
+C2020-EM-01-0118
+A2015-EM-01-0446
+A2018-EM-01-0625
+A2019-NX-01-1243
+A2015-EM-01-0060
+A2018-EM-01-0036
+B2016-EM-01-0039
+C2020-EM-01-0066
+D2020-NX-01-0223
+A2016-EM-01-0284
+A2016-EM-01-0017
+A2020-NX-01-0623
+C2020-EM-01-0303
+B2017-EM-01-0063
+A2020-NX-01-0737
+B2014-EM-01-0051
+A2018-EM-01-0966
+D2019-NX-01-0128
+A2019-NX-01-0316
+A2019-NX-01-0083
+A2019-NX-01-1023
+C2019-EM-01-0071
+A2019-NX-01-0958
+A2019-NX-01-0597
+B2016-EM-01-0002
+A2015-EM-01-0310
+A2015-EM-01-0349
+A2018-EM-01-0146
+A2020-NX-01-0253
+A2019-NX-01-0563
+A2019-NX-01-1095
+A2019-NX-01-0485
+A2018-NX-01-0341
+A2018-EM-01-0254
+C2020-EM-01-0301
+A2017-EM-01-0366
+A2018-EM-01-0569
+D2019-NX-01-0162
+A2019-NX-01-0793
+D2020-NX-01-0205
+A2018-NX-01-0240
+A2017-EM-01-0466
+A2018-EM-01-0819
+C2020-EM-01-0150
+A2019-NX-01-1645
+C2018-EM-01-0104
+A2017-EM-01-0369
+A2018-EM-01-0165
+A2015-EM-01-0145
+C2019-EM-01-0230
+A2018-NX-01-0392
+B2015-EM-01-0081
+A2020-NX-01-0616
+A2019-NX-01-0038
+A2016-EM-01-0322
+A2016-EM-01-0222
+A2019-NX-01-1052
+A2019-NX-01-0596
+A2017-EM-01-0069
+A2019-EM-01-0243
+A2019-NX-01-0845
+A2015-EM-01-0327
+A2019-EM-01-0215
+A2018-EM-01-0912
+A2018-NX-01-0038
+A2019-NX-01-0282
+A2019-NX-01-0161
+A2017-EM-01-0407
+A2018-EM-01-0079
+A2019-NX-01-1322
+A2019-NX-01-0616
+A2015-EM-01-0243
+A2019-NX-01-0072
+B2016-EM-01-0075
+A2018-EM-01-0229
+D2020-NX-01-0153
+A2016-EM-01-0242
+C2020-EM-01-0253
+A2019-NX-01-0567
+A2020-NX-01-0024
+A2016-EM-01-0174
+A2015-EM-01-0047
+A2018-EM-01-0218
+B2018-EM-01-0050
+A2017-EM-01-0194
+B2019-EM-01-0031
+C2020-EM-01-0093
+C2018-EM-01-0336
+C2018-EM-01-0228
+B2014-EM-01-0029
+B2016-EM-01-0072
+C2018-EM-01-0006
+A2018-NX-01-0157
+A2019-EM-01-0296
+B2016-EM-01-0009
+A2020-NX-01-0302
+C2018-EM-01-0227
+A2018-NX-01-0052
+A2018-EM-01-0280
+B2017-EM-01-0073
+A2015-EM-01-0140
+C2020-EM-01-0105
+A2017-EM-01-0207
+C2019-EM-01-0116
+A2020-NX-01-0083
+C2018-EM-01-0010
+A2019-NX-01-1615
+A2018-NX-01-0028
+A2019-NX-01-0263
+A2019-NX-01-1381
+C2020-EM-01-0219
+C2019-EM-01-0375
+A2020-NX-01-0189
+A2016-EM-01-0401
+A2020-NX-01-0403
+A2019-NX-01-0702
+A2016-EM-01-0381
+A2015-EM-01-0335
+D2020-NX-01-0009
+A2018-EM-01-0937
+B2016-EM-01-0017
+C2019-EM-01-0108
+A2020-NX-01-0719
+A2018-EM-01-0335
+A2017-EM-01-0156
+A2018-EM-01-0213
+A2018-EM-01-0887
+A2017-EM-01-0368
+C2018-EM-01-0297
+A2016-EM-01-0311
+A2019-NX-01-0427
+A2019-NX-01-0381
+A2018-EM-01-0080
+A2020-NX-01-0372
+A2018-EM-01-0454
+A2018-EM-01-0707
+A2020-NX-01-0110
+A2020-NX-01-0140
+D2020-NX-01-0294
+A2019-NX-01-0794
+A2018-NX-01-0182
+B2014-EM-01-0085
+A2019-NX-01-0031
+A2016-EM-01-0103
+A2016-EM-01-0138
+C2020-EM-01-0014
+A2020-NX-01-0020
+A2017-EM-01-0454
+A2019-EM-01-0166
+A2018-EM-01-0727
+A2015-EM-01-0340
+A2018-EM-01-0492
+C2019-EM-01-0062
+A2019-NX-01-1203
+A2018-EM-01-0393
+A2017-EM-01-0240
+C2020-EM-01-0174
+A2018-NX-01-0338
+B2016-EM-01-0093
+A2016-EM-01-0365
+A2017-EM-01-0035
+A2015-EM-01-0016
+A2017-EM-01-0149
+A2019-NX-01-0467
+B2019-EM-01-0027
+B2018-EM-01-0052
+A2015-EM-01-0037
+A2015-EM-01-0122
+B2013-EM-01-0009
+B2013-EM-01-0083
+A2018-NX-01-0297
+B2019-EM-01-0019
+A2016-EM-01-0202
+A2019-EM-01-0086
+A2020-NX-01-0027
+A2018-EM-01-0942
+D2020-NX-01-0203
+A2020-NX-01-0312
+A2019-NX-01-0625
+A2019-NX-01-1124
+C2019-EM-01-0169
+C2020-EM-01-0231
+A2020-NX-01-0117
+D2020-NX-01-0058
+A2019-NX-01-0846
+A2020-NX-01-0512
+A2018-NX-01-0282
+A2016-EM-01-0243
+A2019-NX-01-1620
+A2018-EM-01-0419
+C2020-EM-01-0120
+C2019-EM-01-0012
+A2018-EM-01-0104
+A2019-NX-01-0986
+A2020-NX-01-0319
+A2020-NX-01-0328
+D2020-NX-01-0196
+D2019-NX-01-0054
+A2017-EM-01-0327
+A2016-EM-01-0423
+A2019-NX-01-1088
+A2018-NX-01-0026
+C2018-EM-01-0058
+A2019-NX-01-1012
+C2019-EM-01-0003
+A2017-EM-01-0196
+A2018-EM-01-0685
+A2019-EM-01-0194
+C2019-EM-01-0010
+A2019-NX-01-0858
+A2018-EM-01-0411
+A2019-NX-01-0168
+A2019-NX-01-1132
+A2019-NX-01-1263
+A2017-EM-01-0115
+A2017-EM-01-0008
+A2018-EM-01-0203
+A2019-NX-01-1123
+A2020-NX-01-0259
+A2019-EM-01-0228
+A2019-NX-01-0176
+A2017-EM-01-0326
+A2020-NX-01-0564
+A2020-NX-01-0483
+D2019-NX-01-0051
+B2013-EM-01-0107
+C2018-EM-01-0333
+A2018-EM-01-0220
+A2019-NX-01-0713
+A2019-NX-01-0971
+B2018-EM-01-0175
+A2019-NX-01-0104
+A2016-EM-01-0405
+A2017-EM-01-0182
+A2019-NX-01-1468
+A2017-EM-01-0029
+A2020-NX-01-0726
+A2020-NX-01-0460
+A2019-NX-01-1311
+A2019-NX-01-1157
+A2018-EM-01-0989
+A2019-NX-01-0727
+A2020-NX-01-0742
+A2019-NX-01-1398
+A2018-EM-01-0941
+B2013-EM-01-0079
+A2017-EM-01-0523
+A2019-NX-01-0330
+A2016-EM-01-0292
+C2020-EM-01-0090
+A2016-EM-01-0160
+A2019-NX-01-1165
+A2017-EM-01-0410
+A2019-NX-01-1531
+A2015-EM-01-0321
+A2020-NX-01-0316
+B2018-EM-01-0083
+A2018-EM-01-0695
+D2020-NX-01-0012
+A2018-NX-01-0253
+C2019-EM-01-0312
+A2019-NX-01-1318
+A2019-NX-01-0737
+A2018-EM-01-1005
+A2020-NX-01-0001
+A2017-EM-01-0481
+D2020-NX-01-0143
+C2019-EM-01-0017
+A2019-NX-01-1635
+C2018-EM-01-0241
+A2016-EM-01-0183
+A2016-EM-01-0341
+C2019-EM-01-0251
+A2019-NX-01-1542
+B2016-EM-01-0102
+A2020-NX-01-0423
+A2019-NX-01-0556
+A2019-NX-01-1033
+A2018-EM-01-0238
+A2019-EM-01-0047
+A2015-EM-01-0257
+C2019-EM-01-0340
+C2018-EM-01-0048
+A2015-EM-01-0262
+A2019-EM-01-0278
+A2020-NX-01-0636
+B2015-EM-01-0101
+A2020-NX-01-0427
+C2018-EM-01-0340
+A2018-EM-01-0123
+A2019-NX-01-0906
+A2020-NX-01-0785
+A2019-NX-01-0588
+A2018-NX-01-0350
+A2018-EM-01-0288
+A2018-EM-01-0948
+A2019-EM-01-0130
+A2018-EM-01-0262
+A2019-NX-01-0435
+C2020-EM-01-0043
+C2018-EM-01-0092
+A2017-EM-01-0441
+A2018-NX-01-0241
+A2018-EM-01-0700
+D2020-NX-01-0208
+A2018-NX-01-0143
+A2018-EM-01-0684
+A2017-EM-01-0381
+A2018-EM-01-0767
+D2019-NX-01-0062
+A2019-NX-01-1618
+A2020-NX-01-0196
+A2017-EM-01-0399
+A2017-EM-01-0428
+A2018-EM-01-0726
+A2019-NX-01-1607
+A2018-NX-01-0303
+A2019-NX-01-0682
+A2019-NX-01-0502
+A2019-NX-01-0266
+A2017-EM-01-0043
+A2018-NX-01-0375
+A2018-NX-01-0195
+C2018-EM-01-0283
+A2020-NX-01-0091
+B2019-NX-01-0021
+A2018-NX-01-0185
+C2020-EM-01-0196
+A2019-NX-01-0651
+B2017-EM-01-0039
+A2019-NX-01-0313
+A2018-EM-01-0748
+A2019-NX-01-1147
+A2019-NX-01-1499
+A2018-EM-01-0621
+C2019-EM-01-0080
+D2019-NX-01-0209
+A2018-EM-01-0994
+B2018-EM-01-0004
+D2020-NX-01-0166
+A2019-NX-01-0372
+C2020-EM-01-0339
+A2018-EM-01-0133
+B2018-EM-01-0104
+A2019-NX-01-1351
+C2020-EM-01-0127
+A2019-EM-01-0025
+A2019-NX-01-1006
+A2018-EM-01-0961
+A2019-NX-01-1389
+A2018-NX-01-0263
+A2018-EM-01-0653
+A2017-EM-01-0157
+A2018-EM-01-0588
+C2019-EM-01-0258
+A2019-NX-01-1497
+B2017-EM-01-0098
+A2019-NX-01-0087
+A2020-NX-01-0703
+A2020-NX-01-0367
+A2020-NX-01-0368
+A2019-NX-01-0096
+A2018-EM-01-0904
+C2020-EM-01-0104
+A2020-NX-01-0496
+D2019-NX-01-0007
+A2017-EM-01-0203
+A2019-NX-01-1348
+A2017-EM-01-0153
+D2019-NX-01-0042
+C2020-EM-01-0198
+A2019-NX-01-0885
+A2020-NX-01-0653
+A2018-EM-01-0243
+C2020-EM-01-0234
+A2018-EM-01-0014
+B2018-EM-01-0080
+A2016-EM-01-0326
+A2015-EM-01-0429
+D2019-NX-01-0183
+A2019-NX-01-0687
+B2016-EM-01-0021
+C2019-EM-01-0025
+A2020-NX-01-0245
+D2020-NX-01-0156
+A2017-EM-01-0262
+A2018-NX-01-0013
+A2018-EM-01-0699
+B2019-NX-01-0020
+A2019-NX-01-0790
+A2018-EM-01-0180
+D2019-NX-01-0206
+A2018-EM-01-0068
+A2018-EM-01-0556
+A2019-NX-01-0061
+B2015-EM-01-0151
+D2019-NX-01-0203
+A2018-EM-01-0548
+A2018-EM-01-0245
+A2018-EM-01-0773
+A2019-NX-01-1473
+C2019-EM-01-0268
+A2020-EM-01-0066
+A2019-NX-01-1453
+C2020-EM-01-0049
+C2020-EM-01-0033
+A2016-EM-01-0395
+A2015-EM-01-0162
+C2019-EM-01-0243
+A2018-EM-01-0027
+A2020-EM-01-0078
+A2018-EM-01-0752
+A2019-NX-01-1228
+A2018-EM-01-0733
+A2018-NX-01-0268
+C2019-EM-01-0153
+B2017-EM-01-0068
+A2018-NX-01-0203
+B2015-EM-01-0075
+D2020-NX-01-0247
+A2019-NX-01-1173
+A2020-EM-01-0002
+A2019-NX-01-0788
+A2018-EM-01-0808
+A2020-NX-01-0182
+D2019-NX-01-0019
+A2019-NX-01-0011
+A2019-NX-01-1397
+A2020-NX-01-0250
+A2019-NX-01-1166
+A2018-EM-01-0509
+A2017-EM-01-0382
+A2019-EM-01-0183
+C2020-EM-01-0290
+A2018-EM-01-0193
+A2018-EM-01-0938
+C2018-EM-01-0017
+A2020-NX-01-0624
+A2017-EM-01-0107
+A2016-EM-01-0031
+A2018-EM-01-0539
+A2018-EM-01-0574
+A2019-NX-01-1099
+A2018-NX-01-0121
+A2015-EM-01-0107
+D2020-NX-01-0270
+A2015-EM-01-0279
+A2015-EM-01-0453
+B2019-NX-01-0011
+C2018-EM-01-0205
+A2020-EM-01-0063
+A2019-NX-01-0809
+A2015-EM-01-0387
+A2016-EM-01-0012
+A2018-EM-01-0055
+A2020-NX-01-0572
+A2016-EM-01-0205
+A2019-NX-01-0014
+A2019-NX-01-0908
+A2019-NX-01-0099
+A2020-NX-01-0160
+D2019-NX-01-0186
+A2020-NX-01-0242
+A2019-NX-01-0772
+A2019-NX-01-0836
+A2016-EM-01-0167
+A2019-NX-01-0746
+A2019-NX-01-0981
+A2020-NX-01-0028
+D2020-NX-01-0103
+A2017-EM-01-0202
+A2018-NX-01-0183
+C2019-EM-01-0353
+D2020-NX-01-0230
+D2020-NX-01-0256
+A2016-EM-01-0082
+A2019-EM-01-0188
+B2018-EM-01-0006
+D2020-NX-01-0189
+A2019-EM-01-0092
+B2014-EM-01-0031
+A2020-NX-01-0142
+C2019-EM-01-0074
+A2018-EM-01-0195
+A2019-EM-01-0127
+B2016-EM-01-0065
+B2013-EM-01-0037
+A2015-EM-01-0388
+A2019-NX-01-1041
+A2017-EM-01-0211
+B2013-EM-01-0105
+A2017-EM-01-0168
+A2019-NX-01-0043
+A2019-NX-01-0304
+A2018-NX-01-0371
+A2019-NX-01-0950
+B2016-EM-01-0079
+A2019-NX-01-0431
+D2020-NX-01-0065
+C2020-EM-01-0056
+A2018-EM-01-0196
+C2018-EM-01-0271
+A2018-NX-01-0231
+A2020-NX-01-0065
+A2016-EM-01-0022
+A2019-NX-01-0620
+A2019-NX-01-0451
+A2018-EM-01-0789
+A2018-NX-01-0284
+A2019-NX-01-1396
+A2017-EM-01-0223
+A2016-EM-01-0417
+A2015-EM-01-0027
+A2015-EM-01-0050
+D2019-NX-01-0272
+A2019-NX-01-0114
+A2019-NX-01-1278
+A2019-NX-01-1190
+D2020-NX-01-0116
+A2017-EM-01-0259
+A2019-NX-01-1494
+B2016-EM-01-0043
+A2020-NX-01-0217
+D2019-NX-01-0218
+A2019-NX-01-0887
+A2019-NX-01-0005
+A2020-NX-01-0292
+A2018-NX-01-0170
+A2016-EM-01-0419
+A2018-NX-01-0304
+A2020-NX-01-0163
+A2019-NX-01-1565
+A2019-EM-01-0056
+A2020-NX-01-0148
+A2019-NX-01-1551
+A2018-NX-01-0391
+C2020-EM-01-0306
+A2018-EM-01-0394
+A2018-EM-01-0171
+C2020-EM-01-0332
+A2020-NX-01-0678
+C2020-EM-01-0084
+A2017-EM-01-0018
+D2020-NX-01-0228
+D2020-NX-01-0064
+A2018-EM-01-0843
+A2018-EM-01-0549
+A2019-NX-01-0912
+A2018-EM-01-0100
+A2019-NX-01-1566
+A2018-EM-01-0892
+A2020-NX-01-0281
+A2017-EM-01-0331
+A2020-EM-01-0009
+A2017-EM-01-0318
+A2017-EM-01-0200
+A2016-EM-01-0375
+A2018-NX-01-0312
+A2018-NX-01-0224
+D2020-NX-01-0293
+C2020-EM-01-0191
+A2020-NX-01-0349
+A2018-EM-01-0693
+B2017-EM-01-0007
+B2017-EM-01-0015
+C2020-EM-01-0263
+A2017-EM-01-0252
+C2019-EM-01-0218
+A2019-NX-01-0805
+A2017-EM-01-0109
+A2020-NX-01-0131
+A2018-EM-01-0212
+D2019-NX-01-0078
+A2020-NX-01-0565
+A2017-EM-01-0424
+B2017-EM-01-0056
+C2018-EM-01-0013
+A2018-NX-01-0062
+A2015-EM-01-0274
+C2020-EM-01-0304
+A2019-NX-01-0763
+A2020-NX-01-0340
+A2019-NX-01-0766
+A2019-NX-01-0128
+A2020-NX-01-0266
+A2015-EM-01-0161
+C2018-EM-01-0207
+A2018-EM-01-0501
+A2017-EM-01-0393
+A2018-EM-01-0730
+A2019-EM-01-0224
+A2018-NX-01-0370
+D2020-NX-01-0033
+A2018-EM-01-0816
+A2020-NX-01-0509
+A2019-NX-01-1539
+A2015-EM-01-0300
+A2019-NX-01-1139
+A2018-EM-01-0577
+A2018-EM-01-0901
+A2018-EM-01-0354
+A2020-NX-01-0707
+A2019-NX-01-1392
+A2018-EM-01-0602
+A2020-NX-01-0725
+A2019-NX-01-0946
+A2018-EM-01-0304
+A2015-EM-01-0395
+C2019-EM-01-0201
+A2019-NX-01-1628
+C2018-EM-01-0225
+A2020-NX-01-0468
+A2020-NX-01-0289
+A2020-NX-01-0049
+C2020-EM-01-0256
+A2018-EM-01-0925
+C2020-EM-01-0113
+A2018-EM-01-0041
+A2020-NX-01-0106
+C2018-EM-01-0291
+D2020-NX-01-0239
+A2015-EM-01-0020
+A2020-NX-01-0531
+B2015-EM-01-0116
+A2019-NX-01-0518
+A2017-EM-01-0245
+A2020-NX-01-0573
+A2019-NX-01-0380
+D2019-NX-01-0207
+B2013-EM-01-0073
+C2018-EM-01-0179
+A2018-EM-01-0448
+A2018-EM-01-0934
+A2019-NX-01-1380
+A2020-NX-01-0014
+A2018-NX-01-0252
+A2019-NX-01-1483
+A2015-EM-01-0200
+C2018-EM-01-0133
+A2017-EM-01-0006
+A2015-EM-01-0380
+A2019-NX-01-0474
+A2019-NX-01-0228
+A2019-NX-01-1613
+A2015-EM-01-0253
+A2020-NX-01-0133
+A2019-NX-01-0528
+B2016-EM-01-0034
+D2020-NX-01-0246
+C2019-EM-01-0070
+A2019-NX-01-0931
+A2018-EM-01-0676
+A2019-NX-01-1310
+A2019-EM-01-0142
+A2018-NX-01-0330
+A2019-EM-01-0122
+A2020-NX-01-0788
+A2020-NX-01-0731
+A2017-EM-01-0053
+D2019-NX-01-0053
+A2019-NX-01-1162
+A2015-EM-01-0064
+A2016-EM-01-0169
+A2015-EM-01-0362
+A2019-NX-01-1153
+C2020-EM-01-0349
+A2019-NX-01-1485
+A2019-NX-01-1588
+A2018-EM-01-0345
+C2020-EM-01-0155
+A2019-NX-01-0177
+A2020-NX-01-0451
+A2019-NX-01-0143
+A2015-EM-01-0299
+A2019-EM-01-0033
+A2019-NX-01-1264
+A2019-NX-01-0983
+A2020-NX-01-0611
+C2018-EM-01-0233
+A2018-EM-01-0277
+C2019-EM-01-0245
+A2018-NX-01-0041
+C2018-EM-01-0139
+A2018-EM-01-0906
+A2018-EM-01-0768
+B2018-EM-01-0096
+C2019-EM-01-0109
+B2016-EM-01-0019
+A2020-NX-01-0622
+B2018-EM-01-0108
+A2016-EM-01-0305
+C2020-EM-01-0007
+B2016-EM-01-0037
+A2015-EM-01-0158
+A2019-NX-01-0163
+A2019-NX-01-1151
+A2017-EM-01-0067
+D2019-NX-01-0075
+D2020-NX-01-0008
+A2019-EM-01-0169
+A2018-EM-01-0114
+A2016-EM-01-0188
+B2019-NX-01-0084
+A2019-EM-01-0084
+A2019-NX-01-1563
+B2019-EM-01-0034
+A2018-EM-01-0330
+A2016-EM-01-0424
+B2017-EM-01-0012
+A2017-EM-01-0375
+A2020-EM-01-0038
+A2018-NX-01-0247
+A2019-NX-01-1170
+A2018-EM-01-0441
+A2019-EM-01-0295
+A2019-EM-01-0022
+A2018-EM-01-0307
+A2018-EM-01-0034
+A2018-EM-01-0711
+A2019-NX-01-0464
+A2020-NX-01-0335
+C2019-EM-01-0255
+A2018-NX-01-0286
+A2020-NX-01-0559
+B2017-EM-01-0107
+A2018-EM-01-0652
+C2020-EM-01-0324
+A2019-NX-01-0252
+A2017-EM-01-0104
+A2020-NX-01-0787
+A2016-EM-01-0140
+A2019-EM-01-0046
+A2018-EM-01-0403
+A2019-EM-01-0137
+A2020-NX-01-0669
+A2018-EM-01-0996
+A2020-NX-01-0461
+A2019-NX-01-0731
+A2019-EM-01-0146
+B2014-EM-01-0077
+A2020-EM-01-0064
+A2018-EM-01-1000
+A2019-NX-01-1572
+A2019-NX-01-0962
+A2020-NX-01-0097
+B2014-EM-01-0019
+A2018-EM-01-0910
+C2018-EM-01-0226
+A2019-NX-01-0910
+A2018-NX-01-0097
+A2018-NX-01-0030
+A2020-NX-01-0716
+C2019-EM-01-0290
+D2019-NX-01-0150
+A2019-EM-01-0244
+A2019-EM-01-0271
+A2020-NX-01-0418
+A2015-EM-01-0460
+A2018-EM-01-0350
+A2019-NX-01-0303
+A2018-NX-01-0187
+A2018-NX-01-0098
+A2020-EM-01-0081
+A2020-NX-01-0756
+A2019-NX-01-1427
+A2019-NX-01-1442
+A2018-EM-01-0514
+D2019-NX-01-0124
+D2020-NX-01-0240
+B2013-EM-01-0008
+A2019-NX-01-0756
+A2020-NX-01-0138
+A2019-NX-01-0855
+A2017-EM-01-0371
+A2020-NX-01-0399
+C2020-EM-01-0321
+C2019-EM-01-0120
+A2020-NX-01-0376
+A2016-EM-01-0383
+A2015-EM-01-0231
+A2018-EM-01-0050
+A2015-EM-01-0267
+A2015-EM-01-0294
+B2018-EM-01-0153
+C2019-EM-01-0165
+B2014-EM-01-0001
+A2020-NX-01-0592
+B2016-EM-01-0119
+B2013-EM-01-0074
+A2020-NX-01-0428
+A2019-NX-01-0659
+A2019-EM-01-0193
+A2017-EM-01-0047
+B2018-EM-01-0103
+A2018-EM-01-0364
+A2019-NX-01-1020
+B2014-EM-01-0069
+C2019-EM-01-0379
+A2019-NX-01-0675
+A2019-NX-01-1345
+A2019-NX-01-1371
+B2018-EM-01-0129
+C2020-EM-01-0265
+A2019-NX-01-0379
+A2018-NX-01-0144
+C2019-EM-01-0364
+A2018-NX-01-0107
+A2019-EM-01-0017
+A2019-NX-01-0920
+A2018-EM-01-0257
+A2020-NX-01-0290
+B2018-EM-01-0088
+A2019-NX-01-1186
+C2019-EM-01-0152
+B2017-EM-01-0097
+A2020-EM-01-0075
+B2018-EM-01-0149
+D2020-NX-01-0121
+A2019-NX-01-1032
+A2018-EM-01-0879
+A2018-NX-01-0078
+A2019-NX-01-0477
+A2018-EM-01-0124
+A2018-EM-01-0251
+B2018-EM-01-0165
+A2018-EM-01-0958
+A2018-EM-01-0129
+A2019-NX-01-0015
+A2019-NX-01-1455
+A2019-NX-01-0025
+C2020-EM-01-0246
+A2017-EM-01-0304
+A2019-NX-01-1167
+B2015-EM-01-0095
+A2018-NX-01-0384
+A2018-NX-01-0236
+C2018-EM-01-0287
+A2017-EM-01-0489
+A2019-NX-01-1001
+D2020-NX-01-0045
+A2018-NX-01-0146
+A2018-NX-01-0092
+A2019-NX-01-0413
+A2015-EM-01-0179
+A2020-NX-01-0775
+A2018-EM-01-0205
+A2017-EM-01-0514
+A2017-EM-01-0020
+B2017-EM-01-0054
+A2016-EM-01-0265
+A2016-EM-01-0001
+A2019-NX-01-1477
+C2020-EM-01-0347
+B2015-EM-01-0100
+A2019-NX-01-1603
+C2018-EM-01-0030
+A2016-EM-01-0229
+A2019-NX-01-1298
+C2019-EM-01-0147
+A2017-EM-01-0034
+A2015-EM-01-0305
+A2019-NX-01-0318
+C2020-EM-01-0103
+A2017-EM-01-0216
+B2018-EM-01-0178
+A2020-NX-01-0393
+C2018-EM-01-0099
+C2020-EM-01-0085
+A2018-NX-01-0148
+A2015-EM-01-0280
+D2019-NX-01-0038
+A2017-EM-01-0493
+A2019-NX-01-0458
+B2016-EM-01-0130
+A2019-NX-01-1271
+A2018-NX-01-0160
+A2016-EM-01-0029
+B2019-NX-01-0003
+A2018-EM-01-0593
+C2019-EM-01-0114
+A2019-NX-01-1323
+A2019-NX-01-0922
+A2020-NX-01-0466
+C2020-EM-01-0161
+C2019-EM-01-0274
+A2018-NX-01-0442
+A2018-NX-01-0127
+D2019-NX-01-0158
+B2013-EM-01-0039
+A2019-NX-01-0674
+A2019-NX-01-0281
+A2019-NX-01-0205
+A2020-EM-01-0062
+A2019-NX-01-1571
+A2019-NX-01-0785
+C2019-EM-01-0081
+A2015-EM-01-0358
+A2020-NX-01-0497
+A2020-NX-01-0548
+A2018-EM-01-0447
+A2019-EM-01-0104
+A2018-EM-01-0113
+A2018-NX-01-0329
+A2018-NX-01-0119
+A2020-EM-01-0036
+B2018-EM-01-0167
+A2019-NX-01-0610
+A2017-EM-01-0170
+A2019-NX-01-0712
+A2019-NX-01-1525
+C2020-EM-01-0315
+A2019-NX-01-1014
+A2019-NX-01-0386
+A2018-EM-01-0037
+C2019-EM-01-0356
+A2019-NX-01-0118
+C2018-EM-01-0096
+A2019-NX-01-0526
+B2019-EM-01-0001
+A2015-EM-01-0289
+A2019-NX-01-1536
+C2019-EM-01-0113
+A2016-EM-01-0249
+A2019-NX-01-0515
+A2015-EM-01-0074
+A2017-EM-01-0051
+A2019-NX-01-0574
+A2018-EM-01-0827
+A2019-NX-01-1141
+A2019-NX-01-1270
+B2015-EM-01-0063
+A2019-NX-01-1068
+A2018-NX-01-0301
+A2020-NX-01-0439
+A2019-NX-01-0444
+B2016-EM-01-0044
+A2020-NX-01-0795
+A2020-NX-01-0169
+C2020-EM-01-0057
+A2019-NX-01-0211
+B2019-EM-01-0058
+A2020-NX-01-0768
+A2018-EM-01-0137
+A2018-EM-01-0552
+A2016-EM-01-0329
+A2018-EM-01-0437
+B2017-EM-01-0002
+B2013-EM-01-0087
+A2017-EM-01-0305
+A2015-EM-01-0276
+A2020-NX-01-0352
+C2020-EM-01-0114
+B2016-EM-01-0085
+C2018-EM-01-0348
+A2019-EM-01-0284
+A2019-NX-01-1144
+A2016-EM-01-0025
+B2015-EM-01-0117
+A2019-NX-01-1534
+B2018-EM-01-0066
+D2019-NX-01-0030
+A2019-EM-01-0068
+A2016-EM-01-0321
+B2013-EM-01-0004
+C2018-EM-01-0140
+A2019-NX-01-0468
+A2018-EM-01-0664
+A2019-NX-01-0479
+A2020-NX-01-0539
+A2020-NX-01-0426
+D2020-NX-01-0093
+A2016-EM-01-0056
+A2019-NX-01-1254
+A2020-NX-01-0480
+B2018-EM-01-0090
+A2018-EM-01-0070
+C2020-EM-01-0317
+A2015-EM-01-0106
+A2018-EM-01-0516
+C2019-EM-01-0329
+D2019-NX-01-0112
+A2020-EM-01-0011
+A2016-EM-01-0271
+A2018-NX-01-0271
+A2019-NX-01-1457
+A2018-NX-01-0066
+A2018-EM-01-0654
+A2017-EM-01-0427
+A2019-NX-01-0992
+A2019-NX-01-0194
+A2018-EM-01-0111
+A2019-NX-01-0512
+A2018-NX-01-0156
+A2017-EM-01-0453
+A2017-EM-01-0174
+A2020-NX-01-0405
+C2020-EM-01-0086
+C2020-EM-01-0065
+A2020-NX-01-0626
+A2019-NX-01-0990
+A2020-NX-01-0701
+A2019-NX-01-0550
+B2015-EM-01-0019
+A2020-NX-01-0781
+D2020-NX-01-0235
+B2016-EM-01-0074
+A2017-EM-01-0459
+A2019-NX-01-1200
+A2020-NX-01-0143
+A2020-NX-01-0596
+A2015-EM-01-0269
+B2013-EM-01-0040
+A2016-EM-01-0231
+C2020-EM-01-0088
+A2019-NX-01-1521
+A2018-NX-01-0133
+D2019-NX-01-0032
+A2019-NX-01-1623
+A2018-EM-01-0755
+C2018-EM-01-0200
+D2019-NX-01-0117
+A2018-EM-01-0708
+D2019-NX-01-0254
+A2015-EM-01-0465
+A2020-NX-01-0672
+A2019-NX-01-0618
+A2018-NX-01-0023
+A2017-EM-01-0261
+A2019-NX-01-1666
+C2019-EM-01-0336
+A2019-NX-01-0593
+A2019-NX-01-0297
+A2019-NX-01-0669
+A2018-EM-01-0954
+A2020-NX-01-0687
+A2018-EM-01-0660
+A2019-NX-01-0429
+A2016-EM-01-0293
+A2019-EM-01-0235
+A2020-NX-01-0454
+A2019-NX-01-1423
+C2019-EM-01-0013
+A2017-EM-01-0064
+A2019-NX-01-1558
+A2019-NX-01-1233
+A2020-NX-01-0397
+A2015-EM-01-0384
+A2019-NX-01-0957
+A2020-NX-01-0278
+A2018-EM-01-0739
+B2013-EM-01-0018
+A2018-NX-01-0085
+A2019-NX-01-0927
+B2015-EM-01-0029
+A2020-NX-01-0751
+B2013-EM-01-0100
+A2019-NX-01-0158
+B2016-EM-01-0052
+A2018-NX-01-0246
+A2018-EM-01-0439
+D2019-NX-01-0058
+A2019-EM-01-0089
+A2020-NX-01-0345
+A2018-EM-01-1006
+A2019-NX-01-0397
+C2020-EM-01-0148
+C2018-EM-01-0001
+A2019-EM-01-0050
+A2016-EM-01-0132
+A2019-NX-01-0361
+C2019-EM-01-0006
+C2018-EM-01-0328
+A2015-EM-01-0259
+A2018-EM-01-0518
+D2020-NX-01-0094
+A2020-NX-01-0632
+A2019-NX-01-0865
+A2019-NX-01-0419
+A2019-NX-01-1470
+A2020-NX-01-0364
+A2018-NX-01-0213
+A2020-NX-01-0033
+A2018-NX-01-0417
+A2018-EM-01-0340
+A2018-NX-01-0314
+A2017-EM-01-0284
+A2018-EM-01-0136
+A2018-EM-01-0353
+A2018-NX-01-0366
+A2017-EM-01-0547
+A2018-EM-01-0008
+A2020-NX-01-0047
+D2019-NX-01-0090
+A2016-EM-01-0171
+C2020-EM-01-0331
+A2018-EM-01-0750
+A2018-EM-01-0999
+A2019-NX-01-0027
+C2018-EM-01-0350
+A2018-NX-01-0217
+A2020-NX-01-0600
+C2019-EM-01-0276
+A2018-EM-01-0470
+C2019-EM-01-0207
+A2019-NX-01-0225
+B2017-EM-01-0034
+A2019-NX-01-0980
+D2019-NX-01-0131
+C2020-EM-01-0128
+B2017-EM-01-0009
+A2020-NX-01-0570
+B2015-EM-01-0049
+B2017-EM-01-0018
+A2017-EM-01-0080
+A2019-NX-01-0838
+A2018-EM-01-0406
+A2019-NX-01-0834
+B2017-EM-01-0060
+A2016-EM-01-0155
+A2019-NX-01-1368
+A2019-NX-01-1399
+A2017-EM-01-0026
+B2015-EM-01-0142
+A2017-EM-01-0015
+A2019-NX-01-0776
+A2019-NX-01-1350
+A2019-NX-01-0107
+A2019-NX-01-1486
+C2019-EM-01-0285
+C2018-EM-01-0360
+B2015-EM-01-0058
+B2019-EM-01-0025
+D2019-NX-01-0214
+A2020-NX-01-0103
+A2019-NX-01-0288
+D2020-NX-01-0079
+A2020-EM-01-0030
+A2018-EM-01-0344
+A2015-EM-01-0127
+B2017-EM-01-0059
+A2020-EM-01-0051
+C2019-EM-01-0038
+A2018-NX-01-0179
+A2020-NX-01-0358
+A2019-NX-01-0349
+A2019-NX-01-0490
+D2019-NX-01-0006
+A2019-NX-01-1344
+A2018-NX-01-0426
+C2019-EM-01-0008
+A2015-EM-01-0325
+B2013-EM-01-0050
+A2019-NX-01-1067
+A2018-EM-01-0728
+A2019-NX-01-0008
+B2013-EM-01-0054
+A2015-EM-01-0468
+A2019-NX-01-1301
+A2015-EM-01-0334
+A2019-NX-01-1621
+A2018-EM-01-0075
+B2018-EM-01-0156
+A2017-EM-01-0506
+D2020-NX-01-0131
+A2019-NX-01-0171
+A2020-EM-01-0046
+A2018-NX-01-0320
+B2015-EM-01-0006
+A2019-EM-01-0186
+C2019-EM-01-0072
+D2020-NX-01-0249
+B2016-EM-01-0115
+A2017-EM-01-0372
+C2018-EM-01-0080
+A2020-NX-01-0491
+A2017-EM-01-0343
+A2018-EM-01-0144
+A2016-EM-01-0325
+B2014-EM-01-0046
+A2018-EM-01-0268
+A2016-EM-01-0296
+A2016-EM-01-0274
+A2019-NX-01-1048
+A2015-EM-01-0329
+A2018-EM-01-0536
+A2015-EM-01-0281
+A2015-EM-01-0153
+A2020-NX-01-0606
+A2018-EM-01-0930
+B2015-EM-01-0145
+A2019-NX-01-0280
+A2016-EM-01-0281
+B2018-EM-01-0121
+A2018-NX-01-0125
+B2019-NX-01-0016
+A2019-NX-01-0786
+A2019-NX-01-1591
+C2019-EM-01-0332
+A2019-EM-01-0269
+A2018-EM-01-0414
+A2019-NX-01-0434
+A2020-NX-01-0194
+A2018-NX-01-0142
+D2020-NX-01-0201
+A2019-NX-01-0923
+B2019-EM-01-0056
+C2019-EM-01-0314
+A2016-EM-01-0357
+B2017-EM-01-0031
+A2018-EM-01-0857
+A2019-NX-01-0915
+A2016-EM-01-0156
+A2018-NX-01-0351
+A2018-NX-01-0243
+A2015-EM-01-0098
+A2018-EM-01-0028
+A2015-EM-01-0317
+A2020-NX-01-0543
+D2019-NX-01-0084
+A2020-NX-01-0272
+A2018-NX-01-0441
+A2020-NX-01-0356
+A2020-NX-01-0523
+A2018-NX-01-0433
+A2018-NX-01-0373
+A2018-EM-01-0467
+A2018-EM-01-0626
+C2018-EM-01-0202
+A2020-NX-01-0638
+B2015-EM-01-0024
+A2019-NX-01-1651
+A2020-NX-01-0150
+A2019-NX-01-1532
+A2018-EM-01-0858
+B2013-EM-01-0024
+B2019-NX-01-0087
+C2019-EM-01-0358
+A2016-EM-01-0278
+A2017-EM-01-0356
+C2019-EM-01-0367
+C2019-EM-01-0372
+A2015-EM-01-0134
+A2019-NX-01-1516
+B2019-EM-01-0039
+C2020-EM-01-0279
+A2016-EM-01-0288
+C2020-EM-01-0036
+A2016-EM-01-0120
+A2020-NX-01-0098
+A2018-EM-01-0110
+A2018-NX-01-0340
+A2018-EM-01-0822
+D2020-NX-01-0193
+A2020-NX-01-0034
+A2019-NX-01-0964
+A2018-EM-01-0991
+A2019-NX-01-0880
+A2016-EM-01-0256
+A2018-EM-01-0619
+A2019-NX-01-1061
+C2020-EM-01-0159
+A2016-EM-01-0353
+A2019-NX-01-0995
+A2020-NX-01-0306
+A2019-NX-01-1393
+A2019-NX-01-0798
+A2019-NX-01-1653
+A2019-NX-01-0028
+A2016-EM-01-0418
+A2018-EM-01-0837
+A2019-NX-01-1109
+B2018-EM-01-0049
+A2017-EM-01-0068
+A2016-EM-01-0076
+A2019-NX-01-0347
+A2020-NX-01-0659
+A2018-EM-01-0985
+D2020-NX-01-0262
+A2018-NX-01-0046
+A2019-NX-01-0206
+C2019-EM-01-0054
+A2019-EM-01-0292
+A2015-EM-01-0181
+A2017-EM-01-0178
+A2019-EM-01-0172
+A2019-NX-01-1092
+D2019-NX-01-0208
+B2018-EM-01-0056
+A2020-NX-01-0330
+C2019-EM-01-0173
+A2017-EM-01-0195
+A2020-NX-01-0016
+A2018-EM-01-0140
+A2018-EM-01-0911
+A2015-EM-01-0005
+B2016-EM-01-0005
+A2018-EM-01-0065
+D2020-NX-01-0188
+A2017-EM-01-0270
+B2014-EM-01-0052
+A2016-EM-01-0246
+A2019-NX-01-1050
+A2020-NX-01-0114
+A2015-EM-01-0227
+A2017-EM-01-0406
+A2019-NX-01-0633
+D2020-NX-01-0179
+D2019-NX-01-0157
+A2015-EM-01-0189
+A2016-EM-01-0416
+B2015-EM-01-0083
+A2015-EM-01-0256
+A2017-EM-01-0112
+B2014-EM-01-0017
+A2019-NX-01-1567
+D2020-NX-01-0207
+A2020-NX-01-0058
+A2017-EM-01-0242
+A2019-NX-01-1292
+A2019-NX-01-1204
+B2019-EM-01-0012
+A2019-NX-01-1037
+D2020-NX-01-0163
+D2020-NX-01-0169
+B2014-EM-01-0044
+A2019-NX-01-0085
+A2017-EM-01-0504
+A2019-EM-01-0165
+B2019-EM-01-0048
+A2019-NX-01-1022
+A2019-NX-01-0018
+B2015-EM-01-0110
+A2019-NX-01-0984
+B2019-NX-01-0039
+A2017-EM-01-0447
+A2018-EM-01-0702
+A2020-NX-01-0644
+A2018-NX-01-0387
+A2016-EM-01-0270
+A2019-NX-01-1662
+B2014-EM-01-0038
+A2018-NX-01-0177
+A2015-EM-01-0217
+A2018-EM-01-0876
+A2020-NX-01-0711
+A2019-NX-01-1300
+A2020-NX-01-0087
+A2018-EM-01-0918
+A2018-EM-01-0267
+A2020-NX-01-0793
+A2018-EM-01-0595
+A2018-NX-01-0221
+B2013-EM-01-0027
+A2018-NX-01-0199
+D2019-NX-01-0269
+A2020-NX-01-0767
+A2019-NX-01-1213
+B2015-EM-01-0039
+A2019-NX-01-0231
+A2016-EM-01-0247
+A2020-NX-01-0307
+A2019-NX-01-0812
+A2019-NX-01-0694
+C2018-EM-01-0057
+A2020-NX-01-0662
+A2019-EM-01-0115
+C2020-EM-01-0249
+A2020-NX-01-0545
+A2018-NX-01-0242
+A2020-NX-01-0453
+B2013-EM-01-0096
+A2017-EM-01-0315
+C2018-EM-01-0338
+C2018-EM-01-0180
+A2019-NX-01-0948
+A2018-EM-01-0149
+A2019-NX-01-1544
+A2015-EM-01-0377
+A2017-EM-01-0192
+A2018-EM-01-0025
+A2019-NX-01-0644
+D2020-NX-01-0214
+B2014-EM-01-0027
+A2019-NX-01-1437
+A2019-NX-01-0407
+A2019-EM-01-0066
+A2018-EM-01-0038
+A2016-EM-01-0283
+B2018-EM-01-0125
+A2018-EM-01-0259
+B2017-EM-01-0105
+A2019-NX-01-1450
+A2020-NX-01-0238
+A2019-NX-01-0162
+A2015-EM-01-0023
+A2018-NX-01-0424
+C2019-EM-01-0301
+A2020-NX-01-0665
+A2016-EM-01-0259
+A2017-EM-01-0059
+A2019-NX-01-1105
\ No newline at end of file
diff --git a/data/kiss_meta_data/2_valid_patients.txt b/data/kiss_meta_data/2_valid_patients.txt
new file mode 100644
index 0000000000000000000000000000000000000000..18e14e9934cd279e9821996e91ac48be55b18592
--- /dev/null
+++ b/data/kiss_meta_data/2_valid_patients.txt
@@ -0,0 +1,767 @@
+A2016-EM-01-0207
+A2018-EM-01-0833
+A2017-EM-01-0293
+A2019-NX-01-0348
+A2017-EM-01-0134
+A2015-EM-01-0312
+C2018-EM-01-0108
+A2018-EM-01-0425
+A2020-NX-01-0470
+A2019-NX-01-0602
+A2015-EM-01-0463
+A2018-NX-01-0390
+D2020-NX-01-0085
+C2019-EM-01-0293
+A2019-NX-01-1343
+C2018-EM-01-0067
+A2019-NX-01-0939
+A2018-NX-01-0248
+A2019-NX-01-0325
+A2019-EM-01-0275
+A2015-EM-01-0117
+D2019-NX-01-0138
+A2017-EM-01-0457
+A2019-NX-01-1135
+A2017-EM-01-0508
+A2015-EM-01-0034
+A2018-NX-01-0115
+A2019-NX-01-0899
+C2020-EM-01-0338
+A2018-EM-01-0639
+B2016-EM-01-0060
+A2019-NX-01-0319
+A2016-EM-01-0030
+A2016-EM-01-0064
+A2019-NX-01-0253
+A2020-NX-01-0275
+A2019-NX-01-1359
+A2018-EM-01-0128
+A2019-NX-01-0395
+A2015-EM-01-0378
+A2020-NX-01-0387
+A2019-EM-01-0026
+B2014-EM-01-0020
+B2018-EM-01-0186
+C2018-EM-01-0345
+A2015-EM-01-0447
+B2016-EM-01-0046
+B2019-NX-01-0061
+A2019-NX-01-0310
+C2020-EM-01-0006
+A2019-EM-01-0041
+C2020-EM-01-0248
+A2019-NX-01-1365
+D2019-NX-01-0164
+B2018-EM-01-0133
+A2019-NX-01-1419
+A2015-EM-01-0448
+A2017-EM-01-0301
+A2020-NX-01-0159
+B2015-EM-01-0126
+A2015-EM-01-0390
+A2020-NX-01-0484
+A2016-EM-01-0087
+A2019-EM-01-0207
+A2019-NX-01-1038
+A2019-NX-01-0824
+A2019-NX-01-0778
+A2018-EM-01-0714
+C2019-EM-01-0044
+A2019-NX-01-0148
+A2019-NX-01-1146
+C2020-EM-01-0255
+A2018-EM-01-0208
+B2015-EM-01-0036
+C2020-EM-01-0077
+A2017-EM-01-0422
+A2020-EM-01-0089
+A2020-NX-01-0008
+A2018-EM-01-0570
+A2016-EM-01-0411
+A2019-NX-01-1561
+A2015-EM-01-0240
+D2019-NX-01-0018
+A2018-EM-01-0798
+A2020-NX-01-0394
+A2019-NX-01-0818
+B2015-EM-01-0052
+A2020-NX-01-0584
+C2018-EM-01-0159
+D2019-NX-01-0025
+A2020-NX-01-0391
+A2018-EM-01-0741
+A2018-EM-01-0512
+D2020-NX-01-0100
+A2020-NX-01-0128
+C2020-EM-01-0138
+A2017-EM-01-0280
+B2016-EM-01-0116
+A2020-EM-01-0053
+A2018-NX-01-0296
+A2020-NX-01-0282
+C2018-EM-01-0051
+C2019-EM-01-0248
+B2014-EM-01-0048
+A2015-EM-01-0400
+A2019-EM-01-0255
+A2018-EM-01-0785
+B2018-EM-01-0137
+A2020-NX-01-0472
+A2020-NX-01-0099
+A2015-EM-01-0336
+A2018-NX-01-0035
+C2018-EM-01-0337
+A2019-NX-01-0078
+A2018-EM-01-1009
+A2018-EM-01-0436
+A2018-EM-01-0586
+A2016-EM-01-0236
+D2020-NX-01-0140
+A2019-NX-01-0535
+A2019-NX-01-0780
+A2015-EM-01-0423
+A2019-NX-01-0248
+A2019-NX-01-1081
+A2018-EM-01-0092
+D2020-NX-01-0184
+A2020-NX-01-0264
+A2020-NX-01-0682
+B2014-EM-01-0021
+A2020-NX-01-0571
+A2020-EM-01-0068
+A2019-NX-01-0733
+A2019-NX-01-0066
+A2019-NX-01-1559
+A2019-EM-01-0065
+A2018-EM-01-0015
+A2019-NX-01-0537
+A2019-NX-01-0993
+C2018-EM-01-0149
+A2020-NX-01-0320
+C2020-EM-01-0323
+A2018-EM-01-0023
+A2020-NX-01-0602
+C2019-EM-01-0280
+A2019-EM-01-0227
+C2018-EM-01-0074
+A2015-EM-01-0063
+A2019-EM-01-0242
+D2020-NX-01-0107
+A2019-NX-01-0775
+A2017-EM-01-0524
+A2020-NX-01-0440
+A2018-NX-01-0432
+A2019-NX-01-0034
+A2020-NX-01-0527
+A2016-EM-01-0074
+C2020-EM-01-0205
+A2018-NX-01-0349
+A2019-NX-01-0305
+D2019-NX-01-0076
+A2018-NX-01-0120
+A2019-NX-01-1299
+C2020-EM-01-0318
+C2019-EM-01-0295
+A2015-EM-01-0224
+B2019-EM-01-0005
+A2020-NX-01-0175
+A2019-NX-01-1370
+A2016-EM-01-0067
+A2017-EM-01-0440
+A2019-NX-01-1051
+A2018-EM-01-0916
+B2015-EM-01-0109
+B2018-EM-01-0174
+A2020-NX-01-0560
+D2020-NX-01-0210
+A2019-NX-01-0642
+B2019-NX-01-0066
+A2019-NX-01-0707
+A2020-NX-01-0115
+B2016-EM-01-0063
+B2013-EM-01-0076
+A2015-EM-01-0271
+C2020-EM-01-0296
+A2018-EM-01-0713
+A2018-EM-01-0389
+D2020-NX-01-0211
+D2020-NX-01-0168
+C2018-EM-01-0254
+A2018-EM-01-0343
+A2019-EM-01-0238
+A2018-NX-01-0216
+D2020-NX-01-0149
+A2019-NX-01-0955
+C2018-EM-01-0136
+A2017-EM-01-0470
+A2018-NX-01-0361
+A2020-NX-01-0637
+A2018-EM-01-0216
+A2018-NX-01-0396
+C2019-EM-01-0060
+A2019-NX-01-1249
+A2018-EM-01-0062
+A2017-EM-01-0201
+A2019-NX-01-0017
+A2018-NX-01-0021
+D2019-NX-01-0133
+A2015-EM-01-0116
+A2016-EM-01-0376
+A2017-EM-01-0250
+A2020-NX-01-0096
+D2019-NX-01-0020
+D2020-NX-01-0245
+A2020-NX-01-0708
+B2013-EM-01-0089
+D2019-NX-01-0258
+A2019-NX-01-1140
+A2018-EM-01-0077
+A2020-NX-01-0395
+A2018-NX-01-0124
+A2020-NX-01-0329
+D2020-NX-01-0165
+A2018-EM-01-0052
+C2020-EM-01-0295
+A2019-EM-01-0055
+A2018-NX-01-0189
+D2020-NX-01-0274
+A2017-EM-01-0120
+A2019-NX-01-0681
+B2017-EM-01-0091
+A2019-NX-01-1056
+A2018-EM-01-0677
+A2018-EM-01-0201
+B2018-EM-01-0044
+A2019-NX-01-0553
+D2020-NX-01-0083
+A2019-NX-01-0524
+A2018-EM-01-0234
+C2019-EM-01-0344
+A2020-NX-01-0029
+B2013-EM-01-0019
+A2019-NX-01-0449
+A2018-EM-01-0630
+D2019-NX-01-0091
+A2018-EM-01-0881
+A2019-NX-01-0041
+A2019-NX-01-0290
+A2020-NX-01-0382
+A2019-NX-01-1248
+A2018-NX-01-0353
+A2020-NX-01-0006
+A2020-NX-01-0293
+A2017-EM-01-0310
+A2015-EM-01-0437
+A2018-EM-01-0960
+C2020-EM-01-0200
+A2017-EM-01-0510
+C2019-EM-01-0214
+A2015-EM-01-0462
+C2020-EM-01-0129
+A2018-NX-01-0075
+C2019-EM-01-0052
+D2020-NX-01-0226
+A2018-NX-01-0070
+A2016-EM-01-0221
+A2018-EM-01-0125
+A2018-EM-01-0207
+D2019-NX-01-0178
+C2018-EM-01-0002
+A2019-NX-01-0884
+D2019-NX-01-0193
+A2019-NX-01-0549
+C2018-EM-01-0081
+A2018-EM-01-0189
+A2017-EM-01-0367
+C2019-EM-01-0142
+D2019-NX-01-0014
+C2018-EM-01-0199
+A2018-EM-01-0972
+A2020-NX-01-0641
+A2019-NX-01-0398
+A2020-NX-01-0690
+D2019-NX-01-0248
+A2020-NX-01-0746
+A2020-NX-01-0120
+C2019-EM-01-0098
+A2020-NX-01-0193
+A2020-NX-01-0090
+A2020-NX-01-0455
+A2018-EM-01-0214
+A2020-NX-01-0071
+A2018-EM-01-0468
+A2015-EM-01-0392
+D2020-NX-01-0056
+C2019-EM-01-0316
+A2018-EM-01-0802
+A2015-EM-01-0061
+A2018-EM-01-0148
+A2019-NX-01-0529
+A2018-NX-01-0159
+A2019-NX-01-0415
+A2019-NX-01-1102
+A2018-EM-01-0597
+A2017-EM-01-0550
+A2015-EM-01-0250
+A2017-EM-01-0085
+C2020-EM-01-0201
+C2018-EM-01-0070
+A2016-EM-01-0386
+A2020-NX-01-0635
+A2016-EM-01-0054
+A2019-NX-01-1622
+A2016-EM-01-0045
+A2015-EM-01-0439
+B2017-EM-01-0022
+A2019-NX-01-0743
+A2019-NX-01-1598
+C2018-EM-01-0157
+B2016-EM-01-0125
+A2017-EM-01-0098
+A2016-EM-01-0093
+C2020-EM-01-0151
+A2020-NX-01-0516
+A2019-NX-01-1459
+C2018-EM-01-0122
+B2018-EM-01-0176
+A2020-NX-01-0759
+B2015-EM-01-0070
+A2019-NX-01-0544
+A2018-EM-01-0835
+A2020-NX-01-0754
+A2018-NX-01-0279
+A2018-EM-01-0525
+D2019-NX-01-0271
+C2020-EM-01-0045
+A2020-NX-01-0652
+A2020-NX-01-0575
+C2019-EM-01-0091
+B2016-EM-01-0024
+B2018-EM-01-0136
+C2018-EM-01-0150
+A2020-NX-01-0280
+A2018-NX-01-0229
+B2016-EM-01-0035
+A2019-NX-01-0157
+A2019-EM-01-0077
+A2020-NX-01-0339
+B2016-EM-01-0068
+A2019-NX-01-1541
+B2014-EM-01-0033
+B2019-NX-01-0064
+A2019-EM-01-0267
+A2019-NX-01-1579
+C2019-EM-01-0270
+A2019-NX-01-0606
+A2018-EM-01-0787
+A2019-EM-01-0048
+A2020-NX-01-0688
+A2019-NX-01-0691
+A2017-EM-01-0361
+B2014-EM-01-0105
+A2019-NX-01-1199
+B2017-EM-01-0065
+A2020-NX-01-0283
+A2018-EM-01-0740
+C2019-EM-01-0155
+B2018-EM-01-0159
+A2019-NX-01-1611
+A2018-EM-01-0333
+A2019-NX-01-1074
+A2018-EM-01-0474
+A2020-NX-01-0411
+A2020-NX-01-0569
+A2018-EM-01-0933
+C2020-EM-01-0070
+A2018-NX-01-0389
+A2020-NX-01-0064
+C2019-EM-01-0286
+D2019-NX-01-0257
+A2016-EM-01-0170
+B2018-EM-01-0112
+B2014-EM-01-0102
+A2020-NX-01-0743
+A2019-EM-01-0038
+A2017-EM-01-0163
+A2017-EM-01-0257
+A2015-EM-01-0455
+A2017-EM-01-0451
+A2018-EM-01-0321
+A2018-NX-01-0401
+A2017-EM-01-0409
+A2019-EM-01-0118
+B2018-EM-01-0019
+B2018-EM-01-0077
+A2020-NX-01-0124
+A2017-EM-01-0473
+A2018-NX-01-0147
+A2019-NX-01-0203
+A2016-EM-01-0051
+C2019-EM-01-0306
+B2014-EM-01-0072
+A2019-NX-01-1426
+C2018-EM-01-0085
+C2019-EM-01-0111
+A2018-EM-01-0683
+A2018-NX-01-0076
+D2019-NX-01-0239
+A2019-EM-01-0010
+A2016-EM-01-0114
+A2019-EM-01-0170
+C2019-EM-01-0240
+A2016-EM-01-0390
+C2020-EM-01-0197
+A2019-EM-01-0245
+A2017-EM-01-0169
+C2020-EM-01-0002
+A2019-NX-01-0040
+A2019-NX-01-1496
+A2016-EM-01-0342
+B2016-EM-01-0106
+A2020-NX-01-0629
+A2020-NX-01-0060
+A2018-EM-01-0567
+C2018-EM-01-0118
+A2019-NX-01-0064
+A2018-EM-01-0453
+A2020-NX-01-0195
+A2019-NX-01-1314
+A2020-NX-01-0723
+A2018-EM-01-0795
+A2018-NX-01-0309
+A2018-NX-01-0172
+A2018-NX-01-0168
+B2018-EM-01-0107
+A2017-EM-01-0525
+A2016-EM-01-0102
+A2019-NX-01-1462
+A2019-NX-01-1246
+C2018-EM-01-0059
+D2019-NX-01-0108
+B2013-EM-01-0075
+B2013-EM-01-0045
+C2019-EM-01-0139
+A2019-EM-01-0217
+A2019-NX-01-0195
+A2018-EM-01-0178
+A2018-EM-01-0568
+C2019-EM-01-0180
+C2020-EM-01-0132
+A2019-NX-01-0810
+A2020-NX-01-0257
+A2019-NX-01-0298
+A2019-NX-01-1515
+A2019-NX-01-0120
+B2014-EM-01-0064
+A2020-NX-01-0101
+C2019-EM-01-0132
+A2018-EM-01-0541
+A2018-EM-01-0499
+A2019-NX-01-0851
+A2020-NX-01-0448
+A2019-EM-01-0273
+A2018-EM-01-0712
+A2016-EM-01-0250
+A2019-NX-01-0825
+A2018-NX-01-0032
+A2015-EM-01-0144
+D2020-NX-01-0227
+A2020-NX-01-0185
+A2020-NX-01-0039
+A2019-NX-01-1554
+A2018-EM-01-0838
+B2017-EM-01-0042
+C2018-EM-01-0276
+A2020-NX-01-0586
+C2019-EM-01-0239
+A2020-NX-01-0207
+A2018-EM-01-0006
+A2015-EM-01-0043
+A2017-EM-01-0497
+B2017-EM-01-0030
+A2019-NX-01-0653
+A2020-NX-01-0069
+A2018-EM-01-0059
+C2020-EM-01-0149
+A2019-EM-01-0162
+A2015-EM-01-0052
+A2019-NX-01-1341
+D2019-NX-01-0245
+A2015-EM-01-0038
+A2020-NX-01-0286
+A2019-NX-01-1354
+A2018-EM-01-0112
+A2018-NX-01-0001
+C2019-EM-01-0007
+B2017-EM-01-0019
+A2016-EM-01-0344
+A2019-NX-01-0668
+A2018-EM-01-0988
+B2013-EM-01-0003
+A2017-EM-01-0509
+B2019-EM-01-0051
+A2019-EM-01-0158
+A2016-EM-01-0123
+C2018-EM-01-0082
+A2019-NX-01-1156
+A2019-NX-01-0932
+A2019-NX-01-0833
+C2019-EM-01-0193
+C2019-EM-01-0102
+C2018-EM-01-0073
+B2016-EM-01-0108
+A2016-EM-01-0299
+B2013-EM-01-0064
+A2016-EM-01-0422
+C2020-EM-01-0182
+A2018-EM-01-0932
+A2019-NX-01-0705
+A2019-NX-01-1090
+B2018-EM-01-0055
+C2020-EM-01-0121
+D2020-NX-01-0035
+D2019-NX-01-0013
+A2019-NX-01-1369
+A2015-EM-01-0169
+D2020-NX-01-0007
+C2018-EM-01-0065
+D2020-NX-01-0263
+A2020-NX-01-0287
+A2019-EM-01-0131
+A2019-NX-01-0857
+A2017-EM-01-0543
+A2019-NX-01-0970
+A2015-EM-01-0103
+A2019-NX-01-0639
+D2020-NX-01-0002
+C2020-EM-01-0313
+B2016-EM-01-0051
+A2019-NX-01-0262
+A2019-NX-01-0893
+A2019-NX-01-1121
+A2019-NX-01-0847
+A2020-NX-01-0437
+A2018-EM-01-0018
+B2018-EM-01-0023
+A2020-NX-01-0347
+A2018-NX-01-0277
+A2015-EM-01-0022
+D2020-NX-01-0284
+A2017-EM-01-0334
+C2019-EM-01-0124
+A2015-EM-01-0039
+A2019-NX-01-1232
+C2020-EM-01-0026
+A2018-EM-01-0655
+A2020-NX-01-0422
+D2020-NX-01-0003
+A2016-EM-01-0058
+A2018-NX-01-0163
+A2019-EM-01-0004
+A2015-EM-01-0431
+B2015-EM-01-0028
+B2013-EM-01-0097
+A2019-NX-01-0111
+B2017-EM-01-0044
+C2018-EM-01-0238
+A2019-NX-01-0828
+A2018-EM-01-0351
+A2019-NX-01-1472
+A2019-EM-01-0153
+A2019-EM-01-0052
+D2020-NX-01-0281
+D2019-NX-01-0055
+D2019-NX-01-0113
+B2018-EM-01-0162
+A2020-NX-01-0486
+A2015-EM-01-0342
+A2020-NX-01-0510
+A2019-NX-01-0972
+A2019-NX-01-0021
+A2015-EM-01-0214
+A2019-NX-01-0333
+A2015-EM-01-0011
+A2018-EM-01-0360
+A2019-NX-01-1546
+A2018-NX-01-0356
+A2018-EM-01-0851
+A2020-NX-01-0144
+A2018-NX-01-0109
+A2019-NX-01-0309
+D2020-NX-01-0261
+B2015-EM-01-0037
+D2020-NX-01-0178
+A2016-EM-01-0079
+A2020-NX-01-0223
+A2020-NX-01-0205
+A2017-EM-01-0031
+A2019-NX-01-1313
+A2015-EM-01-0174
+A2018-EM-01-0616
+A2018-EM-01-0298
+D2019-NX-01-0089
+B2018-EM-01-0128
+C2020-EM-01-0048
+C2018-EM-01-0290
+A2018-NX-01-0057
+C2019-EM-01-0149
+A2018-EM-01-0118
+C2018-EM-01-0331
+C2019-EM-01-0213
+B2019-NX-01-0042
+C2020-EM-01-0110
+A2018-EM-01-0323
+A2017-EM-01-0296
+A2016-EM-01-0343
+A2019-NX-01-0573
+A2015-EM-01-0003
+A2018-EM-01-0860
+A2016-EM-01-0239
+D2019-NX-01-0064
+A2018-NX-01-0290
+A2018-NX-01-0288
+A2017-EM-01-0392
+C2018-EM-01-0359
+A2020-NX-01-0760
+A2020-NX-01-0386
+A2018-NX-01-0087
+A2019-NX-01-0055
+A2020-NX-01-0296
+B2015-EM-01-0056
+A2018-EM-01-0361
+A2018-NX-01-0149
+A2016-EM-01-0371
+A2018-NX-01-0071
+D2019-NX-01-0002
+A2018-NX-01-0400
+A2018-NX-01-0220
+A2019-NX-01-1465
+A2019-EM-01-0011
+A2016-EM-01-0260
+A2019-NX-01-0619
+A2015-EM-01-0156
+A2018-EM-01-0235
+C2020-EM-01-0261
+C2018-EM-01-0258
+A2020-NX-01-0234
+A2020-NX-01-0095
+C2020-EM-01-0185
+C2020-EM-01-0004
+A2018-EM-01-0951
+D2019-NX-01-0267
+D2019-NX-01-0240
+A2019-NX-01-0643
+A2017-EM-01-0286
+A2020-NX-01-0409
+A2018-NX-01-0451
+D2020-NX-01-0068
+A2018-EM-01-0542
+A2018-EM-01-0021
+A2017-EM-01-0065
+A2016-EM-01-0253
+A2018-NX-01-0106
+A2019-EM-01-0256
+A2019-NX-01-0056
+A2018-NX-01-0096
+A2017-EM-01-0129
+B2019-NX-01-0075
+A2018-EM-01-0983
+A2019-NX-01-1648
+A2019-NX-01-1576
+C2020-EM-01-0054
+A2019-NX-01-0136
+A2019-NX-01-0074
+A2018-NX-01-0413
+A2018-EM-01-0186
+A2017-EM-01-0531
+A2020-NX-01-0634
+B2019-NX-01-0010
+B2017-EM-01-0103
+C2018-EM-01-0007
+A2018-EM-01-0980
+A2018-EM-01-0859
+A2018-EM-01-0503
+A2019-NX-01-0565
+A2018-NX-01-0454
+A2018-EM-01-0929
+A2019-NX-01-1404
+B2016-EM-01-0077
+A2018-EM-01-0162
+D2019-NX-01-0243
+A2017-EM-01-0435
+A2019-EM-01-0176
+A2020-NX-01-0581
+A2015-EM-01-0152
+A2016-EM-01-0124
+C2020-EM-01-0010
+A2015-EM-01-0204
+A2015-EM-01-0407
+C2018-EM-01-0344
+A2015-EM-01-0306
+A2019-NX-01-0401
+B2016-EM-01-0026
+A2019-NX-01-1168
+A2020-NX-01-0276
+B2017-EM-01-0079
+A2017-EM-01-0283
+A2016-EM-01-0175
+A2020-NX-01-0603
+A2019-NX-01-0696
+B2014-EM-01-0023
+A2018-EM-01-0920
+A2017-EM-01-0033
+D2020-NX-01-0147
+A2019-NX-01-1669
+A2015-EM-01-0166
+A2019-NX-01-1070
+A2016-EM-01-0047
+A2020-NX-01-0615
+A2019-NX-01-1339
+A2019-NX-01-0191
+A2019-NX-01-0762
+C2018-EM-01-0165
+B2019-NX-01-0037
+A2019-NX-01-0968
+A2018-EM-01-0367
+A2018-NX-01-0278
+D2019-NX-01-0172
+D2019-NX-01-0036
+A2017-EM-01-0204
+A2019-NX-01-0226
+A2020-NX-01-0244
+A2019-NX-01-0921
+A2019-EM-01-0288
+A2018-EM-01-0545
+A2018-NX-01-0103
+A2019-NX-01-0928
+A2020-NX-01-0210
+A2015-EM-01-0196
+C2018-EM-01-0110
+A2015-EM-01-0002
+A2015-EM-01-0307
+A2015-EM-01-0167
+A2019-NX-01-0440
+A2020-NX-01-0709
+A2018-EM-01-0033
+A2020-NX-01-0081
+A2017-EM-01-0100
+A2019-NX-01-0739
+A2019-NX-01-1440
+A2018-EM-01-0369
+C2020-EM-01-0076
+A2018-NX-01-0245
+C2019-EM-01-0195
+A2019-NX-01-0640
+B2015-EM-01-0141
+A2018-EM-01-0563
+A2018-EM-01-0826
+A2019-NX-01-1456
+A2016-EM-01-0373
+A2020-NX-01-0712
+A2018-NX-01-0408
+A2019-NX-01-1597
+A2020-NX-01-0341
+A2019-EM-01-0126
+A2015-EM-01-0297
+A2019-NX-01-0829
+A2018-EM-01-1004
\ No newline at end of file
diff --git a/data/kiss_meta_data/3_test_patients.txt b/data/kiss_meta_data/3_test_patients.txt
new file mode 100644
index 0000000000000000000000000000000000000000..fc6a2835e8627c7bb5de0b253b62ec3ceb40a43a
--- /dev/null
+++ b/data/kiss_meta_data/3_test_patients.txt
@@ -0,0 +1,775 @@
+B2014-EM-01-0002
+D2019-NX-01-0146
+B2019-NX-01-0065
+A2019-NX-01-0715
+D2019-NX-01-0250
+A2020-NX-01-0530
+D2019-NX-01-0021
+A2018-EM-01-0828
+A2020-EM-01-0016
+A2017-EM-01-0494
+A2017-EM-01-0050
+A2020-NX-01-0666
+A2019-NX-01-0081
+C2018-EM-01-0095
+A2020-NX-01-0304
+B2019-NX-01-0012
+A2018-EM-01-0534
+A2019-NX-01-0417
+A2018-EM-01-0088
+A2019-NX-01-0753
+A2015-EM-01-0396
+A2016-EM-01-0161
+A2018-NX-01-0174
+A2018-NX-01-0151
+A2018-NX-01-0228
+A2016-EM-01-0134
+C2019-EM-01-0055
+A2019-NX-01-0459
+A2018-EM-01-0435
+A2016-EM-01-0294
+A2019-NX-01-0236
+A2018-NX-01-0173
+A2018-EM-01-0529
+A2018-EM-01-0239
+C2020-EM-01-0061
+A2017-EM-01-0045
+A2016-EM-01-0203
+A2018-NX-01-0305
+A2020-NX-01-0457
+A2016-EM-01-0420
+A2019-NX-01-0169
+A2018-EM-01-0965
+B2017-EM-01-0045
+B2019-EM-01-0041
+A2018-EM-01-0135
+A2019-NX-01-0937
+A2020-NX-01-0123
+C2019-EM-01-0050
+A2017-EM-01-0530
+A2016-EM-01-0184
+C2019-EM-01-0196
+A2015-EM-01-0178
+A2017-EM-01-0479
+A2019-EM-01-0181
+A2018-EM-01-0978
+A2018-NX-01-0444
+C2018-EM-01-0351
+A2018-NX-01-0259
+A2019-NX-01-0003
+A2017-EM-01-0143
+A2018-EM-01-0537
+B2017-EM-01-0023
+A2019-NX-01-1552
+A2017-EM-01-0475
+D2020-NX-01-0092
+C2019-EM-01-0034
+C2019-EM-01-0292
+A2019-NX-01-0448
+A2018-NX-01-0359
+B2015-EM-01-0139
+B2016-EM-01-0054
+A2019-NX-01-1593
+A2018-EM-01-0927
+C2019-EM-01-0187
+A2015-EM-01-0192
+A2018-EM-01-0742
+A2019-NX-01-1282
+A2019-NX-01-0094
+B2019-NX-01-0059
+A2019-NX-01-1449
+A2018-NX-01-0283
+C2020-EM-01-0162
+A2018-EM-01-0953
+A2018-NX-01-0455
+A2020-EM-01-0027
+A2019-NX-01-1046
+A2019-NX-01-0837
+A2019-NX-01-0247
+A2019-NX-01-0050
+A2018-NX-01-0285
+A2018-NX-01-0416
+C2019-EM-01-0352
+A2018-EM-01-0226
+C2018-EM-01-0299
+D2020-NX-01-0041
+A2016-EM-01-0312
+A2018-EM-01-0497
+C2020-EM-01-0207
+A2019-NX-01-0900
+B2017-EM-01-0086
+A2018-NX-01-0272
+A2016-EM-01-0388
+D2020-NX-01-0173
+A2019-NX-01-0441
+A2015-EM-01-0235
+A2018-EM-01-0647
+A2015-EM-01-0452
+D2019-NX-01-0140
+A2018-NX-01-0202
+D2020-NX-01-0126
+B2019-EM-01-0038
+A2019-NX-01-1082
+A2018-NX-01-0258
+C2020-EM-01-0286
+A2019-NX-01-0181
+A2015-EM-01-0004
+D2019-NX-01-0148
+A2019-NX-01-0637
+A2019-NX-01-1605
+C2019-EM-01-0350
+A2018-NX-01-0295
+A2020-NX-01-0566
+D2019-NX-01-0082
+A2019-EM-01-0119
+A2015-EM-01-0376
+A2019-NX-01-0146
+A2019-NX-01-0175
+A2019-NX-01-1659
+A2018-EM-01-0159
+D2019-NX-01-0040
+A2019-NX-01-0768
+A2020-NX-01-0507
+D2020-NX-01-0086
+A2018-NX-01-0438
+A2016-EM-01-0282
+A2020-NX-01-0063
+A2016-EM-01-0080
+C2019-EM-01-0289
+A2019-EM-01-0219
+C2019-EM-01-0347
+A2018-EM-01-0513
+B2013-EM-01-0044
+B2017-EM-01-0017
+A2019-EM-01-0241
+A2017-EM-01-0028
+A2020-NX-01-0327
+A2017-EM-01-0275
+A2019-NX-01-0648
+C2018-EM-01-0126
+A2019-NX-01-0580
+C2018-EM-01-0035
+B2019-NX-01-0077
+A2019-EM-01-0101
+C2019-EM-01-0061
+A2019-NX-01-1402
+A2018-EM-01-0085
+A2019-NX-01-0819
+A2019-EM-01-0013
+A2018-NX-01-0136
+C2019-EM-01-0065
+B2013-EM-01-0007
+A2018-EM-01-0875
+A2019-EM-01-0151
+A2019-NX-01-0952
+A2020-NX-01-0221
+C2018-EM-01-0069
+A2020-NX-01-0589
+A2020-NX-01-0270
+A2020-NX-01-0227
+B2016-EM-01-0022
+A2018-EM-01-0320
+D2019-NX-01-0220
+B2014-EM-01-0025
+A2019-EM-01-0054
+A2019-NX-01-0909
+A2019-NX-01-0706
+A2017-EM-01-0474
+A2017-EM-01-0135
+A2017-EM-01-0398
+A2018-NX-01-0254
+C2020-EM-01-0019
+D2020-NX-01-0096
+B2014-EM-01-0058
+A2018-EM-01-0871
+A2018-EM-01-0266
+A2015-EM-01-0433
+A2019-EM-01-0138
+A2019-NX-01-0153
+D2020-NX-01-0036
+A2020-NX-01-0373
+A2019-NX-01-0328
+A2018-EM-01-0478
+A2020-NX-01-0604
+D2020-NX-01-0127
+A2017-EM-01-0173
+A2020-NX-01-0689
+A2020-NX-01-0436
+C2019-EM-01-0105
+A2018-EM-01-0031
+A2019-NX-01-1148
+B2018-EM-01-0016
+A2020-NX-01-0500
+A2018-NX-01-0176
+A2019-NX-01-0267
+C2018-EM-01-0270
+C2020-EM-01-0257
+A2017-EM-01-0516
+A2019-NX-01-0438
+C2020-EM-01-0133
+A2019-EM-01-0019
+A2019-NX-01-0933
+A2019-NX-01-1116
+C2018-EM-01-0123
+A2018-EM-01-0706
+A2020-NX-01-0326
+A2018-NX-01-0044
+A2019-NX-01-0954
+A2019-EM-01-0206
+A2018-EM-01-0177
+A2018-NX-01-0308
+D2019-NX-01-0092
+A2019-EM-01-0249
+A2017-EM-01-0056
+A2020-NX-01-0156
+A2019-NX-01-1617
+A2018-EM-01-0461
+C2020-EM-01-0027
+B2018-EM-01-0171
+C2019-EM-01-0181
+A2018-EM-01-0270
+C2018-EM-01-0094
+A2018-NX-01-0289
+B2015-EM-01-0107
+A2019-EM-01-0073
+A2020-NX-01-0704
+B2019-NX-01-0076
+A2015-EM-01-0435
+A2019-NX-01-1295
+C2020-EM-01-0352
+D2020-NX-01-0237
+A2020-NX-01-0713
+C2019-EM-01-0122
+C2020-EM-01-0046
+A2018-EM-01-0852
+A2019-NX-01-1145
+A2015-EM-01-0355
+A2018-EM-01-0959
+B2015-EM-01-0002
+A2020-NX-01-0583
+A2019-NX-01-1471
+A2018-NX-01-0411
+A2019-NX-01-0557
+D2020-NX-01-0075
+A2015-EM-01-0042
+A2018-EM-01-0312
+C2019-EM-01-0033
+A2020-NX-01-0107
+A2019-EM-01-0276
+A2020-NX-01-0032
+C2018-EM-01-0343
+A2020-NX-01-0597
+A2018-NX-01-0020
+A2019-NX-01-0009
+A2018-EM-01-0681
+A2018-EM-01-0332
+A2017-EM-01-0131
+A2018-NX-01-0405
+C2020-EM-01-0298
+D2020-NX-01-0253
+A2019-EM-01-0263
+A2019-EM-01-0192
+A2017-EM-01-0355
+A2019-NX-01-0779
+A2015-EM-01-0091
+A2019-NX-01-0598
+A2020-NX-01-0200
+B2014-EM-01-0063
+A2019-NX-01-0665
+A2019-NX-01-1527
+A2020-NX-01-0740
+A2019-NX-01-0334
+D2019-NX-01-0227
+B2016-EM-01-0100
+C2020-EM-01-0239
+A2018-EM-01-0644
+A2019-NX-01-1560
+A2016-EM-01-0146
+A2019-NX-01-1252
+A2020-NX-01-0371
+A2018-NX-01-0167
+D2020-NX-01-0013
+B2013-EM-01-0053
+A2017-EM-01-0191
+A2020-NX-01-0037
+B2015-EM-01-0022
+B2019-NX-01-0071
+A2015-EM-01-0099
+A2019-NX-01-0465
+A2015-EM-01-0170
+A2020-EM-01-0023
+A2019-NX-01-1143
+B2018-EM-01-0140
+C2019-EM-01-0186
+A2018-NX-01-0302
+A2019-NX-01-0141
+A2016-EM-01-0208
+A2018-NX-01-0403
+C2020-EM-01-0037
+B2016-EM-01-0050
+A2020-NX-01-0089
+A2019-NX-01-0026
+A2019-NX-01-0095
+A2019-NX-01-0383
+A2017-EM-01-0118
+B2018-EM-01-0087
+A2016-EM-01-0345
+A2019-NX-01-1227
+A2018-NX-01-0232
+A2018-NX-01-0447
+A2019-EM-01-0076
+B2016-EM-01-0101
+A2019-NX-01-0362
+A2018-EM-01-0099
+A2020-NX-01-0671
+B2018-EM-01-0099
+C2019-EM-01-0212
+A2019-NX-01-1355
+A2018-EM-01-0164
+C2018-EM-01-0169
+A2019-NX-01-0442
+A2019-NX-01-1602
+A2019-EM-01-0223
+D2019-NX-01-0063
+A2019-NX-01-1028
+A2016-EM-01-0337
+A2018-NX-01-0112
+D2019-NX-01-0194
+B2014-EM-01-0034
+A2017-EM-01-0110
+A2015-EM-01-0311
+A2016-EM-01-0154
+A2018-EM-01-0598
+C2019-EM-01-0184
+D2019-NX-01-0145
+A2018-EM-01-0363
+C2019-EM-01-0203
+A2017-EM-01-0464
+C2020-EM-01-0293
+A2018-EM-01-0297
+A2019-NX-01-0631
+C2018-EM-01-0106
+A2015-EM-01-0194
+A2018-EM-01-1001
+A2019-NX-01-0387
+A2019-NX-01-0660
+B2013-EM-01-0057
+A2018-EM-01-0432
+A2019-NX-01-0170
+A2018-EM-01-0723
+A2018-EM-01-0319
+A2017-EM-01-0274
+A2019-NX-01-1331
+B2015-EM-01-0118
+A2018-EM-01-0744
+A2019-NX-01-0861
+A2019-NX-01-1482
+A2017-EM-01-0403
+A2017-EM-01-0209
+A2019-NX-01-1655
+A2016-EM-01-0032
+A2020-NX-01-0515
+B2019-EM-01-0015
+A2020-NX-01-0755
+A2016-EM-01-0084
+A2019-NX-01-0843
+A2018-EM-01-0472
+A2019-EM-01-0108
+A2018-EM-01-0609
+A2019-EM-01-0230
+A2018-EM-01-0433
+A2019-NX-01-0393
+A2019-NX-01-0571
+A2019-NX-01-1058
+A2017-EM-01-0160
+A2018-NX-01-0233
+C2018-EM-01-0213
+A2020-NX-01-0288
+C2018-EM-01-0216
+A2020-NX-01-0447
+A2018-EM-01-0894
+A2018-EM-01-0809
+C2018-EM-01-0015
+A2015-EM-01-0365
+B2016-EM-01-0053
+A2016-EM-01-0104
+A2019-NX-01-0406
+D2020-NX-01-0104
+C2018-EM-01-0210
+A2019-NX-01-1362
+A2020-NX-01-0035
+A2018-NX-01-0372
+C2018-EM-01-0089
+A2019-NX-01-1439
+A2019-NX-01-0184
+A2019-NX-01-1460
+A2018-EM-01-0295
+A2019-NX-01-0185
+A2019-NX-01-0804
+A2020-NX-01-0551
+A2019-NX-01-1002
+A2019-NX-01-1136
+A2018-EM-01-0705
+C2019-EM-01-0046
+A2019-NX-01-1390
+A2019-NX-01-1275
+A2019-EM-01-0179
+B2014-EM-01-0039
+A2018-EM-01-0977
+B2018-EM-01-0100
+B2019-EM-01-0037
+A2019-NX-01-0552
+D2020-NX-01-0282
+A2020-NX-01-0482
+A2018-EM-01-0777
+B2018-EM-01-0079
+A2016-EM-01-0141
+A2019-NX-01-0145
+B2014-EM-01-0057
+A2019-EM-01-0222
+A2019-NX-01-1580
+B2018-EM-01-0035
+A2019-EM-01-0042
+A2019-NX-01-0346
+C2020-EM-01-0179
+C2018-EM-01-0127
+D2019-NX-01-0065
+A2020-EM-01-0085
+A2018-EM-01-0396
+C2018-EM-01-0182
+A2018-EM-01-0818
+C2019-EM-01-0216
+B2019-NX-01-0030
+A2018-EM-01-0126
+B2014-EM-01-0045
+A2018-NX-01-0452
+C2019-EM-01-0215
+A2015-EM-01-0195
+A2020-NX-01-0576
+A2019-NX-01-0935
+C2020-EM-01-0223
+A2020-NX-01-0724
+B2019-NX-01-0082
+A2018-EM-01-0703
+A2018-NX-01-0440
+C2018-EM-01-0186
+A2019-NX-01-0214
+A2018-EM-01-0141
+C2018-EM-01-0362
+A2018-NX-01-0347
+A2017-EM-01-0097
+A2017-EM-01-0009
+A2020-NX-01-0215
+A2019-NX-01-1411
+A2019-NX-01-1137
+A2018-EM-01-0519
+A2017-EM-01-0314
+A2017-EM-01-0181
+C2019-EM-01-0024
+A2015-EM-01-0287
+B2019-EM-01-0009
+C2019-EM-01-0035
+A2018-EM-01-0337
+A2019-NX-01-1215
+A2018-EM-01-0780
+D2020-NX-01-0222
+A2015-EM-01-0226
+A2018-EM-01-0443
+A2019-NX-01-0951
+C2019-EM-01-0279
+A2018-NX-01-0262
+A2019-EM-01-0279
+C2019-EM-01-0373
+B2017-EM-01-0053
+A2019-NX-01-0132
+A2020-NX-01-0181
+A2019-NX-01-1320
+A2018-EM-01-0690
+A2019-NX-01-0543
+A2019-NX-01-0585
+A2019-NX-01-1631
+D2020-NX-01-0032
+A2015-EM-01-0049
+A2019-NX-01-0835
+A2019-NX-01-1003
+A2018-NX-01-0337
+B2016-EM-01-0062
+A2020-EM-01-0079
+A2018-EM-01-0108
+C2020-EM-01-0189
+B2018-EM-01-0145
+A2018-EM-01-0650
+B2014-EM-01-0060
+A2015-EM-01-0222
+A2019-NX-01-0254
+C2018-EM-01-0312
+A2017-EM-01-0013
+A2019-NX-01-0690
+B2017-EM-01-0092
+A2018-NX-01-0436
+A2018-NX-01-0446
+C2019-EM-01-0097
+A2015-EM-01-0026
+C2020-EM-01-0291
+A2017-EM-01-0014
+B2013-EM-01-0016
+A2018-EM-01-0017
+C2020-EM-01-0068
+A2019-NX-01-1481
+C2018-EM-01-0045
+A2017-EM-01-0546
+A2015-EM-01-0078
+C2020-EM-01-0333
+A2019-NX-01-1334
+A2020-NX-01-0558
+A2019-NX-01-1503
+C2020-EM-01-0221
+C2020-EM-01-0267
+B2016-EM-01-0070
+C2020-EM-01-0288
+A2018-EM-01-0528
+A2017-EM-01-0165
+C2020-EM-01-0322
+A2018-NX-01-0206
+A2017-EM-01-0007
+A2018-EM-01-0680
+A2018-EM-01-0331
+C2018-EM-01-0357
+C2020-EM-01-0258
+C2020-EM-01-0215
+A2019-NX-01-0586
+A2015-EM-01-0303
+D2020-NX-01-0176
+A2020-NX-01-0792
+C2019-EM-01-0177
+B2013-EM-01-0029
+A2018-NX-01-0083
+A2018-EM-01-0150
+A2019-NX-01-0495
+A2017-EM-01-0352
+A2015-EM-01-0110
+A2017-EM-01-0389
+A2019-NX-01-1349
+A2019-NX-01-1364
+A2019-NX-01-0787
+B2013-EM-01-0067
+A2020-NX-01-0366
+C2018-EM-01-0047
+A2017-EM-01-0030
+B2019-NX-01-0009
+A2019-NX-01-1236
+A2019-NX-01-1196
+A2019-NX-01-0482
+A2017-EM-01-0254
+A2020-NX-01-0487
+A2020-NX-01-0588
+C2018-EM-01-0071
+C2018-EM-01-0056
+D2020-NX-01-0162
+A2020-NX-01-0681
+A2018-NX-01-0428
+A2018-EM-01-0914
+A2017-EM-01-0426
+A2016-EM-01-0042
+A2015-EM-01-0451
+B2015-EM-01-0077
+D2019-NX-01-0231
+A2016-EM-01-0010
+C2019-EM-01-0045
+C2020-EM-01-0081
+C2019-EM-01-0302
+A2018-EM-01-0618
+A2015-EM-01-0241
+A2018-EM-01-0044
+A2020-NX-01-0438
+A2019-EM-01-0160
+A2019-NX-01-0062
+A2018-EM-01-0649
+C2018-EM-01-0261
+C2020-EM-01-0300
+A2019-NX-01-1159
+A2019-NX-01-1363
+A2015-EM-01-0228
+A2019-NX-01-0134
+A2019-NX-01-0271
+D2020-NX-01-0049
+A2017-EM-01-0214
+A2020-NX-01-0650
+A2018-EM-01-0794
+A2020-NX-01-0762
+A2016-EM-01-0182
+A2017-EM-01-0408
+A2018-EM-01-0605
+A2018-EM-01-0290
+A2018-EM-01-0093
+C2018-EM-01-0308
+A2018-EM-01-0797
+A2020-NX-01-0202
+A2018-EM-01-0642
+A2015-EM-01-0315
+A2018-EM-01-0087
+A2018-NX-01-0091
+A2018-EM-01-0940
+A2015-EM-01-0254
+A2016-EM-01-0339
+A2020-NX-01-0243
+A2019-NX-01-1291
+A2019-NX-01-0695
+A2019-NX-01-0629
+A2019-NX-01-1524
+A2018-EM-01-0661
+A2019-NX-01-1428
+A2018-NX-01-0164
+A2018-EM-01-0765
+A2015-EM-01-0263
+A2019-EM-01-0105
+B2018-EM-01-0119
+C2020-EM-01-0232
+C2019-EM-01-0092
+A2020-NX-01-0184
+B2014-EM-01-0112
+A2019-NX-01-1290
+A2019-NX-01-1280
+A2019-NX-01-1059
+A2019-NX-01-0155
+A2020-NX-01-0770
+A2019-NX-01-0343
+A2019-NX-01-0425
+A2018-EM-01-0301
+A2019-EM-01-0164
+C2020-EM-01-0044
+C2020-EM-01-0184
+C2018-EM-01-0009
+A2018-NX-01-0123
+D2020-NX-01-0167
+A2018-EM-01-0064
+A2016-EM-01-0043
+A2020-NX-01-0068
+C2018-EM-01-0107
+A2016-EM-01-0060
+A2018-EM-01-0550
+A2016-EM-01-0027
+A2020-NX-01-0158
+B2018-EM-01-0073
+A2018-NX-01-0201
+A2017-EM-01-0016
+A2018-NX-01-0257
+A2018-NX-01-0299
+D2019-NX-01-0266
+A2018-EM-01-0317
+D2020-NX-01-0231
+A2017-EM-01-0151
+A2018-EM-01-0675
+A2019-EM-01-0020
+A2018-NX-01-0082
+A2020-NX-01-0219
+A2019-NX-01-0601
+A2019-EM-01-0147
+A2020-NX-01-0121
+A2019-NX-01-1219
+C2020-EM-01-0055
+D2020-NX-01-0113
+A2019-NX-01-0022
+A2018-EM-01-0736
+D2020-NX-01-0216
+A2018-EM-01-0250
+A2020-NX-01-0051
+A2020-NX-01-0660
+A2017-EM-01-0434
+A2019-NX-01-1553
+A2018-EM-01-1010
+A2020-NX-01-0444
+A2019-NX-01-1545
+D2019-NX-01-0185
+A2019-EM-01-0128
+A2020-NX-01-0305
+B2018-EM-01-0070
+A2019-EM-01-0085
+A2017-EM-01-0432
+A2019-NX-01-0769
+A2019-NX-01-1405
+D2019-NX-01-0216
+D2020-NX-01-0055
+A2019-NX-01-1016
+B2016-EM-01-0123
+A2018-EM-01-0309
+C2019-EM-01-0107
+A2020-NX-01-0777
+C2019-EM-01-0121
+A2019-NX-01-0108
+A2019-NX-01-1308
+A2017-EM-01-0320
+A2018-EM-01-0561
+A2017-EM-01-0176
+D2020-NX-01-0067
+A2019-EM-01-0268
+A2016-EM-01-0346
+C2018-EM-01-0212
+A2019-EM-01-0270
+A2015-EM-01-0284
+C2019-EM-01-0076
+D2019-NX-01-0173
+D2019-NX-01-0033
+A2017-EM-01-0533
+A2018-NX-01-0022
+A2015-EM-01-0393
+A2020-NX-01-0620
+A2018-EM-01-0803
+A2020-NX-01-0017
+A2017-EM-01-0448
+A2019-NX-01-0773
+A2019-NX-01-1238
+A2019-NX-01-1498
+B2018-EM-01-0086
+A2018-NX-01-0431
+A2019-NX-01-0678
+A2016-EM-01-0204
+C2018-EM-01-0024
+A2019-NX-01-1501
+A2019-EM-01-0053
+D2019-NX-01-0116
+A2017-EM-01-0294
+A2020-NX-01-0228
+A2019-NX-01-0186
+A2018-NX-01-0266
+C2019-EM-01-0118
+A2018-EM-01-0199
+A2017-EM-01-0130
+A2018-EM-01-0687
+A2018-EM-01-0559
+D2020-NX-01-0040
+A2020-NX-01-0533
+B2017-EM-01-0087
+A2017-EM-01-0161
+A2018-NX-01-0376
+A2015-EM-01-0367
+A2019-NX-01-1273
+D2020-NX-01-0047
+A2018-NX-01-0095
+A2019-EM-01-0093
+A2019-NX-01-1414
+A2018-EM-01-0408
+A2019-NX-01-1049
+A2018-EM-01-0724
+A2015-EM-01-0131
+C2019-EM-01-0056
+A2019-NX-01-1388
+A2019-NX-01-1040
+A2019-NX-01-1549
+A2018-NX-01-0039
+D2020-NX-01-0042
+A2019-NX-01-0792
+C2019-EM-01-0063
+A2018-EM-01-0587
+A2020-NX-01-0365
+A2016-EM-01-0098
+A2015-EM-01-0337
+D2020-NX-01-0283
+D2020-NX-01-0234
+C2020-EM-01-0165
+A2020-NX-01-0748
+A2019-NX-01-0149
+A2020-NX-01-0179
+A2015-EM-01-0062
+A2019-NX-01-0652
+A2018-EM-01-0381
\ No newline at end of file
diff --git a/data/kiss_preprocess.py b/data/kiss_preprocess.py
new file mode 100644
index 0000000000000000000000000000000000000000..435bd0acd29894d80bed6f6d310ef6a8875f5c0b
--- /dev/null
+++ b/data/kiss_preprocess.py
@@ -0,0 +1,392 @@
+import os
+import shutil
+import numpy as np
+import pandas as pd
+
+from scipy.signal import iirnotch, lfilter
+from data_utils import butter_bandpass_filter, correct_ecg_inversion
+
+import matplotlib.pyplot as plt
+from tqdm import tqdm
+import shutil
+import librosa
+import pickle
+import gc
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+SAMPLING_RATE = 200
+TARGET_RESAMPLE = 100
+NOTCH_FREQ = 60
+EEG_LOWCUT = 0.3
+EEG_HIGHCUT = 40
+EMG_LOWCUT = 10
+EMG_HIGHCUT = 1000
+ECG_LOWCUT = 0.3
+ECG_HIGHCUT = 70
+FLOW_LOWCUT = 0
+FLOW_HIGHCUT = 15
+
+do_resample = (SAMPLING_RATE != TARGET_RESAMPLE)
+
+NUM_PROCESS = 4
+
+import argparse
+import multiprocessing
+
+def process_ecg(args):
+ sig, chn_grp, chn, split = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, ECG_LOWCUT, ECG_HIGHCUT, SAMPLING_RATE)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, SAMPLING_RATE)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ filtered = filtered.reshape(-1, SAMPLING_RATE*30)
+
+ filtered_epochs = []
+
+ for epoch in filtered:
+ inv_epoch, _ = correct_ecg_inversion(epoch, SAMPLING_RATE)
+ filtered_epochs.append(inv_epoch)
+
+ filtered = np.stack(filtered_epochs, axis=0)
+
+ if do_resample:
+ filtered = np.reshape(filtered, (-1,1))
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+
+def process_eeg(args):
+ sig, chn_grp, chn, split = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EEG_LOWCUT, EEG_HIGHCUT, SAMPLING_RATE)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, SAMPLING_RATE)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ if do_resample:
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_emg(args):
+ sig, chn_grp, chn, split = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EMG_LOWCUT, EMG_HIGHCUT, SAMPLING_RATE)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, SAMPLING_RATE)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ if do_resample:
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_flow(args):
+ sig, chn_grp, chn, split = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, FLOW_LOWCUT, FLOW_HIGHCUT, SAMPLING_RATE)
+
+ # median filter?
+
+ if do_resample:
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def save_mmap(results, sig_list, chn_grp, chn, split='train'):
+ signame_list = [sig.split('.')[0] for sig in sig_list]
+ epoch_lengths = [sig.shape[0] for sig in results]
+ metadata = dict()
+ sig_info = dict()
+ start, end = 0, 0
+ for signame, sig in zip(signame_list, results):
+ length = sig.shape[0]
+ end = start + length
+ info = dict()
+ info['pos'] = (start, end)
+ info['stats'] = {'sum': float(np.sum(sig)), 'sumsq': float(np.sum(sig ** 2))}
+ sig_info[signame] = info
+ start = end
+
+
+ mmap_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ signals_cat = np.concatenate(results, axis=0).astype(np.float32)
+ os.makedirs(os.path.dirname(mmap_path), exist_ok=True)
+ data = np.memmap(mmap_path, dtype=np.float32, mode='w+', shape=signals_cat.shape)
+ data[:] = signals_cat
+ data.flush()
+
+ metadata['sig_info'] = sig_info
+ metadata['data_shape'] = signals_cat.shape
+ info_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ with open(info_path, 'wb') as f:
+ pickle.dump(metadata, f)
+
+ del data
+
+# def get_kiss_lists(save_signals_path, snuh_split_file):
+def get_kiss_lists(snuh_split_file):
+ ids = pd.read_csv(os.path.join("kiss_meta_data", snuh_split_file), header=None, names=['a'])
+ ids = ids['a'].values.tolist()
+ return [id + ".npy" for id in ids]
+ # list_files = [os.path.join(save_signals_path, id + ".npy") for id in ids]
+ # return list_files
+
+def preprocess(sig_list, chn_grp=None, chn=None, split='train'):
+ def _process(sig_list, chn_grp, chn, split):
+
+ print(f"Processing {chn_grp}/{chn}")
+ if chn_grp in ['EEG','EOG']:
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn, split) for sig in sig_list]
+
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_eeg, input_list), total=len(input_list)))
+
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ del results
+
+ elif chn_grp in ['EMG']:
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn, split) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_emg, input_list), total=len(input_list)))
+
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ del results
+
+ elif chn_grp in ['ECG']:
+
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn, split) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_ecg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ del results
+
+ elif chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn, split) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_flow, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ del results
+ else:
+ results = []
+ for sig in tqdm(sig_list):
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ if do_resample or chn == 'SaO2':
+ data = data.reshape(-1, 1)
+ if chn == 'SaO2':
+ data = librosa.resample(data, orig_sr=SAMPLING_RATE, target_sr=1, axis=0, res_type='soxr_qq')
+ data = data / 100
+ if round(np.max(data)) > 1 or round(np.min(data)) < 0:
+ print(f"Warning: SaO2 values out of range: {sig} with min {np.min(data)} and max {np.max(data)}")
+ data = data.reshape(-1, 1*30)
+ else:
+ data = librosa.resample(data, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ data = data.reshape(-1, TARGET_RESAMPLE*30)
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # shutil.copy(sig_path, output_path)
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, data)
+ elif cfg.save_type == 'mmap':
+ results.append(data)
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ del results
+ gc.collect()
+
+
+ if chn_grp is not None and chn is not None:
+ _process(sig_list, chn_grp, chn, split)
+ return
+ else:
+ for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ continue
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)):
+ continue
+ _process(sig_list, chn_grp, chn, split)
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default='kiss/signals_MAE', help='Physionet 2018 raw data location')
+parser.add_argument('--output_dir', default='kiss/mmap_signals_MAE_processed', help='Physionet 2018 processed data location')
+parser.add_argument('--save_type', default='mmap', help='Which data type to save. "npy" or "mmap"')
+parser.add_argument('--chn_grp', default=None, help='If specified, only preprocess this channel group')
+parser.add_argument('--chn', default=None, help='If specified, only preprocess this channel')
+parser.add_argument('--kvss', action='store_true', help='KVSS preprocessing?')
+parser.add_argument('--ann_split', action='store_true', help='To split annotation files into train/val/test')
+
+cfg = parser.parse_args()
+
+
+if __name__ == "__main__":
+
+ if not cfg.kvss:
+ list_files_train = sorted(get_kiss_lists("1_train_patients.txt"))
+ list_files_val = sorted(get_kiss_lists("2_valid_patients.txt"))
+ list_files_test = sorted(get_kiss_lists("3_test_patients.txt"))
+
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, "EEG", "C3-A2")))
+
+ for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ # Skip any files that are not directories
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ continue
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ # Skip any files that are not directories
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)):
+ continue
+ sig_list_chn = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ print(f"Number of records in {chn_grp}/{chn}:", len(sig_list_chn))
+ sig_list = list(set(sig_list).intersection(set(sig_list_chn)))
+
+ print(f"Number of records that exist in all chns:", len(sig_list)) # Total 7698 -> 7579 records
+
+ list_files_train = list(set(list_files_train).intersection(set(sig_list)))
+ list_files_val = list(set(list_files_val).intersection(set(sig_list)))
+ list_files_test = list(set(list_files_test).intersection(set(sig_list)))
+
+ print("Number of records in training set:", len(list_files_train)) # Total 6161 -> 6064 records
+ print("Number of records in validation set:", len(list_files_val)) # Total 765 -> 748 records
+ print("Number of records in test set:", len(list_files_test)) # Total 772 -> 767 records
+ else:
+ # For KVSS, use all data for preprocessing
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, "EEG", "C3-A2")))
+
+ for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ # Skip any files that are not directories
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ continue
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ # Skip any files that are not directories
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)):
+ continue
+ sig_list_chn = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ print(f"Number of records in {chn_grp}/{chn}:", len(sig_list_chn))
+ sig_list = list(set(sig_list).intersection(set(sig_list_chn)))
+
+ print(f"Number of records that exist in all chns:", len(sig_list))
+ list_files_train = sig_list
+ list_files_val = []
+ list_files_test = []
+
+
+ print("Processing training set...")
+ preprocess(list_files_train, cfg.chn_grp, cfg.chn, split='train')
+ print("Processing evaluation set...")
+ preprocess(list_files_val, cfg.chn_grp, cfg.chn, split='val')
+ print("Processing test set...")
+ preprocess(list_files_test, cfg.chn_grp, cfg.chn, split='test')
+
+ if cfg.ann_split and not cfg.kvss:
+ # Reorganize annotations files
+ ANN_PATH = os.path.join(BASE_PATH, 'kiss/annotations')
+ NEW_ANN_PATH = os.path.join(BASE_PATH, 'kiss/annotations_split')
+ os.makedirs(NEW_ANN_PATH, exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'train'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'val'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'test'), exist_ok=True)
+
+ for fname in list_files_train:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'train', ann_fname))
+ for fname in list_files_val:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'val', ann_fname))
+ for fname in list_files_test:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'test', ann_fname))
+
+ AH_PATH = os.path.join(BASE_PATH, 'kiss/ah_labels')
+ NEW_AH_PATH = os.path.join(BASE_PATH, 'kiss/ah_labels_split')
+ os.makedirs(NEW_AH_PATH, exist_ok=True)
+ os.makedirs(os.path.join(NEW_AH_PATH,'train'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_AH_PATH,'val'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_AH_PATH,'test'), exist_ok=True)
+ for fname in list_files_train:
+ ann_fname = fname.replace('.npy', '_ah.npy')
+ shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'train', ann_fname))
+ for fname in list_files_val:
+ ann_fname = fname.replace('.npy', '_ah.npy')
+ shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'val', ann_fname))
+ for fname in list_files_test:
+ ann_fname = fname.replace('.npy', '_ah.npy')
+ shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'test', ann_fname))
+
+ # for split in ['train', 'val', 'test']:
+ # # create link files to respiratory channels
+ # os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP'), exist_ok=True)
+ # for chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ # chns = [f.split('.')[0] for f in os.listdir(os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp))]
+ # for chn in chns:
+ # src_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ # src_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ # dst_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.mmap')
+ # dst_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.pickle')
+ # if not os.path.exists(dst_mmap):
+ # os.symlink(src_mmap, dst_mmap)
+ # if not os.path.exists(dst_pickle):
+ # os.symlink(src_pickle, dst_pickle)
\ No newline at end of file
diff --git a/data/mesa_preprocess_v1.2.py b/data/mesa_preprocess_v1.2.py
new file mode 100644
index 0000000000000000000000000000000000000000..be4fd75c03c80d977dd4112273b5890a658d2e99
--- /dev/null
+++ b/data/mesa_preprocess_v1.2.py
@@ -0,0 +1,380 @@
+import os
+import shutil
+import numpy as np
+import matplotlib.pyplot as plt
+from tqdm import tqdm
+import shutil
+import librosa
+
+from scipy.signal import iirnotch, lfilter
+from data_utils import butter_bandpass_filter, correct_ecg_inversion
+import pickle
+import pandas as pd
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+NOTCH_FREQ = 60
+EEG_LOWCUT = 0.3
+EEG_HIGHCUT = 40
+EMG_LOWCUT = 10
+EMG_HIGHCUT = 1000
+ECG_LOWCUT = 0.3
+ECG_HIGHCUT = 60
+FLOW_LOWCUT = 0
+FLOW_HIGHCUT = 15
+
+
+
+NUM_PROCESS = 4
+
+import argparse
+import multiprocessing
+
+
+
+# SAMPLING_RATE = 250 if cfg.mros2 else 125
+TARGET_RESAMPLE = 100
+
+# do_resample = (SAMPLING_RATE != TARGET_RESAMPLE)
+
+
+
+
+
+def process_ecg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, ECG_LOWCUT, ECG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ filtered = filtered.reshape(-1, sampling_rate*30)
+ # filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered_epochs = []
+
+ for epoch in filtered:
+ inv_epoch, _ = correct_ecg_inversion(epoch, TARGET_RESAMPLE)
+ filtered_epochs.append(inv_epoch)
+
+ filtered = np.stack(filtered_epochs, axis=0)
+
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = np.reshape(filtered, (-1,1))
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+
+def process_eeg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EEG_LOWCUT, EEG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_emg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EMG_LOWCUT, EMG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_flow(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, FLOW_LOWCUT, FLOW_HIGHCUT, sampling_rate)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ # median filter?
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def save_mmap(results, sig_list, chn_grp, chn, split='train'):
+ signame_list = [sig.split('.')[0] for sig in sig_list]
+ epoch_lengths = [sig.shape[0] for sig in results]
+ metadata = dict()
+ sig_info = dict()
+ start, end = 0, 0
+ for signame, sig in zip(signame_list, results):
+ length = sig.shape[0]
+ end = start + length
+ info = dict()
+ info['pos'] = (start, end)
+ info['stats'] = {'sum': float(np.sum(sig)), 'sumsq': float(np.sum(sig ** 2))}
+ sig_info[signame] = info
+ start = end
+
+
+ mmap_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ signals_cat = np.concatenate(results, axis=0).astype(np.float32)
+ os.makedirs(os.path.dirname(mmap_path), exist_ok=True)
+ data = np.memmap(mmap_path, dtype=np.float32, mode='w+', shape=signals_cat.shape)
+ data[:] = signals_cat
+ data.flush()
+
+ metadata['sig_info'] = sig_info
+ metadata['data_shape'] = signals_cat.shape
+ info_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ with open(info_path, 'wb') as f:
+ pickle.dump(metadata, f)
+
+
+def preprocess(sig_list, chn_grp=None, chn=None, split='train'):
+ def _process(sig_list, chn_grp, chn, split):
+ print(f"Processing {chn_grp}/{chn}")
+ # if not (chn == "C4-A1" or chn == "AIRFLOW"): continue
+
+ if chn_grp in ['EEG','EOG']:
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_eeg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['EMG']:
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_emg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['ECG']:
+
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_ecg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_flow, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+
+ else:
+ results = []
+ # for sig in tqdm(sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))):
+ for sig in tqdm(sig_list):
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ if sampling_rate != TARGET_RESAMPLE or chn == 'SpO2':
+ # assuming 30s epochs
+ data = data.reshape(-1, 1)
+ if chn == 'SpO2':
+ data = librosa.resample(data, orig_sr=sampling_rate, target_sr=1, axis=0, res_type='soxr_qq')
+ data = data / 1e8 # data range 0 to 1e8
+ if np.max(data) > 1 or np.min(data) < 0:
+ print(f"Warning: SaO2 values out of range: {sig} with min {np.min(data)} and max {np.max(data)}")
+ data = data.reshape(-1, 1*30)
+ else:
+ data = librosa.resample(data, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ data = data.reshape(-1, TARGET_RESAMPLE*30)
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # shutil.copy(sig_path, output_path)
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, data)
+ elif cfg.save_type == 'mmap':
+ results.append(data)
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ # for sig in tqdm(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))):
+ # sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # # shutil.copy(sig_path, output_path)
+ # data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ # data = librosa.resample(data, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ # data = data.reshape(-1, TARGET_RESAMPLE*30)
+
+ # # Save processed data
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ # np.save(output_path, data)
+
+ if chn_grp is not None and chn is not None:
+ _process(sig_list, chn_grp, chn, split)
+ return
+ else:
+ for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ continue
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)):
+ continue
+ _process(sig_list, chn_grp, chn, split)
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default='#_MESA/signals_MAE', help='mros raw data location')
+parser.add_argument('--output_dir', default='#_MESA/mmap_signals_MAE_processed', help='mros processed data location')
+parser.add_argument('--ann_split', action='store_true', help='To split annotation files into train/val/test')
+parser.add_argument('--save_type', default='mmap', help='Which data type to save. "npy" or "mmap"')
+parser.add_argument('--chn_grp', default=None, help='If specified, only preprocess this channel group')
+parser.add_argument('--chn', default=None, help='If specified, only preprocess this channel')
+parser.add_argument('--mros2', action='store_true')
+
+cfg = parser.parse_args()
+
+if __name__ == '__main__':
+
+ if not cfg.mros2:
+ def get_mros_lists(mros_split_file):
+ ids = pd.read_csv(os.path.join("mesa_meta_data", mros_split_file), header=None)[0].astype(str).tolist()
+ return [x.strip() + ".npy" for x in ids]
+
+ list_files_train = get_mros_lists("1_train_patients.txt")
+ list_files_val = get_mros_lists("2_valid_patients.txt")
+ list_files_test = get_mros_lists("3_test_patients.txt")
+
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, "EEG", "C4-M1")))
+
+ list_files_train = list(set(list_files_train).intersection(set(sig_list)))
+ list_files_val = list(set(list_files_val).intersection(set(sig_list)))
+ list_files_test = list(set(list_files_test).intersection(set(sig_list)))
+
+ print("Number of records in training set:", len(list_files_train))
+ print("Number of records in validation set:", len(list_files_val))
+ print("Number of records in test set:", len(list_files_test))
+ else:
+ # For mros2, use all data for preprocessing
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, "EEG", "C4-M1")))
+
+ # AIRFLOW에 실제로 존재하는 파일만 남기기
+ airflow_dir = os.path.join(BASE_PATH, cfg.data_dir, "AIRFLOW", "AIRFLOW")
+ airflow_files = set(os.listdir(airflow_dir))
+ sig_list = sorted(list(set(sig_list).intersection(airflow_files)))
+
+ list_files_train = sig_list
+ list_files_val = []
+ list_files_test = []
+
+ print("Processing training set...")
+ preprocess(list_files_train, cfg.chn_grp, cfg.chn, split='train')
+ print("Processing evaluation set...")
+ preprocess(list_files_val, cfg.chn_grp, cfg.chn, split='val')
+ print("Processing test set...")
+ preprocess(list_files_test, cfg.chn_grp, cfg.chn, split='test')
+
+
+ # Reorganize annotations files
+ # ANN_PATH = os.path.join(BASE_PATH, 'mros1/annotations')
+ if cfg.ann_split and not cfg.mros2:
+ ANN_PATH = os.path.join(os.path.dirname(os.path.join(BASE_PATH, cfg.data_dir)), 'annotations')
+ NEW_ANN_PATH = ANN_PATH.replace('annotations', 'annotations_split')
+ os.makedirs(NEW_ANN_PATH, exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'train'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'val'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'test'), exist_ok=True)
+
+ for fname in list_files_train:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'train', ann_fname))
+ for fname in list_files_val:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'val', ann_fname))
+ for fname in list_files_test:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'test', ann_fname))
+
+ # AH_PATH = os.path.join(BASE_PATH, 'kiss/ah_labels')
+ # NEW_AH_PATH = os.path.join(BASE_PATH, 'kiss/ah_labels_split')
+ # os.makedirs(NEW_AH_PATH, exist_ok=True)
+ # os.makedirs(os.path.join(NEW_AH_PATH,'train'), exist_ok=True)
+ # os.makedirs(os.path.join(NEW_AH_PATH,'val'), exist_ok=True)
+ # os.makedirs(os.path.join(NEW_AH_PATH,'test'), exist_ok=True)
+ # for fname in list_files_train:
+ # ann_fname = fname.replace('.npy', '_ah.npy')
+ # shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'train', ann_fname))
+ # for fname in list_files_val:
+ # ann_fname = fname.replace('.npy', '_ah.npy')
+ # shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'val', ann_fname))
+ # for fname in list_files_test:
+ # ann_fname = fname.replace('.npy', '_ah.npy')
+ # shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'test', ann_fname))
+
+
+ for split in ['train', 'val', 'test']:
+ # create link files to respiratory channels
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP'), exist_ok=True)
+ for chn_grp in ['ABD', 'AIRFLOW']:
+ chns = [f.split('.')[0] for f in os.listdir(os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp))]
+ for chn in chns:
+ src_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ src_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ dst_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.mmap')
+ dst_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.pickle')
+ if not os.path.exists(dst_mmap):
+ os.symlink(src_mmap, dst_mmap)
+ if not os.path.exists(dst_pickle):
+ os.symlink(src_pickle, dst_pickle)
+
diff --git a/data/mros_preprocess_v1.2.py b/data/mros_preprocess_v1.2.py
new file mode 100644
index 0000000000000000000000000000000000000000..5de830b0e79d30b4534d81c9d10c75d808a510d9
--- /dev/null
+++ b/data/mros_preprocess_v1.2.py
@@ -0,0 +1,380 @@
+import os
+import shutil
+import numpy as np
+import matplotlib.pyplot as plt
+from tqdm import tqdm
+import shutil
+import librosa
+
+from scipy.signal import iirnotch, lfilter
+from data_utils import butter_bandpass_filter, correct_ecg_inversion
+import pickle
+import pandas as pd
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+NOTCH_FREQ = 60
+EEG_LOWCUT = 0.3
+EEG_HIGHCUT = 40
+EMG_LOWCUT = 10
+EMG_HIGHCUT = 1000
+ECG_LOWCUT = 0.3
+ECG_HIGHCUT = 60
+FLOW_LOWCUT = 0
+FLOW_HIGHCUT = 15
+
+
+
+NUM_PROCESS = 4
+
+import argparse
+import multiprocessing
+
+
+
+# SAMPLING_RATE = 250 if cfg.mros2 else 125
+TARGET_RESAMPLE = 100
+
+# do_resample = (SAMPLING_RATE != TARGET_RESAMPLE)
+
+
+
+
+
+def process_ecg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, ECG_LOWCUT, ECG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ filtered = filtered.reshape(-1, sampling_rate*30)
+ # filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered_epochs = []
+
+ for epoch in filtered:
+ inv_epoch, _ = correct_ecg_inversion(epoch, TARGET_RESAMPLE)
+ filtered_epochs.append(inv_epoch)
+
+ filtered = np.stack(filtered_epochs, axis=0)
+
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = np.reshape(filtered, (-1,1))
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+
+def process_eeg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EEG_LOWCUT, EEG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_emg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EMG_LOWCUT, EMG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_flow(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, FLOW_LOWCUT, FLOW_HIGHCUT, sampling_rate)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ # median filter?
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def save_mmap(results, sig_list, chn_grp, chn, split='train'):
+ signame_list = [sig.split('.')[0] for sig in sig_list]
+ epoch_lengths = [sig.shape[0] for sig in results]
+ metadata = dict()
+ sig_info = dict()
+ start, end = 0, 0
+ for signame, sig in zip(signame_list, results):
+ length = sig.shape[0]
+ end = start + length
+ info = dict()
+ info['pos'] = (start, end)
+ info['stats'] = {'sum': float(np.sum(sig)), 'sumsq': float(np.sum(sig ** 2))}
+ sig_info[signame] = info
+ start = end
+
+
+ mmap_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ signals_cat = np.concatenate(results, axis=0).astype(np.float32)
+ os.makedirs(os.path.dirname(mmap_path), exist_ok=True)
+ data = np.memmap(mmap_path, dtype=np.float32, mode='w+', shape=signals_cat.shape)
+ data[:] = signals_cat
+ data.flush()
+
+ metadata['sig_info'] = sig_info
+ metadata['data_shape'] = signals_cat.shape
+ info_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ with open(info_path, 'wb') as f:
+ pickle.dump(metadata, f)
+
+
+def preprocess(sig_list, chn_grp=None, chn=None, split='train'):
+ def _process(sig_list, chn_grp, chn, split):
+ print(f"Processing {chn_grp}/{chn}")
+ # if not (chn == "C4-A1" or chn == "AIRFLOW"): continue
+
+ if chn_grp in ['EEG','EOG']:
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_eeg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['EMG']:
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_emg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['ECG']:
+
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_ecg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_flow, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+
+ else:
+ results = []
+ # for sig in tqdm(sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))):
+ for sig in tqdm(sig_list):
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ if sampling_rate != TARGET_RESAMPLE or chn == 'SaO2':
+ # assuming 30s epochs
+ data = data.reshape(-1, 1)
+ if chn == 'SaO2':
+ data = librosa.resample(data, orig_sr=sampling_rate, target_sr=1, axis=0, res_type='soxr_qq')
+ data = data / 1e8 # data range 0 to 1e8
+ if np.max(data) > 1 or np.min(data) < 0:
+ print(f"Warning: SaO2 values out of range: {sig} with min {np.min(data)} and max {np.max(data)}")
+ data = data.reshape(-1, 1*30)
+ else:
+ data = librosa.resample(data, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ data = data.reshape(-1, TARGET_RESAMPLE*30)
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # shutil.copy(sig_path, output_path)
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, data)
+ elif cfg.save_type == 'mmap':
+ results.append(data)
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ # for sig in tqdm(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))):
+ # sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # # shutil.copy(sig_path, output_path)
+ # data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ # data = librosa.resample(data, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ # data = data.reshape(-1, TARGET_RESAMPLE*30)
+
+ # # Save processed data
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ # np.save(output_path, data)
+
+ if chn_grp is not None and chn is not None:
+ _process(sig_list, chn_grp, chn, split)
+ return
+ else:
+ for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ continue
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)):
+ continue
+ _process(sig_list, chn_grp, chn, split)
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default='#_MrOS1/signals_MAE', help='mros raw data location')
+parser.add_argument('--output_dir', default='#_MrOS1/mmap_signals_MAE_processed', help='mros processed data location')
+parser.add_argument('--ann_split', action='store_true', help='To split annotation files into train/val/test')
+parser.add_argument('--save_type', default='mmap', help='Which data type to save. "npy" or "mmap"')
+parser.add_argument('--chn_grp', default=None, help='If specified, only preprocess this channel group')
+parser.add_argument('--chn', default=None, help='If specified, only preprocess this channel')
+parser.add_argument('--mros2', action='store_true')
+
+cfg = parser.parse_args()
+
+if __name__ == '__main__':
+
+ if not cfg.mros2:
+ def get_mros_lists(mros_split_file):
+ ids = pd.read_csv(os.path.join("mros_meta_data", mros_split_file), header=None)[0].astype(str).tolist()
+ return [x.strip() + ".npy" for x in ids]
+
+ list_files_train = get_mros_lists("1_train_patients.txt")
+ list_files_val = get_mros_lists("2_valid_patients.txt")
+ list_files_test = get_mros_lists("3_test_patients.txt")
+
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, "EEG", "C3-A2")))
+
+ list_files_train = list(set(list_files_train).intersection(set(sig_list)))
+ list_files_val = list(set(list_files_val).intersection(set(sig_list)))
+ list_files_test = list(set(list_files_test).intersection(set(sig_list)))
+
+ print("Number of records in training set:", len(list_files_train))
+ print("Number of records in validation set:", len(list_files_val))
+ print("Number of records in test set:", len(list_files_test))
+ else:
+ # For mros2, use all data for preprocessing
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, "EEG", "C3-A2")))
+
+ # AIRFLOW에 실제로 존재하는 파일만 남기기
+ airflow_dir = os.path.join(BASE_PATH, cfg.data_dir, "AIRFLOW", "AIRFLOW")
+ airflow_files = set(os.listdir(airflow_dir))
+ sig_list = sorted(list(set(sig_list).intersection(airflow_files)))
+
+ list_files_train = sig_list
+ list_files_val = []
+ list_files_test = []
+
+ print("Processing training set...")
+ preprocess(list_files_train, cfg.chn_grp, cfg.chn, split='train')
+ print("Processing evaluation set...")
+ preprocess(list_files_val, cfg.chn_grp, cfg.chn, split='val')
+ print("Processing test set...")
+ preprocess(list_files_test, cfg.chn_grp, cfg.chn, split='test')
+
+
+ # Reorganize annotations files
+ # ANN_PATH = os.path.join(BASE_PATH, 'mros1/annotations')
+ if cfg.ann_split and not cfg.mros2:
+ ANN_PATH = os.path.join(os.path.dirname(os.path.join(BASE_PATH, cfg.data_dir)), 'annotations')
+ NEW_ANN_PATH = ANN_PATH.replace('annotations', 'annotations_split')
+ os.makedirs(NEW_ANN_PATH, exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'train'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'val'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'test'), exist_ok=True)
+
+ for fname in list_files_train:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'train', ann_fname))
+ for fname in list_files_val:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'val', ann_fname))
+ for fname in list_files_test:
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'test', ann_fname))
+
+ # AH_PATH = os.path.join(BASE_PATH, 'kiss/ah_labels')
+ # NEW_AH_PATH = os.path.join(BASE_PATH, 'kiss/ah_labels_split')
+ # os.makedirs(NEW_AH_PATH, exist_ok=True)
+ # os.makedirs(os.path.join(NEW_AH_PATH,'train'), exist_ok=True)
+ # os.makedirs(os.path.join(NEW_AH_PATH,'val'), exist_ok=True)
+ # os.makedirs(os.path.join(NEW_AH_PATH,'test'), exist_ok=True)
+ # for fname in list_files_train:
+ # ann_fname = fname.replace('.npy', '_ah.npy')
+ # shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'train', ann_fname))
+ # for fname in list_files_val:
+ # ann_fname = fname.replace('.npy', '_ah.npy')
+ # shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'val', ann_fname))
+ # for fname in list_files_test:
+ # ann_fname = fname.replace('.npy', '_ah.npy')
+ # shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'test', ann_fname))
+
+
+ for split in ['train', 'val', 'test']:
+ # create link files to respiratory channels
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP'), exist_ok=True)
+ for chn_grp in ['ABD', 'AIRFLOW']:
+ chns = [f.split('.')[0] for f in os.listdir(os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp))]
+ for chn in chns:
+ src_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ src_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ dst_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.mmap')
+ dst_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.pickle')
+ if not os.path.exists(dst_mmap):
+ os.symlink(src_mmap, dst_mmap)
+ if not os.path.exists(dst_pickle):
+ os.symlink(src_pickle, dst_pickle)
+
diff --git a/data/physionet_2018_folds.npy b/data/physionet_2018_folds.npy
new file mode 100644
index 0000000000000000000000000000000000000000..10143aa82eeee7ccddb40d54c38e5a6d53829a88
Binary files /dev/null and b/data/physionet_2018_folds.npy differ
diff --git a/data/physionet_preprocess.py b/data/physionet_preprocess.py
new file mode 100644
index 0000000000000000000000000000000000000000..f94c988af64c51986b2582bbd8dcc6e9e105dcc1
--- /dev/null
+++ b/data/physionet_preprocess.py
@@ -0,0 +1,282 @@
+import os
+import shutil
+import numpy as np
+
+from scipy.signal import iirnotch, lfilter
+from data_utils import butter_bandpass_filter, correct_ecg_inversion
+
+import matplotlib.pyplot as plt
+from tqdm import tqdm
+import librosa
+import pickle
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+SAMPLING_RATE = 200
+TARGET_RESAMPLE = 100
+NOTCH_FREQ = 60
+EEG_LOWCUT = 0.3
+EEG_HIGHCUT = 40
+EMG_LOWCUT = 10
+EMG_HIGHCUT = 1000
+ECG_LOWCUT = 0.3
+ECG_HIGHCUT = 70
+FLOW_LOWCUT = 0
+FLOW_HIGHCUT = 15
+
+do_resample = (SAMPLING_RATE != TARGET_RESAMPLE)
+
+NUM_PROCESS = 4
+
+import argparse
+import multiprocessing
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default='physionet_2018/signals_MAE', help='Physionet 2018 raw data location')
+parser.add_argument('--output_dir', default='physionet_2018/mmap_signals_MAE_processed', help='Physionet 2018 processed data location')
+parser.add_argument('--save_type', default='mmap', help='Which data type to save. "npy" or "mmap"')
+
+cfg = parser.parse_args()
+
+
+
+def process_ecg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, ECG_LOWCUT, ECG_HIGHCUT, SAMPLING_RATE)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, SAMPLING_RATE)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ filtered = filtered.reshape(-1, SAMPLING_RATE*30)
+
+ filtered_epochs = []
+
+ for epoch in filtered:
+ inv_epoch, _ = correct_ecg_inversion(epoch, SAMPLING_RATE)
+ filtered_epochs.append(inv_epoch)
+
+ filtered = np.stack(filtered_epochs, axis=0)
+
+ if do_resample:
+ filtered = np.reshape(filtered, (-1,1))
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+
+def process_eeg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EEG_LOWCUT, EEG_HIGHCUT, SAMPLING_RATE)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, SAMPLING_RATE)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ if do_resample:
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_emg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EMG_LOWCUT, EMG_HIGHCUT, SAMPLING_RATE)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, SAMPLING_RATE)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ if do_resample:
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_flow(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ data = data.reshape(-1,)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, FLOW_LOWCUT, FLOW_HIGHCUT, SAMPLING_RATE)
+
+ # median filter?
+
+ if do_resample:
+ filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def save_mmap(results, sig_list, chn_grp, chn):
+ signame_list = [sig.split('.')[0] for sig in sig_list]
+ epoch_lengths = [sig.shape[0] for sig in results]
+ metadata = dict()
+ sig_info = dict()
+ start, end = 0, 0
+ for signame, sig in zip(signame_list, results):
+ length = sig.shape[0]
+ end = start + length
+ info = dict()
+ info['pos'] = (start, end)
+ info['stats'] = {'sum': float(np.sum(sig)), 'sumsq': float(np.sum(sig ** 2))}
+ sig_info[signame] = info
+ start = end
+
+
+ mmap_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, f'{chn}.mmap')
+ signals_cat = np.concatenate(results, axis=0).astype(np.float32)
+ os.makedirs(os.path.dirname(mmap_path), exist_ok=True)
+ data = np.memmap(mmap_path, dtype=np.float32, mode='w+', shape=signals_cat.shape)
+ data[:] = signals_cat
+ data.flush()
+
+ metadata['sig_info'] = sig_info
+ metadata['data_shape'] = signals_cat.shape
+ info_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, f'{chn}.pickle')
+ with open(info_path, 'wb') as f:
+ pickle.dump(metadata, f)
+
+if __name__ == '__main__':
+
+ for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+
+ print(f"Processing {chn_grp}/{chn}")
+ if chn_grp in ['EEG','EOG']:
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_eeg, input_list), total=len(input_list)))
+
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn)
+ # sig_list = [sig.split('.')[0] for sig in sig_list]
+ # epoch_lengths = [sig.shape[0] for sig in results]
+ # sig_info = dict()
+ # start, end = 0, 0
+ # for sig, length in zip(sig_list, epoch_lengths):
+ # end = start + length
+ # sig_info[sig] = (start, end)
+ # start = end
+
+ # mmap_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, f'{chn}.mmap')
+ # signals_cat = np.concatenate(results, axis=0).astype(np.float32)
+ # data = np.memmap(mmap_path, dtype=np.float32, mode='w+', shape=signals_cat.shape)
+ # data[:] = signals_cat
+ # data.flush()
+
+ # info_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, f'{chn}.pickle')
+ # with open(info_path, 'wb') as f:
+ # pickle.dump(sig_info, f)
+
+ elif chn_grp in ['EMG']:
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_emg, input_list), total=len(input_list)))
+
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn)
+
+ elif chn_grp in ['ECG']:
+
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_ecg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn)
+
+ elif chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_flow, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn)
+
+ else:
+ results = []
+ for sig in tqdm(sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))):
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ if do_resample or chn == 'SaO2':
+ data = data.reshape(-1, 1)
+ if chn == 'SaO2':
+ data = librosa.resample(data, orig_sr=SAMPLING_RATE, target_sr=1, axis=0, res_type='soxr_qq')
+ data = data / 100 # data range 0 to 100
+ if np.max(data) > 1 or np.min(data) < 0:
+ print(f"Warning: SaO2 values out of range: {sig} with min {np.min(data)} and max {np.max(data)}")
+ data = data.reshape(-1, 30)
+ else:
+ data = librosa.resample(data, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ data = data.reshape(-1, TARGET_RESAMPLE*30)
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # shutil.copy(sig_path, output_path)
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, data)
+ elif cfg.save_type == 'mmap':
+ results.append(data)
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ save_mmap(results, sig_list, chn_grp, chn)
+
+ # create link files to respiratory channels
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, 'RESP'), exist_ok=True)
+ for chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ chns = [f.split('.')[0] for f in os.listdir(os.path.join(BASE_PATH, cfg.output_dir, chn_grp))]
+ for chn in chns:
+ src_mmap = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, f'{chn}.mmap')
+ src_pickle = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, f'{chn}.pickle')
+ dst_mmap = os.path.join(BASE_PATH, cfg.output_dir, 'RESP', f'{chn}.mmap')
+ dst_pickle = os.path.join(BASE_PATH, cfg.output_dir, 'RESP', f'{chn}.pickle')
+ if not os.path.exists(dst_mmap):
+ os.symlink(src_mmap, dst_mmap)
+ if not os.path.exists(dst_pickle):
+ os.symlink(src_pickle, dst_pickle)
diff --git a/data/physionet_process_rawdata.py b/data/physionet_process_rawdata.py
new file mode 100644
index 0000000000000000000000000000000000000000..886d35832ef6198d7bf6b167fa936060077a0933
--- /dev/null
+++ b/data/physionet_process_rawdata.py
@@ -0,0 +1,156 @@
+import os
+import scipy
+import numpy as np
+#!pip install wfdb
+import wfdb
+import math
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+
+import argparse
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default='physionet.org/files/challenge-2018/1.0.0/training/', help='Physionet 2018 raw data location')
+parser.add_argument('--output_dir', default='physionet_2018/signals_MAE', help='Physionet 2018 processed data location')
+parser.add_argument('--annotation_dir', default='physionet_2018/annotations', help='Physionet 2018 annotations location')
+parser.add_argument('--ah_dir', default='physionet_2018/ah_labels', help='Physionet 2018 apnea/hypopnea labels location')
+parser.add_argument('--channels', nargs='+', default=[0,1,2,3,4,5,6,7,8,9,10,11,12], help='Physionet 2018 annotations location')
+parser.add_argument('--test', action='store_true', help='Preprocess test set')
+
+cfg = parser.parse_args()
+
+from tqdm.auto import tqdm
+
+if __name__ == '__main__':
+
+ # data_dir = '/tf/00_data/kdpark/physionet_2018/physionet_rawdata'
+ file_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir))
+ if cfg.test:
+ file_list = [f for f in file_list if f.startswith('te')]
+ else:
+ file_list = [f for f in file_list if f.startswith('tr')]
+
+
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir), exist_ok=True)
+ os.makedirs(os.path.join(BASE_PATH, cfg.annotation_dir), exist_ok=True)
+ os.makedirs(os.path.join(BASE_PATH, cfg.ah_dir), exist_ok=True)
+
+ def match_channel_group(chn):
+ """
+ Find the group of the channel.
+ """
+ chn_group = {
+ 'EEG': ['F3-M2', 'F4-M1', 'C3-M2', 'C4-M1', 'O1-M2', 'O2-M1'],
+ 'EOG': ['E1-M2'],
+ 'EMG': ['Chin1-Chin2'],
+ 'ABD': ['ABD'],
+ 'CHEST': ['CHEST'],
+ 'AIRFLOW': ['AIRFLOW'],
+ 'SaO2': ['SaO2'],
+ 'ECG': ['ECG']
+ }
+ for k, v in chn_group.items():
+ if chn in v:
+ return k
+ return None
+
+
+
+ for fl in tqdm(file_list):
+
+ # EEG: [C4-M1], EOG: [E1-M2], EMG: [Chin1-Chin2]
+ # fields: {'fs': 200, 'sig_len': 5569600, 'n_sig': 13, 'base_date': None,
+ # 'base_time': None, 'units': ['uV', 'uV', 'uV', 'uV', 'uV', 'uV', 'uV', 'uV', 'uV', 'uV', 'uV', '%', 'mV'],
+ # 'sig_name': ['F3-M2', 'F4-M1', 'C3-M2', 'C4-M1', 'O1-M2', 'O2-M1', 'E1-M2', 'Chin1-Chin2', 'ABD', 'CHEST', 'AIRFLOW', 'SaO2', 'ECG'], 'comments': []}
+
+ if fl == 'tr07-0023': continue
+
+ signals, fields = wfdb.rdsamp(os.path.join(BASE_PATH, cfg.data_dir, fl, fl), channels=cfg.channels)
+
+ if cfg.test:
+ num_epoch = signals.shape[0] // (200*30)
+ mat_signal = signals.astype(np.float32) #Shape: (num_samples, 13)
+ mat_signal = mat_signal[:num_epoch*200*30,:]
+
+ else:
+ ann = wfdb.rdann(os.path.join(BASE_PATH, cfg.data_dir, fl, fl),extension='arousal')
+ an = np.array(ann.aux_note) #Sleep stage and arousals annotations
+ s_time = ann.sample #annotation locations in samples relative to the beginning of the record.
+
+ an_where = np.concatenate((np.where(an=='W'),np.where(an=='N1'),np.where(an=='N2'),np.where(an=='N3'),np.where(an=='R')), axis=-1)
+ an_where.sort()
+
+ ah_where = np.concatenate((np.where(an=='(resp_obstructiveapnea'),
+ np.where(an=='resp_obstructiveapnea)'),
+ np.where(an=='(resp_hypopnea'),
+ np.where(an=='resp_hypopnea)')), axis=-1)
+ ah_where.sort()
+ stages = an[an_where[0]]
+ stages_time = s_time[an_where[0]]
+ ah = an[ah_where[0]]
+ ah_time = s_time[ah_where[0]]
+
+ print(len(an), len(stages_time))
+ num_epoch = int(stages_time[-1]/200/30) - int(stages_time[0]/200/30)
+ labels = -1 * np.ones((num_epoch,))
+ ah_labels = np.zeros((num_epoch*30,))
+ curr_epoch = 0
+ status= 0 if stages[0]=='W' else 1 if stages[0]=='N1' else 2 if stages[0]=='N2' else 3 if stages[0]=='N3' else 4
+
+ for i in range(1, len(stages)):
+
+ labels[curr_epoch: int(stages_time[i]/200/30) - int(stages_time[0]/200/30)] = status
+ curr_epoch = int(stages_time[i]/200/30 - int(stages_time[0]/200/30))
+
+ if stages[i] == 'W':
+ status = 0
+ elif stages[i] == 'N1':
+ status = 1
+ elif stages[i] == 'N2':
+ status = 2
+ elif stages[i] == 'N3':
+ status = 3
+ elif stages[i] == 'R':
+ status = 4
+ else:
+ status = -1
+ continue
+
+ curr_ah_label = None
+ for ah_label, ah_time_point in zip(ah, ah_time):
+ if ah_label == '(resp_obstructiveapnea' or ah_label == '(resp_hypopnea':
+ start = ah_time_point
+ curr_ah_label = ah_label
+ elif ah_label == 'resp_obstructiveapnea)' or ah_label == 'resp_hypopnea)':
+ end = ah_time_point
+ if curr_ah_label is None or curr_ah_label[1:] != ah_label[:-1]:
+ print(f"file:{fl}, Error in apnea/hypopnea annotation!, start_ah_label:{curr_ah_label}, end_ah_label:{ah_label}, from:{start}, to:{end}")
+ continue
+
+ start_sec = round((start - stages_time[0]) / 200)
+ end_sec = round((end - stages_time[0]) / 200)
+ end_sec = min(end_sec, len(ah_labels))
+ if ah_label == 'resp_obstructiveapnea)':
+ ah_labels[start_sec:end_sec] = 2
+ else:
+ ah_labels[start_sec:end_sec] = 1
+ # print(start_sec, end_sec, ah_label)
+
+
+ #Start time of signal&ann are always the same. Only match the end time
+ mat_signal = signals[stages_time[0]:stages_time[-1]].astype(np.float32) #Shape: (num_samples, 13)
+
+ if status == -1:
+ print("-1 error!")
+
+ print(fl, stages_time[0], stages_time[-1], len(labels)*200*30, len(mat_signal))
+
+ for i, fld in enumerate(fields['sig_name']):
+ chn_grp = match_channel_group(fld)
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, chn_grp, fld), exist_ok=True)
+ np.save(os.path.join(BASE_PATH, cfg.output_dir, chn_grp, fld, fl + '.npy'), mat_signal[:,i].reshape([num_epoch, 200*30]))
+
+ if not cfg.test:
+ # np.save(os.path.join(BASE_PATH, cfg.output_dir, fl + '.npy'), mat_signal)
+ np.save(os.path.join(BASE_PATH, cfg.annotation_dir, fl + '_ann.npy'), labels)
+ np.save(os.path.join(BASE_PATH, cfg.ah_dir, fl + '_ah.npy'), ah_labels)
+
diff --git a/data/prepare_mmap.py b/data/prepare_mmap.py
new file mode 100644
index 0000000000000000000000000000000000000000..b308f2b8923857b46b852f6939ae7512761c6451
--- /dev/null
+++ b/data/prepare_mmap.py
@@ -0,0 +1,31 @@
+import os, sys
+import numpy as np
+from tqdm import tqdm
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+
+import argparse
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default='physionet_2018/signals_MAE_processed', help='Physionet 2018 raw data location')
+parser.add_argument('--output_dir', default='physionet_2018/mmap_signals_MAE_processed', help='mmap save path')
+
+cfg = parser.parse_args()
+
+os.makedirs(os.path.join(BASE_PATH, cfg.output_dir), exist_ok=True)
+
+mmap_dict = {}
+
+for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ print(f"Processing {chn_grp}/{chn}")
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, chn_grp), exist_ok=True)
+ mmap_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, f'{chn}.mmap')
+ signals = []
+ for sig in tqdm(sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))):
+ signal_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ signal = np.load(signal_path)
+ signals.append(signal)
+ signals_cat = np.concatenate(signals, axis=0).astype(np.float32)
+ data = np.memmap(mmap_path, dtype=np.float32, mode='w+', shape=signals_cat.shape)
+ data[:] = signals_cat
+ data.flush()
\ No newline at end of file
diff --git a/data/preprocessing.sh b/data/preprocessing.sh
new file mode 100644
index 0000000000000000000000000000000000000000..830995f895db28437c4b214a0e174f35fe9ce968
--- /dev/null
+++ b/data/preprocessing.sh
@@ -0,0 +1,18 @@
+python physionet_preprocess.py
+# python kiss_preprocess.py --chn_grp SaO2 --chn SaO2
+python kiss_preprocess.py --chn_grp EEG --chn O1-A2
+python kiss_preprocess.py --chn_grp EEG --chn O2-A1
+python kiss_preprocess.py --chn_grp EEG --chn C4-A1
+python kiss_preprocess.py --chn_grp EEG --chn C3-A2
+python kiss_preprocess.py --chn_grp EOG --chn Right-A1
+python kiss_preprocess.py --chn_grp EOG --chn Left-A2
+# python kiss_preprocess.py --chn_grp AIRFLOW --chn AIRFLOW
+# python kiss_preprocess.py --chn_grp EMG --chn EMG
+python kiss_preprocess.py --chn_grp ECG --chn ECG
+# python kiss_preprocess.py --chn_grp CHEST --chn CHEST
+# python kiss_preprocess.py --chn_grp ABD --chn ABD
+python shhs_preprocess.py --chn_grp EEG --chn C3-A2
+python shhs_preprocess.py --chn_grp EEG --chn C4-A1
+python shhs_preprocess.py --chn_grp EOG --chn EOG-Diff
+python shhs_preprocess.py --chn_grp ECG --chn ECG
+
diff --git a/data/process_mesa.py b/data/process_mesa.py
new file mode 100644
index 0000000000000000000000000000000000000000..cbb616b6198bd0e44e94a7fea903b3b10fcbf5b6
--- /dev/null
+++ b/data/process_mesa.py
@@ -0,0 +1,285 @@
+import os
+import scipy
+import numpy as np
+#!pip install wfdb
+import pandas as pd
+from mne.io import concatenate_raws, read_raw_edf
+import xml.etree.ElementTree as ET
+import multiprocessing
+
+# BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+BASE_PATH = os.path.abspath('.') # 현재 디렉토리 기준으로 저장
+EPOCH_SEC_SIZE = 30
+AIRFLOW_CANDS = ["Flow"] # strict cannula only
+
+SELECT_CHNS = [
+ ["SpO2", ["SpO2"]],
+ ["ECG", ["ECG"]],
+ ["EMG", ["EMG"]],
+
+ ["EOG", [["EOG-L"], ["EOG-R"]]],
+ ["Fz-Cz", ['EEG1']],
+ ["Cz-Oz", ['EEG2']],
+ ["C4-M1", ['EEG3']],
+
+ ["Abdominal", ["Abdo"]],
+ ["Thoracic", ["Thor"]],
+
+ ["Cannula Flow", AIRFLOW_CANDS],
+]
+
+CHN_SAVE_DICT = {
+ "SpO2": ("SpO2", "SpO2"),
+ "ECG": ("ECG", "ECG"),
+ "EMG": ("EMG", "EMG"),
+ "EOG": ("EOG", "EOG-Diff"),
+ "Fz-Cz": ("EEG", "Fz-Cz"),
+ "Cz-Oz": ("EEG", "Cz-Oz"),
+ "C4-M1": ("EEG", "C4-M1"),
+ "Abdominal": ("ABD", "ABD"),
+ "Thoracic": ("CHEST", "CHEST"),
+ "Cannula Flow": ("AIRFLOW", "AIRFLOW"),
+}
+
+
+
+
+import argparse
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default="/home/yhna/data3/#_MESA/polysomnography/edfs/", help='MESA EDF directory')
+parser.add_argument('--annotation_dir', default="/home/yhna/data5/#_Annotation_XML/#_MESA_AHI_a0h3a", help='MESA revised XML directory')
+parser.add_argument('--output_dir', default="signals_MAE", help='Output directory under BASE_PATH (default: ./signals_MAE)')
+parser.add_argument('--dataset_name', default='mesa', help='Folder name for saving annotations under BASE_PATH')
+parser.add_argument('--num_workers', type=int, default=8)
+cfg = parser.parse_args()
+
+from tqdm.auto import tqdm
+
+def _pick_first(raw_df, cands):
+ if cands is None:
+ return None, None
+ if isinstance(cands, str):
+ cands = [cands]
+ for c in cands:
+ if c in raw_df.columns:
+ return raw_df[c], c
+ return None, None
+
+
+def process_signal(raw, select_idx, chns, fname):
+ raw_sampling_rate = int(raw.info['sfreq'])
+ raw_df = raw.to_data_frame()
+
+ # ++++ 라벨(선택구간 포함) 기준으로 필요한 epoch 수 계산
+ # ++++ select_idx는 원본 y의 인덱스이므로, 마지막 epoch까지 포함하려면 +1
+ need_epochs = int(select_idx[-1] + 1) # ++++
+ ep_len = EPOCH_SEC_SIZE * raw_sampling_rate # ++++
+ need_len = need_epochs * ep_len # ++++
+
+ for chn_spec in chns:
+ if isinstance(chn_spec, (list, tuple)):
+ out_name, spec = chn_spec[0], chn_spec[1]
+
+ # --- diff case: [[L cands], [R cands]] ---
+ if (isinstance(spec, (list, tuple)) and len(spec) == 2
+ and isinstance(spec[0], (list, tuple)) and isinstance(spec[1], (list, tuple))):
+ left, _ = _pick_first(raw_df, spec[0])
+ right, _ = _pick_first(raw_df, spec[1])
+ if left is None or right is None:
+ continue
+ raw_df[out_name] = left - right
+ raw_ch_df = raw_df[out_name]
+ chn_name = out_name
+
+ # --- alias case: [cand1, cand2, ...] ---
+ else:
+ raw_ch_df, _ = _pick_first(raw_df, spec)
+ if raw_ch_df is None:
+ continue
+ chn_name = out_name
+
+ else:
+ if chn_spec not in raw_df.columns:
+ continue
+ raw_ch_df = raw_df[chn_spec]
+ chn_name = chn_spec
+
+ raw_ch = raw_ch_df.to_numpy().reshape(-1, 1)
+
+ # ++++ 라벨이 존재하는 구간까지만 사용 (tail 1~29초 제거)
+ # ++++ MESA에서는 label_epochs == floor_epochs 패턴이라 truncate가 정답
+ if len(raw_ch) < need_len: # ++++
+ # ++++ 라벨/선택구간이 요구하는 길이보다 신호가 짧으면(이론상 MESA에서는 거의 없음)
+ # ++++ 기존 정책대로 스킵
+ print(f"[SKIP] Signal shorter than label-required length: {len(raw_ch)} < {need_len} ({fname}, {chn_name})") # ++++
+ continue # ++++
+ raw_ch = raw_ch[:need_len] # ++++
+
+ # ++++ 이제 무조건 30초 epoch 정수배가 됨
+ n_epochs = need_epochs # ++++
+ x = raw_ch.reshape(n_epochs, ep_len).astype(np.float32) # ++++
+
+ # select_idx 적용
+ x = x[select_idx]
+ x = x.reshape((-1, ep_len))
+
+ # 저장 경로 결정: chn_name 기준으로 매핑
+ chn_grp, chn_rename = CHN_SAVE_DICT[chn_name]
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn_rename), exist_ok=True)
+ np.save(os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn_rename, f"{fname}.npy"), x)
+
+def process_data(args):
+
+ ann_fname, edf_fname, file_id, shhs2 = args
+ ann_filename = os.path.basename(edf_fname).replace(".edf", "_ann.npy")
+ labels = []
+
+
+ # Read annotation and its header
+ if ann_fname is None:
+ print(f"None of annfname: {edf_fname}")
+ return -1
+
+ # annotations-events-profusion -> annotations-events 변경으로 인한
+ t = ET.parse(ann_fname)
+ r = t.getroot()
+ faulty_File = 0
+
+ use_r4 = False
+ if len(list(r)) > 4:
+ try:
+ if len(r[4]) > 0 and (r[4][0].text is not None) and r[4][0].text.strip().isdigit():
+ use_r4 = True
+ except Exception:
+ use_r4 = False
+
+ if use_r4:
+ for i in range(len(r[4])):
+ lbl = int(r[4][i].text)
+ if lbl == 4:
+ labels.append(3)
+ elif lbl == 5:
+ labels.append(4)
+ else:
+ labels.append(lbl)
+ if lbl > 5:
+ faulty_File = 1
+
+ if faulty_File == 1:
+ print("Faulty labels found!!")
+ return -1
+
+ y = np.asarray(labels, dtype=np.int32)
+
+ # --- (2) NSRR 타입(MrOS/SHHS nsrr): ScoredEvent(Stages|Stages)에서 구간을 epoch로 펼침 ---
+ else:
+ epoch_len = float(r.findtext(".//EpochLength") or EPOCH_SEC_SIZE)
+
+ stage_events = []
+ for ev in r.findall(".//ScoredEvent"):
+ if (ev.findtext("EventType") or "").strip() != "Stages|Stages":
+ continue
+ concept = (ev.findtext("EventConcept") or "").strip()
+ # concept: "Wake|0", "Stage 2 sleep|2", "REM sleep|5" 형태
+ try:
+ lbl = int(concept.split("|")[-1])
+ except Exception:
+ continue
+
+ start = float(ev.findtext("Start") or 0.0)
+ dur = float(ev.findtext("Duration") or 0.0)
+ stage_events.append((start, dur, lbl))
+
+ if len(stage_events) == 0:
+ print(f"[SKIP] No stage events in XML: {ann_fname}")
+ return -1
+
+ stage_events.sort(key=lambda x: x[0])
+ max_end = max(s + d for s, d, _ in stage_events)
+ n_epochs = int(round(max_end / epoch_len))
+
+ y = np.full(n_epochs, -1, dtype=np.int32)
+
+ for start, dur, lbl in stage_events:
+ # 원본 매핑 유지
+ if lbl == 4:
+ v = 3
+ elif lbl == 5:
+ v = 4
+ else:
+ v = lbl
+
+ s_idx = int(round(start / epoch_len))
+ n = int(round(dur / epoch_len))
+ if n <= 0:
+ continue
+ y[s_idx:s_idx + n] = v
+
+ # 빈 구간 채우기 (forward fill)
+ last = 0
+ for i in range(len(y)):
+ if y[i] == -1:
+ y[i] = last
+ else:
+ last = y[i]
+
+ # Select on sleep periods
+ w_edge_mins = 30
+ nw_idx = np.where(y != 0)[0] # get index of first not WAKE
+ start_idx = nw_idx[0] - (w_edge_mins * 2) # start from 30min before first WAKE
+ end_idx = nw_idx[-1] + (w_edge_mins * 2) # end at 30min after first WAKE
+ if start_idx < 0: start_idx = 0
+ if end_idx >= len(y): end_idx = len(y) - 1
+ select_idx = np.arange(start_idx, end_idx + 1)
+
+ # only selected labels
+ y = y[select_idx]
+ raw = read_raw_edf(edf_fname, preload=True, stim_channel=None, verbose=None)
+
+ process_signal(raw, select_idx, SELECT_CHNS, os.path.basename(edf_fname).split('.')[0])
+
+
+ ann_dir = os.path.join(BASE_PATH, cfg.dataset_name, "annotations")
+ os.makedirs(ann_dir, exist_ok=True)
+ np.save(os.path.join(ann_dir, ann_filename), arr=y)
+
+
+if __name__ == '__main__':
+ START_IDX = None # 이미 처리한 개수
+
+ edf_dir = cfg.data_dir
+ xml_dir = cfg.annotation_dir
+
+ # 1) EDF 목록
+ edf_fnames = sorted([
+ os.path.join(edf_dir, f)
+ for f in os.listdir(edf_dir)
+ if f.lower().endswith(".edf")
+ ])
+
+ # 2) EDF -> XML 매칭: {base}.edf <-> {base}-nsrr-revised.xml
+ ann_fnames = []
+ for edf_path in edf_fnames:
+ base = os.path.splitext(os.path.basename(edf_path))[0]
+ xml_path = os.path.join(xml_dir, f"{base}-nsrr-revised.xml")
+ if not os.path.exists(xml_path):
+ print(f"[SKIP] XML not found for {base}: {xml_path}")
+ ann_fnames.append(None)
+ else:
+ ann_fnames.append(xml_path)
+
+ # 3) input_list (XML 없는 건 스킵)
+ input_list = [
+ (ann_fnames[i], edf_fnames[i], i, False)
+ for i in range(len(edf_fnames))
+ if ann_fnames[i] is not None
+ ]
+
+ if START_IDX is not None:
+ input_list = input_list[START_IDX:]
+
+
+ with multiprocessing.Pool(cfg.num_workers) as pool:
+ list(tqdm(pool.imap(process_data, input_list), total=len(input_list)))
+
+
diff --git a/data/process_mros1.py b/data/process_mros1.py
new file mode 100644
index 0000000000000000000000000000000000000000..ef4ebaf1d01026c9263f9600bfdd3e3b0d17cc11
--- /dev/null
+++ b/data/process_mros1.py
@@ -0,0 +1,271 @@
+import os
+import scipy
+import numpy as np
+#!pip install wfdb
+import pandas as pd
+from mne.io import concatenate_raws, read_raw_edf
+import xml.etree.ElementTree as ET
+import multiprocessing
+
+# BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+BASE_PATH = os.path.abspath('.') # 현재 디렉토리 기준으로 저장
+EPOCH_SEC_SIZE = 30
+# ALL_CHANNELS = ['SaO2', 'H.R.', 'EEG(sec)', 'ECG', 'EMG', 'EOG(L)', 'EOG(R)', 'EEG', 'THOR RES', 'ABDO RES', 'POSITION', 'LIGHT', 'NEW AIR', 'OX stat']
+AIRFLOW_NAME = "Cannula Flow"
+
+SELECT_CHNS = [
+ "SaO2",
+ ["ECG L-ECG R", ["ECG L", "ECG R"]],
+ ["L Chin-R Chin", ["L Chin", "R Chin"]],
+ ["EOG-Diff", ["LOC", "ROC"]],
+ ["C3-A2", ["C3", "A2"]],
+ # ["C4-A1", ["C4", "A1"]],
+ "Abdominal", # ABD
+ "Thoracic", # CHEST
+ AIRFLOW_NAME # AIRFLOW (없으면 skip)
+]
+
+# 저장 폴더 매핑(chn_grp / chn_name)
+# (여기 key는 "내부에서 만든 신호 이름"임)
+CHN_SAVE_DICT = {
+ "SaO2": ("SaO2", "SaO2"),
+ "ECG L-ECG R": ("ECG", "ECG"),
+ "L Chin-R Chin": ("EMG", "EMG"),
+ "EOG-Diff": ("EOG", "EOG-Diff"),
+ "C3-A2": ("EEG", "C3-A2"),
+ # "C4-A1": ("EEG", "C4-A1"),
+ "Abdominal": ("ABD", "ABD"),
+ "Thoracic": ("CHEST", "CHEST"),
+ "Cannula Flow": ("AIRFLOW", "AIRFLOW"),
+}
+
+
+
+
+import argparse
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default="/home/yhna/data3/#_MrOS/polysomnography/edfs/visit1", help='MrOS EDF directory')
+parser.add_argument('--annotation_dir', default="/home/yhna/data5/#_Annotation_XML/#_MrOS1_AHI_a0h3a", help='MrOS revised XML directory')
+parser.add_argument('--output_dir', default="signals_MAE", help='Output directory under BASE_PATH (default: ./signals_MAE)')
+parser.add_argument('--dataset_name', default='mros1', help='Folder name for saving annotations under BASE_PATH')
+parser.add_argument('--num_workers', type=int, default=8)
+cfg = parser.parse_args()
+
+from tqdm.auto import tqdm
+
+def process_signal(raw, select_idx, chns, fname):
+ raw_sampling_rate = int(raw.info['sfreq'])
+ raw_df = raw.to_data_frame()
+ print(raw_df.columns)
+ for chn_spec in chns:
+ # chn_spec: str 또는 [a, [b,c]] 형태
+ if isinstance(chn_spec, (list, tuple)):
+ if len(chn_spec) != 2 or not isinstance(chn_spec[0], str):
+ continue
+
+ a = chn_spec[0]
+ bc = chn_spec[1]
+
+ if a in raw_df.columns:
+ raw_ch_df = raw_df[a]
+ else:
+ if not (isinstance(bc, (list, tuple)) and len(bc) == 2):
+ continue
+ b, c = bc[0], bc[1]
+ if (b in raw_df.columns) and (c in raw_df.columns):
+ raw_df[a] = raw_df[b] - raw_df[c]
+ raw_ch_df = raw_df[a]
+ else:
+ continue
+
+ chn_name = a
+
+ else:
+ chn_name = chn_spec
+ if chn_name not in raw_df.columns:
+ continue
+ raw_ch_df = raw_df[chn_name]
+
+ raw_ch_df = raw_ch_df.to_frame()
+ raw_ch_df.index = np.arange(len(raw_ch_df))
+
+ # Remove movement and unknown stages if any
+ raw_ch = raw_ch_df.values
+
+ # Verify that we can split into 30-s epochs
+ ep_len = EPOCH_SEC_SIZE * raw_sampling_rate
+ if len(raw_ch) % ep_len != 0:
+ print(f"Length of raw channel ({len(raw_ch)}) is not multiple of ({EPOCH_SEC_SIZE} * {raw_sampling_rate})")
+ continue
+
+ # get (# of epochs)
+ n_epochs = len(raw_ch) // ep_len
+
+ # split epochs
+ x = raw_ch.reshape(n_epochs, ep_len).astype(np.float32)
+
+ # select_idx 적용
+ x = x[select_idx]
+ x = x.reshape((-1, ep_len))
+
+ # 저장 경로 결정: chn_name 기준으로 매핑
+ chn_grp, chn_rename = CHN_SAVE_DICT[chn_name]
+
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn_rename), exist_ok=True)
+ np.save(os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn_rename, f"{fname}.npy"), x)
+
+
+def process_data(args):
+
+ ann_fname, edf_fname, file_id, shhs2 = args
+ ann_filename = os.path.basename(edf_fname).replace(".edf", "_ann.npy")
+ labels = []
+
+
+ # Read annotation and its header
+ if ann_fname is None:
+ print(f"None of annfname: {edf_fname}")
+ return -1
+
+ # annotations-events-profusion -> annotations-events 변경으로 인한
+ t = ET.parse(ann_fname)
+ r = t.getroot()
+ faulty_File = 0
+
+ use_r4 = False
+ if len(list(r)) > 4:
+ try:
+ if len(r[4]) > 0 and (r[4][0].text is not None) and r[4][0].text.strip().isdigit():
+ use_r4 = True
+ except Exception:
+ use_r4 = False
+
+ if use_r4:
+ for i in range(len(r[4])):
+ lbl = int(r[4][i].text)
+ if lbl == 4:
+ labels.append(3)
+ elif lbl == 5:
+ labels.append(4)
+ else:
+ labels.append(lbl)
+ if lbl > 5:
+ faulty_File = 1
+
+ if faulty_File == 1:
+ print("Faulty labels found!!")
+ return -1
+
+ y = np.asarray(labels, dtype=np.int32)
+
+ # --- (2) NSRR 타입(MrOS/SHHS nsrr): ScoredEvent(Stages|Stages)에서 구간을 epoch로 펼침 ---
+ else:
+ epoch_len = float(r.findtext(".//EpochLength") or EPOCH_SEC_SIZE)
+
+ stage_events = []
+ for ev in r.findall(".//ScoredEvent"):
+ if (ev.findtext("EventType") or "").strip() != "Stages|Stages":
+ continue
+ concept = (ev.findtext("EventConcept") or "").strip()
+ # concept: "Wake|0", "Stage 2 sleep|2", "REM sleep|5" 형태
+ try:
+ lbl = int(concept.split("|")[-1])
+ except Exception:
+ continue
+
+ start = float(ev.findtext("Start") or 0.0)
+ dur = float(ev.findtext("Duration") or 0.0)
+ stage_events.append((start, dur, lbl))
+
+ if len(stage_events) == 0:
+ print(f"[SKIP] No stage events in XML: {ann_fname}")
+ return -1
+
+ stage_events.sort(key=lambda x: x[0])
+ max_end = max(s + d for s, d, _ in stage_events)
+ n_epochs = int(round(max_end / epoch_len))
+
+ y = np.full(n_epochs, -1, dtype=np.int32)
+
+ for start, dur, lbl in stage_events:
+ # 원본 매핑 유지
+ if lbl == 4:
+ v = 3
+ elif lbl == 5:
+ v = 4
+ else:
+ v = lbl
+
+ s_idx = int(round(start / epoch_len))
+ n = int(round(dur / epoch_len))
+ if n <= 0:
+ continue
+ y[s_idx:s_idx + n] = v
+
+ # 빈 구간 채우기 (forward fill)
+ last = 0
+ for i in range(len(y)):
+ if y[i] == -1:
+ y[i] = last
+ else:
+ last = y[i]
+
+ # Select on sleep periods
+ w_edge_mins = 30
+ nw_idx = np.where(y != 0)[0] # get index of first not WAKE
+ start_idx = nw_idx[0] - (w_edge_mins * 2) # start from 30min before first WAKE
+ end_idx = nw_idx[-1] + (w_edge_mins * 2) # end at 30min after first WAKE
+ if start_idx < 0: start_idx = 0
+ if end_idx >= len(y): end_idx = len(y) - 1
+ select_idx = np.arange(start_idx, end_idx + 1)
+
+ # only selected labels
+ y = y[select_idx]
+ raw = read_raw_edf(edf_fname, preload=True, stim_channel=None, verbose=None)
+
+ process_signal(raw, select_idx, SELECT_CHNS, os.path.basename(edf_fname).split('.')[0])
+
+
+ ann_dir = os.path.join(BASE_PATH, cfg.dataset_name, "annotations")
+ os.makedirs(ann_dir, exist_ok=True)
+ np.save(os.path.join(ann_dir, ann_filename), arr=y)
+
+
+if __name__ == '__main__':
+ START_IDX = 2300 # 이미 처리한 개수
+
+ edf_dir = cfg.data_dir
+ xml_dir = cfg.annotation_dir
+
+ # 1) EDF 목록
+ edf_fnames = sorted([
+ os.path.join(edf_dir, f)
+ for f in os.listdir(edf_dir)
+ if f.lower().endswith(".edf")
+ ])
+
+ # 2) EDF -> XML 매칭: {base}.edf <-> {base}-nsrr-revised.xml
+ ann_fnames = []
+ for edf_path in edf_fnames:
+ base = os.path.splitext(os.path.basename(edf_path))[0]
+ xml_path = os.path.join(xml_dir, f"{base}-nsrr-revised.xml")
+ if not os.path.exists(xml_path):
+ print(f"[SKIP] XML not found for {base}: {xml_path}")
+ ann_fnames.append(None)
+ else:
+ ann_fnames.append(xml_path)
+
+ # 3) input_list (XML 없는 건 스킵)
+ input_list = [
+ (ann_fnames[i], edf_fnames[i], i, False)
+ for i in range(len(edf_fnames))
+ if ann_fnames[i] is not None
+ ]
+
+ input_list = input_list[START_IDX:]
+
+
+ with multiprocessing.Pool(cfg.num_workers) as pool:
+ list(tqdm(pool.imap(process_data, input_list), total=len(input_list)))
+
+
diff --git a/data/shhs_meta_data/eval_list.txt b/data/shhs_meta_data/eval_list.txt
new file mode 100644
index 0000000000000000000000000000000000000000..9b86a7a13ed7895a717ded24ba9f0007fc4c9810
--- /dev/null
+++ b/data/shhs_meta_data/eval_list.txt
@@ -0,0 +1,100 @@
+../../mat/n0029_eeg.mat 959
+../../mat/n0038_eeg.mat 959
+../../mat/n0142_eeg.mat 1053
+../../mat/n0169_eeg.mat 1069
+../../mat/n0202_eeg.mat 1067
+../../mat/n0321_eeg.mat 1069
+../../mat/n0463_eeg.mat 899
+../../mat/n0542_eeg.mat 1067
+../../mat/n0638_eeg.mat 1031
+../../mat/n0660_eeg.mat 1049
+../../mat/n0682_eeg.mat 1067
+../../mat/n0685_eeg.mat 930
+../../mat/n0746_eeg.mat 1067
+../../mat/n0781_eeg.mat 809
+../../mat/n0786_eeg.mat 1049
+../../mat/n0787_eeg.mat 945
+../../mat/n0816_eeg.mat 984
+../../mat/n0833_eeg.mat 1069
+../../mat/n0839_eeg.mat 959
+../../mat/n1020_eeg.mat 927
+../../mat/n1099_eeg.mat 899
+../../mat/n1108_eeg.mat 817
+../../mat/n1114_eeg.mat 854
+../../mat/n1115_eeg.mat 1086
+../../mat/n1136_eeg.mat 1047
+../../mat/n1156_eeg.mat 1012
+../../mat/n1261_eeg.mat 959
+../../mat/n1355_eeg.mat 959
+../../mat/n1358_eeg.mat 1051
+../../mat/n1404_eeg.mat 1053
+../../mat/n1415_eeg.mat 1053
+../../mat/n1425_eeg.mat 1053
+../../mat/n1449_eeg.mat 1049
+../../mat/n1500_eeg.mat 1053
+../../mat/n1522_eeg.mat 906
+../../mat/n1525_eeg.mat 1018
+../../mat/n1565_eeg.mat 929
+../../mat/n1727_eeg.mat 1019
+../../mat/n1746_eeg.mat 959
+../../mat/n1843_eeg.mat 899
+../../mat/n1845_eeg.mat 987
+../../mat/n1976_eeg.mat 1055
+../../mat/n2030_eeg.mat 1086
+../../mat/n2162_eeg.mat 1084
+../../mat/n2218_eeg.mat 1053
+../../mat/n2235_eeg.mat 893
+../../mat/n2272_eeg.mat 959
+../../mat/n2347_eeg.mat 1053
+../../mat/n2467_eeg.mat 893
+../../mat/n2534_eeg.mat 1084
+../../mat/n2576_eeg.mat 899
+../../mat/n2579_eeg.mat 797
+../../mat/n2637_eeg.mat 1084
+../../mat/n2665_eeg.mat 745
+../../mat/n2681_eeg.mat 1019
+../../mat/n2719_eeg.mat 1051
+../../mat/n2723_eeg.mat 1050
+../../mat/n3089_eeg.mat 1044
+../../mat/n3254_eeg.mat 1051
+../../mat/n3257_eeg.mat 1019
+../../mat/n3370_eeg.mat 1051
+../../mat/n3479_eeg.mat 1053
+../../mat/n3542_eeg.mat 1053
+../../mat/n3557_eeg.mat 1018
+../../mat/n3591_eeg.mat 1051
+../../mat/n3670_eeg.mat 1053
+../../mat/n3751_eeg.mat 765
+../../mat/n3759_eeg.mat 1068
+../../mat/n3765_eeg.mat 1069
+../../mat/n3804_eeg.mat 1069
+../../mat/n3879_eeg.mat 1051
+../../mat/n3907_eeg.mat 1069
+../../mat/n3943_eeg.mat 1068
+../../mat/n4056_eeg.mat 1068
+../../mat/n4080_eeg.mat 1069
+../../mat/n4143_eeg.mat 1019
+../../mat/n4154_eeg.mat 1067
+../../mat/n4251_eeg.mat 1019
+../../mat/n4262_eeg.mat 1069
+../../mat/n4357_eeg.mat 899
+../../mat/n4425_eeg.mat 1069
+../../mat/n4613_eeg.mat 1069
+../../mat/n4618_eeg.mat 1069
+../../mat/n4671_eeg.mat 1019
+../../mat/n4698_eeg.mat 836
+../../mat/n4736_eeg.mat 1053
+../../mat/n4760_eeg.mat 959
+../../mat/n4883_eeg.mat 1013
+../../mat/n4980_eeg.mat 958
+../../mat/n4984_eeg.mat 822
+../../mat/n5022_eeg.mat 1051
+../../mat/n5060_eeg.mat 751
+../../mat/n5070_eeg.mat 1053
+../../mat/n5096_eeg.mat 1069
+../../mat/n5161_eeg.mat 1019
+../../mat/n5175_eeg.mat 1019
+../../mat/n5282_eeg.mat 1053
+../../mat/n5291_eeg.mat 1053
+../../mat/n5321_eeg.mat 1069
+../../mat/n5381_eeg.mat 1069
diff --git a/data/shhs_meta_data/filenames_ann.txt b/data/shhs_meta_data/filenames_ann.txt
new file mode 100644
index 0000000000000000000000000000000000000000..3230583a2003c96c44545871f9a2df54d6462f49
--- /dev/null
+++ b/data/shhs_meta_data/filenames_ann.txt
@@ -0,0 +1,5793 @@
+shhs1-200001-profusion.xml
+shhs1-200002-profusion.xml
+shhs1-200003-profusion.xml
+shhs1-200004-profusion.xml
+shhs1-200005-profusion.xml
+shhs1-200006-profusion.xml
+shhs1-200007-profusion.xml
+shhs1-200008-profusion.xml
+shhs1-200009-profusion.xml
+shhs1-200010-profusion.xml
+shhs1-200011-profusion.xml
+shhs1-200012-profusion.xml
+shhs1-200013-profusion.xml
+shhs1-200014-profusion.xml
+shhs1-200015-profusion.xml
+shhs1-200016-profusion.xml
+shhs1-200017-profusion.xml
+shhs1-200018-profusion.xml
+shhs1-200019-profusion.xml
+shhs1-200020-profusion.xml
+shhs1-200021-profusion.xml
+shhs1-200022-profusion.xml
+shhs1-200023-profusion.xml
+shhs1-200024-profusion.xml
+shhs1-200025-profusion.xml
+shhs1-200026-profusion.xml
+shhs1-200027-profusion.xml
+shhs1-200028-profusion.xml
+shhs1-200029-profusion.xml
+shhs1-200030-profusion.xml
+shhs1-200031-profusion.xml
+shhs1-200032-profusion.xml
+shhs1-200033-profusion.xml
+shhs1-200034-profusion.xml
+shhs1-200035-profusion.xml
+shhs1-200036-profusion.xml
+shhs1-200037-profusion.xml
+shhs1-200038-profusion.xml
+shhs1-200039-profusion.xml
+shhs1-200040-profusion.xml
+shhs1-200041-profusion.xml
+shhs1-200042-profusion.xml
+shhs1-200043-profusion.xml
+shhs1-200044-profusion.xml
+shhs1-200045-profusion.xml
+shhs1-200046-profusion.xml
+shhs1-200047-profusion.xml
+shhs1-200048-profusion.xml
+shhs1-200049-profusion.xml
+shhs1-200050-profusion.xml
+shhs1-200051-profusion.xml
+shhs1-200052-profusion.xml
+shhs1-200053-profusion.xml
+shhs1-200054-profusion.xml
+shhs1-200055-profusion.xml
+shhs1-200056-profusion.xml
+shhs1-200057-profusion.xml
+shhs1-200058-profusion.xml
+shhs1-200059-profusion.xml
+shhs1-200060-profusion.xml
+shhs1-200061-profusion.xml
+shhs1-200062-profusion.xml
+shhs1-200063-profusion.xml
+shhs1-200064-profusion.xml
+shhs1-200065-profusion.xml
+shhs1-200066-profusion.xml
+shhs1-200067-profusion.xml
+shhs1-200068-profusion.xml
+shhs1-200069-profusion.xml
+shhs1-200070-profusion.xml
+shhs1-200071-profusion.xml
+shhs1-200072-profusion.xml
+shhs1-200073-profusion.xml
+shhs1-200074-profusion.xml
+shhs1-200075-profusion.xml
+shhs1-200076-profusion.xml
+shhs1-200077-profusion.xml
+shhs1-200078-profusion.xml
+shhs1-200079-profusion.xml
+shhs1-200080-profusion.xml
+shhs1-200081-profusion.xml
+shhs1-200082-profusion.xml
+shhs1-200083-profusion.xml
+shhs1-200084-profusion.xml
+shhs1-200085-profusion.xml
+shhs1-200086-profusion.xml
+shhs1-200087-profusion.xml
+shhs1-200088-profusion.xml
+shhs1-200089-profusion.xml
+shhs1-200090-profusion.xml
+shhs1-200091-profusion.xml
+shhs1-200092-profusion.xml
+shhs1-200093-profusion.xml
+shhs1-200094-profusion.xml
+shhs1-200095-profusion.xml
+shhs1-200096-profusion.xml
+shhs1-200097-profusion.xml
+shhs1-200098-profusion.xml
+shhs1-200099-profusion.xml
+shhs1-200100-profusion.xml
+shhs1-200101-profusion.xml
+shhs1-200102-profusion.xml
+shhs1-200103-profusion.xml
+shhs1-200104-profusion.xml
+shhs1-200105-profusion.xml
+shhs1-200106-profusion.xml
+shhs1-200107-profusion.xml
+shhs1-200108-profusion.xml
+shhs1-200109-profusion.xml
+shhs1-200110-profusion.xml
+shhs1-200111-profusion.xml
+shhs1-200112-profusion.xml
+shhs1-200113-profusion.xml
+shhs1-200114-profusion.xml
+shhs1-200115-profusion.xml
+shhs1-200116-profusion.xml
+shhs1-200117-profusion.xml
+shhs1-200118-profusion.xml
+shhs1-200119-profusion.xml
+shhs1-200120-profusion.xml
+shhs1-200121-profusion.xml
+shhs1-200122-profusion.xml
+shhs1-200123-profusion.xml
+shhs1-200124-profusion.xml
+shhs1-200125-profusion.xml
+shhs1-200126-profusion.xml
+shhs1-200127-profusion.xml
+shhs1-200128-profusion.xml
+shhs1-200129-profusion.xml
+shhs1-200130-profusion.xml
+shhs1-200131-profusion.xml
+shhs1-200132-profusion.xml
+shhs1-200133-profusion.xml
+shhs1-200134-profusion.xml
+shhs1-200135-profusion.xml
+shhs1-200136-profusion.xml
+shhs1-200137-profusion.xml
+shhs1-200138-profusion.xml
+shhs1-200139-profusion.xml
+shhs1-200140-profusion.xml
+shhs1-200141-profusion.xml
+shhs1-200142-profusion.xml
+shhs1-200143-profusion.xml
+shhs1-200144-profusion.xml
+shhs1-200145-profusion.xml
+shhs1-200147-profusion.xml
+shhs1-200148-profusion.xml
+shhs1-200149-profusion.xml
+shhs1-200150-profusion.xml
+shhs1-200151-profusion.xml
+shhs1-200152-profusion.xml
+shhs1-200153-profusion.xml
+shhs1-200154-profusion.xml
+shhs1-200155-profusion.xml
+shhs1-200156-profusion.xml
+shhs1-200157-profusion.xml
+shhs1-200158-profusion.xml
+shhs1-200159-profusion.xml
+shhs1-200160-profusion.xml
+shhs1-200161-profusion.xml
+shhs1-200162-profusion.xml
+shhs1-200163-profusion.xml
+shhs1-200164-profusion.xml
+shhs1-200165-profusion.xml
+shhs1-200166-profusion.xml
+shhs1-200167-profusion.xml
+shhs1-200168-profusion.xml
+shhs1-200169-profusion.xml
+shhs1-200170-profusion.xml
+shhs1-200171-profusion.xml
+shhs1-200172-profusion.xml
+shhs1-200173-profusion.xml
+shhs1-200174-profusion.xml
+shhs1-200175-profusion.xml
+shhs1-200176-profusion.xml
+shhs1-200177-profusion.xml
+shhs1-200178-profusion.xml
+shhs1-200179-profusion.xml
+shhs1-200180-profusion.xml
+shhs1-200181-profusion.xml
+shhs1-200182-profusion.xml
+shhs1-200183-profusion.xml
+shhs1-200184-profusion.xml
+shhs1-200185-profusion.xml
+shhs1-200186-profusion.xml
+shhs1-200187-profusion.xml
+shhs1-200188-profusion.xml
+shhs1-200189-profusion.xml
+shhs1-200190-profusion.xml
+shhs1-200191-profusion.xml
+shhs1-200192-profusion.xml
+shhs1-200193-profusion.xml
+shhs1-200194-profusion.xml
+shhs1-200195-profusion.xml
+shhs1-200196-profusion.xml
+shhs1-200197-profusion.xml
+shhs1-200198-profusion.xml
+shhs1-200199-profusion.xml
+shhs1-200200-profusion.xml
+shhs1-200201-profusion.xml
+shhs1-200202-profusion.xml
+shhs1-200203-profusion.xml
+shhs1-200204-profusion.xml
+shhs1-200205-profusion.xml
+shhs1-200206-profusion.xml
+shhs1-200207-profusion.xml
+shhs1-200208-profusion.xml
+shhs1-200209-profusion.xml
+shhs1-200210-profusion.xml
+shhs1-200211-profusion.xml
+shhs1-200212-profusion.xml
+shhs1-200213-profusion.xml
+shhs1-200214-profusion.xml
+shhs1-200215-profusion.xml
+shhs1-200216-profusion.xml
+shhs1-200217-profusion.xml
+shhs1-200218-profusion.xml
+shhs1-200219-profusion.xml
+shhs1-200220-profusion.xml
+shhs1-200221-profusion.xml
+shhs1-200222-profusion.xml
+shhs1-200223-profusion.xml
+shhs1-200224-profusion.xml
+shhs1-200225-profusion.xml
+shhs1-200226-profusion.xml
+shhs1-200227-profusion.xml
+shhs1-200228-profusion.xml
+shhs1-200229-profusion.xml
+shhs1-200230-profusion.xml
+shhs1-200231-profusion.xml
+shhs1-200232-profusion.xml
+shhs1-200233-profusion.xml
+shhs1-200234-profusion.xml
+shhs1-200235-profusion.xml
+shhs1-200236-profusion.xml
+shhs1-200237-profusion.xml
+shhs1-200238-profusion.xml
+shhs1-200239-profusion.xml
+shhs1-200240-profusion.xml
+shhs1-200241-profusion.xml
+shhs1-200242-profusion.xml
+shhs1-200243-profusion.xml
+shhs1-200244-profusion.xml
+shhs1-200245-profusion.xml
+shhs1-200247-profusion.xml
+shhs1-200248-profusion.xml
+shhs1-200249-profusion.xml
+shhs1-200250-profusion.xml
+shhs1-200251-profusion.xml
+shhs1-200252-profusion.xml
+shhs1-200253-profusion.xml
+shhs1-200254-profusion.xml
+shhs1-200255-profusion.xml
+shhs1-200256-profusion.xml
+shhs1-200257-profusion.xml
+shhs1-200258-profusion.xml
+shhs1-200259-profusion.xml
+shhs1-200260-profusion.xml
+shhs1-200261-profusion.xml
+shhs1-200262-profusion.xml
+shhs1-200263-profusion.xml
+shhs1-200264-profusion.xml
+shhs1-200265-profusion.xml
+shhs1-200266-profusion.xml
+shhs1-200267-profusion.xml
+shhs1-200268-profusion.xml
+shhs1-200269-profusion.xml
+shhs1-200270-profusion.xml
+shhs1-200271-profusion.xml
+shhs1-200272-profusion.xml
+shhs1-200273-profusion.xml
+shhs1-200274-profusion.xml
+shhs1-200275-profusion.xml
+shhs1-200276-profusion.xml
+shhs1-200277-profusion.xml
+shhs1-200278-profusion.xml
+shhs1-200280-profusion.xml
+shhs1-200281-profusion.xml
+shhs1-200282-profusion.xml
+shhs1-200283-profusion.xml
+shhs1-200284-profusion.xml
+shhs1-200285-profusion.xml
+shhs1-200286-profusion.xml
+shhs1-200287-profusion.xml
+shhs1-200288-profusion.xml
+shhs1-200289-profusion.xml
+shhs1-200290-profusion.xml
+shhs1-200291-profusion.xml
+shhs1-200292-profusion.xml
+shhs1-200293-profusion.xml
+shhs1-200294-profusion.xml
+shhs1-200295-profusion.xml
+shhs1-200296-profusion.xml
+shhs1-200297-profusion.xml
+shhs1-200298-profusion.xml
+shhs1-200299-profusion.xml
+shhs1-200300-profusion.xml
+shhs1-200301-profusion.xml
+shhs1-200302-profusion.xml
+shhs1-200303-profusion.xml
+shhs1-200304-profusion.xml
+shhs1-200305-profusion.xml
+shhs1-200306-profusion.xml
+shhs1-200307-profusion.xml
+shhs1-200308-profusion.xml
+shhs1-200309-profusion.xml
+shhs1-200310-profusion.xml
+shhs1-200311-profusion.xml
+shhs1-200312-profusion.xml
+shhs1-200313-profusion.xml
+shhs1-200314-profusion.xml
+shhs1-200315-profusion.xml
+shhs1-200316-profusion.xml
+shhs1-200317-profusion.xml
+shhs1-200318-profusion.xml
+shhs1-200319-profusion.xml
+shhs1-200320-profusion.xml
+shhs1-200321-profusion.xml
+shhs1-200322-profusion.xml
+shhs1-200323-profusion.xml
+shhs1-200324-profusion.xml
+shhs1-200325-profusion.xml
+shhs1-200326-profusion.xml
+shhs1-200327-profusion.xml
+shhs1-200328-profusion.xml
+shhs1-200329-profusion.xml
+shhs1-200330-profusion.xml
+shhs1-200331-profusion.xml
+shhs1-200332-profusion.xml
+shhs1-200333-profusion.xml
+shhs1-200334-profusion.xml
+shhs1-200335-profusion.xml
+shhs1-200336-profusion.xml
+shhs1-200337-profusion.xml
+shhs1-200338-profusion.xml
+shhs1-200339-profusion.xml
+shhs1-200340-profusion.xml
+shhs1-200341-profusion.xml
+shhs1-200342-profusion.xml
+shhs1-200343-profusion.xml
+shhs1-200344-profusion.xml
+shhs1-200345-profusion.xml
+shhs1-200346-profusion.xml
+shhs1-200347-profusion.xml
+shhs1-200348-profusion.xml
+shhs1-200349-profusion.xml
+shhs1-200350-profusion.xml
+shhs1-200351-profusion.xml
+shhs1-200352-profusion.xml
+shhs1-200353-profusion.xml
+shhs1-200354-profusion.xml
+shhs1-200355-profusion.xml
+shhs1-200356-profusion.xml
+shhs1-200357-profusion.xml
+shhs1-200358-profusion.xml
+shhs1-200359-profusion.xml
+shhs1-200360-profusion.xml
+shhs1-200361-profusion.xml
+shhs1-200362-profusion.xml
+shhs1-200363-profusion.xml
+shhs1-200364-profusion.xml
+shhs1-200365-profusion.xml
+shhs1-200366-profusion.xml
+shhs1-200367-profusion.xml
+shhs1-200368-profusion.xml
+shhs1-200369-profusion.xml
+shhs1-200370-profusion.xml
+shhs1-200371-profusion.xml
+shhs1-200372-profusion.xml
+shhs1-200373-profusion.xml
+shhs1-200374-profusion.xml
+shhs1-200375-profusion.xml
+shhs1-200376-profusion.xml
+shhs1-200377-profusion.xml
+shhs1-200378-profusion.xml
+shhs1-200379-profusion.xml
+shhs1-200380-profusion.xml
+shhs1-200381-profusion.xml
+shhs1-200382-profusion.xml
+shhs1-200383-profusion.xml
+shhs1-200384-profusion.xml
+shhs1-200385-profusion.xml
+shhs1-200386-profusion.xml
+shhs1-200387-profusion.xml
+shhs1-200388-profusion.xml
+shhs1-200389-profusion.xml
+shhs1-200390-profusion.xml
+shhs1-200391-profusion.xml
+shhs1-200392-profusion.xml
+shhs1-200393-profusion.xml
+shhs1-200394-profusion.xml
+shhs1-200395-profusion.xml
+shhs1-200396-profusion.xml
+shhs1-200397-profusion.xml
+shhs1-200398-profusion.xml
+shhs1-200399-profusion.xml
+shhs1-200400-profusion.xml
+shhs1-200401-profusion.xml
+shhs1-200402-profusion.xml
+shhs1-200403-profusion.xml
+shhs1-200404-profusion.xml
+shhs1-200405-profusion.xml
+shhs1-200406-profusion.xml
+shhs1-200407-profusion.xml
+shhs1-200408-profusion.xml
+shhs1-200409-profusion.xml
+shhs1-200410-profusion.xml
+shhs1-200411-profusion.xml
+shhs1-200412-profusion.xml
+shhs1-200413-profusion.xml
+shhs1-200414-profusion.xml
+shhs1-200415-profusion.xml
+shhs1-200416-profusion.xml
+shhs1-200417-profusion.xml
+shhs1-200418-profusion.xml
+shhs1-200419-profusion.xml
+shhs1-200420-profusion.xml
+shhs1-200421-profusion.xml
+shhs1-200422-profusion.xml
+shhs1-200423-profusion.xml
+shhs1-200424-profusion.xml
+shhs1-200425-profusion.xml
+shhs1-200426-profusion.xml
+shhs1-200427-profusion.xml
+shhs1-200428-profusion.xml
+shhs1-200429-profusion.xml
+shhs1-200430-profusion.xml
+shhs1-200431-profusion.xml
+shhs1-200432-profusion.xml
+shhs1-200433-profusion.xml
+shhs1-200434-profusion.xml
+shhs1-200435-profusion.xml
+shhs1-200436-profusion.xml
+shhs1-200437-profusion.xml
+shhs1-200438-profusion.xml
+shhs1-200439-profusion.xml
+shhs1-200440-profusion.xml
+shhs1-200441-profusion.xml
+shhs1-200442-profusion.xml
+shhs1-200443-profusion.xml
+shhs1-200444-profusion.xml
+shhs1-200445-profusion.xml
+shhs1-200446-profusion.xml
+shhs1-200447-profusion.xml
+shhs1-200448-profusion.xml
+shhs1-200449-profusion.xml
+shhs1-200450-profusion.xml
+shhs1-200451-profusion.xml
+shhs1-200452-profusion.xml
+shhs1-200453-profusion.xml
+shhs1-200454-profusion.xml
+shhs1-200455-profusion.xml
+shhs1-200456-profusion.xml
+shhs1-200457-profusion.xml
+shhs1-200458-profusion.xml
+shhs1-200459-profusion.xml
+shhs1-200460-profusion.xml
+shhs1-200461-profusion.xml
+shhs1-200462-profusion.xml
+shhs1-200463-profusion.xml
+shhs1-200464-profusion.xml
+shhs1-200465-profusion.xml
+shhs1-200466-profusion.xml
+shhs1-200467-profusion.xml
+shhs1-200468-profusion.xml
+shhs1-200469-profusion.xml
+shhs1-200470-profusion.xml
+shhs1-200471-profusion.xml
+shhs1-200472-profusion.xml
+shhs1-200473-profusion.xml
+shhs1-200474-profusion.xml
+shhs1-200475-profusion.xml
+shhs1-200476-profusion.xml
+shhs1-200477-profusion.xml
+shhs1-200478-profusion.xml
+shhs1-200479-profusion.xml
+shhs1-200480-profusion.xml
+shhs1-200481-profusion.xml
+shhs1-200482-profusion.xml
+shhs1-200483-profusion.xml
+shhs1-200484-profusion.xml
+shhs1-200485-profusion.xml
+shhs1-200486-profusion.xml
+shhs1-200487-profusion.xml
+shhs1-200488-profusion.xml
+shhs1-200489-profusion.xml
+shhs1-200490-profusion.xml
+shhs1-200491-profusion.xml
+shhs1-200492-profusion.xml
+shhs1-200493-profusion.xml
+shhs1-200494-profusion.xml
+shhs1-200495-profusion.xml
+shhs1-200496-profusion.xml
+shhs1-200497-profusion.xml
+shhs1-200498-profusion.xml
+shhs1-200499-profusion.xml
+shhs1-200500-profusion.xml
+shhs1-200501-profusion.xml
+shhs1-200502-profusion.xml
+shhs1-200503-profusion.xml
+shhs1-200504-profusion.xml
+shhs1-200505-profusion.xml
+shhs1-200506-profusion.xml
+shhs1-200507-profusion.xml
+shhs1-200508-profusion.xml
+shhs1-200509-profusion.xml
+shhs1-200510-profusion.xml
+shhs1-200511-profusion.xml
+shhs1-200512-profusion.xml
+shhs1-200513-profusion.xml
+shhs1-200514-profusion.xml
+shhs1-200515-profusion.xml
+shhs1-200516-profusion.xml
+shhs1-200517-profusion.xml
+shhs1-200518-profusion.xml
+shhs1-200519-profusion.xml
+shhs1-200520-profusion.xml
+shhs1-200521-profusion.xml
+shhs1-200522-profusion.xml
+shhs1-200523-profusion.xml
+shhs1-200524-profusion.xml
+shhs1-200525-profusion.xml
+shhs1-200526-profusion.xml
+shhs1-200527-profusion.xml
+shhs1-200528-profusion.xml
+shhs1-200529-profusion.xml
+shhs1-200530-profusion.xml
+shhs1-200531-profusion.xml
+shhs1-200532-profusion.xml
+shhs1-200533-profusion.xml
+shhs1-200534-profusion.xml
+shhs1-200535-profusion.xml
+shhs1-200536-profusion.xml
+shhs1-200537-profusion.xml
+shhs1-200538-profusion.xml
+shhs1-200539-profusion.xml
+shhs1-200540-profusion.xml
+shhs1-200541-profusion.xml
+shhs1-200542-profusion.xml
+shhs1-200543-profusion.xml
+shhs1-200544-profusion.xml
+shhs1-200545-profusion.xml
+shhs1-200546-profusion.xml
+shhs1-200547-profusion.xml
+shhs1-200548-profusion.xml
+shhs1-200549-profusion.xml
+shhs1-200550-profusion.xml
+shhs1-200551-profusion.xml
+shhs1-200552-profusion.xml
+shhs1-200553-profusion.xml
+shhs1-200554-profusion.xml
+shhs1-200555-profusion.xml
+shhs1-200556-profusion.xml
+shhs1-200557-profusion.xml
+shhs1-200558-profusion.xml
+shhs1-200559-profusion.xml
+shhs1-200560-profusion.xml
+shhs1-200561-profusion.xml
+shhs1-200562-profusion.xml
+shhs1-200563-profusion.xml
+shhs1-200564-profusion.xml
+shhs1-200565-profusion.xml
+shhs1-200566-profusion.xml
+shhs1-200567-profusion.xml
+shhs1-200568-profusion.xml
+shhs1-200569-profusion.xml
+shhs1-200570-profusion.xml
+shhs1-200571-profusion.xml
+shhs1-200572-profusion.xml
+shhs1-200573-profusion.xml
+shhs1-200574-profusion.xml
+shhs1-200575-profusion.xml
+shhs1-200576-profusion.xml
+shhs1-200577-profusion.xml
+shhs1-200578-profusion.xml
+shhs1-200579-profusion.xml
+shhs1-200580-profusion.xml
+shhs1-200581-profusion.xml
+shhs1-200582-profusion.xml
+shhs1-200583-profusion.xml
+shhs1-200584-profusion.xml
+shhs1-200585-profusion.xml
+shhs1-200586-profusion.xml
+shhs1-200587-profusion.xml
+shhs1-200588-profusion.xml
+shhs1-200589-profusion.xml
+shhs1-200590-profusion.xml
+shhs1-200591-profusion.xml
+shhs1-200592-profusion.xml
+shhs1-200593-profusion.xml
+shhs1-200594-profusion.xml
+shhs1-200595-profusion.xml
+shhs1-200596-profusion.xml
+shhs1-200597-profusion.xml
+shhs1-200598-profusion.xml
+shhs1-200599-profusion.xml
+shhs1-200600-profusion.xml
+shhs1-200601-profusion.xml
+shhs1-200602-profusion.xml
+shhs1-200603-profusion.xml
+shhs1-200604-profusion.xml
+shhs1-200605-profusion.xml
+shhs1-200606-profusion.xml
+shhs1-200607-profusion.xml
+shhs1-200608-profusion.xml
+shhs1-200609-profusion.xml
+shhs1-200610-profusion.xml
+shhs1-200611-profusion.xml
+shhs1-200612-profusion.xml
+shhs1-200613-profusion.xml
+shhs1-200614-profusion.xml
+shhs1-200615-profusion.xml
+shhs1-200616-profusion.xml
+shhs1-200617-profusion.xml
+shhs1-200618-profusion.xml
+shhs1-200619-profusion.xml
+shhs1-200620-profusion.xml
+shhs1-200621-profusion.xml
+shhs1-200622-profusion.xml
+shhs1-200623-profusion.xml
+shhs1-200624-profusion.xml
+shhs1-200625-profusion.xml
+shhs1-200626-profusion.xml
+shhs1-200627-profusion.xml
+shhs1-200628-profusion.xml
+shhs1-200629-profusion.xml
+shhs1-200630-profusion.xml
+shhs1-200631-profusion.xml
+shhs1-200632-profusion.xml
+shhs1-200633-profusion.xml
+shhs1-200634-profusion.xml
+shhs1-200635-profusion.xml
+shhs1-200636-profusion.xml
+shhs1-200637-profusion.xml
+shhs1-200638-profusion.xml
+shhs1-200639-profusion.xml
+shhs1-200640-profusion.xml
+shhs1-200641-profusion.xml
+shhs1-200642-profusion.xml
+shhs1-200643-profusion.xml
+shhs1-200644-profusion.xml
+shhs1-200645-profusion.xml
+shhs1-200646-profusion.xml
+shhs1-200647-profusion.xml
+shhs1-200648-profusion.xml
+shhs1-200649-profusion.xml
+shhs1-200650-profusion.xml
+shhs1-200651-profusion.xml
+shhs1-200652-profusion.xml
+shhs1-200653-profusion.xml
+shhs1-200654-profusion.xml
+shhs1-200655-profusion.xml
+shhs1-200656-profusion.xml
+shhs1-200657-profusion.xml
+shhs1-200658-profusion.xml
+shhs1-200659-profusion.xml
+shhs1-200660-profusion.xml
+shhs1-200661-profusion.xml
+shhs1-200662-profusion.xml
+shhs1-200663-profusion.xml
+shhs1-200664-profusion.xml
+shhs1-200665-profusion.xml
+shhs1-200666-profusion.xml
+shhs1-200667-profusion.xml
+shhs1-200668-profusion.xml
+shhs1-200669-profusion.xml
+shhs1-200670-profusion.xml
+shhs1-200671-profusion.xml
+shhs1-200672-profusion.xml
+shhs1-200673-profusion.xml
+shhs1-200674-profusion.xml
+shhs1-200675-profusion.xml
+shhs1-200676-profusion.xml
+shhs1-200677-profusion.xml
+shhs1-200678-profusion.xml
+shhs1-200679-profusion.xml
+shhs1-200680-profusion.xml
+shhs1-200681-profusion.xml
+shhs1-200682-profusion.xml
+shhs1-200683-profusion.xml
+shhs1-200684-profusion.xml
+shhs1-200685-profusion.xml
+shhs1-200686-profusion.xml
+shhs1-200687-profusion.xml
+shhs1-200688-profusion.xml
+shhs1-200689-profusion.xml
+shhs1-200690-profusion.xml
+shhs1-200691-profusion.xml
+shhs1-200692-profusion.xml
+shhs1-200693-profusion.xml
+shhs1-200694-profusion.xml
+shhs1-200695-profusion.xml
+shhs1-200696-profusion.xml
+shhs1-200697-profusion.xml
+shhs1-200698-profusion.xml
+shhs1-200699-profusion.xml
+shhs1-200700-profusion.xml
+shhs1-200701-profusion.xml
+shhs1-200702-profusion.xml
+shhs1-200703-profusion.xml
+shhs1-200704-profusion.xml
+shhs1-200705-profusion.xml
+shhs1-200706-profusion.xml
+shhs1-200707-profusion.xml
+shhs1-200708-profusion.xml
+shhs1-200709-profusion.xml
+shhs1-200710-profusion.xml
+shhs1-200711-profusion.xml
+shhs1-200712-profusion.xml
+shhs1-200713-profusion.xml
+shhs1-200714-profusion.xml
+shhs1-200715-profusion.xml
+shhs1-200716-profusion.xml
+shhs1-200717-profusion.xml
+shhs1-200718-profusion.xml
+shhs1-200719-profusion.xml
+shhs1-200720-profusion.xml
+shhs1-200721-profusion.xml
+shhs1-200722-profusion.xml
+shhs1-200723-profusion.xml
+shhs1-200724-profusion.xml
+shhs1-200725-profusion.xml
+shhs1-200726-profusion.xml
+shhs1-200727-profusion.xml
+shhs1-200728-profusion.xml
+shhs1-200729-profusion.xml
+shhs1-200730-profusion.xml
+shhs1-200731-profusion.xml
+shhs1-200732-profusion.xml
+shhs1-200733-profusion.xml
+shhs1-200734-profusion.xml
+shhs1-200735-profusion.xml
+shhs1-200736-profusion.xml
+shhs1-200737-profusion.xml
+shhs1-200738-profusion.xml
+shhs1-200739-profusion.xml
+shhs1-200740-profusion.xml
+shhs1-200741-profusion.xml
+shhs1-200742-profusion.xml
+shhs1-200743-profusion.xml
+shhs1-200744-profusion.xml
+shhs1-200745-profusion.xml
+shhs1-200746-profusion.xml
+shhs1-200747-profusion.xml
+shhs1-200748-profusion.xml
+shhs1-200749-profusion.xml
+shhs1-200750-profusion.xml
+shhs1-200751-profusion.xml
+shhs1-200752-profusion.xml
+shhs1-200753-profusion.xml
+shhs1-200754-profusion.xml
+shhs1-200755-profusion.xml
+shhs1-200756-profusion.xml
+shhs1-200757-profusion.xml
+shhs1-200758-profusion.xml
+shhs1-200759-profusion.xml
+shhs1-200760-profusion.xml
+shhs1-200761-profusion.xml
+shhs1-200762-profusion.xml
+shhs1-200763-profusion.xml
+shhs1-200764-profusion.xml
+shhs1-200765-profusion.xml
+shhs1-200766-profusion.xml
+shhs1-200767-profusion.xml
+shhs1-200768-profusion.xml
+shhs1-200769-profusion.xml
+shhs1-200770-profusion.xml
+shhs1-200771-profusion.xml
+shhs1-200772-profusion.xml
+shhs1-200773-profusion.xml
+shhs1-200774-profusion.xml
+shhs1-200775-profusion.xml
+shhs1-200776-profusion.xml
+shhs1-200777-profusion.xml
+shhs1-200778-profusion.xml
+shhs1-200779-profusion.xml
+shhs1-200780-profusion.xml
+shhs1-200781-profusion.xml
+shhs1-200782-profusion.xml
+shhs1-200783-profusion.xml
+shhs1-200784-profusion.xml
+shhs1-200785-profusion.xml
+shhs1-200786-profusion.xml
+shhs1-200787-profusion.xml
+shhs1-200788-profusion.xml
+shhs1-200789-profusion.xml
+shhs1-200790-profusion.xml
+shhs1-200791-profusion.xml
+shhs1-200792-profusion.xml
+shhs1-200793-profusion.xml
+shhs1-200794-profusion.xml
+shhs1-200795-profusion.xml
+shhs1-200796-profusion.xml
+shhs1-200797-profusion.xml
+shhs1-200798-profusion.xml
+shhs1-200799-profusion.xml
+shhs1-200800-profusion.xml
+shhs1-200801-profusion.xml
+shhs1-200802-profusion.xml
+shhs1-200803-profusion.xml
+shhs1-200804-profusion.xml
+shhs1-200805-profusion.xml
+shhs1-200806-profusion.xml
+shhs1-200807-profusion.xml
+shhs1-200808-profusion.xml
+shhs1-200809-profusion.xml
+shhs1-200810-profusion.xml
+shhs1-200811-profusion.xml
+shhs1-200812-profusion.xml
+shhs1-200813-profusion.xml
+shhs1-200814-profusion.xml
+shhs1-200815-profusion.xml
+shhs1-200816-profusion.xml
+shhs1-200817-profusion.xml
+shhs1-200818-profusion.xml
+shhs1-200819-profusion.xml
+shhs1-200820-profusion.xml
+shhs1-200821-profusion.xml
+shhs1-200822-profusion.xml
+shhs1-200823-profusion.xml
+shhs1-200824-profusion.xml
+shhs1-200825-profusion.xml
+shhs1-200826-profusion.xml
+shhs1-200827-profusion.xml
+shhs1-200828-profusion.xml
+shhs1-200829-profusion.xml
+shhs1-200830-profusion.xml
+shhs1-200831-profusion.xml
+shhs1-200832-profusion.xml
+shhs1-200833-profusion.xml
+shhs1-200834-profusion.xml
+shhs1-200835-profusion.xml
+shhs1-200836-profusion.xml
+shhs1-200837-profusion.xml
+shhs1-200838-profusion.xml
+shhs1-200839-profusion.xml
+shhs1-200840-profusion.xml
+shhs1-200841-profusion.xml
+shhs1-200842-profusion.xml
+shhs1-200843-profusion.xml
+shhs1-200844-profusion.xml
+shhs1-200845-profusion.xml
+shhs1-200846-profusion.xml
+shhs1-200847-profusion.xml
+shhs1-200848-profusion.xml
+shhs1-200849-profusion.xml
+shhs1-200850-profusion.xml
+shhs1-200851-profusion.xml
+shhs1-200852-profusion.xml
+shhs1-200853-profusion.xml
+shhs1-200854-profusion.xml
+shhs1-200855-profusion.xml
+shhs1-200856-profusion.xml
+shhs1-200857-profusion.xml
+shhs1-200858-profusion.xml
+shhs1-200859-profusion.xml
+shhs1-200860-profusion.xml
+shhs1-200861-profusion.xml
+shhs1-200862-profusion.xml
+shhs1-200863-profusion.xml
+shhs1-200864-profusion.xml
+shhs1-200865-profusion.xml
+shhs1-200866-profusion.xml
+shhs1-200867-profusion.xml
+shhs1-200868-profusion.xml
+shhs1-200869-profusion.xml
+shhs1-200870-profusion.xml
+shhs1-200871-profusion.xml
+shhs1-200872-profusion.xml
+shhs1-200873-profusion.xml
+shhs1-200874-profusion.xml
+shhs1-200875-profusion.xml
+shhs1-200876-profusion.xml
+shhs1-200877-profusion.xml
+shhs1-200878-profusion.xml
+shhs1-200879-profusion.xml
+shhs1-200880-profusion.xml
+shhs1-200881-profusion.xml
+shhs1-200882-profusion.xml
+shhs1-200883-profusion.xml
+shhs1-200884-profusion.xml
+shhs1-200885-profusion.xml
+shhs1-200886-profusion.xml
+shhs1-200887-profusion.xml
+shhs1-200888-profusion.xml
+shhs1-200889-profusion.xml
+shhs1-200890-profusion.xml
+shhs1-200891-profusion.xml
+shhs1-200892-profusion.xml
+shhs1-200893-profusion.xml
+shhs1-200894-profusion.xml
+shhs1-200895-profusion.xml
+shhs1-200896-profusion.xml
+shhs1-200897-profusion.xml
+shhs1-200898-profusion.xml
+shhs1-200899-profusion.xml
+shhs1-200900-profusion.xml
+shhs1-200901-profusion.xml
+shhs1-200902-profusion.xml
+shhs1-200903-profusion.xml
+shhs1-200904-profusion.xml
+shhs1-200905-profusion.xml
+shhs1-200906-profusion.xml
+shhs1-200907-profusion.xml
+shhs1-200908-profusion.xml
+shhs1-200909-profusion.xml
+shhs1-200910-profusion.xml
+shhs1-200911-profusion.xml
+shhs1-200912-profusion.xml
+shhs1-200913-profusion.xml
+shhs1-200914-profusion.xml
+shhs1-200915-profusion.xml
+shhs1-200916-profusion.xml
+shhs1-200917-profusion.xml
+shhs1-200918-profusion.xml
+shhs1-200919-profusion.xml
+shhs1-200920-profusion.xml
+shhs1-200921-profusion.xml
+shhs1-200922-profusion.xml
+shhs1-200923-profusion.xml
+shhs1-200924-profusion.xml
+shhs1-200925-profusion.xml
+shhs1-200926-profusion.xml
+shhs1-200927-profusion.xml
+shhs1-200928-profusion.xml
+shhs1-200929-profusion.xml
+shhs1-200930-profusion.xml
+shhs1-200931-profusion.xml
+shhs1-200932-profusion.xml
+shhs1-200933-profusion.xml
+shhs1-200934-profusion.xml
+shhs1-200935-profusion.xml
+shhs1-200936-profusion.xml
+shhs1-200937-profusion.xml
+shhs1-200938-profusion.xml
+shhs1-200939-profusion.xml
+shhs1-200940-profusion.xml
+shhs1-200941-profusion.xml
+shhs1-200942-profusion.xml
+shhs1-200943-profusion.xml
+shhs1-200944-profusion.xml
+shhs1-200945-profusion.xml
+shhs1-200946-profusion.xml
+shhs1-200947-profusion.xml
+shhs1-200948-profusion.xml
+shhs1-200949-profusion.xml
+shhs1-200950-profusion.xml
+shhs1-200951-profusion.xml
+shhs1-200952-profusion.xml
+shhs1-200953-profusion.xml
+shhs1-200954-profusion.xml
+shhs1-200955-profusion.xml
+shhs1-200956-profusion.xml
+shhs1-200957-profusion.xml
+shhs1-200958-profusion.xml
+shhs1-200959-profusion.xml
+shhs1-200960-profusion.xml
+shhs1-200961-profusion.xml
+shhs1-200962-profusion.xml
+shhs1-200963-profusion.xml
+shhs1-200964-profusion.xml
+shhs1-200965-profusion.xml
+shhs1-200966-profusion.xml
+shhs1-200967-profusion.xml
+shhs1-200968-profusion.xml
+shhs1-200969-profusion.xml
+shhs1-200970-profusion.xml
+shhs1-200971-profusion.xml
+shhs1-200972-profusion.xml
+shhs1-200973-profusion.xml
+shhs1-200974-profusion.xml
+shhs1-200975-profusion.xml
+shhs1-200976-profusion.xml
+shhs1-200977-profusion.xml
+shhs1-200978-profusion.xml
+shhs1-200979-profusion.xml
+shhs1-200980-profusion.xml
+shhs1-200981-profusion.xml
+shhs1-200982-profusion.xml
+shhs1-200983-profusion.xml
+shhs1-200984-profusion.xml
+shhs1-200985-profusion.xml
+shhs1-200986-profusion.xml
+shhs1-200987-profusion.xml
+shhs1-200988-profusion.xml
+shhs1-200989-profusion.xml
+shhs1-200990-profusion.xml
+shhs1-200991-profusion.xml
+shhs1-200992-profusion.xml
+shhs1-200993-profusion.xml
+shhs1-200994-profusion.xml
+shhs1-200995-profusion.xml
+shhs1-200996-profusion.xml
+shhs1-200997-profusion.xml
+shhs1-200998-profusion.xml
+shhs1-200999-profusion.xml
+shhs1-201000-profusion.xml
+shhs1-201001-profusion.xml
+shhs1-201002-profusion.xml
+shhs1-201003-profusion.xml
+shhs1-201004-profusion.xml
+shhs1-201005-profusion.xml
+shhs1-201006-profusion.xml
+shhs1-201007-profusion.xml
+shhs1-201008-profusion.xml
+shhs1-201009-profusion.xml
+shhs1-201010-profusion.xml
+shhs1-201011-profusion.xml
+shhs1-201012-profusion.xml
+shhs1-201013-profusion.xml
+shhs1-201014-profusion.xml
+shhs1-201015-profusion.xml
+shhs1-201016-profusion.xml
+shhs1-201017-profusion.xml
+shhs1-201018-profusion.xml
+shhs1-201019-profusion.xml
+shhs1-201020-profusion.xml
+shhs1-201021-profusion.xml
+shhs1-201022-profusion.xml
+shhs1-201023-profusion.xml
+shhs1-201024-profusion.xml
+shhs1-201025-profusion.xml
+shhs1-201026-profusion.xml
+shhs1-201027-profusion.xml
+shhs1-201028-profusion.xml
+shhs1-201029-profusion.xml
+shhs1-201030-profusion.xml
+shhs1-201031-profusion.xml
+shhs1-201032-profusion.xml
+shhs1-201033-profusion.xml
+shhs1-201034-profusion.xml
+shhs1-201035-profusion.xml
+shhs1-201036-profusion.xml
+shhs1-201037-profusion.xml
+shhs1-201038-profusion.xml
+shhs1-201039-profusion.xml
+shhs1-201040-profusion.xml
+shhs1-201041-profusion.xml
+shhs1-201042-profusion.xml
+shhs1-201043-profusion.xml
+shhs1-201044-profusion.xml
+shhs1-201045-profusion.xml
+shhs1-201046-profusion.xml
+shhs1-201047-profusion.xml
+shhs1-201048-profusion.xml
+shhs1-201049-profusion.xml
+shhs1-201050-profusion.xml
+shhs1-201051-profusion.xml
+shhs1-201052-profusion.xml
+shhs1-201053-profusion.xml
+shhs1-201054-profusion.xml
+shhs1-201055-profusion.xml
+shhs1-201056-profusion.xml
+shhs1-201057-profusion.xml
+shhs1-201058-profusion.xml
+shhs1-201059-profusion.xml
+shhs1-201060-profusion.xml
+shhs1-201061-profusion.xml
+shhs1-201062-profusion.xml
+shhs1-201063-profusion.xml
+shhs1-201064-profusion.xml
+shhs1-201065-profusion.xml
+shhs1-201066-profusion.xml
+shhs1-201067-profusion.xml
+shhs1-201068-profusion.xml
+shhs1-201069-profusion.xml
+shhs1-201070-profusion.xml
+shhs1-201071-profusion.xml
+shhs1-201072-profusion.xml
+shhs1-201073-profusion.xml
+shhs1-201074-profusion.xml
+shhs1-201075-profusion.xml
+shhs1-201076-profusion.xml
+shhs1-201077-profusion.xml
+shhs1-201078-profusion.xml
+shhs1-201079-profusion.xml
+shhs1-201080-profusion.xml
+shhs1-201081-profusion.xml
+shhs1-201082-profusion.xml
+shhs1-201083-profusion.xml
+shhs1-201084-profusion.xml
+shhs1-201085-profusion.xml
+shhs1-201086-profusion.xml
+shhs1-201087-profusion.xml
+shhs1-201088-profusion.xml
+shhs1-201089-profusion.xml
+shhs1-201090-profusion.xml
+shhs1-201091-profusion.xml
+shhs1-201092-profusion.xml
+shhs1-201093-profusion.xml
+shhs1-201094-profusion.xml
+shhs1-201095-profusion.xml
+shhs1-201096-profusion.xml
+shhs1-201097-profusion.xml
+shhs1-201098-profusion.xml
+shhs1-201099-profusion.xml
+shhs1-201100-profusion.xml
+shhs1-201101-profusion.xml
+shhs1-201102-profusion.xml
+shhs1-201103-profusion.xml
+shhs1-201104-profusion.xml
+shhs1-201105-profusion.xml
+shhs1-201106-profusion.xml
+shhs1-201107-profusion.xml
+shhs1-201108-profusion.xml
+shhs1-201109-profusion.xml
+shhs1-201110-profusion.xml
+shhs1-201111-profusion.xml
+shhs1-201112-profusion.xml
+shhs1-201113-profusion.xml
+shhs1-201114-profusion.xml
+shhs1-201116-profusion.xml
+shhs1-201117-profusion.xml
+shhs1-201118-profusion.xml
+shhs1-201119-profusion.xml
+shhs1-201120-profusion.xml
+shhs1-201121-profusion.xml
+shhs1-201122-profusion.xml
+shhs1-201123-profusion.xml
+shhs1-201124-profusion.xml
+shhs1-201125-profusion.xml
+shhs1-201126-profusion.xml
+shhs1-201127-profusion.xml
+shhs1-201128-profusion.xml
+shhs1-201129-profusion.xml
+shhs1-201130-profusion.xml
+shhs1-201131-profusion.xml
+shhs1-201132-profusion.xml
+shhs1-201133-profusion.xml
+shhs1-201134-profusion.xml
+shhs1-201135-profusion.xml
+shhs1-201136-profusion.xml
+shhs1-201137-profusion.xml
+shhs1-201138-profusion.xml
+shhs1-201139-profusion.xml
+shhs1-201140-profusion.xml
+shhs1-201141-profusion.xml
+shhs1-201142-profusion.xml
+shhs1-201143-profusion.xml
+shhs1-201144-profusion.xml
+shhs1-201145-profusion.xml
+shhs1-201146-profusion.xml
+shhs1-201147-profusion.xml
+shhs1-201148-profusion.xml
+shhs1-201149-profusion.xml
+shhs1-201150-profusion.xml
+shhs1-201151-profusion.xml
+shhs1-201152-profusion.xml
+shhs1-201153-profusion.xml
+shhs1-201154-profusion.xml
+shhs1-201155-profusion.xml
+shhs1-201156-profusion.xml
+shhs1-201157-profusion.xml
+shhs1-201158-profusion.xml
+shhs1-201159-profusion.xml
+shhs1-201160-profusion.xml
+shhs1-201161-profusion.xml
+shhs1-201162-profusion.xml
+shhs1-201163-profusion.xml
+shhs1-201164-profusion.xml
+shhs1-201165-profusion.xml
+shhs1-201166-profusion.xml
+shhs1-201167-profusion.xml
+shhs1-201168-profusion.xml
+shhs1-201169-profusion.xml
+shhs1-201170-profusion.xml
+shhs1-201171-profusion.xml
+shhs1-201172-profusion.xml
+shhs1-201173-profusion.xml
+shhs1-201174-profusion.xml
+shhs1-201175-profusion.xml
+shhs1-201176-profusion.xml
+shhs1-201177-profusion.xml
+shhs1-201178-profusion.xml
+shhs1-201179-profusion.xml
+shhs1-201180-profusion.xml
+shhs1-201181-profusion.xml
+shhs1-201182-profusion.xml
+shhs1-201183-profusion.xml
+shhs1-201184-profusion.xml
+shhs1-201185-profusion.xml
+shhs1-201186-profusion.xml
+shhs1-201187-profusion.xml
+shhs1-201188-profusion.xml
+shhs1-201189-profusion.xml
+shhs1-201190-profusion.xml
+shhs1-201191-profusion.xml
+shhs1-201192-profusion.xml
+shhs1-201193-profusion.xml
+shhs1-201194-profusion.xml
+shhs1-201195-profusion.xml
+shhs1-201196-profusion.xml
+shhs1-201197-profusion.xml
+shhs1-201198-profusion.xml
+shhs1-201199-profusion.xml
+shhs1-201200-profusion.xml
+shhs1-201201-profusion.xml
+shhs1-201202-profusion.xml
+shhs1-201203-profusion.xml
+shhs1-201204-profusion.xml
+shhs1-201205-profusion.xml
+shhs1-201206-profusion.xml
+shhs1-201207-profusion.xml
+shhs1-201208-profusion.xml
+shhs1-201209-profusion.xml
+shhs1-201210-profusion.xml
+shhs1-201211-profusion.xml
+shhs1-201212-profusion.xml
+shhs1-201213-profusion.xml
+shhs1-201214-profusion.xml
+shhs1-201215-profusion.xml
+shhs1-201216-profusion.xml
+shhs1-201217-profusion.xml
+shhs1-201218-profusion.xml
+shhs1-201219-profusion.xml
+shhs1-201220-profusion.xml
+shhs1-201221-profusion.xml
+shhs1-201222-profusion.xml
+shhs1-201223-profusion.xml
+shhs1-201224-profusion.xml
+shhs1-201225-profusion.xml
+shhs1-201226-profusion.xml
+shhs1-201227-profusion.xml
+shhs1-201228-profusion.xml
+shhs1-201229-profusion.xml
+shhs1-201230-profusion.xml
+shhs1-201231-profusion.xml
+shhs1-201232-profusion.xml
+shhs1-201233-profusion.xml
+shhs1-201234-profusion.xml
+shhs1-201235-profusion.xml
+shhs1-201236-profusion.xml
+shhs1-201237-profusion.xml
+shhs1-201238-profusion.xml
+shhs1-201239-profusion.xml
+shhs1-201240-profusion.xml
+shhs1-201241-profusion.xml
+shhs1-201242-profusion.xml
+shhs1-201243-profusion.xml
+shhs1-201244-profusion.xml
+shhs1-201245-profusion.xml
+shhs1-201246-profusion.xml
+shhs1-201247-profusion.xml
+shhs1-201248-profusion.xml
+shhs1-201249-profusion.xml
+shhs1-201250-profusion.xml
+shhs1-201251-profusion.xml
+shhs1-201252-profusion.xml
+shhs1-201253-profusion.xml
+shhs1-201254-profusion.xml
+shhs1-201255-profusion.xml
+shhs1-201256-profusion.xml
+shhs1-201257-profusion.xml
+shhs1-201258-profusion.xml
+shhs1-201259-profusion.xml
+shhs1-201260-profusion.xml
+shhs1-201261-profusion.xml
+shhs1-201262-profusion.xml
+shhs1-201263-profusion.xml
+shhs1-201264-profusion.xml
+shhs1-201265-profusion.xml
+shhs1-201266-profusion.xml
+shhs1-201267-profusion.xml
+shhs1-201268-profusion.xml
+shhs1-201269-profusion.xml
+shhs1-201270-profusion.xml
+shhs1-201271-profusion.xml
+shhs1-201272-profusion.xml
+shhs1-201273-profusion.xml
+shhs1-201274-profusion.xml
+shhs1-201275-profusion.xml
+shhs1-201276-profusion.xml
+shhs1-201277-profusion.xml
+shhs1-201278-profusion.xml
+shhs1-201279-profusion.xml
+shhs1-201280-profusion.xml
+shhs1-201281-profusion.xml
+shhs1-201282-profusion.xml
+shhs1-201283-profusion.xml
+shhs1-201284-profusion.xml
+shhs1-201285-profusion.xml
+shhs1-201286-profusion.xml
+shhs1-201287-profusion.xml
+shhs1-201288-profusion.xml
+shhs1-201289-profusion.xml
+shhs1-201290-profusion.xml
+shhs1-201291-profusion.xml
+shhs1-201292-profusion.xml
+shhs1-201293-profusion.xml
+shhs1-201294-profusion.xml
+shhs1-201295-profusion.xml
+shhs1-201296-profusion.xml
+shhs1-201297-profusion.xml
+shhs1-201298-profusion.xml
+shhs1-201299-profusion.xml
+shhs1-201300-profusion.xml
+shhs1-201301-profusion.xml
+shhs1-201302-profusion.xml
+shhs1-201303-profusion.xml
+shhs1-201304-profusion.xml
+shhs1-201305-profusion.xml
+shhs1-201306-profusion.xml
+shhs1-201307-profusion.xml
+shhs1-201308-profusion.xml
+shhs1-201309-profusion.xml
+shhs1-201310-profusion.xml
+shhs1-201311-profusion.xml
+shhs1-201312-profusion.xml
+shhs1-201313-profusion.xml
+shhs1-201314-profusion.xml
+shhs1-201315-profusion.xml
+shhs1-201316-profusion.xml
+shhs1-201317-profusion.xml
+shhs1-201318-profusion.xml
+shhs1-201319-profusion.xml
+shhs1-201320-profusion.xml
+shhs1-201321-profusion.xml
+shhs1-201322-profusion.xml
+shhs1-201323-profusion.xml
+shhs1-201324-profusion.xml
+shhs1-201325-profusion.xml
+shhs1-201326-profusion.xml
+shhs1-201327-profusion.xml
+shhs1-201328-profusion.xml
+shhs1-201329-profusion.xml
+shhs1-201330-profusion.xml
+shhs1-201331-profusion.xml
+shhs1-201332-profusion.xml
+shhs1-201333-profusion.xml
+shhs1-201334-profusion.xml
+shhs1-201335-profusion.xml
+shhs1-201336-profusion.xml
+shhs1-201337-profusion.xml
+shhs1-201338-profusion.xml
+shhs1-201339-profusion.xml
+shhs1-201340-profusion.xml
+shhs1-201341-profusion.xml
+shhs1-201342-profusion.xml
+shhs1-201343-profusion.xml
+shhs1-201344-profusion.xml
+shhs1-201345-profusion.xml
+shhs1-201346-profusion.xml
+shhs1-201347-profusion.xml
+shhs1-201348-profusion.xml
+shhs1-201349-profusion.xml
+shhs1-201350-profusion.xml
+shhs1-201351-profusion.xml
+shhs1-201352-profusion.xml
+shhs1-201353-profusion.xml
+shhs1-201354-profusion.xml
+shhs1-201355-profusion.xml
+shhs1-201356-profusion.xml
+shhs1-201357-profusion.xml
+shhs1-201358-profusion.xml
+shhs1-201359-profusion.xml
+shhs1-201360-profusion.xml
+shhs1-201361-profusion.xml
+shhs1-201362-profusion.xml
+shhs1-201363-profusion.xml
+shhs1-201364-profusion.xml
+shhs1-201365-profusion.xml
+shhs1-201366-profusion.xml
+shhs1-201367-profusion.xml
+shhs1-201368-profusion.xml
+shhs1-201369-profusion.xml
+shhs1-201370-profusion.xml
+shhs1-201371-profusion.xml
+shhs1-201372-profusion.xml
+shhs1-201373-profusion.xml
+shhs1-201374-profusion.xml
+shhs1-201375-profusion.xml
+shhs1-201376-profusion.xml
+shhs1-201377-profusion.xml
+shhs1-201378-profusion.xml
+shhs1-201379-profusion.xml
+shhs1-201380-profusion.xml
+shhs1-201381-profusion.xml
+shhs1-201382-profusion.xml
+shhs1-201383-profusion.xml
+shhs1-201384-profusion.xml
+shhs1-201385-profusion.xml
+shhs1-201386-profusion.xml
+shhs1-201387-profusion.xml
+shhs1-201388-profusion.xml
+shhs1-201389-profusion.xml
+shhs1-201390-profusion.xml
+shhs1-201391-profusion.xml
+shhs1-201392-profusion.xml
+shhs1-201393-profusion.xml
+shhs1-201394-profusion.xml
+shhs1-201395-profusion.xml
+shhs1-201396-profusion.xml
+shhs1-201397-profusion.xml
+shhs1-201398-profusion.xml
+shhs1-201399-profusion.xml
+shhs1-201400-profusion.xml
+shhs1-201401-profusion.xml
+shhs1-201402-profusion.xml
+shhs1-201403-profusion.xml
+shhs1-201404-profusion.xml
+shhs1-201405-profusion.xml
+shhs1-201406-profusion.xml
+shhs1-201407-profusion.xml
+shhs1-201408-profusion.xml
+shhs1-201409-profusion.xml
+shhs1-201410-profusion.xml
+shhs1-201411-profusion.xml
+shhs1-201412-profusion.xml
+shhs1-201413-profusion.xml
+shhs1-201414-profusion.xml
+shhs1-201415-profusion.xml
+shhs1-201416-profusion.xml
+shhs1-201417-profusion.xml
+shhs1-201418-profusion.xml
+shhs1-201419-profusion.xml
+shhs1-201420-profusion.xml
+shhs1-201421-profusion.xml
+shhs1-201422-profusion.xml
+shhs1-201423-profusion.xml
+shhs1-201424-profusion.xml
+shhs1-201425-profusion.xml
+shhs1-201426-profusion.xml
+shhs1-201427-profusion.xml
+shhs1-201428-profusion.xml
+shhs1-201429-profusion.xml
+shhs1-201430-profusion.xml
+shhs1-201431-profusion.xml
+shhs1-201432-profusion.xml
+shhs1-201433-profusion.xml
+shhs1-201434-profusion.xml
+shhs1-201435-profusion.xml
+shhs1-201436-profusion.xml
+shhs1-201437-profusion.xml
+shhs1-201438-profusion.xml
+shhs1-201439-profusion.xml
+shhs1-201440-profusion.xml
+shhs1-201441-profusion.xml
+shhs1-201442-profusion.xml
+shhs1-201443-profusion.xml
+shhs1-201444-profusion.xml
+shhs1-201445-profusion.xml
+shhs1-201446-profusion.xml
+shhs1-201447-profusion.xml
+shhs1-201448-profusion.xml
+shhs1-201449-profusion.xml
+shhs1-201450-profusion.xml
+shhs1-201451-profusion.xml
+shhs1-201452-profusion.xml
+shhs1-201453-profusion.xml
+shhs1-201454-profusion.xml
+shhs1-201455-profusion.xml
+shhs1-201456-profusion.xml
+shhs1-201457-profusion.xml
+shhs1-201458-profusion.xml
+shhs1-201459-profusion.xml
+shhs1-201460-profusion.xml
+shhs1-201461-profusion.xml
+shhs1-201462-profusion.xml
+shhs1-201463-profusion.xml
+shhs1-201464-profusion.xml
+shhs1-201465-profusion.xml
+shhs1-201466-profusion.xml
+shhs1-201467-profusion.xml
+shhs1-201468-profusion.xml
+shhs1-201469-profusion.xml
+shhs1-201470-profusion.xml
+shhs1-201471-profusion.xml
+shhs1-201472-profusion.xml
+shhs1-201473-profusion.xml
+shhs1-201474-profusion.xml
+shhs1-201475-profusion.xml
+shhs1-201476-profusion.xml
+shhs1-201477-profusion.xml
+shhs1-201478-profusion.xml
+shhs1-201479-profusion.xml
+shhs1-201480-profusion.xml
+shhs1-201481-profusion.xml
+shhs1-201482-profusion.xml
+shhs1-201483-profusion.xml
+shhs1-201484-profusion.xml
+shhs1-201485-profusion.xml
+shhs1-201486-profusion.xml
+shhs1-201487-profusion.xml
+shhs1-201488-profusion.xml
+shhs1-201489-profusion.xml
+shhs1-201490-profusion.xml
+shhs1-201491-profusion.xml
+shhs1-201492-profusion.xml
+shhs1-201493-profusion.xml
+shhs1-201494-profusion.xml
+shhs1-201495-profusion.xml
+shhs1-201496-profusion.xml
+shhs1-201497-profusion.xml
+shhs1-201498-profusion.xml
+shhs1-201499-profusion.xml
+shhs1-201500-profusion.xml
+shhs1-201501-profusion.xml
+shhs1-201502-profusion.xml
+shhs1-201503-profusion.xml
+shhs1-201504-profusion.xml
+shhs1-201505-profusion.xml
+shhs1-201506-profusion.xml
+shhs1-201507-profusion.xml
+shhs1-201508-profusion.xml
+shhs1-201509-profusion.xml
+shhs1-201510-profusion.xml
+shhs1-201511-profusion.xml
+shhs1-201512-profusion.xml
+shhs1-201513-profusion.xml
+shhs1-201514-profusion.xml
+shhs1-201515-profusion.xml
+shhs1-201516-profusion.xml
+shhs1-201517-profusion.xml
+shhs1-201518-profusion.xml
+shhs1-201519-profusion.xml
+shhs1-201520-profusion.xml
+shhs1-201521-profusion.xml
+shhs1-201522-profusion.xml
+shhs1-201523-profusion.xml
+shhs1-201524-profusion.xml
+shhs1-201525-profusion.xml
+shhs1-201526-profusion.xml
+shhs1-201527-profusion.xml
+shhs1-201528-profusion.xml
+shhs1-201529-profusion.xml
+shhs1-201530-profusion.xml
+shhs1-201531-profusion.xml
+shhs1-201532-profusion.xml
+shhs1-201533-profusion.xml
+shhs1-201534-profusion.xml
+shhs1-201535-profusion.xml
+shhs1-201536-profusion.xml
+shhs1-201537-profusion.xml
+shhs1-201538-profusion.xml
+shhs1-201539-profusion.xml
+shhs1-201540-profusion.xml
+shhs1-201541-profusion.xml
+shhs1-201542-profusion.xml
+shhs1-201543-profusion.xml
+shhs1-201544-profusion.xml
+shhs1-201545-profusion.xml
+shhs1-201546-profusion.xml
+shhs1-201547-profusion.xml
+shhs1-201548-profusion.xml
+shhs1-201549-profusion.xml
+shhs1-201550-profusion.xml
+shhs1-201551-profusion.xml
+shhs1-201552-profusion.xml
+shhs1-201553-profusion.xml
+shhs1-201554-profusion.xml
+shhs1-201555-profusion.xml
+shhs1-201556-profusion.xml
+shhs1-201557-profusion.xml
+shhs1-201558-profusion.xml
+shhs1-201559-profusion.xml
+shhs1-201560-profusion.xml
+shhs1-201561-profusion.xml
+shhs1-201562-profusion.xml
+shhs1-201563-profusion.xml
+shhs1-201564-profusion.xml
+shhs1-201565-profusion.xml
+shhs1-201566-profusion.xml
+shhs1-201567-profusion.xml
+shhs1-201568-profusion.xml
+shhs1-201569-profusion.xml
+shhs1-201570-profusion.xml
+shhs1-201571-profusion.xml
+shhs1-201572-profusion.xml
+shhs1-201573-profusion.xml
+shhs1-201574-profusion.xml
+shhs1-201575-profusion.xml
+shhs1-201576-profusion.xml
+shhs1-201577-profusion.xml
+shhs1-201578-profusion.xml
+shhs1-201579-profusion.xml
+shhs1-201580-profusion.xml
+shhs1-201581-profusion.xml
+shhs1-201582-profusion.xml
+shhs1-201583-profusion.xml
+shhs1-201584-profusion.xml
+shhs1-201585-profusion.xml
+shhs1-201586-profusion.xml
+shhs1-201587-profusion.xml
+shhs1-201588-profusion.xml
+shhs1-201589-profusion.xml
+shhs1-201590-profusion.xml
+shhs1-201591-profusion.xml
+shhs1-201592-profusion.xml
+shhs1-201593-profusion.xml
+shhs1-201594-profusion.xml
+shhs1-201595-profusion.xml
+shhs1-201596-profusion.xml
+shhs1-201597-profusion.xml
+shhs1-201598-profusion.xml
+shhs1-201599-profusion.xml
+shhs1-201600-profusion.xml
+shhs1-201601-profusion.xml
+shhs1-201602-profusion.xml
+shhs1-201603-profusion.xml
+shhs1-201604-profusion.xml
+shhs1-201605-profusion.xml
+shhs1-201606-profusion.xml
+shhs1-201607-profusion.xml
+shhs1-201608-profusion.xml
+shhs1-201609-profusion.xml
+shhs1-201610-profusion.xml
+shhs1-201611-profusion.xml
+shhs1-201612-profusion.xml
+shhs1-201613-profusion.xml
+shhs1-201614-profusion.xml
+shhs1-201615-profusion.xml
+shhs1-201616-profusion.xml
+shhs1-201617-profusion.xml
+shhs1-201618-profusion.xml
+shhs1-201619-profusion.xml
+shhs1-201620-profusion.xml
+shhs1-201621-profusion.xml
+shhs1-201622-profusion.xml
+shhs1-201623-profusion.xml
+shhs1-201624-profusion.xml
+shhs1-201625-profusion.xml
+shhs1-201626-profusion.xml
+shhs1-201627-profusion.xml
+shhs1-201628-profusion.xml
+shhs1-201629-profusion.xml
+shhs1-201630-profusion.xml
+shhs1-201631-profusion.xml
+shhs1-201632-profusion.xml
+shhs1-201633-profusion.xml
+shhs1-201634-profusion.xml
+shhs1-201635-profusion.xml
+shhs1-201636-profusion.xml
+shhs1-201637-profusion.xml
+shhs1-201638-profusion.xml
+shhs1-201639-profusion.xml
+shhs1-201640-profusion.xml
+shhs1-201641-profusion.xml
+shhs1-201642-profusion.xml
+shhs1-201643-profusion.xml
+shhs1-201644-profusion.xml
+shhs1-201645-profusion.xml
+shhs1-201646-profusion.xml
+shhs1-201647-profusion.xml
+shhs1-201648-profusion.xml
+shhs1-201649-profusion.xml
+shhs1-201650-profusion.xml
+shhs1-201651-profusion.xml
+shhs1-201652-profusion.xml
+shhs1-201653-profusion.xml
+shhs1-201654-profusion.xml
+shhs1-201655-profusion.xml
+shhs1-201656-profusion.xml
+shhs1-201657-profusion.xml
+shhs1-201658-profusion.xml
+shhs1-201659-profusion.xml
+shhs1-201660-profusion.xml
+shhs1-201661-profusion.xml
+shhs1-201662-profusion.xml
+shhs1-201663-profusion.xml
+shhs1-201664-profusion.xml
+shhs1-201665-profusion.xml
+shhs1-201666-profusion.xml
+shhs1-201667-profusion.xml
+shhs1-201668-profusion.xml
+shhs1-201670-profusion.xml
+shhs1-201671-profusion.xml
+shhs1-201672-profusion.xml
+shhs1-201673-profusion.xml
+shhs1-201674-profusion.xml
+shhs1-201675-profusion.xml
+shhs1-201676-profusion.xml
+shhs1-201677-profusion.xml
+shhs1-201678-profusion.xml
+shhs1-201679-profusion.xml
+shhs1-201680-profusion.xml
+shhs1-201681-profusion.xml
+shhs1-201682-profusion.xml
+shhs1-201683-profusion.xml
+shhs1-201684-profusion.xml
+shhs1-201685-profusion.xml
+shhs1-201686-profusion.xml
+shhs1-201687-profusion.xml
+shhs1-201688-profusion.xml
+shhs1-201689-profusion.xml
+shhs1-201690-profusion.xml
+shhs1-201691-profusion.xml
+shhs1-201692-profusion.xml
+shhs1-201693-profusion.xml
+shhs1-201694-profusion.xml
+shhs1-201695-profusion.xml
+shhs1-201696-profusion.xml
+shhs1-201697-profusion.xml
+shhs1-201698-profusion.xml
+shhs1-201699-profusion.xml
+shhs1-201700-profusion.xml
+shhs1-201701-profusion.xml
+shhs1-201702-profusion.xml
+shhs1-201703-profusion.xml
+shhs1-201704-profusion.xml
+shhs1-201705-profusion.xml
+shhs1-201706-profusion.xml
+shhs1-201707-profusion.xml
+shhs1-201708-profusion.xml
+shhs1-201709-profusion.xml
+shhs1-201710-profusion.xml
+shhs1-201711-profusion.xml
+shhs1-201712-profusion.xml
+shhs1-201713-profusion.xml
+shhs1-201714-profusion.xml
+shhs1-201715-profusion.xml
+shhs1-201716-profusion.xml
+shhs1-201717-profusion.xml
+shhs1-201718-profusion.xml
+shhs1-201719-profusion.xml
+shhs1-201720-profusion.xml
+shhs1-201721-profusion.xml
+shhs1-201722-profusion.xml
+shhs1-201723-profusion.xml
+shhs1-201724-profusion.xml
+shhs1-201725-profusion.xml
+shhs1-201726-profusion.xml
+shhs1-201727-profusion.xml
+shhs1-201728-profusion.xml
+shhs1-201729-profusion.xml
+shhs1-201730-profusion.xml
+shhs1-201731-profusion.xml
+shhs1-201732-profusion.xml
+shhs1-201733-profusion.xml
+shhs1-201734-profusion.xml
+shhs1-201735-profusion.xml
+shhs1-201736-profusion.xml
+shhs1-201737-profusion.xml
+shhs1-201738-profusion.xml
+shhs1-201739-profusion.xml
+shhs1-201740-profusion.xml
+shhs1-201741-profusion.xml
+shhs1-201742-profusion.xml
+shhs1-201743-profusion.xml
+shhs1-201744-profusion.xml
+shhs1-201745-profusion.xml
+shhs1-201746-profusion.xml
+shhs1-201747-profusion.xml
+shhs1-201748-profusion.xml
+shhs1-201749-profusion.xml
+shhs1-201750-profusion.xml
+shhs1-201751-profusion.xml
+shhs1-201752-profusion.xml
+shhs1-201753-profusion.xml
+shhs1-201754-profusion.xml
+shhs1-201755-profusion.xml
+shhs1-201756-profusion.xml
+shhs1-201757-profusion.xml
+shhs1-201758-profusion.xml
+shhs1-201759-profusion.xml
+shhs1-201760-profusion.xml
+shhs1-201761-profusion.xml
+shhs1-201762-profusion.xml
+shhs1-201763-profusion.xml
+shhs1-201764-profusion.xml
+shhs1-201765-profusion.xml
+shhs1-201766-profusion.xml
+shhs1-201767-profusion.xml
+shhs1-201768-profusion.xml
+shhs1-201769-profusion.xml
+shhs1-201770-profusion.xml
+shhs1-201771-profusion.xml
+shhs1-201772-profusion.xml
+shhs1-201773-profusion.xml
+shhs1-201774-profusion.xml
+shhs1-201775-profusion.xml
+shhs1-201776-profusion.xml
+shhs1-201777-profusion.xml
+shhs1-201778-profusion.xml
+shhs1-201779-profusion.xml
+shhs1-201780-profusion.xml
+shhs1-201781-profusion.xml
+shhs1-201782-profusion.xml
+shhs1-201783-profusion.xml
+shhs1-201784-profusion.xml
+shhs1-201785-profusion.xml
+shhs1-201786-profusion.xml
+shhs1-201787-profusion.xml
+shhs1-201788-profusion.xml
+shhs1-201789-profusion.xml
+shhs1-201790-profusion.xml
+shhs1-201791-profusion.xml
+shhs1-201792-profusion.xml
+shhs1-201793-profusion.xml
+shhs1-201794-profusion.xml
+shhs1-201795-profusion.xml
+shhs1-201796-profusion.xml
+shhs1-201797-profusion.xml
+shhs1-201798-profusion.xml
+shhs1-201799-profusion.xml
+shhs1-201800-profusion.xml
+shhs1-201801-profusion.xml
+shhs1-201802-profusion.xml
+shhs1-201803-profusion.xml
+shhs1-201804-profusion.xml
+shhs1-201805-profusion.xml
+shhs1-201806-profusion.xml
+shhs1-201807-profusion.xml
+shhs1-201808-profusion.xml
+shhs1-201809-profusion.xml
+shhs1-201810-profusion.xml
+shhs1-201811-profusion.xml
+shhs1-201812-profusion.xml
+shhs1-201813-profusion.xml
+shhs1-201814-profusion.xml
+shhs1-201815-profusion.xml
+shhs1-201816-profusion.xml
+shhs1-201817-profusion.xml
+shhs1-201818-profusion.xml
+shhs1-201819-profusion.xml
+shhs1-201820-profusion.xml
+shhs1-201822-profusion.xml
+shhs1-201823-profusion.xml
+shhs1-201824-profusion.xml
+shhs1-201825-profusion.xml
+shhs1-201826-profusion.xml
+shhs1-201827-profusion.xml
+shhs1-201828-profusion.xml
+shhs1-201829-profusion.xml
+shhs1-201830-profusion.xml
+shhs1-201831-profusion.xml
+shhs1-201832-profusion.xml
+shhs1-201833-profusion.xml
+shhs1-201834-profusion.xml
+shhs1-201835-profusion.xml
+shhs1-201836-profusion.xml
+shhs1-201837-profusion.xml
+shhs1-201838-profusion.xml
+shhs1-201839-profusion.xml
+shhs1-201840-profusion.xml
+shhs1-201841-profusion.xml
+shhs1-201842-profusion.xml
+shhs1-201843-profusion.xml
+shhs1-201844-profusion.xml
+shhs1-201845-profusion.xml
+shhs1-201846-profusion.xml
+shhs1-201847-profusion.xml
+shhs1-201848-profusion.xml
+shhs1-201849-profusion.xml
+shhs1-201850-profusion.xml
+shhs1-201851-profusion.xml
+shhs1-201852-profusion.xml
+shhs1-201853-profusion.xml
+shhs1-201854-profusion.xml
+shhs1-201855-profusion.xml
+shhs1-201856-profusion.xml
+shhs1-201857-profusion.xml
+shhs1-201858-profusion.xml
+shhs1-201859-profusion.xml
+shhs1-201860-profusion.xml
+shhs1-201861-profusion.xml
+shhs1-201862-profusion.xml
+shhs1-201863-profusion.xml
+shhs1-201864-profusion.xml
+shhs1-201865-profusion.xml
+shhs1-201866-profusion.xml
+shhs1-201867-profusion.xml
+shhs1-201868-profusion.xml
+shhs1-201869-profusion.xml
+shhs1-201870-profusion.xml
+shhs1-201871-profusion.xml
+shhs1-201872-profusion.xml
+shhs1-201873-profusion.xml
+shhs1-201874-profusion.xml
+shhs1-201875-profusion.xml
+shhs1-201876-profusion.xml
+shhs1-201877-profusion.xml
+shhs1-201878-profusion.xml
+shhs1-201879-profusion.xml
+shhs1-201880-profusion.xml
+shhs1-201881-profusion.xml
+shhs1-201882-profusion.xml
+shhs1-201883-profusion.xml
+shhs1-201884-profusion.xml
+shhs1-201885-profusion.xml
+shhs1-201886-profusion.xml
+shhs1-201887-profusion.xml
+shhs1-201888-profusion.xml
+shhs1-201889-profusion.xml
+shhs1-201890-profusion.xml
+shhs1-201891-profusion.xml
+shhs1-201892-profusion.xml
+shhs1-201893-profusion.xml
+shhs1-201894-profusion.xml
+shhs1-201895-profusion.xml
+shhs1-201896-profusion.xml
+shhs1-201897-profusion.xml
+shhs1-201898-profusion.xml
+shhs1-201899-profusion.xml
+shhs1-201900-profusion.xml
+shhs1-201901-profusion.xml
+shhs1-201902-profusion.xml
+shhs1-201903-profusion.xml
+shhs1-201904-profusion.xml
+shhs1-201905-profusion.xml
+shhs1-201906-profusion.xml
+shhs1-201907-profusion.xml
+shhs1-201908-profusion.xml
+shhs1-201909-profusion.xml
+shhs1-201910-profusion.xml
+shhs1-201911-profusion.xml
+shhs1-201912-profusion.xml
+shhs1-201913-profusion.xml
+shhs1-201914-profusion.xml
+shhs1-201915-profusion.xml
+shhs1-201916-profusion.xml
+shhs1-201917-profusion.xml
+shhs1-201918-profusion.xml
+shhs1-201919-profusion.xml
+shhs1-201920-profusion.xml
+shhs1-201921-profusion.xml
+shhs1-201922-profusion.xml
+shhs1-201923-profusion.xml
+shhs1-201924-profusion.xml
+shhs1-201925-profusion.xml
+shhs1-201926-profusion.xml
+shhs1-201927-profusion.xml
+shhs1-201928-profusion.xml
+shhs1-201929-profusion.xml
+shhs1-201930-profusion.xml
+shhs1-201931-profusion.xml
+shhs1-201932-profusion.xml
+shhs1-201933-profusion.xml
+shhs1-201934-profusion.xml
+shhs1-201935-profusion.xml
+shhs1-201936-profusion.xml
+shhs1-201937-profusion.xml
+shhs1-201938-profusion.xml
+shhs1-201939-profusion.xml
+shhs1-201940-profusion.xml
+shhs1-201941-profusion.xml
+shhs1-201942-profusion.xml
+shhs1-201943-profusion.xml
+shhs1-201944-profusion.xml
+shhs1-201945-profusion.xml
+shhs1-201946-profusion.xml
+shhs1-201947-profusion.xml
+shhs1-201948-profusion.xml
+shhs1-201949-profusion.xml
+shhs1-201950-profusion.xml
+shhs1-201951-profusion.xml
+shhs1-201952-profusion.xml
+shhs1-201953-profusion.xml
+shhs1-201954-profusion.xml
+shhs1-201955-profusion.xml
+shhs1-201956-profusion.xml
+shhs1-201957-profusion.xml
+shhs1-201958-profusion.xml
+shhs1-201959-profusion.xml
+shhs1-201960-profusion.xml
+shhs1-201961-profusion.xml
+shhs1-201962-profusion.xml
+shhs1-201963-profusion.xml
+shhs1-201964-profusion.xml
+shhs1-201965-profusion.xml
+shhs1-201966-profusion.xml
+shhs1-201967-profusion.xml
+shhs1-201968-profusion.xml
+shhs1-201969-profusion.xml
+shhs1-201970-profusion.xml
+shhs1-201971-profusion.xml
+shhs1-201972-profusion.xml
+shhs1-201973-profusion.xml
+shhs1-201974-profusion.xml
+shhs1-201975-profusion.xml
+shhs1-201976-profusion.xml
+shhs1-201977-profusion.xml
+shhs1-201978-profusion.xml
+shhs1-201979-profusion.xml
+shhs1-201980-profusion.xml
+shhs1-201981-profusion.xml
+shhs1-201982-profusion.xml
+shhs1-201983-profusion.xml
+shhs1-201984-profusion.xml
+shhs1-201985-profusion.xml
+shhs1-201986-profusion.xml
+shhs1-201987-profusion.xml
+shhs1-201988-profusion.xml
+shhs1-201989-profusion.xml
+shhs1-201990-profusion.xml
+shhs1-201991-profusion.xml
+shhs1-201992-profusion.xml
+shhs1-201993-profusion.xml
+shhs1-201994-profusion.xml
+shhs1-201995-profusion.xml
+shhs1-201996-profusion.xml
+shhs1-201997-profusion.xml
+shhs1-201998-profusion.xml
+shhs1-201999-profusion.xml
+shhs1-202000-profusion.xml
+shhs1-202001-profusion.xml
+shhs1-202002-profusion.xml
+shhs1-202003-profusion.xml
+shhs1-202004-profusion.xml
+shhs1-202005-profusion.xml
+shhs1-202006-profusion.xml
+shhs1-202007-profusion.xml
+shhs1-202008-profusion.xml
+shhs1-202009-profusion.xml
+shhs1-202010-profusion.xml
+shhs1-202011-profusion.xml
+shhs1-202012-profusion.xml
+shhs1-202013-profusion.xml
+shhs1-202014-profusion.xml
+shhs1-202015-profusion.xml
+shhs1-202016-profusion.xml
+shhs1-202017-profusion.xml
+shhs1-202018-profusion.xml
+shhs1-202019-profusion.xml
+shhs1-202020-profusion.xml
+shhs1-202021-profusion.xml
+shhs1-202022-profusion.xml
+shhs1-202023-profusion.xml
+shhs1-202024-profusion.xml
+shhs1-202025-profusion.xml
+shhs1-202026-profusion.xml
+shhs1-202027-profusion.xml
+shhs1-202028-profusion.xml
+shhs1-202029-profusion.xml
+shhs1-202030-profusion.xml
+shhs1-202031-profusion.xml
+shhs1-202032-profusion.xml
+shhs1-202033-profusion.xml
+shhs1-202034-profusion.xml
+shhs1-202035-profusion.xml
+shhs1-202036-profusion.xml
+shhs1-202037-profusion.xml
+shhs1-202038-profusion.xml
+shhs1-202039-profusion.xml
+shhs1-202040-profusion.xml
+shhs1-202041-profusion.xml
+shhs1-202042-profusion.xml
+shhs1-202043-profusion.xml
+shhs1-202044-profusion.xml
+shhs1-202045-profusion.xml
+shhs1-202046-profusion.xml
+shhs1-202047-profusion.xml
+shhs1-202048-profusion.xml
+shhs1-202049-profusion.xml
+shhs1-202050-profusion.xml
+shhs1-202051-profusion.xml
+shhs1-202052-profusion.xml
+shhs1-202053-profusion.xml
+shhs1-202054-profusion.xml
+shhs1-202055-profusion.xml
+shhs1-202056-profusion.xml
+shhs1-202057-profusion.xml
+shhs1-202058-profusion.xml
+shhs1-202059-profusion.xml
+shhs1-202060-profusion.xml
+shhs1-202061-profusion.xml
+shhs1-202062-profusion.xml
+shhs1-202063-profusion.xml
+shhs1-202064-profusion.xml
+shhs1-202065-profusion.xml
+shhs1-202066-profusion.xml
+shhs1-202067-profusion.xml
+shhs1-202068-profusion.xml
+shhs1-202069-profusion.xml
+shhs1-202070-profusion.xml
+shhs1-202071-profusion.xml
+shhs1-202072-profusion.xml
+shhs1-202073-profusion.xml
+shhs1-202074-profusion.xml
+shhs1-202075-profusion.xml
+shhs1-202076-profusion.xml
+shhs1-202077-profusion.xml
+shhs1-202078-profusion.xml
+shhs1-202079-profusion.xml
+shhs1-202080-profusion.xml
+shhs1-202081-profusion.xml
+shhs1-202082-profusion.xml
+shhs1-202083-profusion.xml
+shhs1-202084-profusion.xml
+shhs1-202085-profusion.xml
+shhs1-202086-profusion.xml
+shhs1-202087-profusion.xml
+shhs1-202088-profusion.xml
+shhs1-202089-profusion.xml
+shhs1-202090-profusion.xml
+shhs1-202091-profusion.xml
+shhs1-202092-profusion.xml
+shhs1-202093-profusion.xml
+shhs1-202094-profusion.xml
+shhs1-202095-profusion.xml
+shhs1-202096-profusion.xml
+shhs1-202097-profusion.xml
+shhs1-202098-profusion.xml
+shhs1-202099-profusion.xml
+shhs1-202100-profusion.xml
+shhs1-202101-profusion.xml
+shhs1-202102-profusion.xml
+shhs1-202103-profusion.xml
+shhs1-202104-profusion.xml
+shhs1-202105-profusion.xml
+shhs1-202106-profusion.xml
+shhs1-202107-profusion.xml
+shhs1-202108-profusion.xml
+shhs1-202109-profusion.xml
+shhs1-202110-profusion.xml
+shhs1-202111-profusion.xml
+shhs1-202112-profusion.xml
+shhs1-202113-profusion.xml
+shhs1-202114-profusion.xml
+shhs1-202115-profusion.xml
+shhs1-202116-profusion.xml
+shhs1-202117-profusion.xml
+shhs1-202118-profusion.xml
+shhs1-202119-profusion.xml
+shhs1-202120-profusion.xml
+shhs1-202121-profusion.xml
+shhs1-202122-profusion.xml
+shhs1-202123-profusion.xml
+shhs1-202124-profusion.xml
+shhs1-202125-profusion.xml
+shhs1-202126-profusion.xml
+shhs1-202127-profusion.xml
+shhs1-202128-profusion.xml
+shhs1-202129-profusion.xml
+shhs1-202130-profusion.xml
+shhs1-202131-profusion.xml
+shhs1-202132-profusion.xml
+shhs1-202133-profusion.xml
+shhs1-202134-profusion.xml
+shhs1-202135-profusion.xml
+shhs1-202136-profusion.xml
+shhs1-202137-profusion.xml
+shhs1-202138-profusion.xml
+shhs1-202139-profusion.xml
+shhs1-202140-profusion.xml
+shhs1-202141-profusion.xml
+shhs1-202142-profusion.xml
+shhs1-202143-profusion.xml
+shhs1-202144-profusion.xml
+shhs1-202145-profusion.xml
+shhs1-202146-profusion.xml
+shhs1-202147-profusion.xml
+shhs1-202148-profusion.xml
+shhs1-202149-profusion.xml
+shhs1-202150-profusion.xml
+shhs1-202151-profusion.xml
+shhs1-202152-profusion.xml
+shhs1-202153-profusion.xml
+shhs1-202154-profusion.xml
+shhs1-202155-profusion.xml
+shhs1-202156-profusion.xml
+shhs1-202157-profusion.xml
+shhs1-202158-profusion.xml
+shhs1-202159-profusion.xml
+shhs1-202160-profusion.xml
+shhs1-202161-profusion.xml
+shhs1-202162-profusion.xml
+shhs1-202163-profusion.xml
+shhs1-202164-profusion.xml
+shhs1-202165-profusion.xml
+shhs1-202166-profusion.xml
+shhs1-202167-profusion.xml
+shhs1-202168-profusion.xml
+shhs1-202169-profusion.xml
+shhs1-202170-profusion.xml
+shhs1-202171-profusion.xml
+shhs1-202172-profusion.xml
+shhs1-202173-profusion.xml
+shhs1-202174-profusion.xml
+shhs1-202175-profusion.xml
+shhs1-202176-profusion.xml
+shhs1-202177-profusion.xml
+shhs1-202178-profusion.xml
+shhs1-202179-profusion.xml
+shhs1-202180-profusion.xml
+shhs1-202181-profusion.xml
+shhs1-202182-profusion.xml
+shhs1-202183-profusion.xml
+shhs1-202184-profusion.xml
+shhs1-202185-profusion.xml
+shhs1-202186-profusion.xml
+shhs1-202187-profusion.xml
+shhs1-202188-profusion.xml
+shhs1-202189-profusion.xml
+shhs1-202190-profusion.xml
+shhs1-202191-profusion.xml
+shhs1-202192-profusion.xml
+shhs1-202193-profusion.xml
+shhs1-202194-profusion.xml
+shhs1-202195-profusion.xml
+shhs1-202196-profusion.xml
+shhs1-202197-profusion.xml
+shhs1-202198-profusion.xml
+shhs1-202199-profusion.xml
+shhs1-202200-profusion.xml
+shhs1-202201-profusion.xml
+shhs1-202202-profusion.xml
+shhs1-202203-profusion.xml
+shhs1-202204-profusion.xml
+shhs1-202205-profusion.xml
+shhs1-202206-profusion.xml
+shhs1-202207-profusion.xml
+shhs1-202208-profusion.xml
+shhs1-202209-profusion.xml
+shhs1-202210-profusion.xml
+shhs1-202211-profusion.xml
+shhs1-202212-profusion.xml
+shhs1-202213-profusion.xml
+shhs1-202214-profusion.xml
+shhs1-202215-profusion.xml
+shhs1-202216-profusion.xml
+shhs1-202217-profusion.xml
+shhs1-202218-profusion.xml
+shhs1-202219-profusion.xml
+shhs1-202220-profusion.xml
+shhs1-202221-profusion.xml
+shhs1-202222-profusion.xml
+shhs1-202223-profusion.xml
+shhs1-202224-profusion.xml
+shhs1-202225-profusion.xml
+shhs1-202226-profusion.xml
+shhs1-202227-profusion.xml
+shhs1-202228-profusion.xml
+shhs1-202229-profusion.xml
+shhs1-202230-profusion.xml
+shhs1-202231-profusion.xml
+shhs1-202232-profusion.xml
+shhs1-202233-profusion.xml
+shhs1-202234-profusion.xml
+shhs1-202235-profusion.xml
+shhs1-202236-profusion.xml
+shhs1-202237-profusion.xml
+shhs1-202238-profusion.xml
+shhs1-202239-profusion.xml
+shhs1-202240-profusion.xml
+shhs1-202241-profusion.xml
+shhs1-202242-profusion.xml
+shhs1-202243-profusion.xml
+shhs1-202244-profusion.xml
+shhs1-202245-profusion.xml
+shhs1-202246-profusion.xml
+shhs1-202247-profusion.xml
+shhs1-202249-profusion.xml
+shhs1-202250-profusion.xml
+shhs1-202251-profusion.xml
+shhs1-202252-profusion.xml
+shhs1-202253-profusion.xml
+shhs1-202254-profusion.xml
+shhs1-202255-profusion.xml
+shhs1-202256-profusion.xml
+shhs1-202257-profusion.xml
+shhs1-202258-profusion.xml
+shhs1-202259-profusion.xml
+shhs1-202260-profusion.xml
+shhs1-202261-profusion.xml
+shhs1-202262-profusion.xml
+shhs1-202263-profusion.xml
+shhs1-202264-profusion.xml
+shhs1-202265-profusion.xml
+shhs1-202266-profusion.xml
+shhs1-202267-profusion.xml
+shhs1-202268-profusion.xml
+shhs1-202269-profusion.xml
+shhs1-202270-profusion.xml
+shhs1-202271-profusion.xml
+shhs1-202272-profusion.xml
+shhs1-202273-profusion.xml
+shhs1-202274-profusion.xml
+shhs1-202275-profusion.xml
+shhs1-202276-profusion.xml
+shhs1-202277-profusion.xml
+shhs1-202278-profusion.xml
+shhs1-202279-profusion.xml
+shhs1-202280-profusion.xml
+shhs1-202281-profusion.xml
+shhs1-202282-profusion.xml
+shhs1-202283-profusion.xml
+shhs1-202284-profusion.xml
+shhs1-202285-profusion.xml
+shhs1-202286-profusion.xml
+shhs1-202287-profusion.xml
+shhs1-202288-profusion.xml
+shhs1-202289-profusion.xml
+shhs1-202290-profusion.xml
+shhs1-202291-profusion.xml
+shhs1-202292-profusion.xml
+shhs1-202293-profusion.xml
+shhs1-202294-profusion.xml
+shhs1-202295-profusion.xml
+shhs1-202296-profusion.xml
+shhs1-202297-profusion.xml
+shhs1-202298-profusion.xml
+shhs1-202299-profusion.xml
+shhs1-202300-profusion.xml
+shhs1-202301-profusion.xml
+shhs1-202302-profusion.xml
+shhs1-202303-profusion.xml
+shhs1-202304-profusion.xml
+shhs1-202305-profusion.xml
+shhs1-202306-profusion.xml
+shhs1-202307-profusion.xml
+shhs1-202309-profusion.xml
+shhs1-202310-profusion.xml
+shhs1-202311-profusion.xml
+shhs1-202312-profusion.xml
+shhs1-202313-profusion.xml
+shhs1-202314-profusion.xml
+shhs1-202315-profusion.xml
+shhs1-202316-profusion.xml
+shhs1-202318-profusion.xml
+shhs1-202319-profusion.xml
+shhs1-202320-profusion.xml
+shhs1-202321-profusion.xml
+shhs1-202322-profusion.xml
+shhs1-202323-profusion.xml
+shhs1-202324-profusion.xml
+shhs1-202325-profusion.xml
+shhs1-202326-profusion.xml
+shhs1-202327-profusion.xml
+shhs1-202328-profusion.xml
+shhs1-202329-profusion.xml
+shhs1-202330-profusion.xml
+shhs1-202331-profusion.xml
+shhs1-202332-profusion.xml
+shhs1-202333-profusion.xml
+shhs1-202334-profusion.xml
+shhs1-202335-profusion.xml
+shhs1-202336-profusion.xml
+shhs1-202337-profusion.xml
+shhs1-202338-profusion.xml
+shhs1-202339-profusion.xml
+shhs1-202340-profusion.xml
+shhs1-202341-profusion.xml
+shhs1-202342-profusion.xml
+shhs1-202343-profusion.xml
+shhs1-202344-profusion.xml
+shhs1-202345-profusion.xml
+shhs1-202346-profusion.xml
+shhs1-202347-profusion.xml
+shhs1-202348-profusion.xml
+shhs1-202349-profusion.xml
+shhs1-202350-profusion.xml
+shhs1-202351-profusion.xml
+shhs1-202352-profusion.xml
+shhs1-202353-profusion.xml
+shhs1-202354-profusion.xml
+shhs1-202355-profusion.xml
+shhs1-202356-profusion.xml
+shhs1-202357-profusion.xml
+shhs1-202358-profusion.xml
+shhs1-202359-profusion.xml
+shhs1-202360-profusion.xml
+shhs1-202361-profusion.xml
+shhs1-202362-profusion.xml
+shhs1-202363-profusion.xml
+shhs1-202364-profusion.xml
+shhs1-202365-profusion.xml
+shhs1-202366-profusion.xml
+shhs1-202367-profusion.xml
+shhs1-202368-profusion.xml
+shhs1-202369-profusion.xml
+shhs1-202370-profusion.xml
+shhs1-202371-profusion.xml
+shhs1-202372-profusion.xml
+shhs1-202373-profusion.xml
+shhs1-202374-profusion.xml
+shhs1-202375-profusion.xml
+shhs1-202376-profusion.xml
+shhs1-202377-profusion.xml
+shhs1-202378-profusion.xml
+shhs1-202379-profusion.xml
+shhs1-202380-profusion.xml
+shhs1-202381-profusion.xml
+shhs1-202382-profusion.xml
+shhs1-202383-profusion.xml
+shhs1-202384-profusion.xml
+shhs1-202385-profusion.xml
+shhs1-202386-profusion.xml
+shhs1-202387-profusion.xml
+shhs1-202388-profusion.xml
+shhs1-202389-profusion.xml
+shhs1-202390-profusion.xml
+shhs1-202391-profusion.xml
+shhs1-202392-profusion.xml
+shhs1-202393-profusion.xml
+shhs1-202394-profusion.xml
+shhs1-202395-profusion.xml
+shhs1-202396-profusion.xml
+shhs1-202397-profusion.xml
+shhs1-202398-profusion.xml
+shhs1-202399-profusion.xml
+shhs1-202400-profusion.xml
+shhs1-202401-profusion.xml
+shhs1-202402-profusion.xml
+shhs1-202403-profusion.xml
+shhs1-202404-profusion.xml
+shhs1-202405-profusion.xml
+shhs1-202406-profusion.xml
+shhs1-202407-profusion.xml
+shhs1-202408-profusion.xml
+shhs1-202409-profusion.xml
+shhs1-202410-profusion.xml
+shhs1-202411-profusion.xml
+shhs1-202412-profusion.xml
+shhs1-202413-profusion.xml
+shhs1-202414-profusion.xml
+shhs1-202415-profusion.xml
+shhs1-202416-profusion.xml
+shhs1-202417-profusion.xml
+shhs1-202418-profusion.xml
+shhs1-202419-profusion.xml
+shhs1-202420-profusion.xml
+shhs1-202421-profusion.xml
+shhs1-202422-profusion.xml
+shhs1-202423-profusion.xml
+shhs1-202424-profusion.xml
+shhs1-202425-profusion.xml
+shhs1-202426-profusion.xml
+shhs1-202427-profusion.xml
+shhs1-202428-profusion.xml
+shhs1-202429-profusion.xml
+shhs1-202430-profusion.xml
+shhs1-202431-profusion.xml
+shhs1-202432-profusion.xml
+shhs1-202433-profusion.xml
+shhs1-202434-profusion.xml
+shhs1-202435-profusion.xml
+shhs1-202436-profusion.xml
+shhs1-202437-profusion.xml
+shhs1-202438-profusion.xml
+shhs1-202439-profusion.xml
+shhs1-202440-profusion.xml
+shhs1-202441-profusion.xml
+shhs1-202442-profusion.xml
+shhs1-202443-profusion.xml
+shhs1-202444-profusion.xml
+shhs1-202445-profusion.xml
+shhs1-202446-profusion.xml
+shhs1-202447-profusion.xml
+shhs1-202448-profusion.xml
+shhs1-202449-profusion.xml
+shhs1-202450-profusion.xml
+shhs1-202451-profusion.xml
+shhs1-202452-profusion.xml
+shhs1-202453-profusion.xml
+shhs1-202454-profusion.xml
+shhs1-202455-profusion.xml
+shhs1-202456-profusion.xml
+shhs1-202457-profusion.xml
+shhs1-202458-profusion.xml
+shhs1-202459-profusion.xml
+shhs1-202460-profusion.xml
+shhs1-202461-profusion.xml
+shhs1-202462-profusion.xml
+shhs1-202463-profusion.xml
+shhs1-202464-profusion.xml
+shhs1-202465-profusion.xml
+shhs1-202466-profusion.xml
+shhs1-202467-profusion.xml
+shhs1-202468-profusion.xml
+shhs1-202469-profusion.xml
+shhs1-202470-profusion.xml
+shhs1-202471-profusion.xml
+shhs1-202472-profusion.xml
+shhs1-202473-profusion.xml
+shhs1-202474-profusion.xml
+shhs1-202475-profusion.xml
+shhs1-202476-profusion.xml
+shhs1-202477-profusion.xml
+shhs1-202478-profusion.xml
+shhs1-202479-profusion.xml
+shhs1-202480-profusion.xml
+shhs1-202481-profusion.xml
+shhs1-202482-profusion.xml
+shhs1-202483-profusion.xml
+shhs1-202484-profusion.xml
+shhs1-202485-profusion.xml
+shhs1-202486-profusion.xml
+shhs1-202487-profusion.xml
+shhs1-202488-profusion.xml
+shhs1-202489-profusion.xml
+shhs1-202490-profusion.xml
+shhs1-202491-profusion.xml
+shhs1-202492-profusion.xml
+shhs1-202493-profusion.xml
+shhs1-202494-profusion.xml
+shhs1-202495-profusion.xml
+shhs1-202496-profusion.xml
+shhs1-202497-profusion.xml
+shhs1-202498-profusion.xml
+shhs1-202499-profusion.xml
+shhs1-202500-profusion.xml
+shhs1-202501-profusion.xml
+shhs1-202502-profusion.xml
+shhs1-202503-profusion.xml
+shhs1-202504-profusion.xml
+shhs1-202505-profusion.xml
+shhs1-202506-profusion.xml
+shhs1-202507-profusion.xml
+shhs1-202508-profusion.xml
+shhs1-202509-profusion.xml
+shhs1-202510-profusion.xml
+shhs1-202511-profusion.xml
+shhs1-202512-profusion.xml
+shhs1-202513-profusion.xml
+shhs1-202514-profusion.xml
+shhs1-202515-profusion.xml
+shhs1-202516-profusion.xml
+shhs1-202517-profusion.xml
+shhs1-202518-profusion.xml
+shhs1-202519-profusion.xml
+shhs1-202520-profusion.xml
+shhs1-202521-profusion.xml
+shhs1-202522-profusion.xml
+shhs1-202523-profusion.xml
+shhs1-202524-profusion.xml
+shhs1-202525-profusion.xml
+shhs1-202526-profusion.xml
+shhs1-202527-profusion.xml
+shhs1-202528-profusion.xml
+shhs1-202529-profusion.xml
+shhs1-202530-profusion.xml
+shhs1-202531-profusion.xml
+shhs1-202532-profusion.xml
+shhs1-202533-profusion.xml
+shhs1-202534-profusion.xml
+shhs1-202535-profusion.xml
+shhs1-202536-profusion.xml
+shhs1-202537-profusion.xml
+shhs1-202538-profusion.xml
+shhs1-202539-profusion.xml
+shhs1-202540-profusion.xml
+shhs1-202541-profusion.xml
+shhs1-202542-profusion.xml
+shhs1-202543-profusion.xml
+shhs1-202544-profusion.xml
+shhs1-202545-profusion.xml
+shhs1-202546-profusion.xml
+shhs1-202547-profusion.xml
+shhs1-202548-profusion.xml
+shhs1-202549-profusion.xml
+shhs1-202550-profusion.xml
+shhs1-202551-profusion.xml
+shhs1-202552-profusion.xml
+shhs1-202553-profusion.xml
+shhs1-202554-profusion.xml
+shhs1-202555-profusion.xml
+shhs1-202556-profusion.xml
+shhs1-202557-profusion.xml
+shhs1-202558-profusion.xml
+shhs1-202559-profusion.xml
+shhs1-202560-profusion.xml
+shhs1-202561-profusion.xml
+shhs1-202562-profusion.xml
+shhs1-202563-profusion.xml
+shhs1-202564-profusion.xml
+shhs1-202565-profusion.xml
+shhs1-202566-profusion.xml
+shhs1-202567-profusion.xml
+shhs1-202568-profusion.xml
+shhs1-202569-profusion.xml
+shhs1-202570-profusion.xml
+shhs1-202571-profusion.xml
+shhs1-202572-profusion.xml
+shhs1-202573-profusion.xml
+shhs1-202574-profusion.xml
+shhs1-202575-profusion.xml
+shhs1-202576-profusion.xml
+shhs1-202577-profusion.xml
+shhs1-202578-profusion.xml
+shhs1-202579-profusion.xml
+shhs1-202580-profusion.xml
+shhs1-202581-profusion.xml
+shhs1-202582-profusion.xml
+shhs1-202583-profusion.xml
+shhs1-202584-profusion.xml
+shhs1-202585-profusion.xml
+shhs1-202586-profusion.xml
+shhs1-202587-profusion.xml
+shhs1-202588-profusion.xml
+shhs1-202589-profusion.xml
+shhs1-202590-profusion.xml
+shhs1-202591-profusion.xml
+shhs1-202592-profusion.xml
+shhs1-202593-profusion.xml
+shhs1-202594-profusion.xml
+shhs1-202595-profusion.xml
+shhs1-202596-profusion.xml
+shhs1-202597-profusion.xml
+shhs1-202598-profusion.xml
+shhs1-202599-profusion.xml
+shhs1-202600-profusion.xml
+shhs1-202601-profusion.xml
+shhs1-202602-profusion.xml
+shhs1-202603-profusion.xml
+shhs1-202604-profusion.xml
+shhs1-202605-profusion.xml
+shhs1-202606-profusion.xml
+shhs1-202607-profusion.xml
+shhs1-202608-profusion.xml
+shhs1-202609-profusion.xml
+shhs1-202610-profusion.xml
+shhs1-202611-profusion.xml
+shhs1-202612-profusion.xml
+shhs1-202613-profusion.xml
+shhs1-202614-profusion.xml
+shhs1-202615-profusion.xml
+shhs1-202616-profusion.xml
+shhs1-202617-profusion.xml
+shhs1-202618-profusion.xml
+shhs1-202619-profusion.xml
+shhs1-202620-profusion.xml
+shhs1-202621-profusion.xml
+shhs1-202622-profusion.xml
+shhs1-202623-profusion.xml
+shhs1-202624-profusion.xml
+shhs1-202625-profusion.xml
+shhs1-202626-profusion.xml
+shhs1-202627-profusion.xml
+shhs1-202628-profusion.xml
+shhs1-202629-profusion.xml
+shhs1-202630-profusion.xml
+shhs1-202631-profusion.xml
+shhs1-202632-profusion.xml
+shhs1-202633-profusion.xml
+shhs1-202634-profusion.xml
+shhs1-202635-profusion.xml
+shhs1-202636-profusion.xml
+shhs1-202637-profusion.xml
+shhs1-202638-profusion.xml
+shhs1-202639-profusion.xml
+shhs1-202640-profusion.xml
+shhs1-202641-profusion.xml
+shhs1-202642-profusion.xml
+shhs1-202643-profusion.xml
+shhs1-202644-profusion.xml
+shhs1-202645-profusion.xml
+shhs1-202646-profusion.xml
+shhs1-202647-profusion.xml
+shhs1-202648-profusion.xml
+shhs1-202649-profusion.xml
+shhs1-202650-profusion.xml
+shhs1-202651-profusion.xml
+shhs1-202652-profusion.xml
+shhs1-202653-profusion.xml
+shhs1-202654-profusion.xml
+shhs1-202655-profusion.xml
+shhs1-202656-profusion.xml
+shhs1-202657-profusion.xml
+shhs1-202658-profusion.xml
+shhs1-202659-profusion.xml
+shhs1-202660-profusion.xml
+shhs1-202661-profusion.xml
+shhs1-202662-profusion.xml
+shhs1-202663-profusion.xml
+shhs1-202664-profusion.xml
+shhs1-202665-profusion.xml
+shhs1-202666-profusion.xml
+shhs1-202667-profusion.xml
+shhs1-202668-profusion.xml
+shhs1-202669-profusion.xml
+shhs1-202670-profusion.xml
+shhs1-202671-profusion.xml
+shhs1-202672-profusion.xml
+shhs1-202673-profusion.xml
+shhs1-202674-profusion.xml
+shhs1-202675-profusion.xml
+shhs1-202676-profusion.xml
+shhs1-202677-profusion.xml
+shhs1-202678-profusion.xml
+shhs1-202679-profusion.xml
+shhs1-202680-profusion.xml
+shhs1-202681-profusion.xml
+shhs1-202682-profusion.xml
+shhs1-202683-profusion.xml
+shhs1-202684-profusion.xml
+shhs1-202685-profusion.xml
+shhs1-202686-profusion.xml
+shhs1-202687-profusion.xml
+shhs1-202688-profusion.xml
+shhs1-202689-profusion.xml
+shhs1-202690-profusion.xml
+shhs1-202691-profusion.xml
+shhs1-202692-profusion.xml
+shhs1-202693-profusion.xml
+shhs1-202694-profusion.xml
+shhs1-202695-profusion.xml
+shhs1-202696-profusion.xml
+shhs1-202697-profusion.xml
+shhs1-202698-profusion.xml
+shhs1-202699-profusion.xml
+shhs1-202700-profusion.xml
+shhs1-202701-profusion.xml
+shhs1-202702-profusion.xml
+shhs1-202703-profusion.xml
+shhs1-202704-profusion.xml
+shhs1-202705-profusion.xml
+shhs1-202706-profusion.xml
+shhs1-202707-profusion.xml
+shhs1-202708-profusion.xml
+shhs1-202709-profusion.xml
+shhs1-202710-profusion.xml
+shhs1-202711-profusion.xml
+shhs1-202712-profusion.xml
+shhs1-202713-profusion.xml
+shhs1-202714-profusion.xml
+shhs1-202715-profusion.xml
+shhs1-202716-profusion.xml
+shhs1-202717-profusion.xml
+shhs1-202718-profusion.xml
+shhs1-202719-profusion.xml
+shhs1-202720-profusion.xml
+shhs1-202721-profusion.xml
+shhs1-202722-profusion.xml
+shhs1-202723-profusion.xml
+shhs1-202724-profusion.xml
+shhs1-202725-profusion.xml
+shhs1-202726-profusion.xml
+shhs1-202727-profusion.xml
+shhs1-202728-profusion.xml
+shhs1-202729-profusion.xml
+shhs1-202730-profusion.xml
+shhs1-202731-profusion.xml
+shhs1-202732-profusion.xml
+shhs1-202733-profusion.xml
+shhs1-202734-profusion.xml
+shhs1-202735-profusion.xml
+shhs1-202736-profusion.xml
+shhs1-202737-profusion.xml
+shhs1-202738-profusion.xml
+shhs1-202739-profusion.xml
+shhs1-202740-profusion.xml
+shhs1-202741-profusion.xml
+shhs1-202742-profusion.xml
+shhs1-202743-profusion.xml
+shhs1-202744-profusion.xml
+shhs1-202745-profusion.xml
+shhs1-202746-profusion.xml
+shhs1-202747-profusion.xml
+shhs1-202748-profusion.xml
+shhs1-202749-profusion.xml
+shhs1-202750-profusion.xml
+shhs1-202751-profusion.xml
+shhs1-202752-profusion.xml
+shhs1-202753-profusion.xml
+shhs1-202754-profusion.xml
+shhs1-202755-profusion.xml
+shhs1-202756-profusion.xml
+shhs1-202757-profusion.xml
+shhs1-202758-profusion.xml
+shhs1-202759-profusion.xml
+shhs1-202760-profusion.xml
+shhs1-202761-profusion.xml
+shhs1-202762-profusion.xml
+shhs1-202763-profusion.xml
+shhs1-202764-profusion.xml
+shhs1-202765-profusion.xml
+shhs1-202766-profusion.xml
+shhs1-202767-profusion.xml
+shhs1-202768-profusion.xml
+shhs1-202769-profusion.xml
+shhs1-202770-profusion.xml
+shhs1-202771-profusion.xml
+shhs1-202772-profusion.xml
+shhs1-202773-profusion.xml
+shhs1-202774-profusion.xml
+shhs1-202775-profusion.xml
+shhs1-202776-profusion.xml
+shhs1-202777-profusion.xml
+shhs1-202778-profusion.xml
+shhs1-202779-profusion.xml
+shhs1-202780-profusion.xml
+shhs1-202781-profusion.xml
+shhs1-202782-profusion.xml
+shhs1-202783-profusion.xml
+shhs1-202784-profusion.xml
+shhs1-202785-profusion.xml
+shhs1-202786-profusion.xml
+shhs1-202787-profusion.xml
+shhs1-202788-profusion.xml
+shhs1-202789-profusion.xml
+shhs1-202790-profusion.xml
+shhs1-202791-profusion.xml
+shhs1-202792-profusion.xml
+shhs1-202793-profusion.xml
+shhs1-202794-profusion.xml
+shhs1-202795-profusion.xml
+shhs1-202796-profusion.xml
+shhs1-202797-profusion.xml
+shhs1-202798-profusion.xml
+shhs1-202799-profusion.xml
+shhs1-202800-profusion.xml
+shhs1-202801-profusion.xml
+shhs1-202802-profusion.xml
+shhs1-202803-profusion.xml
+shhs1-202804-profusion.xml
+shhs1-202805-profusion.xml
+shhs1-202806-profusion.xml
+shhs1-202807-profusion.xml
+shhs1-202808-profusion.xml
+shhs1-202809-profusion.xml
+shhs1-202810-profusion.xml
+shhs1-202811-profusion.xml
+shhs1-202812-profusion.xml
+shhs1-202813-profusion.xml
+shhs1-202814-profusion.xml
+shhs1-202815-profusion.xml
+shhs1-202816-profusion.xml
+shhs1-202817-profusion.xml
+shhs1-202818-profusion.xml
+shhs1-202819-profusion.xml
+shhs1-202820-profusion.xml
+shhs1-202821-profusion.xml
+shhs1-202822-profusion.xml
+shhs1-202823-profusion.xml
+shhs1-202824-profusion.xml
+shhs1-202825-profusion.xml
+shhs1-202826-profusion.xml
+shhs1-202827-profusion.xml
+shhs1-202828-profusion.xml
+shhs1-202829-profusion.xml
+shhs1-202830-profusion.xml
+shhs1-202831-profusion.xml
+shhs1-202832-profusion.xml
+shhs1-202833-profusion.xml
+shhs1-202834-profusion.xml
+shhs1-202835-profusion.xml
+shhs1-202836-profusion.xml
+shhs1-202837-profusion.xml
+shhs1-202838-profusion.xml
+shhs1-202839-profusion.xml
+shhs1-202840-profusion.xml
+shhs1-202841-profusion.xml
+shhs1-202842-profusion.xml
+shhs1-202843-profusion.xml
+shhs1-202844-profusion.xml
+shhs1-202845-profusion.xml
+shhs1-202846-profusion.xml
+shhs1-202847-profusion.xml
+shhs1-202848-profusion.xml
+shhs1-202849-profusion.xml
+shhs1-202850-profusion.xml
+shhs1-202851-profusion.xml
+shhs1-202852-profusion.xml
+shhs1-202853-profusion.xml
+shhs1-202854-profusion.xml
+shhs1-202855-profusion.xml
+shhs1-202856-profusion.xml
+shhs1-202857-profusion.xml
+shhs1-202858-profusion.xml
+shhs1-202859-profusion.xml
+shhs1-202860-profusion.xml
+shhs1-202861-profusion.xml
+shhs1-202862-profusion.xml
+shhs1-202863-profusion.xml
+shhs1-202864-profusion.xml
+shhs1-202865-profusion.xml
+shhs1-202866-profusion.xml
+shhs1-202867-profusion.xml
+shhs1-202868-profusion.xml
+shhs1-202869-profusion.xml
+shhs1-202870-profusion.xml
+shhs1-202871-profusion.xml
+shhs1-202872-profusion.xml
+shhs1-202873-profusion.xml
+shhs1-202874-profusion.xml
+shhs1-202875-profusion.xml
+shhs1-202876-profusion.xml
+shhs1-202877-profusion.xml
+shhs1-202878-profusion.xml
+shhs1-202879-profusion.xml
+shhs1-202880-profusion.xml
+shhs1-202881-profusion.xml
+shhs1-202882-profusion.xml
+shhs1-202883-profusion.xml
+shhs1-202884-profusion.xml
+shhs1-202885-profusion.xml
+shhs1-202886-profusion.xml
+shhs1-202887-profusion.xml
+shhs1-202888-profusion.xml
+shhs1-202889-profusion.xml
+shhs1-202890-profusion.xml
+shhs1-202891-profusion.xml
+shhs1-202892-profusion.xml
+shhs1-202893-profusion.xml
+shhs1-202894-profusion.xml
+shhs1-202895-profusion.xml
+shhs1-202896-profusion.xml
+shhs1-202897-profusion.xml
+shhs1-202898-profusion.xml
+shhs1-202899-profusion.xml
+shhs1-202900-profusion.xml
+shhs1-202901-profusion.xml
+shhs1-202902-profusion.xml
+shhs1-202903-profusion.xml
+shhs1-202904-profusion.xml
+shhs1-202905-profusion.xml
+shhs1-202906-profusion.xml
+shhs1-202907-profusion.xml
+shhs1-202908-profusion.xml
+shhs1-202909-profusion.xml
+shhs1-202910-profusion.xml
+shhs1-202911-profusion.xml
+shhs1-202912-profusion.xml
+shhs1-202913-profusion.xml
+shhs1-202914-profusion.xml
+shhs1-202915-profusion.xml
+shhs1-202916-profusion.xml
+shhs1-202917-profusion.xml
+shhs1-202918-profusion.xml
+shhs1-202919-profusion.xml
+shhs1-202920-profusion.xml
+shhs1-202921-profusion.xml
+shhs1-202922-profusion.xml
+shhs1-202923-profusion.xml
+shhs1-202924-profusion.xml
+shhs1-202925-profusion.xml
+shhs1-202926-profusion.xml
+shhs1-202927-profusion.xml
+shhs1-202928-profusion.xml
+shhs1-202929-profusion.xml
+shhs1-202930-profusion.xml
+shhs1-202931-profusion.xml
+shhs1-202932-profusion.xml
+shhs1-202933-profusion.xml
+shhs1-202934-profusion.xml
+shhs1-202935-profusion.xml
+shhs1-202936-profusion.xml
+shhs1-202937-profusion.xml
+shhs1-202938-profusion.xml
+shhs1-202939-profusion.xml
+shhs1-202940-profusion.xml
+shhs1-202941-profusion.xml
+shhs1-202942-profusion.xml
+shhs1-202943-profusion.xml
+shhs1-202944-profusion.xml
+shhs1-202945-profusion.xml
+shhs1-202946-profusion.xml
+shhs1-202947-profusion.xml
+shhs1-202948-profusion.xml
+shhs1-202949-profusion.xml
+shhs1-202950-profusion.xml
+shhs1-202951-profusion.xml
+shhs1-202952-profusion.xml
+shhs1-202953-profusion.xml
+shhs1-202954-profusion.xml
+shhs1-202955-profusion.xml
+shhs1-202956-profusion.xml
+shhs1-202957-profusion.xml
+shhs1-202958-profusion.xml
+shhs1-202959-profusion.xml
+shhs1-202960-profusion.xml
+shhs1-202961-profusion.xml
+shhs1-202962-profusion.xml
+shhs1-202963-profusion.xml
+shhs1-202964-profusion.xml
+shhs1-202965-profusion.xml
+shhs1-202966-profusion.xml
+shhs1-202967-profusion.xml
+shhs1-202968-profusion.xml
+shhs1-202969-profusion.xml
+shhs1-202970-profusion.xml
+shhs1-202971-profusion.xml
+shhs1-202972-profusion.xml
+shhs1-202973-profusion.xml
+shhs1-202974-profusion.xml
+shhs1-202975-profusion.xml
+shhs1-202976-profusion.xml
+shhs1-202977-profusion.xml
+shhs1-202978-profusion.xml
+shhs1-202979-profusion.xml
+shhs1-202980-profusion.xml
+shhs1-202981-profusion.xml
+shhs1-202982-profusion.xml
+shhs1-202983-profusion.xml
+shhs1-202984-profusion.xml
+shhs1-202985-profusion.xml
+shhs1-202986-profusion.xml
+shhs1-202987-profusion.xml
+shhs1-202988-profusion.xml
+shhs1-202989-profusion.xml
+shhs1-202990-profusion.xml
+shhs1-202991-profusion.xml
+shhs1-202992-profusion.xml
+shhs1-202993-profusion.xml
+shhs1-202994-profusion.xml
+shhs1-202995-profusion.xml
+shhs1-202996-profusion.xml
+shhs1-202997-profusion.xml
+shhs1-202998-profusion.xml
+shhs1-202999-profusion.xml
+shhs1-203000-profusion.xml
+shhs1-203001-profusion.xml
+shhs1-203002-profusion.xml
+shhs1-203003-profusion.xml
+shhs1-203004-profusion.xml
+shhs1-203005-profusion.xml
+shhs1-203006-profusion.xml
+shhs1-203007-profusion.xml
+shhs1-203008-profusion.xml
+shhs1-203009-profusion.xml
+shhs1-203010-profusion.xml
+shhs1-203011-profusion.xml
+shhs1-203012-profusion.xml
+shhs1-203013-profusion.xml
+shhs1-203014-profusion.xml
+shhs1-203015-profusion.xml
+shhs1-203016-profusion.xml
+shhs1-203017-profusion.xml
+shhs1-203018-profusion.xml
+shhs1-203019-profusion.xml
+shhs1-203020-profusion.xml
+shhs1-203021-profusion.xml
+shhs1-203022-profusion.xml
+shhs1-203023-profusion.xml
+shhs1-203024-profusion.xml
+shhs1-203025-profusion.xml
+shhs1-203026-profusion.xml
+shhs1-203027-profusion.xml
+shhs1-203028-profusion.xml
+shhs1-203029-profusion.xml
+shhs1-203030-profusion.xml
+shhs1-203031-profusion.xml
+shhs1-203032-profusion.xml
+shhs1-203033-profusion.xml
+shhs1-203034-profusion.xml
+shhs1-203035-profusion.xml
+shhs1-203036-profusion.xml
+shhs1-203037-profusion.xml
+shhs1-203038-profusion.xml
+shhs1-203039-profusion.xml
+shhs1-203040-profusion.xml
+shhs1-203041-profusion.xml
+shhs1-203042-profusion.xml
+shhs1-203043-profusion.xml
+shhs1-203044-profusion.xml
+shhs1-203045-profusion.xml
+shhs1-203046-profusion.xml
+shhs1-203047-profusion.xml
+shhs1-203048-profusion.xml
+shhs1-203049-profusion.xml
+shhs1-203050-profusion.xml
+shhs1-203051-profusion.xml
+shhs1-203052-profusion.xml
+shhs1-203053-profusion.xml
+shhs1-203054-profusion.xml
+shhs1-203055-profusion.xml
+shhs1-203056-profusion.xml
+shhs1-203057-profusion.xml
+shhs1-203058-profusion.xml
+shhs1-203059-profusion.xml
+shhs1-203060-profusion.xml
+shhs1-203061-profusion.xml
+shhs1-203062-profusion.xml
+shhs1-203063-profusion.xml
+shhs1-203064-profusion.xml
+shhs1-203065-profusion.xml
+shhs1-203066-profusion.xml
+shhs1-203067-profusion.xml
+shhs1-203068-profusion.xml
+shhs1-203069-profusion.xml
+shhs1-203070-profusion.xml
+shhs1-203071-profusion.xml
+shhs1-203072-profusion.xml
+shhs1-203073-profusion.xml
+shhs1-203074-profusion.xml
+shhs1-203075-profusion.xml
+shhs1-203076-profusion.xml
+shhs1-203077-profusion.xml
+shhs1-203078-profusion.xml
+shhs1-203079-profusion.xml
+shhs1-203080-profusion.xml
+shhs1-203081-profusion.xml
+shhs1-203082-profusion.xml
+shhs1-203083-profusion.xml
+shhs1-203084-profusion.xml
+shhs1-203085-profusion.xml
+shhs1-203086-profusion.xml
+shhs1-203087-profusion.xml
+shhs1-203088-profusion.xml
+shhs1-203089-profusion.xml
+shhs1-203090-profusion.xml
+shhs1-203091-profusion.xml
+shhs1-203092-profusion.xml
+shhs1-203093-profusion.xml
+shhs1-203094-profusion.xml
+shhs1-203095-profusion.xml
+shhs1-203096-profusion.xml
+shhs1-203097-profusion.xml
+shhs1-203098-profusion.xml
+shhs1-203099-profusion.xml
+shhs1-203100-profusion.xml
+shhs1-203101-profusion.xml
+shhs1-203102-profusion.xml
+shhs1-203103-profusion.xml
+shhs1-203104-profusion.xml
+shhs1-203105-profusion.xml
+shhs1-203106-profusion.xml
+shhs1-203107-profusion.xml
+shhs1-203108-profusion.xml
+shhs1-203109-profusion.xml
+shhs1-203110-profusion.xml
+shhs1-203111-profusion.xml
+shhs1-203112-profusion.xml
+shhs1-203113-profusion.xml
+shhs1-203114-profusion.xml
+shhs1-203115-profusion.xml
+shhs1-203116-profusion.xml
+shhs1-203117-profusion.xml
+shhs1-203118-profusion.xml
+shhs1-203119-profusion.xml
+shhs1-203120-profusion.xml
+shhs1-203121-profusion.xml
+shhs1-203122-profusion.xml
+shhs1-203123-profusion.xml
+shhs1-203124-profusion.xml
+shhs1-203125-profusion.xml
+shhs1-203126-profusion.xml
+shhs1-203127-profusion.xml
+shhs1-203128-profusion.xml
+shhs1-203129-profusion.xml
+shhs1-203130-profusion.xml
+shhs1-203131-profusion.xml
+shhs1-203132-profusion.xml
+shhs1-203133-profusion.xml
+shhs1-203134-profusion.xml
+shhs1-203135-profusion.xml
+shhs1-203136-profusion.xml
+shhs1-203137-profusion.xml
+shhs1-203138-profusion.xml
+shhs1-203139-profusion.xml
+shhs1-203140-profusion.xml
+shhs1-203141-profusion.xml
+shhs1-203142-profusion.xml
+shhs1-203143-profusion.xml
+shhs1-203144-profusion.xml
+shhs1-203145-profusion.xml
+shhs1-203146-profusion.xml
+shhs1-203147-profusion.xml
+shhs1-203148-profusion.xml
+shhs1-203149-profusion.xml
+shhs1-203150-profusion.xml
+shhs1-203151-profusion.xml
+shhs1-203152-profusion.xml
+shhs1-203153-profusion.xml
+shhs1-203154-profusion.xml
+shhs1-203155-profusion.xml
+shhs1-203156-profusion.xml
+shhs1-203157-profusion.xml
+shhs1-203158-profusion.xml
+shhs1-203159-profusion.xml
+shhs1-203160-profusion.xml
+shhs1-203161-profusion.xml
+shhs1-203162-profusion.xml
+shhs1-203163-profusion.xml
+shhs1-203164-profusion.xml
+shhs1-203165-profusion.xml
+shhs1-203166-profusion.xml
+shhs1-203167-profusion.xml
+shhs1-203168-profusion.xml
+shhs1-203170-profusion.xml
+shhs1-203171-profusion.xml
+shhs1-203172-profusion.xml
+shhs1-203173-profusion.xml
+shhs1-203174-profusion.xml
+shhs1-203175-profusion.xml
+shhs1-203176-profusion.xml
+shhs1-203177-profusion.xml
+shhs1-203178-profusion.xml
+shhs1-203179-profusion.xml
+shhs1-203180-profusion.xml
+shhs1-203181-profusion.xml
+shhs1-203182-profusion.xml
+shhs1-203183-profusion.xml
+shhs1-203184-profusion.xml
+shhs1-203185-profusion.xml
+shhs1-203186-profusion.xml
+shhs1-203187-profusion.xml
+shhs1-203188-profusion.xml
+shhs1-203189-profusion.xml
+shhs1-203190-profusion.xml
+shhs1-203191-profusion.xml
+shhs1-203192-profusion.xml
+shhs1-203193-profusion.xml
+shhs1-203194-profusion.xml
+shhs1-203195-profusion.xml
+shhs1-203196-profusion.xml
+shhs1-203197-profusion.xml
+shhs1-203198-profusion.xml
+shhs1-203199-profusion.xml
+shhs1-203200-profusion.xml
+shhs1-203201-profusion.xml
+shhs1-203202-profusion.xml
+shhs1-203203-profusion.xml
+shhs1-203204-profusion.xml
+shhs1-203205-profusion.xml
+shhs1-203206-profusion.xml
+shhs1-203207-profusion.xml
+shhs1-203208-profusion.xml
+shhs1-203209-profusion.xml
+shhs1-203210-profusion.xml
+shhs1-203211-profusion.xml
+shhs1-203212-profusion.xml
+shhs1-203213-profusion.xml
+shhs1-203214-profusion.xml
+shhs1-203215-profusion.xml
+shhs1-203216-profusion.xml
+shhs1-203217-profusion.xml
+shhs1-203218-profusion.xml
+shhs1-203219-profusion.xml
+shhs1-203220-profusion.xml
+shhs1-203221-profusion.xml
+shhs1-203222-profusion.xml
+shhs1-203223-profusion.xml
+shhs1-203224-profusion.xml
+shhs1-203225-profusion.xml
+shhs1-203226-profusion.xml
+shhs1-203227-profusion.xml
+shhs1-203228-profusion.xml
+shhs1-203229-profusion.xml
+shhs1-203230-profusion.xml
+shhs1-203231-profusion.xml
+shhs1-203232-profusion.xml
+shhs1-203233-profusion.xml
+shhs1-203234-profusion.xml
+shhs1-203235-profusion.xml
+shhs1-203236-profusion.xml
+shhs1-203237-profusion.xml
+shhs1-203238-profusion.xml
+shhs1-203239-profusion.xml
+shhs1-203240-profusion.xml
+shhs1-203241-profusion.xml
+shhs1-203242-profusion.xml
+shhs1-203243-profusion.xml
+shhs1-203244-profusion.xml
+shhs1-203245-profusion.xml
+shhs1-203246-profusion.xml
+shhs1-203247-profusion.xml
+shhs1-203248-profusion.xml
+shhs1-203249-profusion.xml
+shhs1-203250-profusion.xml
+shhs1-203251-profusion.xml
+shhs1-203252-profusion.xml
+shhs1-203253-profusion.xml
+shhs1-203254-profusion.xml
+shhs1-203255-profusion.xml
+shhs1-203256-profusion.xml
+shhs1-203257-profusion.xml
+shhs1-203258-profusion.xml
+shhs1-203259-profusion.xml
+shhs1-203260-profusion.xml
+shhs1-203261-profusion.xml
+shhs1-203262-profusion.xml
+shhs1-203263-profusion.xml
+shhs1-203264-profusion.xml
+shhs1-203265-profusion.xml
+shhs1-203266-profusion.xml
+shhs1-203267-profusion.xml
+shhs1-203268-profusion.xml
+shhs1-203269-profusion.xml
+shhs1-203270-profusion.xml
+shhs1-203271-profusion.xml
+shhs1-203272-profusion.xml
+shhs1-203273-profusion.xml
+shhs1-203274-profusion.xml
+shhs1-203275-profusion.xml
+shhs1-203276-profusion.xml
+shhs1-203277-profusion.xml
+shhs1-203278-profusion.xml
+shhs1-203279-profusion.xml
+shhs1-203280-profusion.xml
+shhs1-203281-profusion.xml
+shhs1-203282-profusion.xml
+shhs1-203283-profusion.xml
+shhs1-203284-profusion.xml
+shhs1-203285-profusion.xml
+shhs1-203286-profusion.xml
+shhs1-203287-profusion.xml
+shhs1-203288-profusion.xml
+shhs1-203289-profusion.xml
+shhs1-203290-profusion.xml
+shhs1-203291-profusion.xml
+shhs1-203292-profusion.xml
+shhs1-203293-profusion.xml
+shhs1-203294-profusion.xml
+shhs1-203295-profusion.xml
+shhs1-203296-profusion.xml
+shhs1-203297-profusion.xml
+shhs1-203298-profusion.xml
+shhs1-203299-profusion.xml
+shhs1-203300-profusion.xml
+shhs1-203301-profusion.xml
+shhs1-203302-profusion.xml
+shhs1-203303-profusion.xml
+shhs1-203304-profusion.xml
+shhs1-203305-profusion.xml
+shhs1-203306-profusion.xml
+shhs1-203307-profusion.xml
+shhs1-203308-profusion.xml
+shhs1-203309-profusion.xml
+shhs1-203310-profusion.xml
+shhs1-203311-profusion.xml
+shhs1-203312-profusion.xml
+shhs1-203313-profusion.xml
+shhs1-203314-profusion.xml
+shhs1-203315-profusion.xml
+shhs1-203316-profusion.xml
+shhs1-203317-profusion.xml
+shhs1-203318-profusion.xml
+shhs1-203319-profusion.xml
+shhs1-203320-profusion.xml
+shhs1-203321-profusion.xml
+shhs1-203322-profusion.xml
+shhs1-203323-profusion.xml
+shhs1-203324-profusion.xml
+shhs1-203325-profusion.xml
+shhs1-203326-profusion.xml
+shhs1-203327-profusion.xml
+shhs1-203328-profusion.xml
+shhs1-203329-profusion.xml
+shhs1-203330-profusion.xml
+shhs1-203331-profusion.xml
+shhs1-203332-profusion.xml
+shhs1-203333-profusion.xml
+shhs1-203334-profusion.xml
+shhs1-203335-profusion.xml
+shhs1-203336-profusion.xml
+shhs1-203337-profusion.xml
+shhs1-203338-profusion.xml
+shhs1-203339-profusion.xml
+shhs1-203340-profusion.xml
+shhs1-203341-profusion.xml
+shhs1-203342-profusion.xml
+shhs1-203343-profusion.xml
+shhs1-203344-profusion.xml
+shhs1-203345-profusion.xml
+shhs1-203346-profusion.xml
+shhs1-203347-profusion.xml
+shhs1-203348-profusion.xml
+shhs1-203349-profusion.xml
+shhs1-203350-profusion.xml
+shhs1-203351-profusion.xml
+shhs1-203352-profusion.xml
+shhs1-203353-profusion.xml
+shhs1-203354-profusion.xml
+shhs1-203355-profusion.xml
+shhs1-203356-profusion.xml
+shhs1-203357-profusion.xml
+shhs1-203358-profusion.xml
+shhs1-203359-profusion.xml
+shhs1-203360-profusion.xml
+shhs1-203361-profusion.xml
+shhs1-203362-profusion.xml
+shhs1-203363-profusion.xml
+shhs1-203364-profusion.xml
+shhs1-203365-profusion.xml
+shhs1-203366-profusion.xml
+shhs1-203367-profusion.xml
+shhs1-203368-profusion.xml
+shhs1-203369-profusion.xml
+shhs1-203370-profusion.xml
+shhs1-203371-profusion.xml
+shhs1-203372-profusion.xml
+shhs1-203373-profusion.xml
+shhs1-203374-profusion.xml
+shhs1-203375-profusion.xml
+shhs1-203376-profusion.xml
+shhs1-203377-profusion.xml
+shhs1-203378-profusion.xml
+shhs1-203379-profusion.xml
+shhs1-203380-profusion.xml
+shhs1-203381-profusion.xml
+shhs1-203382-profusion.xml
+shhs1-203383-profusion.xml
+shhs1-203384-profusion.xml
+shhs1-203385-profusion.xml
+shhs1-203386-profusion.xml
+shhs1-203387-profusion.xml
+shhs1-203388-profusion.xml
+shhs1-203389-profusion.xml
+shhs1-203390-profusion.xml
+shhs1-203391-profusion.xml
+shhs1-203392-profusion.xml
+shhs1-203393-profusion.xml
+shhs1-203394-profusion.xml
+shhs1-203395-profusion.xml
+shhs1-203396-profusion.xml
+shhs1-203397-profusion.xml
+shhs1-203398-profusion.xml
+shhs1-203399-profusion.xml
+shhs1-203400-profusion.xml
+shhs1-203401-profusion.xml
+shhs1-203402-profusion.xml
+shhs1-203403-profusion.xml
+shhs1-203404-profusion.xml
+shhs1-203405-profusion.xml
+shhs1-203406-profusion.xml
+shhs1-203407-profusion.xml
+shhs1-203408-profusion.xml
+shhs1-203409-profusion.xml
+shhs1-203410-profusion.xml
+shhs1-203411-profusion.xml
+shhs1-203412-profusion.xml
+shhs1-203413-profusion.xml
+shhs1-203414-profusion.xml
+shhs1-203415-profusion.xml
+shhs1-203416-profusion.xml
+shhs1-203417-profusion.xml
+shhs1-203418-profusion.xml
+shhs1-203419-profusion.xml
+shhs1-203420-profusion.xml
+shhs1-203421-profusion.xml
+shhs1-203422-profusion.xml
+shhs1-203423-profusion.xml
+shhs1-203424-profusion.xml
+shhs1-203425-profusion.xml
+shhs1-203426-profusion.xml
+shhs1-203427-profusion.xml
+shhs1-203428-profusion.xml
+shhs1-203429-profusion.xml
+shhs1-203430-profusion.xml
+shhs1-203431-profusion.xml
+shhs1-203432-profusion.xml
+shhs1-203433-profusion.xml
+shhs1-203434-profusion.xml
+shhs1-203435-profusion.xml
+shhs1-203436-profusion.xml
+shhs1-203437-profusion.xml
+shhs1-203438-profusion.xml
+shhs1-203439-profusion.xml
+shhs1-203440-profusion.xml
+shhs1-203441-profusion.xml
+shhs1-203442-profusion.xml
+shhs1-203443-profusion.xml
+shhs1-203444-profusion.xml
+shhs1-203445-profusion.xml
+shhs1-203446-profusion.xml
+shhs1-203447-profusion.xml
+shhs1-203448-profusion.xml
+shhs1-203449-profusion.xml
+shhs1-203450-profusion.xml
+shhs1-203451-profusion.xml
+shhs1-203452-profusion.xml
+shhs1-203453-profusion.xml
+shhs1-203454-profusion.xml
+shhs1-203455-profusion.xml
+shhs1-203456-profusion.xml
+shhs1-203457-profusion.xml
+shhs1-203458-profusion.xml
+shhs1-203459-profusion.xml
+shhs1-203460-profusion.xml
+shhs1-203461-profusion.xml
+shhs1-203462-profusion.xml
+shhs1-203463-profusion.xml
+shhs1-203464-profusion.xml
+shhs1-203465-profusion.xml
+shhs1-203466-profusion.xml
+shhs1-203467-profusion.xml
+shhs1-203468-profusion.xml
+shhs1-203469-profusion.xml
+shhs1-203470-profusion.xml
+shhs1-203471-profusion.xml
+shhs1-203472-profusion.xml
+shhs1-203473-profusion.xml
+shhs1-203474-profusion.xml
+shhs1-203475-profusion.xml
+shhs1-203476-profusion.xml
+shhs1-203477-profusion.xml
+shhs1-203478-profusion.xml
+shhs1-203479-profusion.xml
+shhs1-203480-profusion.xml
+shhs1-203481-profusion.xml
+shhs1-203482-profusion.xml
+shhs1-203483-profusion.xml
+shhs1-203484-profusion.xml
+shhs1-203485-profusion.xml
+shhs1-203486-profusion.xml
+shhs1-203487-profusion.xml
+shhs1-203488-profusion.xml
+shhs1-203489-profusion.xml
+shhs1-203490-profusion.xml
+shhs1-203491-profusion.xml
+shhs1-203492-profusion.xml
+shhs1-203493-profusion.xml
+shhs1-203494-profusion.xml
+shhs1-203495-profusion.xml
+shhs1-203496-profusion.xml
+shhs1-203497-profusion.xml
+shhs1-203498-profusion.xml
+shhs1-203499-profusion.xml
+shhs1-203500-profusion.xml
+shhs1-203501-profusion.xml
+shhs1-203502-profusion.xml
+shhs1-203503-profusion.xml
+shhs1-203504-profusion.xml
+shhs1-203505-profusion.xml
+shhs1-203506-profusion.xml
+shhs1-203507-profusion.xml
+shhs1-203508-profusion.xml
+shhs1-203509-profusion.xml
+shhs1-203510-profusion.xml
+shhs1-203511-profusion.xml
+shhs1-203512-profusion.xml
+shhs1-203513-profusion.xml
+shhs1-203514-profusion.xml
+shhs1-203515-profusion.xml
+shhs1-203516-profusion.xml
+shhs1-203517-profusion.xml
+shhs1-203518-profusion.xml
+shhs1-203519-profusion.xml
+shhs1-203520-profusion.xml
+shhs1-203521-profusion.xml
+shhs1-203522-profusion.xml
+shhs1-203523-profusion.xml
+shhs1-203524-profusion.xml
+shhs1-203525-profusion.xml
+shhs1-203526-profusion.xml
+shhs1-203527-profusion.xml
+shhs1-203528-profusion.xml
+shhs1-203529-profusion.xml
+shhs1-203530-profusion.xml
+shhs1-203531-profusion.xml
+shhs1-203532-profusion.xml
+shhs1-203533-profusion.xml
+shhs1-203534-profusion.xml
+shhs1-203535-profusion.xml
+shhs1-203536-profusion.xml
+shhs1-203537-profusion.xml
+shhs1-203538-profusion.xml
+shhs1-203539-profusion.xml
+shhs1-203540-profusion.xml
+shhs1-203541-profusion.xml
+shhs1-203542-profusion.xml
+shhs1-203543-profusion.xml
+shhs1-203544-profusion.xml
+shhs1-203545-profusion.xml
+shhs1-203546-profusion.xml
+shhs1-203547-profusion.xml
+shhs1-203548-profusion.xml
+shhs1-203549-profusion.xml
+shhs1-203550-profusion.xml
+shhs1-203551-profusion.xml
+shhs1-203552-profusion.xml
+shhs1-203553-profusion.xml
+shhs1-203554-profusion.xml
+shhs1-203555-profusion.xml
+shhs1-203556-profusion.xml
+shhs1-203557-profusion.xml
+shhs1-203558-profusion.xml
+shhs1-203559-profusion.xml
+shhs1-203560-profusion.xml
+shhs1-203561-profusion.xml
+shhs1-203562-profusion.xml
+shhs1-203563-profusion.xml
+shhs1-203564-profusion.xml
+shhs1-203565-profusion.xml
+shhs1-203566-profusion.xml
+shhs1-203567-profusion.xml
+shhs1-203568-profusion.xml
+shhs1-203569-profusion.xml
+shhs1-203570-profusion.xml
+shhs1-203571-profusion.xml
+shhs1-203572-profusion.xml
+shhs1-203573-profusion.xml
+shhs1-203574-profusion.xml
+shhs1-203575-profusion.xml
+shhs1-203576-profusion.xml
+shhs1-203577-profusion.xml
+shhs1-203578-profusion.xml
+shhs1-203579-profusion.xml
+shhs1-203580-profusion.xml
+shhs1-203581-profusion.xml
+shhs1-203582-profusion.xml
+shhs1-203583-profusion.xml
+shhs1-203584-profusion.xml
+shhs1-203585-profusion.xml
+shhs1-203586-profusion.xml
+shhs1-203587-profusion.xml
+shhs1-203588-profusion.xml
+shhs1-203589-profusion.xml
+shhs1-203590-profusion.xml
+shhs1-203591-profusion.xml
+shhs1-203592-profusion.xml
+shhs1-203593-profusion.xml
+shhs1-203594-profusion.xml
+shhs1-203595-profusion.xml
+shhs1-203596-profusion.xml
+shhs1-203597-profusion.xml
+shhs1-203598-profusion.xml
+shhs1-203599-profusion.xml
+shhs1-203600-profusion.xml
+shhs1-203601-profusion.xml
+shhs1-203602-profusion.xml
+shhs1-203603-profusion.xml
+shhs1-203604-profusion.xml
+shhs1-203605-profusion.xml
+shhs1-203606-profusion.xml
+shhs1-203607-profusion.xml
+shhs1-203608-profusion.xml
+shhs1-203609-profusion.xml
+shhs1-203610-profusion.xml
+shhs1-203611-profusion.xml
+shhs1-203612-profusion.xml
+shhs1-203613-profusion.xml
+shhs1-203614-profusion.xml
+shhs1-203615-profusion.xml
+shhs1-203616-profusion.xml
+shhs1-203617-profusion.xml
+shhs1-203618-profusion.xml
+shhs1-203619-profusion.xml
+shhs1-203620-profusion.xml
+shhs1-203621-profusion.xml
+shhs1-203622-profusion.xml
+shhs1-203623-profusion.xml
+shhs1-203624-profusion.xml
+shhs1-203625-profusion.xml
+shhs1-203626-profusion.xml
+shhs1-203627-profusion.xml
+shhs1-203628-profusion.xml
+shhs1-203629-profusion.xml
+shhs1-203630-profusion.xml
+shhs1-203631-profusion.xml
+shhs1-203632-profusion.xml
+shhs1-203633-profusion.xml
+shhs1-203634-profusion.xml
+shhs1-203635-profusion.xml
+shhs1-203636-profusion.xml
+shhs1-203637-profusion.xml
+shhs1-203638-profusion.xml
+shhs1-203639-profusion.xml
+shhs1-203640-profusion.xml
+shhs1-203641-profusion.xml
+shhs1-203642-profusion.xml
+shhs1-203643-profusion.xml
+shhs1-203644-profusion.xml
+shhs1-203645-profusion.xml
+shhs1-203646-profusion.xml
+shhs1-203647-profusion.xml
+shhs1-203648-profusion.xml
+shhs1-203649-profusion.xml
+shhs1-203650-profusion.xml
+shhs1-203651-profusion.xml
+shhs1-203652-profusion.xml
+shhs1-203653-profusion.xml
+shhs1-203654-profusion.xml
+shhs1-203655-profusion.xml
+shhs1-203656-profusion.xml
+shhs1-203657-profusion.xml
+shhs1-203658-profusion.xml
+shhs1-203659-profusion.xml
+shhs1-203660-profusion.xml
+shhs1-203661-profusion.xml
+shhs1-203662-profusion.xml
+shhs1-203663-profusion.xml
+shhs1-203664-profusion.xml
+shhs1-203665-profusion.xml
+shhs1-203666-profusion.xml
+shhs1-203667-profusion.xml
+shhs1-203668-profusion.xml
+shhs1-203669-profusion.xml
+shhs1-203670-profusion.xml
+shhs1-203671-profusion.xml
+shhs1-203672-profusion.xml
+shhs1-203673-profusion.xml
+shhs1-203674-profusion.xml
+shhs1-203675-profusion.xml
+shhs1-203676-profusion.xml
+shhs1-203677-profusion.xml
+shhs1-203678-profusion.xml
+shhs1-203679-profusion.xml
+shhs1-203680-profusion.xml
+shhs1-203681-profusion.xml
+shhs1-203682-profusion.xml
+shhs1-203683-profusion.xml
+shhs1-203684-profusion.xml
+shhs1-203685-profusion.xml
+shhs1-203686-profusion.xml
+shhs1-203687-profusion.xml
+shhs1-203688-profusion.xml
+shhs1-203689-profusion.xml
+shhs1-203690-profusion.xml
+shhs1-203691-profusion.xml
+shhs1-203692-profusion.xml
+shhs1-203693-profusion.xml
+shhs1-203694-profusion.xml
+shhs1-203695-profusion.xml
+shhs1-203696-profusion.xml
+shhs1-203697-profusion.xml
+shhs1-203698-profusion.xml
+shhs1-203699-profusion.xml
+shhs1-203700-profusion.xml
+shhs1-203701-profusion.xml
+shhs1-203702-profusion.xml
+shhs1-203703-profusion.xml
+shhs1-203704-profusion.xml
+shhs1-203705-profusion.xml
+shhs1-203706-profusion.xml
+shhs1-203707-profusion.xml
+shhs1-203708-profusion.xml
+shhs1-203709-profusion.xml
+shhs1-203710-profusion.xml
+shhs1-203711-profusion.xml
+shhs1-203712-profusion.xml
+shhs1-203713-profusion.xml
+shhs1-203714-profusion.xml
+shhs1-203715-profusion.xml
+shhs1-203716-profusion.xml
+shhs1-203717-profusion.xml
+shhs1-203718-profusion.xml
+shhs1-203719-profusion.xml
+shhs1-203720-profusion.xml
+shhs1-203721-profusion.xml
+shhs1-203722-profusion.xml
+shhs1-203723-profusion.xml
+shhs1-203724-profusion.xml
+shhs1-203725-profusion.xml
+shhs1-203726-profusion.xml
+shhs1-203727-profusion.xml
+shhs1-203728-profusion.xml
+shhs1-203729-profusion.xml
+shhs1-203730-profusion.xml
+shhs1-203731-profusion.xml
+shhs1-203732-profusion.xml
+shhs1-203733-profusion.xml
+shhs1-203734-profusion.xml
+shhs1-203735-profusion.xml
+shhs1-203736-profusion.xml
+shhs1-203737-profusion.xml
+shhs1-203738-profusion.xml
+shhs1-203739-profusion.xml
+shhs1-203740-profusion.xml
+shhs1-203741-profusion.xml
+shhs1-203742-profusion.xml
+shhs1-203743-profusion.xml
+shhs1-203744-profusion.xml
+shhs1-203745-profusion.xml
+shhs1-203746-profusion.xml
+shhs1-203747-profusion.xml
+shhs1-203748-profusion.xml
+shhs1-203749-profusion.xml
+shhs1-203750-profusion.xml
+shhs1-203751-profusion.xml
+shhs1-203752-profusion.xml
+shhs1-203753-profusion.xml
+shhs1-203754-profusion.xml
+shhs1-203755-profusion.xml
+shhs1-203756-profusion.xml
+shhs1-203757-profusion.xml
+shhs1-203758-profusion.xml
+shhs1-203759-profusion.xml
+shhs1-203760-profusion.xml
+shhs1-203761-profusion.xml
+shhs1-203762-profusion.xml
+shhs1-203763-profusion.xml
+shhs1-203764-profusion.xml
+shhs1-203765-profusion.xml
+shhs1-203766-profusion.xml
+shhs1-203767-profusion.xml
+shhs1-203768-profusion.xml
+shhs1-203769-profusion.xml
+shhs1-203770-profusion.xml
+shhs1-203771-profusion.xml
+shhs1-203772-profusion.xml
+shhs1-203773-profusion.xml
+shhs1-203774-profusion.xml
+shhs1-203775-profusion.xml
+shhs1-203776-profusion.xml
+shhs1-203777-profusion.xml
+shhs1-203778-profusion.xml
+shhs1-203779-profusion.xml
+shhs1-203780-profusion.xml
+shhs1-203781-profusion.xml
+shhs1-203782-profusion.xml
+shhs1-203783-profusion.xml
+shhs1-203784-profusion.xml
+shhs1-203785-profusion.xml
+shhs1-203786-profusion.xml
+shhs1-203787-profusion.xml
+shhs1-203788-profusion.xml
+shhs1-203789-profusion.xml
+shhs1-203790-profusion.xml
+shhs1-203791-profusion.xml
+shhs1-203792-profusion.xml
+shhs1-203793-profusion.xml
+shhs1-203794-profusion.xml
+shhs1-203795-profusion.xml
+shhs1-203796-profusion.xml
+shhs1-203797-profusion.xml
+shhs1-203798-profusion.xml
+shhs1-203799-profusion.xml
+shhs1-203800-profusion.xml
+shhs1-203801-profusion.xml
+shhs1-203802-profusion.xml
+shhs1-203803-profusion.xml
+shhs1-203804-profusion.xml
+shhs1-203805-profusion.xml
+shhs1-203806-profusion.xml
+shhs1-203807-profusion.xml
+shhs1-203808-profusion.xml
+shhs1-203809-profusion.xml
+shhs1-203810-profusion.xml
+shhs1-203811-profusion.xml
+shhs1-203812-profusion.xml
+shhs1-203813-profusion.xml
+shhs1-203814-profusion.xml
+shhs1-203815-profusion.xml
+shhs1-203816-profusion.xml
+shhs1-203817-profusion.xml
+shhs1-203818-profusion.xml
+shhs1-203819-profusion.xml
+shhs1-203820-profusion.xml
+shhs1-203821-profusion.xml
+shhs1-203822-profusion.xml
+shhs1-203823-profusion.xml
+shhs1-203824-profusion.xml
+shhs1-203825-profusion.xml
+shhs1-203826-profusion.xml
+shhs1-203827-profusion.xml
+shhs1-203828-profusion.xml
+shhs1-203829-profusion.xml
+shhs1-203830-profusion.xml
+shhs1-203831-profusion.xml
+shhs1-203832-profusion.xml
+shhs1-203833-profusion.xml
+shhs1-203834-profusion.xml
+shhs1-203835-profusion.xml
+shhs1-203836-profusion.xml
+shhs1-203837-profusion.xml
+shhs1-203838-profusion.xml
+shhs1-203839-profusion.xml
+shhs1-203840-profusion.xml
+shhs1-203841-profusion.xml
+shhs1-203842-profusion.xml
+shhs1-203843-profusion.xml
+shhs1-203844-profusion.xml
+shhs1-203845-profusion.xml
+shhs1-203846-profusion.xml
+shhs1-203847-profusion.xml
+shhs1-203848-profusion.xml
+shhs1-203849-profusion.xml
+shhs1-203850-profusion.xml
+shhs1-203851-profusion.xml
+shhs1-203852-profusion.xml
+shhs1-203853-profusion.xml
+shhs1-203854-profusion.xml
+shhs1-203855-profusion.xml
+shhs1-203856-profusion.xml
+shhs1-203857-profusion.xml
+shhs1-203858-profusion.xml
+shhs1-203859-profusion.xml
+shhs1-203860-profusion.xml
+shhs1-203861-profusion.xml
+shhs1-203862-profusion.xml
+shhs1-203863-profusion.xml
+shhs1-203864-profusion.xml
+shhs1-203865-profusion.xml
+shhs1-203866-profusion.xml
+shhs1-203867-profusion.xml
+shhs1-203868-profusion.xml
+shhs1-203869-profusion.xml
+shhs1-203870-profusion.xml
+shhs1-203871-profusion.xml
+shhs1-203872-profusion.xml
+shhs1-203873-profusion.xml
+shhs1-203874-profusion.xml
+shhs1-203875-profusion.xml
+shhs1-203876-profusion.xml
+shhs1-203877-profusion.xml
+shhs1-203878-profusion.xml
+shhs1-203879-profusion.xml
+shhs1-203880-profusion.xml
+shhs1-203881-profusion.xml
+shhs1-203882-profusion.xml
+shhs1-203883-profusion.xml
+shhs1-203884-profusion.xml
+shhs1-203885-profusion.xml
+shhs1-203886-profusion.xml
+shhs1-203887-profusion.xml
+shhs1-203888-profusion.xml
+shhs1-203889-profusion.xml
+shhs1-203890-profusion.xml
+shhs1-203891-profusion.xml
+shhs1-203892-profusion.xml
+shhs1-203893-profusion.xml
+shhs1-203894-profusion.xml
+shhs1-203895-profusion.xml
+shhs1-203896-profusion.xml
+shhs1-203897-profusion.xml
+shhs1-203898-profusion.xml
+shhs1-203899-profusion.xml
+shhs1-203900-profusion.xml
+shhs1-203901-profusion.xml
+shhs1-203902-profusion.xml
+shhs1-203903-profusion.xml
+shhs1-203904-profusion.xml
+shhs1-203905-profusion.xml
+shhs1-203906-profusion.xml
+shhs1-203907-profusion.xml
+shhs1-203908-profusion.xml
+shhs1-203909-profusion.xml
+shhs1-203910-profusion.xml
+shhs1-203911-profusion.xml
+shhs1-203912-profusion.xml
+shhs1-203913-profusion.xml
+shhs1-203914-profusion.xml
+shhs1-203915-profusion.xml
+shhs1-203916-profusion.xml
+shhs1-203917-profusion.xml
+shhs1-203918-profusion.xml
+shhs1-203919-profusion.xml
+shhs1-203920-profusion.xml
+shhs1-203921-profusion.xml
+shhs1-203922-profusion.xml
+shhs1-203923-profusion.xml
+shhs1-203924-profusion.xml
+shhs1-203925-profusion.xml
+shhs1-203926-profusion.xml
+shhs1-203927-profusion.xml
+shhs1-203928-profusion.xml
+shhs1-203929-profusion.xml
+shhs1-203930-profusion.xml
+shhs1-203931-profusion.xml
+shhs1-203932-profusion.xml
+shhs1-203933-profusion.xml
+shhs1-203934-profusion.xml
+shhs1-203935-profusion.xml
+shhs1-203936-profusion.xml
+shhs1-203937-profusion.xml
+shhs1-203938-profusion.xml
+shhs1-203939-profusion.xml
+shhs1-203940-profusion.xml
+shhs1-203941-profusion.xml
+shhs1-203942-profusion.xml
+shhs1-203943-profusion.xml
+shhs1-203944-profusion.xml
+shhs1-203945-profusion.xml
+shhs1-203946-profusion.xml
+shhs1-203947-profusion.xml
+shhs1-203948-profusion.xml
+shhs1-203949-profusion.xml
+shhs1-203950-profusion.xml
+shhs1-203951-profusion.xml
+shhs1-203952-profusion.xml
+shhs1-203953-profusion.xml
+shhs1-203954-profusion.xml
+shhs1-203955-profusion.xml
+shhs1-203956-profusion.xml
+shhs1-203957-profusion.xml
+shhs1-203958-profusion.xml
+shhs1-203959-profusion.xml
+shhs1-203960-profusion.xml
+shhs1-203961-profusion.xml
+shhs1-203962-profusion.xml
+shhs1-203963-profusion.xml
+shhs1-203964-profusion.xml
+shhs1-203965-profusion.xml
+shhs1-203966-profusion.xml
+shhs1-203967-profusion.xml
+shhs1-203968-profusion.xml
+shhs1-203969-profusion.xml
+shhs1-203970-profusion.xml
+shhs1-203971-profusion.xml
+shhs1-203972-profusion.xml
+shhs1-203973-profusion.xml
+shhs1-203974-profusion.xml
+shhs1-203975-profusion.xml
+shhs1-203976-profusion.xml
+shhs1-203977-profusion.xml
+shhs1-203978-profusion.xml
+shhs1-203979-profusion.xml
+shhs1-203980-profusion.xml
+shhs1-203981-profusion.xml
+shhs1-203982-profusion.xml
+shhs1-203983-profusion.xml
+shhs1-203984-profusion.xml
+shhs1-203985-profusion.xml
+shhs1-203986-profusion.xml
+shhs1-203987-profusion.xml
+shhs1-203988-profusion.xml
+shhs1-203989-profusion.xml
+shhs1-203990-profusion.xml
+shhs1-203991-profusion.xml
+shhs1-203992-profusion.xml
+shhs1-203993-profusion.xml
+shhs1-203994-profusion.xml
+shhs1-203995-profusion.xml
+shhs1-203996-profusion.xml
+shhs1-203997-profusion.xml
+shhs1-203998-profusion.xml
+shhs1-203999-profusion.xml
+shhs1-204000-profusion.xml
+shhs1-204001-profusion.xml
+shhs1-204002-profusion.xml
+shhs1-204003-profusion.xml
+shhs1-204004-profusion.xml
+shhs1-204005-profusion.xml
+shhs1-204006-profusion.xml
+shhs1-204007-profusion.xml
+shhs1-204008-profusion.xml
+shhs1-204009-profusion.xml
+shhs1-204010-profusion.xml
+shhs1-204011-profusion.xml
+shhs1-204012-profusion.xml
+shhs1-204013-profusion.xml
+shhs1-204014-profusion.xml
+shhs1-204015-profusion.xml
+shhs1-204016-profusion.xml
+shhs1-204017-profusion.xml
+shhs1-204018-profusion.xml
+shhs1-204019-profusion.xml
+shhs1-204020-profusion.xml
+shhs1-204021-profusion.xml
+shhs1-204022-profusion.xml
+shhs1-204023-profusion.xml
+shhs1-204024-profusion.xml
+shhs1-204025-profusion.xml
+shhs1-204026-profusion.xml
+shhs1-204027-profusion.xml
+shhs1-204028-profusion.xml
+shhs1-204029-profusion.xml
+shhs1-204030-profusion.xml
+shhs1-204031-profusion.xml
+shhs1-204032-profusion.xml
+shhs1-204033-profusion.xml
+shhs1-204034-profusion.xml
+shhs1-204035-profusion.xml
+shhs1-204036-profusion.xml
+shhs1-204037-profusion.xml
+shhs1-204038-profusion.xml
+shhs1-204039-profusion.xml
+shhs1-204040-profusion.xml
+shhs1-204041-profusion.xml
+shhs1-204042-profusion.xml
+shhs1-204043-profusion.xml
+shhs1-204044-profusion.xml
+shhs1-204045-profusion.xml
+shhs1-204046-profusion.xml
+shhs1-204047-profusion.xml
+shhs1-204048-profusion.xml
+shhs1-204049-profusion.xml
+shhs1-204050-profusion.xml
+shhs1-204051-profusion.xml
+shhs1-204052-profusion.xml
+shhs1-204053-profusion.xml
+shhs1-204054-profusion.xml
+shhs1-204055-profusion.xml
+shhs1-204056-profusion.xml
+shhs1-204057-profusion.xml
+shhs1-204058-profusion.xml
+shhs1-204059-profusion.xml
+shhs1-204060-profusion.xml
+shhs1-204061-profusion.xml
+shhs1-204062-profusion.xml
+shhs1-204063-profusion.xml
+shhs1-204064-profusion.xml
+shhs1-204065-profusion.xml
+shhs1-204066-profusion.xml
+shhs1-204067-profusion.xml
+shhs1-204068-profusion.xml
+shhs1-204069-profusion.xml
+shhs1-204070-profusion.xml
+shhs1-204071-profusion.xml
+shhs1-204072-profusion.xml
+shhs1-204073-profusion.xml
+shhs1-204074-profusion.xml
+shhs1-204075-profusion.xml
+shhs1-204076-profusion.xml
+shhs1-204077-profusion.xml
+shhs1-204078-profusion.xml
+shhs1-204079-profusion.xml
+shhs1-204080-profusion.xml
+shhs1-204081-profusion.xml
+shhs1-204082-profusion.xml
+shhs1-204083-profusion.xml
+shhs1-204084-profusion.xml
+shhs1-204085-profusion.xml
+shhs1-204086-profusion.xml
+shhs1-204087-profusion.xml
+shhs1-204088-profusion.xml
+shhs1-204089-profusion.xml
+shhs1-204090-profusion.xml
+shhs1-204091-profusion.xml
+shhs1-204092-profusion.xml
+shhs1-204093-profusion.xml
+shhs1-204094-profusion.xml
+shhs1-204095-profusion.xml
+shhs1-204096-profusion.xml
+shhs1-204097-profusion.xml
+shhs1-204098-profusion.xml
+shhs1-204099-profusion.xml
+shhs1-204100-profusion.xml
+shhs1-204101-profusion.xml
+shhs1-204102-profusion.xml
+shhs1-204103-profusion.xml
+shhs1-204104-profusion.xml
+shhs1-204105-profusion.xml
+shhs1-204106-profusion.xml
+shhs1-204107-profusion.xml
+shhs1-204108-profusion.xml
+shhs1-204109-profusion.xml
+shhs1-204110-profusion.xml
+shhs1-204111-profusion.xml
+shhs1-204112-profusion.xml
+shhs1-204113-profusion.xml
+shhs1-204114-profusion.xml
+shhs1-204115-profusion.xml
+shhs1-204116-profusion.xml
+shhs1-204117-profusion.xml
+shhs1-204118-profusion.xml
+shhs1-204119-profusion.xml
+shhs1-204120-profusion.xml
+shhs1-204121-profusion.xml
+shhs1-204122-profusion.xml
+shhs1-204123-profusion.xml
+shhs1-204124-profusion.xml
+shhs1-204125-profusion.xml
+shhs1-204126-profusion.xml
+shhs1-204127-profusion.xml
+shhs1-204128-profusion.xml
+shhs1-204129-profusion.xml
+shhs1-204130-profusion.xml
+shhs1-204131-profusion.xml
+shhs1-204132-profusion.xml
+shhs1-204133-profusion.xml
+shhs1-204134-profusion.xml
+shhs1-204135-profusion.xml
+shhs1-204136-profusion.xml
+shhs1-204137-profusion.xml
+shhs1-204138-profusion.xml
+shhs1-204139-profusion.xml
+shhs1-204140-profusion.xml
+shhs1-204141-profusion.xml
+shhs1-204142-profusion.xml
+shhs1-204143-profusion.xml
+shhs1-204144-profusion.xml
+shhs1-204145-profusion.xml
+shhs1-204146-profusion.xml
+shhs1-204147-profusion.xml
+shhs1-204148-profusion.xml
+shhs1-204149-profusion.xml
+shhs1-204150-profusion.xml
+shhs1-204151-profusion.xml
+shhs1-204152-profusion.xml
+shhs1-204153-profusion.xml
+shhs1-204154-profusion.xml
+shhs1-204155-profusion.xml
+shhs1-204156-profusion.xml
+shhs1-204157-profusion.xml
+shhs1-204158-profusion.xml
+shhs1-204159-profusion.xml
+shhs1-204160-profusion.xml
+shhs1-204161-profusion.xml
+shhs1-204162-profusion.xml
+shhs1-204163-profusion.xml
+shhs1-204164-profusion.xml
+shhs1-204165-profusion.xml
+shhs1-204166-profusion.xml
+shhs1-204167-profusion.xml
+shhs1-204168-profusion.xml
+shhs1-204169-profusion.xml
+shhs1-204170-profusion.xml
+shhs1-204171-profusion.xml
+shhs1-204172-profusion.xml
+shhs1-204173-profusion.xml
+shhs1-204174-profusion.xml
+shhs1-204175-profusion.xml
+shhs1-204176-profusion.xml
+shhs1-204177-profusion.xml
+shhs1-204178-profusion.xml
+shhs1-204179-profusion.xml
+shhs1-204180-profusion.xml
+shhs1-204181-profusion.xml
+shhs1-204182-profusion.xml
+shhs1-204183-profusion.xml
+shhs1-204184-profusion.xml
+shhs1-204185-profusion.xml
+shhs1-204186-profusion.xml
+shhs1-204187-profusion.xml
+shhs1-204188-profusion.xml
+shhs1-204189-profusion.xml
+shhs1-204190-profusion.xml
+shhs1-204191-profusion.xml
+shhs1-204192-profusion.xml
+shhs1-204193-profusion.xml
+shhs1-204194-profusion.xml
+shhs1-204195-profusion.xml
+shhs1-204196-profusion.xml
+shhs1-204197-profusion.xml
+shhs1-204198-profusion.xml
+shhs1-204199-profusion.xml
+shhs1-204200-profusion.xml
+shhs1-204201-profusion.xml
+shhs1-204202-profusion.xml
+shhs1-204203-profusion.xml
+shhs1-204204-profusion.xml
+shhs1-204205-profusion.xml
+shhs1-204206-profusion.xml
+shhs1-204207-profusion.xml
+shhs1-204208-profusion.xml
+shhs1-204209-profusion.xml
+shhs1-204210-profusion.xml
+shhs1-204211-profusion.xml
+shhs1-204212-profusion.xml
+shhs1-204213-profusion.xml
+shhs1-204214-profusion.xml
+shhs1-204215-profusion.xml
+shhs1-204216-profusion.xml
+shhs1-204218-profusion.xml
+shhs1-204219-profusion.xml
+shhs1-204220-profusion.xml
+shhs1-204221-profusion.xml
+shhs1-204222-profusion.xml
+shhs1-204223-profusion.xml
+shhs1-204224-profusion.xml
+shhs1-204225-profusion.xml
+shhs1-204226-profusion.xml
+shhs1-204227-profusion.xml
+shhs1-204228-profusion.xml
+shhs1-204229-profusion.xml
+shhs1-204230-profusion.xml
+shhs1-204231-profusion.xml
+shhs1-204232-profusion.xml
+shhs1-204233-profusion.xml
+shhs1-204234-profusion.xml
+shhs1-204235-profusion.xml
+shhs1-204236-profusion.xml
+shhs1-204237-profusion.xml
+shhs1-204238-profusion.xml
+shhs1-204239-profusion.xml
+shhs1-204240-profusion.xml
+shhs1-204241-profusion.xml
+shhs1-204242-profusion.xml
+shhs1-204243-profusion.xml
+shhs1-204244-profusion.xml
+shhs1-204245-profusion.xml
+shhs1-204246-profusion.xml
+shhs1-204247-profusion.xml
+shhs1-204248-profusion.xml
+shhs1-204249-profusion.xml
+shhs1-204250-profusion.xml
+shhs1-204251-profusion.xml
+shhs1-204252-profusion.xml
+shhs1-204253-profusion.xml
+shhs1-204254-profusion.xml
+shhs1-204255-profusion.xml
+shhs1-204256-profusion.xml
+shhs1-204257-profusion.xml
+shhs1-204258-profusion.xml
+shhs1-204259-profusion.xml
+shhs1-204260-profusion.xml
+shhs1-204261-profusion.xml
+shhs1-204262-profusion.xml
+shhs1-204263-profusion.xml
+shhs1-204264-profusion.xml
+shhs1-204265-profusion.xml
+shhs1-204266-profusion.xml
+shhs1-204267-profusion.xml
+shhs1-204268-profusion.xml
+shhs1-204269-profusion.xml
+shhs1-204270-profusion.xml
+shhs1-204271-profusion.xml
+shhs1-204272-profusion.xml
+shhs1-204273-profusion.xml
+shhs1-204274-profusion.xml
+shhs1-204275-profusion.xml
+shhs1-204276-profusion.xml
+shhs1-204277-profusion.xml
+shhs1-204278-profusion.xml
+shhs1-204279-profusion.xml
+shhs1-204280-profusion.xml
+shhs1-204281-profusion.xml
+shhs1-204282-profusion.xml
+shhs1-204283-profusion.xml
+shhs1-204284-profusion.xml
+shhs1-204285-profusion.xml
+shhs1-204286-profusion.xml
+shhs1-204287-profusion.xml
+shhs1-204288-profusion.xml
+shhs1-204289-profusion.xml
+shhs1-204290-profusion.xml
+shhs1-204291-profusion.xml
+shhs1-204292-profusion.xml
+shhs1-204293-profusion.xml
+shhs1-204294-profusion.xml
+shhs1-204295-profusion.xml
+shhs1-204296-profusion.xml
+shhs1-204297-profusion.xml
+shhs1-204298-profusion.xml
+shhs1-204299-profusion.xml
+shhs1-204300-profusion.xml
+shhs1-204301-profusion.xml
+shhs1-204302-profusion.xml
+shhs1-204303-profusion.xml
+shhs1-204304-profusion.xml
+shhs1-204305-profusion.xml
+shhs1-204306-profusion.xml
+shhs1-204307-profusion.xml
+shhs1-204308-profusion.xml
+shhs1-204309-profusion.xml
+shhs1-204310-profusion.xml
+shhs1-204311-profusion.xml
+shhs1-204312-profusion.xml
+shhs1-204313-profusion.xml
+shhs1-204314-profusion.xml
+shhs1-204315-profusion.xml
+shhs1-204316-profusion.xml
+shhs1-204317-profusion.xml
+shhs1-204318-profusion.xml
+shhs1-204319-profusion.xml
+shhs1-204320-profusion.xml
+shhs1-204321-profusion.xml
+shhs1-204322-profusion.xml
+shhs1-204323-profusion.xml
+shhs1-204324-profusion.xml
+shhs1-204325-profusion.xml
+shhs1-204326-profusion.xml
+shhs1-204327-profusion.xml
+shhs1-204328-profusion.xml
+shhs1-204329-profusion.xml
+shhs1-204330-profusion.xml
+shhs1-204331-profusion.xml
+shhs1-204332-profusion.xml
+shhs1-204333-profusion.xml
+shhs1-204334-profusion.xml
+shhs1-204335-profusion.xml
+shhs1-204336-profusion.xml
+shhs1-204337-profusion.xml
+shhs1-204338-profusion.xml
+shhs1-204339-profusion.xml
+shhs1-204340-profusion.xml
+shhs1-204341-profusion.xml
+shhs1-204342-profusion.xml
+shhs1-204343-profusion.xml
+shhs1-204344-profusion.xml
+shhs1-204345-profusion.xml
+shhs1-204346-profusion.xml
+shhs1-204347-profusion.xml
+shhs1-204348-profusion.xml
+shhs1-204349-profusion.xml
+shhs1-204350-profusion.xml
+shhs1-204351-profusion.xml
+shhs1-204352-profusion.xml
+shhs1-204353-profusion.xml
+shhs1-204354-profusion.xml
+shhs1-204355-profusion.xml
+shhs1-204356-profusion.xml
+shhs1-204357-profusion.xml
+shhs1-204358-profusion.xml
+shhs1-204359-profusion.xml
+shhs1-204360-profusion.xml
+shhs1-204361-profusion.xml
+shhs1-204362-profusion.xml
+shhs1-204363-profusion.xml
+shhs1-204364-profusion.xml
+shhs1-204365-profusion.xml
+shhs1-204366-profusion.xml
+shhs1-204367-profusion.xml
+shhs1-204368-profusion.xml
+shhs1-204369-profusion.xml
+shhs1-204370-profusion.xml
+shhs1-204371-profusion.xml
+shhs1-204372-profusion.xml
+shhs1-204373-profusion.xml
+shhs1-204374-profusion.xml
+shhs1-204375-profusion.xml
+shhs1-204376-profusion.xml
+shhs1-204377-profusion.xml
+shhs1-204378-profusion.xml
+shhs1-204379-profusion.xml
+shhs1-204380-profusion.xml
+shhs1-204381-profusion.xml
+shhs1-204382-profusion.xml
+shhs1-204383-profusion.xml
+shhs1-204384-profusion.xml
+shhs1-204385-profusion.xml
+shhs1-204386-profusion.xml
+shhs1-204387-profusion.xml
+shhs1-204388-profusion.xml
+shhs1-204389-profusion.xml
+shhs1-204390-profusion.xml
+shhs1-204391-profusion.xml
+shhs1-204392-profusion.xml
+shhs1-204393-profusion.xml
+shhs1-204394-profusion.xml
+shhs1-204395-profusion.xml
+shhs1-204396-profusion.xml
+shhs1-204397-profusion.xml
+shhs1-204398-profusion.xml
+shhs1-204399-profusion.xml
+shhs1-204400-profusion.xml
+shhs1-204401-profusion.xml
+shhs1-204402-profusion.xml
+shhs1-204403-profusion.xml
+shhs1-204404-profusion.xml
+shhs1-204405-profusion.xml
+shhs1-204406-profusion.xml
+shhs1-204407-profusion.xml
+shhs1-204408-profusion.xml
+shhs1-204409-profusion.xml
+shhs1-204410-profusion.xml
+shhs1-204411-profusion.xml
+shhs1-204412-profusion.xml
+shhs1-204413-profusion.xml
+shhs1-204414-profusion.xml
+shhs1-204415-profusion.xml
+shhs1-204416-profusion.xml
+shhs1-204417-profusion.xml
+shhs1-204418-profusion.xml
+shhs1-204419-profusion.xml
+shhs1-204420-profusion.xml
+shhs1-204421-profusion.xml
+shhs1-204422-profusion.xml
+shhs1-204423-profusion.xml
+shhs1-204424-profusion.xml
+shhs1-204425-profusion.xml
+shhs1-204426-profusion.xml
+shhs1-204427-profusion.xml
+shhs1-204428-profusion.xml
+shhs1-204429-profusion.xml
+shhs1-204430-profusion.xml
+shhs1-204431-profusion.xml
+shhs1-204432-profusion.xml
+shhs1-204433-profusion.xml
+shhs1-204434-profusion.xml
+shhs1-204435-profusion.xml
+shhs1-204436-profusion.xml
+shhs1-204437-profusion.xml
+shhs1-204438-profusion.xml
+shhs1-204439-profusion.xml
+shhs1-204440-profusion.xml
+shhs1-204441-profusion.xml
+shhs1-204442-profusion.xml
+shhs1-204443-profusion.xml
+shhs1-204444-profusion.xml
+shhs1-204445-profusion.xml
+shhs1-204446-profusion.xml
+shhs1-204447-profusion.xml
+shhs1-204448-profusion.xml
+shhs1-204449-profusion.xml
+shhs1-204450-profusion.xml
+shhs1-204451-profusion.xml
+shhs1-204452-profusion.xml
+shhs1-204453-profusion.xml
+shhs1-204454-profusion.xml
+shhs1-204455-profusion.xml
+shhs1-204456-profusion.xml
+shhs1-204457-profusion.xml
+shhs1-204458-profusion.xml
+shhs1-204459-profusion.xml
+shhs1-204460-profusion.xml
+shhs1-204461-profusion.xml
+shhs1-204462-profusion.xml
+shhs1-204463-profusion.xml
+shhs1-204464-profusion.xml
+shhs1-204465-profusion.xml
+shhs1-204466-profusion.xml
+shhs1-204467-profusion.xml
+shhs1-204468-profusion.xml
+shhs1-204469-profusion.xml
+shhs1-204470-profusion.xml
+shhs1-204471-profusion.xml
+shhs1-204472-profusion.xml
+shhs1-204473-profusion.xml
+shhs1-204474-profusion.xml
+shhs1-204475-profusion.xml
+shhs1-204476-profusion.xml
+shhs1-204477-profusion.xml
+shhs1-204478-profusion.xml
+shhs1-204479-profusion.xml
+shhs1-204480-profusion.xml
+shhs1-204481-profusion.xml
+shhs1-204482-profusion.xml
+shhs1-204483-profusion.xml
+shhs1-204484-profusion.xml
+shhs1-204485-profusion.xml
+shhs1-204486-profusion.xml
+shhs1-204487-profusion.xml
+shhs1-204488-profusion.xml
+shhs1-204489-profusion.xml
+shhs1-204490-profusion.xml
+shhs1-204491-profusion.xml
+shhs1-204492-profusion.xml
+shhs1-204493-profusion.xml
+shhs1-204494-profusion.xml
+shhs1-204495-profusion.xml
+shhs1-204496-profusion.xml
+shhs1-204497-profusion.xml
+shhs1-204498-profusion.xml
+shhs1-204499-profusion.xml
+shhs1-204500-profusion.xml
+shhs1-204501-profusion.xml
+shhs1-204502-profusion.xml
+shhs1-204503-profusion.xml
+shhs1-204504-profusion.xml
+shhs1-204505-profusion.xml
+shhs1-204506-profusion.xml
+shhs1-204507-profusion.xml
+shhs1-204508-profusion.xml
+shhs1-204509-profusion.xml
+shhs1-204510-profusion.xml
+shhs1-204511-profusion.xml
+shhs1-204512-profusion.xml
+shhs1-204513-profusion.xml
+shhs1-204514-profusion.xml
+shhs1-204515-profusion.xml
+shhs1-204516-profusion.xml
+shhs1-204517-profusion.xml
+shhs1-204518-profusion.xml
+shhs1-204519-profusion.xml
+shhs1-204520-profusion.xml
+shhs1-204521-profusion.xml
+shhs1-204522-profusion.xml
+shhs1-204523-profusion.xml
+shhs1-204524-profusion.xml
+shhs1-204525-profusion.xml
+shhs1-204526-profusion.xml
+shhs1-204527-profusion.xml
+shhs1-204528-profusion.xml
+shhs1-204529-profusion.xml
+shhs1-204530-profusion.xml
+shhs1-204531-profusion.xml
+shhs1-204532-profusion.xml
+shhs1-204533-profusion.xml
+shhs1-204534-profusion.xml
+shhs1-204535-profusion.xml
+shhs1-204536-profusion.xml
+shhs1-204537-profusion.xml
+shhs1-204538-profusion.xml
+shhs1-204539-profusion.xml
+shhs1-204540-profusion.xml
+shhs1-204541-profusion.xml
+shhs1-204542-profusion.xml
+shhs1-204543-profusion.xml
+shhs1-204544-profusion.xml
+shhs1-204545-profusion.xml
+shhs1-204546-profusion.xml
+shhs1-204547-profusion.xml
+shhs1-204548-profusion.xml
+shhs1-204549-profusion.xml
+shhs1-204550-profusion.xml
+shhs1-204551-profusion.xml
+shhs1-204552-profusion.xml
+shhs1-204553-profusion.xml
+shhs1-204554-profusion.xml
+shhs1-204555-profusion.xml
+shhs1-204556-profusion.xml
+shhs1-204557-profusion.xml
+shhs1-204558-profusion.xml
+shhs1-204559-profusion.xml
+shhs1-204560-profusion.xml
+shhs1-204561-profusion.xml
+shhs1-204562-profusion.xml
+shhs1-204563-profusion.xml
+shhs1-204564-profusion.xml
+shhs1-204565-profusion.xml
+shhs1-204566-profusion.xml
+shhs1-204567-profusion.xml
+shhs1-204568-profusion.xml
+shhs1-204569-profusion.xml
+shhs1-204570-profusion.xml
+shhs1-204571-profusion.xml
+shhs1-204572-profusion.xml
+shhs1-204573-profusion.xml
+shhs1-204574-profusion.xml
+shhs1-204575-profusion.xml
+shhs1-204576-profusion.xml
+shhs1-204577-profusion.xml
+shhs1-204578-profusion.xml
+shhs1-204579-profusion.xml
+shhs1-204580-profusion.xml
+shhs1-204581-profusion.xml
+shhs1-204582-profusion.xml
+shhs1-204583-profusion.xml
+shhs1-204584-profusion.xml
+shhs1-204585-profusion.xml
+shhs1-204586-profusion.xml
+shhs1-204587-profusion.xml
+shhs1-204588-profusion.xml
+shhs1-204589-profusion.xml
+shhs1-204590-profusion.xml
+shhs1-204591-profusion.xml
+shhs1-204592-profusion.xml
+shhs1-204593-profusion.xml
+shhs1-204594-profusion.xml
+shhs1-204595-profusion.xml
+shhs1-204596-profusion.xml
+shhs1-204597-profusion.xml
+shhs1-204598-profusion.xml
+shhs1-204599-profusion.xml
+shhs1-204600-profusion.xml
+shhs1-204601-profusion.xml
+shhs1-204602-profusion.xml
+shhs1-204603-profusion.xml
+shhs1-204604-profusion.xml
+shhs1-204605-profusion.xml
+shhs1-204606-profusion.xml
+shhs1-204607-profusion.xml
+shhs1-204608-profusion.xml
+shhs1-204609-profusion.xml
+shhs1-204610-profusion.xml
+shhs1-204611-profusion.xml
+shhs1-204612-profusion.xml
+shhs1-204613-profusion.xml
+shhs1-204614-profusion.xml
+shhs1-204615-profusion.xml
+shhs1-204616-profusion.xml
+shhs1-204617-profusion.xml
+shhs1-204618-profusion.xml
+shhs1-204619-profusion.xml
+shhs1-204620-profusion.xml
+shhs1-204621-profusion.xml
+shhs1-204622-profusion.xml
+shhs1-204623-profusion.xml
+shhs1-204624-profusion.xml
+shhs1-204625-profusion.xml
+shhs1-204626-profusion.xml
+shhs1-204627-profusion.xml
+shhs1-204628-profusion.xml
+shhs1-204629-profusion.xml
+shhs1-204630-profusion.xml
+shhs1-204631-profusion.xml
+shhs1-204632-profusion.xml
+shhs1-204633-profusion.xml
+shhs1-204634-profusion.xml
+shhs1-204635-profusion.xml
+shhs1-204636-profusion.xml
+shhs1-204637-profusion.xml
+shhs1-204638-profusion.xml
+shhs1-204639-profusion.xml
+shhs1-204640-profusion.xml
+shhs1-204641-profusion.xml
+shhs1-204642-profusion.xml
+shhs1-204643-profusion.xml
+shhs1-204644-profusion.xml
+shhs1-204645-profusion.xml
+shhs1-204646-profusion.xml
+shhs1-204647-profusion.xml
+shhs1-204648-profusion.xml
+shhs1-204649-profusion.xml
+shhs1-204650-profusion.xml
+shhs1-204651-profusion.xml
+shhs1-204652-profusion.xml
+shhs1-204653-profusion.xml
+shhs1-204654-profusion.xml
+shhs1-204655-profusion.xml
+shhs1-204656-profusion.xml
+shhs1-204657-profusion.xml
+shhs1-204658-profusion.xml
+shhs1-204659-profusion.xml
+shhs1-204660-profusion.xml
+shhs1-204661-profusion.xml
+shhs1-204662-profusion.xml
+shhs1-204663-profusion.xml
+shhs1-204664-profusion.xml
+shhs1-204665-profusion.xml
+shhs1-204666-profusion.xml
+shhs1-204667-profusion.xml
+shhs1-204668-profusion.xml
+shhs1-204669-profusion.xml
+shhs1-204670-profusion.xml
+shhs1-204671-profusion.xml
+shhs1-204672-profusion.xml
+shhs1-204673-profusion.xml
+shhs1-204674-profusion.xml
+shhs1-204675-profusion.xml
+shhs1-204676-profusion.xml
+shhs1-204677-profusion.xml
+shhs1-204678-profusion.xml
+shhs1-204679-profusion.xml
+shhs1-204680-profusion.xml
+shhs1-204681-profusion.xml
+shhs1-204682-profusion.xml
+shhs1-204683-profusion.xml
+shhs1-204684-profusion.xml
+shhs1-204685-profusion.xml
+shhs1-204686-profusion.xml
+shhs1-204687-profusion.xml
+shhs1-204688-profusion.xml
+shhs1-204689-profusion.xml
+shhs1-204690-profusion.xml
+shhs1-204691-profusion.xml
+shhs1-204692-profusion.xml
+shhs1-204693-profusion.xml
+shhs1-204694-profusion.xml
+shhs1-204695-profusion.xml
+shhs1-204696-profusion.xml
+shhs1-204697-profusion.xml
+shhs1-204698-profusion.xml
+shhs1-204699-profusion.xml
+shhs1-204700-profusion.xml
+shhs1-204701-profusion.xml
+shhs1-204702-profusion.xml
+shhs1-204703-profusion.xml
+shhs1-204704-profusion.xml
+shhs1-204705-profusion.xml
+shhs1-204706-profusion.xml
+shhs1-204707-profusion.xml
+shhs1-204708-profusion.xml
+shhs1-204709-profusion.xml
+shhs1-204710-profusion.xml
+shhs1-204711-profusion.xml
+shhs1-204712-profusion.xml
+shhs1-204713-profusion.xml
+shhs1-204714-profusion.xml
+shhs1-204715-profusion.xml
+shhs1-204716-profusion.xml
+shhs1-204717-profusion.xml
+shhs1-204718-profusion.xml
+shhs1-204719-profusion.xml
+shhs1-204720-profusion.xml
+shhs1-204721-profusion.xml
+shhs1-204722-profusion.xml
+shhs1-204723-profusion.xml
+shhs1-204724-profusion.xml
+shhs1-204725-profusion.xml
+shhs1-204726-profusion.xml
+shhs1-204727-profusion.xml
+shhs1-204728-profusion.xml
+shhs1-204729-profusion.xml
+shhs1-204730-profusion.xml
+shhs1-204731-profusion.xml
+shhs1-204732-profusion.xml
+shhs1-204733-profusion.xml
+shhs1-204734-profusion.xml
+shhs1-204735-profusion.xml
+shhs1-204736-profusion.xml
+shhs1-204737-profusion.xml
+shhs1-204738-profusion.xml
+shhs1-204739-profusion.xml
+shhs1-204740-profusion.xml
+shhs1-204741-profusion.xml
+shhs1-204742-profusion.xml
+shhs1-204743-profusion.xml
+shhs1-204744-profusion.xml
+shhs1-204745-profusion.xml
+shhs1-204746-profusion.xml
+shhs1-204747-profusion.xml
+shhs1-204748-profusion.xml
+shhs1-204749-profusion.xml
+shhs1-204750-profusion.xml
+shhs1-204751-profusion.xml
+shhs1-204752-profusion.xml
+shhs1-204753-profusion.xml
+shhs1-204754-profusion.xml
+shhs1-204755-profusion.xml
+shhs1-204756-profusion.xml
+shhs1-204757-profusion.xml
+shhs1-204758-profusion.xml
+shhs1-204759-profusion.xml
+shhs1-204760-profusion.xml
+shhs1-204761-profusion.xml
+shhs1-204762-profusion.xml
+shhs1-204763-profusion.xml
+shhs1-204764-profusion.xml
+shhs1-204765-profusion.xml
+shhs1-204766-profusion.xml
+shhs1-204767-profusion.xml
+shhs1-204768-profusion.xml
+shhs1-204769-profusion.xml
+shhs1-204770-profusion.xml
+shhs1-204771-profusion.xml
+shhs1-204772-profusion.xml
+shhs1-204773-profusion.xml
+shhs1-204774-profusion.xml
+shhs1-204775-profusion.xml
+shhs1-204776-profusion.xml
+shhs1-204777-profusion.xml
+shhs1-204778-profusion.xml
+shhs1-204779-profusion.xml
+shhs1-204780-profusion.xml
+shhs1-204781-profusion.xml
+shhs1-204782-profusion.xml
+shhs1-204783-profusion.xml
+shhs1-204784-profusion.xml
+shhs1-204785-profusion.xml
+shhs1-204786-profusion.xml
+shhs1-204787-profusion.xml
+shhs1-204788-profusion.xml
+shhs1-204789-profusion.xml
+shhs1-204790-profusion.xml
+shhs1-204791-profusion.xml
+shhs1-204792-profusion.xml
+shhs1-204793-profusion.xml
+shhs1-204794-profusion.xml
+shhs1-204795-profusion.xml
+shhs1-204796-profusion.xml
+shhs1-204797-profusion.xml
+shhs1-204798-profusion.xml
+shhs1-204799-profusion.xml
+shhs1-204800-profusion.xml
+shhs1-204801-profusion.xml
+shhs1-204802-profusion.xml
+shhs1-204803-profusion.xml
+shhs1-204804-profusion.xml
+shhs1-204805-profusion.xml
+shhs1-204806-profusion.xml
+shhs1-204807-profusion.xml
+shhs1-204808-profusion.xml
+shhs1-204809-profusion.xml
+shhs1-204810-profusion.xml
+shhs1-204811-profusion.xml
+shhs1-204812-profusion.xml
+shhs1-204813-profusion.xml
+shhs1-204814-profusion.xml
+shhs1-204815-profusion.xml
+shhs1-204816-profusion.xml
+shhs1-204817-profusion.xml
+shhs1-204818-profusion.xml
+shhs1-204819-profusion.xml
+shhs1-204820-profusion.xml
+shhs1-204821-profusion.xml
+shhs1-204822-profusion.xml
+shhs1-204823-profusion.xml
+shhs1-204824-profusion.xml
+shhs1-204825-profusion.xml
+shhs1-204826-profusion.xml
+shhs1-204827-profusion.xml
+shhs1-204828-profusion.xml
+shhs1-204829-profusion.xml
+shhs1-204830-profusion.xml
+shhs1-204831-profusion.xml
+shhs1-204832-profusion.xml
+shhs1-204833-profusion.xml
+shhs1-204834-profusion.xml
+shhs1-204835-profusion.xml
+shhs1-204836-profusion.xml
+shhs1-204837-profusion.xml
+shhs1-204838-profusion.xml
+shhs1-204839-profusion.xml
+shhs1-204840-profusion.xml
+shhs1-204841-profusion.xml
+shhs1-204842-profusion.xml
+shhs1-204843-profusion.xml
+shhs1-204844-profusion.xml
+shhs1-204845-profusion.xml
+shhs1-204846-profusion.xml
+shhs1-204847-profusion.xml
+shhs1-204848-profusion.xml
+shhs1-204849-profusion.xml
+shhs1-204850-profusion.xml
+shhs1-204851-profusion.xml
+shhs1-204852-profusion.xml
+shhs1-204853-profusion.xml
+shhs1-204854-profusion.xml
+shhs1-204855-profusion.xml
+shhs1-204856-profusion.xml
+shhs1-204857-profusion.xml
+shhs1-204858-profusion.xml
+shhs1-204859-profusion.xml
+shhs1-204860-profusion.xml
+shhs1-204861-profusion.xml
+shhs1-204862-profusion.xml
+shhs1-204863-profusion.xml
+shhs1-204864-profusion.xml
+shhs1-204865-profusion.xml
+shhs1-204866-profusion.xml
+shhs1-204867-profusion.xml
+shhs1-204868-profusion.xml
+shhs1-204869-profusion.xml
+shhs1-204870-profusion.xml
+shhs1-204871-profusion.xml
+shhs1-204872-profusion.xml
+shhs1-204873-profusion.xml
+shhs1-204874-profusion.xml
+shhs1-204875-profusion.xml
+shhs1-204876-profusion.xml
+shhs1-204877-profusion.xml
+shhs1-204878-profusion.xml
+shhs1-204879-profusion.xml
+shhs1-204880-profusion.xml
+shhs1-204881-profusion.xml
+shhs1-204882-profusion.xml
+shhs1-204883-profusion.xml
+shhs1-204884-profusion.xml
+shhs1-204885-profusion.xml
+shhs1-204886-profusion.xml
+shhs1-204887-profusion.xml
+shhs1-204888-profusion.xml
+shhs1-204889-profusion.xml
+shhs1-204890-profusion.xml
+shhs1-204891-profusion.xml
+shhs1-204892-profusion.xml
+shhs1-204893-profusion.xml
+shhs1-204894-profusion.xml
+shhs1-204895-profusion.xml
+shhs1-204896-profusion.xml
+shhs1-204897-profusion.xml
+shhs1-204898-profusion.xml
+shhs1-204899-profusion.xml
+shhs1-204900-profusion.xml
+shhs1-204901-profusion.xml
+shhs1-204902-profusion.xml
+shhs1-204903-profusion.xml
+shhs1-204904-profusion.xml
+shhs1-204905-profusion.xml
+shhs1-204906-profusion.xml
+shhs1-204907-profusion.xml
+shhs1-204908-profusion.xml
+shhs1-204909-profusion.xml
+shhs1-204910-profusion.xml
+shhs1-204911-profusion.xml
+shhs1-204912-profusion.xml
+shhs1-204913-profusion.xml
+shhs1-204914-profusion.xml
+shhs1-204915-profusion.xml
+shhs1-204916-profusion.xml
+shhs1-204917-profusion.xml
+shhs1-204918-profusion.xml
+shhs1-204919-profusion.xml
+shhs1-204920-profusion.xml
+shhs1-204921-profusion.xml
+shhs1-204922-profusion.xml
+shhs1-204923-profusion.xml
+shhs1-204924-profusion.xml
+shhs1-204925-profusion.xml
+shhs1-204926-profusion.xml
+shhs1-204927-profusion.xml
+shhs1-204928-profusion.xml
+shhs1-204929-profusion.xml
+shhs1-204930-profusion.xml
+shhs1-204931-profusion.xml
+shhs1-204932-profusion.xml
+shhs1-204933-profusion.xml
+shhs1-204934-profusion.xml
+shhs1-204935-profusion.xml
+shhs1-204936-profusion.xml
+shhs1-204937-profusion.xml
+shhs1-204938-profusion.xml
+shhs1-204939-profusion.xml
+shhs1-204940-profusion.xml
+shhs1-204941-profusion.xml
+shhs1-204942-profusion.xml
+shhs1-204943-profusion.xml
+shhs1-204944-profusion.xml
+shhs1-204945-profusion.xml
+shhs1-204946-profusion.xml
+shhs1-204947-profusion.xml
+shhs1-204948-profusion.xml
+shhs1-204949-profusion.xml
+shhs1-204950-profusion.xml
+shhs1-204951-profusion.xml
+shhs1-204952-profusion.xml
+shhs1-204953-profusion.xml
+shhs1-204954-profusion.xml
+shhs1-204955-profusion.xml
+shhs1-204956-profusion.xml
+shhs1-204957-profusion.xml
+shhs1-204958-profusion.xml
+shhs1-204959-profusion.xml
+shhs1-204960-profusion.xml
+shhs1-204961-profusion.xml
+shhs1-204962-profusion.xml
+shhs1-204963-profusion.xml
+shhs1-204964-profusion.xml
+shhs1-204965-profusion.xml
+shhs1-204966-profusion.xml
+shhs1-204967-profusion.xml
+shhs1-204968-profusion.xml
+shhs1-204969-profusion.xml
+shhs1-204970-profusion.xml
+shhs1-204971-profusion.xml
+shhs1-204972-profusion.xml
+shhs1-204973-profusion.xml
+shhs1-204974-profusion.xml
+shhs1-204975-profusion.xml
+shhs1-204976-profusion.xml
+shhs1-204977-profusion.xml
+shhs1-204978-profusion.xml
+shhs1-204979-profusion.xml
+shhs1-204980-profusion.xml
+shhs1-204981-profusion.xml
+shhs1-204982-profusion.xml
+shhs1-204983-profusion.xml
+shhs1-204984-profusion.xml
+shhs1-204985-profusion.xml
+shhs1-204986-profusion.xml
+shhs1-204987-profusion.xml
+shhs1-204988-profusion.xml
+shhs1-204989-profusion.xml
+shhs1-204990-profusion.xml
+shhs1-204991-profusion.xml
+shhs1-204992-profusion.xml
+shhs1-204993-profusion.xml
+shhs1-204994-profusion.xml
+shhs1-204995-profusion.xml
+shhs1-204996-profusion.xml
+shhs1-204997-profusion.xml
+shhs1-204998-profusion.xml
+shhs1-204999-profusion.xml
+shhs1-205000-profusion.xml
+shhs1-205001-profusion.xml
+shhs1-205002-profusion.xml
+shhs1-205003-profusion.xml
+shhs1-205004-profusion.xml
+shhs1-205005-profusion.xml
+shhs1-205006-profusion.xml
+shhs1-205007-profusion.xml
+shhs1-205008-profusion.xml
+shhs1-205009-profusion.xml
+shhs1-205010-profusion.xml
+shhs1-205011-profusion.xml
+shhs1-205012-profusion.xml
+shhs1-205013-profusion.xml
+shhs1-205014-profusion.xml
+shhs1-205015-profusion.xml
+shhs1-205016-profusion.xml
+shhs1-205017-profusion.xml
+shhs1-205018-profusion.xml
+shhs1-205019-profusion.xml
+shhs1-205020-profusion.xml
+shhs1-205021-profusion.xml
+shhs1-205022-profusion.xml
+shhs1-205023-profusion.xml
+shhs1-205024-profusion.xml
+shhs1-205025-profusion.xml
+shhs1-205026-profusion.xml
+shhs1-205027-profusion.xml
+shhs1-205028-profusion.xml
+shhs1-205029-profusion.xml
+shhs1-205030-profusion.xml
+shhs1-205031-profusion.xml
+shhs1-205032-profusion.xml
+shhs1-205033-profusion.xml
+shhs1-205034-profusion.xml
+shhs1-205035-profusion.xml
+shhs1-205036-profusion.xml
+shhs1-205037-profusion.xml
+shhs1-205038-profusion.xml
+shhs1-205039-profusion.xml
+shhs1-205040-profusion.xml
+shhs1-205041-profusion.xml
+shhs1-205042-profusion.xml
+shhs1-205043-profusion.xml
+shhs1-205044-profusion.xml
+shhs1-205045-profusion.xml
+shhs1-205046-profusion.xml
+shhs1-205047-profusion.xml
+shhs1-205048-profusion.xml
+shhs1-205049-profusion.xml
+shhs1-205050-profusion.xml
+shhs1-205051-profusion.xml
+shhs1-205052-profusion.xml
+shhs1-205053-profusion.xml
+shhs1-205054-profusion.xml
+shhs1-205055-profusion.xml
+shhs1-205056-profusion.xml
+shhs1-205057-profusion.xml
+shhs1-205058-profusion.xml
+shhs1-205059-profusion.xml
+shhs1-205060-profusion.xml
+shhs1-205061-profusion.xml
+shhs1-205062-profusion.xml
+shhs1-205063-profusion.xml
+shhs1-205064-profusion.xml
+shhs1-205065-profusion.xml
+shhs1-205066-profusion.xml
+shhs1-205067-profusion.xml
+shhs1-205068-profusion.xml
+shhs1-205069-profusion.xml
+shhs1-205070-profusion.xml
+shhs1-205071-profusion.xml
+shhs1-205072-profusion.xml
+shhs1-205073-profusion.xml
+shhs1-205074-profusion.xml
+shhs1-205075-profusion.xml
+shhs1-205076-profusion.xml
+shhs1-205077-profusion.xml
+shhs1-205078-profusion.xml
+shhs1-205079-profusion.xml
+shhs1-205080-profusion.xml
+shhs1-205081-profusion.xml
+shhs1-205082-profusion.xml
+shhs1-205083-profusion.xml
+shhs1-205084-profusion.xml
+shhs1-205085-profusion.xml
+shhs1-205086-profusion.xml
+shhs1-205087-profusion.xml
+shhs1-205088-profusion.xml
+shhs1-205089-profusion.xml
+shhs1-205090-profusion.xml
+shhs1-205091-profusion.xml
+shhs1-205092-profusion.xml
+shhs1-205093-profusion.xml
+shhs1-205094-profusion.xml
+shhs1-205095-profusion.xml
+shhs1-205096-profusion.xml
+shhs1-205097-profusion.xml
+shhs1-205098-profusion.xml
+shhs1-205099-profusion.xml
+shhs1-205100-profusion.xml
+shhs1-205101-profusion.xml
+shhs1-205102-profusion.xml
+shhs1-205103-profusion.xml
+shhs1-205104-profusion.xml
+shhs1-205105-profusion.xml
+shhs1-205106-profusion.xml
+shhs1-205107-profusion.xml
+shhs1-205108-profusion.xml
+shhs1-205109-profusion.xml
+shhs1-205110-profusion.xml
+shhs1-205111-profusion.xml
+shhs1-205112-profusion.xml
+shhs1-205113-profusion.xml
+shhs1-205114-profusion.xml
+shhs1-205115-profusion.xml
+shhs1-205116-profusion.xml
+shhs1-205117-profusion.xml
+shhs1-205118-profusion.xml
+shhs1-205119-profusion.xml
+shhs1-205120-profusion.xml
+shhs1-205121-profusion.xml
+shhs1-205122-profusion.xml
+shhs1-205123-profusion.xml
+shhs1-205124-profusion.xml
+shhs1-205125-profusion.xml
+shhs1-205126-profusion.xml
+shhs1-205127-profusion.xml
+shhs1-205128-profusion.xml
+shhs1-205129-profusion.xml
+shhs1-205130-profusion.xml
+shhs1-205131-profusion.xml
+shhs1-205132-profusion.xml
+shhs1-205133-profusion.xml
+shhs1-205134-profusion.xml
+shhs1-205135-profusion.xml
+shhs1-205136-profusion.xml
+shhs1-205137-profusion.xml
+shhs1-205138-profusion.xml
+shhs1-205139-profusion.xml
+shhs1-205140-profusion.xml
+shhs1-205141-profusion.xml
+shhs1-205142-profusion.xml
+shhs1-205143-profusion.xml
+shhs1-205144-profusion.xml
+shhs1-205145-profusion.xml
+shhs1-205146-profusion.xml
+shhs1-205147-profusion.xml
+shhs1-205148-profusion.xml
+shhs1-205149-profusion.xml
+shhs1-205150-profusion.xml
+shhs1-205151-profusion.xml
+shhs1-205152-profusion.xml
+shhs1-205153-profusion.xml
+shhs1-205154-profusion.xml
+shhs1-205155-profusion.xml
+shhs1-205156-profusion.xml
+shhs1-205157-profusion.xml
+shhs1-205158-profusion.xml
+shhs1-205159-profusion.xml
+shhs1-205160-profusion.xml
+shhs1-205161-profusion.xml
+shhs1-205162-profusion.xml
+shhs1-205163-profusion.xml
+shhs1-205164-profusion.xml
+shhs1-205165-profusion.xml
+shhs1-205166-profusion.xml
+shhs1-205167-profusion.xml
+shhs1-205168-profusion.xml
+shhs1-205169-profusion.xml
+shhs1-205170-profusion.xml
+shhs1-205171-profusion.xml
+shhs1-205172-profusion.xml
+shhs1-205173-profusion.xml
+shhs1-205174-profusion.xml
+shhs1-205175-profusion.xml
+shhs1-205176-profusion.xml
+shhs1-205177-profusion.xml
+shhs1-205178-profusion.xml
+shhs1-205179-profusion.xml
+shhs1-205180-profusion.xml
+shhs1-205181-profusion.xml
+shhs1-205182-profusion.xml
+shhs1-205183-profusion.xml
+shhs1-205184-profusion.xml
+shhs1-205185-profusion.xml
+shhs1-205186-profusion.xml
+shhs1-205187-profusion.xml
+shhs1-205188-profusion.xml
+shhs1-205189-profusion.xml
+shhs1-205190-profusion.xml
+shhs1-205191-profusion.xml
+shhs1-205192-profusion.xml
+shhs1-205193-profusion.xml
+shhs1-205194-profusion.xml
+shhs1-205195-profusion.xml
+shhs1-205196-profusion.xml
+shhs1-205197-profusion.xml
+shhs1-205198-profusion.xml
+shhs1-205199-profusion.xml
+shhs1-205200-profusion.xml
+shhs1-205201-profusion.xml
+shhs1-205202-profusion.xml
+shhs1-205203-profusion.xml
+shhs1-205204-profusion.xml
+shhs1-205205-profusion.xml
+shhs1-205206-profusion.xml
+shhs1-205207-profusion.xml
+shhs1-205208-profusion.xml
+shhs1-205209-profusion.xml
+shhs1-205210-profusion.xml
+shhs1-205211-profusion.xml
+shhs1-205212-profusion.xml
+shhs1-205213-profusion.xml
+shhs1-205214-profusion.xml
+shhs1-205215-profusion.xml
+shhs1-205216-profusion.xml
+shhs1-205217-profusion.xml
+shhs1-205218-profusion.xml
+shhs1-205219-profusion.xml
+shhs1-205220-profusion.xml
+shhs1-205221-profusion.xml
+shhs1-205222-profusion.xml
+shhs1-205223-profusion.xml
+shhs1-205224-profusion.xml
+shhs1-205225-profusion.xml
+shhs1-205226-profusion.xml
+shhs1-205227-profusion.xml
+shhs1-205228-profusion.xml
+shhs1-205229-profusion.xml
+shhs1-205230-profusion.xml
+shhs1-205231-profusion.xml
+shhs1-205232-profusion.xml
+shhs1-205233-profusion.xml
+shhs1-205234-profusion.xml
+shhs1-205235-profusion.xml
+shhs1-205236-profusion.xml
+shhs1-205237-profusion.xml
+shhs1-205238-profusion.xml
+shhs1-205239-profusion.xml
+shhs1-205240-profusion.xml
+shhs1-205241-profusion.xml
+shhs1-205242-profusion.xml
+shhs1-205243-profusion.xml
+shhs1-205244-profusion.xml
+shhs1-205245-profusion.xml
+shhs1-205246-profusion.xml
+shhs1-205247-profusion.xml
+shhs1-205248-profusion.xml
+shhs1-205249-profusion.xml
+shhs1-205250-profusion.xml
+shhs1-205251-profusion.xml
+shhs1-205252-profusion.xml
+shhs1-205253-profusion.xml
+shhs1-205254-profusion.xml
+shhs1-205255-profusion.xml
+shhs1-205256-profusion.xml
+shhs1-205257-profusion.xml
+shhs1-205258-profusion.xml
+shhs1-205259-profusion.xml
+shhs1-205260-profusion.xml
+shhs1-205261-profusion.xml
+shhs1-205262-profusion.xml
+shhs1-205263-profusion.xml
+shhs1-205264-profusion.xml
+shhs1-205265-profusion.xml
+shhs1-205266-profusion.xml
+shhs1-205267-profusion.xml
+shhs1-205268-profusion.xml
+shhs1-205269-profusion.xml
+shhs1-205270-profusion.xml
+shhs1-205271-profusion.xml
+shhs1-205272-profusion.xml
+shhs1-205273-profusion.xml
+shhs1-205274-profusion.xml
+shhs1-205275-profusion.xml
+shhs1-205276-profusion.xml
+shhs1-205277-profusion.xml
+shhs1-205278-profusion.xml
+shhs1-205279-profusion.xml
+shhs1-205280-profusion.xml
+shhs1-205281-profusion.xml
+shhs1-205282-profusion.xml
+shhs1-205283-profusion.xml
+shhs1-205284-profusion.xml
+shhs1-205285-profusion.xml
+shhs1-205286-profusion.xml
+shhs1-205287-profusion.xml
+shhs1-205288-profusion.xml
+shhs1-205289-profusion.xml
+shhs1-205290-profusion.xml
+shhs1-205291-profusion.xml
+shhs1-205292-profusion.xml
+shhs1-205293-profusion.xml
+shhs1-205294-profusion.xml
+shhs1-205295-profusion.xml
+shhs1-205296-profusion.xml
+shhs1-205297-profusion.xml
+shhs1-205298-profusion.xml
+shhs1-205299-profusion.xml
+shhs1-205300-profusion.xml
+shhs1-205301-profusion.xml
+shhs1-205302-profusion.xml
+shhs1-205303-profusion.xml
+shhs1-205304-profusion.xml
+shhs1-205305-profusion.xml
+shhs1-205306-profusion.xml
+shhs1-205307-profusion.xml
+shhs1-205308-profusion.xml
+shhs1-205309-profusion.xml
+shhs1-205310-profusion.xml
+shhs1-205311-profusion.xml
+shhs1-205312-profusion.xml
+shhs1-205313-profusion.xml
+shhs1-205314-profusion.xml
+shhs1-205315-profusion.xml
+shhs1-205316-profusion.xml
+shhs1-205317-profusion.xml
+shhs1-205318-profusion.xml
+shhs1-205319-profusion.xml
+shhs1-205320-profusion.xml
+shhs1-205321-profusion.xml
+shhs1-205322-profusion.xml
+shhs1-205323-profusion.xml
+shhs1-205324-profusion.xml
+shhs1-205325-profusion.xml
+shhs1-205326-profusion.xml
+shhs1-205327-profusion.xml
+shhs1-205328-profusion.xml
+shhs1-205329-profusion.xml
+shhs1-205330-profusion.xml
+shhs1-205331-profusion.xml
+shhs1-205332-profusion.xml
+shhs1-205333-profusion.xml
+shhs1-205334-profusion.xml
+shhs1-205335-profusion.xml
+shhs1-205336-profusion.xml
+shhs1-205337-profusion.xml
+shhs1-205338-profusion.xml
+shhs1-205339-profusion.xml
+shhs1-205340-profusion.xml
+shhs1-205341-profusion.xml
+shhs1-205342-profusion.xml
+shhs1-205343-profusion.xml
+shhs1-205344-profusion.xml
+shhs1-205345-profusion.xml
+shhs1-205346-profusion.xml
+shhs1-205347-profusion.xml
+shhs1-205348-profusion.xml
+shhs1-205349-profusion.xml
+shhs1-205350-profusion.xml
+shhs1-205351-profusion.xml
+shhs1-205352-profusion.xml
+shhs1-205353-profusion.xml
+shhs1-205354-profusion.xml
+shhs1-205355-profusion.xml
+shhs1-205356-profusion.xml
+shhs1-205357-profusion.xml
+shhs1-205358-profusion.xml
+shhs1-205359-profusion.xml
+shhs1-205360-profusion.xml
+shhs1-205361-profusion.xml
+shhs1-205362-profusion.xml
+shhs1-205363-profusion.xml
+shhs1-205364-profusion.xml
+shhs1-205365-profusion.xml
+shhs1-205366-profusion.xml
+shhs1-205367-profusion.xml
+shhs1-205368-profusion.xml
+shhs1-205369-profusion.xml
+shhs1-205370-profusion.xml
+shhs1-205371-profusion.xml
+shhs1-205372-profusion.xml
+shhs1-205373-profusion.xml
+shhs1-205374-profusion.xml
+shhs1-205375-profusion.xml
+shhs1-205376-profusion.xml
+shhs1-205377-profusion.xml
+shhs1-205378-profusion.xml
+shhs1-205379-profusion.xml
+shhs1-205380-profusion.xml
+shhs1-205381-profusion.xml
+shhs1-205382-profusion.xml
+shhs1-205383-profusion.xml
+shhs1-205384-profusion.xml
+shhs1-205385-profusion.xml
+shhs1-205386-profusion.xml
+shhs1-205387-profusion.xml
+shhs1-205388-profusion.xml
+shhs1-205389-profusion.xml
+shhs1-205390-profusion.xml
+shhs1-205391-profusion.xml
+shhs1-205392-profusion.xml
+shhs1-205393-profusion.xml
+shhs1-205394-profusion.xml
+shhs1-205395-profusion.xml
+shhs1-205396-profusion.xml
+shhs1-205397-profusion.xml
+shhs1-205398-profusion.xml
+shhs1-205399-profusion.xml
+shhs1-205400-profusion.xml
+shhs1-205401-profusion.xml
+shhs1-205402-profusion.xml
+shhs1-205403-profusion.xml
+shhs1-205404-profusion.xml
+shhs1-205405-profusion.xml
+shhs1-205406-profusion.xml
+shhs1-205407-profusion.xml
+shhs1-205408-profusion.xml
+shhs1-205409-profusion.xml
+shhs1-205410-profusion.xml
+shhs1-205411-profusion.xml
+shhs1-205412-profusion.xml
+shhs1-205413-profusion.xml
+shhs1-205414-profusion.xml
+shhs1-205415-profusion.xml
+shhs1-205416-profusion.xml
+shhs1-205417-profusion.xml
+shhs1-205418-profusion.xml
+shhs1-205419-profusion.xml
+shhs1-205420-profusion.xml
+shhs1-205421-profusion.xml
+shhs1-205422-profusion.xml
+shhs1-205423-profusion.xml
+shhs1-205424-profusion.xml
+shhs1-205425-profusion.xml
+shhs1-205426-profusion.xml
+shhs1-205427-profusion.xml
+shhs1-205428-profusion.xml
+shhs1-205429-profusion.xml
+shhs1-205430-profusion.xml
+shhs1-205431-profusion.xml
+shhs1-205432-profusion.xml
+shhs1-205433-profusion.xml
+shhs1-205434-profusion.xml
+shhs1-205435-profusion.xml
+shhs1-205436-profusion.xml
+shhs1-205437-profusion.xml
+shhs1-205438-profusion.xml
+shhs1-205439-profusion.xml
+shhs1-205440-profusion.xml
+shhs1-205441-profusion.xml
+shhs1-205442-profusion.xml
+shhs1-205443-profusion.xml
+shhs1-205444-profusion.xml
+shhs1-205445-profusion.xml
+shhs1-205446-profusion.xml
+shhs1-205447-profusion.xml
+shhs1-205448-profusion.xml
+shhs1-205449-profusion.xml
+shhs1-205450-profusion.xml
+shhs1-205451-profusion.xml
+shhs1-205452-profusion.xml
+shhs1-205453-profusion.xml
+shhs1-205454-profusion.xml
+shhs1-205455-profusion.xml
+shhs1-205456-profusion.xml
+shhs1-205457-profusion.xml
+shhs1-205458-profusion.xml
+shhs1-205459-profusion.xml
+shhs1-205460-profusion.xml
+shhs1-205461-profusion.xml
+shhs1-205462-profusion.xml
+shhs1-205463-profusion.xml
+shhs1-205464-profusion.xml
+shhs1-205465-profusion.xml
+shhs1-205466-profusion.xml
+shhs1-205467-profusion.xml
+shhs1-205468-profusion.xml
+shhs1-205469-profusion.xml
+shhs1-205470-profusion.xml
+shhs1-205471-profusion.xml
+shhs1-205472-profusion.xml
+shhs1-205473-profusion.xml
+shhs1-205474-profusion.xml
+shhs1-205475-profusion.xml
+shhs1-205476-profusion.xml
+shhs1-205477-profusion.xml
+shhs1-205478-profusion.xml
+shhs1-205479-profusion.xml
+shhs1-205480-profusion.xml
+shhs1-205481-profusion.xml
+shhs1-205482-profusion.xml
+shhs1-205483-profusion.xml
+shhs1-205484-profusion.xml
+shhs1-205485-profusion.xml
+shhs1-205486-profusion.xml
+shhs1-205487-profusion.xml
+shhs1-205488-profusion.xml
+shhs1-205489-profusion.xml
+shhs1-205490-profusion.xml
+shhs1-205491-profusion.xml
+shhs1-205492-profusion.xml
+shhs1-205493-profusion.xml
+shhs1-205494-profusion.xml
+shhs1-205495-profusion.xml
+shhs1-205496-profusion.xml
+shhs1-205497-profusion.xml
+shhs1-205498-profusion.xml
+shhs1-205499-profusion.xml
+shhs1-205500-profusion.xml
+shhs1-205501-profusion.xml
+shhs1-205502-profusion.xml
+shhs1-205503-profusion.xml
+shhs1-205504-profusion.xml
+shhs1-205505-profusion.xml
+shhs1-205506-profusion.xml
+shhs1-205507-profusion.xml
+shhs1-205508-profusion.xml
+shhs1-205509-profusion.xml
+shhs1-205510-profusion.xml
+shhs1-205511-profusion.xml
+shhs1-205512-profusion.xml
+shhs1-205513-profusion.xml
+shhs1-205514-profusion.xml
+shhs1-205515-profusion.xml
+shhs1-205516-profusion.xml
+shhs1-205517-profusion.xml
+shhs1-205518-profusion.xml
+shhs1-205519-profusion.xml
+shhs1-205520-profusion.xml
+shhs1-205521-profusion.xml
+shhs1-205522-profusion.xml
+shhs1-205523-profusion.xml
+shhs1-205524-profusion.xml
+shhs1-205525-profusion.xml
+shhs1-205526-profusion.xml
+shhs1-205527-profusion.xml
+shhs1-205528-profusion.xml
+shhs1-205529-profusion.xml
+shhs1-205530-profusion.xml
+shhs1-205531-profusion.xml
+shhs1-205532-profusion.xml
+shhs1-205533-profusion.xml
+shhs1-205534-profusion.xml
+shhs1-205535-profusion.xml
+shhs1-205536-profusion.xml
+shhs1-205537-profusion.xml
+shhs1-205538-profusion.xml
+shhs1-205539-profusion.xml
+shhs1-205540-profusion.xml
+shhs1-205541-profusion.xml
+shhs1-205542-profusion.xml
+shhs1-205543-profusion.xml
+shhs1-205544-profusion.xml
+shhs1-205545-profusion.xml
+shhs1-205546-profusion.xml
+shhs1-205547-profusion.xml
+shhs1-205548-profusion.xml
+shhs1-205549-profusion.xml
+shhs1-205550-profusion.xml
+shhs1-205551-profusion.xml
+shhs1-205552-profusion.xml
+shhs1-205553-profusion.xml
+shhs1-205554-profusion.xml
+shhs1-205555-profusion.xml
+shhs1-205556-profusion.xml
+shhs1-205557-profusion.xml
+shhs1-205558-profusion.xml
+shhs1-205559-profusion.xml
+shhs1-205560-profusion.xml
+shhs1-205561-profusion.xml
+shhs1-205562-profusion.xml
+shhs1-205563-profusion.xml
+shhs1-205564-profusion.xml
+shhs1-205565-profusion.xml
+shhs1-205566-profusion.xml
+shhs1-205567-profusion.xml
+shhs1-205568-profusion.xml
+shhs1-205569-profusion.xml
+shhs1-205570-profusion.xml
+shhs1-205571-profusion.xml
+shhs1-205572-profusion.xml
+shhs1-205573-profusion.xml
+shhs1-205574-profusion.xml
+shhs1-205575-profusion.xml
+shhs1-205576-profusion.xml
+shhs1-205577-profusion.xml
+shhs1-205578-profusion.xml
+shhs1-205579-profusion.xml
+shhs1-205580-profusion.xml
+shhs1-205581-profusion.xml
+shhs1-205582-profusion.xml
+shhs1-205583-profusion.xml
+shhs1-205584-profusion.xml
+shhs1-205585-profusion.xml
+shhs1-205586-profusion.xml
+shhs1-205587-profusion.xml
+shhs1-205588-profusion.xml
+shhs1-205589-profusion.xml
+shhs1-205590-profusion.xml
+shhs1-205591-profusion.xml
+shhs1-205592-profusion.xml
+shhs1-205593-profusion.xml
+shhs1-205594-profusion.xml
+shhs1-205595-profusion.xml
+shhs1-205596-profusion.xml
+shhs1-205597-profusion.xml
+shhs1-205598-profusion.xml
+shhs1-205599-profusion.xml
+shhs1-205600-profusion.xml
+shhs1-205601-profusion.xml
+shhs1-205602-profusion.xml
+shhs1-205603-profusion.xml
+shhs1-205604-profusion.xml
+shhs1-205605-profusion.xml
+shhs1-205606-profusion.xml
+shhs1-205607-profusion.xml
+shhs1-205608-profusion.xml
+shhs1-205609-profusion.xml
+shhs1-205610-profusion.xml
+shhs1-205611-profusion.xml
+shhs1-205612-profusion.xml
+shhs1-205613-profusion.xml
+shhs1-205614-profusion.xml
+shhs1-205615-profusion.xml
+shhs1-205616-profusion.xml
+shhs1-205617-profusion.xml
+shhs1-205618-profusion.xml
+shhs1-205619-profusion.xml
+shhs1-205620-profusion.xml
+shhs1-205621-profusion.xml
+shhs1-205622-profusion.xml
+shhs1-205623-profusion.xml
+shhs1-205624-profusion.xml
+shhs1-205625-profusion.xml
+shhs1-205626-profusion.xml
+shhs1-205627-profusion.xml
+shhs1-205628-profusion.xml
+shhs1-205629-profusion.xml
+shhs1-205630-profusion.xml
+shhs1-205631-profusion.xml
+shhs1-205632-profusion.xml
+shhs1-205633-profusion.xml
+shhs1-205634-profusion.xml
+shhs1-205635-profusion.xml
+shhs1-205636-profusion.xml
+shhs1-205637-profusion.xml
+shhs1-205638-profusion.xml
+shhs1-205639-profusion.xml
+shhs1-205640-profusion.xml
+shhs1-205641-profusion.xml
+shhs1-205642-profusion.xml
+shhs1-205643-profusion.xml
+shhs1-205644-profusion.xml
+shhs1-205645-profusion.xml
+shhs1-205646-profusion.xml
+shhs1-205647-profusion.xml
+shhs1-205648-profusion.xml
+shhs1-205649-profusion.xml
+shhs1-205650-profusion.xml
+shhs1-205651-profusion.xml
+shhs1-205652-profusion.xml
+shhs1-205653-profusion.xml
+shhs1-205654-profusion.xml
+shhs1-205655-profusion.xml
+shhs1-205656-profusion.xml
+shhs1-205657-profusion.xml
+shhs1-205658-profusion.xml
+shhs1-205659-profusion.xml
+shhs1-205660-profusion.xml
+shhs1-205661-profusion.xml
+shhs1-205662-profusion.xml
+shhs1-205663-profusion.xml
+shhs1-205664-profusion.xml
+shhs1-205665-profusion.xml
+shhs1-205666-profusion.xml
+shhs1-205667-profusion.xml
+shhs1-205668-profusion.xml
+shhs1-205669-profusion.xml
+shhs1-205670-profusion.xml
+shhs1-205671-profusion.xml
+shhs1-205672-profusion.xml
+shhs1-205673-profusion.xml
+shhs1-205674-profusion.xml
+shhs1-205675-profusion.xml
+shhs1-205676-profusion.xml
+shhs1-205677-profusion.xml
+shhs1-205678-profusion.xml
+shhs1-205679-profusion.xml
+shhs1-205680-profusion.xml
+shhs1-205681-profusion.xml
+shhs1-205682-profusion.xml
+shhs1-205683-profusion.xml
+shhs1-205684-profusion.xml
+shhs1-205685-profusion.xml
+shhs1-205686-profusion.xml
+shhs1-205687-profusion.xml
+shhs1-205688-profusion.xml
+shhs1-205689-profusion.xml
+shhs1-205690-profusion.xml
+shhs1-205691-profusion.xml
+shhs1-205692-profusion.xml
+shhs1-205693-profusion.xml
+shhs1-205694-profusion.xml
+shhs1-205695-profusion.xml
+shhs1-205696-profusion.xml
+shhs1-205697-profusion.xml
+shhs1-205698-profusion.xml
+shhs1-205699-profusion.xml
+shhs1-205700-profusion.xml
+shhs1-205701-profusion.xml
+shhs1-205702-profusion.xml
+shhs1-205703-profusion.xml
+shhs1-205704-profusion.xml
+shhs1-205705-profusion.xml
+shhs1-205706-profusion.xml
+shhs1-205707-profusion.xml
+shhs1-205708-profusion.xml
+shhs1-205709-profusion.xml
+shhs1-205710-profusion.xml
+shhs1-205711-profusion.xml
+shhs1-205712-profusion.xml
+shhs1-205713-profusion.xml
+shhs1-205714-profusion.xml
+shhs1-205715-profusion.xml
+shhs1-205716-profusion.xml
+shhs1-205717-profusion.xml
+shhs1-205718-profusion.xml
+shhs1-205719-profusion.xml
+shhs1-205720-profusion.xml
+shhs1-205721-profusion.xml
+shhs1-205722-profusion.xml
+shhs1-205723-profusion.xml
+shhs1-205724-profusion.xml
+shhs1-205725-profusion.xml
+shhs1-205726-profusion.xml
+shhs1-205727-profusion.xml
+shhs1-205728-profusion.xml
+shhs1-205729-profusion.xml
+shhs1-205730-profusion.xml
+shhs1-205731-profusion.xml
+shhs1-205732-profusion.xml
+shhs1-205733-profusion.xml
+shhs1-205734-profusion.xml
+shhs1-205735-profusion.xml
+shhs1-205736-profusion.xml
+shhs1-205737-profusion.xml
+shhs1-205738-profusion.xml
+shhs1-205739-profusion.xml
+shhs1-205740-profusion.xml
+shhs1-205741-profusion.xml
+shhs1-205742-profusion.xml
+shhs1-205743-profusion.xml
+shhs1-205744-profusion.xml
+shhs1-205745-profusion.xml
+shhs1-205746-profusion.xml
+shhs1-205747-profusion.xml
+shhs1-205748-profusion.xml
+shhs1-205749-profusion.xml
+shhs1-205750-profusion.xml
+shhs1-205751-profusion.xml
+shhs1-205752-profusion.xml
+shhs1-205753-profusion.xml
+shhs1-205754-profusion.xml
+shhs1-205755-profusion.xml
+shhs1-205756-profusion.xml
+shhs1-205757-profusion.xml
+shhs1-205758-profusion.xml
+shhs1-205759-profusion.xml
+shhs1-205760-profusion.xml
+shhs1-205761-profusion.xml
+shhs1-205762-profusion.xml
+shhs1-205763-profusion.xml
+shhs1-205764-profusion.xml
+shhs1-205765-profusion.xml
+shhs1-205766-profusion.xml
+shhs1-205767-profusion.xml
+shhs1-205768-profusion.xml
+shhs1-205769-profusion.xml
+shhs1-205770-profusion.xml
+shhs1-205771-profusion.xml
+shhs1-205772-profusion.xml
+shhs1-205773-profusion.xml
+shhs1-205774-profusion.xml
+shhs1-205775-profusion.xml
+shhs1-205776-profusion.xml
+shhs1-205777-profusion.xml
+shhs1-205778-profusion.xml
+shhs1-205779-profusion.xml
+shhs1-205780-profusion.xml
+shhs1-205781-profusion.xml
+shhs1-205782-profusion.xml
+shhs1-205783-profusion.xml
+shhs1-205784-profusion.xml
+shhs1-205785-profusion.xml
+shhs1-205786-profusion.xml
+shhs1-205787-profusion.xml
+shhs1-205788-profusion.xml
+shhs1-205789-profusion.xml
+shhs1-205790-profusion.xml
+shhs1-205791-profusion.xml
+shhs1-205792-profusion.xml
+shhs1-205793-profusion.xml
+shhs1-205794-profusion.xml
+shhs1-205795-profusion.xml
+shhs1-205796-profusion.xml
+shhs1-205797-profusion.xml
+shhs1-205798-profusion.xml
+shhs1-205799-profusion.xml
+shhs1-205800-profusion.xml
+shhs1-205801-profusion.xml
+shhs1-205802-profusion.xml
+shhs1-205803-profusion.xml
+shhs1-205804-profusion.xml
diff --git a/data/shhs_meta_data/filenames_edf.txt b/data/shhs_meta_data/filenames_edf.txt
new file mode 100644
index 0000000000000000000000000000000000000000..a61733487deacd07e9086b77a42d0b142abd3e0f
--- /dev/null
+++ b/data/shhs_meta_data/filenames_edf.txt
@@ -0,0 +1,5793 @@
+shhs1-200001.edf
+shhs1-200002.edf
+shhs1-200003.edf
+shhs1-200004.edf
+shhs1-200005.edf
+shhs1-200006.edf
+shhs1-200007.edf
+shhs1-200008.edf
+shhs1-200009.edf
+shhs1-200010.edf
+shhs1-200011.edf
+shhs1-200012.edf
+shhs1-200013.edf
+shhs1-200014.edf
+shhs1-200015.edf
+shhs1-200016.edf
+shhs1-200017.edf
+shhs1-200018.edf
+shhs1-200019.edf
+shhs1-200020.edf
+shhs1-200021.edf
+shhs1-200022.edf
+shhs1-200023.edf
+shhs1-200024.edf
+shhs1-200025.edf
+shhs1-200026.edf
+shhs1-200027.edf
+shhs1-200028.edf
+shhs1-200029.edf
+shhs1-200030.edf
+shhs1-200031.edf
+shhs1-200032.edf
+shhs1-200033.edf
+shhs1-200034.edf
+shhs1-200035.edf
+shhs1-200036.edf
+shhs1-200037.edf
+shhs1-200038.edf
+shhs1-200039.edf
+shhs1-200040.edf
+shhs1-200041.edf
+shhs1-200042.edf
+shhs1-200043.edf
+shhs1-200044.edf
+shhs1-200045.edf
+shhs1-200046.edf
+shhs1-200047.edf
+shhs1-200048.edf
+shhs1-200049.edf
+shhs1-200050.edf
+shhs1-200051.edf
+shhs1-200052.edf
+shhs1-200053.edf
+shhs1-200054.edf
+shhs1-200055.edf
+shhs1-200056.edf
+shhs1-200057.edf
+shhs1-200058.edf
+shhs1-200059.edf
+shhs1-200060.edf
+shhs1-200061.edf
+shhs1-200062.edf
+shhs1-200063.edf
+shhs1-200064.edf
+shhs1-200065.edf
+shhs1-200066.edf
+shhs1-200067.edf
+shhs1-200068.edf
+shhs1-200069.edf
+shhs1-200070.edf
+shhs1-200071.edf
+shhs1-200072.edf
+shhs1-200073.edf
+shhs1-200074.edf
+shhs1-200075.edf
+shhs1-200076.edf
+shhs1-200077.edf
+shhs1-200078.edf
+shhs1-200079.edf
+shhs1-200080.edf
+shhs1-200081.edf
+shhs1-200082.edf
+shhs1-200083.edf
+shhs1-200084.edf
+shhs1-200085.edf
+shhs1-200086.edf
+shhs1-200087.edf
+shhs1-200088.edf
+shhs1-200089.edf
+shhs1-200090.edf
+shhs1-200091.edf
+shhs1-200092.edf
+shhs1-200093.edf
+shhs1-200094.edf
+shhs1-200095.edf
+shhs1-200096.edf
+shhs1-200097.edf
+shhs1-200098.edf
+shhs1-200099.edf
+shhs1-200100.edf
+shhs1-200101.edf
+shhs1-200102.edf
+shhs1-200103.edf
+shhs1-200104.edf
+shhs1-200105.edf
+shhs1-200106.edf
+shhs1-200107.edf
+shhs1-200108.edf
+shhs1-200109.edf
+shhs1-200110.edf
+shhs1-200111.edf
+shhs1-200112.edf
+shhs1-200113.edf
+shhs1-200114.edf
+shhs1-200115.edf
+shhs1-200116.edf
+shhs1-200117.edf
+shhs1-200118.edf
+shhs1-200119.edf
+shhs1-200120.edf
+shhs1-200121.edf
+shhs1-200122.edf
+shhs1-200123.edf
+shhs1-200124.edf
+shhs1-200125.edf
+shhs1-200126.edf
+shhs1-200127.edf
+shhs1-200128.edf
+shhs1-200129.edf
+shhs1-200130.edf
+shhs1-200131.edf
+shhs1-200132.edf
+shhs1-200133.edf
+shhs1-200134.edf
+shhs1-200135.edf
+shhs1-200136.edf
+shhs1-200137.edf
+shhs1-200138.edf
+shhs1-200139.edf
+shhs1-200140.edf
+shhs1-200141.edf
+shhs1-200142.edf
+shhs1-200143.edf
+shhs1-200144.edf
+shhs1-200145.edf
+shhs1-200147.edf
+shhs1-200148.edf
+shhs1-200149.edf
+shhs1-200150.edf
+shhs1-200151.edf
+shhs1-200152.edf
+shhs1-200153.edf
+shhs1-200154.edf
+shhs1-200155.edf
+shhs1-200156.edf
+shhs1-200157.edf
+shhs1-200158.edf
+shhs1-200159.edf
+shhs1-200160.edf
+shhs1-200161.edf
+shhs1-200162.edf
+shhs1-200163.edf
+shhs1-200164.edf
+shhs1-200165.edf
+shhs1-200166.edf
+shhs1-200167.edf
+shhs1-200168.edf
+shhs1-200169.edf
+shhs1-200170.edf
+shhs1-200171.edf
+shhs1-200172.edf
+shhs1-200173.edf
+shhs1-200174.edf
+shhs1-200175.edf
+shhs1-200176.edf
+shhs1-200177.edf
+shhs1-200178.edf
+shhs1-200179.edf
+shhs1-200180.edf
+shhs1-200181.edf
+shhs1-200182.edf
+shhs1-200183.edf
+shhs1-200184.edf
+shhs1-200185.edf
+shhs1-200186.edf
+shhs1-200187.edf
+shhs1-200188.edf
+shhs1-200189.edf
+shhs1-200190.edf
+shhs1-200191.edf
+shhs1-200192.edf
+shhs1-200193.edf
+shhs1-200194.edf
+shhs1-200195.edf
+shhs1-200196.edf
+shhs1-200197.edf
+shhs1-200198.edf
+shhs1-200199.edf
+shhs1-200200.edf
+shhs1-200201.edf
+shhs1-200202.edf
+shhs1-200203.edf
+shhs1-200204.edf
+shhs1-200205.edf
+shhs1-200206.edf
+shhs1-200207.edf
+shhs1-200208.edf
+shhs1-200209.edf
+shhs1-200210.edf
+shhs1-200211.edf
+shhs1-200212.edf
+shhs1-200213.edf
+shhs1-200214.edf
+shhs1-200215.edf
+shhs1-200216.edf
+shhs1-200217.edf
+shhs1-200218.edf
+shhs1-200219.edf
+shhs1-200220.edf
+shhs1-200221.edf
+shhs1-200222.edf
+shhs1-200223.edf
+shhs1-200224.edf
+shhs1-200225.edf
+shhs1-200226.edf
+shhs1-200227.edf
+shhs1-200228.edf
+shhs1-200229.edf
+shhs1-200230.edf
+shhs1-200231.edf
+shhs1-200232.edf
+shhs1-200233.edf
+shhs1-200234.edf
+shhs1-200235.edf
+shhs1-200236.edf
+shhs1-200237.edf
+shhs1-200238.edf
+shhs1-200239.edf
+shhs1-200240.edf
+shhs1-200241.edf
+shhs1-200242.edf
+shhs1-200243.edf
+shhs1-200244.edf
+shhs1-200245.edf
+shhs1-200247.edf
+shhs1-200248.edf
+shhs1-200249.edf
+shhs1-200250.edf
+shhs1-200251.edf
+shhs1-200252.edf
+shhs1-200253.edf
+shhs1-200254.edf
+shhs1-200255.edf
+shhs1-200256.edf
+shhs1-200257.edf
+shhs1-200258.edf
+shhs1-200259.edf
+shhs1-200260.edf
+shhs1-200261.edf
+shhs1-200262.edf
+shhs1-200263.edf
+shhs1-200264.edf
+shhs1-200265.edf
+shhs1-200266.edf
+shhs1-200267.edf
+shhs1-200268.edf
+shhs1-200269.edf
+shhs1-200270.edf
+shhs1-200271.edf
+shhs1-200272.edf
+shhs1-200273.edf
+shhs1-200274.edf
+shhs1-200275.edf
+shhs1-200276.edf
+shhs1-200277.edf
+shhs1-200278.edf
+shhs1-200280.edf
+shhs1-200281.edf
+shhs1-200282.edf
+shhs1-200283.edf
+shhs1-200284.edf
+shhs1-200285.edf
+shhs1-200286.edf
+shhs1-200287.edf
+shhs1-200288.edf
+shhs1-200289.edf
+shhs1-200290.edf
+shhs1-200291.edf
+shhs1-200292.edf
+shhs1-200293.edf
+shhs1-200294.edf
+shhs1-200295.edf
+shhs1-200296.edf
+shhs1-200297.edf
+shhs1-200298.edf
+shhs1-200299.edf
+shhs1-200300.edf
+shhs1-200301.edf
+shhs1-200302.edf
+shhs1-200303.edf
+shhs1-200304.edf
+shhs1-200305.edf
+shhs1-200306.edf
+shhs1-200307.edf
+shhs1-200308.edf
+shhs1-200309.edf
+shhs1-200310.edf
+shhs1-200311.edf
+shhs1-200312.edf
+shhs1-200313.edf
+shhs1-200314.edf
+shhs1-200315.edf
+shhs1-200316.edf
+shhs1-200317.edf
+shhs1-200318.edf
+shhs1-200319.edf
+shhs1-200320.edf
+shhs1-200321.edf
+shhs1-200322.edf
+shhs1-200323.edf
+shhs1-200324.edf
+shhs1-200325.edf
+shhs1-200326.edf
+shhs1-200327.edf
+shhs1-200328.edf
+shhs1-200329.edf
+shhs1-200330.edf
+shhs1-200331.edf
+shhs1-200332.edf
+shhs1-200333.edf
+shhs1-200334.edf
+shhs1-200335.edf
+shhs1-200336.edf
+shhs1-200337.edf
+shhs1-200338.edf
+shhs1-200339.edf
+shhs1-200340.edf
+shhs1-200341.edf
+shhs1-200342.edf
+shhs1-200343.edf
+shhs1-200344.edf
+shhs1-200345.edf
+shhs1-200346.edf
+shhs1-200347.edf
+shhs1-200348.edf
+shhs1-200349.edf
+shhs1-200350.edf
+shhs1-200351.edf
+shhs1-200352.edf
+shhs1-200353.edf
+shhs1-200354.edf
+shhs1-200355.edf
+shhs1-200356.edf
+shhs1-200357.edf
+shhs1-200358.edf
+shhs1-200359.edf
+shhs1-200360.edf
+shhs1-200361.edf
+shhs1-200362.edf
+shhs1-200363.edf
+shhs1-200364.edf
+shhs1-200365.edf
+shhs1-200366.edf
+shhs1-200367.edf
+shhs1-200368.edf
+shhs1-200369.edf
+shhs1-200370.edf
+shhs1-200371.edf
+shhs1-200372.edf
+shhs1-200373.edf
+shhs1-200374.edf
+shhs1-200375.edf
+shhs1-200376.edf
+shhs1-200377.edf
+shhs1-200378.edf
+shhs1-200379.edf
+shhs1-200380.edf
+shhs1-200381.edf
+shhs1-200382.edf
+shhs1-200383.edf
+shhs1-200384.edf
+shhs1-200385.edf
+shhs1-200386.edf
+shhs1-200387.edf
+shhs1-200388.edf
+shhs1-200389.edf
+shhs1-200390.edf
+shhs1-200391.edf
+shhs1-200392.edf
+shhs1-200393.edf
+shhs1-200394.edf
+shhs1-200395.edf
+shhs1-200396.edf
+shhs1-200397.edf
+shhs1-200398.edf
+shhs1-200399.edf
+shhs1-200400.edf
+shhs1-200401.edf
+shhs1-200402.edf
+shhs1-200403.edf
+shhs1-200404.edf
+shhs1-200405.edf
+shhs1-200406.edf
+shhs1-200407.edf
+shhs1-200408.edf
+shhs1-200409.edf
+shhs1-200410.edf
+shhs1-200411.edf
+shhs1-200412.edf
+shhs1-200413.edf
+shhs1-200414.edf
+shhs1-200415.edf
+shhs1-200416.edf
+shhs1-200417.edf
+shhs1-200418.edf
+shhs1-200419.edf
+shhs1-200420.edf
+shhs1-200421.edf
+shhs1-200422.edf
+shhs1-200423.edf
+shhs1-200424.edf
+shhs1-200425.edf
+shhs1-200426.edf
+shhs1-200427.edf
+shhs1-200428.edf
+shhs1-200429.edf
+shhs1-200430.edf
+shhs1-200431.edf
+shhs1-200432.edf
+shhs1-200433.edf
+shhs1-200434.edf
+shhs1-200435.edf
+shhs1-200436.edf
+shhs1-200437.edf
+shhs1-200438.edf
+shhs1-200439.edf
+shhs1-200440.edf
+shhs1-200441.edf
+shhs1-200442.edf
+shhs1-200443.edf
+shhs1-200444.edf
+shhs1-200445.edf
+shhs1-200446.edf
+shhs1-200447.edf
+shhs1-200448.edf
+shhs1-200449.edf
+shhs1-200450.edf
+shhs1-200451.edf
+shhs1-200452.edf
+shhs1-200453.edf
+shhs1-200454.edf
+shhs1-200455.edf
+shhs1-200456.edf
+shhs1-200457.edf
+shhs1-200458.edf
+shhs1-200459.edf
+shhs1-200460.edf
+shhs1-200461.edf
+shhs1-200462.edf
+shhs1-200463.edf
+shhs1-200464.edf
+shhs1-200465.edf
+shhs1-200466.edf
+shhs1-200467.edf
+shhs1-200468.edf
+shhs1-200469.edf
+shhs1-200470.edf
+shhs1-200471.edf
+shhs1-200472.edf
+shhs1-200473.edf
+shhs1-200474.edf
+shhs1-200475.edf
+shhs1-200476.edf
+shhs1-200477.edf
+shhs1-200478.edf
+shhs1-200479.edf
+shhs1-200480.edf
+shhs1-200481.edf
+shhs1-200482.edf
+shhs1-200483.edf
+shhs1-200484.edf
+shhs1-200485.edf
+shhs1-200486.edf
+shhs1-200487.edf
+shhs1-200488.edf
+shhs1-200489.edf
+shhs1-200490.edf
+shhs1-200491.edf
+shhs1-200492.edf
+shhs1-200493.edf
+shhs1-200494.edf
+shhs1-200495.edf
+shhs1-200496.edf
+shhs1-200497.edf
+shhs1-200498.edf
+shhs1-200499.edf
+shhs1-200500.edf
+shhs1-200501.edf
+shhs1-200502.edf
+shhs1-200503.edf
+shhs1-200504.edf
+shhs1-200505.edf
+shhs1-200506.edf
+shhs1-200507.edf
+shhs1-200508.edf
+shhs1-200509.edf
+shhs1-200510.edf
+shhs1-200511.edf
+shhs1-200512.edf
+shhs1-200513.edf
+shhs1-200514.edf
+shhs1-200515.edf
+shhs1-200516.edf
+shhs1-200517.edf
+shhs1-200518.edf
+shhs1-200519.edf
+shhs1-200520.edf
+shhs1-200521.edf
+shhs1-200522.edf
+shhs1-200523.edf
+shhs1-200524.edf
+shhs1-200525.edf
+shhs1-200526.edf
+shhs1-200527.edf
+shhs1-200528.edf
+shhs1-200529.edf
+shhs1-200530.edf
+shhs1-200531.edf
+shhs1-200532.edf
+shhs1-200533.edf
+shhs1-200534.edf
+shhs1-200535.edf
+shhs1-200536.edf
+shhs1-200537.edf
+shhs1-200538.edf
+shhs1-200539.edf
+shhs1-200540.edf
+shhs1-200541.edf
+shhs1-200542.edf
+shhs1-200543.edf
+shhs1-200544.edf
+shhs1-200545.edf
+shhs1-200546.edf
+shhs1-200547.edf
+shhs1-200548.edf
+shhs1-200549.edf
+shhs1-200550.edf
+shhs1-200551.edf
+shhs1-200552.edf
+shhs1-200553.edf
+shhs1-200554.edf
+shhs1-200555.edf
+shhs1-200556.edf
+shhs1-200557.edf
+shhs1-200558.edf
+shhs1-200559.edf
+shhs1-200560.edf
+shhs1-200561.edf
+shhs1-200562.edf
+shhs1-200563.edf
+shhs1-200564.edf
+shhs1-200565.edf
+shhs1-200566.edf
+shhs1-200567.edf
+shhs1-200568.edf
+shhs1-200569.edf
+shhs1-200570.edf
+shhs1-200571.edf
+shhs1-200572.edf
+shhs1-200573.edf
+shhs1-200574.edf
+shhs1-200575.edf
+shhs1-200576.edf
+shhs1-200577.edf
+shhs1-200578.edf
+shhs1-200579.edf
+shhs1-200580.edf
+shhs1-200581.edf
+shhs1-200582.edf
+shhs1-200583.edf
+shhs1-200584.edf
+shhs1-200585.edf
+shhs1-200586.edf
+shhs1-200587.edf
+shhs1-200588.edf
+shhs1-200589.edf
+shhs1-200590.edf
+shhs1-200591.edf
+shhs1-200592.edf
+shhs1-200593.edf
+shhs1-200594.edf
+shhs1-200595.edf
+shhs1-200596.edf
+shhs1-200597.edf
+shhs1-200598.edf
+shhs1-200599.edf
+shhs1-200600.edf
+shhs1-200601.edf
+shhs1-200602.edf
+shhs1-200603.edf
+shhs1-200604.edf
+shhs1-200605.edf
+shhs1-200606.edf
+shhs1-200607.edf
+shhs1-200608.edf
+shhs1-200609.edf
+shhs1-200610.edf
+shhs1-200611.edf
+shhs1-200612.edf
+shhs1-200613.edf
+shhs1-200614.edf
+shhs1-200615.edf
+shhs1-200616.edf
+shhs1-200617.edf
+shhs1-200618.edf
+shhs1-200619.edf
+shhs1-200620.edf
+shhs1-200621.edf
+shhs1-200622.edf
+shhs1-200623.edf
+shhs1-200624.edf
+shhs1-200625.edf
+shhs1-200626.edf
+shhs1-200627.edf
+shhs1-200628.edf
+shhs1-200629.edf
+shhs1-200630.edf
+shhs1-200631.edf
+shhs1-200632.edf
+shhs1-200633.edf
+shhs1-200634.edf
+shhs1-200635.edf
+shhs1-200636.edf
+shhs1-200637.edf
+shhs1-200638.edf
+shhs1-200639.edf
+shhs1-200640.edf
+shhs1-200641.edf
+shhs1-200642.edf
+shhs1-200643.edf
+shhs1-200644.edf
+shhs1-200645.edf
+shhs1-200646.edf
+shhs1-200647.edf
+shhs1-200648.edf
+shhs1-200649.edf
+shhs1-200650.edf
+shhs1-200651.edf
+shhs1-200652.edf
+shhs1-200653.edf
+shhs1-200654.edf
+shhs1-200655.edf
+shhs1-200656.edf
+shhs1-200657.edf
+shhs1-200658.edf
+shhs1-200659.edf
+shhs1-200660.edf
+shhs1-200661.edf
+shhs1-200662.edf
+shhs1-200663.edf
+shhs1-200664.edf
+shhs1-200665.edf
+shhs1-200666.edf
+shhs1-200667.edf
+shhs1-200668.edf
+shhs1-200669.edf
+shhs1-200670.edf
+shhs1-200671.edf
+shhs1-200672.edf
+shhs1-200673.edf
+shhs1-200674.edf
+shhs1-200675.edf
+shhs1-200676.edf
+shhs1-200677.edf
+shhs1-200678.edf
+shhs1-200679.edf
+shhs1-200680.edf
+shhs1-200681.edf
+shhs1-200682.edf
+shhs1-200683.edf
+shhs1-200684.edf
+shhs1-200685.edf
+shhs1-200686.edf
+shhs1-200687.edf
+shhs1-200688.edf
+shhs1-200689.edf
+shhs1-200690.edf
+shhs1-200691.edf
+shhs1-200692.edf
+shhs1-200693.edf
+shhs1-200694.edf
+shhs1-200695.edf
+shhs1-200696.edf
+shhs1-200697.edf
+shhs1-200698.edf
+shhs1-200699.edf
+shhs1-200700.edf
+shhs1-200701.edf
+shhs1-200702.edf
+shhs1-200703.edf
+shhs1-200704.edf
+shhs1-200705.edf
+shhs1-200706.edf
+shhs1-200707.edf
+shhs1-200708.edf
+shhs1-200709.edf
+shhs1-200710.edf
+shhs1-200711.edf
+shhs1-200712.edf
+shhs1-200713.edf
+shhs1-200714.edf
+shhs1-200715.edf
+shhs1-200716.edf
+shhs1-200717.edf
+shhs1-200718.edf
+shhs1-200719.edf
+shhs1-200720.edf
+shhs1-200721.edf
+shhs1-200722.edf
+shhs1-200723.edf
+shhs1-200724.edf
+shhs1-200725.edf
+shhs1-200726.edf
+shhs1-200727.edf
+shhs1-200728.edf
+shhs1-200729.edf
+shhs1-200730.edf
+shhs1-200731.edf
+shhs1-200732.edf
+shhs1-200733.edf
+shhs1-200734.edf
+shhs1-200735.edf
+shhs1-200736.edf
+shhs1-200737.edf
+shhs1-200738.edf
+shhs1-200739.edf
+shhs1-200740.edf
+shhs1-200741.edf
+shhs1-200742.edf
+shhs1-200743.edf
+shhs1-200744.edf
+shhs1-200745.edf
+shhs1-200746.edf
+shhs1-200747.edf
+shhs1-200748.edf
+shhs1-200749.edf
+shhs1-200750.edf
+shhs1-200751.edf
+shhs1-200752.edf
+shhs1-200753.edf
+shhs1-200754.edf
+shhs1-200755.edf
+shhs1-200756.edf
+shhs1-200757.edf
+shhs1-200758.edf
+shhs1-200759.edf
+shhs1-200760.edf
+shhs1-200761.edf
+shhs1-200762.edf
+shhs1-200763.edf
+shhs1-200764.edf
+shhs1-200765.edf
+shhs1-200766.edf
+shhs1-200767.edf
+shhs1-200768.edf
+shhs1-200769.edf
+shhs1-200770.edf
+shhs1-200771.edf
+shhs1-200772.edf
+shhs1-200773.edf
+shhs1-200774.edf
+shhs1-200775.edf
+shhs1-200776.edf
+shhs1-200777.edf
+shhs1-200778.edf
+shhs1-200779.edf
+shhs1-200780.edf
+shhs1-200781.edf
+shhs1-200782.edf
+shhs1-200783.edf
+shhs1-200784.edf
+shhs1-200785.edf
+shhs1-200786.edf
+shhs1-200787.edf
+shhs1-200788.edf
+shhs1-200789.edf
+shhs1-200790.edf
+shhs1-200791.edf
+shhs1-200792.edf
+shhs1-200793.edf
+shhs1-200794.edf
+shhs1-200795.edf
+shhs1-200796.edf
+shhs1-200797.edf
+shhs1-200798.edf
+shhs1-200799.edf
+shhs1-200800.edf
+shhs1-200801.edf
+shhs1-200802.edf
+shhs1-200803.edf
+shhs1-200804.edf
+shhs1-200805.edf
+shhs1-200806.edf
+shhs1-200807.edf
+shhs1-200808.edf
+shhs1-200809.edf
+shhs1-200810.edf
+shhs1-200811.edf
+shhs1-200812.edf
+shhs1-200813.edf
+shhs1-200814.edf
+shhs1-200815.edf
+shhs1-200816.edf
+shhs1-200817.edf
+shhs1-200818.edf
+shhs1-200819.edf
+shhs1-200820.edf
+shhs1-200821.edf
+shhs1-200822.edf
+shhs1-200823.edf
+shhs1-200824.edf
+shhs1-200825.edf
+shhs1-200826.edf
+shhs1-200827.edf
+shhs1-200828.edf
+shhs1-200829.edf
+shhs1-200830.edf
+shhs1-200831.edf
+shhs1-200832.edf
+shhs1-200833.edf
+shhs1-200834.edf
+shhs1-200835.edf
+shhs1-200836.edf
+shhs1-200837.edf
+shhs1-200838.edf
+shhs1-200839.edf
+shhs1-200840.edf
+shhs1-200841.edf
+shhs1-200842.edf
+shhs1-200843.edf
+shhs1-200844.edf
+shhs1-200845.edf
+shhs1-200846.edf
+shhs1-200847.edf
+shhs1-200848.edf
+shhs1-200849.edf
+shhs1-200850.edf
+shhs1-200851.edf
+shhs1-200852.edf
+shhs1-200853.edf
+shhs1-200854.edf
+shhs1-200855.edf
+shhs1-200856.edf
+shhs1-200857.edf
+shhs1-200858.edf
+shhs1-200859.edf
+shhs1-200860.edf
+shhs1-200861.edf
+shhs1-200862.edf
+shhs1-200863.edf
+shhs1-200864.edf
+shhs1-200865.edf
+shhs1-200866.edf
+shhs1-200867.edf
+shhs1-200868.edf
+shhs1-200869.edf
+shhs1-200870.edf
+shhs1-200871.edf
+shhs1-200872.edf
+shhs1-200873.edf
+shhs1-200874.edf
+shhs1-200875.edf
+shhs1-200876.edf
+shhs1-200877.edf
+shhs1-200878.edf
+shhs1-200879.edf
+shhs1-200880.edf
+shhs1-200881.edf
+shhs1-200882.edf
+shhs1-200883.edf
+shhs1-200884.edf
+shhs1-200885.edf
+shhs1-200886.edf
+shhs1-200887.edf
+shhs1-200888.edf
+shhs1-200889.edf
+shhs1-200890.edf
+shhs1-200891.edf
+shhs1-200892.edf
+shhs1-200893.edf
+shhs1-200894.edf
+shhs1-200895.edf
+shhs1-200896.edf
+shhs1-200897.edf
+shhs1-200898.edf
+shhs1-200899.edf
+shhs1-200900.edf
+shhs1-200901.edf
+shhs1-200902.edf
+shhs1-200903.edf
+shhs1-200904.edf
+shhs1-200905.edf
+shhs1-200906.edf
+shhs1-200907.edf
+shhs1-200908.edf
+shhs1-200909.edf
+shhs1-200910.edf
+shhs1-200911.edf
+shhs1-200912.edf
+shhs1-200913.edf
+shhs1-200914.edf
+shhs1-200915.edf
+shhs1-200916.edf
+shhs1-200917.edf
+shhs1-200918.edf
+shhs1-200919.edf
+shhs1-200920.edf
+shhs1-200921.edf
+shhs1-200922.edf
+shhs1-200923.edf
+shhs1-200924.edf
+shhs1-200925.edf
+shhs1-200926.edf
+shhs1-200927.edf
+shhs1-200928.edf
+shhs1-200929.edf
+shhs1-200930.edf
+shhs1-200931.edf
+shhs1-200932.edf
+shhs1-200933.edf
+shhs1-200934.edf
+shhs1-200935.edf
+shhs1-200936.edf
+shhs1-200937.edf
+shhs1-200938.edf
+shhs1-200939.edf
+shhs1-200940.edf
+shhs1-200941.edf
+shhs1-200942.edf
+shhs1-200943.edf
+shhs1-200944.edf
+shhs1-200945.edf
+shhs1-200946.edf
+shhs1-200947.edf
+shhs1-200948.edf
+shhs1-200949.edf
+shhs1-200950.edf
+shhs1-200951.edf
+shhs1-200952.edf
+shhs1-200953.edf
+shhs1-200954.edf
+shhs1-200955.edf
+shhs1-200956.edf
+shhs1-200957.edf
+shhs1-200958.edf
+shhs1-200959.edf
+shhs1-200960.edf
+shhs1-200961.edf
+shhs1-200962.edf
+shhs1-200963.edf
+shhs1-200964.edf
+shhs1-200965.edf
+shhs1-200966.edf
+shhs1-200967.edf
+shhs1-200968.edf
+shhs1-200969.edf
+shhs1-200970.edf
+shhs1-200971.edf
+shhs1-200972.edf
+shhs1-200973.edf
+shhs1-200974.edf
+shhs1-200975.edf
+shhs1-200976.edf
+shhs1-200977.edf
+shhs1-200978.edf
+shhs1-200979.edf
+shhs1-200980.edf
+shhs1-200981.edf
+shhs1-200982.edf
+shhs1-200983.edf
+shhs1-200984.edf
+shhs1-200985.edf
+shhs1-200986.edf
+shhs1-200987.edf
+shhs1-200988.edf
+shhs1-200989.edf
+shhs1-200990.edf
+shhs1-200991.edf
+shhs1-200992.edf
+shhs1-200993.edf
+shhs1-200994.edf
+shhs1-200995.edf
+shhs1-200996.edf
+shhs1-200997.edf
+shhs1-200998.edf
+shhs1-200999.edf
+shhs1-201000.edf
+shhs1-201001.edf
+shhs1-201002.edf
+shhs1-201003.edf
+shhs1-201004.edf
+shhs1-201005.edf
+shhs1-201006.edf
+shhs1-201007.edf
+shhs1-201008.edf
+shhs1-201009.edf
+shhs1-201010.edf
+shhs1-201011.edf
+shhs1-201012.edf
+shhs1-201013.edf
+shhs1-201014.edf
+shhs1-201015.edf
+shhs1-201016.edf
+shhs1-201017.edf
+shhs1-201018.edf
+shhs1-201019.edf
+shhs1-201020.edf
+shhs1-201021.edf
+shhs1-201022.edf
+shhs1-201023.edf
+shhs1-201024.edf
+shhs1-201025.edf
+shhs1-201026.edf
+shhs1-201027.edf
+shhs1-201028.edf
+shhs1-201029.edf
+shhs1-201030.edf
+shhs1-201031.edf
+shhs1-201032.edf
+shhs1-201033.edf
+shhs1-201034.edf
+shhs1-201035.edf
+shhs1-201036.edf
+shhs1-201037.edf
+shhs1-201038.edf
+shhs1-201039.edf
+shhs1-201040.edf
+shhs1-201041.edf
+shhs1-201042.edf
+shhs1-201043.edf
+shhs1-201044.edf
+shhs1-201045.edf
+shhs1-201046.edf
+shhs1-201047.edf
+shhs1-201048.edf
+shhs1-201049.edf
+shhs1-201050.edf
+shhs1-201051.edf
+shhs1-201052.edf
+shhs1-201053.edf
+shhs1-201054.edf
+shhs1-201055.edf
+shhs1-201056.edf
+shhs1-201057.edf
+shhs1-201058.edf
+shhs1-201059.edf
+shhs1-201060.edf
+shhs1-201061.edf
+shhs1-201062.edf
+shhs1-201063.edf
+shhs1-201064.edf
+shhs1-201065.edf
+shhs1-201066.edf
+shhs1-201067.edf
+shhs1-201068.edf
+shhs1-201069.edf
+shhs1-201070.edf
+shhs1-201071.edf
+shhs1-201072.edf
+shhs1-201073.edf
+shhs1-201074.edf
+shhs1-201075.edf
+shhs1-201076.edf
+shhs1-201077.edf
+shhs1-201078.edf
+shhs1-201079.edf
+shhs1-201080.edf
+shhs1-201081.edf
+shhs1-201082.edf
+shhs1-201083.edf
+shhs1-201084.edf
+shhs1-201085.edf
+shhs1-201086.edf
+shhs1-201087.edf
+shhs1-201088.edf
+shhs1-201089.edf
+shhs1-201090.edf
+shhs1-201091.edf
+shhs1-201092.edf
+shhs1-201093.edf
+shhs1-201094.edf
+shhs1-201095.edf
+shhs1-201096.edf
+shhs1-201097.edf
+shhs1-201098.edf
+shhs1-201099.edf
+shhs1-201100.edf
+shhs1-201101.edf
+shhs1-201102.edf
+shhs1-201103.edf
+shhs1-201104.edf
+shhs1-201105.edf
+shhs1-201106.edf
+shhs1-201107.edf
+shhs1-201108.edf
+shhs1-201109.edf
+shhs1-201110.edf
+shhs1-201111.edf
+shhs1-201112.edf
+shhs1-201113.edf
+shhs1-201114.edf
+shhs1-201116.edf
+shhs1-201117.edf
+shhs1-201118.edf
+shhs1-201119.edf
+shhs1-201120.edf
+shhs1-201121.edf
+shhs1-201122.edf
+shhs1-201123.edf
+shhs1-201124.edf
+shhs1-201125.edf
+shhs1-201126.edf
+shhs1-201127.edf
+shhs1-201128.edf
+shhs1-201129.edf
+shhs1-201130.edf
+shhs1-201131.edf
+shhs1-201132.edf
+shhs1-201133.edf
+shhs1-201134.edf
+shhs1-201135.edf
+shhs1-201136.edf
+shhs1-201137.edf
+shhs1-201138.edf
+shhs1-201139.edf
+shhs1-201140.edf
+shhs1-201141.edf
+shhs1-201142.edf
+shhs1-201143.edf
+shhs1-201144.edf
+shhs1-201145.edf
+shhs1-201146.edf
+shhs1-201147.edf
+shhs1-201148.edf
+shhs1-201149.edf
+shhs1-201150.edf
+shhs1-201151.edf
+shhs1-201152.edf
+shhs1-201153.edf
+shhs1-201154.edf
+shhs1-201155.edf
+shhs1-201156.edf
+shhs1-201157.edf
+shhs1-201158.edf
+shhs1-201159.edf
+shhs1-201160.edf
+shhs1-201161.edf
+shhs1-201162.edf
+shhs1-201163.edf
+shhs1-201164.edf
+shhs1-201165.edf
+shhs1-201166.edf
+shhs1-201167.edf
+shhs1-201168.edf
+shhs1-201169.edf
+shhs1-201170.edf
+shhs1-201171.edf
+shhs1-201172.edf
+shhs1-201173.edf
+shhs1-201174.edf
+shhs1-201175.edf
+shhs1-201176.edf
+shhs1-201177.edf
+shhs1-201178.edf
+shhs1-201179.edf
+shhs1-201180.edf
+shhs1-201181.edf
+shhs1-201182.edf
+shhs1-201183.edf
+shhs1-201184.edf
+shhs1-201185.edf
+shhs1-201186.edf
+shhs1-201187.edf
+shhs1-201188.edf
+shhs1-201189.edf
+shhs1-201190.edf
+shhs1-201191.edf
+shhs1-201192.edf
+shhs1-201193.edf
+shhs1-201194.edf
+shhs1-201195.edf
+shhs1-201196.edf
+shhs1-201197.edf
+shhs1-201198.edf
+shhs1-201199.edf
+shhs1-201200.edf
+shhs1-201201.edf
+shhs1-201202.edf
+shhs1-201203.edf
+shhs1-201204.edf
+shhs1-201205.edf
+shhs1-201206.edf
+shhs1-201207.edf
+shhs1-201208.edf
+shhs1-201209.edf
+shhs1-201210.edf
+shhs1-201211.edf
+shhs1-201212.edf
+shhs1-201213.edf
+shhs1-201214.edf
+shhs1-201215.edf
+shhs1-201216.edf
+shhs1-201217.edf
+shhs1-201218.edf
+shhs1-201219.edf
+shhs1-201220.edf
+shhs1-201221.edf
+shhs1-201222.edf
+shhs1-201223.edf
+shhs1-201224.edf
+shhs1-201225.edf
+shhs1-201226.edf
+shhs1-201227.edf
+shhs1-201228.edf
+shhs1-201229.edf
+shhs1-201230.edf
+shhs1-201231.edf
+shhs1-201232.edf
+shhs1-201233.edf
+shhs1-201234.edf
+shhs1-201235.edf
+shhs1-201236.edf
+shhs1-201237.edf
+shhs1-201238.edf
+shhs1-201239.edf
+shhs1-201240.edf
+shhs1-201241.edf
+shhs1-201242.edf
+shhs1-201243.edf
+shhs1-201244.edf
+shhs1-201245.edf
+shhs1-201246.edf
+shhs1-201247.edf
+shhs1-201248.edf
+shhs1-201249.edf
+shhs1-201250.edf
+shhs1-201251.edf
+shhs1-201252.edf
+shhs1-201253.edf
+shhs1-201254.edf
+shhs1-201255.edf
+shhs1-201256.edf
+shhs1-201257.edf
+shhs1-201258.edf
+shhs1-201259.edf
+shhs1-201260.edf
+shhs1-201261.edf
+shhs1-201262.edf
+shhs1-201263.edf
+shhs1-201264.edf
+shhs1-201265.edf
+shhs1-201266.edf
+shhs1-201267.edf
+shhs1-201268.edf
+shhs1-201269.edf
+shhs1-201270.edf
+shhs1-201271.edf
+shhs1-201272.edf
+shhs1-201273.edf
+shhs1-201274.edf
+shhs1-201275.edf
+shhs1-201276.edf
+shhs1-201277.edf
+shhs1-201278.edf
+shhs1-201279.edf
+shhs1-201280.edf
+shhs1-201281.edf
+shhs1-201282.edf
+shhs1-201283.edf
+shhs1-201284.edf
+shhs1-201285.edf
+shhs1-201286.edf
+shhs1-201287.edf
+shhs1-201288.edf
+shhs1-201289.edf
+shhs1-201290.edf
+shhs1-201291.edf
+shhs1-201292.edf
+shhs1-201293.edf
+shhs1-201294.edf
+shhs1-201295.edf
+shhs1-201296.edf
+shhs1-201297.edf
+shhs1-201298.edf
+shhs1-201299.edf
+shhs1-201300.edf
+shhs1-201301.edf
+shhs1-201302.edf
+shhs1-201303.edf
+shhs1-201304.edf
+shhs1-201305.edf
+shhs1-201306.edf
+shhs1-201307.edf
+shhs1-201308.edf
+shhs1-201309.edf
+shhs1-201310.edf
+shhs1-201311.edf
+shhs1-201312.edf
+shhs1-201313.edf
+shhs1-201314.edf
+shhs1-201315.edf
+shhs1-201316.edf
+shhs1-201317.edf
+shhs1-201318.edf
+shhs1-201319.edf
+shhs1-201320.edf
+shhs1-201321.edf
+shhs1-201322.edf
+shhs1-201323.edf
+shhs1-201324.edf
+shhs1-201325.edf
+shhs1-201326.edf
+shhs1-201327.edf
+shhs1-201328.edf
+shhs1-201329.edf
+shhs1-201330.edf
+shhs1-201331.edf
+shhs1-201332.edf
+shhs1-201333.edf
+shhs1-201334.edf
+shhs1-201335.edf
+shhs1-201336.edf
+shhs1-201337.edf
+shhs1-201338.edf
+shhs1-201339.edf
+shhs1-201340.edf
+shhs1-201341.edf
+shhs1-201342.edf
+shhs1-201343.edf
+shhs1-201344.edf
+shhs1-201345.edf
+shhs1-201346.edf
+shhs1-201347.edf
+shhs1-201348.edf
+shhs1-201349.edf
+shhs1-201350.edf
+shhs1-201351.edf
+shhs1-201352.edf
+shhs1-201353.edf
+shhs1-201354.edf
+shhs1-201355.edf
+shhs1-201356.edf
+shhs1-201357.edf
+shhs1-201358.edf
+shhs1-201359.edf
+shhs1-201360.edf
+shhs1-201361.edf
+shhs1-201362.edf
+shhs1-201363.edf
+shhs1-201364.edf
+shhs1-201365.edf
+shhs1-201366.edf
+shhs1-201367.edf
+shhs1-201368.edf
+shhs1-201369.edf
+shhs1-201370.edf
+shhs1-201371.edf
+shhs1-201372.edf
+shhs1-201373.edf
+shhs1-201374.edf
+shhs1-201375.edf
+shhs1-201376.edf
+shhs1-201377.edf
+shhs1-201378.edf
+shhs1-201379.edf
+shhs1-201380.edf
+shhs1-201381.edf
+shhs1-201382.edf
+shhs1-201383.edf
+shhs1-201384.edf
+shhs1-201385.edf
+shhs1-201386.edf
+shhs1-201387.edf
+shhs1-201388.edf
+shhs1-201389.edf
+shhs1-201390.edf
+shhs1-201391.edf
+shhs1-201392.edf
+shhs1-201393.edf
+shhs1-201394.edf
+shhs1-201395.edf
+shhs1-201396.edf
+shhs1-201397.edf
+shhs1-201398.edf
+shhs1-201399.edf
+shhs1-201400.edf
+shhs1-201401.edf
+shhs1-201402.edf
+shhs1-201403.edf
+shhs1-201404.edf
+shhs1-201405.edf
+shhs1-201406.edf
+shhs1-201407.edf
+shhs1-201408.edf
+shhs1-201409.edf
+shhs1-201410.edf
+shhs1-201411.edf
+shhs1-201412.edf
+shhs1-201413.edf
+shhs1-201414.edf
+shhs1-201415.edf
+shhs1-201416.edf
+shhs1-201417.edf
+shhs1-201418.edf
+shhs1-201419.edf
+shhs1-201420.edf
+shhs1-201421.edf
+shhs1-201422.edf
+shhs1-201423.edf
+shhs1-201424.edf
+shhs1-201425.edf
+shhs1-201426.edf
+shhs1-201427.edf
+shhs1-201428.edf
+shhs1-201429.edf
+shhs1-201430.edf
+shhs1-201431.edf
+shhs1-201432.edf
+shhs1-201433.edf
+shhs1-201434.edf
+shhs1-201435.edf
+shhs1-201436.edf
+shhs1-201437.edf
+shhs1-201438.edf
+shhs1-201439.edf
+shhs1-201440.edf
+shhs1-201441.edf
+shhs1-201442.edf
+shhs1-201443.edf
+shhs1-201444.edf
+shhs1-201445.edf
+shhs1-201446.edf
+shhs1-201447.edf
+shhs1-201448.edf
+shhs1-201449.edf
+shhs1-201450.edf
+shhs1-201451.edf
+shhs1-201452.edf
+shhs1-201453.edf
+shhs1-201454.edf
+shhs1-201455.edf
+shhs1-201456.edf
+shhs1-201457.edf
+shhs1-201458.edf
+shhs1-201459.edf
+shhs1-201460.edf
+shhs1-201461.edf
+shhs1-201462.edf
+shhs1-201463.edf
+shhs1-201464.edf
+shhs1-201465.edf
+shhs1-201466.edf
+shhs1-201467.edf
+shhs1-201468.edf
+shhs1-201469.edf
+shhs1-201470.edf
+shhs1-201471.edf
+shhs1-201472.edf
+shhs1-201473.edf
+shhs1-201474.edf
+shhs1-201475.edf
+shhs1-201476.edf
+shhs1-201477.edf
+shhs1-201478.edf
+shhs1-201479.edf
+shhs1-201480.edf
+shhs1-201481.edf
+shhs1-201482.edf
+shhs1-201483.edf
+shhs1-201484.edf
+shhs1-201485.edf
+shhs1-201486.edf
+shhs1-201487.edf
+shhs1-201488.edf
+shhs1-201489.edf
+shhs1-201490.edf
+shhs1-201491.edf
+shhs1-201492.edf
+shhs1-201493.edf
+shhs1-201494.edf
+shhs1-201495.edf
+shhs1-201496.edf
+shhs1-201497.edf
+shhs1-201498.edf
+shhs1-201499.edf
+shhs1-201500.edf
+shhs1-201501.edf
+shhs1-201502.edf
+shhs1-201503.edf
+shhs1-201504.edf
+shhs1-201505.edf
+shhs1-201506.edf
+shhs1-201507.edf
+shhs1-201508.edf
+shhs1-201509.edf
+shhs1-201510.edf
+shhs1-201511.edf
+shhs1-201512.edf
+shhs1-201513.edf
+shhs1-201514.edf
+shhs1-201515.edf
+shhs1-201516.edf
+shhs1-201517.edf
+shhs1-201518.edf
+shhs1-201519.edf
+shhs1-201520.edf
+shhs1-201521.edf
+shhs1-201522.edf
+shhs1-201523.edf
+shhs1-201524.edf
+shhs1-201525.edf
+shhs1-201526.edf
+shhs1-201527.edf
+shhs1-201528.edf
+shhs1-201529.edf
+shhs1-201530.edf
+shhs1-201531.edf
+shhs1-201532.edf
+shhs1-201533.edf
+shhs1-201534.edf
+shhs1-201535.edf
+shhs1-201536.edf
+shhs1-201537.edf
+shhs1-201538.edf
+shhs1-201539.edf
+shhs1-201540.edf
+shhs1-201541.edf
+shhs1-201542.edf
+shhs1-201543.edf
+shhs1-201544.edf
+shhs1-201545.edf
+shhs1-201546.edf
+shhs1-201547.edf
+shhs1-201548.edf
+shhs1-201549.edf
+shhs1-201550.edf
+shhs1-201551.edf
+shhs1-201552.edf
+shhs1-201553.edf
+shhs1-201554.edf
+shhs1-201555.edf
+shhs1-201556.edf
+shhs1-201557.edf
+shhs1-201558.edf
+shhs1-201559.edf
+shhs1-201560.edf
+shhs1-201561.edf
+shhs1-201562.edf
+shhs1-201563.edf
+shhs1-201564.edf
+shhs1-201565.edf
+shhs1-201566.edf
+shhs1-201567.edf
+shhs1-201568.edf
+shhs1-201569.edf
+shhs1-201570.edf
+shhs1-201571.edf
+shhs1-201572.edf
+shhs1-201573.edf
+shhs1-201574.edf
+shhs1-201575.edf
+shhs1-201576.edf
+shhs1-201577.edf
+shhs1-201578.edf
+shhs1-201579.edf
+shhs1-201580.edf
+shhs1-201581.edf
+shhs1-201582.edf
+shhs1-201583.edf
+shhs1-201584.edf
+shhs1-201585.edf
+shhs1-201586.edf
+shhs1-201587.edf
+shhs1-201588.edf
+shhs1-201589.edf
+shhs1-201590.edf
+shhs1-201591.edf
+shhs1-201592.edf
+shhs1-201593.edf
+shhs1-201594.edf
+shhs1-201595.edf
+shhs1-201596.edf
+shhs1-201597.edf
+shhs1-201598.edf
+shhs1-201599.edf
+shhs1-201600.edf
+shhs1-201601.edf
+shhs1-201602.edf
+shhs1-201603.edf
+shhs1-201604.edf
+shhs1-201605.edf
+shhs1-201606.edf
+shhs1-201607.edf
+shhs1-201608.edf
+shhs1-201609.edf
+shhs1-201610.edf
+shhs1-201611.edf
+shhs1-201612.edf
+shhs1-201613.edf
+shhs1-201614.edf
+shhs1-201615.edf
+shhs1-201616.edf
+shhs1-201617.edf
+shhs1-201618.edf
+shhs1-201619.edf
+shhs1-201620.edf
+shhs1-201621.edf
+shhs1-201622.edf
+shhs1-201623.edf
+shhs1-201624.edf
+shhs1-201625.edf
+shhs1-201626.edf
+shhs1-201627.edf
+shhs1-201628.edf
+shhs1-201629.edf
+shhs1-201630.edf
+shhs1-201631.edf
+shhs1-201632.edf
+shhs1-201633.edf
+shhs1-201634.edf
+shhs1-201635.edf
+shhs1-201636.edf
+shhs1-201637.edf
+shhs1-201638.edf
+shhs1-201639.edf
+shhs1-201640.edf
+shhs1-201641.edf
+shhs1-201642.edf
+shhs1-201643.edf
+shhs1-201644.edf
+shhs1-201645.edf
+shhs1-201646.edf
+shhs1-201647.edf
+shhs1-201648.edf
+shhs1-201649.edf
+shhs1-201650.edf
+shhs1-201651.edf
+shhs1-201652.edf
+shhs1-201653.edf
+shhs1-201654.edf
+shhs1-201655.edf
+shhs1-201656.edf
+shhs1-201657.edf
+shhs1-201658.edf
+shhs1-201659.edf
+shhs1-201660.edf
+shhs1-201661.edf
+shhs1-201662.edf
+shhs1-201663.edf
+shhs1-201664.edf
+shhs1-201665.edf
+shhs1-201666.edf
+shhs1-201667.edf
+shhs1-201668.edf
+shhs1-201670.edf
+shhs1-201671.edf
+shhs1-201672.edf
+shhs1-201673.edf
+shhs1-201674.edf
+shhs1-201675.edf
+shhs1-201676.edf
+shhs1-201677.edf
+shhs1-201678.edf
+shhs1-201679.edf
+shhs1-201680.edf
+shhs1-201681.edf
+shhs1-201682.edf
+shhs1-201683.edf
+shhs1-201684.edf
+shhs1-201685.edf
+shhs1-201686.edf
+shhs1-201687.edf
+shhs1-201688.edf
+shhs1-201689.edf
+shhs1-201690.edf
+shhs1-201691.edf
+shhs1-201692.edf
+shhs1-201693.edf
+shhs1-201694.edf
+shhs1-201695.edf
+shhs1-201696.edf
+shhs1-201697.edf
+shhs1-201698.edf
+shhs1-201699.edf
+shhs1-201700.edf
+shhs1-201701.edf
+shhs1-201702.edf
+shhs1-201703.edf
+shhs1-201704.edf
+shhs1-201705.edf
+shhs1-201706.edf
+shhs1-201707.edf
+shhs1-201708.edf
+shhs1-201709.edf
+shhs1-201710.edf
+shhs1-201711.edf
+shhs1-201712.edf
+shhs1-201713.edf
+shhs1-201714.edf
+shhs1-201715.edf
+shhs1-201716.edf
+shhs1-201717.edf
+shhs1-201718.edf
+shhs1-201719.edf
+shhs1-201720.edf
+shhs1-201721.edf
+shhs1-201722.edf
+shhs1-201723.edf
+shhs1-201724.edf
+shhs1-201725.edf
+shhs1-201726.edf
+shhs1-201727.edf
+shhs1-201728.edf
+shhs1-201729.edf
+shhs1-201730.edf
+shhs1-201731.edf
+shhs1-201732.edf
+shhs1-201733.edf
+shhs1-201734.edf
+shhs1-201735.edf
+shhs1-201736.edf
+shhs1-201737.edf
+shhs1-201738.edf
+shhs1-201739.edf
+shhs1-201740.edf
+shhs1-201741.edf
+shhs1-201742.edf
+shhs1-201743.edf
+shhs1-201744.edf
+shhs1-201745.edf
+shhs1-201746.edf
+shhs1-201747.edf
+shhs1-201748.edf
+shhs1-201749.edf
+shhs1-201750.edf
+shhs1-201751.edf
+shhs1-201752.edf
+shhs1-201753.edf
+shhs1-201754.edf
+shhs1-201755.edf
+shhs1-201756.edf
+shhs1-201757.edf
+shhs1-201758.edf
+shhs1-201759.edf
+shhs1-201760.edf
+shhs1-201761.edf
+shhs1-201762.edf
+shhs1-201763.edf
+shhs1-201764.edf
+shhs1-201765.edf
+shhs1-201766.edf
+shhs1-201767.edf
+shhs1-201768.edf
+shhs1-201769.edf
+shhs1-201770.edf
+shhs1-201771.edf
+shhs1-201772.edf
+shhs1-201773.edf
+shhs1-201774.edf
+shhs1-201775.edf
+shhs1-201776.edf
+shhs1-201777.edf
+shhs1-201778.edf
+shhs1-201779.edf
+shhs1-201780.edf
+shhs1-201781.edf
+shhs1-201782.edf
+shhs1-201783.edf
+shhs1-201784.edf
+shhs1-201785.edf
+shhs1-201786.edf
+shhs1-201787.edf
+shhs1-201788.edf
+shhs1-201789.edf
+shhs1-201790.edf
+shhs1-201791.edf
+shhs1-201792.edf
+shhs1-201793.edf
+shhs1-201794.edf
+shhs1-201795.edf
+shhs1-201796.edf
+shhs1-201797.edf
+shhs1-201798.edf
+shhs1-201799.edf
+shhs1-201800.edf
+shhs1-201801.edf
+shhs1-201802.edf
+shhs1-201803.edf
+shhs1-201804.edf
+shhs1-201805.edf
+shhs1-201806.edf
+shhs1-201807.edf
+shhs1-201808.edf
+shhs1-201809.edf
+shhs1-201810.edf
+shhs1-201811.edf
+shhs1-201812.edf
+shhs1-201813.edf
+shhs1-201814.edf
+shhs1-201815.edf
+shhs1-201816.edf
+shhs1-201817.edf
+shhs1-201818.edf
+shhs1-201819.edf
+shhs1-201820.edf
+shhs1-201822.edf
+shhs1-201823.edf
+shhs1-201824.edf
+shhs1-201825.edf
+shhs1-201826.edf
+shhs1-201827.edf
+shhs1-201828.edf
+shhs1-201829.edf
+shhs1-201830.edf
+shhs1-201831.edf
+shhs1-201832.edf
+shhs1-201833.edf
+shhs1-201834.edf
+shhs1-201835.edf
+shhs1-201836.edf
+shhs1-201837.edf
+shhs1-201838.edf
+shhs1-201839.edf
+shhs1-201840.edf
+shhs1-201841.edf
+shhs1-201842.edf
+shhs1-201843.edf
+shhs1-201844.edf
+shhs1-201845.edf
+shhs1-201846.edf
+shhs1-201847.edf
+shhs1-201848.edf
+shhs1-201849.edf
+shhs1-201850.edf
+shhs1-201851.edf
+shhs1-201852.edf
+shhs1-201853.edf
+shhs1-201854.edf
+shhs1-201855.edf
+shhs1-201856.edf
+shhs1-201857.edf
+shhs1-201858.edf
+shhs1-201859.edf
+shhs1-201860.edf
+shhs1-201861.edf
+shhs1-201862.edf
+shhs1-201863.edf
+shhs1-201864.edf
+shhs1-201865.edf
+shhs1-201866.edf
+shhs1-201867.edf
+shhs1-201868.edf
+shhs1-201869.edf
+shhs1-201870.edf
+shhs1-201871.edf
+shhs1-201872.edf
+shhs1-201873.edf
+shhs1-201874.edf
+shhs1-201875.edf
+shhs1-201876.edf
+shhs1-201877.edf
+shhs1-201878.edf
+shhs1-201879.edf
+shhs1-201880.edf
+shhs1-201881.edf
+shhs1-201882.edf
+shhs1-201883.edf
+shhs1-201884.edf
+shhs1-201885.edf
+shhs1-201886.edf
+shhs1-201887.edf
+shhs1-201888.edf
+shhs1-201889.edf
+shhs1-201890.edf
+shhs1-201891.edf
+shhs1-201892.edf
+shhs1-201893.edf
+shhs1-201894.edf
+shhs1-201895.edf
+shhs1-201896.edf
+shhs1-201897.edf
+shhs1-201898.edf
+shhs1-201899.edf
+shhs1-201900.edf
+shhs1-201901.edf
+shhs1-201902.edf
+shhs1-201903.edf
+shhs1-201904.edf
+shhs1-201905.edf
+shhs1-201906.edf
+shhs1-201907.edf
+shhs1-201908.edf
+shhs1-201909.edf
+shhs1-201910.edf
+shhs1-201911.edf
+shhs1-201912.edf
+shhs1-201913.edf
+shhs1-201914.edf
+shhs1-201915.edf
+shhs1-201916.edf
+shhs1-201917.edf
+shhs1-201918.edf
+shhs1-201919.edf
+shhs1-201920.edf
+shhs1-201921.edf
+shhs1-201922.edf
+shhs1-201923.edf
+shhs1-201924.edf
+shhs1-201925.edf
+shhs1-201926.edf
+shhs1-201927.edf
+shhs1-201928.edf
+shhs1-201929.edf
+shhs1-201930.edf
+shhs1-201931.edf
+shhs1-201932.edf
+shhs1-201933.edf
+shhs1-201934.edf
+shhs1-201935.edf
+shhs1-201936.edf
+shhs1-201937.edf
+shhs1-201938.edf
+shhs1-201939.edf
+shhs1-201940.edf
+shhs1-201941.edf
+shhs1-201942.edf
+shhs1-201943.edf
+shhs1-201944.edf
+shhs1-201945.edf
+shhs1-201946.edf
+shhs1-201947.edf
+shhs1-201948.edf
+shhs1-201949.edf
+shhs1-201950.edf
+shhs1-201951.edf
+shhs1-201952.edf
+shhs1-201953.edf
+shhs1-201954.edf
+shhs1-201955.edf
+shhs1-201956.edf
+shhs1-201957.edf
+shhs1-201958.edf
+shhs1-201959.edf
+shhs1-201960.edf
+shhs1-201961.edf
+shhs1-201962.edf
+shhs1-201963.edf
+shhs1-201964.edf
+shhs1-201965.edf
+shhs1-201966.edf
+shhs1-201967.edf
+shhs1-201968.edf
+shhs1-201969.edf
+shhs1-201970.edf
+shhs1-201971.edf
+shhs1-201972.edf
+shhs1-201973.edf
+shhs1-201974.edf
+shhs1-201975.edf
+shhs1-201976.edf
+shhs1-201977.edf
+shhs1-201978.edf
+shhs1-201979.edf
+shhs1-201980.edf
+shhs1-201981.edf
+shhs1-201982.edf
+shhs1-201983.edf
+shhs1-201984.edf
+shhs1-201985.edf
+shhs1-201986.edf
+shhs1-201987.edf
+shhs1-201988.edf
+shhs1-201989.edf
+shhs1-201990.edf
+shhs1-201991.edf
+shhs1-201992.edf
+shhs1-201993.edf
+shhs1-201994.edf
+shhs1-201995.edf
+shhs1-201996.edf
+shhs1-201997.edf
+shhs1-201998.edf
+shhs1-201999.edf
+shhs1-202000.edf
+shhs1-202001.edf
+shhs1-202002.edf
+shhs1-202003.edf
+shhs1-202004.edf
+shhs1-202005.edf
+shhs1-202006.edf
+shhs1-202007.edf
+shhs1-202008.edf
+shhs1-202009.edf
+shhs1-202010.edf
+shhs1-202011.edf
+shhs1-202012.edf
+shhs1-202013.edf
+shhs1-202014.edf
+shhs1-202015.edf
+shhs1-202016.edf
+shhs1-202017.edf
+shhs1-202018.edf
+shhs1-202019.edf
+shhs1-202020.edf
+shhs1-202021.edf
+shhs1-202022.edf
+shhs1-202023.edf
+shhs1-202024.edf
+shhs1-202025.edf
+shhs1-202026.edf
+shhs1-202027.edf
+shhs1-202028.edf
+shhs1-202029.edf
+shhs1-202030.edf
+shhs1-202031.edf
+shhs1-202032.edf
+shhs1-202033.edf
+shhs1-202034.edf
+shhs1-202035.edf
+shhs1-202036.edf
+shhs1-202037.edf
+shhs1-202038.edf
+shhs1-202039.edf
+shhs1-202040.edf
+shhs1-202041.edf
+shhs1-202042.edf
+shhs1-202043.edf
+shhs1-202044.edf
+shhs1-202045.edf
+shhs1-202046.edf
+shhs1-202047.edf
+shhs1-202048.edf
+shhs1-202049.edf
+shhs1-202050.edf
+shhs1-202051.edf
+shhs1-202052.edf
+shhs1-202053.edf
+shhs1-202054.edf
+shhs1-202055.edf
+shhs1-202056.edf
+shhs1-202057.edf
+shhs1-202058.edf
+shhs1-202059.edf
+shhs1-202060.edf
+shhs1-202061.edf
+shhs1-202062.edf
+shhs1-202063.edf
+shhs1-202064.edf
+shhs1-202065.edf
+shhs1-202066.edf
+shhs1-202067.edf
+shhs1-202068.edf
+shhs1-202069.edf
+shhs1-202070.edf
+shhs1-202071.edf
+shhs1-202072.edf
+shhs1-202073.edf
+shhs1-202074.edf
+shhs1-202075.edf
+shhs1-202076.edf
+shhs1-202077.edf
+shhs1-202078.edf
+shhs1-202079.edf
+shhs1-202080.edf
+shhs1-202081.edf
+shhs1-202082.edf
+shhs1-202083.edf
+shhs1-202084.edf
+shhs1-202085.edf
+shhs1-202086.edf
+shhs1-202087.edf
+shhs1-202088.edf
+shhs1-202089.edf
+shhs1-202090.edf
+shhs1-202091.edf
+shhs1-202092.edf
+shhs1-202093.edf
+shhs1-202094.edf
+shhs1-202095.edf
+shhs1-202096.edf
+shhs1-202097.edf
+shhs1-202098.edf
+shhs1-202099.edf
+shhs1-202100.edf
+shhs1-202101.edf
+shhs1-202102.edf
+shhs1-202103.edf
+shhs1-202104.edf
+shhs1-202105.edf
+shhs1-202106.edf
+shhs1-202107.edf
+shhs1-202108.edf
+shhs1-202109.edf
+shhs1-202110.edf
+shhs1-202111.edf
+shhs1-202112.edf
+shhs1-202113.edf
+shhs1-202114.edf
+shhs1-202115.edf
+shhs1-202116.edf
+shhs1-202117.edf
+shhs1-202118.edf
+shhs1-202119.edf
+shhs1-202120.edf
+shhs1-202121.edf
+shhs1-202122.edf
+shhs1-202123.edf
+shhs1-202124.edf
+shhs1-202125.edf
+shhs1-202126.edf
+shhs1-202127.edf
+shhs1-202128.edf
+shhs1-202129.edf
+shhs1-202130.edf
+shhs1-202131.edf
+shhs1-202132.edf
+shhs1-202133.edf
+shhs1-202134.edf
+shhs1-202135.edf
+shhs1-202136.edf
+shhs1-202137.edf
+shhs1-202138.edf
+shhs1-202139.edf
+shhs1-202140.edf
+shhs1-202141.edf
+shhs1-202142.edf
+shhs1-202143.edf
+shhs1-202144.edf
+shhs1-202145.edf
+shhs1-202146.edf
+shhs1-202147.edf
+shhs1-202148.edf
+shhs1-202149.edf
+shhs1-202150.edf
+shhs1-202151.edf
+shhs1-202152.edf
+shhs1-202153.edf
+shhs1-202154.edf
+shhs1-202155.edf
+shhs1-202156.edf
+shhs1-202157.edf
+shhs1-202158.edf
+shhs1-202159.edf
+shhs1-202160.edf
+shhs1-202161.edf
+shhs1-202162.edf
+shhs1-202163.edf
+shhs1-202164.edf
+shhs1-202165.edf
+shhs1-202166.edf
+shhs1-202167.edf
+shhs1-202168.edf
+shhs1-202169.edf
+shhs1-202170.edf
+shhs1-202171.edf
+shhs1-202172.edf
+shhs1-202173.edf
+shhs1-202174.edf
+shhs1-202175.edf
+shhs1-202176.edf
+shhs1-202177.edf
+shhs1-202178.edf
+shhs1-202179.edf
+shhs1-202180.edf
+shhs1-202181.edf
+shhs1-202182.edf
+shhs1-202183.edf
+shhs1-202184.edf
+shhs1-202185.edf
+shhs1-202186.edf
+shhs1-202187.edf
+shhs1-202188.edf
+shhs1-202189.edf
+shhs1-202190.edf
+shhs1-202191.edf
+shhs1-202192.edf
+shhs1-202193.edf
+shhs1-202194.edf
+shhs1-202195.edf
+shhs1-202196.edf
+shhs1-202197.edf
+shhs1-202198.edf
+shhs1-202199.edf
+shhs1-202200.edf
+shhs1-202201.edf
+shhs1-202202.edf
+shhs1-202203.edf
+shhs1-202204.edf
+shhs1-202205.edf
+shhs1-202206.edf
+shhs1-202207.edf
+shhs1-202208.edf
+shhs1-202209.edf
+shhs1-202210.edf
+shhs1-202211.edf
+shhs1-202212.edf
+shhs1-202213.edf
+shhs1-202214.edf
+shhs1-202215.edf
+shhs1-202216.edf
+shhs1-202217.edf
+shhs1-202218.edf
+shhs1-202219.edf
+shhs1-202220.edf
+shhs1-202221.edf
+shhs1-202222.edf
+shhs1-202223.edf
+shhs1-202224.edf
+shhs1-202225.edf
+shhs1-202226.edf
+shhs1-202227.edf
+shhs1-202228.edf
+shhs1-202229.edf
+shhs1-202230.edf
+shhs1-202231.edf
+shhs1-202232.edf
+shhs1-202233.edf
+shhs1-202234.edf
+shhs1-202235.edf
+shhs1-202236.edf
+shhs1-202237.edf
+shhs1-202238.edf
+shhs1-202239.edf
+shhs1-202240.edf
+shhs1-202241.edf
+shhs1-202242.edf
+shhs1-202243.edf
+shhs1-202244.edf
+shhs1-202245.edf
+shhs1-202246.edf
+shhs1-202247.edf
+shhs1-202249.edf
+shhs1-202250.edf
+shhs1-202251.edf
+shhs1-202252.edf
+shhs1-202253.edf
+shhs1-202254.edf
+shhs1-202255.edf
+shhs1-202256.edf
+shhs1-202257.edf
+shhs1-202258.edf
+shhs1-202259.edf
+shhs1-202260.edf
+shhs1-202261.edf
+shhs1-202262.edf
+shhs1-202263.edf
+shhs1-202264.edf
+shhs1-202265.edf
+shhs1-202266.edf
+shhs1-202267.edf
+shhs1-202268.edf
+shhs1-202269.edf
+shhs1-202270.edf
+shhs1-202271.edf
+shhs1-202272.edf
+shhs1-202273.edf
+shhs1-202274.edf
+shhs1-202275.edf
+shhs1-202276.edf
+shhs1-202277.edf
+shhs1-202278.edf
+shhs1-202279.edf
+shhs1-202280.edf
+shhs1-202281.edf
+shhs1-202282.edf
+shhs1-202283.edf
+shhs1-202284.edf
+shhs1-202285.edf
+shhs1-202286.edf
+shhs1-202287.edf
+shhs1-202288.edf
+shhs1-202289.edf
+shhs1-202290.edf
+shhs1-202291.edf
+shhs1-202292.edf
+shhs1-202293.edf
+shhs1-202294.edf
+shhs1-202295.edf
+shhs1-202296.edf
+shhs1-202297.edf
+shhs1-202298.edf
+shhs1-202299.edf
+shhs1-202300.edf
+shhs1-202301.edf
+shhs1-202302.edf
+shhs1-202303.edf
+shhs1-202304.edf
+shhs1-202305.edf
+shhs1-202306.edf
+shhs1-202307.edf
+shhs1-202309.edf
+shhs1-202310.edf
+shhs1-202311.edf
+shhs1-202312.edf
+shhs1-202313.edf
+shhs1-202314.edf
+shhs1-202315.edf
+shhs1-202316.edf
+shhs1-202318.edf
+shhs1-202319.edf
+shhs1-202320.edf
+shhs1-202321.edf
+shhs1-202322.edf
+shhs1-202323.edf
+shhs1-202324.edf
+shhs1-202325.edf
+shhs1-202326.edf
+shhs1-202327.edf
+shhs1-202328.edf
+shhs1-202329.edf
+shhs1-202330.edf
+shhs1-202331.edf
+shhs1-202332.edf
+shhs1-202333.edf
+shhs1-202334.edf
+shhs1-202335.edf
+shhs1-202336.edf
+shhs1-202337.edf
+shhs1-202338.edf
+shhs1-202339.edf
+shhs1-202340.edf
+shhs1-202341.edf
+shhs1-202342.edf
+shhs1-202343.edf
+shhs1-202344.edf
+shhs1-202345.edf
+shhs1-202346.edf
+shhs1-202347.edf
+shhs1-202348.edf
+shhs1-202349.edf
+shhs1-202350.edf
+shhs1-202351.edf
+shhs1-202352.edf
+shhs1-202353.edf
+shhs1-202354.edf
+shhs1-202355.edf
+shhs1-202356.edf
+shhs1-202357.edf
+shhs1-202358.edf
+shhs1-202359.edf
+shhs1-202360.edf
+shhs1-202361.edf
+shhs1-202362.edf
+shhs1-202363.edf
+shhs1-202364.edf
+shhs1-202365.edf
+shhs1-202366.edf
+shhs1-202367.edf
+shhs1-202368.edf
+shhs1-202369.edf
+shhs1-202370.edf
+shhs1-202371.edf
+shhs1-202372.edf
+shhs1-202373.edf
+shhs1-202374.edf
+shhs1-202375.edf
+shhs1-202376.edf
+shhs1-202377.edf
+shhs1-202378.edf
+shhs1-202379.edf
+shhs1-202380.edf
+shhs1-202381.edf
+shhs1-202382.edf
+shhs1-202383.edf
+shhs1-202384.edf
+shhs1-202385.edf
+shhs1-202386.edf
+shhs1-202387.edf
+shhs1-202388.edf
+shhs1-202389.edf
+shhs1-202390.edf
+shhs1-202391.edf
+shhs1-202392.edf
+shhs1-202393.edf
+shhs1-202394.edf
+shhs1-202395.edf
+shhs1-202396.edf
+shhs1-202397.edf
+shhs1-202398.edf
+shhs1-202399.edf
+shhs1-202400.edf
+shhs1-202401.edf
+shhs1-202402.edf
+shhs1-202403.edf
+shhs1-202404.edf
+shhs1-202405.edf
+shhs1-202406.edf
+shhs1-202407.edf
+shhs1-202408.edf
+shhs1-202409.edf
+shhs1-202410.edf
+shhs1-202411.edf
+shhs1-202412.edf
+shhs1-202413.edf
+shhs1-202414.edf
+shhs1-202415.edf
+shhs1-202416.edf
+shhs1-202417.edf
+shhs1-202418.edf
+shhs1-202419.edf
+shhs1-202420.edf
+shhs1-202421.edf
+shhs1-202422.edf
+shhs1-202423.edf
+shhs1-202424.edf
+shhs1-202425.edf
+shhs1-202426.edf
+shhs1-202427.edf
+shhs1-202428.edf
+shhs1-202429.edf
+shhs1-202430.edf
+shhs1-202431.edf
+shhs1-202432.edf
+shhs1-202433.edf
+shhs1-202434.edf
+shhs1-202435.edf
+shhs1-202436.edf
+shhs1-202437.edf
+shhs1-202438.edf
+shhs1-202439.edf
+shhs1-202440.edf
+shhs1-202441.edf
+shhs1-202442.edf
+shhs1-202443.edf
+shhs1-202444.edf
+shhs1-202445.edf
+shhs1-202446.edf
+shhs1-202447.edf
+shhs1-202448.edf
+shhs1-202449.edf
+shhs1-202450.edf
+shhs1-202451.edf
+shhs1-202452.edf
+shhs1-202453.edf
+shhs1-202454.edf
+shhs1-202455.edf
+shhs1-202456.edf
+shhs1-202457.edf
+shhs1-202458.edf
+shhs1-202459.edf
+shhs1-202460.edf
+shhs1-202461.edf
+shhs1-202462.edf
+shhs1-202463.edf
+shhs1-202464.edf
+shhs1-202465.edf
+shhs1-202466.edf
+shhs1-202467.edf
+shhs1-202468.edf
+shhs1-202469.edf
+shhs1-202470.edf
+shhs1-202471.edf
+shhs1-202472.edf
+shhs1-202473.edf
+shhs1-202474.edf
+shhs1-202475.edf
+shhs1-202476.edf
+shhs1-202477.edf
+shhs1-202478.edf
+shhs1-202479.edf
+shhs1-202480.edf
+shhs1-202481.edf
+shhs1-202482.edf
+shhs1-202483.edf
+shhs1-202484.edf
+shhs1-202485.edf
+shhs1-202486.edf
+shhs1-202487.edf
+shhs1-202488.edf
+shhs1-202489.edf
+shhs1-202490.edf
+shhs1-202491.edf
+shhs1-202492.edf
+shhs1-202493.edf
+shhs1-202494.edf
+shhs1-202495.edf
+shhs1-202496.edf
+shhs1-202497.edf
+shhs1-202498.edf
+shhs1-202499.edf
+shhs1-202500.edf
+shhs1-202501.edf
+shhs1-202502.edf
+shhs1-202503.edf
+shhs1-202504.edf
+shhs1-202505.edf
+shhs1-202506.edf
+shhs1-202507.edf
+shhs1-202508.edf
+shhs1-202509.edf
+shhs1-202510.edf
+shhs1-202511.edf
+shhs1-202512.edf
+shhs1-202513.edf
+shhs1-202514.edf
+shhs1-202515.edf
+shhs1-202516.edf
+shhs1-202517.edf
+shhs1-202518.edf
+shhs1-202519.edf
+shhs1-202520.edf
+shhs1-202521.edf
+shhs1-202522.edf
+shhs1-202523.edf
+shhs1-202524.edf
+shhs1-202525.edf
+shhs1-202526.edf
+shhs1-202527.edf
+shhs1-202528.edf
+shhs1-202529.edf
+shhs1-202530.edf
+shhs1-202531.edf
+shhs1-202532.edf
+shhs1-202533.edf
+shhs1-202534.edf
+shhs1-202535.edf
+shhs1-202536.edf
+shhs1-202537.edf
+shhs1-202538.edf
+shhs1-202539.edf
+shhs1-202540.edf
+shhs1-202541.edf
+shhs1-202542.edf
+shhs1-202543.edf
+shhs1-202544.edf
+shhs1-202545.edf
+shhs1-202546.edf
+shhs1-202547.edf
+shhs1-202548.edf
+shhs1-202549.edf
+shhs1-202550.edf
+shhs1-202551.edf
+shhs1-202552.edf
+shhs1-202553.edf
+shhs1-202554.edf
+shhs1-202555.edf
+shhs1-202556.edf
+shhs1-202557.edf
+shhs1-202558.edf
+shhs1-202559.edf
+shhs1-202560.edf
+shhs1-202561.edf
+shhs1-202562.edf
+shhs1-202563.edf
+shhs1-202564.edf
+shhs1-202565.edf
+shhs1-202566.edf
+shhs1-202567.edf
+shhs1-202568.edf
+shhs1-202569.edf
+shhs1-202570.edf
+shhs1-202571.edf
+shhs1-202572.edf
+shhs1-202573.edf
+shhs1-202574.edf
+shhs1-202575.edf
+shhs1-202576.edf
+shhs1-202577.edf
+shhs1-202578.edf
+shhs1-202579.edf
+shhs1-202580.edf
+shhs1-202581.edf
+shhs1-202582.edf
+shhs1-202583.edf
+shhs1-202584.edf
+shhs1-202585.edf
+shhs1-202586.edf
+shhs1-202587.edf
+shhs1-202588.edf
+shhs1-202589.edf
+shhs1-202590.edf
+shhs1-202591.edf
+shhs1-202592.edf
+shhs1-202593.edf
+shhs1-202594.edf
+shhs1-202595.edf
+shhs1-202596.edf
+shhs1-202597.edf
+shhs1-202598.edf
+shhs1-202599.edf
+shhs1-202600.edf
+shhs1-202601.edf
+shhs1-202602.edf
+shhs1-202603.edf
+shhs1-202604.edf
+shhs1-202605.edf
+shhs1-202606.edf
+shhs1-202607.edf
+shhs1-202608.edf
+shhs1-202609.edf
+shhs1-202610.edf
+shhs1-202611.edf
+shhs1-202612.edf
+shhs1-202613.edf
+shhs1-202614.edf
+shhs1-202615.edf
+shhs1-202616.edf
+shhs1-202617.edf
+shhs1-202618.edf
+shhs1-202619.edf
+shhs1-202620.edf
+shhs1-202621.edf
+shhs1-202622.edf
+shhs1-202623.edf
+shhs1-202624.edf
+shhs1-202625.edf
+shhs1-202626.edf
+shhs1-202627.edf
+shhs1-202628.edf
+shhs1-202629.edf
+shhs1-202630.edf
+shhs1-202631.edf
+shhs1-202632.edf
+shhs1-202633.edf
+shhs1-202634.edf
+shhs1-202635.edf
+shhs1-202636.edf
+shhs1-202637.edf
+shhs1-202638.edf
+shhs1-202639.edf
+shhs1-202640.edf
+shhs1-202641.edf
+shhs1-202642.edf
+shhs1-202643.edf
+shhs1-202644.edf
+shhs1-202645.edf
+shhs1-202646.edf
+shhs1-202647.edf
+shhs1-202648.edf
+shhs1-202649.edf
+shhs1-202650.edf
+shhs1-202651.edf
+shhs1-202652.edf
+shhs1-202653.edf
+shhs1-202654.edf
+shhs1-202655.edf
+shhs1-202656.edf
+shhs1-202657.edf
+shhs1-202658.edf
+shhs1-202659.edf
+shhs1-202660.edf
+shhs1-202661.edf
+shhs1-202662.edf
+shhs1-202663.edf
+shhs1-202664.edf
+shhs1-202665.edf
+shhs1-202666.edf
+shhs1-202667.edf
+shhs1-202668.edf
+shhs1-202669.edf
+shhs1-202670.edf
+shhs1-202671.edf
+shhs1-202672.edf
+shhs1-202673.edf
+shhs1-202674.edf
+shhs1-202675.edf
+shhs1-202676.edf
+shhs1-202677.edf
+shhs1-202678.edf
+shhs1-202679.edf
+shhs1-202680.edf
+shhs1-202681.edf
+shhs1-202682.edf
+shhs1-202683.edf
+shhs1-202684.edf
+shhs1-202685.edf
+shhs1-202686.edf
+shhs1-202687.edf
+shhs1-202688.edf
+shhs1-202689.edf
+shhs1-202690.edf
+shhs1-202691.edf
+shhs1-202692.edf
+shhs1-202693.edf
+shhs1-202694.edf
+shhs1-202695.edf
+shhs1-202696.edf
+shhs1-202697.edf
+shhs1-202698.edf
+shhs1-202699.edf
+shhs1-202700.edf
+shhs1-202701.edf
+shhs1-202702.edf
+shhs1-202703.edf
+shhs1-202704.edf
+shhs1-202705.edf
+shhs1-202706.edf
+shhs1-202707.edf
+shhs1-202708.edf
+shhs1-202709.edf
+shhs1-202710.edf
+shhs1-202711.edf
+shhs1-202712.edf
+shhs1-202713.edf
+shhs1-202714.edf
+shhs1-202715.edf
+shhs1-202716.edf
+shhs1-202717.edf
+shhs1-202718.edf
+shhs1-202719.edf
+shhs1-202720.edf
+shhs1-202721.edf
+shhs1-202722.edf
+shhs1-202723.edf
+shhs1-202724.edf
+shhs1-202725.edf
+shhs1-202726.edf
+shhs1-202727.edf
+shhs1-202728.edf
+shhs1-202729.edf
+shhs1-202730.edf
+shhs1-202731.edf
+shhs1-202732.edf
+shhs1-202733.edf
+shhs1-202734.edf
+shhs1-202735.edf
+shhs1-202736.edf
+shhs1-202737.edf
+shhs1-202738.edf
+shhs1-202739.edf
+shhs1-202740.edf
+shhs1-202741.edf
+shhs1-202742.edf
+shhs1-202743.edf
+shhs1-202744.edf
+shhs1-202745.edf
+shhs1-202746.edf
+shhs1-202747.edf
+shhs1-202748.edf
+shhs1-202749.edf
+shhs1-202750.edf
+shhs1-202751.edf
+shhs1-202752.edf
+shhs1-202753.edf
+shhs1-202754.edf
+shhs1-202755.edf
+shhs1-202756.edf
+shhs1-202757.edf
+shhs1-202758.edf
+shhs1-202759.edf
+shhs1-202760.edf
+shhs1-202761.edf
+shhs1-202762.edf
+shhs1-202763.edf
+shhs1-202764.edf
+shhs1-202765.edf
+shhs1-202766.edf
+shhs1-202767.edf
+shhs1-202768.edf
+shhs1-202769.edf
+shhs1-202770.edf
+shhs1-202771.edf
+shhs1-202772.edf
+shhs1-202773.edf
+shhs1-202774.edf
+shhs1-202775.edf
+shhs1-202776.edf
+shhs1-202777.edf
+shhs1-202778.edf
+shhs1-202779.edf
+shhs1-202780.edf
+shhs1-202781.edf
+shhs1-202782.edf
+shhs1-202783.edf
+shhs1-202784.edf
+shhs1-202785.edf
+shhs1-202786.edf
+shhs1-202787.edf
+shhs1-202788.edf
+shhs1-202789.edf
+shhs1-202790.edf
+shhs1-202791.edf
+shhs1-202792.edf
+shhs1-202793.edf
+shhs1-202794.edf
+shhs1-202795.edf
+shhs1-202796.edf
+shhs1-202797.edf
+shhs1-202798.edf
+shhs1-202799.edf
+shhs1-202800.edf
+shhs1-202801.edf
+shhs1-202802.edf
+shhs1-202803.edf
+shhs1-202804.edf
+shhs1-202805.edf
+shhs1-202806.edf
+shhs1-202807.edf
+shhs1-202808.edf
+shhs1-202809.edf
+shhs1-202810.edf
+shhs1-202811.edf
+shhs1-202812.edf
+shhs1-202813.edf
+shhs1-202814.edf
+shhs1-202815.edf
+shhs1-202816.edf
+shhs1-202817.edf
+shhs1-202818.edf
+shhs1-202819.edf
+shhs1-202820.edf
+shhs1-202821.edf
+shhs1-202822.edf
+shhs1-202823.edf
+shhs1-202824.edf
+shhs1-202825.edf
+shhs1-202826.edf
+shhs1-202827.edf
+shhs1-202828.edf
+shhs1-202829.edf
+shhs1-202830.edf
+shhs1-202831.edf
+shhs1-202832.edf
+shhs1-202833.edf
+shhs1-202834.edf
+shhs1-202835.edf
+shhs1-202836.edf
+shhs1-202837.edf
+shhs1-202838.edf
+shhs1-202839.edf
+shhs1-202840.edf
+shhs1-202841.edf
+shhs1-202842.edf
+shhs1-202843.edf
+shhs1-202844.edf
+shhs1-202845.edf
+shhs1-202846.edf
+shhs1-202847.edf
+shhs1-202848.edf
+shhs1-202849.edf
+shhs1-202850.edf
+shhs1-202851.edf
+shhs1-202852.edf
+shhs1-202853.edf
+shhs1-202854.edf
+shhs1-202855.edf
+shhs1-202856.edf
+shhs1-202857.edf
+shhs1-202858.edf
+shhs1-202859.edf
+shhs1-202860.edf
+shhs1-202861.edf
+shhs1-202862.edf
+shhs1-202863.edf
+shhs1-202864.edf
+shhs1-202865.edf
+shhs1-202866.edf
+shhs1-202867.edf
+shhs1-202868.edf
+shhs1-202869.edf
+shhs1-202870.edf
+shhs1-202871.edf
+shhs1-202872.edf
+shhs1-202873.edf
+shhs1-202874.edf
+shhs1-202875.edf
+shhs1-202876.edf
+shhs1-202877.edf
+shhs1-202878.edf
+shhs1-202879.edf
+shhs1-202880.edf
+shhs1-202881.edf
+shhs1-202882.edf
+shhs1-202883.edf
+shhs1-202884.edf
+shhs1-202885.edf
+shhs1-202886.edf
+shhs1-202887.edf
+shhs1-202888.edf
+shhs1-202889.edf
+shhs1-202890.edf
+shhs1-202891.edf
+shhs1-202892.edf
+shhs1-202893.edf
+shhs1-202894.edf
+shhs1-202895.edf
+shhs1-202896.edf
+shhs1-202897.edf
+shhs1-202898.edf
+shhs1-202899.edf
+shhs1-202900.edf
+shhs1-202901.edf
+shhs1-202902.edf
+shhs1-202903.edf
+shhs1-202904.edf
+shhs1-202905.edf
+shhs1-202906.edf
+shhs1-202907.edf
+shhs1-202908.edf
+shhs1-202909.edf
+shhs1-202910.edf
+shhs1-202911.edf
+shhs1-202912.edf
+shhs1-202913.edf
+shhs1-202914.edf
+shhs1-202915.edf
+shhs1-202916.edf
+shhs1-202917.edf
+shhs1-202918.edf
+shhs1-202919.edf
+shhs1-202920.edf
+shhs1-202921.edf
+shhs1-202922.edf
+shhs1-202923.edf
+shhs1-202924.edf
+shhs1-202925.edf
+shhs1-202926.edf
+shhs1-202927.edf
+shhs1-202928.edf
+shhs1-202929.edf
+shhs1-202930.edf
+shhs1-202931.edf
+shhs1-202932.edf
+shhs1-202933.edf
+shhs1-202934.edf
+shhs1-202935.edf
+shhs1-202936.edf
+shhs1-202937.edf
+shhs1-202938.edf
+shhs1-202939.edf
+shhs1-202940.edf
+shhs1-202941.edf
+shhs1-202942.edf
+shhs1-202943.edf
+shhs1-202944.edf
+shhs1-202945.edf
+shhs1-202946.edf
+shhs1-202947.edf
+shhs1-202948.edf
+shhs1-202949.edf
+shhs1-202950.edf
+shhs1-202951.edf
+shhs1-202952.edf
+shhs1-202953.edf
+shhs1-202954.edf
+shhs1-202955.edf
+shhs1-202956.edf
+shhs1-202957.edf
+shhs1-202958.edf
+shhs1-202959.edf
+shhs1-202960.edf
+shhs1-202961.edf
+shhs1-202962.edf
+shhs1-202963.edf
+shhs1-202964.edf
+shhs1-202965.edf
+shhs1-202966.edf
+shhs1-202967.edf
+shhs1-202968.edf
+shhs1-202969.edf
+shhs1-202970.edf
+shhs1-202971.edf
+shhs1-202972.edf
+shhs1-202973.edf
+shhs1-202974.edf
+shhs1-202975.edf
+shhs1-202976.edf
+shhs1-202977.edf
+shhs1-202978.edf
+shhs1-202979.edf
+shhs1-202980.edf
+shhs1-202981.edf
+shhs1-202982.edf
+shhs1-202983.edf
+shhs1-202984.edf
+shhs1-202985.edf
+shhs1-202986.edf
+shhs1-202987.edf
+shhs1-202988.edf
+shhs1-202989.edf
+shhs1-202990.edf
+shhs1-202991.edf
+shhs1-202992.edf
+shhs1-202993.edf
+shhs1-202994.edf
+shhs1-202995.edf
+shhs1-202996.edf
+shhs1-202997.edf
+shhs1-202998.edf
+shhs1-202999.edf
+shhs1-203000.edf
+shhs1-203001.edf
+shhs1-203002.edf
+shhs1-203003.edf
+shhs1-203004.edf
+shhs1-203005.edf
+shhs1-203006.edf
+shhs1-203007.edf
+shhs1-203008.edf
+shhs1-203009.edf
+shhs1-203010.edf
+shhs1-203011.edf
+shhs1-203012.edf
+shhs1-203013.edf
+shhs1-203014.edf
+shhs1-203015.edf
+shhs1-203016.edf
+shhs1-203017.edf
+shhs1-203018.edf
+shhs1-203019.edf
+shhs1-203020.edf
+shhs1-203021.edf
+shhs1-203022.edf
+shhs1-203023.edf
+shhs1-203024.edf
+shhs1-203025.edf
+shhs1-203026.edf
+shhs1-203027.edf
+shhs1-203028.edf
+shhs1-203029.edf
+shhs1-203030.edf
+shhs1-203031.edf
+shhs1-203032.edf
+shhs1-203033.edf
+shhs1-203034.edf
+shhs1-203035.edf
+shhs1-203036.edf
+shhs1-203037.edf
+shhs1-203038.edf
+shhs1-203039.edf
+shhs1-203040.edf
+shhs1-203041.edf
+shhs1-203042.edf
+shhs1-203043.edf
+shhs1-203044.edf
+shhs1-203045.edf
+shhs1-203046.edf
+shhs1-203047.edf
+shhs1-203048.edf
+shhs1-203049.edf
+shhs1-203050.edf
+shhs1-203051.edf
+shhs1-203052.edf
+shhs1-203053.edf
+shhs1-203054.edf
+shhs1-203055.edf
+shhs1-203056.edf
+shhs1-203057.edf
+shhs1-203058.edf
+shhs1-203059.edf
+shhs1-203060.edf
+shhs1-203061.edf
+shhs1-203062.edf
+shhs1-203063.edf
+shhs1-203064.edf
+shhs1-203065.edf
+shhs1-203066.edf
+shhs1-203067.edf
+shhs1-203068.edf
+shhs1-203069.edf
+shhs1-203070.edf
+shhs1-203071.edf
+shhs1-203072.edf
+shhs1-203073.edf
+shhs1-203074.edf
+shhs1-203075.edf
+shhs1-203076.edf
+shhs1-203077.edf
+shhs1-203078.edf
+shhs1-203079.edf
+shhs1-203080.edf
+shhs1-203081.edf
+shhs1-203082.edf
+shhs1-203083.edf
+shhs1-203084.edf
+shhs1-203085.edf
+shhs1-203086.edf
+shhs1-203087.edf
+shhs1-203088.edf
+shhs1-203089.edf
+shhs1-203090.edf
+shhs1-203091.edf
+shhs1-203092.edf
+shhs1-203093.edf
+shhs1-203094.edf
+shhs1-203095.edf
+shhs1-203096.edf
+shhs1-203097.edf
+shhs1-203098.edf
+shhs1-203099.edf
+shhs1-203100.edf
+shhs1-203101.edf
+shhs1-203102.edf
+shhs1-203103.edf
+shhs1-203104.edf
+shhs1-203105.edf
+shhs1-203106.edf
+shhs1-203107.edf
+shhs1-203108.edf
+shhs1-203109.edf
+shhs1-203110.edf
+shhs1-203111.edf
+shhs1-203112.edf
+shhs1-203113.edf
+shhs1-203114.edf
+shhs1-203115.edf
+shhs1-203116.edf
+shhs1-203117.edf
+shhs1-203118.edf
+shhs1-203119.edf
+shhs1-203120.edf
+shhs1-203121.edf
+shhs1-203122.edf
+shhs1-203123.edf
+shhs1-203124.edf
+shhs1-203125.edf
+shhs1-203126.edf
+shhs1-203127.edf
+shhs1-203128.edf
+shhs1-203129.edf
+shhs1-203130.edf
+shhs1-203131.edf
+shhs1-203132.edf
+shhs1-203133.edf
+shhs1-203134.edf
+shhs1-203135.edf
+shhs1-203136.edf
+shhs1-203137.edf
+shhs1-203138.edf
+shhs1-203139.edf
+shhs1-203140.edf
+shhs1-203141.edf
+shhs1-203142.edf
+shhs1-203143.edf
+shhs1-203144.edf
+shhs1-203145.edf
+shhs1-203146.edf
+shhs1-203147.edf
+shhs1-203148.edf
+shhs1-203149.edf
+shhs1-203150.edf
+shhs1-203151.edf
+shhs1-203152.edf
+shhs1-203153.edf
+shhs1-203154.edf
+shhs1-203155.edf
+shhs1-203156.edf
+shhs1-203157.edf
+shhs1-203158.edf
+shhs1-203159.edf
+shhs1-203160.edf
+shhs1-203161.edf
+shhs1-203162.edf
+shhs1-203163.edf
+shhs1-203164.edf
+shhs1-203165.edf
+shhs1-203166.edf
+shhs1-203167.edf
+shhs1-203168.edf
+shhs1-203170.edf
+shhs1-203171.edf
+shhs1-203172.edf
+shhs1-203173.edf
+shhs1-203174.edf
+shhs1-203175.edf
+shhs1-203176.edf
+shhs1-203177.edf
+shhs1-203178.edf
+shhs1-203179.edf
+shhs1-203180.edf
+shhs1-203181.edf
+shhs1-203182.edf
+shhs1-203183.edf
+shhs1-203184.edf
+shhs1-203185.edf
+shhs1-203186.edf
+shhs1-203187.edf
+shhs1-203188.edf
+shhs1-203189.edf
+shhs1-203190.edf
+shhs1-203191.edf
+shhs1-203192.edf
+shhs1-203193.edf
+shhs1-203194.edf
+shhs1-203195.edf
+shhs1-203196.edf
+shhs1-203197.edf
+shhs1-203198.edf
+shhs1-203199.edf
+shhs1-203200.edf
+shhs1-203201.edf
+shhs1-203202.edf
+shhs1-203203.edf
+shhs1-203204.edf
+shhs1-203205.edf
+shhs1-203206.edf
+shhs1-203207.edf
+shhs1-203208.edf
+shhs1-203209.edf
+shhs1-203210.edf
+shhs1-203211.edf
+shhs1-203212.edf
+shhs1-203213.edf
+shhs1-203214.edf
+shhs1-203215.edf
+shhs1-203216.edf
+shhs1-203217.edf
+shhs1-203218.edf
+shhs1-203219.edf
+shhs1-203220.edf
+shhs1-203221.edf
+shhs1-203222.edf
+shhs1-203223.edf
+shhs1-203224.edf
+shhs1-203225.edf
+shhs1-203226.edf
+shhs1-203227.edf
+shhs1-203228.edf
+shhs1-203229.edf
+shhs1-203230.edf
+shhs1-203231.edf
+shhs1-203232.edf
+shhs1-203233.edf
+shhs1-203234.edf
+shhs1-203235.edf
+shhs1-203236.edf
+shhs1-203237.edf
+shhs1-203238.edf
+shhs1-203239.edf
+shhs1-203240.edf
+shhs1-203241.edf
+shhs1-203242.edf
+shhs1-203243.edf
+shhs1-203244.edf
+shhs1-203245.edf
+shhs1-203246.edf
+shhs1-203247.edf
+shhs1-203248.edf
+shhs1-203249.edf
+shhs1-203250.edf
+shhs1-203251.edf
+shhs1-203252.edf
+shhs1-203253.edf
+shhs1-203254.edf
+shhs1-203255.edf
+shhs1-203256.edf
+shhs1-203257.edf
+shhs1-203258.edf
+shhs1-203259.edf
+shhs1-203260.edf
+shhs1-203261.edf
+shhs1-203262.edf
+shhs1-203263.edf
+shhs1-203264.edf
+shhs1-203265.edf
+shhs1-203266.edf
+shhs1-203267.edf
+shhs1-203268.edf
+shhs1-203269.edf
+shhs1-203270.edf
+shhs1-203271.edf
+shhs1-203272.edf
+shhs1-203273.edf
+shhs1-203274.edf
+shhs1-203275.edf
+shhs1-203276.edf
+shhs1-203277.edf
+shhs1-203278.edf
+shhs1-203279.edf
+shhs1-203280.edf
+shhs1-203281.edf
+shhs1-203282.edf
+shhs1-203283.edf
+shhs1-203284.edf
+shhs1-203285.edf
+shhs1-203286.edf
+shhs1-203287.edf
+shhs1-203288.edf
+shhs1-203289.edf
+shhs1-203290.edf
+shhs1-203291.edf
+shhs1-203292.edf
+shhs1-203293.edf
+shhs1-203294.edf
+shhs1-203295.edf
+shhs1-203296.edf
+shhs1-203297.edf
+shhs1-203298.edf
+shhs1-203299.edf
+shhs1-203300.edf
+shhs1-203301.edf
+shhs1-203302.edf
+shhs1-203303.edf
+shhs1-203304.edf
+shhs1-203305.edf
+shhs1-203306.edf
+shhs1-203307.edf
+shhs1-203308.edf
+shhs1-203309.edf
+shhs1-203310.edf
+shhs1-203311.edf
+shhs1-203312.edf
+shhs1-203313.edf
+shhs1-203314.edf
+shhs1-203315.edf
+shhs1-203316.edf
+shhs1-203317.edf
+shhs1-203318.edf
+shhs1-203319.edf
+shhs1-203320.edf
+shhs1-203321.edf
+shhs1-203322.edf
+shhs1-203323.edf
+shhs1-203324.edf
+shhs1-203325.edf
+shhs1-203326.edf
+shhs1-203327.edf
+shhs1-203328.edf
+shhs1-203329.edf
+shhs1-203330.edf
+shhs1-203331.edf
+shhs1-203332.edf
+shhs1-203333.edf
+shhs1-203334.edf
+shhs1-203335.edf
+shhs1-203336.edf
+shhs1-203337.edf
+shhs1-203338.edf
+shhs1-203339.edf
+shhs1-203340.edf
+shhs1-203341.edf
+shhs1-203342.edf
+shhs1-203343.edf
+shhs1-203344.edf
+shhs1-203345.edf
+shhs1-203346.edf
+shhs1-203347.edf
+shhs1-203348.edf
+shhs1-203349.edf
+shhs1-203350.edf
+shhs1-203351.edf
+shhs1-203352.edf
+shhs1-203353.edf
+shhs1-203354.edf
+shhs1-203355.edf
+shhs1-203356.edf
+shhs1-203357.edf
+shhs1-203358.edf
+shhs1-203359.edf
+shhs1-203360.edf
+shhs1-203361.edf
+shhs1-203362.edf
+shhs1-203363.edf
+shhs1-203364.edf
+shhs1-203365.edf
+shhs1-203366.edf
+shhs1-203367.edf
+shhs1-203368.edf
+shhs1-203369.edf
+shhs1-203370.edf
+shhs1-203371.edf
+shhs1-203372.edf
+shhs1-203373.edf
+shhs1-203374.edf
+shhs1-203375.edf
+shhs1-203376.edf
+shhs1-203377.edf
+shhs1-203378.edf
+shhs1-203379.edf
+shhs1-203380.edf
+shhs1-203381.edf
+shhs1-203382.edf
+shhs1-203383.edf
+shhs1-203384.edf
+shhs1-203385.edf
+shhs1-203386.edf
+shhs1-203387.edf
+shhs1-203388.edf
+shhs1-203389.edf
+shhs1-203390.edf
+shhs1-203391.edf
+shhs1-203392.edf
+shhs1-203393.edf
+shhs1-203394.edf
+shhs1-203395.edf
+shhs1-203396.edf
+shhs1-203397.edf
+shhs1-203398.edf
+shhs1-203399.edf
+shhs1-203400.edf
+shhs1-203401.edf
+shhs1-203402.edf
+shhs1-203403.edf
+shhs1-203404.edf
+shhs1-203405.edf
+shhs1-203406.edf
+shhs1-203407.edf
+shhs1-203408.edf
+shhs1-203409.edf
+shhs1-203410.edf
+shhs1-203411.edf
+shhs1-203412.edf
+shhs1-203413.edf
+shhs1-203414.edf
+shhs1-203415.edf
+shhs1-203416.edf
+shhs1-203417.edf
+shhs1-203418.edf
+shhs1-203419.edf
+shhs1-203420.edf
+shhs1-203421.edf
+shhs1-203422.edf
+shhs1-203423.edf
+shhs1-203424.edf
+shhs1-203425.edf
+shhs1-203426.edf
+shhs1-203427.edf
+shhs1-203428.edf
+shhs1-203429.edf
+shhs1-203430.edf
+shhs1-203431.edf
+shhs1-203432.edf
+shhs1-203433.edf
+shhs1-203434.edf
+shhs1-203435.edf
+shhs1-203436.edf
+shhs1-203437.edf
+shhs1-203438.edf
+shhs1-203439.edf
+shhs1-203440.edf
+shhs1-203441.edf
+shhs1-203442.edf
+shhs1-203443.edf
+shhs1-203444.edf
+shhs1-203445.edf
+shhs1-203446.edf
+shhs1-203447.edf
+shhs1-203448.edf
+shhs1-203449.edf
+shhs1-203450.edf
+shhs1-203451.edf
+shhs1-203452.edf
+shhs1-203453.edf
+shhs1-203454.edf
+shhs1-203455.edf
+shhs1-203456.edf
+shhs1-203457.edf
+shhs1-203458.edf
+shhs1-203459.edf
+shhs1-203460.edf
+shhs1-203461.edf
+shhs1-203462.edf
+shhs1-203463.edf
+shhs1-203464.edf
+shhs1-203465.edf
+shhs1-203466.edf
+shhs1-203467.edf
+shhs1-203468.edf
+shhs1-203469.edf
+shhs1-203470.edf
+shhs1-203471.edf
+shhs1-203472.edf
+shhs1-203473.edf
+shhs1-203474.edf
+shhs1-203475.edf
+shhs1-203476.edf
+shhs1-203477.edf
+shhs1-203478.edf
+shhs1-203479.edf
+shhs1-203480.edf
+shhs1-203481.edf
+shhs1-203482.edf
+shhs1-203483.edf
+shhs1-203484.edf
+shhs1-203485.edf
+shhs1-203486.edf
+shhs1-203487.edf
+shhs1-203488.edf
+shhs1-203489.edf
+shhs1-203490.edf
+shhs1-203491.edf
+shhs1-203492.edf
+shhs1-203493.edf
+shhs1-203494.edf
+shhs1-203495.edf
+shhs1-203496.edf
+shhs1-203497.edf
+shhs1-203498.edf
+shhs1-203499.edf
+shhs1-203500.edf
+shhs1-203501.edf
+shhs1-203502.edf
+shhs1-203503.edf
+shhs1-203504.edf
+shhs1-203505.edf
+shhs1-203506.edf
+shhs1-203507.edf
+shhs1-203508.edf
+shhs1-203509.edf
+shhs1-203510.edf
+shhs1-203511.edf
+shhs1-203512.edf
+shhs1-203513.edf
+shhs1-203514.edf
+shhs1-203515.edf
+shhs1-203516.edf
+shhs1-203517.edf
+shhs1-203518.edf
+shhs1-203519.edf
+shhs1-203520.edf
+shhs1-203521.edf
+shhs1-203522.edf
+shhs1-203523.edf
+shhs1-203524.edf
+shhs1-203525.edf
+shhs1-203526.edf
+shhs1-203527.edf
+shhs1-203528.edf
+shhs1-203529.edf
+shhs1-203530.edf
+shhs1-203531.edf
+shhs1-203532.edf
+shhs1-203533.edf
+shhs1-203534.edf
+shhs1-203535.edf
+shhs1-203536.edf
+shhs1-203537.edf
+shhs1-203538.edf
+shhs1-203539.edf
+shhs1-203540.edf
+shhs1-203541.edf
+shhs1-203542.edf
+shhs1-203543.edf
+shhs1-203544.edf
+shhs1-203545.edf
+shhs1-203546.edf
+shhs1-203547.edf
+shhs1-203548.edf
+shhs1-203549.edf
+shhs1-203550.edf
+shhs1-203551.edf
+shhs1-203552.edf
+shhs1-203553.edf
+shhs1-203554.edf
+shhs1-203555.edf
+shhs1-203556.edf
+shhs1-203557.edf
+shhs1-203558.edf
+shhs1-203559.edf
+shhs1-203560.edf
+shhs1-203561.edf
+shhs1-203562.edf
+shhs1-203563.edf
+shhs1-203564.edf
+shhs1-203565.edf
+shhs1-203566.edf
+shhs1-203567.edf
+shhs1-203568.edf
+shhs1-203569.edf
+shhs1-203570.edf
+shhs1-203571.edf
+shhs1-203572.edf
+shhs1-203573.edf
+shhs1-203574.edf
+shhs1-203575.edf
+shhs1-203576.edf
+shhs1-203577.edf
+shhs1-203578.edf
+shhs1-203579.edf
+shhs1-203580.edf
+shhs1-203581.edf
+shhs1-203582.edf
+shhs1-203583.edf
+shhs1-203584.edf
+shhs1-203585.edf
+shhs1-203586.edf
+shhs1-203587.edf
+shhs1-203588.edf
+shhs1-203589.edf
+shhs1-203590.edf
+shhs1-203591.edf
+shhs1-203592.edf
+shhs1-203593.edf
+shhs1-203594.edf
+shhs1-203595.edf
+shhs1-203596.edf
+shhs1-203597.edf
+shhs1-203598.edf
+shhs1-203599.edf
+shhs1-203600.edf
+shhs1-203601.edf
+shhs1-203602.edf
+shhs1-203603.edf
+shhs1-203604.edf
+shhs1-203605.edf
+shhs1-203606.edf
+shhs1-203607.edf
+shhs1-203608.edf
+shhs1-203609.edf
+shhs1-203610.edf
+shhs1-203611.edf
+shhs1-203612.edf
+shhs1-203613.edf
+shhs1-203614.edf
+shhs1-203615.edf
+shhs1-203616.edf
+shhs1-203617.edf
+shhs1-203618.edf
+shhs1-203619.edf
+shhs1-203620.edf
+shhs1-203621.edf
+shhs1-203622.edf
+shhs1-203623.edf
+shhs1-203624.edf
+shhs1-203625.edf
+shhs1-203626.edf
+shhs1-203627.edf
+shhs1-203628.edf
+shhs1-203629.edf
+shhs1-203630.edf
+shhs1-203631.edf
+shhs1-203632.edf
+shhs1-203633.edf
+shhs1-203634.edf
+shhs1-203635.edf
+shhs1-203636.edf
+shhs1-203637.edf
+shhs1-203638.edf
+shhs1-203639.edf
+shhs1-203640.edf
+shhs1-203641.edf
+shhs1-203642.edf
+shhs1-203643.edf
+shhs1-203644.edf
+shhs1-203645.edf
+shhs1-203646.edf
+shhs1-203647.edf
+shhs1-203648.edf
+shhs1-203649.edf
+shhs1-203650.edf
+shhs1-203651.edf
+shhs1-203652.edf
+shhs1-203653.edf
+shhs1-203654.edf
+shhs1-203655.edf
+shhs1-203656.edf
+shhs1-203657.edf
+shhs1-203658.edf
+shhs1-203659.edf
+shhs1-203660.edf
+shhs1-203661.edf
+shhs1-203662.edf
+shhs1-203663.edf
+shhs1-203664.edf
+shhs1-203665.edf
+shhs1-203666.edf
+shhs1-203667.edf
+shhs1-203668.edf
+shhs1-203669.edf
+shhs1-203670.edf
+shhs1-203671.edf
+shhs1-203672.edf
+shhs1-203673.edf
+shhs1-203674.edf
+shhs1-203675.edf
+shhs1-203676.edf
+shhs1-203677.edf
+shhs1-203678.edf
+shhs1-203679.edf
+shhs1-203680.edf
+shhs1-203681.edf
+shhs1-203682.edf
+shhs1-203683.edf
+shhs1-203684.edf
+shhs1-203685.edf
+shhs1-203686.edf
+shhs1-203687.edf
+shhs1-203688.edf
+shhs1-203689.edf
+shhs1-203690.edf
+shhs1-203691.edf
+shhs1-203692.edf
+shhs1-203693.edf
+shhs1-203694.edf
+shhs1-203695.edf
+shhs1-203696.edf
+shhs1-203697.edf
+shhs1-203698.edf
+shhs1-203699.edf
+shhs1-203700.edf
+shhs1-203701.edf
+shhs1-203702.edf
+shhs1-203703.edf
+shhs1-203704.edf
+shhs1-203705.edf
+shhs1-203706.edf
+shhs1-203707.edf
+shhs1-203708.edf
+shhs1-203709.edf
+shhs1-203710.edf
+shhs1-203711.edf
+shhs1-203712.edf
+shhs1-203713.edf
+shhs1-203714.edf
+shhs1-203715.edf
+shhs1-203716.edf
+shhs1-203717.edf
+shhs1-203718.edf
+shhs1-203719.edf
+shhs1-203720.edf
+shhs1-203721.edf
+shhs1-203722.edf
+shhs1-203723.edf
+shhs1-203724.edf
+shhs1-203725.edf
+shhs1-203726.edf
+shhs1-203727.edf
+shhs1-203728.edf
+shhs1-203729.edf
+shhs1-203730.edf
+shhs1-203731.edf
+shhs1-203732.edf
+shhs1-203733.edf
+shhs1-203734.edf
+shhs1-203735.edf
+shhs1-203736.edf
+shhs1-203737.edf
+shhs1-203738.edf
+shhs1-203739.edf
+shhs1-203740.edf
+shhs1-203741.edf
+shhs1-203742.edf
+shhs1-203743.edf
+shhs1-203744.edf
+shhs1-203745.edf
+shhs1-203746.edf
+shhs1-203747.edf
+shhs1-203748.edf
+shhs1-203749.edf
+shhs1-203750.edf
+shhs1-203751.edf
+shhs1-203752.edf
+shhs1-203753.edf
+shhs1-203754.edf
+shhs1-203755.edf
+shhs1-203756.edf
+shhs1-203757.edf
+shhs1-203758.edf
+shhs1-203759.edf
+shhs1-203760.edf
+shhs1-203761.edf
+shhs1-203762.edf
+shhs1-203763.edf
+shhs1-203764.edf
+shhs1-203765.edf
+shhs1-203766.edf
+shhs1-203767.edf
+shhs1-203768.edf
+shhs1-203769.edf
+shhs1-203770.edf
+shhs1-203771.edf
+shhs1-203772.edf
+shhs1-203773.edf
+shhs1-203774.edf
+shhs1-203775.edf
+shhs1-203776.edf
+shhs1-203777.edf
+shhs1-203778.edf
+shhs1-203779.edf
+shhs1-203780.edf
+shhs1-203781.edf
+shhs1-203782.edf
+shhs1-203783.edf
+shhs1-203784.edf
+shhs1-203785.edf
+shhs1-203786.edf
+shhs1-203787.edf
+shhs1-203788.edf
+shhs1-203789.edf
+shhs1-203790.edf
+shhs1-203791.edf
+shhs1-203792.edf
+shhs1-203793.edf
+shhs1-203794.edf
+shhs1-203795.edf
+shhs1-203796.edf
+shhs1-203797.edf
+shhs1-203798.edf
+shhs1-203799.edf
+shhs1-203800.edf
+shhs1-203801.edf
+shhs1-203802.edf
+shhs1-203803.edf
+shhs1-203804.edf
+shhs1-203805.edf
+shhs1-203806.edf
+shhs1-203807.edf
+shhs1-203808.edf
+shhs1-203809.edf
+shhs1-203810.edf
+shhs1-203811.edf
+shhs1-203812.edf
+shhs1-203813.edf
+shhs1-203814.edf
+shhs1-203815.edf
+shhs1-203816.edf
+shhs1-203817.edf
+shhs1-203818.edf
+shhs1-203819.edf
+shhs1-203820.edf
+shhs1-203821.edf
+shhs1-203822.edf
+shhs1-203823.edf
+shhs1-203824.edf
+shhs1-203825.edf
+shhs1-203826.edf
+shhs1-203827.edf
+shhs1-203828.edf
+shhs1-203829.edf
+shhs1-203830.edf
+shhs1-203831.edf
+shhs1-203832.edf
+shhs1-203833.edf
+shhs1-203834.edf
+shhs1-203835.edf
+shhs1-203836.edf
+shhs1-203837.edf
+shhs1-203838.edf
+shhs1-203839.edf
+shhs1-203840.edf
+shhs1-203841.edf
+shhs1-203842.edf
+shhs1-203843.edf
+shhs1-203844.edf
+shhs1-203845.edf
+shhs1-203846.edf
+shhs1-203847.edf
+shhs1-203848.edf
+shhs1-203849.edf
+shhs1-203850.edf
+shhs1-203851.edf
+shhs1-203852.edf
+shhs1-203853.edf
+shhs1-203854.edf
+shhs1-203855.edf
+shhs1-203856.edf
+shhs1-203857.edf
+shhs1-203858.edf
+shhs1-203859.edf
+shhs1-203860.edf
+shhs1-203861.edf
+shhs1-203862.edf
+shhs1-203863.edf
+shhs1-203864.edf
+shhs1-203865.edf
+shhs1-203866.edf
+shhs1-203867.edf
+shhs1-203868.edf
+shhs1-203869.edf
+shhs1-203870.edf
+shhs1-203871.edf
+shhs1-203872.edf
+shhs1-203873.edf
+shhs1-203874.edf
+shhs1-203875.edf
+shhs1-203876.edf
+shhs1-203877.edf
+shhs1-203878.edf
+shhs1-203879.edf
+shhs1-203880.edf
+shhs1-203881.edf
+shhs1-203882.edf
+shhs1-203883.edf
+shhs1-203884.edf
+shhs1-203885.edf
+shhs1-203886.edf
+shhs1-203887.edf
+shhs1-203888.edf
+shhs1-203889.edf
+shhs1-203890.edf
+shhs1-203891.edf
+shhs1-203892.edf
+shhs1-203893.edf
+shhs1-203894.edf
+shhs1-203895.edf
+shhs1-203896.edf
+shhs1-203897.edf
+shhs1-203898.edf
+shhs1-203899.edf
+shhs1-203900.edf
+shhs1-203901.edf
+shhs1-203902.edf
+shhs1-203903.edf
+shhs1-203904.edf
+shhs1-203905.edf
+shhs1-203906.edf
+shhs1-203907.edf
+shhs1-203908.edf
+shhs1-203909.edf
+shhs1-203910.edf
+shhs1-203911.edf
+shhs1-203912.edf
+shhs1-203913.edf
+shhs1-203914.edf
+shhs1-203915.edf
+shhs1-203916.edf
+shhs1-203917.edf
+shhs1-203918.edf
+shhs1-203919.edf
+shhs1-203920.edf
+shhs1-203921.edf
+shhs1-203922.edf
+shhs1-203923.edf
+shhs1-203924.edf
+shhs1-203925.edf
+shhs1-203926.edf
+shhs1-203927.edf
+shhs1-203928.edf
+shhs1-203929.edf
+shhs1-203930.edf
+shhs1-203931.edf
+shhs1-203932.edf
+shhs1-203933.edf
+shhs1-203934.edf
+shhs1-203935.edf
+shhs1-203936.edf
+shhs1-203937.edf
+shhs1-203938.edf
+shhs1-203939.edf
+shhs1-203940.edf
+shhs1-203941.edf
+shhs1-203942.edf
+shhs1-203943.edf
+shhs1-203944.edf
+shhs1-203945.edf
+shhs1-203946.edf
+shhs1-203947.edf
+shhs1-203948.edf
+shhs1-203949.edf
+shhs1-203950.edf
+shhs1-203951.edf
+shhs1-203952.edf
+shhs1-203953.edf
+shhs1-203954.edf
+shhs1-203955.edf
+shhs1-203956.edf
+shhs1-203957.edf
+shhs1-203958.edf
+shhs1-203959.edf
+shhs1-203960.edf
+shhs1-203961.edf
+shhs1-203962.edf
+shhs1-203963.edf
+shhs1-203964.edf
+shhs1-203965.edf
+shhs1-203966.edf
+shhs1-203967.edf
+shhs1-203968.edf
+shhs1-203969.edf
+shhs1-203970.edf
+shhs1-203971.edf
+shhs1-203972.edf
+shhs1-203973.edf
+shhs1-203974.edf
+shhs1-203975.edf
+shhs1-203976.edf
+shhs1-203977.edf
+shhs1-203978.edf
+shhs1-203979.edf
+shhs1-203980.edf
+shhs1-203981.edf
+shhs1-203982.edf
+shhs1-203983.edf
+shhs1-203984.edf
+shhs1-203985.edf
+shhs1-203986.edf
+shhs1-203987.edf
+shhs1-203988.edf
+shhs1-203989.edf
+shhs1-203990.edf
+shhs1-203991.edf
+shhs1-203992.edf
+shhs1-203993.edf
+shhs1-203994.edf
+shhs1-203995.edf
+shhs1-203996.edf
+shhs1-203997.edf
+shhs1-203998.edf
+shhs1-203999.edf
+shhs1-204000.edf
+shhs1-204001.edf
+shhs1-204002.edf
+shhs1-204003.edf
+shhs1-204004.edf
+shhs1-204005.edf
+shhs1-204006.edf
+shhs1-204007.edf
+shhs1-204008.edf
+shhs1-204009.edf
+shhs1-204010.edf
+shhs1-204011.edf
+shhs1-204012.edf
+shhs1-204013.edf
+shhs1-204014.edf
+shhs1-204015.edf
+shhs1-204016.edf
+shhs1-204017.edf
+shhs1-204018.edf
+shhs1-204019.edf
+shhs1-204020.edf
+shhs1-204021.edf
+shhs1-204022.edf
+shhs1-204023.edf
+shhs1-204024.edf
+shhs1-204025.edf
+shhs1-204026.edf
+shhs1-204027.edf
+shhs1-204028.edf
+shhs1-204029.edf
+shhs1-204030.edf
+shhs1-204031.edf
+shhs1-204032.edf
+shhs1-204033.edf
+shhs1-204034.edf
+shhs1-204035.edf
+shhs1-204036.edf
+shhs1-204037.edf
+shhs1-204038.edf
+shhs1-204039.edf
+shhs1-204040.edf
+shhs1-204041.edf
+shhs1-204042.edf
+shhs1-204043.edf
+shhs1-204044.edf
+shhs1-204045.edf
+shhs1-204046.edf
+shhs1-204047.edf
+shhs1-204048.edf
+shhs1-204049.edf
+shhs1-204050.edf
+shhs1-204051.edf
+shhs1-204052.edf
+shhs1-204053.edf
+shhs1-204054.edf
+shhs1-204055.edf
+shhs1-204056.edf
+shhs1-204057.edf
+shhs1-204058.edf
+shhs1-204059.edf
+shhs1-204060.edf
+shhs1-204061.edf
+shhs1-204062.edf
+shhs1-204063.edf
+shhs1-204064.edf
+shhs1-204065.edf
+shhs1-204066.edf
+shhs1-204067.edf
+shhs1-204068.edf
+shhs1-204069.edf
+shhs1-204070.edf
+shhs1-204071.edf
+shhs1-204072.edf
+shhs1-204073.edf
+shhs1-204074.edf
+shhs1-204075.edf
+shhs1-204076.edf
+shhs1-204077.edf
+shhs1-204078.edf
+shhs1-204079.edf
+shhs1-204080.edf
+shhs1-204081.edf
+shhs1-204082.edf
+shhs1-204083.edf
+shhs1-204084.edf
+shhs1-204085.edf
+shhs1-204086.edf
+shhs1-204087.edf
+shhs1-204088.edf
+shhs1-204089.edf
+shhs1-204090.edf
+shhs1-204091.edf
+shhs1-204092.edf
+shhs1-204093.edf
+shhs1-204094.edf
+shhs1-204095.edf
+shhs1-204096.edf
+shhs1-204097.edf
+shhs1-204098.edf
+shhs1-204099.edf
+shhs1-204100.edf
+shhs1-204101.edf
+shhs1-204102.edf
+shhs1-204103.edf
+shhs1-204104.edf
+shhs1-204105.edf
+shhs1-204106.edf
+shhs1-204107.edf
+shhs1-204108.edf
+shhs1-204109.edf
+shhs1-204110.edf
+shhs1-204111.edf
+shhs1-204112.edf
+shhs1-204113.edf
+shhs1-204114.edf
+shhs1-204115.edf
+shhs1-204116.edf
+shhs1-204117.edf
+shhs1-204118.edf
+shhs1-204119.edf
+shhs1-204120.edf
+shhs1-204121.edf
+shhs1-204122.edf
+shhs1-204123.edf
+shhs1-204124.edf
+shhs1-204125.edf
+shhs1-204126.edf
+shhs1-204127.edf
+shhs1-204128.edf
+shhs1-204129.edf
+shhs1-204130.edf
+shhs1-204131.edf
+shhs1-204132.edf
+shhs1-204133.edf
+shhs1-204134.edf
+shhs1-204135.edf
+shhs1-204136.edf
+shhs1-204137.edf
+shhs1-204138.edf
+shhs1-204139.edf
+shhs1-204140.edf
+shhs1-204141.edf
+shhs1-204142.edf
+shhs1-204143.edf
+shhs1-204144.edf
+shhs1-204145.edf
+shhs1-204146.edf
+shhs1-204147.edf
+shhs1-204148.edf
+shhs1-204149.edf
+shhs1-204150.edf
+shhs1-204151.edf
+shhs1-204152.edf
+shhs1-204153.edf
+shhs1-204154.edf
+shhs1-204155.edf
+shhs1-204156.edf
+shhs1-204157.edf
+shhs1-204158.edf
+shhs1-204159.edf
+shhs1-204160.edf
+shhs1-204161.edf
+shhs1-204162.edf
+shhs1-204163.edf
+shhs1-204164.edf
+shhs1-204165.edf
+shhs1-204166.edf
+shhs1-204167.edf
+shhs1-204168.edf
+shhs1-204169.edf
+shhs1-204170.edf
+shhs1-204171.edf
+shhs1-204172.edf
+shhs1-204173.edf
+shhs1-204174.edf
+shhs1-204175.edf
+shhs1-204176.edf
+shhs1-204177.edf
+shhs1-204178.edf
+shhs1-204179.edf
+shhs1-204180.edf
+shhs1-204181.edf
+shhs1-204182.edf
+shhs1-204183.edf
+shhs1-204184.edf
+shhs1-204185.edf
+shhs1-204186.edf
+shhs1-204187.edf
+shhs1-204188.edf
+shhs1-204189.edf
+shhs1-204190.edf
+shhs1-204191.edf
+shhs1-204192.edf
+shhs1-204193.edf
+shhs1-204194.edf
+shhs1-204195.edf
+shhs1-204196.edf
+shhs1-204197.edf
+shhs1-204198.edf
+shhs1-204199.edf
+shhs1-204200.edf
+shhs1-204201.edf
+shhs1-204202.edf
+shhs1-204203.edf
+shhs1-204204.edf
+shhs1-204205.edf
+shhs1-204206.edf
+shhs1-204207.edf
+shhs1-204208.edf
+shhs1-204209.edf
+shhs1-204210.edf
+shhs1-204211.edf
+shhs1-204212.edf
+shhs1-204213.edf
+shhs1-204214.edf
+shhs1-204215.edf
+shhs1-204216.edf
+shhs1-204218.edf
+shhs1-204219.edf
+shhs1-204220.edf
+shhs1-204221.edf
+shhs1-204222.edf
+shhs1-204223.edf
+shhs1-204224.edf
+shhs1-204225.edf
+shhs1-204226.edf
+shhs1-204227.edf
+shhs1-204228.edf
+shhs1-204229.edf
+shhs1-204230.edf
+shhs1-204231.edf
+shhs1-204232.edf
+shhs1-204233.edf
+shhs1-204234.edf
+shhs1-204235.edf
+shhs1-204236.edf
+shhs1-204237.edf
+shhs1-204238.edf
+shhs1-204239.edf
+shhs1-204240.edf
+shhs1-204241.edf
+shhs1-204242.edf
+shhs1-204243.edf
+shhs1-204244.edf
+shhs1-204245.edf
+shhs1-204246.edf
+shhs1-204247.edf
+shhs1-204248.edf
+shhs1-204249.edf
+shhs1-204250.edf
+shhs1-204251.edf
+shhs1-204252.edf
+shhs1-204253.edf
+shhs1-204254.edf
+shhs1-204255.edf
+shhs1-204256.edf
+shhs1-204257.edf
+shhs1-204258.edf
+shhs1-204259.edf
+shhs1-204260.edf
+shhs1-204261.edf
+shhs1-204262.edf
+shhs1-204263.edf
+shhs1-204264.edf
+shhs1-204265.edf
+shhs1-204266.edf
+shhs1-204267.edf
+shhs1-204268.edf
+shhs1-204269.edf
+shhs1-204270.edf
+shhs1-204271.edf
+shhs1-204272.edf
+shhs1-204273.edf
+shhs1-204274.edf
+shhs1-204275.edf
+shhs1-204276.edf
+shhs1-204277.edf
+shhs1-204278.edf
+shhs1-204279.edf
+shhs1-204280.edf
+shhs1-204281.edf
+shhs1-204282.edf
+shhs1-204283.edf
+shhs1-204284.edf
+shhs1-204285.edf
+shhs1-204286.edf
+shhs1-204287.edf
+shhs1-204288.edf
+shhs1-204289.edf
+shhs1-204290.edf
+shhs1-204291.edf
+shhs1-204292.edf
+shhs1-204293.edf
+shhs1-204294.edf
+shhs1-204295.edf
+shhs1-204296.edf
+shhs1-204297.edf
+shhs1-204298.edf
+shhs1-204299.edf
+shhs1-204300.edf
+shhs1-204301.edf
+shhs1-204302.edf
+shhs1-204303.edf
+shhs1-204304.edf
+shhs1-204305.edf
+shhs1-204306.edf
+shhs1-204307.edf
+shhs1-204308.edf
+shhs1-204309.edf
+shhs1-204310.edf
+shhs1-204311.edf
+shhs1-204312.edf
+shhs1-204313.edf
+shhs1-204314.edf
+shhs1-204315.edf
+shhs1-204316.edf
+shhs1-204317.edf
+shhs1-204318.edf
+shhs1-204319.edf
+shhs1-204320.edf
+shhs1-204321.edf
+shhs1-204322.edf
+shhs1-204323.edf
+shhs1-204324.edf
+shhs1-204325.edf
+shhs1-204326.edf
+shhs1-204327.edf
+shhs1-204328.edf
+shhs1-204329.edf
+shhs1-204330.edf
+shhs1-204331.edf
+shhs1-204332.edf
+shhs1-204333.edf
+shhs1-204334.edf
+shhs1-204335.edf
+shhs1-204336.edf
+shhs1-204337.edf
+shhs1-204338.edf
+shhs1-204339.edf
+shhs1-204340.edf
+shhs1-204341.edf
+shhs1-204342.edf
+shhs1-204343.edf
+shhs1-204344.edf
+shhs1-204345.edf
+shhs1-204346.edf
+shhs1-204347.edf
+shhs1-204348.edf
+shhs1-204349.edf
+shhs1-204350.edf
+shhs1-204351.edf
+shhs1-204352.edf
+shhs1-204353.edf
+shhs1-204354.edf
+shhs1-204355.edf
+shhs1-204356.edf
+shhs1-204357.edf
+shhs1-204358.edf
+shhs1-204359.edf
+shhs1-204360.edf
+shhs1-204361.edf
+shhs1-204362.edf
+shhs1-204363.edf
+shhs1-204364.edf
+shhs1-204365.edf
+shhs1-204366.edf
+shhs1-204367.edf
+shhs1-204368.edf
+shhs1-204369.edf
+shhs1-204370.edf
+shhs1-204371.edf
+shhs1-204372.edf
+shhs1-204373.edf
+shhs1-204374.edf
+shhs1-204375.edf
+shhs1-204376.edf
+shhs1-204377.edf
+shhs1-204378.edf
+shhs1-204379.edf
+shhs1-204380.edf
+shhs1-204381.edf
+shhs1-204382.edf
+shhs1-204383.edf
+shhs1-204384.edf
+shhs1-204385.edf
+shhs1-204386.edf
+shhs1-204387.edf
+shhs1-204388.edf
+shhs1-204389.edf
+shhs1-204390.edf
+shhs1-204391.edf
+shhs1-204392.edf
+shhs1-204393.edf
+shhs1-204394.edf
+shhs1-204395.edf
+shhs1-204396.edf
+shhs1-204397.edf
+shhs1-204398.edf
+shhs1-204399.edf
+shhs1-204400.edf
+shhs1-204401.edf
+shhs1-204402.edf
+shhs1-204403.edf
+shhs1-204404.edf
+shhs1-204405.edf
+shhs1-204406.edf
+shhs1-204407.edf
+shhs1-204408.edf
+shhs1-204409.edf
+shhs1-204410.edf
+shhs1-204411.edf
+shhs1-204412.edf
+shhs1-204413.edf
+shhs1-204414.edf
+shhs1-204415.edf
+shhs1-204416.edf
+shhs1-204417.edf
+shhs1-204418.edf
+shhs1-204419.edf
+shhs1-204420.edf
+shhs1-204421.edf
+shhs1-204422.edf
+shhs1-204423.edf
+shhs1-204424.edf
+shhs1-204425.edf
+shhs1-204426.edf
+shhs1-204427.edf
+shhs1-204428.edf
+shhs1-204429.edf
+shhs1-204430.edf
+shhs1-204431.edf
+shhs1-204432.edf
+shhs1-204433.edf
+shhs1-204434.edf
+shhs1-204435.edf
+shhs1-204436.edf
+shhs1-204437.edf
+shhs1-204438.edf
+shhs1-204439.edf
+shhs1-204440.edf
+shhs1-204441.edf
+shhs1-204442.edf
+shhs1-204443.edf
+shhs1-204444.edf
+shhs1-204445.edf
+shhs1-204446.edf
+shhs1-204447.edf
+shhs1-204448.edf
+shhs1-204449.edf
+shhs1-204450.edf
+shhs1-204451.edf
+shhs1-204452.edf
+shhs1-204453.edf
+shhs1-204454.edf
+shhs1-204455.edf
+shhs1-204456.edf
+shhs1-204457.edf
+shhs1-204458.edf
+shhs1-204459.edf
+shhs1-204460.edf
+shhs1-204461.edf
+shhs1-204462.edf
+shhs1-204463.edf
+shhs1-204464.edf
+shhs1-204465.edf
+shhs1-204466.edf
+shhs1-204467.edf
+shhs1-204468.edf
+shhs1-204469.edf
+shhs1-204470.edf
+shhs1-204471.edf
+shhs1-204472.edf
+shhs1-204473.edf
+shhs1-204474.edf
+shhs1-204475.edf
+shhs1-204476.edf
+shhs1-204477.edf
+shhs1-204478.edf
+shhs1-204479.edf
+shhs1-204480.edf
+shhs1-204481.edf
+shhs1-204482.edf
+shhs1-204483.edf
+shhs1-204484.edf
+shhs1-204485.edf
+shhs1-204486.edf
+shhs1-204487.edf
+shhs1-204488.edf
+shhs1-204489.edf
+shhs1-204490.edf
+shhs1-204491.edf
+shhs1-204492.edf
+shhs1-204493.edf
+shhs1-204494.edf
+shhs1-204495.edf
+shhs1-204496.edf
+shhs1-204497.edf
+shhs1-204498.edf
+shhs1-204499.edf
+shhs1-204500.edf
+shhs1-204501.edf
+shhs1-204502.edf
+shhs1-204503.edf
+shhs1-204504.edf
+shhs1-204505.edf
+shhs1-204506.edf
+shhs1-204507.edf
+shhs1-204508.edf
+shhs1-204509.edf
+shhs1-204510.edf
+shhs1-204511.edf
+shhs1-204512.edf
+shhs1-204513.edf
+shhs1-204514.edf
+shhs1-204515.edf
+shhs1-204516.edf
+shhs1-204517.edf
+shhs1-204518.edf
+shhs1-204519.edf
+shhs1-204520.edf
+shhs1-204521.edf
+shhs1-204522.edf
+shhs1-204523.edf
+shhs1-204524.edf
+shhs1-204525.edf
+shhs1-204526.edf
+shhs1-204527.edf
+shhs1-204528.edf
+shhs1-204529.edf
+shhs1-204530.edf
+shhs1-204531.edf
+shhs1-204532.edf
+shhs1-204533.edf
+shhs1-204534.edf
+shhs1-204535.edf
+shhs1-204536.edf
+shhs1-204537.edf
+shhs1-204538.edf
+shhs1-204539.edf
+shhs1-204540.edf
+shhs1-204541.edf
+shhs1-204542.edf
+shhs1-204543.edf
+shhs1-204544.edf
+shhs1-204545.edf
+shhs1-204546.edf
+shhs1-204547.edf
+shhs1-204548.edf
+shhs1-204549.edf
+shhs1-204550.edf
+shhs1-204551.edf
+shhs1-204552.edf
+shhs1-204553.edf
+shhs1-204554.edf
+shhs1-204555.edf
+shhs1-204556.edf
+shhs1-204557.edf
+shhs1-204558.edf
+shhs1-204559.edf
+shhs1-204560.edf
+shhs1-204561.edf
+shhs1-204562.edf
+shhs1-204563.edf
+shhs1-204564.edf
+shhs1-204565.edf
+shhs1-204566.edf
+shhs1-204567.edf
+shhs1-204568.edf
+shhs1-204569.edf
+shhs1-204570.edf
+shhs1-204571.edf
+shhs1-204572.edf
+shhs1-204573.edf
+shhs1-204574.edf
+shhs1-204575.edf
+shhs1-204576.edf
+shhs1-204577.edf
+shhs1-204578.edf
+shhs1-204579.edf
+shhs1-204580.edf
+shhs1-204581.edf
+shhs1-204582.edf
+shhs1-204583.edf
+shhs1-204584.edf
+shhs1-204585.edf
+shhs1-204586.edf
+shhs1-204587.edf
+shhs1-204588.edf
+shhs1-204589.edf
+shhs1-204590.edf
+shhs1-204591.edf
+shhs1-204592.edf
+shhs1-204593.edf
+shhs1-204594.edf
+shhs1-204595.edf
+shhs1-204596.edf
+shhs1-204597.edf
+shhs1-204598.edf
+shhs1-204599.edf
+shhs1-204600.edf
+shhs1-204601.edf
+shhs1-204602.edf
+shhs1-204603.edf
+shhs1-204604.edf
+shhs1-204605.edf
+shhs1-204606.edf
+shhs1-204607.edf
+shhs1-204608.edf
+shhs1-204609.edf
+shhs1-204610.edf
+shhs1-204611.edf
+shhs1-204612.edf
+shhs1-204613.edf
+shhs1-204614.edf
+shhs1-204615.edf
+shhs1-204616.edf
+shhs1-204617.edf
+shhs1-204618.edf
+shhs1-204619.edf
+shhs1-204620.edf
+shhs1-204621.edf
+shhs1-204622.edf
+shhs1-204623.edf
+shhs1-204624.edf
+shhs1-204625.edf
+shhs1-204626.edf
+shhs1-204627.edf
+shhs1-204628.edf
+shhs1-204629.edf
+shhs1-204630.edf
+shhs1-204631.edf
+shhs1-204632.edf
+shhs1-204633.edf
+shhs1-204634.edf
+shhs1-204635.edf
+shhs1-204636.edf
+shhs1-204637.edf
+shhs1-204638.edf
+shhs1-204639.edf
+shhs1-204640.edf
+shhs1-204641.edf
+shhs1-204642.edf
+shhs1-204643.edf
+shhs1-204644.edf
+shhs1-204645.edf
+shhs1-204646.edf
+shhs1-204647.edf
+shhs1-204648.edf
+shhs1-204649.edf
+shhs1-204650.edf
+shhs1-204651.edf
+shhs1-204652.edf
+shhs1-204653.edf
+shhs1-204654.edf
+shhs1-204655.edf
+shhs1-204656.edf
+shhs1-204657.edf
+shhs1-204658.edf
+shhs1-204659.edf
+shhs1-204660.edf
+shhs1-204661.edf
+shhs1-204662.edf
+shhs1-204663.edf
+shhs1-204664.edf
+shhs1-204665.edf
+shhs1-204666.edf
+shhs1-204667.edf
+shhs1-204668.edf
+shhs1-204669.edf
+shhs1-204670.edf
+shhs1-204671.edf
+shhs1-204672.edf
+shhs1-204673.edf
+shhs1-204674.edf
+shhs1-204675.edf
+shhs1-204676.edf
+shhs1-204677.edf
+shhs1-204678.edf
+shhs1-204679.edf
+shhs1-204680.edf
+shhs1-204681.edf
+shhs1-204682.edf
+shhs1-204683.edf
+shhs1-204684.edf
+shhs1-204685.edf
+shhs1-204686.edf
+shhs1-204687.edf
+shhs1-204688.edf
+shhs1-204689.edf
+shhs1-204690.edf
+shhs1-204691.edf
+shhs1-204692.edf
+shhs1-204693.edf
+shhs1-204694.edf
+shhs1-204695.edf
+shhs1-204696.edf
+shhs1-204697.edf
+shhs1-204698.edf
+shhs1-204699.edf
+shhs1-204700.edf
+shhs1-204701.edf
+shhs1-204702.edf
+shhs1-204703.edf
+shhs1-204704.edf
+shhs1-204705.edf
+shhs1-204706.edf
+shhs1-204707.edf
+shhs1-204708.edf
+shhs1-204709.edf
+shhs1-204710.edf
+shhs1-204711.edf
+shhs1-204712.edf
+shhs1-204713.edf
+shhs1-204714.edf
+shhs1-204715.edf
+shhs1-204716.edf
+shhs1-204717.edf
+shhs1-204718.edf
+shhs1-204719.edf
+shhs1-204720.edf
+shhs1-204721.edf
+shhs1-204722.edf
+shhs1-204723.edf
+shhs1-204724.edf
+shhs1-204725.edf
+shhs1-204726.edf
+shhs1-204727.edf
+shhs1-204728.edf
+shhs1-204729.edf
+shhs1-204730.edf
+shhs1-204731.edf
+shhs1-204732.edf
+shhs1-204733.edf
+shhs1-204734.edf
+shhs1-204735.edf
+shhs1-204736.edf
+shhs1-204737.edf
+shhs1-204738.edf
+shhs1-204739.edf
+shhs1-204740.edf
+shhs1-204741.edf
+shhs1-204742.edf
+shhs1-204743.edf
+shhs1-204744.edf
+shhs1-204745.edf
+shhs1-204746.edf
+shhs1-204747.edf
+shhs1-204748.edf
+shhs1-204749.edf
+shhs1-204750.edf
+shhs1-204751.edf
+shhs1-204752.edf
+shhs1-204753.edf
+shhs1-204754.edf
+shhs1-204755.edf
+shhs1-204756.edf
+shhs1-204757.edf
+shhs1-204758.edf
+shhs1-204759.edf
+shhs1-204760.edf
+shhs1-204761.edf
+shhs1-204762.edf
+shhs1-204763.edf
+shhs1-204764.edf
+shhs1-204765.edf
+shhs1-204766.edf
+shhs1-204767.edf
+shhs1-204768.edf
+shhs1-204769.edf
+shhs1-204770.edf
+shhs1-204771.edf
+shhs1-204772.edf
+shhs1-204773.edf
+shhs1-204774.edf
+shhs1-204775.edf
+shhs1-204776.edf
+shhs1-204777.edf
+shhs1-204778.edf
+shhs1-204779.edf
+shhs1-204780.edf
+shhs1-204781.edf
+shhs1-204782.edf
+shhs1-204783.edf
+shhs1-204784.edf
+shhs1-204785.edf
+shhs1-204786.edf
+shhs1-204787.edf
+shhs1-204788.edf
+shhs1-204789.edf
+shhs1-204790.edf
+shhs1-204791.edf
+shhs1-204792.edf
+shhs1-204793.edf
+shhs1-204794.edf
+shhs1-204795.edf
+shhs1-204796.edf
+shhs1-204797.edf
+shhs1-204798.edf
+shhs1-204799.edf
+shhs1-204800.edf
+shhs1-204801.edf
+shhs1-204802.edf
+shhs1-204803.edf
+shhs1-204804.edf
+shhs1-204805.edf
+shhs1-204806.edf
+shhs1-204807.edf
+shhs1-204808.edf
+shhs1-204809.edf
+shhs1-204810.edf
+shhs1-204811.edf
+shhs1-204812.edf
+shhs1-204813.edf
+shhs1-204814.edf
+shhs1-204815.edf
+shhs1-204816.edf
+shhs1-204817.edf
+shhs1-204818.edf
+shhs1-204819.edf
+shhs1-204820.edf
+shhs1-204821.edf
+shhs1-204822.edf
+shhs1-204823.edf
+shhs1-204824.edf
+shhs1-204825.edf
+shhs1-204826.edf
+shhs1-204827.edf
+shhs1-204828.edf
+shhs1-204829.edf
+shhs1-204830.edf
+shhs1-204831.edf
+shhs1-204832.edf
+shhs1-204833.edf
+shhs1-204834.edf
+shhs1-204835.edf
+shhs1-204836.edf
+shhs1-204837.edf
+shhs1-204838.edf
+shhs1-204839.edf
+shhs1-204840.edf
+shhs1-204841.edf
+shhs1-204842.edf
+shhs1-204843.edf
+shhs1-204844.edf
+shhs1-204845.edf
+shhs1-204846.edf
+shhs1-204847.edf
+shhs1-204848.edf
+shhs1-204849.edf
+shhs1-204850.edf
+shhs1-204851.edf
+shhs1-204852.edf
+shhs1-204853.edf
+shhs1-204854.edf
+shhs1-204855.edf
+shhs1-204856.edf
+shhs1-204857.edf
+shhs1-204858.edf
+shhs1-204859.edf
+shhs1-204860.edf
+shhs1-204861.edf
+shhs1-204862.edf
+shhs1-204863.edf
+shhs1-204864.edf
+shhs1-204865.edf
+shhs1-204866.edf
+shhs1-204867.edf
+shhs1-204868.edf
+shhs1-204869.edf
+shhs1-204870.edf
+shhs1-204871.edf
+shhs1-204872.edf
+shhs1-204873.edf
+shhs1-204874.edf
+shhs1-204875.edf
+shhs1-204876.edf
+shhs1-204877.edf
+shhs1-204878.edf
+shhs1-204879.edf
+shhs1-204880.edf
+shhs1-204881.edf
+shhs1-204882.edf
+shhs1-204883.edf
+shhs1-204884.edf
+shhs1-204885.edf
+shhs1-204886.edf
+shhs1-204887.edf
+shhs1-204888.edf
+shhs1-204889.edf
+shhs1-204890.edf
+shhs1-204891.edf
+shhs1-204892.edf
+shhs1-204893.edf
+shhs1-204894.edf
+shhs1-204895.edf
+shhs1-204896.edf
+shhs1-204897.edf
+shhs1-204898.edf
+shhs1-204899.edf
+shhs1-204900.edf
+shhs1-204901.edf
+shhs1-204902.edf
+shhs1-204903.edf
+shhs1-204904.edf
+shhs1-204905.edf
+shhs1-204906.edf
+shhs1-204907.edf
+shhs1-204908.edf
+shhs1-204909.edf
+shhs1-204910.edf
+shhs1-204911.edf
+shhs1-204912.edf
+shhs1-204913.edf
+shhs1-204914.edf
+shhs1-204915.edf
+shhs1-204916.edf
+shhs1-204917.edf
+shhs1-204918.edf
+shhs1-204919.edf
+shhs1-204920.edf
+shhs1-204921.edf
+shhs1-204922.edf
+shhs1-204923.edf
+shhs1-204924.edf
+shhs1-204925.edf
+shhs1-204926.edf
+shhs1-204927.edf
+shhs1-204928.edf
+shhs1-204929.edf
+shhs1-204930.edf
+shhs1-204931.edf
+shhs1-204932.edf
+shhs1-204933.edf
+shhs1-204934.edf
+shhs1-204935.edf
+shhs1-204936.edf
+shhs1-204937.edf
+shhs1-204938.edf
+shhs1-204939.edf
+shhs1-204940.edf
+shhs1-204941.edf
+shhs1-204942.edf
+shhs1-204943.edf
+shhs1-204944.edf
+shhs1-204945.edf
+shhs1-204946.edf
+shhs1-204947.edf
+shhs1-204948.edf
+shhs1-204949.edf
+shhs1-204950.edf
+shhs1-204951.edf
+shhs1-204952.edf
+shhs1-204953.edf
+shhs1-204954.edf
+shhs1-204955.edf
+shhs1-204956.edf
+shhs1-204957.edf
+shhs1-204958.edf
+shhs1-204959.edf
+shhs1-204960.edf
+shhs1-204961.edf
+shhs1-204962.edf
+shhs1-204963.edf
+shhs1-204964.edf
+shhs1-204965.edf
+shhs1-204966.edf
+shhs1-204967.edf
+shhs1-204968.edf
+shhs1-204969.edf
+shhs1-204970.edf
+shhs1-204971.edf
+shhs1-204972.edf
+shhs1-204973.edf
+shhs1-204974.edf
+shhs1-204975.edf
+shhs1-204976.edf
+shhs1-204977.edf
+shhs1-204978.edf
+shhs1-204979.edf
+shhs1-204980.edf
+shhs1-204981.edf
+shhs1-204982.edf
+shhs1-204983.edf
+shhs1-204984.edf
+shhs1-204985.edf
+shhs1-204986.edf
+shhs1-204987.edf
+shhs1-204988.edf
+shhs1-204989.edf
+shhs1-204990.edf
+shhs1-204991.edf
+shhs1-204992.edf
+shhs1-204993.edf
+shhs1-204994.edf
+shhs1-204995.edf
+shhs1-204996.edf
+shhs1-204997.edf
+shhs1-204998.edf
+shhs1-204999.edf
+shhs1-205000.edf
+shhs1-205001.edf
+shhs1-205002.edf
+shhs1-205003.edf
+shhs1-205004.edf
+shhs1-205005.edf
+shhs1-205006.edf
+shhs1-205007.edf
+shhs1-205008.edf
+shhs1-205009.edf
+shhs1-205010.edf
+shhs1-205011.edf
+shhs1-205012.edf
+shhs1-205013.edf
+shhs1-205014.edf
+shhs1-205015.edf
+shhs1-205016.edf
+shhs1-205017.edf
+shhs1-205018.edf
+shhs1-205019.edf
+shhs1-205020.edf
+shhs1-205021.edf
+shhs1-205022.edf
+shhs1-205023.edf
+shhs1-205024.edf
+shhs1-205025.edf
+shhs1-205026.edf
+shhs1-205027.edf
+shhs1-205028.edf
+shhs1-205029.edf
+shhs1-205030.edf
+shhs1-205031.edf
+shhs1-205032.edf
+shhs1-205033.edf
+shhs1-205034.edf
+shhs1-205035.edf
+shhs1-205036.edf
+shhs1-205037.edf
+shhs1-205038.edf
+shhs1-205039.edf
+shhs1-205040.edf
+shhs1-205041.edf
+shhs1-205042.edf
+shhs1-205043.edf
+shhs1-205044.edf
+shhs1-205045.edf
+shhs1-205046.edf
+shhs1-205047.edf
+shhs1-205048.edf
+shhs1-205049.edf
+shhs1-205050.edf
+shhs1-205051.edf
+shhs1-205052.edf
+shhs1-205053.edf
+shhs1-205054.edf
+shhs1-205055.edf
+shhs1-205056.edf
+shhs1-205057.edf
+shhs1-205058.edf
+shhs1-205059.edf
+shhs1-205060.edf
+shhs1-205061.edf
+shhs1-205062.edf
+shhs1-205063.edf
+shhs1-205064.edf
+shhs1-205065.edf
+shhs1-205066.edf
+shhs1-205067.edf
+shhs1-205068.edf
+shhs1-205069.edf
+shhs1-205070.edf
+shhs1-205071.edf
+shhs1-205072.edf
+shhs1-205073.edf
+shhs1-205074.edf
+shhs1-205075.edf
+shhs1-205076.edf
+shhs1-205077.edf
+shhs1-205078.edf
+shhs1-205079.edf
+shhs1-205080.edf
+shhs1-205081.edf
+shhs1-205082.edf
+shhs1-205083.edf
+shhs1-205084.edf
+shhs1-205085.edf
+shhs1-205086.edf
+shhs1-205087.edf
+shhs1-205088.edf
+shhs1-205089.edf
+shhs1-205090.edf
+shhs1-205091.edf
+shhs1-205092.edf
+shhs1-205093.edf
+shhs1-205094.edf
+shhs1-205095.edf
+shhs1-205096.edf
+shhs1-205097.edf
+shhs1-205098.edf
+shhs1-205099.edf
+shhs1-205100.edf
+shhs1-205101.edf
+shhs1-205102.edf
+shhs1-205103.edf
+shhs1-205104.edf
+shhs1-205105.edf
+shhs1-205106.edf
+shhs1-205107.edf
+shhs1-205108.edf
+shhs1-205109.edf
+shhs1-205110.edf
+shhs1-205111.edf
+shhs1-205112.edf
+shhs1-205113.edf
+shhs1-205114.edf
+shhs1-205115.edf
+shhs1-205116.edf
+shhs1-205117.edf
+shhs1-205118.edf
+shhs1-205119.edf
+shhs1-205120.edf
+shhs1-205121.edf
+shhs1-205122.edf
+shhs1-205123.edf
+shhs1-205124.edf
+shhs1-205125.edf
+shhs1-205126.edf
+shhs1-205127.edf
+shhs1-205128.edf
+shhs1-205129.edf
+shhs1-205130.edf
+shhs1-205131.edf
+shhs1-205132.edf
+shhs1-205133.edf
+shhs1-205134.edf
+shhs1-205135.edf
+shhs1-205136.edf
+shhs1-205137.edf
+shhs1-205138.edf
+shhs1-205139.edf
+shhs1-205140.edf
+shhs1-205141.edf
+shhs1-205142.edf
+shhs1-205143.edf
+shhs1-205144.edf
+shhs1-205145.edf
+shhs1-205146.edf
+shhs1-205147.edf
+shhs1-205148.edf
+shhs1-205149.edf
+shhs1-205150.edf
+shhs1-205151.edf
+shhs1-205152.edf
+shhs1-205153.edf
+shhs1-205154.edf
+shhs1-205155.edf
+shhs1-205156.edf
+shhs1-205157.edf
+shhs1-205158.edf
+shhs1-205159.edf
+shhs1-205160.edf
+shhs1-205161.edf
+shhs1-205162.edf
+shhs1-205163.edf
+shhs1-205164.edf
+shhs1-205165.edf
+shhs1-205166.edf
+shhs1-205167.edf
+shhs1-205168.edf
+shhs1-205169.edf
+shhs1-205170.edf
+shhs1-205171.edf
+shhs1-205172.edf
+shhs1-205173.edf
+shhs1-205174.edf
+shhs1-205175.edf
+shhs1-205176.edf
+shhs1-205177.edf
+shhs1-205178.edf
+shhs1-205179.edf
+shhs1-205180.edf
+shhs1-205181.edf
+shhs1-205182.edf
+shhs1-205183.edf
+shhs1-205184.edf
+shhs1-205185.edf
+shhs1-205186.edf
+shhs1-205187.edf
+shhs1-205188.edf
+shhs1-205189.edf
+shhs1-205190.edf
+shhs1-205191.edf
+shhs1-205192.edf
+shhs1-205193.edf
+shhs1-205194.edf
+shhs1-205195.edf
+shhs1-205196.edf
+shhs1-205197.edf
+shhs1-205198.edf
+shhs1-205199.edf
+shhs1-205200.edf
+shhs1-205201.edf
+shhs1-205202.edf
+shhs1-205203.edf
+shhs1-205204.edf
+shhs1-205205.edf
+shhs1-205206.edf
+shhs1-205207.edf
+shhs1-205208.edf
+shhs1-205209.edf
+shhs1-205210.edf
+shhs1-205211.edf
+shhs1-205212.edf
+shhs1-205213.edf
+shhs1-205214.edf
+shhs1-205215.edf
+shhs1-205216.edf
+shhs1-205217.edf
+shhs1-205218.edf
+shhs1-205219.edf
+shhs1-205220.edf
+shhs1-205221.edf
+shhs1-205222.edf
+shhs1-205223.edf
+shhs1-205224.edf
+shhs1-205225.edf
+shhs1-205226.edf
+shhs1-205227.edf
+shhs1-205228.edf
+shhs1-205229.edf
+shhs1-205230.edf
+shhs1-205231.edf
+shhs1-205232.edf
+shhs1-205233.edf
+shhs1-205234.edf
+shhs1-205235.edf
+shhs1-205236.edf
+shhs1-205237.edf
+shhs1-205238.edf
+shhs1-205239.edf
+shhs1-205240.edf
+shhs1-205241.edf
+shhs1-205242.edf
+shhs1-205243.edf
+shhs1-205244.edf
+shhs1-205245.edf
+shhs1-205246.edf
+shhs1-205247.edf
+shhs1-205248.edf
+shhs1-205249.edf
+shhs1-205250.edf
+shhs1-205251.edf
+shhs1-205252.edf
+shhs1-205253.edf
+shhs1-205254.edf
+shhs1-205255.edf
+shhs1-205256.edf
+shhs1-205257.edf
+shhs1-205258.edf
+shhs1-205259.edf
+shhs1-205260.edf
+shhs1-205261.edf
+shhs1-205262.edf
+shhs1-205263.edf
+shhs1-205264.edf
+shhs1-205265.edf
+shhs1-205266.edf
+shhs1-205267.edf
+shhs1-205268.edf
+shhs1-205269.edf
+shhs1-205270.edf
+shhs1-205271.edf
+shhs1-205272.edf
+shhs1-205273.edf
+shhs1-205274.edf
+shhs1-205275.edf
+shhs1-205276.edf
+shhs1-205277.edf
+shhs1-205278.edf
+shhs1-205279.edf
+shhs1-205280.edf
+shhs1-205281.edf
+shhs1-205282.edf
+shhs1-205283.edf
+shhs1-205284.edf
+shhs1-205285.edf
+shhs1-205286.edf
+shhs1-205287.edf
+shhs1-205288.edf
+shhs1-205289.edf
+shhs1-205290.edf
+shhs1-205291.edf
+shhs1-205292.edf
+shhs1-205293.edf
+shhs1-205294.edf
+shhs1-205295.edf
+shhs1-205296.edf
+shhs1-205297.edf
+shhs1-205298.edf
+shhs1-205299.edf
+shhs1-205300.edf
+shhs1-205301.edf
+shhs1-205302.edf
+shhs1-205303.edf
+shhs1-205304.edf
+shhs1-205305.edf
+shhs1-205306.edf
+shhs1-205307.edf
+shhs1-205308.edf
+shhs1-205309.edf
+shhs1-205310.edf
+shhs1-205311.edf
+shhs1-205312.edf
+shhs1-205313.edf
+shhs1-205314.edf
+shhs1-205315.edf
+shhs1-205316.edf
+shhs1-205317.edf
+shhs1-205318.edf
+shhs1-205319.edf
+shhs1-205320.edf
+shhs1-205321.edf
+shhs1-205322.edf
+shhs1-205323.edf
+shhs1-205324.edf
+shhs1-205325.edf
+shhs1-205326.edf
+shhs1-205327.edf
+shhs1-205328.edf
+shhs1-205329.edf
+shhs1-205330.edf
+shhs1-205331.edf
+shhs1-205332.edf
+shhs1-205333.edf
+shhs1-205334.edf
+shhs1-205335.edf
+shhs1-205336.edf
+shhs1-205337.edf
+shhs1-205338.edf
+shhs1-205339.edf
+shhs1-205340.edf
+shhs1-205341.edf
+shhs1-205342.edf
+shhs1-205343.edf
+shhs1-205344.edf
+shhs1-205345.edf
+shhs1-205346.edf
+shhs1-205347.edf
+shhs1-205348.edf
+shhs1-205349.edf
+shhs1-205350.edf
+shhs1-205351.edf
+shhs1-205352.edf
+shhs1-205353.edf
+shhs1-205354.edf
+shhs1-205355.edf
+shhs1-205356.edf
+shhs1-205357.edf
+shhs1-205358.edf
+shhs1-205359.edf
+shhs1-205360.edf
+shhs1-205361.edf
+shhs1-205362.edf
+shhs1-205363.edf
+shhs1-205364.edf
+shhs1-205365.edf
+shhs1-205366.edf
+shhs1-205367.edf
+shhs1-205368.edf
+shhs1-205369.edf
+shhs1-205370.edf
+shhs1-205371.edf
+shhs1-205372.edf
+shhs1-205373.edf
+shhs1-205374.edf
+shhs1-205375.edf
+shhs1-205376.edf
+shhs1-205377.edf
+shhs1-205378.edf
+shhs1-205379.edf
+shhs1-205380.edf
+shhs1-205381.edf
+shhs1-205382.edf
+shhs1-205383.edf
+shhs1-205384.edf
+shhs1-205385.edf
+shhs1-205386.edf
+shhs1-205387.edf
+shhs1-205388.edf
+shhs1-205389.edf
+shhs1-205390.edf
+shhs1-205391.edf
+shhs1-205392.edf
+shhs1-205393.edf
+shhs1-205394.edf
+shhs1-205395.edf
+shhs1-205396.edf
+shhs1-205397.edf
+shhs1-205398.edf
+shhs1-205399.edf
+shhs1-205400.edf
+shhs1-205401.edf
+shhs1-205402.edf
+shhs1-205403.edf
+shhs1-205404.edf
+shhs1-205405.edf
+shhs1-205406.edf
+shhs1-205407.edf
+shhs1-205408.edf
+shhs1-205409.edf
+shhs1-205410.edf
+shhs1-205411.edf
+shhs1-205412.edf
+shhs1-205413.edf
+shhs1-205414.edf
+shhs1-205415.edf
+shhs1-205416.edf
+shhs1-205417.edf
+shhs1-205418.edf
+shhs1-205419.edf
+shhs1-205420.edf
+shhs1-205421.edf
+shhs1-205422.edf
+shhs1-205423.edf
+shhs1-205424.edf
+shhs1-205425.edf
+shhs1-205426.edf
+shhs1-205427.edf
+shhs1-205428.edf
+shhs1-205429.edf
+shhs1-205430.edf
+shhs1-205431.edf
+shhs1-205432.edf
+shhs1-205433.edf
+shhs1-205434.edf
+shhs1-205435.edf
+shhs1-205436.edf
+shhs1-205437.edf
+shhs1-205438.edf
+shhs1-205439.edf
+shhs1-205440.edf
+shhs1-205441.edf
+shhs1-205442.edf
+shhs1-205443.edf
+shhs1-205444.edf
+shhs1-205445.edf
+shhs1-205446.edf
+shhs1-205447.edf
+shhs1-205448.edf
+shhs1-205449.edf
+shhs1-205450.edf
+shhs1-205451.edf
+shhs1-205452.edf
+shhs1-205453.edf
+shhs1-205454.edf
+shhs1-205455.edf
+shhs1-205456.edf
+shhs1-205457.edf
+shhs1-205458.edf
+shhs1-205459.edf
+shhs1-205460.edf
+shhs1-205461.edf
+shhs1-205462.edf
+shhs1-205463.edf
+shhs1-205464.edf
+shhs1-205465.edf
+shhs1-205466.edf
+shhs1-205467.edf
+shhs1-205468.edf
+shhs1-205469.edf
+shhs1-205470.edf
+shhs1-205471.edf
+shhs1-205472.edf
+shhs1-205473.edf
+shhs1-205474.edf
+shhs1-205475.edf
+shhs1-205476.edf
+shhs1-205477.edf
+shhs1-205478.edf
+shhs1-205479.edf
+shhs1-205480.edf
+shhs1-205481.edf
+shhs1-205482.edf
+shhs1-205483.edf
+shhs1-205484.edf
+shhs1-205485.edf
+shhs1-205486.edf
+shhs1-205487.edf
+shhs1-205488.edf
+shhs1-205489.edf
+shhs1-205490.edf
+shhs1-205491.edf
+shhs1-205492.edf
+shhs1-205493.edf
+shhs1-205494.edf
+shhs1-205495.edf
+shhs1-205496.edf
+shhs1-205497.edf
+shhs1-205498.edf
+shhs1-205499.edf
+shhs1-205500.edf
+shhs1-205501.edf
+shhs1-205502.edf
+shhs1-205503.edf
+shhs1-205504.edf
+shhs1-205505.edf
+shhs1-205506.edf
+shhs1-205507.edf
+shhs1-205508.edf
+shhs1-205509.edf
+shhs1-205510.edf
+shhs1-205511.edf
+shhs1-205512.edf
+shhs1-205513.edf
+shhs1-205514.edf
+shhs1-205515.edf
+shhs1-205516.edf
+shhs1-205517.edf
+shhs1-205518.edf
+shhs1-205519.edf
+shhs1-205520.edf
+shhs1-205521.edf
+shhs1-205522.edf
+shhs1-205523.edf
+shhs1-205524.edf
+shhs1-205525.edf
+shhs1-205526.edf
+shhs1-205527.edf
+shhs1-205528.edf
+shhs1-205529.edf
+shhs1-205530.edf
+shhs1-205531.edf
+shhs1-205532.edf
+shhs1-205533.edf
+shhs1-205534.edf
+shhs1-205535.edf
+shhs1-205536.edf
+shhs1-205537.edf
+shhs1-205538.edf
+shhs1-205539.edf
+shhs1-205540.edf
+shhs1-205541.edf
+shhs1-205542.edf
+shhs1-205543.edf
+shhs1-205544.edf
+shhs1-205545.edf
+shhs1-205546.edf
+shhs1-205547.edf
+shhs1-205548.edf
+shhs1-205549.edf
+shhs1-205550.edf
+shhs1-205551.edf
+shhs1-205552.edf
+shhs1-205553.edf
+shhs1-205554.edf
+shhs1-205555.edf
+shhs1-205556.edf
+shhs1-205557.edf
+shhs1-205558.edf
+shhs1-205559.edf
+shhs1-205560.edf
+shhs1-205561.edf
+shhs1-205562.edf
+shhs1-205563.edf
+shhs1-205564.edf
+shhs1-205565.edf
+shhs1-205566.edf
+shhs1-205567.edf
+shhs1-205568.edf
+shhs1-205569.edf
+shhs1-205570.edf
+shhs1-205571.edf
+shhs1-205572.edf
+shhs1-205573.edf
+shhs1-205574.edf
+shhs1-205575.edf
+shhs1-205576.edf
+shhs1-205577.edf
+shhs1-205578.edf
+shhs1-205579.edf
+shhs1-205580.edf
+shhs1-205581.edf
+shhs1-205582.edf
+shhs1-205583.edf
+shhs1-205584.edf
+shhs1-205585.edf
+shhs1-205586.edf
+shhs1-205587.edf
+shhs1-205588.edf
+shhs1-205589.edf
+shhs1-205590.edf
+shhs1-205591.edf
+shhs1-205592.edf
+shhs1-205593.edf
+shhs1-205594.edf
+shhs1-205595.edf
+shhs1-205596.edf
+shhs1-205597.edf
+shhs1-205598.edf
+shhs1-205599.edf
+shhs1-205600.edf
+shhs1-205601.edf
+shhs1-205602.edf
+shhs1-205603.edf
+shhs1-205604.edf
+shhs1-205605.edf
+shhs1-205606.edf
+shhs1-205607.edf
+shhs1-205608.edf
+shhs1-205609.edf
+shhs1-205610.edf
+shhs1-205611.edf
+shhs1-205612.edf
+shhs1-205613.edf
+shhs1-205614.edf
+shhs1-205615.edf
+shhs1-205616.edf
+shhs1-205617.edf
+shhs1-205618.edf
+shhs1-205619.edf
+shhs1-205620.edf
+shhs1-205621.edf
+shhs1-205622.edf
+shhs1-205623.edf
+shhs1-205624.edf
+shhs1-205625.edf
+shhs1-205626.edf
+shhs1-205627.edf
+shhs1-205628.edf
+shhs1-205629.edf
+shhs1-205630.edf
+shhs1-205631.edf
+shhs1-205632.edf
+shhs1-205633.edf
+shhs1-205634.edf
+shhs1-205635.edf
+shhs1-205636.edf
+shhs1-205637.edf
+shhs1-205638.edf
+shhs1-205639.edf
+shhs1-205640.edf
+shhs1-205641.edf
+shhs1-205642.edf
+shhs1-205643.edf
+shhs1-205644.edf
+shhs1-205645.edf
+shhs1-205646.edf
+shhs1-205647.edf
+shhs1-205648.edf
+shhs1-205649.edf
+shhs1-205650.edf
+shhs1-205651.edf
+shhs1-205652.edf
+shhs1-205653.edf
+shhs1-205654.edf
+shhs1-205655.edf
+shhs1-205656.edf
+shhs1-205657.edf
+shhs1-205658.edf
+shhs1-205659.edf
+shhs1-205660.edf
+shhs1-205661.edf
+shhs1-205662.edf
+shhs1-205663.edf
+shhs1-205664.edf
+shhs1-205665.edf
+shhs1-205666.edf
+shhs1-205667.edf
+shhs1-205668.edf
+shhs1-205669.edf
+shhs1-205670.edf
+shhs1-205671.edf
+shhs1-205672.edf
+shhs1-205673.edf
+shhs1-205674.edf
+shhs1-205675.edf
+shhs1-205676.edf
+shhs1-205677.edf
+shhs1-205678.edf
+shhs1-205679.edf
+shhs1-205680.edf
+shhs1-205681.edf
+shhs1-205682.edf
+shhs1-205683.edf
+shhs1-205684.edf
+shhs1-205685.edf
+shhs1-205686.edf
+shhs1-205687.edf
+shhs1-205688.edf
+shhs1-205689.edf
+shhs1-205690.edf
+shhs1-205691.edf
+shhs1-205692.edf
+shhs1-205693.edf
+shhs1-205694.edf
+shhs1-205695.edf
+shhs1-205696.edf
+shhs1-205697.edf
+shhs1-205698.edf
+shhs1-205699.edf
+shhs1-205700.edf
+shhs1-205701.edf
+shhs1-205702.edf
+shhs1-205703.edf
+shhs1-205704.edf
+shhs1-205705.edf
+shhs1-205706.edf
+shhs1-205707.edf
+shhs1-205708.edf
+shhs1-205709.edf
+shhs1-205710.edf
+shhs1-205711.edf
+shhs1-205712.edf
+shhs1-205713.edf
+shhs1-205714.edf
+shhs1-205715.edf
+shhs1-205716.edf
+shhs1-205717.edf
+shhs1-205718.edf
+shhs1-205719.edf
+shhs1-205720.edf
+shhs1-205721.edf
+shhs1-205722.edf
+shhs1-205723.edf
+shhs1-205724.edf
+shhs1-205725.edf
+shhs1-205726.edf
+shhs1-205727.edf
+shhs1-205728.edf
+shhs1-205729.edf
+shhs1-205730.edf
+shhs1-205731.edf
+shhs1-205732.edf
+shhs1-205733.edf
+shhs1-205734.edf
+shhs1-205735.edf
+shhs1-205736.edf
+shhs1-205737.edf
+shhs1-205738.edf
+shhs1-205739.edf
+shhs1-205740.edf
+shhs1-205741.edf
+shhs1-205742.edf
+shhs1-205743.edf
+shhs1-205744.edf
+shhs1-205745.edf
+shhs1-205746.edf
+shhs1-205747.edf
+shhs1-205748.edf
+shhs1-205749.edf
+shhs1-205750.edf
+shhs1-205751.edf
+shhs1-205752.edf
+shhs1-205753.edf
+shhs1-205754.edf
+shhs1-205755.edf
+shhs1-205756.edf
+shhs1-205757.edf
+shhs1-205758.edf
+shhs1-205759.edf
+shhs1-205760.edf
+shhs1-205761.edf
+shhs1-205762.edf
+shhs1-205763.edf
+shhs1-205764.edf
+shhs1-205765.edf
+shhs1-205766.edf
+shhs1-205767.edf
+shhs1-205768.edf
+shhs1-205769.edf
+shhs1-205770.edf
+shhs1-205771.edf
+shhs1-205772.edf
+shhs1-205773.edf
+shhs1-205774.edf
+shhs1-205775.edf
+shhs1-205776.edf
+shhs1-205777.edf
+shhs1-205778.edf
+shhs1-205779.edf
+shhs1-205780.edf
+shhs1-205781.edf
+shhs1-205782.edf
+shhs1-205783.edf
+shhs1-205784.edf
+shhs1-205785.edf
+shhs1-205786.edf
+shhs1-205787.edf
+shhs1-205788.edf
+shhs1-205789.edf
+shhs1-205790.edf
+shhs1-205791.edf
+shhs1-205792.edf
+shhs1-205793.edf
+shhs1-205794.edf
+shhs1-205795.edf
+shhs1-205796.edf
+shhs1-205797.edf
+shhs1-205798.edf
+shhs1-205799.edf
+shhs1-205800.edf
+shhs1-205801.edf
+shhs1-205802.edf
+shhs1-205803.edf
+shhs1-205804.edf
diff --git a/data/shhs_meta_data/test_list.txt b/data/shhs_meta_data/test_list.txt
new file mode 100644
index 0000000000000000000000000000000000000000..1c8d9be1e2294e2e582d621780b1e512ad3737fa
--- /dev/null
+++ b/data/shhs_meta_data/test_list.txt
@@ -0,0 +1,1639 @@
+../../mat/n0002_eeg.mat 689
+../../mat/n0006_eeg.mat 1084
+../../mat/n0007_eeg.mat 919
+../../mat/n0009_eeg.mat 1086
+../../mat/n0010_eeg.mat 1084
+../../mat/n0013_eeg.mat 916
+../../mat/n0022_eeg.mat 948
+../../mat/n0035_eeg.mat 989
+../../mat/n0037_eeg.mat 842
+../../mat/n0039_eeg.mat 959
+../../mat/n0043_eeg.mat 1084
+../../mat/n0050_eeg.mat 959
+../../mat/n0052_eeg.mat 1086
+../../mat/n0054_eeg.mat 862
+../../mat/n0060_eeg.mat 884
+../../mat/n0065_eeg.mat 805
+../../mat/n0067_eeg.mat 1086
+../../mat/n0071_eeg.mat 1084
+../../mat/n0076_eeg.mat 959
+../../mat/n0084_eeg.mat 899
+../../mat/n0086_eeg.mat 908
+../../mat/n0088_eeg.mat 1053
+../../mat/n0093_eeg.mat 1056
+../../mat/n0103_eeg.mat 959
+../../mat/n0108_eeg.mat 1019
+../../mat/n0114_eeg.mat 864
+../../mat/n0115_eeg.mat 751
+../../mat/n0117_eeg.mat 1059
+../../mat/n0118_eeg.mat 1067
+../../mat/n0121_eeg.mat 1019
+../../mat/n0123_eeg.mat 1069
+../../mat/n0127_eeg.mat 1053
+../../mat/n0128_eeg.mat 1069
+../../mat/n0130_eeg.mat 1053
+../../mat/n0131_eeg.mat 998
+../../mat/n0133_eeg.mat 1029
+../../mat/n0139_eeg.mat 925
+../../mat/n0147_eeg.mat 943
+../../mat/n0150_eeg.mat 976
+../../mat/n0152_eeg.mat 1019
+../../mat/n0155_eeg.mat 1069
+../../mat/n0159_eeg.mat 1067
+../../mat/n0162_eeg.mat 1019
+../../mat/n0163_eeg.mat 779
+../../mat/n0168_eeg.mat 1069
+../../mat/n0176_eeg.mat 929
+../../mat/n0178_eeg.mat 1069
+../../mat/n0183_eeg.mat 999
+../../mat/n0184_eeg.mat 938
+../../mat/n0189_eeg.mat 959
+../../mat/n0191_eeg.mat 1079
+../../mat/n0193_eeg.mat 1056
+../../mat/n0194_eeg.mat 888
+../../mat/n0200_eeg.mat 939
+../../mat/n0206_eeg.mat 839
+../../mat/n0211_eeg.mat 959
+../../mat/n0217_eeg.mat 894
+../../mat/n0218_eeg.mat 899
+../../mat/n0219_eeg.mat 899
+../../mat/n0220_eeg.mat 1069
+../../mat/n0221_eeg.mat 899
+../../mat/n0224_eeg.mat 908
+../../mat/n0227_eeg.mat 1073
+../../mat/n0229_eeg.mat 874
+../../mat/n0236_eeg.mat 1065
+../../mat/n0245_eeg.mat 1006
+../../mat/n0248_eeg.mat 985
+../../mat/n0250_eeg.mat 1086
+../../mat/n0257_eeg.mat 1081
+../../mat/n0261_eeg.mat 1086
+../../mat/n0262_eeg.mat 1086
+../../mat/n0266_eeg.mat 1079
+../../mat/n0267_eeg.mat 1084
+../../mat/n0274_eeg.mat 899
+../../mat/n0275_eeg.mat 1057
+../../mat/n0280_eeg.mat 959
+../../mat/n0288_eeg.mat 772
+../../mat/n0290_eeg.mat 1069
+../../mat/n0291_eeg.mat 839
+../../mat/n0299_eeg.mat 939
+../../mat/n0302_eeg.mat 719
+../../mat/n0306_eeg.mat 1067
+../../mat/n0307_eeg.mat 1019
+../../mat/n0311_eeg.mat 1069
+../../mat/n0314_eeg.mat 892
+../../mat/n0318_eeg.mat 1019
+../../mat/n0320_eeg.mat 1067
+../../mat/n0322_eeg.mat 968
+../../mat/n0323_eeg.mat 959
+../../mat/n0325_eeg.mat 1051
+../../mat/n0326_eeg.mat 880
+../../mat/n0329_eeg.mat 990
+../../mat/n0332_eeg.mat 1015
+../../mat/n0338_eeg.mat 989
+../../mat/n0348_eeg.mat 959
+../../mat/n0353_eeg.mat 1069
+../../mat/n0355_eeg.mat 962
+../../mat/n0356_eeg.mat 1051
+../../mat/n0357_eeg.mat 1069
+../../mat/n0361_eeg.mat 1019
+../../mat/n0362_eeg.mat 957
+../../mat/n0365_eeg.mat 1084
+../../mat/n0368_eeg.mat 1067
+../../mat/n0371_eeg.mat 1022
+../../mat/n0379_eeg.mat 887
+../../mat/n0382_eeg.mat 1049
+../../mat/n0387_eeg.mat 1084
+../../mat/n0388_eeg.mat 1069
+../../mat/n0390_eeg.mat 1069
+../../mat/n0391_eeg.mat 1019
+../../mat/n0392_eeg.mat 1019
+../../mat/n0393_eeg.mat 959
+../../mat/n0394_eeg.mat 1049
+../../mat/n0395_eeg.mat 1049
+../../mat/n0400_eeg.mat 1019
+../../mat/n0401_eeg.mat 1086
+../../mat/n0413_eeg.mat 1069
+../../mat/n0420_eeg.mat 1069
+../../mat/n0421_eeg.mat 719
+../../mat/n0422_eeg.mat 946
+../../mat/n0423_eeg.mat 901
+../../mat/n0438_eeg.mat 1051
+../../mat/n0442_eeg.mat 1067
+../../mat/n0443_eeg.mat 959
+../../mat/n0453_eeg.mat 1069
+../../mat/n0456_eeg.mat 929
+../../mat/n0457_eeg.mat 889
+../../mat/n0460_eeg.mat 1019
+../../mat/n0461_eeg.mat 839
+../../mat/n0462_eeg.mat 1051
+../../mat/n0466_eeg.mat 1033
+../../mat/n0469_eeg.mat 1084
+../../mat/n0474_eeg.mat 1019
+../../mat/n0481_eeg.mat 1053
+../../mat/n0482_eeg.mat 1069
+../../mat/n0483_eeg.mat 1019
+../../mat/n0488_eeg.mat 1019
+../../mat/n0492_eeg.mat 899
+../../mat/n0493_eeg.mat 1084
+../../mat/n0495_eeg.mat 1049
+../../mat/n0498_eeg.mat 929
+../../mat/n0501_eeg.mat 959
+../../mat/n0502_eeg.mat 1086
+../../mat/n0504_eeg.mat 1084
+../../mat/n0508_eeg.mat 928
+../../mat/n0509_eeg.mat 1011
+../../mat/n0510_eeg.mat 801
+../../mat/n0513_eeg.mat 1079
+../../mat/n0520_eeg.mat 1084
+../../mat/n0521_eeg.mat 959
+../../mat/n0524_eeg.mat 959
+../../mat/n0530_eeg.mat 1019
+../../mat/n0531_eeg.mat 770
+../../mat/n0533_eeg.mat 897
+../../mat/n0535_eeg.mat 973
+../../mat/n0536_eeg.mat 1069
+../../mat/n0541_eeg.mat 1069
+../../mat/n0543_eeg.mat 1022
+../../mat/n0545_eeg.mat 876
+../../mat/n0548_eeg.mat 1069
+../../mat/n0549_eeg.mat 1069
+../../mat/n0550_eeg.mat 899
+../../mat/n0554_eeg.mat 1069
+../../mat/n0561_eeg.mat 877
+../../mat/n0563_eeg.mat 1010
+../../mat/n0564_eeg.mat 927
+../../mat/n0565_eeg.mat 987
+../../mat/n0568_eeg.mat 912
+../../mat/n0569_eeg.mat 959
+../../mat/n0570_eeg.mat 960
+../../mat/n0574_eeg.mat 904
+../../mat/n0575_eeg.mat 905
+../../mat/n0585_eeg.mat 1067
+../../mat/n0587_eeg.mat 1053
+../../mat/n0591_eeg.mat 1069
+../../mat/n0592_eeg.mat 860
+../../mat/n0593_eeg.mat 899
+../../mat/n0595_eeg.mat 1053
+../../mat/n0597_eeg.mat 1049
+../../mat/n0601_eeg.mat 959
+../../mat/n0604_eeg.mat 1019
+../../mat/n0606_eeg.mat 945
+../../mat/n0608_eeg.mat 1049
+../../mat/n0611_eeg.mat 888
+../../mat/n0612_eeg.mat 729
+../../mat/n0619_eeg.mat 1019
+../../mat/n0624_eeg.mat 1049
+../../mat/n0627_eeg.mat 1069
+../../mat/n0628_eeg.mat 1069
+../../mat/n0629_eeg.mat 1019
+../../mat/n0631_eeg.mat 1069
+../../mat/n0634_eeg.mat 1022
+../../mat/n0639_eeg.mat 929
+../../mat/n0642_eeg.mat 1069
+../../mat/n0644_eeg.mat 1069
+../../mat/n0647_eeg.mat 1061
+../../mat/n0650_eeg.mat 1019
+../../mat/n0651_eeg.mat 1069
+../../mat/n0653_eeg.mat 959
+../../mat/n0654_eeg.mat 1069
+../../mat/n0655_eeg.mat 959
+../../mat/n0656_eeg.mat 839
+../../mat/n0658_eeg.mat 989
+../../mat/n0664_eeg.mat 839
+../../mat/n0674_eeg.mat 1069
+../../mat/n0679_eeg.mat 1053
+../../mat/n0680_eeg.mat 839
+../../mat/n0683_eeg.mat 1069
+../../mat/n0690_eeg.mat 824
+../../mat/n0696_eeg.mat 1069
+../../mat/n0697_eeg.mat 1039
+../../mat/n0700_eeg.mat 989
+../../mat/n0705_eeg.mat 859
+../../mat/n0707_eeg.mat 1069
+../../mat/n0714_eeg.mat 989
+../../mat/n0715_eeg.mat 936
+../../mat/n0717_eeg.mat 1019
+../../mat/n0720_eeg.mat 959
+../../mat/n0721_eeg.mat 1069
+../../mat/n0729_eeg.mat 959
+../../mat/n0736_eeg.mat 1069
+../../mat/n0737_eeg.mat 1067
+../../mat/n0742_eeg.mat 1069
+../../mat/n0744_eeg.mat 959
+../../mat/n0747_eeg.mat 1027
+../../mat/n0749_eeg.mat 1086
+../../mat/n0758_eeg.mat 959
+../../mat/n0759_eeg.mat 963
+../../mat/n0769_eeg.mat 1069
+../../mat/n0774_eeg.mat 934
+../../mat/n0777_eeg.mat 959
+../../mat/n0788_eeg.mat 929
+../../mat/n0791_eeg.mat 803
+../../mat/n0798_eeg.mat 813
+../../mat/n0809_eeg.mat 1019
+../../mat/n0814_eeg.mat 1053
+../../mat/n0815_eeg.mat 1019
+../../mat/n0826_eeg.mat 1051
+../../mat/n0830_eeg.mat 1069
+../../mat/n0831_eeg.mat 959
+../../mat/n0834_eeg.mat 899
+../../mat/n0837_eeg.mat 1019
+../../mat/n0838_eeg.mat 959
+../../mat/n0841_eeg.mat 1019
+../../mat/n0844_eeg.mat 1069
+../../mat/n0846_eeg.mat 1069
+../../mat/n0848_eeg.mat 959
+../../mat/n0851_eeg.mat 1069
+../../mat/n0853_eeg.mat 959
+../../mat/n0860_eeg.mat 1069
+../../mat/n0865_eeg.mat 870
+../../mat/n0866_eeg.mat 1053
+../../mat/n0867_eeg.mat 1051
+../../mat/n0869_eeg.mat 899
+../../mat/n0875_eeg.mat 1069
+../../mat/n0876_eeg.mat 1043
+../../mat/n0879_eeg.mat 929
+../../mat/n0880_eeg.mat 1053
+../../mat/n0889_eeg.mat 1086
+../../mat/n0893_eeg.mat 1069
+../../mat/n0897_eeg.mat 1019
+../../mat/n0905_eeg.mat 929
+../../mat/n0906_eeg.mat 1067
+../../mat/n0908_eeg.mat 1069
+../../mat/n0909_eeg.mat 1069
+../../mat/n0918_eeg.mat 1069
+../../mat/n0921_eeg.mat 1069
+../../mat/n0922_eeg.mat 959
+../../mat/n0926_eeg.mat 779
+../../mat/n0930_eeg.mat 1049
+../../mat/n0939_eeg.mat 929
+../../mat/n0947_eeg.mat 1069
+../../mat/n0952_eeg.mat 839
+../../mat/n0954_eeg.mat 955
+../../mat/n0955_eeg.mat 1069
+../../mat/n0962_eeg.mat 1067
+../../mat/n0964_eeg.mat 1019
+../../mat/n0966_eeg.mat 959
+../../mat/n0967_eeg.mat 1017
+../../mat/n0968_eeg.mat 1053
+../../mat/n0970_eeg.mat 1019
+../../mat/n0974_eeg.mat 953
+../../mat/n0976_eeg.mat 959
+../../mat/n0977_eeg.mat 959
+../../mat/n0978_eeg.mat 1069
+../../mat/n0981_eeg.mat 929
+../../mat/n0983_eeg.mat 940
+../../mat/n0989_eeg.mat 1069
+../../mat/n0990_eeg.mat 1069
+../../mat/n0992_eeg.mat 1069
+../../mat/n0993_eeg.mat 1067
+../../mat/n0994_eeg.mat 1069
+../../mat/n0997_eeg.mat 1069
+../../mat/n0998_eeg.mat 1084
+../../mat/n1000_eeg.mat 1069
+../../mat/n1005_eeg.mat 917
+../../mat/n1006_eeg.mat 1056
+../../mat/n1010_eeg.mat 1069
+../../mat/n1015_eeg.mat 897
+../../mat/n1021_eeg.mat 959
+../../mat/n1024_eeg.mat 839
+../../mat/n1026_eeg.mat 899
+../../mat/n1031_eeg.mat 1069
+../../mat/n1033_eeg.mat 839
+../../mat/n1039_eeg.mat 1069
+../../mat/n1043_eeg.mat 1069
+../../mat/n1047_eeg.mat 1067
+../../mat/n1048_eeg.mat 1009
+../../mat/n1053_eeg.mat 959
+../../mat/n1055_eeg.mat 787
+../../mat/n1057_eeg.mat 1051
+../../mat/n1058_eeg.mat 959
+../../mat/n1065_eeg.mat 1069
+../../mat/n1068_eeg.mat 946
+../../mat/n1077_eeg.mat 949
+../../mat/n1078_eeg.mat 920
+../../mat/n1080_eeg.mat 1039
+../../mat/n1088_eeg.mat 1079
+../../mat/n1089_eeg.mat 1086
+../../mat/n1091_eeg.mat 989
+../../mat/n1093_eeg.mat 826
+../../mat/n1097_eeg.mat 1084
+../../mat/n1102_eeg.mat 1086
+../../mat/n1104_eeg.mat 1086
+../../mat/n1106_eeg.mat 1084
+../../mat/n1109_eeg.mat 959
+../../mat/n1110_eeg.mat 875
+../../mat/n1116_eeg.mat 884
+../../mat/n1118_eeg.mat 1084
+../../mat/n1119_eeg.mat 1084
+../../mat/n1127_eeg.mat 1053
+../../mat/n1128_eeg.mat 972
+../../mat/n1132_eeg.mat 1019
+../../mat/n1137_eeg.mat 1049
+../../mat/n1140_eeg.mat 1053
+../../mat/n1141_eeg.mat 1053
+../../mat/n1144_eeg.mat 959
+../../mat/n1146_eeg.mat 1053
+../../mat/n1147_eeg.mat 719
+../../mat/n1148_eeg.mat 1019
+../../mat/n1149_eeg.mat 1017
+../../mat/n1160_eeg.mat 1053
+../../mat/n1161_eeg.mat 1053
+../../mat/n1162_eeg.mat 1053
+../../mat/n1164_eeg.mat 1019
+../../mat/n1166_eeg.mat 899
+../../mat/n1171_eeg.mat 989
+../../mat/n1172_eeg.mat 1023
+../../mat/n1174_eeg.mat 1053
+../../mat/n1177_eeg.mat 899
+../../mat/n1178_eeg.mat 1051
+../../mat/n1181_eeg.mat 929
+../../mat/n1183_eeg.mat 1053
+../../mat/n1190_eeg.mat 899
+../../mat/n1191_eeg.mat 1019
+../../mat/n1192_eeg.mat 1019
+../../mat/n1193_eeg.mat 1053
+../../mat/n1196_eeg.mat 1053
+../../mat/n1202_eeg.mat 1051
+../../mat/n1204_eeg.mat 1053
+../../mat/n1208_eeg.mat 841
+../../mat/n1209_eeg.mat 989
+../../mat/n1211_eeg.mat 1019
+../../mat/n1214_eeg.mat 1053
+../../mat/n1220_eeg.mat 1053
+../../mat/n1224_eeg.mat 1047
+../../mat/n1226_eeg.mat 957
+../../mat/n1227_eeg.mat 1051
+../../mat/n1229_eeg.mat 1051
+../../mat/n1231_eeg.mat 1053
+../../mat/n1232_eeg.mat 959
+../../mat/n1236_eeg.mat 929
+../../mat/n1237_eeg.mat 1051
+../../mat/n1245_eeg.mat 1049
+../../mat/n1249_eeg.mat 1053
+../../mat/n1258_eeg.mat 1053
+../../mat/n1259_eeg.mat 899
+../../mat/n1260_eeg.mat 1051
+../../mat/n1262_eeg.mat 1050
+../../mat/n1264_eeg.mat 1019
+../../mat/n1265_eeg.mat 880
+../../mat/n1270_eeg.mat 907
+../../mat/n1278_eeg.mat 1053
+../../mat/n1286_eeg.mat 1053
+../../mat/n1288_eeg.mat 952
+../../mat/n1290_eeg.mat 1052
+../../mat/n1291_eeg.mat 1053
+../../mat/n1294_eeg.mat 1019
+../../mat/n1296_eeg.mat 899
+../../mat/n1301_eeg.mat 959
+../../mat/n1304_eeg.mat 899
+../../mat/n1309_eeg.mat 1049
+../../mat/n1311_eeg.mat 956
+../../mat/n1319_eeg.mat 1051
+../../mat/n1326_eeg.mat 1051
+../../mat/n1327_eeg.mat 1044
+../../mat/n1328_eeg.mat 929
+../../mat/n1330_eeg.mat 1009
+../../mat/n1339_eeg.mat 1053
+../../mat/n1341_eeg.mat 1053
+../../mat/n1345_eeg.mat 959
+../../mat/n1348_eeg.mat 1051
+../../mat/n1350_eeg.mat 989
+../../mat/n1353_eeg.mat 1051
+../../mat/n1354_eeg.mat 1019
+../../mat/n1356_eeg.mat 1053
+../../mat/n1359_eeg.mat 1053
+../../mat/n1369_eeg.mat 1051
+../../mat/n1370_eeg.mat 1053
+../../mat/n1372_eeg.mat 1053
+../../mat/n1374_eeg.mat 1053
+../../mat/n1375_eeg.mat 951
+../../mat/n1376_eeg.mat 1079
+../../mat/n1381_eeg.mat 1049
+../../mat/n1391_eeg.mat 793
+../../mat/n1392_eeg.mat 1053
+../../mat/n1394_eeg.mat 1049
+../../mat/n1395_eeg.mat 1053
+../../mat/n1397_eeg.mat 1053
+../../mat/n1405_eeg.mat 1053
+../../mat/n1407_eeg.mat 1053
+../../mat/n1411_eeg.mat 1053
+../../mat/n1414_eeg.mat 1052
+../../mat/n1420_eeg.mat 1049
+../../mat/n1421_eeg.mat 1053
+../../mat/n1423_eeg.mat 813
+../../mat/n1434_eeg.mat 1053
+../../mat/n1435_eeg.mat 668
+../../mat/n1442_eeg.mat 1053
+../../mat/n1444_eeg.mat 869
+../../mat/n1445_eeg.mat 1051
+../../mat/n1457_eeg.mat 1070
+../../mat/n1462_eeg.mat 1084
+../../mat/n1464_eeg.mat 876
+../../mat/n1468_eeg.mat 1043
+../../mat/n1472_eeg.mat 881
+../../mat/n1479_eeg.mat 984
+../../mat/n1483_eeg.mat 1086
+../../mat/n1484_eeg.mat 943
+../../mat/n1487_eeg.mat 1081
+../../mat/n1503_eeg.mat 1019
+../../mat/n1509_eeg.mat 1052
+../../mat/n1510_eeg.mat 925
+../../mat/n1514_eeg.mat 1053
+../../mat/n1521_eeg.mat 1053
+../../mat/n1524_eeg.mat 700
+../../mat/n1528_eeg.mat 1019
+../../mat/n1529_eeg.mat 959
+../../mat/n1531_eeg.mat 1019
+../../mat/n1540_eeg.mat 938
+../../mat/n1541_eeg.mat 1049
+../../mat/n1542_eeg.mat 1049
+../../mat/n1545_eeg.mat 899
+../../mat/n1564_eeg.mat 1053
+../../mat/n1568_eeg.mat 1053
+../../mat/n1572_eeg.mat 1046
+../../mat/n1579_eeg.mat 899
+../../mat/n1580_eeg.mat 899
+../../mat/n1581_eeg.mat 1053
+../../mat/n1582_eeg.mat 979
+../../mat/n1583_eeg.mat 1053
+../../mat/n1586_eeg.mat 839
+../../mat/n1600_eeg.mat 1086
+../../mat/n1608_eeg.mat 1080
+../../mat/n1612_eeg.mat 929
+../../mat/n1613_eeg.mat 896
+../../mat/n1624_eeg.mat 959
+../../mat/n1628_eeg.mat 1019
+../../mat/n1630_eeg.mat 957
+../../mat/n1631_eeg.mat 1084
+../../mat/n1633_eeg.mat 985
+../../mat/n1638_eeg.mat 836
+../../mat/n1639_eeg.mat 959
+../../mat/n1642_eeg.mat 971
+../../mat/n1644_eeg.mat 1078
+../../mat/n1647_eeg.mat 700
+../../mat/n1648_eeg.mat 1078
+../../mat/n1650_eeg.mat 877
+../../mat/n1651_eeg.mat 1079
+../../mat/n1652_eeg.mat 881
+../../mat/n1657_eeg.mat 1079
+../../mat/n1661_eeg.mat 1049
+../../mat/n1663_eeg.mat 1019
+../../mat/n1664_eeg.mat 899
+../../mat/n1666_eeg.mat 1053
+../../mat/n1667_eeg.mat 1051
+../../mat/n1672_eeg.mat 1053
+../../mat/n1673_eeg.mat 1086
+../../mat/n1674_eeg.mat 686
+../../mat/n1680_eeg.mat 1086
+../../mat/n1682_eeg.mat 1019
+../../mat/n1683_eeg.mat 1084
+../../mat/n1687_eeg.mat 1009
+../../mat/n1697_eeg.mat 1035
+../../mat/n1698_eeg.mat 1052
+../../mat/n1701_eeg.mat 1054
+../../mat/n1702_eeg.mat 899
+../../mat/n1703_eeg.mat 1056
+../../mat/n1706_eeg.mat 1056
+../../mat/n1708_eeg.mat 1069
+../../mat/n1710_eeg.mat 1056
+../../mat/n1713_eeg.mat 899
+../../mat/n1715_eeg.mat 929
+../../mat/n1719_eeg.mat 778
+../../mat/n1721_eeg.mat 909
+../../mat/n1722_eeg.mat 839
+../../mat/n1726_eeg.mat 1047
+../../mat/n1728_eeg.mat 1051
+../../mat/n1732_eeg.mat 980
+../../mat/n1738_eeg.mat 1019
+../../mat/n1739_eeg.mat 1054
+../../mat/n1742_eeg.mat 1019
+../../mat/n1744_eeg.mat 974
+../../mat/n1745_eeg.mat 899
+../../mat/n1752_eeg.mat 894
+../../mat/n1754_eeg.mat 839
+../../mat/n1757_eeg.mat 1053
+../../mat/n1760_eeg.mat 959
+../../mat/n1773_eeg.mat 809
+../../mat/n1776_eeg.mat 702
+../../mat/n1777_eeg.mat 957
+../../mat/n1778_eeg.mat 1053
+../../mat/n1789_eeg.mat 868
+../../mat/n1791_eeg.mat 1019
+../../mat/n1793_eeg.mat 1056
+../../mat/n1794_eeg.mat 1051
+../../mat/n1798_eeg.mat 1053
+../../mat/n1803_eeg.mat 1084
+../../mat/n1805_eeg.mat 774
+../../mat/n1806_eeg.mat 929
+../../mat/n1807_eeg.mat 947
+../../mat/n1808_eeg.mat 959
+../../mat/n1810_eeg.mat 1069
+../../mat/n1814_eeg.mat 1056
+../../mat/n1823_eeg.mat 906
+../../mat/n1833_eeg.mat 959
+../../mat/n1840_eeg.mat 1054
+../../mat/n1841_eeg.mat 1056
+../../mat/n1846_eeg.mat 1056
+../../mat/n1849_eeg.mat 839
+../../mat/n1850_eeg.mat 929
+../../mat/n1856_eeg.mat 959
+../../mat/n1859_eeg.mat 1044
+../../mat/n1860_eeg.mat 929
+../../mat/n1861_eeg.mat 899
+../../mat/n1868_eeg.mat 839
+../../mat/n1870_eeg.mat 959
+../../mat/n1872_eeg.mat 1053
+../../mat/n1876_eeg.mat 839
+../../mat/n1890_eeg.mat 912
+../../mat/n1891_eeg.mat 929
+../../mat/n1893_eeg.mat 854
+../../mat/n1898_eeg.mat 1019
+../../mat/n1902_eeg.mat 959
+../../mat/n1903_eeg.mat 779
+../../mat/n1907_eeg.mat 1051
+../../mat/n1913_eeg.mat 1084
+../../mat/n1914_eeg.mat 899
+../../mat/n1916_eeg.mat 1084
+../../mat/n1925_eeg.mat 582
+../../mat/n1926_eeg.mat 856
+../../mat/n1927_eeg.mat 918
+../../mat/n1929_eeg.mat 618
+../../mat/n1931_eeg.mat 1029
+../../mat/n1935_eeg.mat 1084
+../../mat/n1938_eeg.mat 839
+../../mat/n1939_eeg.mat 995
+../../mat/n1941_eeg.mat 1059
+../../mat/n1942_eeg.mat 1019
+../../mat/n1943_eeg.mat 1019
+../../mat/n1944_eeg.mat 1086
+../../mat/n1945_eeg.mat 927
+../../mat/n1946_eeg.mat 1084
+../../mat/n1951_eeg.mat 1060
+../../mat/n1953_eeg.mat 1084
+../../mat/n1957_eeg.mat 1056
+../../mat/n1958_eeg.mat 1054
+../../mat/n1960_eeg.mat 1049
+../../mat/n1963_eeg.mat 1051
+../../mat/n1965_eeg.mat 1054
+../../mat/n1972_eeg.mat 1041
+../../mat/n1978_eeg.mat 1084
+../../mat/n1980_eeg.mat 1067
+../../mat/n1985_eeg.mat 948
+../../mat/n1988_eeg.mat 1053
+../../mat/n1989_eeg.mat 1053
+../../mat/n1991_eeg.mat 1051
+../../mat/n2000_eeg.mat 959
+../../mat/n2004_eeg.mat 955
+../../mat/n2009_eeg.mat 958
+../../mat/n2010_eeg.mat 1053
+../../mat/n2016_eeg.mat 895
+../../mat/n2019_eeg.mat 1052
+../../mat/n2023_eeg.mat 899
+../../mat/n2024_eeg.mat 959
+../../mat/n2025_eeg.mat 959
+../../mat/n2026_eeg.mat 1049
+../../mat/n2027_eeg.mat 959
+../../mat/n2028_eeg.mat 959
+../../mat/n2029_eeg.mat 929
+../../mat/n2039_eeg.mat 1056
+../../mat/n2040_eeg.mat 899
+../../mat/n2042_eeg.mat 1056
+../../mat/n2046_eeg.mat 779
+../../mat/n2053_eeg.mat 839
+../../mat/n2058_eeg.mat 775
+../../mat/n2061_eeg.mat 959
+../../mat/n2063_eeg.mat 959
+../../mat/n2065_eeg.mat 899
+../../mat/n2066_eeg.mat 959
+../../mat/n2067_eeg.mat 1069
+../../mat/n2075_eeg.mat 779
+../../mat/n2078_eeg.mat 779
+../../mat/n2079_eeg.mat 899
+../../mat/n2086_eeg.mat 1017
+../../mat/n2089_eeg.mat 773
+../../mat/n2090_eeg.mat 882
+../../mat/n2091_eeg.mat 1079
+../../mat/n2092_eeg.mat 1048
+../../mat/n2095_eeg.mat 1079
+../../mat/n2096_eeg.mat 899
+../../mat/n2103_eeg.mat 959
+../../mat/n2111_eeg.mat 1084
+../../mat/n2113_eeg.mat 1056
+../../mat/n2119_eeg.mat 1086
+../../mat/n2121_eeg.mat 839
+../../mat/n2122_eeg.mat 866
+../../mat/n2124_eeg.mat 1086
+../../mat/n2128_eeg.mat 855
+../../mat/n2130_eeg.mat 942
+../../mat/n2132_eeg.mat 839
+../../mat/n2133_eeg.mat 1086
+../../mat/n2135_eeg.mat 916
+../../mat/n2136_eeg.mat 973
+../../mat/n2138_eeg.mat 833
+../../mat/n2140_eeg.mat 946
+../../mat/n2142_eeg.mat 1028
+../../mat/n2143_eeg.mat 1086
+../../mat/n2146_eeg.mat 1086
+../../mat/n2147_eeg.mat 959
+../../mat/n2151_eeg.mat 787
+../../mat/n2153_eeg.mat 1040
+../../mat/n2154_eeg.mat 854
+../../mat/n2157_eeg.mat 1086
+../../mat/n2163_eeg.mat 742
+../../mat/n2166_eeg.mat 1084
+../../mat/n2172_eeg.mat 1086
+../../mat/n2181_eeg.mat 852
+../../mat/n2182_eeg.mat 922
+../../mat/n2184_eeg.mat 1086
+../../mat/n2185_eeg.mat 1049
+../../mat/n2190_eeg.mat 837
+../../mat/n2191_eeg.mat 1069
+../../mat/n2192_eeg.mat 911
+../../mat/n2198_eeg.mat 899
+../../mat/n2199_eeg.mat 899
+../../mat/n2200_eeg.mat 1051
+../../mat/n2201_eeg.mat 1051
+../../mat/n2202_eeg.mat 961
+../../mat/n2205_eeg.mat 561
+../../mat/n2207_eeg.mat 929
+../../mat/n2209_eeg.mat 894
+../../mat/n2211_eeg.mat 988
+../../mat/n2221_eeg.mat 867
+../../mat/n2225_eeg.mat 1053
+../../mat/n2226_eeg.mat 1053
+../../mat/n2228_eeg.mat 1053
+../../mat/n2229_eeg.mat 1051
+../../mat/n2230_eeg.mat 960
+../../mat/n2232_eeg.mat 844
+../../mat/n2233_eeg.mat 913
+../../mat/n2240_eeg.mat 1051
+../../mat/n2247_eeg.mat 1051
+../../mat/n2248_eeg.mat 781
+../../mat/n2253_eeg.mat 855
+../../mat/n2256_eeg.mat 1051
+../../mat/n2258_eeg.mat 899
+../../mat/n2262_eeg.mat 1019
+../../mat/n2264_eeg.mat 1053
+../../mat/n2266_eeg.mat 839
+../../mat/n2267_eeg.mat 781
+../../mat/n2270_eeg.mat 959
+../../mat/n2273_eeg.mat 1053
+../../mat/n2274_eeg.mat 1069
+../../mat/n2277_eeg.mat 1069
+../../mat/n2278_eeg.mat 1019
+../../mat/n2279_eeg.mat 1051
+../../mat/n2281_eeg.mat 938
+../../mat/n2283_eeg.mat 949
+../../mat/n2287_eeg.mat 869
+../../mat/n2294_eeg.mat 1069
+../../mat/n2297_eeg.mat 1051
+../../mat/n2298_eeg.mat 1053
+../../mat/n2299_eeg.mat 1069
+../../mat/n2303_eeg.mat 1069
+../../mat/n2308_eeg.mat 959
+../../mat/n2309_eeg.mat 743
+../../mat/n2312_eeg.mat 790
+../../mat/n2315_eeg.mat 1051
+../../mat/n2316_eeg.mat 1053
+../../mat/n2319_eeg.mat 1051
+../../mat/n2322_eeg.mat 1053
+../../mat/n2324_eeg.mat 1019
+../../mat/n2325_eeg.mat 1053
+../../mat/n2327_eeg.mat 1051
+../../mat/n2338_eeg.mat 955
+../../mat/n2340_eeg.mat 1053
+../../mat/n2341_eeg.mat 1053
+../../mat/n2344_eeg.mat 1053
+../../mat/n2350_eeg.mat 1069
+../../mat/n2359_eeg.mat 959
+../../mat/n2365_eeg.mat 1019
+../../mat/n2370_eeg.mat 658
+../../mat/n2376_eeg.mat 1051
+../../mat/n2378_eeg.mat 959
+../../mat/n2379_eeg.mat 959
+../../mat/n2382_eeg.mat 1019
+../../mat/n2391_eeg.mat 1069
+../../mat/n2394_eeg.mat 1019
+../../mat/n2395_eeg.mat 1067
+../../mat/n2396_eeg.mat 1019
+../../mat/n2405_eeg.mat 901
+../../mat/n2406_eeg.mat 959
+../../mat/n2412_eeg.mat 1051
+../../mat/n2413_eeg.mat 1053
+../../mat/n2417_eeg.mat 839
+../../mat/n2419_eeg.mat 1051
+../../mat/n2421_eeg.mat 1051
+../../mat/n2425_eeg.mat 1051
+../../mat/n2427_eeg.mat 922
+../../mat/n2429_eeg.mat 1079
+../../mat/n2434_eeg.mat 1069
+../../mat/n2438_eeg.mat 1051
+../../mat/n2440_eeg.mat 1051
+../../mat/n2441_eeg.mat 839
+../../mat/n2444_eeg.mat 1051
+../../mat/n2446_eeg.mat 959
+../../mat/n2451_eeg.mat 1051
+../../mat/n2453_eeg.mat 779
+../../mat/n2454_eeg.mat 899
+../../mat/n2461_eeg.mat 1051
+../../mat/n2463_eeg.mat 688
+../../mat/n2469_eeg.mat 825
+../../mat/n2471_eeg.mat 956
+../../mat/n2472_eeg.mat 959
+../../mat/n2473_eeg.mat 1079
+../../mat/n2477_eeg.mat 1086
+../../mat/n2484_eeg.mat 899
+../../mat/n2485_eeg.mat 773
+../../mat/n2491_eeg.mat 955
+../../mat/n2500_eeg.mat 987
+../../mat/n2507_eeg.mat 1086
+../../mat/n2510_eeg.mat 1084
+../../mat/n2513_eeg.mat 900
+../../mat/n2514_eeg.mat 905
+../../mat/n2524_eeg.mat 868
+../../mat/n2526_eeg.mat 960
+../../mat/n2527_eeg.mat 869
+../../mat/n2531_eeg.mat 762
+../../mat/n2533_eeg.mat 795
+../../mat/n2544_eeg.mat 780
+../../mat/n2545_eeg.mat 1086
+../../mat/n2546_eeg.mat 887
+../../mat/n2553_eeg.mat 1067
+../../mat/n2554_eeg.mat 1017
+../../mat/n2567_eeg.mat 898
+../../mat/n2568_eeg.mat 897
+../../mat/n2570_eeg.mat 1053
+../../mat/n2571_eeg.mat 1051
+../../mat/n2572_eeg.mat 1051
+../../mat/n2573_eeg.mat 929
+../../mat/n2575_eeg.mat 899
+../../mat/n2581_eeg.mat 1019
+../../mat/n2582_eeg.mat 1019
+../../mat/n2584_eeg.mat 1051
+../../mat/n2587_eeg.mat 735
+../../mat/n2590_eeg.mat 959
+../../mat/n2594_eeg.mat 1019
+../../mat/n2597_eeg.mat 1019
+../../mat/n2598_eeg.mat 1017
+../../mat/n2599_eeg.mat 1051
+../../mat/n2600_eeg.mat 1019
+../../mat/n2601_eeg.mat 1053
+../../mat/n2602_eeg.mat 1067
+../../mat/n2609_eeg.mat 1067
+../../mat/n2612_eeg.mat 1053
+../../mat/n2615_eeg.mat 1019
+../../mat/n2616_eeg.mat 899
+../../mat/n2620_eeg.mat 1019
+../../mat/n2627_eeg.mat 929
+../../mat/n2631_eeg.mat 839
+../../mat/n2635_eeg.mat 1026
+../../mat/n2638_eeg.mat 1086
+../../mat/n2639_eeg.mat 959
+../../mat/n2641_eeg.mat 747
+../../mat/n2643_eeg.mat 990
+../../mat/n2649_eeg.mat 985
+../../mat/n2652_eeg.mat 859
+../../mat/n2657_eeg.mat 1079
+../../mat/n2659_eeg.mat 989
+../../mat/n2663_eeg.mat 1069
+../../mat/n2664_eeg.mat 882
+../../mat/n2666_eeg.mat 929
+../../mat/n2667_eeg.mat 893
+../../mat/n2674_eeg.mat 1062
+../../mat/n2675_eeg.mat 883
+../../mat/n2677_eeg.mat 916
+../../mat/n2678_eeg.mat 793
+../../mat/n2680_eeg.mat 841
+../../mat/n2688_eeg.mat 997
+../../mat/n2690_eeg.mat 1053
+../../mat/n2696_eeg.mat 899
+../../mat/n2697_eeg.mat 1052
+../../mat/n2699_eeg.mat 1053
+../../mat/n2709_eeg.mat 1051
+../../mat/n2711_eeg.mat 1019
+../../mat/n2713_eeg.mat 1053
+../../mat/n2714_eeg.mat 1047
+../../mat/n2716_eeg.mat 1053
+../../mat/n2717_eeg.mat 974
+../../mat/n2722_eeg.mat 1053
+../../mat/n2726_eeg.mat 959
+../../mat/n2738_eeg.mat 1051
+../../mat/n2741_eeg.mat 1051
+../../mat/n2742_eeg.mat 1019
+../../mat/n2743_eeg.mat 1053
+../../mat/n2745_eeg.mat 1053
+../../mat/n2751_eeg.mat 1053
+../../mat/n2753_eeg.mat 1050
+../../mat/n2755_eeg.mat 1047
+../../mat/n2760_eeg.mat 1053
+../../mat/n2761_eeg.mat 1053
+../../mat/n2762_eeg.mat 1053
+../../mat/n2764_eeg.mat 961
+../../mat/n2767_eeg.mat 959
+../../mat/n2768_eeg.mat 839
+../../mat/n2769_eeg.mat 1051
+../../mat/n2772_eeg.mat 1015
+../../mat/n2775_eeg.mat 1053
+../../mat/n2776_eeg.mat 1052
+../../mat/n2780_eeg.mat 1053
+../../mat/n2781_eeg.mat 1053
+../../mat/n2792_eeg.mat 988
+../../mat/n2796_eeg.mat 1053
+../../mat/n2798_eeg.mat 895
+../../mat/n2802_eeg.mat 1019
+../../mat/n2804_eeg.mat 1051
+../../mat/n2806_eeg.mat 795
+../../mat/n2815_eeg.mat 910
+../../mat/n2821_eeg.mat 1052
+../../mat/n2822_eeg.mat 1051
+../../mat/n2823_eeg.mat 1053
+../../mat/n2825_eeg.mat 1017
+../../mat/n2827_eeg.mat 931
+../../mat/n2831_eeg.mat 1051
+../../mat/n2832_eeg.mat 1053
+../../mat/n2834_eeg.mat 1053
+../../mat/n2837_eeg.mat 1053
+../../mat/n2842_eeg.mat 1053
+../../mat/n2846_eeg.mat 1019
+../../mat/n2847_eeg.mat 1053
+../../mat/n2853_eeg.mat 1053
+../../mat/n2854_eeg.mat 899
+../../mat/n2855_eeg.mat 1051
+../../mat/n2860_eeg.mat 1053
+../../mat/n2863_eeg.mat 1053
+../../mat/n2866_eeg.mat 1051
+../../mat/n2867_eeg.mat 1053
+../../mat/n2869_eeg.mat 1050
+../../mat/n2871_eeg.mat 1019
+../../mat/n2877_eeg.mat 1053
+../../mat/n2878_eeg.mat 1050
+../../mat/n2885_eeg.mat 986
+../../mat/n2898_eeg.mat 1023
+../../mat/n2904_eeg.mat 1053
+../../mat/n2908_eeg.mat 1053
+../../mat/n2915_eeg.mat 687
+../../mat/n2917_eeg.mat 989
+../../mat/n2918_eeg.mat 1028
+../../mat/n2919_eeg.mat 1025
+../../mat/n2920_eeg.mat 1053
+../../mat/n2921_eeg.mat 1025
+../../mat/n2929_eeg.mat 959
+../../mat/n2930_eeg.mat 959
+../../mat/n2935_eeg.mat 1050
+../../mat/n2936_eeg.mat 1023
+../../mat/n2937_eeg.mat 1025
+../../mat/n2939_eeg.mat 1025
+../../mat/n2947_eeg.mat 839
+../../mat/n2954_eeg.mat 1053
+../../mat/n2956_eeg.mat 553
+../../mat/n2958_eeg.mat 1019
+../../mat/n2959_eeg.mat 984
+../../mat/n2960_eeg.mat 1053
+../../mat/n2962_eeg.mat 1053
+../../mat/n2963_eeg.mat 1053
+../../mat/n2967_eeg.mat 1053
+../../mat/n2968_eeg.mat 1052
+../../mat/n2972_eeg.mat 1025
+../../mat/n2976_eeg.mat 1019
+../../mat/n2978_eeg.mat 1019
+../../mat/n2982_eeg.mat 1053
+../../mat/n2986_eeg.mat 923
+../../mat/n2987_eeg.mat 1053
+../../mat/n2988_eeg.mat 1019
+../../mat/n2991_eeg.mat 1053
+../../mat/n2994_eeg.mat 959
+../../mat/n2996_eeg.mat 1051
+../../mat/n2997_eeg.mat 1025
+../../mat/n2998_eeg.mat 1053
+../../mat/n3002_eeg.mat 979
+../../mat/n3010_eeg.mat 612
+../../mat/n3011_eeg.mat 1053
+../../mat/n3015_eeg.mat 1051
+../../mat/n3017_eeg.mat 959
+../../mat/n3018_eeg.mat 1051
+../../mat/n3022_eeg.mat 809
+../../mat/n3024_eeg.mat 1053
+../../mat/n3026_eeg.mat 830
+../../mat/n3027_eeg.mat 899
+../../mat/n3030_eeg.mat 959
+../../mat/n3033_eeg.mat 1053
+../../mat/n3044_eeg.mat 1051
+../../mat/n3048_eeg.mat 1053
+../../mat/n3049_eeg.mat 1053
+../../mat/n3050_eeg.mat 1051
+../../mat/n3053_eeg.mat 1015
+../../mat/n3054_eeg.mat 1053
+../../mat/n3057_eeg.mat 756
+../../mat/n3065_eeg.mat 839
+../../mat/n3066_eeg.mat 1019
+../../mat/n3072_eeg.mat 1053
+../../mat/n3074_eeg.mat 1053
+../../mat/n3075_eeg.mat 1053
+../../mat/n3080_eeg.mat 1051
+../../mat/n3086_eeg.mat 1053
+../../mat/n3087_eeg.mat 1053
+../../mat/n3088_eeg.mat 1019
+../../mat/n3090_eeg.mat 1051
+../../mat/n3094_eeg.mat 1052
+../../mat/n3096_eeg.mat 1031
+../../mat/n3097_eeg.mat 1052
+../../mat/n3104_eeg.mat 955
+../../mat/n3105_eeg.mat 1053
+../../mat/n3115_eeg.mat 1053
+../../mat/n3119_eeg.mat 1051
+../../mat/n3120_eeg.mat 1053
+../../mat/n3121_eeg.mat 988
+../../mat/n3123_eeg.mat 1053
+../../mat/n3127_eeg.mat 1051
+../../mat/n3132_eeg.mat 959
+../../mat/n3133_eeg.mat 959
+../../mat/n3134_eeg.mat 986
+../../mat/n3136_eeg.mat 1051
+../../mat/n3141_eeg.mat 1053
+../../mat/n3143_eeg.mat 1053
+../../mat/n3152_eeg.mat 1014
+../../mat/n3154_eeg.mat 1053
+../../mat/n3159_eeg.mat 1053
+../../mat/n3161_eeg.mat 839
+../../mat/n3170_eeg.mat 1018
+../../mat/n3172_eeg.mat 714
+../../mat/n3177_eeg.mat 1053
+../../mat/n3179_eeg.mat 1053
+../../mat/n3181_eeg.mat 1052
+../../mat/n3190_eeg.mat 1051
+../../mat/n3199_eeg.mat 1053
+../../mat/n3201_eeg.mat 1042
+../../mat/n3204_eeg.mat 1053
+../../mat/n3205_eeg.mat 1053
+../../mat/n3206_eeg.mat 1053
+../../mat/n3207_eeg.mat 1051
+../../mat/n3208_eeg.mat 1053
+../../mat/n3211_eeg.mat 1053
+../../mat/n3212_eeg.mat 1052
+../../mat/n3213_eeg.mat 959
+../../mat/n3218_eeg.mat 1053
+../../mat/n3220_eeg.mat 1053
+../../mat/n3224_eeg.mat 1053
+../../mat/n3225_eeg.mat 1053
+../../mat/n3226_eeg.mat 778
+../../mat/n3227_eeg.mat 1048
+../../mat/n3228_eeg.mat 1042
+../../mat/n3229_eeg.mat 1051
+../../mat/n3230_eeg.mat 1051
+../../mat/n3235_eeg.mat 873
+../../mat/n3236_eeg.mat 1051
+../../mat/n3238_eeg.mat 1053
+../../mat/n3240_eeg.mat 957
+../../mat/n3243_eeg.mat 1050
+../../mat/n3253_eeg.mat 1053
+../../mat/n3256_eeg.mat 1053
+../../mat/n3258_eeg.mat 899
+../../mat/n3263_eeg.mat 1053
+../../mat/n3265_eeg.mat 959
+../../mat/n3267_eeg.mat 1025
+../../mat/n3268_eeg.mat 1053
+../../mat/n3274_eeg.mat 1039
+../../mat/n3278_eeg.mat 914
+../../mat/n3288_eeg.mat 1053
+../../mat/n3290_eeg.mat 1019
+../../mat/n3297_eeg.mat 959
+../../mat/n3302_eeg.mat 903
+../../mat/n3307_eeg.mat 959
+../../mat/n3308_eeg.mat 1053
+../../mat/n3309_eeg.mat 1053
+../../mat/n3310_eeg.mat 1072
+../../mat/n3314_eeg.mat 1053
+../../mat/n3315_eeg.mat 1053
+../../mat/n3317_eeg.mat 1049
+../../mat/n3325_eeg.mat 1053
+../../mat/n3326_eeg.mat 1053
+../../mat/n3328_eeg.mat 1051
+../../mat/n3329_eeg.mat 920
+../../mat/n3330_eeg.mat 980
+../../mat/n3331_eeg.mat 1048
+../../mat/n3332_eeg.mat 1019
+../../mat/n3333_eeg.mat 1049
+../../mat/n3340_eeg.mat 1051
+../../mat/n3350_eeg.mat 958
+../../mat/n3355_eeg.mat 1053
+../../mat/n3360_eeg.mat 997
+../../mat/n3362_eeg.mat 1051
+../../mat/n3364_eeg.mat 1051
+../../mat/n3373_eeg.mat 1051
+../../mat/n3374_eeg.mat 1053
+../../mat/n3377_eeg.mat 1053
+../../mat/n3381_eeg.mat 1051
+../../mat/n3382_eeg.mat 1051
+../../mat/n3390_eeg.mat 1053
+../../mat/n3392_eeg.mat 1053
+../../mat/n3394_eeg.mat 947
+../../mat/n3399_eeg.mat 1053
+../../mat/n3416_eeg.mat 1056
+../../mat/n3422_eeg.mat 1052
+../../mat/n3423_eeg.mat 1051
+../../mat/n3425_eeg.mat 1053
+../../mat/n3430_eeg.mat 1019
+../../mat/n3436_eeg.mat 1053
+../../mat/n3443_eeg.mat 1053
+../../mat/n3447_eeg.mat 1053
+../../mat/n3449_eeg.mat 959
+../../mat/n3450_eeg.mat 1051
+../../mat/n3454_eeg.mat 1053
+../../mat/n3457_eeg.mat 1053
+../../mat/n3459_eeg.mat 1053
+../../mat/n3462_eeg.mat 1053
+../../mat/n3463_eeg.mat 1051
+../../mat/n3465_eeg.mat 1053
+../../mat/n3469_eeg.mat 1053
+../../mat/n3477_eeg.mat 878
+../../mat/n3478_eeg.mat 959
+../../mat/n3481_eeg.mat 1053
+../../mat/n3483_eeg.mat 959
+../../mat/n3484_eeg.mat 959
+../../mat/n3485_eeg.mat 955
+../../mat/n3489_eeg.mat 1072
+../../mat/n3495_eeg.mat 1053
+../../mat/n3499_eeg.mat 1053
+../../mat/n3505_eeg.mat 1049
+../../mat/n3506_eeg.mat 1050
+../../mat/n3509_eeg.mat 1053
+../../mat/n3510_eeg.mat 1019
+../../mat/n3511_eeg.mat 1053
+../../mat/n3512_eeg.mat 1053
+../../mat/n3516_eeg.mat 1019
+../../mat/n3517_eeg.mat 1007
+../../mat/n3521_eeg.mat 923
+../../mat/n3536_eeg.mat 1014
+../../mat/n3538_eeg.mat 1049
+../../mat/n3539_eeg.mat 929
+../../mat/n3543_eeg.mat 1053
+../../mat/n3545_eeg.mat 1051
+../../mat/n3553_eeg.mat 1019
+../../mat/n3559_eeg.mat 1053
+../../mat/n3560_eeg.mat 1053
+../../mat/n3565_eeg.mat 1051
+../../mat/n3573_eeg.mat 1053
+../../mat/n3574_eeg.mat 1053
+../../mat/n3578_eeg.mat 816
+../../mat/n3579_eeg.mat 1019
+../../mat/n3583_eeg.mat 1019
+../../mat/n3584_eeg.mat 1051
+../../mat/n3585_eeg.mat 1049
+../../mat/n3587_eeg.mat 1053
+../../mat/n3592_eeg.mat 1051
+../../mat/n3593_eeg.mat 1051
+../../mat/n3595_eeg.mat 1053
+../../mat/n3596_eeg.mat 1053
+../../mat/n3597_eeg.mat 764
+../../mat/n3600_eeg.mat 1050
+../../mat/n3603_eeg.mat 1053
+../../mat/n3605_eeg.mat 1053
+../../mat/n3607_eeg.mat 1051
+../../mat/n3608_eeg.mat 1053
+../../mat/n3609_eeg.mat 1053
+../../mat/n3613_eeg.mat 898
+../../mat/n3614_eeg.mat 1048
+../../mat/n3620_eeg.mat 959
+../../mat/n3629_eeg.mat 1019
+../../mat/n3630_eeg.mat 918
+../../mat/n3632_eeg.mat 1053
+../../mat/n3634_eeg.mat 1051
+../../mat/n3638_eeg.mat 1043
+../../mat/n3639_eeg.mat 899
+../../mat/n3641_eeg.mat 1051
+../../mat/n3643_eeg.mat 504
+../../mat/n3645_eeg.mat 1053
+../../mat/n3649_eeg.mat 899
+../../mat/n3656_eeg.mat 1049
+../../mat/n3658_eeg.mat 1050
+../../mat/n3659_eeg.mat 1051
+../../mat/n3671_eeg.mat 989
+../../mat/n3672_eeg.mat 1053
+../../mat/n3673_eeg.mat 1051
+../../mat/n3674_eeg.mat 1005
+../../mat/n3675_eeg.mat 1038
+../../mat/n3676_eeg.mat 1051
+../../mat/n3680_eeg.mat 1019
+../../mat/n3681_eeg.mat 1049
+../../mat/n3684_eeg.mat 1053
+../../mat/n3685_eeg.mat 959
+../../mat/n3689_eeg.mat 1053
+../../mat/n3691_eeg.mat 1050
+../../mat/n3697_eeg.mat 1053
+../../mat/n3699_eeg.mat 1052
+../../mat/n3702_eeg.mat 1051
+../../mat/n3704_eeg.mat 1053
+../../mat/n3707_eeg.mat 1053
+../../mat/n3709_eeg.mat 1053
+../../mat/n3710_eeg.mat 1053
+../../mat/n3721_eeg.mat 1069
+../../mat/n3724_eeg.mat 1069
+../../mat/n3727_eeg.mat 1067
+../../mat/n3735_eeg.mat 1067
+../../mat/n3736_eeg.mat 1069
+../../mat/n3741_eeg.mat 1019
+../../mat/n3742_eeg.mat 1069
+../../mat/n3744_eeg.mat 1021
+../../mat/n3746_eeg.mat 1069
+../../mat/n3752_eeg.mat 749
+../../mat/n3755_eeg.mat 958
+../../mat/n3761_eeg.mat 1019
+../../mat/n3762_eeg.mat 855
+../../mat/n3763_eeg.mat 1018
+../../mat/n3764_eeg.mat 1067
+../../mat/n3767_eeg.mat 1067
+../../mat/n3773_eeg.mat 1068
+../../mat/n3774_eeg.mat 724
+../../mat/n3780_eeg.mat 1068
+../../mat/n3790_eeg.mat 989
+../../mat/n3791_eeg.mat 959
+../../mat/n3792_eeg.mat 1069
+../../mat/n3802_eeg.mat 959
+../../mat/n3806_eeg.mat 1047
+../../mat/n3809_eeg.mat 1067
+../../mat/n3814_eeg.mat 1067
+../../mat/n3819_eeg.mat 927
+../../mat/n3820_eeg.mat 1067
+../../mat/n3821_eeg.mat 1019
+../../mat/n3827_eeg.mat 1048
+../../mat/n3828_eeg.mat 1069
+../../mat/n3830_eeg.mat 1049
+../../mat/n3834_eeg.mat 961
+../../mat/n3836_eeg.mat 901
+../../mat/n3840_eeg.mat 1067
+../../mat/n3846_eeg.mat 1067
+../../mat/n3849_eeg.mat 1069
+../../mat/n3852_eeg.mat 1019
+../../mat/n3854_eeg.mat 1019
+../../mat/n3860_eeg.mat 989
+../../mat/n3862_eeg.mat 1049
+../../mat/n3863_eeg.mat 959
+../../mat/n3868_eeg.mat 410
+../../mat/n3870_eeg.mat 1067
+../../mat/n3878_eeg.mat 1067
+../../mat/n3888_eeg.mat 1019
+../../mat/n3890_eeg.mat 1067
+../../mat/n3891_eeg.mat 797
+../../mat/n3897_eeg.mat 1069
+../../mat/n3911_eeg.mat 1067
+../../mat/n3915_eeg.mat 1067
+../../mat/n3919_eeg.mat 1019
+../../mat/n3932_eeg.mat 1019
+../../mat/n3934_eeg.mat 1019
+../../mat/n3935_eeg.mat 1067
+../../mat/n3937_eeg.mat 1017
+../../mat/n3945_eeg.mat 1067
+../../mat/n3946_eeg.mat 1049
+../../mat/n3949_eeg.mat 1067
+../../mat/n3950_eeg.mat 1069
+../../mat/n3953_eeg.mat 1019
+../../mat/n3961_eeg.mat 1054
+../../mat/n3965_eeg.mat 1069
+../../mat/n3966_eeg.mat 1068
+../../mat/n3970_eeg.mat 1019
+../../mat/n3975_eeg.mat 956
+../../mat/n3978_eeg.mat 1067
+../../mat/n3984_eeg.mat 1067
+../../mat/n3990_eeg.mat 823
+../../mat/n3991_eeg.mat 1067
+../../mat/n3992_eeg.mat 1068
+../../mat/n3993_eeg.mat 1068
+../../mat/n3994_eeg.mat 1047
+../../mat/n4003_eeg.mat 1068
+../../mat/n4004_eeg.mat 1019
+../../mat/n4006_eeg.mat 1068
+../../mat/n4008_eeg.mat 1067
+../../mat/n4012_eeg.mat 1066
+../../mat/n4015_eeg.mat 959
+../../mat/n4020_eeg.mat 1019
+../../mat/n4022_eeg.mat 1068
+../../mat/n4025_eeg.mat 957
+../../mat/n4027_eeg.mat 1069
+../../mat/n4028_eeg.mat 1068
+../../mat/n4029_eeg.mat 1067
+../../mat/n4031_eeg.mat 1067
+../../mat/n4035_eeg.mat 1052
+../../mat/n4036_eeg.mat 1069
+../../mat/n4037_eeg.mat 1067
+../../mat/n4041_eeg.mat 993
+../../mat/n4043_eeg.mat 1045
+../../mat/n4046_eeg.mat 1017
+../../mat/n4048_eeg.mat 1067
+../../mat/n4053_eeg.mat 961
+../../mat/n4061_eeg.mat 1018
+../../mat/n4063_eeg.mat 1068
+../../mat/n4064_eeg.mat 870
+../../mat/n4067_eeg.mat 1069
+../../mat/n4068_eeg.mat 1067
+../../mat/n4070_eeg.mat 1069
+../../mat/n4073_eeg.mat 1068
+../../mat/n4075_eeg.mat 1019
+../../mat/n4076_eeg.mat 1068
+../../mat/n4085_eeg.mat 1069
+../../mat/n4086_eeg.mat 1069
+../../mat/n4087_eeg.mat 1067
+../../mat/n4088_eeg.mat 1068
+../../mat/n4089_eeg.mat 1069
+../../mat/n4092_eeg.mat 1067
+../../mat/n4100_eeg.mat 1069
+../../mat/n4107_eeg.mat 1051
+../../mat/n4117_eeg.mat 959
+../../mat/n4122_eeg.mat 1019
+../../mat/n4126_eeg.mat 1049
+../../mat/n4128_eeg.mat 839
+../../mat/n4133_eeg.mat 1069
+../../mat/n4136_eeg.mat 1044
+../../mat/n4137_eeg.mat 1068
+../../mat/n4139_eeg.mat 892
+../../mat/n4142_eeg.mat 1021
+../../mat/n4146_eeg.mat 1019
+../../mat/n4148_eeg.mat 1059
+../../mat/n4151_eeg.mat 1066
+../../mat/n4155_eeg.mat 1067
+../../mat/n4157_eeg.mat 1019
+../../mat/n4159_eeg.mat 959
+../../mat/n4161_eeg.mat 1067
+../../mat/n4163_eeg.mat 1068
+../../mat/n4165_eeg.mat 1068
+../../mat/n4166_eeg.mat 1067
+../../mat/n4168_eeg.mat 1068
+../../mat/n4175_eeg.mat 1068
+../../mat/n4185_eeg.mat 1068
+../../mat/n4186_eeg.mat 644
+../../mat/n4190_eeg.mat 1067
+../../mat/n4191_eeg.mat 1069
+../../mat/n4195_eeg.mat 1067
+../../mat/n4203_eeg.mat 1051
+../../mat/n4205_eeg.mat 1058
+../../mat/n4206_eeg.mat 1067
+../../mat/n4210_eeg.mat 1066
+../../mat/n4215_eeg.mat 1069
+../../mat/n4220_eeg.mat 1069
+../../mat/n4223_eeg.mat 1068
+../../mat/n4225_eeg.mat 1067
+../../mat/n4229_eeg.mat 1067
+../../mat/n4233_eeg.mat 1067
+../../mat/n4235_eeg.mat 899
+../../mat/n4247_eeg.mat 1019
+../../mat/n4248_eeg.mat 959
+../../mat/n4250_eeg.mat 1068
+../../mat/n4252_eeg.mat 1052
+../../mat/n4253_eeg.mat 1069
+../../mat/n4255_eeg.mat 1019
+../../mat/n4263_eeg.mat 1069
+../../mat/n4269_eeg.mat 1019
+../../mat/n4271_eeg.mat 1067
+../../mat/n4274_eeg.mat 1068
+../../mat/n4277_eeg.mat 1019
+../../mat/n4281_eeg.mat 1067
+../../mat/n4286_eeg.mat 1069
+../../mat/n4290_eeg.mat 959
+../../mat/n4292_eeg.mat 959
+../../mat/n4296_eeg.mat 1042
+../../mat/n4311_eeg.mat 1067
+../../mat/n4312_eeg.mat 1019
+../../mat/n4314_eeg.mat 1051
+../../mat/n4316_eeg.mat 1051
+../../mat/n4317_eeg.mat 1019
+../../mat/n4319_eeg.mat 1019
+../../mat/n4328_eeg.mat 1069
+../../mat/n4331_eeg.mat 958
+../../mat/n4335_eeg.mat 1067
+../../mat/n4336_eeg.mat 959
+../../mat/n4350_eeg.mat 1053
+../../mat/n4358_eeg.mat 1051
+../../mat/n4362_eeg.mat 1067
+../../mat/n4365_eeg.mat 1067
+../../mat/n4368_eeg.mat 1019
+../../mat/n4369_eeg.mat 1067
+../../mat/n4374_eeg.mat 1067
+../../mat/n4375_eeg.mat 1019
+../../mat/n4377_eeg.mat 989
+../../mat/n4379_eeg.mat 899
+../../mat/n4382_eeg.mat 1019
+../../mat/n4383_eeg.mat 989
+../../mat/n4387_eeg.mat 1069
+../../mat/n4388_eeg.mat 1053
+../../mat/n4389_eeg.mat 1067
+../../mat/n4391_eeg.mat 959
+../../mat/n4401_eeg.mat 1019
+../../mat/n4402_eeg.mat 1059
+../../mat/n4406_eeg.mat 791
+../../mat/n4407_eeg.mat 1049
+../../mat/n4416_eeg.mat 989
+../../mat/n4418_eeg.mat 1066
+../../mat/n4420_eeg.mat 989
+../../mat/n4424_eeg.mat 1069
+../../mat/n4436_eeg.mat 1069
+../../mat/n4439_eeg.mat 1067
+../../mat/n4444_eeg.mat 1019
+../../mat/n4445_eeg.mat 959
+../../mat/n4455_eeg.mat 1067
+../../mat/n4456_eeg.mat 1069
+../../mat/n4457_eeg.mat 1067
+../../mat/n4458_eeg.mat 1069
+../../mat/n4460_eeg.mat 1067
+../../mat/n4463_eeg.mat 1069
+../../mat/n4464_eeg.mat 1069
+../../mat/n4469_eeg.mat 1069
+../../mat/n4470_eeg.mat 1067
+../../mat/n4473_eeg.mat 1019
+../../mat/n4479_eeg.mat 1067
+../../mat/n4487_eeg.mat 1068
+../../mat/n4496_eeg.mat 1067
+../../mat/n4498_eeg.mat 959
+../../mat/n4499_eeg.mat 1069
+../../mat/n4505_eeg.mat 1067
+../../mat/n4509_eeg.mat 1018
+../../mat/n4510_eeg.mat 1067
+../../mat/n4513_eeg.mat 1069
+../../mat/n4517_eeg.mat 1067
+../../mat/n4520_eeg.mat 1021
+../../mat/n4521_eeg.mat 1069
+../../mat/n4523_eeg.mat 953
+../../mat/n4527_eeg.mat 1055
+../../mat/n4529_eeg.mat 1069
+../../mat/n4533_eeg.mat 1065
+../../mat/n4534_eeg.mat 1019
+../../mat/n4539_eeg.mat 1068
+../../mat/n4541_eeg.mat 1067
+../../mat/n4546_eeg.mat 799
+../../mat/n4548_eeg.mat 1067
+../../mat/n4554_eeg.mat 892
+../../mat/n4556_eeg.mat 1045
+../../mat/n4559_eeg.mat 1067
+../../mat/n4560_eeg.mat 1068
+../../mat/n4564_eeg.mat 637
+../../mat/n4569_eeg.mat 1069
+../../mat/n4585_eeg.mat 1067
+../../mat/n4589_eeg.mat 1068
+../../mat/n4591_eeg.mat 1068
+../../mat/n4593_eeg.mat 1068
+../../mat/n4595_eeg.mat 930
+../../mat/n4596_eeg.mat 1006
+../../mat/n4601_eeg.mat 1019
+../../mat/n4605_eeg.mat 1068
+../../mat/n4607_eeg.mat 1068
+../../mat/n4608_eeg.mat 1067
+../../mat/n4612_eeg.mat 1012
+../../mat/n4615_eeg.mat 1069
+../../mat/n4616_eeg.mat 1069
+../../mat/n4624_eeg.mat 1055
+../../mat/n4627_eeg.mat 1068
+../../mat/n4630_eeg.mat 1069
+../../mat/n4638_eeg.mat 1067
+../../mat/n4639_eeg.mat 958
+../../mat/n4642_eeg.mat 987
+../../mat/n4644_eeg.mat 1069
+../../mat/n4646_eeg.mat 1069
+../../mat/n4648_eeg.mat 1069
+../../mat/n4649_eeg.mat 1069
+../../mat/n4651_eeg.mat 1067
+../../mat/n4653_eeg.mat 1019
+../../mat/n4659_eeg.mat 1069
+../../mat/n4661_eeg.mat 899
+../../mat/n4666_eeg.mat 1067
+../../mat/n4668_eeg.mat 957
+../../mat/n4669_eeg.mat 929
+../../mat/n4674_eeg.mat 1056
+../../mat/n4676_eeg.mat 1067
+../../mat/n4679_eeg.mat 959
+../../mat/n4686_eeg.mat 1053
+../../mat/n4690_eeg.mat 1051
+../../mat/n4691_eeg.mat 1019
+../../mat/n4692_eeg.mat 1053
+../../mat/n4693_eeg.mat 959
+../../mat/n4697_eeg.mat 1018
+../../mat/n4700_eeg.mat 1019
+../../mat/n4703_eeg.mat 839
+../../mat/n4704_eeg.mat 867
+../../mat/n4706_eeg.mat 1018
+../../mat/n4711_eeg.mat 1056
+../../mat/n4712_eeg.mat 899
+../../mat/n4713_eeg.mat 959
+../../mat/n4717_eeg.mat 899
+../../mat/n4720_eeg.mat 839
+../../mat/n4723_eeg.mat 1055
+../../mat/n4725_eeg.mat 839
+../../mat/n4726_eeg.mat 1056
+../../mat/n4727_eeg.mat 1056
+../../mat/n4728_eeg.mat 811
+../../mat/n4729_eeg.mat 959
+../../mat/n4731_eeg.mat 899
+../../mat/n4733_eeg.mat 1019
+../../mat/n4742_eeg.mat 1056
+../../mat/n4744_eeg.mat 959
+../../mat/n4746_eeg.mat 1013
+../../mat/n4751_eeg.mat 1056
+../../mat/n4753_eeg.mat 1019
+../../mat/n4756_eeg.mat 1056
+../../mat/n4757_eeg.mat 1019
+../../mat/n4765_eeg.mat 959
+../../mat/n4766_eeg.mat 1053
+../../mat/n4767_eeg.mat 632
+../../mat/n4768_eeg.mat 959
+../../mat/n4769_eeg.mat 959
+../../mat/n4770_eeg.mat 959
+../../mat/n4772_eeg.mat 1056
+../../mat/n4779_eeg.mat 959
+../../mat/n4783_eeg.mat 899
+../../mat/n4792_eeg.mat 1019
+../../mat/n4793_eeg.mat 721
+../../mat/n4794_eeg.mat 959
+../../mat/n4798_eeg.mat 719
+../../mat/n4807_eeg.mat 899
+../../mat/n4811_eeg.mat 1017
+../../mat/n4813_eeg.mat 1056
+../../mat/n4814_eeg.mat 1051
+../../mat/n4823_eeg.mat 1055
+../../mat/n4825_eeg.mat 1056
+../../mat/n4828_eeg.mat 1056
+../../mat/n4832_eeg.mat 839
+../../mat/n4841_eeg.mat 1015
+../../mat/n4842_eeg.mat 1053
+../../mat/n4850_eeg.mat 959
+../../mat/n4855_eeg.mat 790
+../../mat/n4863_eeg.mat 1053
+../../mat/n4866_eeg.mat 1053
+../../mat/n4869_eeg.mat 868
+../../mat/n4872_eeg.mat 1018
+../../mat/n4874_eeg.mat 687
+../../mat/n4879_eeg.mat 959
+../../mat/n4880_eeg.mat 1051
+../../mat/n4888_eeg.mat 1053
+../../mat/n4890_eeg.mat 959
+../../mat/n4891_eeg.mat 1053
+../../mat/n4895_eeg.mat 1051
+../../mat/n4896_eeg.mat 1019
+../../mat/n4897_eeg.mat 1053
+../../mat/n4898_eeg.mat 1019
+../../mat/n4902_eeg.mat 1053
+../../mat/n4903_eeg.mat 1019
+../../mat/n4904_eeg.mat 1053
+../../mat/n4905_eeg.mat 959
+../../mat/n4906_eeg.mat 839
+../../mat/n4912_eeg.mat 1053
+../../mat/n4913_eeg.mat 1053
+../../mat/n4914_eeg.mat 899
+../../mat/n4921_eeg.mat 921
+../../mat/n4928_eeg.mat 899
+../../mat/n4934_eeg.mat 959
+../../mat/n4936_eeg.mat 1053
+../../mat/n4945_eeg.mat 1019
+../../mat/n4952_eeg.mat 1053
+../../mat/n4958_eeg.mat 1053
+../../mat/n4963_eeg.mat 1051
+../../mat/n4967_eeg.mat 958
+../../mat/n4970_eeg.mat 1053
+../../mat/n4971_eeg.mat 1019
+../../mat/n4976_eeg.mat 839
+../../mat/n4983_eeg.mat 1051
+../../mat/n4987_eeg.mat 779
+../../mat/n4988_eeg.mat 1053
+../../mat/n4989_eeg.mat 936
+../../mat/n4990_eeg.mat 989
+../../mat/n4991_eeg.mat 1053
+../../mat/n4993_eeg.mat 989
+../../mat/n4996_eeg.mat 1053
+../../mat/n4997_eeg.mat 899
+../../mat/n4998_eeg.mat 899
+../../mat/n5001_eeg.mat 959
+../../mat/n5002_eeg.mat 899
+../../mat/n5003_eeg.mat 959
+../../mat/n5006_eeg.mat 879
+../../mat/n5007_eeg.mat 899
+../../mat/n5008_eeg.mat 1049
+../../mat/n5009_eeg.mat 1053
+../../mat/n5010_eeg.mat 1019
+../../mat/n5016_eeg.mat 959
+../../mat/n5019_eeg.mat 749
+../../mat/n5020_eeg.mat 959
+../../mat/n5024_eeg.mat 1053
+../../mat/n5027_eeg.mat 1053
+../../mat/n5028_eeg.mat 1051
+../../mat/n5030_eeg.mat 959
+../../mat/n5037_eeg.mat 1053
+../../mat/n5044_eeg.mat 1053
+../../mat/n5049_eeg.mat 1053
+../../mat/n5057_eeg.mat 959
+../../mat/n5065_eeg.mat 959
+../../mat/n5071_eeg.mat 1053
+../../mat/n5073_eeg.mat 1051
+../../mat/n5074_eeg.mat 1021
+../../mat/n5083_eeg.mat 1053
+../../mat/n5084_eeg.mat 963
+../../mat/n5087_eeg.mat 1053
+../../mat/n5095_eeg.mat 959
+../../mat/n5100_eeg.mat 974
+../../mat/n5102_eeg.mat 1051
+../../mat/n5109_eeg.mat 1069
+../../mat/n5114_eeg.mat 1019
+../../mat/n5115_eeg.mat 989
+../../mat/n5118_eeg.mat 1017
+../../mat/n5120_eeg.mat 1053
+../../mat/n5121_eeg.mat 1014
+../../mat/n5127_eeg.mat 1053
+../../mat/n5131_eeg.mat 1069
+../../mat/n5134_eeg.mat 1051
+../../mat/n5139_eeg.mat 1018
+../../mat/n5141_eeg.mat 940
+../../mat/n5152_eeg.mat 1053
+../../mat/n5155_eeg.mat 1053
+../../mat/n5158_eeg.mat 959
+../../mat/n5159_eeg.mat 1053
+../../mat/n5160_eeg.mat 1019
+../../mat/n5168_eeg.mat 1053
+../../mat/n5171_eeg.mat 913
+../../mat/n5174_eeg.mat 1053
+../../mat/n5180_eeg.mat 1069
+../../mat/n5184_eeg.mat 1053
+../../mat/n5188_eeg.mat 1069
+../../mat/n5190_eeg.mat 1053
+../../mat/n5191_eeg.mat 1053
+../../mat/n5193_eeg.mat 1053
+../../mat/n5194_eeg.mat 899
+../../mat/n5197_eeg.mat 1049
+../../mat/n5198_eeg.mat 1067
+../../mat/n5203_eeg.mat 1053
+../../mat/n5206_eeg.mat 1069
+../../mat/n5207_eeg.mat 1014
+../../mat/n5212_eeg.mat 779
+../../mat/n5214_eeg.mat 1053
+../../mat/n5216_eeg.mat 1053
+../../mat/n5221_eeg.mat 1051
+../../mat/n5224_eeg.mat 991
+../../mat/n5228_eeg.mat 957
+../../mat/n5236_eeg.mat 1052
+../../mat/n5239_eeg.mat 1069
+../../mat/n5240_eeg.mat 1053
+../../mat/n5246_eeg.mat 899
+../../mat/n5247_eeg.mat 1053
+../../mat/n5248_eeg.mat 1019
+../../mat/n5255_eeg.mat 929
+../../mat/n5260_eeg.mat 1053
+../../mat/n5262_eeg.mat 1051
+../../mat/n5267_eeg.mat 1053
+../../mat/n5268_eeg.mat 778
+../../mat/n5269_eeg.mat 1053
+../../mat/n5271_eeg.mat 1069
+../../mat/n5276_eeg.mat 1053
+../../mat/n5277_eeg.mat 967
+../../mat/n5280_eeg.mat 1067
+../../mat/n5284_eeg.mat 1053
+../../mat/n5287_eeg.mat 1069
+../../mat/n5293_eeg.mat 1053
+../../mat/n5297_eeg.mat 1053
+../../mat/n5301_eeg.mat 1053
+../../mat/n5302_eeg.mat 1018
+../../mat/n5304_eeg.mat 509
+../../mat/n5305_eeg.mat 895
+../../mat/n5307_eeg.mat 1069
+../../mat/n5308_eeg.mat 839
+../../mat/n5310_eeg.mat 957
+../../mat/n5311_eeg.mat 959
+../../mat/n5314_eeg.mat 775
+../../mat/n5318_eeg.mat 1051
+../../mat/n5319_eeg.mat 1053
+../../mat/n5326_eeg.mat 1053
+../../mat/n5327_eeg.mat 1052
+../../mat/n5328_eeg.mat 1053
+../../mat/n5334_eeg.mat 899
+../../mat/n5342_eeg.mat 1069
+../../mat/n5345_eeg.mat 1069
+../../mat/n5346_eeg.mat 1032
+../../mat/n5347_eeg.mat 1065
+../../mat/n5349_eeg.mat 1053
+../../mat/n5359_eeg.mat 1069
+../../mat/n5361_eeg.mat 1017
+../../mat/n5364_eeg.mat 1019
+../../mat/n5366_eeg.mat 958
+../../mat/n5368_eeg.mat 1069
+../../mat/n5369_eeg.mat 1069
+../../mat/n5375_eeg.mat 1069
+../../mat/n5378_eeg.mat 1020
+../../mat/n5380_eeg.mat 1065
+../../mat/n5383_eeg.mat 1069
+../../mat/n5384_eeg.mat 1067
+../../mat/n5388_eeg.mat 1067
+../../mat/n5391_eeg.mat 762
+../../mat/n5393_eeg.mat 1069
+../../mat/n5394_eeg.mat 1069
+../../mat/n5395_eeg.mat 959
+../../mat/n5398_eeg.mat 1066
+../../mat/n5401_eeg.mat 1069
+../../mat/n5409_eeg.mat 1069
+../../mat/n5410_eeg.mat 1069
+../../mat/n5416_eeg.mat 947
+../../mat/n5421_eeg.mat 1069
+../../mat/n5424_eeg.mat 1069
+../../mat/n5429_eeg.mat 1069
+../../mat/n5437_eeg.mat 1069
+../../mat/n5440_eeg.mat 1019
+../../mat/n5441_eeg.mat 1069
+../../mat/n5442_eeg.mat 1069
+../../mat/n5451_eeg.mat 1069
+../../mat/n5453_eeg.mat 1069
+../../mat/n5462_eeg.mat 1067
diff --git a/data/shhs_meta_data/train_list.txt b/data/shhs_meta_data/train_list.txt
new file mode 100644
index 0000000000000000000000000000000000000000..64e42cdc3bfe594ea10c2d9ff969643b67cedd86
--- /dev/null
+++ b/data/shhs_meta_data/train_list.txt
@@ -0,0 +1,3724 @@
+../../mat/n0001_eeg.mat 1081
+../../mat/n0003_eeg.mat 1049
+../../mat/n0004_eeg.mat 865
+../../mat/n0005_eeg.mat 1084
+../../mat/n0008_eeg.mat 959
+../../mat/n0011_eeg.mat 989
+../../mat/n0012_eeg.mat 964
+../../mat/n0014_eeg.mat 959
+../../mat/n0015_eeg.mat 1086
+../../mat/n0016_eeg.mat 950
+../../mat/n0017_eeg.mat 1084
+../../mat/n0018_eeg.mat 734
+../../mat/n0019_eeg.mat 819
+../../mat/n0020_eeg.mat 1072
+../../mat/n0021_eeg.mat 1079
+../../mat/n0023_eeg.mat 929
+../../mat/n0024_eeg.mat 899
+../../mat/n0025_eeg.mat 1076
+../../mat/n0026_eeg.mat 987
+../../mat/n0027_eeg.mat 924
+../../mat/n0028_eeg.mat 1080
+../../mat/n0030_eeg.mat 940
+../../mat/n0031_eeg.mat 966
+../../mat/n0032_eeg.mat 336
+../../mat/n0033_eeg.mat 869
+../../mat/n0034_eeg.mat 1084
+../../mat/n0036_eeg.mat 938
+../../mat/n0040_eeg.mat 1016
+../../mat/n0041_eeg.mat 1080
+../../mat/n0042_eeg.mat 839
+../../mat/n0044_eeg.mat 1045
+../../mat/n0045_eeg.mat 1084
+../../mat/n0046_eeg.mat 959
+../../mat/n0047_eeg.mat 970
+../../mat/n0048_eeg.mat 1084
+../../mat/n0049_eeg.mat 1086
+../../mat/n0051_eeg.mat 1019
+../../mat/n0053_eeg.mat 948
+../../mat/n0055_eeg.mat 1016
+../../mat/n0056_eeg.mat 1084
+../../mat/n0057_eeg.mat 1084
+../../mat/n0058_eeg.mat 747
+../../mat/n0059_eeg.mat 1085
+../../mat/n0061_eeg.mat 838
+../../mat/n0062_eeg.mat 1084
+../../mat/n0063_eeg.mat 973
+../../mat/n0064_eeg.mat 1086
+../../mat/n0066_eeg.mat 873
+../../mat/n0068_eeg.mat 1084
+../../mat/n0069_eeg.mat 1080
+../../mat/n0070_eeg.mat 1086
+../../mat/n0072_eeg.mat 1019
+../../mat/n0073_eeg.mat 859
+../../mat/n0074_eeg.mat 1069
+../../mat/n0075_eeg.mat 1069
+../../mat/n0077_eeg.mat 959
+../../mat/n0078_eeg.mat 975
+../../mat/n0079_eeg.mat 1067
+../../mat/n0080_eeg.mat 1069
+../../mat/n0081_eeg.mat 839
+../../mat/n0082_eeg.mat 1053
+../../mat/n0083_eeg.mat 719
+../../mat/n0085_eeg.mat 913
+../../mat/n0087_eeg.mat 959
+../../mat/n0089_eeg.mat 901
+../../mat/n0090_eeg.mat 987
+../../mat/n0091_eeg.mat 924
+../../mat/n0092_eeg.mat 899
+../../mat/n0094_eeg.mat 636
+../../mat/n0095_eeg.mat 908
+../../mat/n0096_eeg.mat 841
+../../mat/n0097_eeg.mat 1056
+../../mat/n0098_eeg.mat 1039
+../../mat/n0099_eeg.mat 961
+../../mat/n0100_eeg.mat 607
+../../mat/n0101_eeg.mat 1049
+../../mat/n0102_eeg.mat 959
+../../mat/n0104_eeg.mat 1051
+../../mat/n0105_eeg.mat 899
+../../mat/n0106_eeg.mat 605
+../../mat/n0107_eeg.mat 1069
+../../mat/n0109_eeg.mat 1019
+../../mat/n0110_eeg.mat 899
+../../mat/n0111_eeg.mat 1053
+../../mat/n0112_eeg.mat 1067
+../../mat/n0113_eeg.mat 1084
+../../mat/n0116_eeg.mat 978
+../../mat/n0119_eeg.mat 1015
+../../mat/n0120_eeg.mat 1069
+../../mat/n0122_eeg.mat 1022
+../../mat/n0124_eeg.mat 1067
+../../mat/n0125_eeg.mat 1069
+../../mat/n0126_eeg.mat 927
+../../mat/n0129_eeg.mat 1069
+../../mat/n0132_eeg.mat 959
+../../mat/n0134_eeg.mat 959
+../../mat/n0135_eeg.mat 919
+../../mat/n0136_eeg.mat 934
+../../mat/n0137_eeg.mat 1049
+../../mat/n0138_eeg.mat 1069
+../../mat/n0140_eeg.mat 1069
+../../mat/n0141_eeg.mat 1018
+../../mat/n0143_eeg.mat 1069
+../../mat/n0144_eeg.mat 1069
+../../mat/n0145_eeg.mat 804
+../../mat/n0146_eeg.mat 1067
+../../mat/n0148_eeg.mat 849
+../../mat/n0149_eeg.mat 1069
+../../mat/n0151_eeg.mat 892
+../../mat/n0153_eeg.mat 787
+../../mat/n0154_eeg.mat 971
+../../mat/n0156_eeg.mat 959
+../../mat/n0157_eeg.mat 889
+../../mat/n0158_eeg.mat 1049
+../../mat/n0160_eeg.mat 1019
+../../mat/n0161_eeg.mat 1067
+../../mat/n0164_eeg.mat 779
+../../mat/n0165_eeg.mat 964
+../../mat/n0166_eeg.mat 1069
+../../mat/n0167_eeg.mat 899
+../../mat/n0170_eeg.mat 1049
+../../mat/n0171_eeg.mat 1044
+../../mat/n0172_eeg.mat 985
+../../mat/n0173_eeg.mat 809
+../../mat/n0174_eeg.mat 1069
+../../mat/n0175_eeg.mat 959
+../../mat/n0177_eeg.mat 1069
+../../mat/n0179_eeg.mat 1025
+../../mat/n0180_eeg.mat 959
+../../mat/n0181_eeg.mat 957
+../../mat/n0182_eeg.mat 702
+../../mat/n0185_eeg.mat 1069
+../../mat/n0186_eeg.mat 1069
+../../mat/n0187_eeg.mat 1069
+../../mat/n0188_eeg.mat 1064
+../../mat/n0190_eeg.mat 959
+../../mat/n0192_eeg.mat 931
+../../mat/n0195_eeg.mat 959
+../../mat/n0196_eeg.mat 959
+../../mat/n0197_eeg.mat 899
+../../mat/n0198_eeg.mat 899
+../../mat/n0199_eeg.mat 1019
+../../mat/n0201_eeg.mat 1019
+../../mat/n0203_eeg.mat 967
+../../mat/n0204_eeg.mat 1069
+../../mat/n0205_eeg.mat 1069
+../../mat/n0207_eeg.mat 839
+../../mat/n0208_eeg.mat 1069
+../../mat/n0209_eeg.mat 926
+../../mat/n0210_eeg.mat 858
+../../mat/n0212_eeg.mat 924
+../../mat/n0213_eeg.mat 1019
+../../mat/n0214_eeg.mat 1019
+../../mat/n0215_eeg.mat 1038
+../../mat/n0216_eeg.mat 959
+../../mat/n0222_eeg.mat 960
+../../mat/n0223_eeg.mat 848
+../../mat/n0225_eeg.mat 1086
+../../mat/n0226_eeg.mat 1086
+../../mat/n0228_eeg.mat 959
+../../mat/n0230_eeg.mat 1049
+../../mat/n0231_eeg.mat 1028
+../../mat/n0232_eeg.mat 1021
+../../mat/n0233_eeg.mat 1079
+../../mat/n0234_eeg.mat 958
+../../mat/n0235_eeg.mat 1086
+../../mat/n0237_eeg.mat 981
+../../mat/n0238_eeg.mat 1014
+../../mat/n0239_eeg.mat 1079
+../../mat/n0240_eeg.mat 958
+../../mat/n0241_eeg.mat 1086
+../../mat/n0242_eeg.mat 1084
+../../mat/n0243_eeg.mat 903
+../../mat/n0244_eeg.mat 827
+../../mat/n0246_eeg.mat 1086
+../../mat/n0247_eeg.mat 1019
+../../mat/n0249_eeg.mat 1086
+../../mat/n0251_eeg.mat 999
+../../mat/n0252_eeg.mat 970
+../../mat/n0253_eeg.mat 918
+../../mat/n0254_eeg.mat 982
+../../mat/n0255_eeg.mat 839
+../../mat/n0256_eeg.mat 796
+../../mat/n0258_eeg.mat 883
+../../mat/n0259_eeg.mat 1011
+../../mat/n0260_eeg.mat 975
+../../mat/n0263_eeg.mat 954
+../../mat/n0264_eeg.mat 891
+../../mat/n0265_eeg.mat 1084
+../../mat/n0268_eeg.mat 1056
+../../mat/n0269_eeg.mat 1084
+../../mat/n0270_eeg.mat 1041
+../../mat/n0271_eeg.mat 1003
+../../mat/n0272_eeg.mat 1084
+../../mat/n0273_eeg.mat 959
+../../mat/n0276_eeg.mat 1029
+../../mat/n0277_eeg.mat 907
+../../mat/n0278_eeg.mat 1002
+../../mat/n0279_eeg.mat 961
+../../mat/n0281_eeg.mat 1019
+../../mat/n0282_eeg.mat 959
+../../mat/n0283_eeg.mat 1069
+../../mat/n0284_eeg.mat 959
+../../mat/n0285_eeg.mat 959
+../../mat/n0286_eeg.mat 1067
+../../mat/n0287_eeg.mat 987
+../../mat/n0289_eeg.mat 959
+../../mat/n0292_eeg.mat 959
+../../mat/n0293_eeg.mat 989
+../../mat/n0294_eeg.mat 1069
+../../mat/n0295_eeg.mat 1069
+../../mat/n0296_eeg.mat 1030
+../../mat/n0297_eeg.mat 890
+../../mat/n0298_eeg.mat 968
+../../mat/n0300_eeg.mat 959
+../../mat/n0301_eeg.mat 1067
+../../mat/n0303_eeg.mat 718
+../../mat/n0304_eeg.mat 959
+../../mat/n0305_eeg.mat 1069
+../../mat/n0308_eeg.mat 1005
+../../mat/n0309_eeg.mat 996
+../../mat/n0310_eeg.mat 959
+../../mat/n0312_eeg.mat 1069
+../../mat/n0313_eeg.mat 839
+../../mat/n0315_eeg.mat 1069
+../../mat/n0316_eeg.mat 959
+../../mat/n0317_eeg.mat 892
+../../mat/n0319_eeg.mat 1086
+../../mat/n0324_eeg.mat 959
+../../mat/n0327_eeg.mat 921
+../../mat/n0328_eeg.mat 1001
+../../mat/n0330_eeg.mat 944
+../../mat/n0331_eeg.mat 989
+../../mat/n0333_eeg.mat 933
+../../mat/n0334_eeg.mat 1029
+../../mat/n0335_eeg.mat 1067
+../../mat/n0336_eeg.mat 1069
+../../mat/n0337_eeg.mat 861
+../../mat/n0339_eeg.mat 689
+../../mat/n0340_eeg.mat 1067
+../../mat/n0341_eeg.mat 1019
+../../mat/n0342_eeg.mat 1084
+../../mat/n0343_eeg.mat 911
+../../mat/n0344_eeg.mat 1086
+../../mat/n0345_eeg.mat 887
+../../mat/n0346_eeg.mat 1061
+../../mat/n0347_eeg.mat 983
+../../mat/n0349_eeg.mat 1067
+../../mat/n0350_eeg.mat 1051
+../../mat/n0351_eeg.mat 1069
+../../mat/n0352_eeg.mat 927
+../../mat/n0354_eeg.mat 1085
+../../mat/n0358_eeg.mat 959
+../../mat/n0359_eeg.mat 845
+../../mat/n0360_eeg.mat 1021
+../../mat/n0363_eeg.mat 944
+../../mat/n0364_eeg.mat 1067
+../../mat/n0366_eeg.mat 779
+../../mat/n0367_eeg.mat 776
+../../mat/n0369_eeg.mat 959
+../../mat/n0370_eeg.mat 976
+../../mat/n0372_eeg.mat 989
+../../mat/n0373_eeg.mat 958
+../../mat/n0374_eeg.mat 1068
+../../mat/n0375_eeg.mat 664
+../../mat/n0376_eeg.mat 959
+../../mat/n0377_eeg.mat 1053
+../../mat/n0378_eeg.mat 1069
+../../mat/n0380_eeg.mat 982
+../../mat/n0381_eeg.mat 1069
+../../mat/n0383_eeg.mat 1019
+../../mat/n0384_eeg.mat 899
+../../mat/n0385_eeg.mat 1003
+../../mat/n0386_eeg.mat 1050
+../../mat/n0389_eeg.mat 1051
+../../mat/n0396_eeg.mat 839
+../../mat/n0397_eeg.mat 837
+../../mat/n0398_eeg.mat 987
+../../mat/n0399_eeg.mat 1069
+../../mat/n0402_eeg.mat 994
+../../mat/n0403_eeg.mat 1049
+../../mat/n0404_eeg.mat 859
+../../mat/n0405_eeg.mat 647
+../../mat/n0406_eeg.mat 944
+../../mat/n0407_eeg.mat 839
+../../mat/n0408_eeg.mat 1069
+../../mat/n0409_eeg.mat 1069
+../../mat/n0410_eeg.mat 959
+../../mat/n0411_eeg.mat 887
+../../mat/n0412_eeg.mat 1049
+../../mat/n0414_eeg.mat 1067
+../../mat/n0415_eeg.mat 980
+../../mat/n0416_eeg.mat 856
+../../mat/n0417_eeg.mat 899
+../../mat/n0418_eeg.mat 1067
+../../mat/n0419_eeg.mat 959
+../../mat/n0424_eeg.mat 901
+../../mat/n0425_eeg.mat 986
+../../mat/n0426_eeg.mat 1019
+../../mat/n0427_eeg.mat 1067
+../../mat/n0428_eeg.mat 1025
+../../mat/n0429_eeg.mat 880
+../../mat/n0430_eeg.mat 1049
+../../mat/n0431_eeg.mat 779
+../../mat/n0432_eeg.mat 929
+../../mat/n0433_eeg.mat 996
+../../mat/n0434_eeg.mat 1062
+../../mat/n0435_eeg.mat 1045
+../../mat/n0436_eeg.mat 1069
+../../mat/n0437_eeg.mat 1053
+../../mat/n0439_eeg.mat 958
+../../mat/n0440_eeg.mat 1049
+../../mat/n0441_eeg.mat 1049
+../../mat/n0444_eeg.mat 1019
+../../mat/n0445_eeg.mat 1019
+../../mat/n0446_eeg.mat 1069
+../../mat/n0447_eeg.mat 872
+../../mat/n0448_eeg.mat 1053
+../../mat/n0449_eeg.mat 1069
+../../mat/n0450_eeg.mat 1067
+../../mat/n0451_eeg.mat 1069
+../../mat/n0452_eeg.mat 1019
+../../mat/n0454_eeg.mat 996
+../../mat/n0455_eeg.mat 645
+../../mat/n0458_eeg.mat 959
+../../mat/n0459_eeg.mat 959
+../../mat/n0464_eeg.mat 929
+../../mat/n0465_eeg.mat 959
+../../mat/n0467_eeg.mat 989
+../../mat/n0468_eeg.mat 1049
+../../mat/n0470_eeg.mat 1019
+../../mat/n0471_eeg.mat 1067
+../../mat/n0472_eeg.mat 989
+../../mat/n0473_eeg.mat 987
+../../mat/n0475_eeg.mat 1069
+../../mat/n0476_eeg.mat 1069
+../../mat/n0477_eeg.mat 1019
+../../mat/n0478_eeg.mat 959
+../../mat/n0479_eeg.mat 1067
+../../mat/n0480_eeg.mat 894
+../../mat/n0484_eeg.mat 1067
+../../mat/n0485_eeg.mat 1018
+../../mat/n0486_eeg.mat 973
+../../mat/n0487_eeg.mat 959
+../../mat/n0489_eeg.mat 1053
+../../mat/n0490_eeg.mat 1040
+../../mat/n0491_eeg.mat 1084
+../../mat/n0494_eeg.mat 1037
+../../mat/n0496_eeg.mat 1048
+../../mat/n0497_eeg.mat 1086
+../../mat/n0499_eeg.mat 1086
+../../mat/n0500_eeg.mat 1084
+../../mat/n0503_eeg.mat 1067
+../../mat/n0505_eeg.mat 877
+../../mat/n0506_eeg.mat 1084
+../../mat/n0507_eeg.mat 1005
+../../mat/n0511_eeg.mat 1018
+../../mat/n0512_eeg.mat 1086
+../../mat/n0514_eeg.mat 1084
+../../mat/n0515_eeg.mat 989
+../../mat/n0516_eeg.mat 803
+../../mat/n0517_eeg.mat 929
+../../mat/n0518_eeg.mat 968
+../../mat/n0519_eeg.mat 901
+../../mat/n0522_eeg.mat 899
+../../mat/n0523_eeg.mat 881
+../../mat/n0525_eeg.mat 959
+../../mat/n0526_eeg.mat 1049
+../../mat/n0527_eeg.mat 889
+../../mat/n0528_eeg.mat 953
+../../mat/n0529_eeg.mat 1019
+../../mat/n0532_eeg.mat 1069
+../../mat/n0534_eeg.mat 868
+../../mat/n0537_eeg.mat 779
+../../mat/n0538_eeg.mat 894
+../../mat/n0539_eeg.mat 1067
+../../mat/n0540_eeg.mat 869
+../../mat/n0544_eeg.mat 1069
+../../mat/n0546_eeg.mat 1019
+../../mat/n0547_eeg.mat 1019
+../../mat/n0551_eeg.mat 1049
+../../mat/n0552_eeg.mat 877
+../../mat/n0553_eeg.mat 785
+../../mat/n0555_eeg.mat 1069
+../../mat/n0556_eeg.mat 1019
+../../mat/n0557_eeg.mat 836
+../../mat/n0558_eeg.mat 1069
+../../mat/n0559_eeg.mat 1067
+../../mat/n0560_eeg.mat 1069
+../../mat/n0562_eeg.mat 1019
+../../mat/n0566_eeg.mat 898
+../../mat/n0567_eeg.mat 957
+../../mat/n0571_eeg.mat 899
+../../mat/n0572_eeg.mat 989
+../../mat/n0573_eeg.mat 1037
+../../mat/n0576_eeg.mat 1069
+../../mat/n0577_eeg.mat 1069
+../../mat/n0578_eeg.mat 839
+../../mat/n0579_eeg.mat 1069
+../../mat/n0580_eeg.mat 1039
+../../mat/n0581_eeg.mat 1053
+../../mat/n0582_eeg.mat 959
+../../mat/n0583_eeg.mat 959
+../../mat/n0584_eeg.mat 1067
+../../mat/n0586_eeg.mat 1067
+../../mat/n0588_eeg.mat 951
+../../mat/n0589_eeg.mat 1067
+../../mat/n0590_eeg.mat 1067
+../../mat/n0594_eeg.mat 1048
+../../mat/n0596_eeg.mat 1019
+../../mat/n0598_eeg.mat 1049
+../../mat/n0599_eeg.mat 964
+../../mat/n0600_eeg.mat 962
+../../mat/n0602_eeg.mat 1019
+../../mat/n0603_eeg.mat 912
+../../mat/n0605_eeg.mat 1069
+../../mat/n0607_eeg.mat 1069
+../../mat/n0609_eeg.mat 1053
+../../mat/n0610_eeg.mat 1069
+../../mat/n0613_eeg.mat 1017
+../../mat/n0614_eeg.mat 1021
+../../mat/n0615_eeg.mat 841
+../../mat/n0616_eeg.mat 959
+../../mat/n0617_eeg.mat 959
+../../mat/n0618_eeg.mat 1012
+../../mat/n0620_eeg.mat 779
+../../mat/n0621_eeg.mat 837
+../../mat/n0622_eeg.mat 1013
+../../mat/n0623_eeg.mat 879
+../../mat/n0625_eeg.mat 1019
+../../mat/n0626_eeg.mat 1019
+../../mat/n0630_eeg.mat 899
+../../mat/n0632_eeg.mat 1067
+../../mat/n0633_eeg.mat 775
+../../mat/n0635_eeg.mat 869
+../../mat/n0636_eeg.mat 1050
+../../mat/n0637_eeg.mat 989
+../../mat/n0640_eeg.mat 779
+../../mat/n0641_eeg.mat 959
+../../mat/n0643_eeg.mat 1019
+../../mat/n0645_eeg.mat 1019
+../../mat/n0646_eeg.mat 1053
+../../mat/n0648_eeg.mat 1019
+../../mat/n0649_eeg.mat 1019
+../../mat/n0652_eeg.mat 1049
+../../mat/n0657_eeg.mat 959
+../../mat/n0659_eeg.mat 1067
+../../mat/n0661_eeg.mat 943
+../../mat/n0662_eeg.mat 959
+../../mat/n0663_eeg.mat 779
+../../mat/n0665_eeg.mat 1016
+../../mat/n0666_eeg.mat 954
+../../mat/n0667_eeg.mat 1069
+../../mat/n0668_eeg.mat 1069
+../../mat/n0669_eeg.mat 869
+../../mat/n0670_eeg.mat 1067
+../../mat/n0671_eeg.mat 1019
+../../mat/n0672_eeg.mat 959
+../../mat/n0673_eeg.mat 1065
+../../mat/n0675_eeg.mat 1069
+../../mat/n0676_eeg.mat 1069
+../../mat/n0677_eeg.mat 1003
+../../mat/n0678_eeg.mat 1042
+../../mat/n0681_eeg.mat 838
+../../mat/n0684_eeg.mat 1084
+../../mat/n0686_eeg.mat 1019
+../../mat/n0687_eeg.mat 1069
+../../mat/n0688_eeg.mat 961
+../../mat/n0689_eeg.mat 1069
+../../mat/n0691_eeg.mat 1022
+../../mat/n0692_eeg.mat 1018
+../../mat/n0693_eeg.mat 1069
+../../mat/n0694_eeg.mat 849
+../../mat/n0695_eeg.mat 839
+../../mat/n0698_eeg.mat 594
+../../mat/n0699_eeg.mat 1069
+../../mat/n0701_eeg.mat 899
+../../mat/n0702_eeg.mat 1010
+../../mat/n0703_eeg.mat 1013
+../../mat/n0704_eeg.mat 1053
+../../mat/n0706_eeg.mat 890
+../../mat/n0708_eeg.mat 1019
+../../mat/n0709_eeg.mat 1069
+../../mat/n0710_eeg.mat 1069
+../../mat/n0711_eeg.mat 1069
+../../mat/n0712_eeg.mat 1067
+../../mat/n0713_eeg.mat 1069
+../../mat/n0716_eeg.mat 719
+../../mat/n0718_eeg.mat 1019
+../../mat/n0719_eeg.mat 779
+../../mat/n0722_eeg.mat 1069
+../../mat/n0723_eeg.mat 1067
+../../mat/n0724_eeg.mat 1069
+../../mat/n0725_eeg.mat 1036
+../../mat/n0726_eeg.mat 844
+../../mat/n0727_eeg.mat 1053
+../../mat/n0728_eeg.mat 1019
+../../mat/n0730_eeg.mat 1018
+../../mat/n0731_eeg.mat 950
+../../mat/n0732_eeg.mat 1069
+../../mat/n0733_eeg.mat 1067
+../../mat/n0734_eeg.mat 822
+../../mat/n0735_eeg.mat 839
+../../mat/n0738_eeg.mat 761
+../../mat/n0739_eeg.mat 959
+../../mat/n0740_eeg.mat 959
+../../mat/n0741_eeg.mat 1069
+../../mat/n0743_eeg.mat 967
+../../mat/n0745_eeg.mat 1069
+../../mat/n0748_eeg.mat 1019
+../../mat/n0750_eeg.mat 980
+../../mat/n0751_eeg.mat 1001
+../../mat/n0752_eeg.mat 1000
+../../mat/n0753_eeg.mat 1019
+../../mat/n0754_eeg.mat 1079
+../../mat/n0755_eeg.mat 1084
+../../mat/n0756_eeg.mat 959
+../../mat/n0757_eeg.mat 899
+../../mat/n0760_eeg.mat 959
+../../mat/n0761_eeg.mat 1054
+../../mat/n0762_eeg.mat 809
+../../mat/n0763_eeg.mat 1019
+../../mat/n0764_eeg.mat 1049
+../../mat/n0765_eeg.mat 1069
+../../mat/n0766_eeg.mat 985
+../../mat/n0767_eeg.mat 899
+../../mat/n0768_eeg.mat 1067
+../../mat/n0770_eeg.mat 1069
+../../mat/n0771_eeg.mat 899
+../../mat/n0772_eeg.mat 839
+../../mat/n0773_eeg.mat 825
+../../mat/n0775_eeg.mat 1069
+../../mat/n0776_eeg.mat 959
+../../mat/n0778_eeg.mat 1053
+../../mat/n0779_eeg.mat 1039
+../../mat/n0780_eeg.mat 988
+../../mat/n0782_eeg.mat 1019
+../../mat/n0783_eeg.mat 1069
+../../mat/n0784_eeg.mat 987
+../../mat/n0785_eeg.mat 1069
+../../mat/n0789_eeg.mat 1019
+../../mat/n0790_eeg.mat 1019
+../../mat/n0792_eeg.mat 1069
+../../mat/n0793_eeg.mat 1019
+../../mat/n0794_eeg.mat 1019
+../../mat/n0795_eeg.mat 911
+../../mat/n0796_eeg.mat 959
+../../mat/n0797_eeg.mat 579
+../../mat/n0799_eeg.mat 1069
+../../mat/n0800_eeg.mat 1023
+../../mat/n0801_eeg.mat 959
+../../mat/n0802_eeg.mat 779
+../../mat/n0803_eeg.mat 1069
+../../mat/n0804_eeg.mat 997
+../../mat/n0805_eeg.mat 989
+../../mat/n0806_eeg.mat 1086
+../../mat/n0807_eeg.mat 1069
+../../mat/n0808_eeg.mat 1067
+../../mat/n0810_eeg.mat 1053
+../../mat/n0811_eeg.mat 959
+../../mat/n0812_eeg.mat 839
+../../mat/n0813_eeg.mat 1067
+../../mat/n0817_eeg.mat 1053
+../../mat/n0818_eeg.mat 1053
+../../mat/n0819_eeg.mat 1019
+../../mat/n0820_eeg.mat 1067
+../../mat/n0821_eeg.mat 1069
+../../mat/n0822_eeg.mat 929
+../../mat/n0823_eeg.mat 876
+../../mat/n0824_eeg.mat 1019
+../../mat/n0825_eeg.mat 788
+../../mat/n0827_eeg.mat 1053
+../../mat/n0828_eeg.mat 1069
+../../mat/n0829_eeg.mat 1066
+../../mat/n0832_eeg.mat 1019
+../../mat/n0835_eeg.mat 1019
+../../mat/n0836_eeg.mat 1066
+../../mat/n0840_eeg.mat 1069
+../../mat/n0842_eeg.mat 1041
+../../mat/n0843_eeg.mat 1069
+../../mat/n0845_eeg.mat 1067
+../../mat/n0847_eeg.mat 843
+../../mat/n0849_eeg.mat 730
+../../mat/n0850_eeg.mat 1024
+../../mat/n0852_eeg.mat 1069
+../../mat/n0854_eeg.mat 881
+../../mat/n0855_eeg.mat 1019
+../../mat/n0856_eeg.mat 959
+../../mat/n0857_eeg.mat 957
+../../mat/n0858_eeg.mat 1067
+../../mat/n0859_eeg.mat 923
+../../mat/n0861_eeg.mat 1069
+../../mat/n0862_eeg.mat 1069
+../../mat/n0863_eeg.mat 869
+../../mat/n0864_eeg.mat 809
+../../mat/n0868_eeg.mat 1023
+../../mat/n0870_eeg.mat 1019
+../../mat/n0871_eeg.mat 1069
+../../mat/n0872_eeg.mat 959
+../../mat/n0873_eeg.mat 1069
+../../mat/n0874_eeg.mat 1067
+../../mat/n0877_eeg.mat 909
+../../mat/n0878_eeg.mat 1069
+../../mat/n0881_eeg.mat 1069
+../../mat/n0882_eeg.mat 1069
+../../mat/n0883_eeg.mat 1049
+../../mat/n0884_eeg.mat 1069
+../../mat/n0885_eeg.mat 970
+../../mat/n0886_eeg.mat 1049
+../../mat/n0887_eeg.mat 1069
+../../mat/n0888_eeg.mat 1015
+../../mat/n0890_eeg.mat 1067
+../../mat/n0891_eeg.mat 1069
+../../mat/n0892_eeg.mat 1053
+../../mat/n0894_eeg.mat 959
+../../mat/n0895_eeg.mat 1069
+../../mat/n0896_eeg.mat 959
+../../mat/n0898_eeg.mat 1019
+../../mat/n0899_eeg.mat 886
+../../mat/n0900_eeg.mat 957
+../../mat/n0901_eeg.mat 959
+../../mat/n0902_eeg.mat 1069
+../../mat/n0903_eeg.mat 1067
+../../mat/n0904_eeg.mat 1069
+../../mat/n0907_eeg.mat 1069
+../../mat/n0910_eeg.mat 1069
+../../mat/n0911_eeg.mat 1069
+../../mat/n0912_eeg.mat 869
+../../mat/n0913_eeg.mat 983
+../../mat/n0914_eeg.mat 1053
+../../mat/n0915_eeg.mat 1069
+../../mat/n0916_eeg.mat 941
+../../mat/n0917_eeg.mat 710
+../../mat/n0919_eeg.mat 1049
+../../mat/n0920_eeg.mat 1019
+../../mat/n0923_eeg.mat 993
+../../mat/n0924_eeg.mat 1069
+../../mat/n0925_eeg.mat 779
+../../mat/n0927_eeg.mat 777
+../../mat/n0928_eeg.mat 997
+../../mat/n0929_eeg.mat 1053
+../../mat/n0931_eeg.mat 1019
+../../mat/n0932_eeg.mat 1066
+../../mat/n0933_eeg.mat 1044
+../../mat/n0934_eeg.mat 924
+../../mat/n0935_eeg.mat 923
+../../mat/n0936_eeg.mat 839
+../../mat/n0937_eeg.mat 638
+../../mat/n0938_eeg.mat 959
+../../mat/n0940_eeg.mat 1067
+../../mat/n0941_eeg.mat 957
+../../mat/n0942_eeg.mat 925
+../../mat/n0943_eeg.mat 766
+../../mat/n0944_eeg.mat 1051
+../../mat/n0945_eeg.mat 957
+../../mat/n0946_eeg.mat 952
+../../mat/n0948_eeg.mat 899
+../../mat/n0949_eeg.mat 959
+../../mat/n0950_eeg.mat 1053
+../../mat/n0951_eeg.mat 918
+../../mat/n0953_eeg.mat 906
+../../mat/n0956_eeg.mat 1019
+../../mat/n0957_eeg.mat 839
+../../mat/n0958_eeg.mat 1069
+../../mat/n0959_eeg.mat 1049
+../../mat/n0960_eeg.mat 988
+../../mat/n0961_eeg.mat 1067
+../../mat/n0963_eeg.mat 997
+../../mat/n0965_eeg.mat 1067
+../../mat/n0969_eeg.mat 1053
+../../mat/n0971_eeg.mat 877
+../../mat/n0972_eeg.mat 1069
+../../mat/n0973_eeg.mat 1069
+../../mat/n0975_eeg.mat 837
+../../mat/n0979_eeg.mat 1069
+../../mat/n0980_eeg.mat 1069
+../../mat/n0982_eeg.mat 910
+../../mat/n0984_eeg.mat 1015
+../../mat/n0985_eeg.mat 1069
+../../mat/n0986_eeg.mat 1049
+../../mat/n0987_eeg.mat 1026
+../../mat/n0988_eeg.mat 765
+../../mat/n0991_eeg.mat 1051
+../../mat/n0995_eeg.mat 822
+../../mat/n0996_eeg.mat 974
+../../mat/n0999_eeg.mat 1086
+../../mat/n1001_eeg.mat 1065
+../../mat/n1002_eeg.mat 1053
+../../mat/n1003_eeg.mat 899
+../../mat/n1004_eeg.mat 1069
+../../mat/n1007_eeg.mat 839
+../../mat/n1008_eeg.mat 853
+../../mat/n1009_eeg.mat 1013
+../../mat/n1011_eeg.mat 1069
+../../mat/n1012_eeg.mat 1069
+../../mat/n1013_eeg.mat 1019
+../../mat/n1014_eeg.mat 1084
+../../mat/n1016_eeg.mat 959
+../../mat/n1017_eeg.mat 919
+../../mat/n1018_eeg.mat 1069
+../../mat/n1019_eeg.mat 959
+../../mat/n1022_eeg.mat 1067
+../../mat/n1023_eeg.mat 1033
+../../mat/n1025_eeg.mat 1054
+../../mat/n1027_eeg.mat 899
+../../mat/n1028_eeg.mat 1019
+../../mat/n1029_eeg.mat 959
+../../mat/n1030_eeg.mat 920
+../../mat/n1032_eeg.mat 920
+../../mat/n1034_eeg.mat 1053
+../../mat/n1035_eeg.mat 899
+../../mat/n1036_eeg.mat 899
+../../mat/n1037_eeg.mat 961
+../../mat/n1038_eeg.mat 1053
+../../mat/n1040_eeg.mat 959
+../../mat/n1041_eeg.mat 1069
+../../mat/n1042_eeg.mat 1049
+../../mat/n1044_eeg.mat 1079
+../../mat/n1045_eeg.mat 1051
+../../mat/n1046_eeg.mat 1053
+../../mat/n1049_eeg.mat 899
+../../mat/n1050_eeg.mat 959
+../../mat/n1051_eeg.mat 1019
+../../mat/n1052_eeg.mat 959
+../../mat/n1054_eeg.mat 1006
+../../mat/n1056_eeg.mat 884
+../../mat/n1059_eeg.mat 869
+../../mat/n1060_eeg.mat 1019
+../../mat/n1061_eeg.mat 1011
+../../mat/n1062_eeg.mat 959
+../../mat/n1063_eeg.mat 1069
+../../mat/n1064_eeg.mat 837
+../../mat/n1066_eeg.mat 1023
+../../mat/n1067_eeg.mat 1052
+../../mat/n1069_eeg.mat 1003
+../../mat/n1070_eeg.mat 1069
+../../mat/n1071_eeg.mat 1086
+../../mat/n1072_eeg.mat 831
+../../mat/n1073_eeg.mat 1003
+../../mat/n1074_eeg.mat 1053
+../../mat/n1075_eeg.mat 959
+../../mat/n1076_eeg.mat 881
+../../mat/n1079_eeg.mat 1086
+../../mat/n1081_eeg.mat 990
+../../mat/n1082_eeg.mat 1086
+../../mat/n1083_eeg.mat 983
+../../mat/n1084_eeg.mat 899
+../../mat/n1085_eeg.mat 779
+../../mat/n1086_eeg.mat 1066
+../../mat/n1087_eeg.mat 894
+../../mat/n1090_eeg.mat 927
+../../mat/n1092_eeg.mat 1073
+../../mat/n1094_eeg.mat 1016
+../../mat/n1095_eeg.mat 927
+../../mat/n1096_eeg.mat 779
+../../mat/n1098_eeg.mat 1044
+../../mat/n1100_eeg.mat 1076
+../../mat/n1101_eeg.mat 1086
+../../mat/n1103_eeg.mat 1086
+../../mat/n1105_eeg.mat 1054
+../../mat/n1107_eeg.mat 1083
+../../mat/n1111_eeg.mat 1084
+../../mat/n1112_eeg.mat 906
+../../mat/n1113_eeg.mat 963
+../../mat/n1117_eeg.mat 1086
+../../mat/n1120_eeg.mat 828
+../../mat/n1121_eeg.mat 1019
+../../mat/n1122_eeg.mat 1051
+../../mat/n1123_eeg.mat 839
+../../mat/n1124_eeg.mat 959
+../../mat/n1125_eeg.mat 1019
+../../mat/n1126_eeg.mat 959
+../../mat/n1129_eeg.mat 989
+../../mat/n1130_eeg.mat 1049
+../../mat/n1131_eeg.mat 749
+../../mat/n1133_eeg.mat 899
+../../mat/n1134_eeg.mat 876
+../../mat/n1135_eeg.mat 1051
+../../mat/n1138_eeg.mat 1051
+../../mat/n1139_eeg.mat 1053
+../../mat/n1142_eeg.mat 1053
+../../mat/n1143_eeg.mat 839
+../../mat/n1145_eeg.mat 1019
+../../mat/n1150_eeg.mat 989
+../../mat/n1151_eeg.mat 1053
+../../mat/n1152_eeg.mat 1049
+../../mat/n1153_eeg.mat 939
+../../mat/n1154_eeg.mat 1053
+../../mat/n1155_eeg.mat 989
+../../mat/n1157_eeg.mat 623
+../../mat/n1158_eeg.mat 1019
+../../mat/n1159_eeg.mat 1053
+../../mat/n1163_eeg.mat 1019
+../../mat/n1165_eeg.mat 959
+../../mat/n1167_eeg.mat 1012
+../../mat/n1168_eeg.mat 959
+../../mat/n1169_eeg.mat 1053
+../../mat/n1170_eeg.mat 1053
+../../mat/n1173_eeg.mat 1053
+../../mat/n1175_eeg.mat 989
+../../mat/n1176_eeg.mat 1051
+../../mat/n1179_eeg.mat 1053
+../../mat/n1180_eeg.mat 1051
+../../mat/n1182_eeg.mat 672
+../../mat/n1184_eeg.mat 1053
+../../mat/n1185_eeg.mat 899
+../../mat/n1186_eeg.mat 1053
+../../mat/n1187_eeg.mat 1053
+../../mat/n1188_eeg.mat 1053
+../../mat/n1189_eeg.mat 1019
+../../mat/n1194_eeg.mat 620
+../../mat/n1195_eeg.mat 959
+../../mat/n1197_eeg.mat 1051
+../../mat/n1198_eeg.mat 958
+../../mat/n1199_eeg.mat 1053
+../../mat/n1200_eeg.mat 1053
+../../mat/n1201_eeg.mat 1053
+../../mat/n1203_eeg.mat 1053
+../../mat/n1205_eeg.mat 989
+../../mat/n1206_eeg.mat 909
+../../mat/n1207_eeg.mat 1049
+../../mat/n1210_eeg.mat 1009
+../../mat/n1212_eeg.mat 1048
+../../mat/n1213_eeg.mat 1053
+../../mat/n1215_eeg.mat 1050
+../../mat/n1216_eeg.mat 989
+../../mat/n1217_eeg.mat 899
+../../mat/n1218_eeg.mat 1053
+../../mat/n1219_eeg.mat 1053
+../../mat/n1221_eeg.mat 1051
+../../mat/n1222_eeg.mat 1053
+../../mat/n1223_eeg.mat 901
+../../mat/n1225_eeg.mat 1053
+../../mat/n1228_eeg.mat 989
+../../mat/n1230_eeg.mat 1053
+../../mat/n1233_eeg.mat 1053
+../../mat/n1234_eeg.mat 989
+../../mat/n1235_eeg.mat 809
+../../mat/n1238_eeg.mat 1053
+../../mat/n1239_eeg.mat 1053
+../../mat/n1240_eeg.mat 1049
+../../mat/n1241_eeg.mat 1053
+../../mat/n1242_eeg.mat 719
+../../mat/n1243_eeg.mat 1053
+../../mat/n1244_eeg.mat 899
+../../mat/n1246_eeg.mat 869
+../../mat/n1247_eeg.mat 839
+../../mat/n1248_eeg.mat 1053
+../../mat/n1250_eeg.mat 1053
+../../mat/n1251_eeg.mat 1051
+../../mat/n1252_eeg.mat 959
+../../mat/n1253_eeg.mat 1053
+../../mat/n1254_eeg.mat 929
+../../mat/n1255_eeg.mat 1053
+../../mat/n1256_eeg.mat 690
+../../mat/n1257_eeg.mat 1053
+../../mat/n1263_eeg.mat 839
+../../mat/n1266_eeg.mat 1052
+../../mat/n1267_eeg.mat 1053
+../../mat/n1268_eeg.mat 1050
+../../mat/n1269_eeg.mat 899
+../../mat/n1271_eeg.mat 1053
+../../mat/n1272_eeg.mat 1053
+../../mat/n1273_eeg.mat 649
+../../mat/n1274_eeg.mat 1051
+../../mat/n1275_eeg.mat 979
+../../mat/n1276_eeg.mat 1053
+../../mat/n1277_eeg.mat 1053
+../../mat/n1279_eeg.mat 1053
+../../mat/n1280_eeg.mat 1053
+../../mat/n1281_eeg.mat 899
+../../mat/n1282_eeg.mat 841
+../../mat/n1283_eeg.mat 919
+../../mat/n1284_eeg.mat 1051
+../../mat/n1285_eeg.mat 1053
+../../mat/n1287_eeg.mat 1053
+../../mat/n1289_eeg.mat 1043
+../../mat/n1292_eeg.mat 987
+../../mat/n1293_eeg.mat 868
+../../mat/n1295_eeg.mat 1040
+../../mat/n1297_eeg.mat 1019
+../../mat/n1298_eeg.mat 1053
+../../mat/n1299_eeg.mat 1052
+../../mat/n1300_eeg.mat 749
+../../mat/n1302_eeg.mat 843
+../../mat/n1303_eeg.mat 1053
+../../mat/n1305_eeg.mat 1050
+../../mat/n1306_eeg.mat 1019
+../../mat/n1307_eeg.mat 1049
+../../mat/n1308_eeg.mat 899
+../../mat/n1310_eeg.mat 1051
+../../mat/n1312_eeg.mat 1051
+../../mat/n1313_eeg.mat 1053
+../../mat/n1314_eeg.mat 840
+../../mat/n1315_eeg.mat 959
+../../mat/n1316_eeg.mat 1052
+../../mat/n1317_eeg.mat 1053
+../../mat/n1318_eeg.mat 1053
+../../mat/n1320_eeg.mat 1051
+../../mat/n1321_eeg.mat 959
+../../mat/n1322_eeg.mat 1051
+../../mat/n1323_eeg.mat 1049
+../../mat/n1324_eeg.mat 1053
+../../mat/n1325_eeg.mat 807
+../../mat/n1329_eeg.mat 1051
+../../mat/n1331_eeg.mat 931
+../../mat/n1332_eeg.mat 1019
+../../mat/n1333_eeg.mat 1053
+../../mat/n1334_eeg.mat 1053
+../../mat/n1335_eeg.mat 1048
+../../mat/n1336_eeg.mat 1053
+../../mat/n1337_eeg.mat 989
+../../mat/n1338_eeg.mat 927
+../../mat/n1340_eeg.mat 1008
+../../mat/n1342_eeg.mat 899
+../../mat/n1343_eeg.mat 959
+../../mat/n1344_eeg.mat 1019
+../../mat/n1346_eeg.mat 1053
+../../mat/n1347_eeg.mat 959
+../../mat/n1349_eeg.mat 779
+../../mat/n1351_eeg.mat 1053
+../../mat/n1352_eeg.mat 1079
+../../mat/n1357_eeg.mat 978
+../../mat/n1360_eeg.mat 1053
+../../mat/n1361_eeg.mat 929
+../../mat/n1362_eeg.mat 888
+../../mat/n1363_eeg.mat 928
+../../mat/n1364_eeg.mat 989
+../../mat/n1365_eeg.mat 1051
+../../mat/n1366_eeg.mat 1049
+../../mat/n1367_eeg.mat 1051
+../../mat/n1368_eeg.mat 839
+../../mat/n1371_eeg.mat 959
+../../mat/n1373_eeg.mat 927
+../../mat/n1377_eeg.mat 847
+../../mat/n1378_eeg.mat 824
+../../mat/n1379_eeg.mat 1053
+../../mat/n1380_eeg.mat 1049
+../../mat/n1382_eeg.mat 1051
+../../mat/n1383_eeg.mat 1053
+../../mat/n1384_eeg.mat 1053
+../../mat/n1385_eeg.mat 1051
+../../mat/n1386_eeg.mat 1019
+../../mat/n1387_eeg.mat 899
+../../mat/n1388_eeg.mat 1053
+../../mat/n1389_eeg.mat 721
+../../mat/n1390_eeg.mat 1053
+../../mat/n1393_eeg.mat 1051
+../../mat/n1396_eeg.mat 1053
+../../mat/n1398_eeg.mat 1052
+../../mat/n1399_eeg.mat 1051
+../../mat/n1400_eeg.mat 1053
+../../mat/n1401_eeg.mat 1053
+../../mat/n1402_eeg.mat 1051
+../../mat/n1403_eeg.mat 1051
+../../mat/n1406_eeg.mat 989
+../../mat/n1408_eeg.mat 1019
+../../mat/n1409_eeg.mat 898
+../../mat/n1410_eeg.mat 1049
+../../mat/n1412_eeg.mat 1053
+../../mat/n1413_eeg.mat 899
+../../mat/n1416_eeg.mat 959
+../../mat/n1417_eeg.mat 989
+../../mat/n1418_eeg.mat 685
+../../mat/n1419_eeg.mat 1053
+../../mat/n1422_eeg.mat 1019
+../../mat/n1424_eeg.mat 1051
+../../mat/n1426_eeg.mat 1053
+../../mat/n1427_eeg.mat 1019
+../../mat/n1428_eeg.mat 897
+../../mat/n1429_eeg.mat 853
+../../mat/n1430_eeg.mat 977
+../../mat/n1431_eeg.mat 1053
+../../mat/n1432_eeg.mat 959
+../../mat/n1433_eeg.mat 1053
+../../mat/n1436_eeg.mat 769
+../../mat/n1437_eeg.mat 1053
+../../mat/n1438_eeg.mat 1053
+../../mat/n1439_eeg.mat 1053
+../../mat/n1440_eeg.mat 839
+../../mat/n1441_eeg.mat 1053
+../../mat/n1443_eeg.mat 989
+../../mat/n1446_eeg.mat 899
+../../mat/n1447_eeg.mat 1053
+../../mat/n1448_eeg.mat 1053
+../../mat/n1450_eeg.mat 989
+../../mat/n1451_eeg.mat 1053
+../../mat/n1452_eeg.mat 929
+../../mat/n1453_eeg.mat 1053
+../../mat/n1454_eeg.mat 1084
+../../mat/n1455_eeg.mat 1079
+../../mat/n1456_eeg.mat 1084
+../../mat/n1458_eeg.mat 1072
+../../mat/n1459_eeg.mat 1086
+../../mat/n1460_eeg.mat 1023
+../../mat/n1461_eeg.mat 1028
+../../mat/n1463_eeg.mat 1086
+../../mat/n1465_eeg.mat 948
+../../mat/n1466_eeg.mat 1086
+../../mat/n1467_eeg.mat 934
+../../mat/n1469_eeg.mat 1084
+../../mat/n1470_eeg.mat 1040
+../../mat/n1471_eeg.mat 1084
+../../mat/n1473_eeg.mat 1086
+../../mat/n1474_eeg.mat 1084
+../../mat/n1475_eeg.mat 1086
+../../mat/n1476_eeg.mat 1084
+../../mat/n1477_eeg.mat 1084
+../../mat/n1478_eeg.mat 1084
+../../mat/n1480_eeg.mat 1086
+../../mat/n1481_eeg.mat 984
+../../mat/n1482_eeg.mat 1086
+../../mat/n1485_eeg.mat 1051
+../../mat/n1486_eeg.mat 882
+../../mat/n1488_eeg.mat 1052
+../../mat/n1489_eeg.mat 1051
+../../mat/n1490_eeg.mat 1053
+../../mat/n1491_eeg.mat 1053
+../../mat/n1492_eeg.mat 842
+../../mat/n1493_eeg.mat 997
+../../mat/n1494_eeg.mat 929
+../../mat/n1495_eeg.mat 983
+../../mat/n1496_eeg.mat 1051
+../../mat/n1497_eeg.mat 1053
+../../mat/n1498_eeg.mat 1053
+../../mat/n1499_eeg.mat 959
+../../mat/n1501_eeg.mat 1019
+../../mat/n1502_eeg.mat 882
+../../mat/n1504_eeg.mat 989
+../../mat/n1505_eeg.mat 1051
+../../mat/n1506_eeg.mat 1053
+../../mat/n1507_eeg.mat 756
+../../mat/n1508_eeg.mat 929
+../../mat/n1511_eeg.mat 959
+../../mat/n1512_eeg.mat 1053
+../../mat/n1513_eeg.mat 1053
+../../mat/n1515_eeg.mat 1053
+../../mat/n1516_eeg.mat 1019
+../../mat/n1517_eeg.mat 1053
+../../mat/n1518_eeg.mat 1053
+../../mat/n1519_eeg.mat 1044
+../../mat/n1520_eeg.mat 1053
+../../mat/n1523_eeg.mat 872
+../../mat/n1526_eeg.mat 959
+../../mat/n1527_eeg.mat 877
+../../mat/n1530_eeg.mat 1053
+../../mat/n1532_eeg.mat 1051
+../../mat/n1533_eeg.mat 959
+../../mat/n1534_eeg.mat 959
+../../mat/n1535_eeg.mat 1053
+../../mat/n1536_eeg.mat 896
+../../mat/n1537_eeg.mat 966
+../../mat/n1538_eeg.mat 1053
+../../mat/n1539_eeg.mat 1053
+../../mat/n1543_eeg.mat 834
+../../mat/n1544_eeg.mat 1053
+../../mat/n1546_eeg.mat 1053
+../../mat/n1547_eeg.mat 1053
+../../mat/n1548_eeg.mat 1051
+../../mat/n1549_eeg.mat 1019
+../../mat/n1550_eeg.mat 899
+../../mat/n1551_eeg.mat 1051
+../../mat/n1552_eeg.mat 1051
+../../mat/n1553_eeg.mat 931
+../../mat/n1554_eeg.mat 950
+../../mat/n1555_eeg.mat 1052
+../../mat/n1556_eeg.mat 1053
+../../mat/n1557_eeg.mat 1053
+../../mat/n1558_eeg.mat 1051
+../../mat/n1559_eeg.mat 1049
+../../mat/n1560_eeg.mat 1053
+../../mat/n1561_eeg.mat 1051
+../../mat/n1562_eeg.mat 899
+../../mat/n1563_eeg.mat 839
+../../mat/n1566_eeg.mat 1053
+../../mat/n1567_eeg.mat 959
+../../mat/n1569_eeg.mat 1019
+../../mat/n1570_eeg.mat 1053
+../../mat/n1571_eeg.mat 927
+../../mat/n1573_eeg.mat 593
+../../mat/n1574_eeg.mat 1053
+../../mat/n1575_eeg.mat 1053
+../../mat/n1576_eeg.mat 989
+../../mat/n1577_eeg.mat 1051
+../../mat/n1578_eeg.mat 1049
+../../mat/n1584_eeg.mat 1053
+../../mat/n1585_eeg.mat 1053
+../../mat/n1587_eeg.mat 989
+../../mat/n1588_eeg.mat 989
+../../mat/n1589_eeg.mat 1019
+../../mat/n1590_eeg.mat 1051
+../../mat/n1591_eeg.mat 1053
+../../mat/n1592_eeg.mat 1053
+../../mat/n1593_eeg.mat 899
+../../mat/n1594_eeg.mat 1086
+../../mat/n1595_eeg.mat 959
+../../mat/n1596_eeg.mat 1019
+../../mat/n1597_eeg.mat 1084
+../../mat/n1598_eeg.mat 1062
+../../mat/n1599_eeg.mat 824
+../../mat/n1601_eeg.mat 959
+../../mat/n1602_eeg.mat 965
+../../mat/n1603_eeg.mat 975
+../../mat/n1604_eeg.mat 1081
+../../mat/n1605_eeg.mat 913
+../../mat/n1606_eeg.mat 720
+../../mat/n1607_eeg.mat 1019
+../../mat/n1609_eeg.mat 719
+../../mat/n1610_eeg.mat 708
+../../mat/n1611_eeg.mat 849
+../../mat/n1614_eeg.mat 1019
+../../mat/n1615_eeg.mat 1060
+../../mat/n1616_eeg.mat 852
+../../mat/n1617_eeg.mat 965
+../../mat/n1618_eeg.mat 916
+../../mat/n1619_eeg.mat 929
+../../mat/n1620_eeg.mat 977
+../../mat/n1621_eeg.mat 1084
+../../mat/n1622_eeg.mat 962
+../../mat/n1623_eeg.mat 994
+../../mat/n1625_eeg.mat 959
+../../mat/n1626_eeg.mat 899
+../../mat/n1627_eeg.mat 1058
+../../mat/n1629_eeg.mat 899
+../../mat/n1632_eeg.mat 973
+../../mat/n1634_eeg.mat 1085
+../../mat/n1635_eeg.mat 1052
+../../mat/n1636_eeg.mat 869
+../../mat/n1637_eeg.mat 962
+../../mat/n1640_eeg.mat 1019
+../../mat/n1641_eeg.mat 796
+../../mat/n1643_eeg.mat 1086
+../../mat/n1645_eeg.mat 1086
+../../mat/n1646_eeg.mat 935
+../../mat/n1649_eeg.mat 959
+../../mat/n1653_eeg.mat 983
+../../mat/n1654_eeg.mat 1086
+../../mat/n1655_eeg.mat 969
+../../mat/n1656_eeg.mat 1079
+../../mat/n1658_eeg.mat 1084
+../../mat/n1659_eeg.mat 832
+../../mat/n1660_eeg.mat 1053
+../../mat/n1662_eeg.mat 899
+../../mat/n1665_eeg.mat 959
+../../mat/n1668_eeg.mat 1053
+../../mat/n1669_eeg.mat 1049
+../../mat/n1670_eeg.mat 1051
+../../mat/n1671_eeg.mat 1053
+../../mat/n1675_eeg.mat 678
+../../mat/n1676_eeg.mat 1084
+../../mat/n1677_eeg.mat 689
+../../mat/n1678_eeg.mat 898
+../../mat/n1679_eeg.mat 719
+../../mat/n1681_eeg.mat 771
+../../mat/n1684_eeg.mat 979
+../../mat/n1685_eeg.mat 1084
+../../mat/n1686_eeg.mat 1076
+../../mat/n1688_eeg.mat 1076
+../../mat/n1689_eeg.mat 1019
+../../mat/n1690_eeg.mat 979
+../../mat/n1691_eeg.mat 922
+../../mat/n1692_eeg.mat 869
+../../mat/n1693_eeg.mat 929
+../../mat/n1694_eeg.mat 1086
+../../mat/n1695_eeg.mat 1086
+../../mat/n1696_eeg.mat 1043
+../../mat/n1699_eeg.mat 863
+../../mat/n1700_eeg.mat 893
+../../mat/n1704_eeg.mat 869
+../../mat/n1705_eeg.mat 1019
+../../mat/n1707_eeg.mat 1056
+../../mat/n1709_eeg.mat 1010
+../../mat/n1711_eeg.mat 959
+../../mat/n1712_eeg.mat 899
+../../mat/n1714_eeg.mat 959
+../../mat/n1716_eeg.mat 1053
+../../mat/n1717_eeg.mat 959
+../../mat/n1718_eeg.mat 1019
+../../mat/n1720_eeg.mat 1056
+../../mat/n1723_eeg.mat 1002
+../../mat/n1724_eeg.mat 1053
+../../mat/n1725_eeg.mat 1053
+../../mat/n1729_eeg.mat 741
+../../mat/n1730_eeg.mat 899
+../../mat/n1731_eeg.mat 1051
+../../mat/n1733_eeg.mat 1053
+../../mat/n1734_eeg.mat 1052
+../../mat/n1735_eeg.mat 959
+../../mat/n1736_eeg.mat 1054
+../../mat/n1737_eeg.mat 973
+../../mat/n1740_eeg.mat 899
+../../mat/n1741_eeg.mat 989
+../../mat/n1743_eeg.mat 1053
+../../mat/n1747_eeg.mat 959
+../../mat/n1748_eeg.mat 1028
+../../mat/n1749_eeg.mat 1051
+../../mat/n1750_eeg.mat 1018
+../../mat/n1751_eeg.mat 929
+../../mat/n1753_eeg.mat 845
+../../mat/n1755_eeg.mat 1086
+../../mat/n1756_eeg.mat 958
+../../mat/n1758_eeg.mat 983
+../../mat/n1759_eeg.mat 1056
+../../mat/n1761_eeg.mat 1019
+../../mat/n1762_eeg.mat 1019
+../../mat/n1763_eeg.mat 839
+../../mat/n1764_eeg.mat 1051
+../../mat/n1765_eeg.mat 1069
+../../mat/n1766_eeg.mat 1053
+../../mat/n1767_eeg.mat 1053
+../../mat/n1768_eeg.mat 959
+../../mat/n1769_eeg.mat 958
+../../mat/n1770_eeg.mat 1053
+../../mat/n1771_eeg.mat 1053
+../../mat/n1772_eeg.mat 959
+../../mat/n1774_eeg.mat 1056
+../../mat/n1775_eeg.mat 809
+../../mat/n1779_eeg.mat 1053
+../../mat/n1780_eeg.mat 839
+../../mat/n1781_eeg.mat 959
+../../mat/n1782_eeg.mat 959
+../../mat/n1783_eeg.mat 1054
+../../mat/n1784_eeg.mat 899
+../../mat/n1785_eeg.mat 1017
+../../mat/n1786_eeg.mat 959
+../../mat/n1787_eeg.mat 1053
+../../mat/n1788_eeg.mat 959
+../../mat/n1790_eeg.mat 899
+../../mat/n1792_eeg.mat 1053
+../../mat/n1795_eeg.mat 706
+../../mat/n1796_eeg.mat 959
+../../mat/n1797_eeg.mat 1042
+../../mat/n1799_eeg.mat 1014
+../../mat/n1800_eeg.mat 899
+../../mat/n1801_eeg.mat 959
+../../mat/n1802_eeg.mat 1051
+../../mat/n1804_eeg.mat 899
+../../mat/n1809_eeg.mat 1049
+../../mat/n1811_eeg.mat 1075
+../../mat/n1812_eeg.mat 1069
+../../mat/n1813_eeg.mat 1051
+../../mat/n1815_eeg.mat 898
+../../mat/n1816_eeg.mat 839
+../../mat/n1817_eeg.mat 898
+../../mat/n1818_eeg.mat 959
+../../mat/n1819_eeg.mat 1056
+../../mat/n1820_eeg.mat 718
+../../mat/n1821_eeg.mat 1053
+../../mat/n1822_eeg.mat 929
+../../mat/n1824_eeg.mat 1017
+../../mat/n1825_eeg.mat 1024
+../../mat/n1826_eeg.mat 959
+../../mat/n1827_eeg.mat 1056
+../../mat/n1828_eeg.mat 869
+../../mat/n1829_eeg.mat 1056
+../../mat/n1830_eeg.mat 1056
+../../mat/n1831_eeg.mat 1056
+../../mat/n1832_eeg.mat 658
+../../mat/n1834_eeg.mat 839
+../../mat/n1835_eeg.mat 1056
+../../mat/n1836_eeg.mat 1019
+../../mat/n1837_eeg.mat 892
+../../mat/n1838_eeg.mat 616
+../../mat/n1839_eeg.mat 1053
+../../mat/n1842_eeg.mat 958
+../../mat/n1844_eeg.mat 1019
+../../mat/n1847_eeg.mat 788
+../../mat/n1848_eeg.mat 1019
+../../mat/n1851_eeg.mat 1019
+../../mat/n1852_eeg.mat 1053
+../../mat/n1853_eeg.mat 958
+../../mat/n1854_eeg.mat 869
+../../mat/n1855_eeg.mat 959
+../../mat/n1857_eeg.mat 989
+../../mat/n1858_eeg.mat 1019
+../../mat/n1862_eeg.mat 965
+../../mat/n1863_eeg.mat 1084
+../../mat/n1864_eeg.mat 1053
+../../mat/n1865_eeg.mat 959
+../../mat/n1866_eeg.mat 923
+../../mat/n1867_eeg.mat 899
+../../mat/n1869_eeg.mat 899
+../../mat/n1871_eeg.mat 677
+../../mat/n1873_eeg.mat 839
+../../mat/n1874_eeg.mat 899
+../../mat/n1875_eeg.mat 1069
+../../mat/n1877_eeg.mat 957
+../../mat/n1878_eeg.mat 1053
+../../mat/n1879_eeg.mat 1054
+../../mat/n1880_eeg.mat 1055
+../../mat/n1881_eeg.mat 779
+../../mat/n1882_eeg.mat 959
+../../mat/n1883_eeg.mat 989
+../../mat/n1884_eeg.mat 989
+../../mat/n1885_eeg.mat 929
+../../mat/n1886_eeg.mat 1054
+../../mat/n1887_eeg.mat 1069
+../../mat/n1888_eeg.mat 1040
+../../mat/n1889_eeg.mat 1056
+../../mat/n1892_eeg.mat 959
+../../mat/n1894_eeg.mat 1056
+../../mat/n1895_eeg.mat 1053
+../../mat/n1896_eeg.mat 779
+../../mat/n1897_eeg.mat 1053
+../../mat/n1899_eeg.mat 1054
+../../mat/n1900_eeg.mat 1053
+../../mat/n1901_eeg.mat 956
+../../mat/n1904_eeg.mat 929
+../../mat/n1905_eeg.mat 959
+../../mat/n1906_eeg.mat 1056
+../../mat/n1908_eeg.mat 1053
+../../mat/n1909_eeg.mat 963
+../../mat/n1910_eeg.mat 779
+../../mat/n1911_eeg.mat 1084
+../../mat/n1912_eeg.mat 1086
+../../mat/n1915_eeg.mat 964
+../../mat/n1917_eeg.mat 1016
+../../mat/n1918_eeg.mat 962
+../../mat/n1919_eeg.mat 787
+../../mat/n1920_eeg.mat 1086
+../../mat/n1921_eeg.mat 954
+../../mat/n1922_eeg.mat 1077
+../../mat/n1923_eeg.mat 1086
+../../mat/n1924_eeg.mat 816
+../../mat/n1928_eeg.mat 1019
+../../mat/n1930_eeg.mat 1018
+../../mat/n1932_eeg.mat 1007
+../../mat/n1933_eeg.mat 1028
+../../mat/n1934_eeg.mat 872
+../../mat/n1936_eeg.mat 886
+../../mat/n1937_eeg.mat 1083
+../../mat/n1940_eeg.mat 1084
+../../mat/n1947_eeg.mat 981
+../../mat/n1948_eeg.mat 959
+../../mat/n1949_eeg.mat 1084
+../../mat/n1950_eeg.mat 1084
+../../mat/n1952_eeg.mat 860
+../../mat/n1954_eeg.mat 976
+../../mat/n1955_eeg.mat 1084
+../../mat/n1956_eeg.mat 1086
+../../mat/n1959_eeg.mat 959
+../../mat/n1961_eeg.mat 1056
+../../mat/n1962_eeg.mat 959
+../../mat/n1964_eeg.mat 1054
+../../mat/n1966_eeg.mat 909
+../../mat/n1967_eeg.mat 959
+../../mat/n1968_eeg.mat 992
+../../mat/n1969_eeg.mat 959
+../../mat/n1970_eeg.mat 1053
+../../mat/n1971_eeg.mat 1019
+../../mat/n1973_eeg.mat 1053
+../../mat/n1974_eeg.mat 1014
+../../mat/n1975_eeg.mat 1053
+../../mat/n1977_eeg.mat 839
+../../mat/n1979_eeg.mat 1053
+../../mat/n1981_eeg.mat 917
+../../mat/n1982_eeg.mat 959
+../../mat/n1983_eeg.mat 1053
+../../mat/n1984_eeg.mat 1051
+../../mat/n1986_eeg.mat 762
+../../mat/n1987_eeg.mat 1053
+../../mat/n1990_eeg.mat 959
+../../mat/n1992_eeg.mat 809
+../../mat/n1993_eeg.mat 989
+../../mat/n1994_eeg.mat 1019
+../../mat/n1995_eeg.mat 1053
+../../mat/n1996_eeg.mat 1053
+../../mat/n1997_eeg.mat 959
+../../mat/n1998_eeg.mat 1053
+../../mat/n1999_eeg.mat 959
+../../mat/n2001_eeg.mat 1056
+../../mat/n2002_eeg.mat 1044
+../../mat/n2003_eeg.mat 958
+../../mat/n2005_eeg.mat 899
+../../mat/n2006_eeg.mat 666
+../../mat/n2007_eeg.mat 899
+../../mat/n2008_eeg.mat 1019
+../../mat/n2011_eeg.mat 1056
+../../mat/n2012_eeg.mat 1053
+../../mat/n2013_eeg.mat 1019
+../../mat/n2014_eeg.mat 869
+../../mat/n2015_eeg.mat 1053
+../../mat/n2017_eeg.mat 928
+../../mat/n2018_eeg.mat 959
+../../mat/n2020_eeg.mat 1053
+../../mat/n2021_eeg.mat 869
+../../mat/n2022_eeg.mat 1053
+../../mat/n2031_eeg.mat 1056
+../../mat/n2032_eeg.mat 899
+../../mat/n2033_eeg.mat 899
+../../mat/n2034_eeg.mat 956
+../../mat/n2035_eeg.mat 959
+../../mat/n2036_eeg.mat 1053
+../../mat/n2037_eeg.mat 1019
+../../mat/n2038_eeg.mat 1019
+../../mat/n2041_eeg.mat 929
+../../mat/n2043_eeg.mat 920
+../../mat/n2044_eeg.mat 959
+../../mat/n2045_eeg.mat 1019
+../../mat/n2047_eeg.mat 779
+../../mat/n2048_eeg.mat 897
+../../mat/n2049_eeg.mat 959
+../../mat/n2050_eeg.mat 959
+../../mat/n2051_eeg.mat 1056
+../../mat/n2052_eeg.mat 1056
+../../mat/n2054_eeg.mat 959
+../../mat/n2055_eeg.mat 1069
+../../mat/n2056_eeg.mat 943
+../../mat/n2057_eeg.mat 1056
+../../mat/n2059_eeg.mat 1056
+../../mat/n2060_eeg.mat 551
+../../mat/n2062_eeg.mat 929
+../../mat/n2064_eeg.mat 1054
+../../mat/n2068_eeg.mat 1019
+../../mat/n2069_eeg.mat 1056
+../../mat/n2070_eeg.mat 959
+../../mat/n2071_eeg.mat 961
+../../mat/n2072_eeg.mat 1019
+../../mat/n2073_eeg.mat 1054
+../../mat/n2074_eeg.mat 1054
+../../mat/n2076_eeg.mat 987
+../../mat/n2077_eeg.mat 959
+../../mat/n2080_eeg.mat 934
+../../mat/n2081_eeg.mat 981
+../../mat/n2082_eeg.mat 996
+../../mat/n2083_eeg.mat 791
+../../mat/n2084_eeg.mat 1085
+../../mat/n2085_eeg.mat 1086
+../../mat/n2087_eeg.mat 1019
+../../mat/n2088_eeg.mat 1086
+../../mat/n2093_eeg.mat 1010
+../../mat/n2094_eeg.mat 1018
+../../mat/n2097_eeg.mat 964
+../../mat/n2098_eeg.mat 823
+../../mat/n2099_eeg.mat 871
+../../mat/n2100_eeg.mat 871
+../../mat/n2101_eeg.mat 1079
+../../mat/n2102_eeg.mat 987
+../../mat/n2104_eeg.mat 985
+../../mat/n2105_eeg.mat 1086
+../../mat/n2106_eeg.mat 959
+../../mat/n2107_eeg.mat 963
+../../mat/n2108_eeg.mat 1000
+../../mat/n2109_eeg.mat 680
+../../mat/n2110_eeg.mat 1020
+../../mat/n2112_eeg.mat 985
+../../mat/n2114_eeg.mat 839
+../../mat/n2115_eeg.mat 997
+../../mat/n2116_eeg.mat 979
+../../mat/n2117_eeg.mat 1065
+../../mat/n2118_eeg.mat 935
+../../mat/n2120_eeg.mat 909
+../../mat/n2123_eeg.mat 839
+../../mat/n2125_eeg.mat 1068
+../../mat/n2126_eeg.mat 986
+../../mat/n2127_eeg.mat 1086
+../../mat/n2129_eeg.mat 951
+../../mat/n2131_eeg.mat 1022
+../../mat/n2134_eeg.mat 1086
+../../mat/n2137_eeg.mat 881
+../../mat/n2139_eeg.mat 1084
+../../mat/n2141_eeg.mat 959
+../../mat/n2144_eeg.mat 1086
+../../mat/n2145_eeg.mat 584
+../../mat/n2148_eeg.mat 979
+../../mat/n2149_eeg.mat 1017
+../../mat/n2150_eeg.mat 1086
+../../mat/n2152_eeg.mat 1086
+../../mat/n2155_eeg.mat 1086
+../../mat/n2156_eeg.mat 839
+../../mat/n2158_eeg.mat 1084
+../../mat/n2159_eeg.mat 1086
+../../mat/n2160_eeg.mat 913
+../../mat/n2161_eeg.mat 1086
+../../mat/n2164_eeg.mat 1019
+../../mat/n2165_eeg.mat 974
+../../mat/n2167_eeg.mat 1019
+../../mat/n2168_eeg.mat 927
+../../mat/n2169_eeg.mat 1086
+../../mat/n2170_eeg.mat 956
+../../mat/n2171_eeg.mat 1084
+../../mat/n2173_eeg.mat 899
+../../mat/n2174_eeg.mat 993
+../../mat/n2175_eeg.mat 949
+../../mat/n2176_eeg.mat 1037
+../../mat/n2177_eeg.mat 610
+../../mat/n2178_eeg.mat 952
+../../mat/n2179_eeg.mat 847
+../../mat/n2180_eeg.mat 929
+../../mat/n2183_eeg.mat 706
+../../mat/n2186_eeg.mat 1084
+../../mat/n2187_eeg.mat 926
+../../mat/n2188_eeg.mat 1079
+../../mat/n2189_eeg.mat 667
+../../mat/n2193_eeg.mat 1053
+../../mat/n2194_eeg.mat 1019
+../../mat/n2195_eeg.mat 929
+../../mat/n2196_eeg.mat 1050
+../../mat/n2197_eeg.mat 888
+../../mat/n2203_eeg.mat 1053
+../../mat/n2204_eeg.mat 839
+../../mat/n2206_eeg.mat 959
+../../mat/n2208_eeg.mat 1051
+../../mat/n2210_eeg.mat 958
+../../mat/n2212_eeg.mat 1053
+../../mat/n2213_eeg.mat 1053
+../../mat/n2214_eeg.mat 1053
+../../mat/n2215_eeg.mat 1053
+../../mat/n2216_eeg.mat 1049
+../../mat/n2217_eeg.mat 929
+../../mat/n2219_eeg.mat 1051
+../../mat/n2220_eeg.mat 1053
+../../mat/n2222_eeg.mat 1021
+../../mat/n2223_eeg.mat 1053
+../../mat/n2224_eeg.mat 959
+../../mat/n2227_eeg.mat 858
+../../mat/n2231_eeg.mat 1039
+../../mat/n2234_eeg.mat 930
+../../mat/n2236_eeg.mat 1019
+../../mat/n2237_eeg.mat 839
+../../mat/n2238_eeg.mat 1051
+../../mat/n2239_eeg.mat 1018
+../../mat/n2241_eeg.mat 959
+../../mat/n2242_eeg.mat 1053
+../../mat/n2243_eeg.mat 899
+../../mat/n2244_eeg.mat 1019
+../../mat/n2245_eeg.mat 929
+../../mat/n2246_eeg.mat 1051
+../../mat/n2249_eeg.mat 1069
+../../mat/n2250_eeg.mat 1019
+../../mat/n2251_eeg.mat 1051
+../../mat/n2252_eeg.mat 1051
+../../mat/n2254_eeg.mat 1019
+../../mat/n2255_eeg.mat 1051
+../../mat/n2257_eeg.mat 1019
+../../mat/n2259_eeg.mat 1051
+../../mat/n2260_eeg.mat 890
+../../mat/n2261_eeg.mat 1053
+../../mat/n2263_eeg.mat 899
+../../mat/n2265_eeg.mat 899
+../../mat/n2268_eeg.mat 959
+../../mat/n2269_eeg.mat 1019
+../../mat/n2271_eeg.mat 1051
+../../mat/n2275_eeg.mat 899
+../../mat/n2276_eeg.mat 1053
+../../mat/n2280_eeg.mat 1019
+../../mat/n2282_eeg.mat 959
+../../mat/n2284_eeg.mat 957
+../../mat/n2285_eeg.mat 1051
+../../mat/n2286_eeg.mat 1051
+../../mat/n2288_eeg.mat 995
+../../mat/n2289_eeg.mat 1051
+../../mat/n2290_eeg.mat 1069
+../../mat/n2291_eeg.mat 719
+../../mat/n2292_eeg.mat 1053
+../../mat/n2293_eeg.mat 894
+../../mat/n2295_eeg.mat 899
+../../mat/n2296_eeg.mat 932
+../../mat/n2300_eeg.mat 1069
+../../mat/n2301_eeg.mat 1067
+../../mat/n2302_eeg.mat 869
+../../mat/n2304_eeg.mat 959
+../../mat/n2305_eeg.mat 1051
+../../mat/n2306_eeg.mat 857
+../../mat/n2307_eeg.mat 1051
+../../mat/n2310_eeg.mat 1017
+../../mat/n2311_eeg.mat 1069
+../../mat/n2313_eeg.mat 1051
+../../mat/n2314_eeg.mat 874
+../../mat/n2317_eeg.mat 1053
+../../mat/n2318_eeg.mat 1069
+../../mat/n2320_eeg.mat 1051
+../../mat/n2321_eeg.mat 869
+../../mat/n2323_eeg.mat 1069
+../../mat/n2326_eeg.mat 959
+../../mat/n2328_eeg.mat 959
+../../mat/n2329_eeg.mat 961
+../../mat/n2330_eeg.mat 1053
+../../mat/n2331_eeg.mat 1053
+../../mat/n2332_eeg.mat 1051
+../../mat/n2333_eeg.mat 959
+../../mat/n2334_eeg.mat 839
+../../mat/n2335_eeg.mat 958
+../../mat/n2336_eeg.mat 1069
+../../mat/n2337_eeg.mat 1069
+../../mat/n2339_eeg.mat 860
+../../mat/n2342_eeg.mat 1053
+../../mat/n2343_eeg.mat 1067
+../../mat/n2345_eeg.mat 959
+../../mat/n2346_eeg.mat 1051
+../../mat/n2348_eeg.mat 837
+../../mat/n2349_eeg.mat 1069
+../../mat/n2351_eeg.mat 1019
+../../mat/n2352_eeg.mat 1019
+../../mat/n2353_eeg.mat 1019
+../../mat/n2354_eeg.mat 1051
+../../mat/n2355_eeg.mat 1053
+../../mat/n2356_eeg.mat 944
+../../mat/n2357_eeg.mat 1053
+../../mat/n2358_eeg.mat 1053
+../../mat/n2360_eeg.mat 897
+../../mat/n2361_eeg.mat 1050
+../../mat/n2362_eeg.mat 1019
+../../mat/n2363_eeg.mat 1062
+../../mat/n2364_eeg.mat 1039
+../../mat/n2366_eeg.mat 1020
+../../mat/n2367_eeg.mat 1051
+../../mat/n2368_eeg.mat 1051
+../../mat/n2369_eeg.mat 1051
+../../mat/n2371_eeg.mat 814
+../../mat/n2372_eeg.mat 1053
+../../mat/n2373_eeg.mat 944
+../../mat/n2374_eeg.mat 928
+../../mat/n2375_eeg.mat 1051
+../../mat/n2377_eeg.mat 1019
+../../mat/n2380_eeg.mat 1051
+../../mat/n2381_eeg.mat 1013
+../../mat/n2383_eeg.mat 899
+../../mat/n2384_eeg.mat 675
+../../mat/n2385_eeg.mat 1019
+../../mat/n2386_eeg.mat 1051
+../../mat/n2387_eeg.mat 901
+../../mat/n2388_eeg.mat 1019
+../../mat/n2389_eeg.mat 899
+../../mat/n2390_eeg.mat 959
+../../mat/n2392_eeg.mat 1019
+../../mat/n2393_eeg.mat 1053
+../../mat/n2397_eeg.mat 957
+../../mat/n2398_eeg.mat 1034
+../../mat/n2399_eeg.mat 997
+../../mat/n2400_eeg.mat 1051
+../../mat/n2401_eeg.mat 1053
+../../mat/n2402_eeg.mat 1065
+../../mat/n2403_eeg.mat 958
+../../mat/n2404_eeg.mat 1069
+../../mat/n2407_eeg.mat 1017
+../../mat/n2408_eeg.mat 1051
+../../mat/n2409_eeg.mat 888
+../../mat/n2410_eeg.mat 839
+../../mat/n2411_eeg.mat 1051
+../../mat/n2414_eeg.mat 897
+../../mat/n2415_eeg.mat 839
+../../mat/n2416_eeg.mat 1069
+../../mat/n2418_eeg.mat 700
+../../mat/n2420_eeg.mat 749
+../../mat/n2422_eeg.mat 899
+../../mat/n2423_eeg.mat 911
+../../mat/n2424_eeg.mat 1053
+../../mat/n2426_eeg.mat 969
+../../mat/n2428_eeg.mat 959
+../../mat/n2430_eeg.mat 719
+../../mat/n2431_eeg.mat 939
+../../mat/n2432_eeg.mat 1053
+../../mat/n2433_eeg.mat 733
+../../mat/n2435_eeg.mat 1053
+../../mat/n2436_eeg.mat 1053
+../../mat/n2437_eeg.mat 897
+../../mat/n2439_eeg.mat 1053
+../../mat/n2442_eeg.mat 1017
+../../mat/n2443_eeg.mat 1019
+../../mat/n2445_eeg.mat 1052
+../../mat/n2447_eeg.mat 1053
+../../mat/n2448_eeg.mat 813
+../../mat/n2449_eeg.mat 959
+../../mat/n2450_eeg.mat 1051
+../../mat/n2452_eeg.mat 1019
+../../mat/n2455_eeg.mat 1069
+../../mat/n2456_eeg.mat 779
+../../mat/n2457_eeg.mat 1019
+../../mat/n2458_eeg.mat 612
+../../mat/n2459_eeg.mat 959
+../../mat/n2460_eeg.mat 1051
+../../mat/n2462_eeg.mat 969
+../../mat/n2464_eeg.mat 959
+../../mat/n2465_eeg.mat 888
+../../mat/n2466_eeg.mat 831
+../../mat/n2468_eeg.mat 1079
+../../mat/n2470_eeg.mat 1079
+../../mat/n2474_eeg.mat 534
+../../mat/n2475_eeg.mat 1078
+../../mat/n2476_eeg.mat 964
+../../mat/n2478_eeg.mat 1060
+../../mat/n2479_eeg.mat 959
+../../mat/n2480_eeg.mat 959
+../../mat/n2481_eeg.mat 1012
+../../mat/n2482_eeg.mat 823
+../../mat/n2483_eeg.mat 718
+../../mat/n2486_eeg.mat 989
+../../mat/n2487_eeg.mat 832
+../../mat/n2488_eeg.mat 989
+../../mat/n2489_eeg.mat 852
+../../mat/n2490_eeg.mat 959
+../../mat/n2492_eeg.mat 978
+../../mat/n2493_eeg.mat 844
+../../mat/n2494_eeg.mat 877
+../../mat/n2495_eeg.mat 840
+../../mat/n2496_eeg.mat 882
+../../mat/n2497_eeg.mat 886
+../../mat/n2498_eeg.mat 1079
+../../mat/n2499_eeg.mat 816
+../../mat/n2501_eeg.mat 1021
+../../mat/n2502_eeg.mat 921
+../../mat/n2503_eeg.mat 1072
+../../mat/n2504_eeg.mat 980
+../../mat/n2505_eeg.mat 1086
+../../mat/n2506_eeg.mat 1086
+../../mat/n2508_eeg.mat 929
+../../mat/n2509_eeg.mat 900
+../../mat/n2511_eeg.mat 828
+../../mat/n2512_eeg.mat 841
+../../mat/n2515_eeg.mat 746
+../../mat/n2516_eeg.mat 899
+../../mat/n2517_eeg.mat 1026
+../../mat/n2518_eeg.mat 970
+../../mat/n2519_eeg.mat 895
+../../mat/n2520_eeg.mat 1086
+../../mat/n2521_eeg.mat 839
+../../mat/n2522_eeg.mat 899
+../../mat/n2523_eeg.mat 895
+../../mat/n2525_eeg.mat 1011
+../../mat/n2528_eeg.mat 1007
+../../mat/n2529_eeg.mat 1086
+../../mat/n2530_eeg.mat 1077
+../../mat/n2532_eeg.mat 1019
+../../mat/n2535_eeg.mat 747
+../../mat/n2536_eeg.mat 936
+../../mat/n2537_eeg.mat 1019
+../../mat/n2538_eeg.mat 660
+../../mat/n2539_eeg.mat 899
+../../mat/n2540_eeg.mat 1086
+../../mat/n2541_eeg.mat 988
+../../mat/n2542_eeg.mat 1086
+../../mat/n2543_eeg.mat 810
+../../mat/n2547_eeg.mat 1085
+../../mat/n2548_eeg.mat 1086
+../../mat/n2549_eeg.mat 972
+../../mat/n2550_eeg.mat 1086
+../../mat/n2551_eeg.mat 908
+../../mat/n2552_eeg.mat 779
+../../mat/n2555_eeg.mat 899
+../../mat/n2556_eeg.mat 1019
+../../mat/n2557_eeg.mat 1013
+../../mat/n2558_eeg.mat 1017
+../../mat/n2559_eeg.mat 1053
+../../mat/n2560_eeg.mat 1053
+../../mat/n2561_eeg.mat 1053
+../../mat/n2562_eeg.mat 1051
+../../mat/n2563_eeg.mat 1053
+../../mat/n2564_eeg.mat 1053
+../../mat/n2565_eeg.mat 899
+../../mat/n2566_eeg.mat 1068
+../../mat/n2569_eeg.mat 839
+../../mat/n2574_eeg.mat 1018
+../../mat/n2577_eeg.mat 1051
+../../mat/n2578_eeg.mat 1051
+../../mat/n2580_eeg.mat 1019
+../../mat/n2583_eeg.mat 1053
+../../mat/n2585_eeg.mat 1051
+../../mat/n2586_eeg.mat 959
+../../mat/n2588_eeg.mat 1012
+../../mat/n2589_eeg.mat 959
+../../mat/n2591_eeg.mat 885
+../../mat/n2592_eeg.mat 839
+../../mat/n2593_eeg.mat 959
+../../mat/n2595_eeg.mat 1053
+../../mat/n2596_eeg.mat 1053
+../../mat/n2603_eeg.mat 911
+../../mat/n2604_eeg.mat 1053
+../../mat/n2605_eeg.mat 899
+../../mat/n2606_eeg.mat 1053
+../../mat/n2607_eeg.mat 1019
+../../mat/n2608_eeg.mat 719
+../../mat/n2610_eeg.mat 1069
+../../mat/n2611_eeg.mat 1019
+../../mat/n2613_eeg.mat 1051
+../../mat/n2614_eeg.mat 959
+../../mat/n2617_eeg.mat 1051
+../../mat/n2618_eeg.mat 1019
+../../mat/n2619_eeg.mat 1065
+../../mat/n2621_eeg.mat 1051
+../../mat/n2622_eeg.mat 1067
+../../mat/n2623_eeg.mat 1069
+../../mat/n2624_eeg.mat 899
+../../mat/n2625_eeg.mat 899
+../../mat/n2626_eeg.mat 1067
+../../mat/n2628_eeg.mat 1051
+../../mat/n2629_eeg.mat 1051
+../../mat/n2630_eeg.mat 1048
+../../mat/n2632_eeg.mat 959
+../../mat/n2633_eeg.mat 1084
+../../mat/n2634_eeg.mat 1000
+../../mat/n2636_eeg.mat 841
+../../mat/n2640_eeg.mat 1084
+../../mat/n2642_eeg.mat 1086
+../../mat/n2644_eeg.mat 1009
+../../mat/n2645_eeg.mat 750
+../../mat/n2646_eeg.mat 1086
+../../mat/n2647_eeg.mat 1086
+../../mat/n2648_eeg.mat 1084
+../../mat/n2650_eeg.mat 899
+../../mat/n2651_eeg.mat 1016
+../../mat/n2653_eeg.mat 995
+../../mat/n2654_eeg.mat 827
+../../mat/n2655_eeg.mat 949
+../../mat/n2656_eeg.mat 830
+../../mat/n2658_eeg.mat 845
+../../mat/n2660_eeg.mat 838
+../../mat/n2661_eeg.mat 1086
+../../mat/n2662_eeg.mat 1009
+../../mat/n2668_eeg.mat 1084
+../../mat/n2669_eeg.mat 821
+../../mat/n2670_eeg.mat 722
+../../mat/n2671_eeg.mat 1019
+../../mat/n2672_eeg.mat 1080
+../../mat/n2673_eeg.mat 1085
+../../mat/n2676_eeg.mat 959
+../../mat/n2679_eeg.mat 840
+../../mat/n2682_eeg.mat 1053
+../../mat/n2683_eeg.mat 1019
+../../mat/n2684_eeg.mat 971
+../../mat/n2685_eeg.mat 1053
+../../mat/n2686_eeg.mat 1053
+../../mat/n2687_eeg.mat 1053
+../../mat/n2689_eeg.mat 899
+../../mat/n2691_eeg.mat 1053
+../../mat/n2692_eeg.mat 1053
+../../mat/n2693_eeg.mat 1053
+../../mat/n2694_eeg.mat 1019
+../../mat/n2695_eeg.mat 1051
+../../mat/n2698_eeg.mat 1051
+../../mat/n2700_eeg.mat 1053
+../../mat/n2701_eeg.mat 1051
+../../mat/n2702_eeg.mat 1053
+../../mat/n2703_eeg.mat 1051
+../../mat/n2704_eeg.mat 1053
+../../mat/n2705_eeg.mat 1048
+../../mat/n2706_eeg.mat 1051
+../../mat/n2707_eeg.mat 1053
+../../mat/n2708_eeg.mat 1040
+../../mat/n2710_eeg.mat 1053
+../../mat/n2712_eeg.mat 872
+../../mat/n2715_eeg.mat 1053
+../../mat/n2718_eeg.mat 866
+../../mat/n2720_eeg.mat 1019
+../../mat/n2721_eeg.mat 1053
+../../mat/n2724_eeg.mat 1037
+../../mat/n2725_eeg.mat 1053
+../../mat/n2727_eeg.mat 691
+../../mat/n2728_eeg.mat 1051
+../../mat/n2729_eeg.mat 1053
+../../mat/n2730_eeg.mat 1053
+../../mat/n2731_eeg.mat 1051
+../../mat/n2732_eeg.mat 1053
+../../mat/n2733_eeg.mat 1053
+../../mat/n2734_eeg.mat 1051
+../../mat/n2735_eeg.mat 1051
+../../mat/n2736_eeg.mat 1053
+../../mat/n2737_eeg.mat 1053
+../../mat/n2739_eeg.mat 1053
+../../mat/n2740_eeg.mat 1053
+../../mat/n2744_eeg.mat 1018
+../../mat/n2746_eeg.mat 1053
+../../mat/n2747_eeg.mat 1053
+../../mat/n2748_eeg.mat 1038
+../../mat/n2749_eeg.mat 959
+../../mat/n2750_eeg.mat 1072
+../../mat/n2752_eeg.mat 1053
+../../mat/n2754_eeg.mat 1051
+../../mat/n2756_eeg.mat 1052
+../../mat/n2757_eeg.mat 997
+../../mat/n2758_eeg.mat 1053
+../../mat/n2759_eeg.mat 1053
+../../mat/n2763_eeg.mat 1053
+../../mat/n2765_eeg.mat 1051
+../../mat/n2766_eeg.mat 989
+../../mat/n2770_eeg.mat 959
+../../mat/n2771_eeg.mat 907
+../../mat/n2773_eeg.mat 1051
+../../mat/n2774_eeg.mat 1053
+../../mat/n2777_eeg.mat 1051
+../../mat/n2778_eeg.mat 1053
+../../mat/n2779_eeg.mat 1053
+../../mat/n2782_eeg.mat 1053
+../../mat/n2783_eeg.mat 1052
+../../mat/n2784_eeg.mat 1019
+../../mat/n2785_eeg.mat 1051
+../../mat/n2786_eeg.mat 1019
+../../mat/n2787_eeg.mat 1025
+../../mat/n2788_eeg.mat 1053
+../../mat/n2789_eeg.mat 1025
+../../mat/n2790_eeg.mat 756
+../../mat/n2791_eeg.mat 1019
+../../mat/n2793_eeg.mat 1051
+../../mat/n2794_eeg.mat 1051
+../../mat/n2795_eeg.mat 1053
+../../mat/n2797_eeg.mat 1043
+../../mat/n2799_eeg.mat 1051
+../../mat/n2800_eeg.mat 1019
+../../mat/n2801_eeg.mat 1051
+../../mat/n2803_eeg.mat 959
+../../mat/n2805_eeg.mat 1053
+../../mat/n2807_eeg.mat 1019
+../../mat/n2808_eeg.mat 1053
+../../mat/n2809_eeg.mat 1018
+../../mat/n2810_eeg.mat 959
+../../mat/n2811_eeg.mat 959
+../../mat/n2812_eeg.mat 1053
+../../mat/n2813_eeg.mat 1053
+../../mat/n2814_eeg.mat 1051
+../../mat/n2816_eeg.mat 1018
+../../mat/n2817_eeg.mat 1053
+../../mat/n2818_eeg.mat 1053
+../../mat/n2819_eeg.mat 972
+../../mat/n2820_eeg.mat 1053
+../../mat/n2824_eeg.mat 839
+../../mat/n2826_eeg.mat 1051
+../../mat/n2828_eeg.mat 1051
+../../mat/n2829_eeg.mat 1019
+../../mat/n2830_eeg.mat 1051
+../../mat/n2833_eeg.mat 1049
+../../mat/n2835_eeg.mat 1047
+../../mat/n2836_eeg.mat 1050
+../../mat/n2838_eeg.mat 1051
+../../mat/n2839_eeg.mat 1053
+../../mat/n2840_eeg.mat 859
+../../mat/n2841_eeg.mat 1051
+../../mat/n2843_eeg.mat 1053
+../../mat/n2844_eeg.mat 1053
+../../mat/n2845_eeg.mat 1053
+../../mat/n2848_eeg.mat 1051
+../../mat/n2849_eeg.mat 1053
+../../mat/n2850_eeg.mat 1051
+../../mat/n2851_eeg.mat 1053
+../../mat/n2852_eeg.mat 1051
+../../mat/n2856_eeg.mat 779
+../../mat/n2857_eeg.mat 1051
+../../mat/n2858_eeg.mat 1053
+../../mat/n2859_eeg.mat 1043
+../../mat/n2861_eeg.mat 1053
+../../mat/n2862_eeg.mat 1053
+../../mat/n2864_eeg.mat 1051
+../../mat/n2865_eeg.mat 759
+../../mat/n2868_eeg.mat 1053
+../../mat/n2870_eeg.mat 1053
+../../mat/n2872_eeg.mat 1051
+../../mat/n2873_eeg.mat 1053
+../../mat/n2874_eeg.mat 1051
+../../mat/n2875_eeg.mat 979
+../../mat/n2876_eeg.mat 1019
+../../mat/n2879_eeg.mat 1051
+../../mat/n2880_eeg.mat 1053
+../../mat/n2881_eeg.mat 1008
+../../mat/n2882_eeg.mat 489
+../../mat/n2883_eeg.mat 1026
+../../mat/n2884_eeg.mat 980
+../../mat/n2886_eeg.mat 1028
+../../mat/n2887_eeg.mat 1028
+../../mat/n2888_eeg.mat 1053
+../../mat/n2889_eeg.mat 1028
+../../mat/n2890_eeg.mat 556
+../../mat/n2891_eeg.mat 1028
+../../mat/n2892_eeg.mat 860
+../../mat/n2893_eeg.mat 989
+../../mat/n2894_eeg.mat 989
+../../mat/n2895_eeg.mat 1051
+../../mat/n2896_eeg.mat 1053
+../../mat/n2897_eeg.mat 1025
+../../mat/n2899_eeg.mat 1025
+../../mat/n2900_eeg.mat 1048
+../../mat/n2901_eeg.mat 1053
+../../mat/n2902_eeg.mat 1025
+../../mat/n2903_eeg.mat 1021
+../../mat/n2905_eeg.mat 1026
+../../mat/n2906_eeg.mat 959
+../../mat/n2907_eeg.mat 1051
+../../mat/n2909_eeg.mat 1051
+../../mat/n2910_eeg.mat 1053
+../../mat/n2911_eeg.mat 959
+../../mat/n2912_eeg.mat 958
+../../mat/n2913_eeg.mat 959
+../../mat/n2914_eeg.mat 899
+../../mat/n2916_eeg.mat 589
+../../mat/n2922_eeg.mat 1025
+../../mat/n2923_eeg.mat 1017
+../../mat/n2924_eeg.mat 1025
+../../mat/n2925_eeg.mat 1053
+../../mat/n2926_eeg.mat 1028
+../../mat/n2927_eeg.mat 1023
+../../mat/n2928_eeg.mat 975
+../../mat/n2931_eeg.mat 1053
+../../mat/n2932_eeg.mat 1023
+../../mat/n2933_eeg.mat 1028
+../../mat/n2934_eeg.mat 1053
+../../mat/n2938_eeg.mat 1053
+../../mat/n2940_eeg.mat 1025
+../../mat/n2941_eeg.mat 1053
+../../mat/n2942_eeg.mat 1025
+../../mat/n2943_eeg.mat 1049
+../../mat/n2944_eeg.mat 989
+../../mat/n2945_eeg.mat 1053
+../../mat/n2946_eeg.mat 989
+../../mat/n2948_eeg.mat 1053
+../../mat/n2949_eeg.mat 988
+../../mat/n2950_eeg.mat 1051
+../../mat/n2951_eeg.mat 1053
+../../mat/n2952_eeg.mat 869
+../../mat/n2953_eeg.mat 885
+../../mat/n2955_eeg.mat 1051
+../../mat/n2957_eeg.mat 1051
+../../mat/n2961_eeg.mat 1025
+../../mat/n2964_eeg.mat 1049
+../../mat/n2965_eeg.mat 660
+../../mat/n2966_eeg.mat 1025
+../../mat/n2969_eeg.mat 989
+../../mat/n2970_eeg.mat 921
+../../mat/n2971_eeg.mat 1051
+../../mat/n2973_eeg.mat 1051
+../../mat/n2974_eeg.mat 959
+../../mat/n2975_eeg.mat 959
+../../mat/n2977_eeg.mat 1051
+../../mat/n2979_eeg.mat 1053
+../../mat/n2980_eeg.mat 849
+../../mat/n2981_eeg.mat 1019
+../../mat/n2983_eeg.mat 1053
+../../mat/n2984_eeg.mat 1051
+../../mat/n2985_eeg.mat 1025
+../../mat/n2989_eeg.mat 1048
+../../mat/n2990_eeg.mat 959
+../../mat/n2992_eeg.mat 932
+../../mat/n2993_eeg.mat 706
+../../mat/n2995_eeg.mat 1025
+../../mat/n2999_eeg.mat 838
+../../mat/n3000_eeg.mat 1053
+../../mat/n3001_eeg.mat 779
+../../mat/n3003_eeg.mat 1053
+../../mat/n3004_eeg.mat 1053
+../../mat/n3005_eeg.mat 1053
+../../mat/n3006_eeg.mat 1051
+../../mat/n3007_eeg.mat 1025
+../../mat/n3008_eeg.mat 1053
+../../mat/n3009_eeg.mat 1051
+../../mat/n3012_eeg.mat 794
+../../mat/n3013_eeg.mat 899
+../../mat/n3014_eeg.mat 1053
+../../mat/n3016_eeg.mat 1053
+../../mat/n3019_eeg.mat 1053
+../../mat/n3020_eeg.mat 1053
+../../mat/n3021_eeg.mat 1051
+../../mat/n3023_eeg.mat 896
+../../mat/n3025_eeg.mat 1019
+../../mat/n3028_eeg.mat 1051
+../../mat/n3029_eeg.mat 869
+../../mat/n3031_eeg.mat 1053
+../../mat/n3032_eeg.mat 1019
+../../mat/n3034_eeg.mat 1053
+../../mat/n3035_eeg.mat 834
+../../mat/n3036_eeg.mat 1052
+../../mat/n3037_eeg.mat 841
+../../mat/n3038_eeg.mat 667
+../../mat/n3039_eeg.mat 1018
+../../mat/n3040_eeg.mat 1053
+../../mat/n3041_eeg.mat 1019
+../../mat/n3042_eeg.mat 1053
+../../mat/n3043_eeg.mat 837
+../../mat/n3045_eeg.mat 1053
+../../mat/n3046_eeg.mat 899
+../../mat/n3047_eeg.mat 1053
+../../mat/n3051_eeg.mat 1051
+../../mat/n3052_eeg.mat 1053
+../../mat/n3055_eeg.mat 1051
+../../mat/n3056_eeg.mat 1053
+../../mat/n3058_eeg.mat 1053
+../../mat/n3059_eeg.mat 1050
+../../mat/n3060_eeg.mat 1053
+../../mat/n3061_eeg.mat 959
+../../mat/n3062_eeg.mat 1053
+../../mat/n3063_eeg.mat 1053
+../../mat/n3064_eeg.mat 899
+../../mat/n3067_eeg.mat 1053
+../../mat/n3068_eeg.mat 1053
+../../mat/n3069_eeg.mat 1053
+../../mat/n3070_eeg.mat 1052
+../../mat/n3071_eeg.mat 1053
+../../mat/n3073_eeg.mat 1053
+../../mat/n3076_eeg.mat 1053
+../../mat/n3077_eeg.mat 1053
+../../mat/n3078_eeg.mat 951
+../../mat/n3079_eeg.mat 1050
+../../mat/n3081_eeg.mat 1053
+../../mat/n3082_eeg.mat 928
+../../mat/n3083_eeg.mat 1037
+../../mat/n3084_eeg.mat 1053
+../../mat/n3085_eeg.mat 1019
+../../mat/n3091_eeg.mat 1052
+../../mat/n3092_eeg.mat 1053
+../../mat/n3093_eeg.mat 1053
+../../mat/n3095_eeg.mat 968
+../../mat/n3098_eeg.mat 1051
+../../mat/n3099_eeg.mat 1053
+../../mat/n3100_eeg.mat 1047
+../../mat/n3101_eeg.mat 1053
+../../mat/n3102_eeg.mat 1053
+../../mat/n3103_eeg.mat 897
+../../mat/n3106_eeg.mat 741
+../../mat/n3107_eeg.mat 1053
+../../mat/n3108_eeg.mat 1053
+../../mat/n3109_eeg.mat 1053
+../../mat/n3110_eeg.mat 1053
+../../mat/n3111_eeg.mat 1053
+../../mat/n3112_eeg.mat 1014
+../../mat/n3113_eeg.mat 885
+../../mat/n3114_eeg.mat 969
+../../mat/n3116_eeg.mat 1048
+../../mat/n3117_eeg.mat 1053
+../../mat/n3118_eeg.mat 864
+../../mat/n3122_eeg.mat 1050
+../../mat/n3124_eeg.mat 959
+../../mat/n3125_eeg.mat 640
+../../mat/n3126_eeg.mat 989
+../../mat/n3128_eeg.mat 1032
+../../mat/n3129_eeg.mat 787
+../../mat/n3130_eeg.mat 1053
+../../mat/n3131_eeg.mat 959
+../../mat/n3135_eeg.mat 1019
+../../mat/n3137_eeg.mat 959
+../../mat/n3138_eeg.mat 1051
+../../mat/n3139_eeg.mat 1053
+../../mat/n3140_eeg.mat 1017
+../../mat/n3142_eeg.mat 1019
+../../mat/n3144_eeg.mat 1019
+../../mat/n3145_eeg.mat 1019
+../../mat/n3146_eeg.mat 1053
+../../mat/n3147_eeg.mat 1051
+../../mat/n3148_eeg.mat 955
+../../mat/n3149_eeg.mat 912
+../../mat/n3150_eeg.mat 1053
+../../mat/n3151_eeg.mat 1050
+../../mat/n3153_eeg.mat 1053
+../../mat/n3155_eeg.mat 1052
+../../mat/n3156_eeg.mat 1053
+../../mat/n3157_eeg.mat 1052
+../../mat/n3158_eeg.mat 1053
+../../mat/n3160_eeg.mat 1053
+../../mat/n3162_eeg.mat 1049
+../../mat/n3163_eeg.mat 1053
+../../mat/n3164_eeg.mat 1053
+../../mat/n3165_eeg.mat 1019
+../../mat/n3166_eeg.mat 1019
+../../mat/n3167_eeg.mat 899
+../../mat/n3168_eeg.mat 1050
+../../mat/n3169_eeg.mat 1034
+../../mat/n3171_eeg.mat 1015
+../../mat/n3173_eeg.mat 1053
+../../mat/n3174_eeg.mat 1053
+../../mat/n3175_eeg.mat 1053
+../../mat/n3176_eeg.mat 1051
+../../mat/n3178_eeg.mat 1053
+../../mat/n3180_eeg.mat 1051
+../../mat/n3182_eeg.mat 1052
+../../mat/n3183_eeg.mat 959
+../../mat/n3184_eeg.mat 1019
+../../mat/n3185_eeg.mat 1051
+../../mat/n3186_eeg.mat 898
+../../mat/n3187_eeg.mat 976
+../../mat/n3188_eeg.mat 959
+../../mat/n3189_eeg.mat 1051
+../../mat/n3191_eeg.mat 1019
+../../mat/n3192_eeg.mat 1051
+../../mat/n3193_eeg.mat 1051
+../../mat/n3194_eeg.mat 1053
+../../mat/n3195_eeg.mat 837
+../../mat/n3196_eeg.mat 1053
+../../mat/n3197_eeg.mat 1050
+../../mat/n3198_eeg.mat 1053
+../../mat/n3200_eeg.mat 1019
+../../mat/n3202_eeg.mat 1053
+../../mat/n3203_eeg.mat 1053
+../../mat/n3209_eeg.mat 1053
+../../mat/n3210_eeg.mat 1051
+../../mat/n3214_eeg.mat 948
+../../mat/n3215_eeg.mat 1053
+../../mat/n3216_eeg.mat 1019
+../../mat/n3217_eeg.mat 1051
+../../mat/n3219_eeg.mat 1051
+../../mat/n3221_eeg.mat 961
+../../mat/n3222_eeg.mat 1053
+../../mat/n3223_eeg.mat 1052
+../../mat/n3231_eeg.mat 1018
+../../mat/n3232_eeg.mat 1007
+../../mat/n3233_eeg.mat 903
+../../mat/n3234_eeg.mat 1019
+../../mat/n3237_eeg.mat 957
+../../mat/n3239_eeg.mat 959
+../../mat/n3241_eeg.mat 1019
+../../mat/n3242_eeg.mat 1053
+../../mat/n3244_eeg.mat 1053
+../../mat/n3245_eeg.mat 1051
+../../mat/n3246_eeg.mat 1053
+../../mat/n3247_eeg.mat 1042
+../../mat/n3248_eeg.mat 1051
+../../mat/n3249_eeg.mat 1053
+../../mat/n3250_eeg.mat 1053
+../../mat/n3251_eeg.mat 1051
+../../mat/n3252_eeg.mat 1053
+../../mat/n3255_eeg.mat 877
+../../mat/n3259_eeg.mat 1031
+../../mat/n3260_eeg.mat 1053
+../../mat/n3261_eeg.mat 839
+../../mat/n3262_eeg.mat 899
+../../mat/n3264_eeg.mat 1019
+../../mat/n3266_eeg.mat 957
+../../mat/n3269_eeg.mat 1051
+../../mat/n3270_eeg.mat 1052
+../../mat/n3271_eeg.mat 1053
+../../mat/n3272_eeg.mat 1052
+../../mat/n3273_eeg.mat 1050
+../../mat/n3275_eeg.mat 1040
+../../mat/n3276_eeg.mat 1048
+../../mat/n3277_eeg.mat 1051
+../../mat/n3279_eeg.mat 1051
+../../mat/n3280_eeg.mat 871
+../../mat/n3281_eeg.mat 1051
+../../mat/n3282_eeg.mat 1053
+../../mat/n3283_eeg.mat 935
+../../mat/n3284_eeg.mat 958
+../../mat/n3285_eeg.mat 1053
+../../mat/n3286_eeg.mat 1053
+../../mat/n3287_eeg.mat 959
+../../mat/n3289_eeg.mat 839
+../../mat/n3291_eeg.mat 1019
+../../mat/n3292_eeg.mat 1043
+../../mat/n3293_eeg.mat 1049
+../../mat/n3294_eeg.mat 1053
+../../mat/n3295_eeg.mat 1053
+../../mat/n3296_eeg.mat 961
+../../mat/n3298_eeg.mat 882
+../../mat/n3299_eeg.mat 1051
+../../mat/n3300_eeg.mat 989
+../../mat/n3301_eeg.mat 1051
+../../mat/n3303_eeg.mat 958
+../../mat/n3304_eeg.mat 1019
+../../mat/n3305_eeg.mat 1053
+../../mat/n3306_eeg.mat 1019
+../../mat/n3311_eeg.mat 958
+../../mat/n3312_eeg.mat 1053
+../../mat/n3313_eeg.mat 791
+../../mat/n3316_eeg.mat 959
+../../mat/n3318_eeg.mat 1051
+../../mat/n3319_eeg.mat 1051
+../../mat/n3320_eeg.mat 1049
+../../mat/n3321_eeg.mat 1053
+../../mat/n3322_eeg.mat 1051
+../../mat/n3323_eeg.mat 1051
+../../mat/n3324_eeg.mat 1053
+../../mat/n3327_eeg.mat 1053
+../../mat/n3334_eeg.mat 1053
+../../mat/n3335_eeg.mat 899
+../../mat/n3336_eeg.mat 1053
+../../mat/n3337_eeg.mat 1053
+../../mat/n3338_eeg.mat 959
+../../mat/n3339_eeg.mat 1053
+../../mat/n3341_eeg.mat 1053
+../../mat/n3342_eeg.mat 1019
+../../mat/n3343_eeg.mat 1051
+../../mat/n3344_eeg.mat 1051
+../../mat/n3345_eeg.mat 1034
+../../mat/n3346_eeg.mat 1051
+../../mat/n3347_eeg.mat 1051
+../../mat/n3348_eeg.mat 1053
+../../mat/n3349_eeg.mat 1017
+../../mat/n3351_eeg.mat 1051
+../../mat/n3352_eeg.mat 1051
+../../mat/n3353_eeg.mat 1019
+../../mat/n3354_eeg.mat 869
+../../mat/n3356_eeg.mat 1051
+../../mat/n3357_eeg.mat 839
+../../mat/n3358_eeg.mat 1053
+../../mat/n3359_eeg.mat 1053
+../../mat/n3361_eeg.mat 1053
+../../mat/n3363_eeg.mat 1051
+../../mat/n3365_eeg.mat 1019
+../../mat/n3366_eeg.mat 1019
+../../mat/n3367_eeg.mat 1050
+../../mat/n3368_eeg.mat 531
+../../mat/n3369_eeg.mat 1006
+../../mat/n3371_eeg.mat 959
+../../mat/n3372_eeg.mat 1019
+../../mat/n3375_eeg.mat 1052
+../../mat/n3376_eeg.mat 877
+../../mat/n3378_eeg.mat 1053
+../../mat/n3379_eeg.mat 1053
+../../mat/n3380_eeg.mat 959
+../../mat/n3383_eeg.mat 1051
+../../mat/n3384_eeg.mat 1053
+../../mat/n3385_eeg.mat 779
+../../mat/n3386_eeg.mat 868
+../../mat/n3387_eeg.mat 1053
+../../mat/n3388_eeg.mat 1053
+../../mat/n3389_eeg.mat 1053
+../../mat/n3391_eeg.mat 1051
+../../mat/n3393_eeg.mat 1053
+../../mat/n3395_eeg.mat 996
+../../mat/n3396_eeg.mat 939
+../../mat/n3397_eeg.mat 1019
+../../mat/n3398_eeg.mat 1046
+../../mat/n3400_eeg.mat 958
+../../mat/n3401_eeg.mat 1051
+../../mat/n3402_eeg.mat 1049
+../../mat/n3403_eeg.mat 898
+../../mat/n3404_eeg.mat 837
+../../mat/n3405_eeg.mat 1051
+../../mat/n3406_eeg.mat 1019
+../../mat/n3407_eeg.mat 911
+../../mat/n3408_eeg.mat 1053
+../../mat/n3409_eeg.mat 1053
+../../mat/n3410_eeg.mat 1053
+../../mat/n3411_eeg.mat 1051
+../../mat/n3412_eeg.mat 1049
+../../mat/n3413_eeg.mat 1019
+../../mat/n3414_eeg.mat 1053
+../../mat/n3415_eeg.mat 1053
+../../mat/n3417_eeg.mat 1053
+../../mat/n3418_eeg.mat 1053
+../../mat/n3419_eeg.mat 959
+../../mat/n3420_eeg.mat 1051
+../../mat/n3421_eeg.mat 1019
+../../mat/n3424_eeg.mat 1051
+../../mat/n3426_eeg.mat 954
+../../mat/n3427_eeg.mat 959
+../../mat/n3428_eeg.mat 1051
+../../mat/n3429_eeg.mat 1051
+../../mat/n3431_eeg.mat 1050
+../../mat/n3432_eeg.mat 1051
+../../mat/n3433_eeg.mat 1051
+../../mat/n3434_eeg.mat 1053
+../../mat/n3435_eeg.mat 1051
+../../mat/n3437_eeg.mat 1053
+../../mat/n3438_eeg.mat 959
+../../mat/n3439_eeg.mat 1019
+../../mat/n3440_eeg.mat 957
+../../mat/n3441_eeg.mat 1051
+../../mat/n3442_eeg.mat 1051
+../../mat/n3444_eeg.mat 1051
+../../mat/n3445_eeg.mat 1053
+../../mat/n3446_eeg.mat 1050
+../../mat/n3448_eeg.mat 1051
+../../mat/n3451_eeg.mat 1051
+../../mat/n3452_eeg.mat 714
+../../mat/n3453_eeg.mat 1050
+../../mat/n3455_eeg.mat 1052
+../../mat/n3456_eeg.mat 1019
+../../mat/n3458_eeg.mat 1051
+../../mat/n3460_eeg.mat 1053
+../../mat/n3461_eeg.mat 1053
+../../mat/n3464_eeg.mat 1053
+../../mat/n3466_eeg.mat 1051
+../../mat/n3467_eeg.mat 1019
+../../mat/n3468_eeg.mat 1051
+../../mat/n3470_eeg.mat 1019
+../../mat/n3471_eeg.mat 1051
+../../mat/n3472_eeg.mat 917
+../../mat/n3473_eeg.mat 959
+../../mat/n3474_eeg.mat 1053
+../../mat/n3475_eeg.mat 1048
+../../mat/n3476_eeg.mat 1016
+../../mat/n3480_eeg.mat 899
+../../mat/n3482_eeg.mat 1050
+../../mat/n3486_eeg.mat 1053
+../../mat/n3487_eeg.mat 847
+../../mat/n3488_eeg.mat 1039
+../../mat/n3490_eeg.mat 1053
+../../mat/n3491_eeg.mat 1051
+../../mat/n3492_eeg.mat 1047
+../../mat/n3493_eeg.mat 1051
+../../mat/n3494_eeg.mat 1051
+../../mat/n3496_eeg.mat 808
+../../mat/n3497_eeg.mat 1053
+../../mat/n3498_eeg.mat 1045
+../../mat/n3500_eeg.mat 1053
+../../mat/n3501_eeg.mat 1051
+../../mat/n3502_eeg.mat 959
+../../mat/n3503_eeg.mat 1052
+../../mat/n3504_eeg.mat 1051
+../../mat/n3507_eeg.mat 1051
+../../mat/n3508_eeg.mat 1051
+../../mat/n3513_eeg.mat 1053
+../../mat/n3514_eeg.mat 958
+../../mat/n3515_eeg.mat 1050
+../../mat/n3518_eeg.mat 960
+../../mat/n3519_eeg.mat 1019
+../../mat/n3520_eeg.mat 899
+../../mat/n3522_eeg.mat 1053
+../../mat/n3523_eeg.mat 1053
+../../mat/n3524_eeg.mat 1053
+../../mat/n3525_eeg.mat 959
+../../mat/n3526_eeg.mat 1019
+../../mat/n3527_eeg.mat 959
+../../mat/n3528_eeg.mat 1053
+../../mat/n3529_eeg.mat 1051
+../../mat/n3530_eeg.mat 1018
+../../mat/n3531_eeg.mat 1053
+../../mat/n3532_eeg.mat 839
+../../mat/n3533_eeg.mat 1051
+../../mat/n3534_eeg.mat 1018
+../../mat/n3535_eeg.mat 1053
+../../mat/n3537_eeg.mat 1051
+../../mat/n3540_eeg.mat 1051
+../../mat/n3541_eeg.mat 782
+../../mat/n3544_eeg.mat 1053
+../../mat/n3546_eeg.mat 1051
+../../mat/n3547_eeg.mat 988
+../../mat/n3548_eeg.mat 899
+../../mat/n3549_eeg.mat 1051
+../../mat/n3550_eeg.mat 959
+../../mat/n3551_eeg.mat 1053
+../../mat/n3552_eeg.mat 1053
+../../mat/n3554_eeg.mat 805
+../../mat/n3555_eeg.mat 1053
+../../mat/n3556_eeg.mat 959
+../../mat/n3558_eeg.mat 1023
+../../mat/n3561_eeg.mat 1053
+../../mat/n3562_eeg.mat 1049
+../../mat/n3563_eeg.mat 1049
+../../mat/n3564_eeg.mat 1051
+../../mat/n3566_eeg.mat 1053
+../../mat/n3567_eeg.mat 935
+../../mat/n3568_eeg.mat 899
+../../mat/n3569_eeg.mat 958
+../../mat/n3570_eeg.mat 1051
+../../mat/n3571_eeg.mat 1053
+../../mat/n3572_eeg.mat 1053
+../../mat/n3575_eeg.mat 1051
+../../mat/n3576_eeg.mat 1051
+../../mat/n3577_eeg.mat 965
+../../mat/n3580_eeg.mat 1049
+../../mat/n3581_eeg.mat 1053
+../../mat/n3582_eeg.mat 988
+../../mat/n3586_eeg.mat 1047
+../../mat/n3588_eeg.mat 1050
+../../mat/n3589_eeg.mat 1051
+../../mat/n3590_eeg.mat 1051
+../../mat/n3594_eeg.mat 1053
+../../mat/n3598_eeg.mat 1053
+../../mat/n3599_eeg.mat 1053
+../../mat/n3601_eeg.mat 1053
+../../mat/n3602_eeg.mat 1051
+../../mat/n3604_eeg.mat 1051
+../../mat/n3606_eeg.mat 1052
+../../mat/n3610_eeg.mat 899
+../../mat/n3611_eeg.mat 1051
+../../mat/n3612_eeg.mat 1053
+../../mat/n3615_eeg.mat 1053
+../../mat/n3616_eeg.mat 1019
+../../mat/n3617_eeg.mat 1021
+../../mat/n3618_eeg.mat 915
+../../mat/n3619_eeg.mat 1051
+../../mat/n3621_eeg.mat 1053
+../../mat/n3622_eeg.mat 1053
+../../mat/n3623_eeg.mat 1019
+../../mat/n3624_eeg.mat 942
+../../mat/n3625_eeg.mat 959
+../../mat/n3626_eeg.mat 1051
+../../mat/n3627_eeg.mat 1053
+../../mat/n3628_eeg.mat 1053
+../../mat/n3631_eeg.mat 1053
+../../mat/n3633_eeg.mat 1051
+../../mat/n3635_eeg.mat 1051
+../../mat/n3636_eeg.mat 1053
+../../mat/n3637_eeg.mat 1051
+../../mat/n3640_eeg.mat 1052
+../../mat/n3642_eeg.mat 959
+../../mat/n3644_eeg.mat 1051
+../../mat/n3646_eeg.mat 1053
+../../mat/n3647_eeg.mat 1051
+../../mat/n3648_eeg.mat 1051
+../../mat/n3650_eeg.mat 1051
+../../mat/n3651_eeg.mat 1053
+../../mat/n3652_eeg.mat 1053
+../../mat/n3653_eeg.mat 844
+../../mat/n3654_eeg.mat 1053
+../../mat/n3655_eeg.mat 1051
+../../mat/n3657_eeg.mat 1050
+../../mat/n3660_eeg.mat 925
+../../mat/n3661_eeg.mat 1053
+../../mat/n3662_eeg.mat 1019
+../../mat/n3663_eeg.mat 1052
+../../mat/n3664_eeg.mat 894
+../../mat/n3665_eeg.mat 1051
+../../mat/n3666_eeg.mat 1051
+../../mat/n3667_eeg.mat 1052
+../../mat/n3668_eeg.mat 929
+../../mat/n3669_eeg.mat 1053
+../../mat/n3677_eeg.mat 1053
+../../mat/n3678_eeg.mat 1050
+../../mat/n3679_eeg.mat 995
+../../mat/n3682_eeg.mat 1053
+../../mat/n3683_eeg.mat 1053
+../../mat/n3686_eeg.mat 1051
+../../mat/n3687_eeg.mat 900
+../../mat/n3688_eeg.mat 1053
+../../mat/n3690_eeg.mat 1053
+../../mat/n3692_eeg.mat 1053
+../../mat/n3693_eeg.mat 1053
+../../mat/n3694_eeg.mat 1051
+../../mat/n3695_eeg.mat 1053
+../../mat/n3696_eeg.mat 1053
+../../mat/n3698_eeg.mat 1051
+../../mat/n3700_eeg.mat 1051
+../../mat/n3701_eeg.mat 1051
+../../mat/n3703_eeg.mat 839
+../../mat/n3705_eeg.mat 888
+../../mat/n3706_eeg.mat 1053
+../../mat/n3708_eeg.mat 1016
+../../mat/n3711_eeg.mat 1053
+../../mat/n3712_eeg.mat 959
+../../mat/n3713_eeg.mat 1019
+../../mat/n3714_eeg.mat 1051
+../../mat/n3715_eeg.mat 1053
+../../mat/n3716_eeg.mat 1042
+../../mat/n3717_eeg.mat 1053
+../../mat/n3718_eeg.mat 1019
+../../mat/n3719_eeg.mat 895
+../../mat/n3720_eeg.mat 1018
+../../mat/n3722_eeg.mat 1068
+../../mat/n3723_eeg.mat 1018
+../../mat/n3725_eeg.mat 1067
+../../mat/n3726_eeg.mat 1047
+../../mat/n3728_eeg.mat 1069
+../../mat/n3729_eeg.mat 1069
+../../mat/n3730_eeg.mat 839
+../../mat/n3731_eeg.mat 895
+../../mat/n3732_eeg.mat 1067
+../../mat/n3733_eeg.mat 1067
+../../mat/n3734_eeg.mat 929
+../../mat/n3737_eeg.mat 1049
+../../mat/n3738_eeg.mat 1069
+../../mat/n3739_eeg.mat 1067
+../../mat/n3740_eeg.mat 1067
+../../mat/n3743_eeg.mat 1067
+../../mat/n3745_eeg.mat 1019
+../../mat/n3747_eeg.mat 961
+../../mat/n3748_eeg.mat 821
+../../mat/n3749_eeg.mat 1019
+../../mat/n3750_eeg.mat 861
+../../mat/n3753_eeg.mat 1069
+../../mat/n3754_eeg.mat 1069
+../../mat/n3756_eeg.mat 1019
+../../mat/n3757_eeg.mat 929
+../../mat/n3758_eeg.mat 1019
+../../mat/n3760_eeg.mat 1067
+../../mat/n3766_eeg.mat 1069
+../../mat/n3768_eeg.mat 1068
+../../mat/n3769_eeg.mat 1068
+../../mat/n3770_eeg.mat 958
+../../mat/n3771_eeg.mat 1069
+../../mat/n3772_eeg.mat 1019
+../../mat/n3775_eeg.mat 839
+../../mat/n3776_eeg.mat 1019
+../../mat/n3777_eeg.mat 1019
+../../mat/n3778_eeg.mat 1068
+../../mat/n3779_eeg.mat 959
+../../mat/n3781_eeg.mat 1019
+../../mat/n3782_eeg.mat 1067
+../../mat/n3783_eeg.mat 1019
+../../mat/n3784_eeg.mat 1067
+../../mat/n3785_eeg.mat 1069
+../../mat/n3786_eeg.mat 1048
+../../mat/n3787_eeg.mat 1067
+../../mat/n3788_eeg.mat 1067
+../../mat/n3789_eeg.mat 1067
+../../mat/n3793_eeg.mat 1019
+../../mat/n3794_eeg.mat 1059
+../../mat/n3795_eeg.mat 1067
+../../mat/n3796_eeg.mat 911
+../../mat/n3797_eeg.mat 1015
+../../mat/n3798_eeg.mat 1034
+../../mat/n3799_eeg.mat 1067
+../../mat/n3800_eeg.mat 1067
+../../mat/n3801_eeg.mat 1069
+../../mat/n3803_eeg.mat 1019
+../../mat/n3805_eeg.mat 957
+../../mat/n3807_eeg.mat 1018
+../../mat/n3808_eeg.mat 1049
+../../mat/n3810_eeg.mat 1069
+../../mat/n3811_eeg.mat 1069
+../../mat/n3812_eeg.mat 1068
+../../mat/n3813_eeg.mat 1069
+../../mat/n3815_eeg.mat 1068
+../../mat/n3816_eeg.mat 1068
+../../mat/n3817_eeg.mat 1067
+../../mat/n3818_eeg.mat 1019
+../../mat/n3822_eeg.mat 896
+../../mat/n3823_eeg.mat 959
+../../mat/n3824_eeg.mat 1069
+../../mat/n3825_eeg.mat 1019
+../../mat/n3826_eeg.mat 1066
+../../mat/n3829_eeg.mat 1067
+../../mat/n3831_eeg.mat 1069
+../../mat/n3832_eeg.mat 1067
+../../mat/n3833_eeg.mat 1062
+../../mat/n3835_eeg.mat 1067
+../../mat/n3837_eeg.mat 1067
+../../mat/n3838_eeg.mat 1019
+../../mat/n3839_eeg.mat 1018
+../../mat/n3841_eeg.mat 757
+../../mat/n3842_eeg.mat 1066
+../../mat/n3843_eeg.mat 1049
+../../mat/n3844_eeg.mat 1049
+../../mat/n3845_eeg.mat 1069
+../../mat/n3847_eeg.mat 1067
+../../mat/n3848_eeg.mat 1019
+../../mat/n3850_eeg.mat 1019
+../../mat/n3851_eeg.mat 1068
+../../mat/n3853_eeg.mat 959
+../../mat/n3855_eeg.mat 1069
+../../mat/n3856_eeg.mat 1021
+../../mat/n3857_eeg.mat 1068
+../../mat/n3858_eeg.mat 1019
+../../mat/n3859_eeg.mat 1019
+../../mat/n3861_eeg.mat 1067
+../../mat/n3864_eeg.mat 1067
+../../mat/n3865_eeg.mat 984
+../../mat/n3866_eeg.mat 1009
+../../mat/n3867_eeg.mat 1019
+../../mat/n3869_eeg.mat 1021
+../../mat/n3871_eeg.mat 1049
+../../mat/n3872_eeg.mat 1069
+../../mat/n3873_eeg.mat 1019
+../../mat/n3874_eeg.mat 1068
+../../mat/n3875_eeg.mat 1067
+../../mat/n3876_eeg.mat 989
+../../mat/n3877_eeg.mat 1019
+../../mat/n3880_eeg.mat 1019
+../../mat/n3881_eeg.mat 1067
+../../mat/n3882_eeg.mat 1069
+../../mat/n3883_eeg.mat 1068
+../../mat/n3884_eeg.mat 1019
+../../mat/n3885_eeg.mat 1067
+../../mat/n3886_eeg.mat 1019
+../../mat/n3887_eeg.mat 1069
+../../mat/n3889_eeg.mat 1019
+../../mat/n3892_eeg.mat 1066
+../../mat/n3893_eeg.mat 899
+../../mat/n3894_eeg.mat 959
+../../mat/n3895_eeg.mat 1069
+../../mat/n3896_eeg.mat 1023
+../../mat/n3898_eeg.mat 1049
+../../mat/n3899_eeg.mat 1019
+../../mat/n3900_eeg.mat 1049
+../../mat/n3901_eeg.mat 1067
+../../mat/n3902_eeg.mat 1067
+../../mat/n3903_eeg.mat 852
+../../mat/n3904_eeg.mat 1067
+../../mat/n3905_eeg.mat 1019
+../../mat/n3906_eeg.mat 959
+../../mat/n3908_eeg.mat 1069
+../../mat/n3909_eeg.mat 1048
+../../mat/n3910_eeg.mat 1067
+../../mat/n3912_eeg.mat 1067
+../../mat/n3913_eeg.mat 1068
+../../mat/n3914_eeg.mat 1064
+../../mat/n3916_eeg.mat 1017
+../../mat/n3917_eeg.mat 1053
+../../mat/n3918_eeg.mat 1019
+../../mat/n3920_eeg.mat 1067
+../../mat/n3921_eeg.mat 1067
+../../mat/n3922_eeg.mat 1049
+../../mat/n3923_eeg.mat 1063
+../../mat/n3924_eeg.mat 1019
+../../mat/n3925_eeg.mat 1067
+../../mat/n3926_eeg.mat 1069
+../../mat/n3927_eeg.mat 991
+../../mat/n3928_eeg.mat 1049
+../../mat/n3929_eeg.mat 1067
+../../mat/n3930_eeg.mat 1016
+../../mat/n3931_eeg.mat 1069
+../../mat/n3933_eeg.mat 1069
+../../mat/n3936_eeg.mat 958
+../../mat/n3938_eeg.mat 1067
+../../mat/n3939_eeg.mat 1019
+../../mat/n3940_eeg.mat 1019
+../../mat/n3941_eeg.mat 1067
+../../mat/n3942_eeg.mat 1063
+../../mat/n3944_eeg.mat 1019
+../../mat/n3947_eeg.mat 1069
+../../mat/n3948_eeg.mat 1019
+../../mat/n3951_eeg.mat 1069
+../../mat/n3952_eeg.mat 1019
+../../mat/n3954_eeg.mat 1049
+../../mat/n3955_eeg.mat 1019
+../../mat/n3956_eeg.mat 1069
+../../mat/n3957_eeg.mat 1069
+../../mat/n3958_eeg.mat 1068
+../../mat/n3959_eeg.mat 1069
+../../mat/n3960_eeg.mat 1021
+../../mat/n3962_eeg.mat 1019
+../../mat/n3963_eeg.mat 1066
+../../mat/n3964_eeg.mat 1067
+../../mat/n3967_eeg.mat 1068
+../../mat/n3968_eeg.mat 899
+../../mat/n3969_eeg.mat 829
+../../mat/n3971_eeg.mat 1019
+../../mat/n3972_eeg.mat 1069
+../../mat/n3973_eeg.mat 1049
+../../mat/n3974_eeg.mat 1067
+../../mat/n3976_eeg.mat 1019
+../../mat/n3977_eeg.mat 959
+../../mat/n3979_eeg.mat 958
+../../mat/n3980_eeg.mat 1019
+../../mat/n3981_eeg.mat 1067
+../../mat/n3982_eeg.mat 1019
+../../mat/n3983_eeg.mat 1067
+../../mat/n3985_eeg.mat 1019
+../../mat/n3986_eeg.mat 1019
+../../mat/n3987_eeg.mat 1019
+../../mat/n3988_eeg.mat 1068
+../../mat/n3989_eeg.mat 1067
+../../mat/n3995_eeg.mat 1019
+../../mat/n3996_eeg.mat 963
+../../mat/n3997_eeg.mat 1068
+../../mat/n3998_eeg.mat 1067
+../../mat/n3999_eeg.mat 1067
+../../mat/n4000_eeg.mat 1019
+../../mat/n4001_eeg.mat 1067
+../../mat/n4002_eeg.mat 959
+../../mat/n4005_eeg.mat 1067
+../../mat/n4007_eeg.mat 1068
+../../mat/n4009_eeg.mat 1067
+../../mat/n4010_eeg.mat 1019
+../../mat/n4011_eeg.mat 857
+../../mat/n4013_eeg.mat 1069
+../../mat/n4014_eeg.mat 1019
+../../mat/n4016_eeg.mat 1067
+../../mat/n4017_eeg.mat 957
+../../mat/n4018_eeg.mat 1069
+../../mat/n4019_eeg.mat 1069
+../../mat/n4021_eeg.mat 959
+../../mat/n4023_eeg.mat 1049
+../../mat/n4024_eeg.mat 1069
+../../mat/n4026_eeg.mat 1015
+../../mat/n4030_eeg.mat 1069
+../../mat/n4032_eeg.mat 1069
+../../mat/n4033_eeg.mat 1067
+../../mat/n4034_eeg.mat 1067
+../../mat/n4038_eeg.mat 899
+../../mat/n4039_eeg.mat 901
+../../mat/n4040_eeg.mat 1067
+../../mat/n4042_eeg.mat 1061
+../../mat/n4044_eeg.mat 1067
+../../mat/n4045_eeg.mat 959
+../../mat/n4047_eeg.mat 1019
+../../mat/n4049_eeg.mat 1067
+../../mat/n4050_eeg.mat 1069
+../../mat/n4051_eeg.mat 1067
+../../mat/n4052_eeg.mat 1019
+../../mat/n4054_eeg.mat 971
+../../mat/n4055_eeg.mat 1067
+../../mat/n4057_eeg.mat 1019
+../../mat/n4058_eeg.mat 1068
+../../mat/n4059_eeg.mat 1067
+../../mat/n4060_eeg.mat 1068
+../../mat/n4062_eeg.mat 1067
+../../mat/n4065_eeg.mat 1068
+../../mat/n4066_eeg.mat 1067
+../../mat/n4069_eeg.mat 899
+../../mat/n4071_eeg.mat 1067
+../../mat/n4072_eeg.mat 900
+../../mat/n4074_eeg.mat 1018
+../../mat/n4077_eeg.mat 1067
+../../mat/n4078_eeg.mat 1069
+../../mat/n4079_eeg.mat 1069
+../../mat/n4081_eeg.mat 1049
+../../mat/n4082_eeg.mat 1019
+../../mat/n4083_eeg.mat 929
+../../mat/n4084_eeg.mat 1067
+../../mat/n4090_eeg.mat 1068
+../../mat/n4091_eeg.mat 1067
+../../mat/n4093_eeg.mat 1067
+../../mat/n4094_eeg.mat 1066
+../../mat/n4095_eeg.mat 899
+../../mat/n4096_eeg.mat 1019
+../../mat/n4097_eeg.mat 1019
+../../mat/n4098_eeg.mat 1069
+../../mat/n4099_eeg.mat 929
+../../mat/n4101_eeg.mat 1067
+../../mat/n4102_eeg.mat 1067
+../../mat/n4103_eeg.mat 1019
+../../mat/n4104_eeg.mat 1068
+../../mat/n4105_eeg.mat 901
+../../mat/n4106_eeg.mat 1067
+../../mat/n4108_eeg.mat 1019
+../../mat/n4109_eeg.mat 1067
+../../mat/n4110_eeg.mat 979
+../../mat/n4111_eeg.mat 1069
+../../mat/n4112_eeg.mat 957
+../../mat/n4113_eeg.mat 1068
+../../mat/n4114_eeg.mat 1067
+../../mat/n4115_eeg.mat 1039
+../../mat/n4116_eeg.mat 1068
+../../mat/n4118_eeg.mat 1069
+../../mat/n4119_eeg.mat 1068
+../../mat/n4120_eeg.mat 1019
+../../mat/n4121_eeg.mat 1069
+../../mat/n4123_eeg.mat 1068
+../../mat/n4124_eeg.mat 1067
+../../mat/n4125_eeg.mat 1067
+../../mat/n4127_eeg.mat 1039
+../../mat/n4129_eeg.mat 1066
+../../mat/n4130_eeg.mat 1017
+../../mat/n4131_eeg.mat 1067
+../../mat/n4132_eeg.mat 1019
+../../mat/n4134_eeg.mat 674
+../../mat/n4135_eeg.mat 958
+../../mat/n4138_eeg.mat 1019
+../../mat/n4140_eeg.mat 1068
+../../mat/n4141_eeg.mat 1069
+../../mat/n4144_eeg.mat 1067
+../../mat/n4145_eeg.mat 1067
+../../mat/n4147_eeg.mat 1019
+../../mat/n4149_eeg.mat 1069
+../../mat/n4150_eeg.mat 1068
+../../mat/n4152_eeg.mat 959
+../../mat/n4153_eeg.mat 1067
+../../mat/n4156_eeg.mat 895
+../../mat/n4158_eeg.mat 1068
+../../mat/n4160_eeg.mat 999
+../../mat/n4162_eeg.mat 1019
+../../mat/n4164_eeg.mat 1067
+../../mat/n4167_eeg.mat 1021
+../../mat/n4169_eeg.mat 959
+../../mat/n4170_eeg.mat 1067
+../../mat/n4171_eeg.mat 1067
+../../mat/n4172_eeg.mat 1067
+../../mat/n4173_eeg.mat 1069
+../../mat/n4174_eeg.mat 1069
+../../mat/n4176_eeg.mat 959
+../../mat/n4177_eeg.mat 673
+../../mat/n4178_eeg.mat 1068
+../../mat/n4179_eeg.mat 1068
+../../mat/n4180_eeg.mat 956
+../../mat/n4181_eeg.mat 1067
+../../mat/n4182_eeg.mat 1068
+../../mat/n4183_eeg.mat 1051
+../../mat/n4184_eeg.mat 1051
+../../mat/n4187_eeg.mat 1068
+../../mat/n4188_eeg.mat 1069
+../../mat/n4189_eeg.mat 1069
+../../mat/n4192_eeg.mat 1052
+../../mat/n4193_eeg.mat 1051
+../../mat/n4194_eeg.mat 1069
+../../mat/n4196_eeg.mat 1079
+../../mat/n4197_eeg.mat 1019
+../../mat/n4198_eeg.mat 1049
+../../mat/n4199_eeg.mat 1069
+../../mat/n4200_eeg.mat 1000
+../../mat/n4201_eeg.mat 1019
+../../mat/n4202_eeg.mat 959
+../../mat/n4204_eeg.mat 1049
+../../mat/n4207_eeg.mat 1067
+../../mat/n4208_eeg.mat 1069
+../../mat/n4209_eeg.mat 1019
+../../mat/n4211_eeg.mat 1068
+../../mat/n4212_eeg.mat 1048
+../../mat/n4213_eeg.mat 1069
+../../mat/n4214_eeg.mat 1067
+../../mat/n4216_eeg.mat 1069
+../../mat/n4217_eeg.mat 1051
+../../mat/n4218_eeg.mat 959
+../../mat/n4219_eeg.mat 1069
+../../mat/n4221_eeg.mat 1019
+../../mat/n4222_eeg.mat 1067
+../../mat/n4224_eeg.mat 1019
+../../mat/n4226_eeg.mat 1051
+../../mat/n4227_eeg.mat 972
+../../mat/n4228_eeg.mat 1019
+../../mat/n4230_eeg.mat 1067
+../../mat/n4231_eeg.mat 959
+../../mat/n4232_eeg.mat 1013
+../../mat/n4234_eeg.mat 957
+../../mat/n4236_eeg.mat 1068
+../../mat/n4237_eeg.mat 959
+../../mat/n4238_eeg.mat 1067
+../../mat/n4239_eeg.mat 1068
+../../mat/n4240_eeg.mat 1067
+../../mat/n4241_eeg.mat 1051
+../../mat/n4242_eeg.mat 959
+../../mat/n4243_eeg.mat 1067
+../../mat/n4244_eeg.mat 1069
+../../mat/n4245_eeg.mat 897
+../../mat/n4246_eeg.mat 1067
+../../mat/n4249_eeg.mat 1051
+../../mat/n4254_eeg.mat 1019
+../../mat/n4256_eeg.mat 1068
+../../mat/n4257_eeg.mat 1067
+../../mat/n4258_eeg.mat 1067
+../../mat/n4259_eeg.mat 1069
+../../mat/n4260_eeg.mat 1008
+../../mat/n4261_eeg.mat 1067
+../../mat/n4264_eeg.mat 1067
+../../mat/n4265_eeg.mat 963
+../../mat/n4266_eeg.mat 1069
+../../mat/n4267_eeg.mat 1019
+../../mat/n4268_eeg.mat 1068
+../../mat/n4270_eeg.mat 959
+../../mat/n4272_eeg.mat 959
+../../mat/n4273_eeg.mat 1069
+../../mat/n4275_eeg.mat 1019
+../../mat/n4276_eeg.mat 1053
+../../mat/n4278_eeg.mat 1068
+../../mat/n4279_eeg.mat 1051
+../../mat/n4280_eeg.mat 1067
+../../mat/n4282_eeg.mat 1069
+../../mat/n4283_eeg.mat 1069
+../../mat/n4284_eeg.mat 1069
+../../mat/n4285_eeg.mat 1068
+../../mat/n4287_eeg.mat 959
+../../mat/n4288_eeg.mat 1053
+../../mat/n4289_eeg.mat 1069
+../../mat/n4291_eeg.mat 1019
+../../mat/n4293_eeg.mat 959
+../../mat/n4294_eeg.mat 1019
+../../mat/n4295_eeg.mat 1069
+../../mat/n4297_eeg.mat 1053
+../../mat/n4298_eeg.mat 1067
+../../mat/n4299_eeg.mat 1069
+../../mat/n4300_eeg.mat 1068
+../../mat/n4301_eeg.mat 1067
+../../mat/n4302_eeg.mat 1068
+../../mat/n4303_eeg.mat 1069
+../../mat/n4304_eeg.mat 1051
+../../mat/n4305_eeg.mat 1067
+../../mat/n4306_eeg.mat 1068
+../../mat/n4307_eeg.mat 1014
+../../mat/n4308_eeg.mat 1067
+../../mat/n4309_eeg.mat 1019
+../../mat/n4310_eeg.mat 899
+../../mat/n4313_eeg.mat 955
+../../mat/n4315_eeg.mat 1065
+../../mat/n4318_eeg.mat 989
+../../mat/n4320_eeg.mat 960
+../../mat/n4321_eeg.mat 839
+../../mat/n4322_eeg.mat 1067
+../../mat/n4323_eeg.mat 869
+../../mat/n4324_eeg.mat 989
+../../mat/n4325_eeg.mat 1053
+../../mat/n4326_eeg.mat 1067
+../../mat/n4327_eeg.mat 959
+../../mat/n4329_eeg.mat 1019
+../../mat/n4330_eeg.mat 1067
+../../mat/n4332_eeg.mat 1019
+../../mat/n4333_eeg.mat 1068
+../../mat/n4334_eeg.mat 1067
+../../mat/n4337_eeg.mat 1018
+../../mat/n4338_eeg.mat 1069
+../../mat/n4339_eeg.mat 1068
+../../mat/n4340_eeg.mat 940
+../../mat/n4341_eeg.mat 1067
+../../mat/n4342_eeg.mat 1006
+../../mat/n4343_eeg.mat 959
+../../mat/n4344_eeg.mat 1068
+../../mat/n4345_eeg.mat 1019
+../../mat/n4346_eeg.mat 839
+../../mat/n4347_eeg.mat 1019
+../../mat/n4348_eeg.mat 959
+../../mat/n4349_eeg.mat 1067
+../../mat/n4351_eeg.mat 1048
+../../mat/n4352_eeg.mat 1063
+../../mat/n4353_eeg.mat 1019
+../../mat/n4354_eeg.mat 957
+../../mat/n4355_eeg.mat 955
+../../mat/n4356_eeg.mat 673
+../../mat/n4359_eeg.mat 1067
+../../mat/n4360_eeg.mat 1052
+../../mat/n4361_eeg.mat 1019
+../../mat/n4363_eeg.mat 1066
+../../mat/n4364_eeg.mat 1018
+../../mat/n4366_eeg.mat 1069
+../../mat/n4367_eeg.mat 1067
+../../mat/n4370_eeg.mat 1039
+../../mat/n4371_eeg.mat 1051
+../../mat/n4372_eeg.mat 1019
+../../mat/n4373_eeg.mat 1051
+../../mat/n4376_eeg.mat 1019
+../../mat/n4378_eeg.mat 1017
+../../mat/n4380_eeg.mat 1052
+../../mat/n4381_eeg.mat 839
+../../mat/n4384_eeg.mat 944
+../../mat/n4385_eeg.mat 1019
+../../mat/n4386_eeg.mat 1067
+../../mat/n4390_eeg.mat 959
+../../mat/n4392_eeg.mat 918
+../../mat/n4393_eeg.mat 971
+../../mat/n4394_eeg.mat 916
+../../mat/n4395_eeg.mat 839
+../../mat/n4396_eeg.mat 989
+../../mat/n4397_eeg.mat 1067
+../../mat/n4398_eeg.mat 959
+../../mat/n4399_eeg.mat 1067
+../../mat/n4400_eeg.mat 1051
+../../mat/n4403_eeg.mat 951
+../../mat/n4404_eeg.mat 921
+../../mat/n4405_eeg.mat 1019
+../../mat/n4408_eeg.mat 959
+../../mat/n4409_eeg.mat 1068
+../../mat/n4410_eeg.mat 1019
+../../mat/n4411_eeg.mat 1067
+../../mat/n4412_eeg.mat 1065
+../../mat/n4413_eeg.mat 1068
+../../mat/n4414_eeg.mat 1067
+../../mat/n4415_eeg.mat 1019
+../../mat/n4417_eeg.mat 1049
+../../mat/n4419_eeg.mat 959
+../../mat/n4421_eeg.mat 958
+../../mat/n4422_eeg.mat 959
+../../mat/n4423_eeg.mat 1019
+../../mat/n4426_eeg.mat 1019
+../../mat/n4427_eeg.mat 868
+../../mat/n4428_eeg.mat 1067
+../../mat/n4429_eeg.mat 1018
+../../mat/n4430_eeg.mat 959
+../../mat/n4431_eeg.mat 1020
+../../mat/n4432_eeg.mat 1019
+../../mat/n4433_eeg.mat 1019
+../../mat/n4434_eeg.mat 1069
+../../mat/n4435_eeg.mat 1067
+../../mat/n4437_eeg.mat 1019
+../../mat/n4438_eeg.mat 1069
+../../mat/n4440_eeg.mat 979
+../../mat/n4441_eeg.mat 959
+../../mat/n4442_eeg.mat 958
+../../mat/n4443_eeg.mat 1019
+../../mat/n4446_eeg.mat 1069
+../../mat/n4447_eeg.mat 1068
+../../mat/n4448_eeg.mat 1019
+../../mat/n4449_eeg.mat 1068
+../../mat/n4450_eeg.mat 1067
+../../mat/n4451_eeg.mat 1067
+../../mat/n4452_eeg.mat 1066
+../../mat/n4453_eeg.mat 1019
+../../mat/n4454_eeg.mat 1019
+../../mat/n4459_eeg.mat 1019
+../../mat/n4461_eeg.mat 959
+../../mat/n4462_eeg.mat 1019
+../../mat/n4465_eeg.mat 1068
+../../mat/n4466_eeg.mat 959
+../../mat/n4467_eeg.mat 1067
+../../mat/n4468_eeg.mat 959
+../../mat/n4471_eeg.mat 1057
+../../mat/n4472_eeg.mat 1019
+../../mat/n4474_eeg.mat 1069
+../../mat/n4475_eeg.mat 1069
+../../mat/n4476_eeg.mat 829
+../../mat/n4477_eeg.mat 1067
+../../mat/n4478_eeg.mat 1019
+../../mat/n4480_eeg.mat 1019
+../../mat/n4481_eeg.mat 1067
+../../mat/n4482_eeg.mat 949
+../../mat/n4483_eeg.mat 988
+../../mat/n4484_eeg.mat 1067
+../../mat/n4485_eeg.mat 1067
+../../mat/n4486_eeg.mat 959
+../../mat/n4488_eeg.mat 1067
+../../mat/n4489_eeg.mat 1018
+../../mat/n4490_eeg.mat 1019
+../../mat/n4491_eeg.mat 1069
+../../mat/n4492_eeg.mat 1068
+../../mat/n4493_eeg.mat 1068
+../../mat/n4494_eeg.mat 1069
+../../mat/n4495_eeg.mat 832
+../../mat/n4497_eeg.mat 1067
+../../mat/n4500_eeg.mat 1069
+../../mat/n4501_eeg.mat 1068
+../../mat/n4502_eeg.mat 1067
+../../mat/n4503_eeg.mat 1069
+../../mat/n4504_eeg.mat 1069
+../../mat/n4506_eeg.mat 1067
+../../mat/n4507_eeg.mat 1067
+../../mat/n4508_eeg.mat 1069
+../../mat/n4511_eeg.mat 1067
+../../mat/n4512_eeg.mat 1019
+../../mat/n4514_eeg.mat 1051
+../../mat/n4515_eeg.mat 1052
+../../mat/n4516_eeg.mat 1069
+../../mat/n4518_eeg.mat 1019
+../../mat/n4519_eeg.mat 1059
+../../mat/n4522_eeg.mat 1019
+../../mat/n4524_eeg.mat 1015
+../../mat/n4525_eeg.mat 1067
+../../mat/n4526_eeg.mat 1069
+../../mat/n4528_eeg.mat 957
+../../mat/n4530_eeg.mat 1019
+../../mat/n4531_eeg.mat 959
+../../mat/n4532_eeg.mat 1016
+../../mat/n4535_eeg.mat 827
+../../mat/n4536_eeg.mat 1199
+../../mat/n4537_eeg.mat 899
+../../mat/n4538_eeg.mat 1067
+../../mat/n4540_eeg.mat 1068
+../../mat/n4542_eeg.mat 1069
+../../mat/n4543_eeg.mat 1068
+../../mat/n4544_eeg.mat 1019
+../../mat/n4545_eeg.mat 1019
+../../mat/n4547_eeg.mat 1069
+../../mat/n4549_eeg.mat 946
+../../mat/n4550_eeg.mat 1069
+../../mat/n4551_eeg.mat 1067
+../../mat/n4552_eeg.mat 945
+../../mat/n4553_eeg.mat 899
+../../mat/n4555_eeg.mat 1039
+../../mat/n4557_eeg.mat 1019
+../../mat/n4558_eeg.mat 1069
+../../mat/n4561_eeg.mat 958
+../../mat/n4562_eeg.mat 1067
+../../mat/n4563_eeg.mat 1019
+../../mat/n4565_eeg.mat 1069
+../../mat/n4566_eeg.mat 1067
+../../mat/n4567_eeg.mat 1067
+../../mat/n4568_eeg.mat 1067
+../../mat/n4570_eeg.mat 1069
+../../mat/n4571_eeg.mat 1069
+../../mat/n4572_eeg.mat 1068
+../../mat/n4573_eeg.mat 1069
+../../mat/n4574_eeg.mat 1069
+../../mat/n4575_eeg.mat 1019
+../../mat/n4576_eeg.mat 1068
+../../mat/n4577_eeg.mat 1019
+../../mat/n4578_eeg.mat 1069
+../../mat/n4579_eeg.mat 1067
+../../mat/n4580_eeg.mat 1069
+../../mat/n4581_eeg.mat 849
+../../mat/n4582_eeg.mat 1067
+../../mat/n4583_eeg.mat 1019
+../../mat/n4584_eeg.mat 872
+../../mat/n4586_eeg.mat 1067
+../../mat/n4587_eeg.mat 1067
+../../mat/n4588_eeg.mat 839
+../../mat/n4590_eeg.mat 1066
+../../mat/n4592_eeg.mat 1008
+../../mat/n4594_eeg.mat 1069
+../../mat/n4597_eeg.mat 1067
+../../mat/n4598_eeg.mat 1067
+../../mat/n4599_eeg.mat 1069
+../../mat/n4600_eeg.mat 1067
+../../mat/n4602_eeg.mat 1067
+../../mat/n4603_eeg.mat 1067
+../../mat/n4604_eeg.mat 1069
+../../mat/n4606_eeg.mat 781
+../../mat/n4609_eeg.mat 1069
+../../mat/n4610_eeg.mat 1069
+../../mat/n4611_eeg.mat 1021
+../../mat/n4614_eeg.mat 1069
+../../mat/n4617_eeg.mat 1069
+../../mat/n4619_eeg.mat 1068
+../../mat/n4620_eeg.mat 1069
+../../mat/n4621_eeg.mat 958
+../../mat/n4622_eeg.mat 1067
+../../mat/n4623_eeg.mat 1067
+../../mat/n4625_eeg.mat 899
+../../mat/n4626_eeg.mat 1069
+../../mat/n4628_eeg.mat 1034
+../../mat/n4629_eeg.mat 1046
+../../mat/n4631_eeg.mat 1069
+../../mat/n4632_eeg.mat 1067
+../../mat/n4633_eeg.mat 1069
+../../mat/n4634_eeg.mat 1068
+../../mat/n4635_eeg.mat 1050
+../../mat/n4636_eeg.mat 580
+../../mat/n4637_eeg.mat 1067
+../../mat/n4640_eeg.mat 1069
+../../mat/n4641_eeg.mat 899
+../../mat/n4643_eeg.mat 1069
+../../mat/n4645_eeg.mat 1067
+../../mat/n4647_eeg.mat 1068
+../../mat/n4650_eeg.mat 1069
+../../mat/n4652_eeg.mat 1068
+../../mat/n4654_eeg.mat 999
+../../mat/n4655_eeg.mat 1069
+../../mat/n4656_eeg.mat 1067
+../../mat/n4657_eeg.mat 959
+../../mat/n4658_eeg.mat 1019
+../../mat/n4660_eeg.mat 959
+../../mat/n4662_eeg.mat 1069
+../../mat/n4663_eeg.mat 1067
+../../mat/n4664_eeg.mat 1068
+../../mat/n4665_eeg.mat 1055
+../../mat/n4667_eeg.mat 1068
+../../mat/n4670_eeg.mat 1019
+../../mat/n4672_eeg.mat 1021
+../../mat/n4673_eeg.mat 1049
+../../mat/n4675_eeg.mat 1017
+../../mat/n4677_eeg.mat 1017
+../../mat/n4678_eeg.mat 1069
+../../mat/n4680_eeg.mat 839
+../../mat/n4681_eeg.mat 779
+../../mat/n4682_eeg.mat 1053
+../../mat/n4683_eeg.mat 899
+../../mat/n4684_eeg.mat 839
+../../mat/n4685_eeg.mat 1019
+../../mat/n4687_eeg.mat 1053
+../../mat/n4688_eeg.mat 897
+../../mat/n4689_eeg.mat 635
+../../mat/n4694_eeg.mat 809
+../../mat/n4695_eeg.mat 1053
+../../mat/n4696_eeg.mat 1053
+../../mat/n4699_eeg.mat 1019
+../../mat/n4701_eeg.mat 1056
+../../mat/n4702_eeg.mat 1051
+../../mat/n4705_eeg.mat 898
+../../mat/n4707_eeg.mat 1053
+../../mat/n4708_eeg.mat 1053
+../../mat/n4709_eeg.mat 1019
+../../mat/n4710_eeg.mat 929
+../../mat/n4714_eeg.mat 1056
+../../mat/n4715_eeg.mat 1056
+../../mat/n4716_eeg.mat 1019
+../../mat/n4718_eeg.mat 1056
+../../mat/n4719_eeg.mat 1019
+../../mat/n4721_eeg.mat 927
+../../mat/n4722_eeg.mat 1056
+../../mat/n4724_eeg.mat 959
+../../mat/n4730_eeg.mat 1019
+../../mat/n4732_eeg.mat 899
+../../mat/n4734_eeg.mat 1053
+../../mat/n4735_eeg.mat 958
+../../mat/n4737_eeg.mat 961
+../../mat/n4738_eeg.mat 899
+../../mat/n4739_eeg.mat 899
+../../mat/n4740_eeg.mat 899
+../../mat/n4741_eeg.mat 1019
+../../mat/n4743_eeg.mat 1019
+../../mat/n4745_eeg.mat 839
+../../mat/n4747_eeg.mat 959
+../../mat/n4748_eeg.mat 959
+../../mat/n4749_eeg.mat 1055
+../../mat/n4750_eeg.mat 1056
+../../mat/n4752_eeg.mat 957
+../../mat/n4754_eeg.mat 1053
+../../mat/n4755_eeg.mat 899
+../../mat/n4758_eeg.mat 1019
+../../mat/n4759_eeg.mat 899
+../../mat/n4761_eeg.mat 1053
+../../mat/n4762_eeg.mat 779
+../../mat/n4763_eeg.mat 839
+../../mat/n4764_eeg.mat 1019
+../../mat/n4771_eeg.mat 959
+../../mat/n4773_eeg.mat 1019
+../../mat/n4774_eeg.mat 795
+../../mat/n4775_eeg.mat 1053
+../../mat/n4776_eeg.mat 1053
+../../mat/n4777_eeg.mat 869
+../../mat/n4778_eeg.mat 869
+../../mat/n4780_eeg.mat 959
+../../mat/n4781_eeg.mat 1053
+../../mat/n4782_eeg.mat 899
+../../mat/n4784_eeg.mat 1019
+../../mat/n4785_eeg.mat 1019
+../../mat/n4786_eeg.mat 779
+../../mat/n4787_eeg.mat 1056
+../../mat/n4788_eeg.mat 1054
+../../mat/n4789_eeg.mat 1019
+../../mat/n4790_eeg.mat 779
+../../mat/n4791_eeg.mat 989
+../../mat/n4795_eeg.mat 1056
+../../mat/n4796_eeg.mat 1056
+../../mat/n4797_eeg.mat 1053
+../../mat/n4799_eeg.mat 951
+../../mat/n4800_eeg.mat 899
+../../mat/n4801_eeg.mat 1056
+../../mat/n4802_eeg.mat 1056
+../../mat/n4803_eeg.mat 959
+../../mat/n4804_eeg.mat 1053
+../../mat/n4805_eeg.mat 959
+../../mat/n4806_eeg.mat 1056
+../../mat/n4808_eeg.mat 1053
+../../mat/n4809_eeg.mat 959
+../../mat/n4810_eeg.mat 958
+../../mat/n4812_eeg.mat 899
+../../mat/n4815_eeg.mat 959
+../../mat/n4816_eeg.mat 1053
+../../mat/n4817_eeg.mat 1069
+../../mat/n4818_eeg.mat 1069
+../../mat/n4819_eeg.mat 892
+../../mat/n4820_eeg.mat 779
+../../mat/n4821_eeg.mat 1056
+../../mat/n4822_eeg.mat 1056
+../../mat/n4824_eeg.mat 1056
+../../mat/n4826_eeg.mat 1053
+../../mat/n4827_eeg.mat 989
+../../mat/n4829_eeg.mat 777
+../../mat/n4830_eeg.mat 1053
+../../mat/n4831_eeg.mat 1019
+../../mat/n4833_eeg.mat 899
+../../mat/n4834_eeg.mat 959
+../../mat/n4835_eeg.mat 1053
+../../mat/n4836_eeg.mat 959
+../../mat/n4837_eeg.mat 959
+../../mat/n4838_eeg.mat 959
+../../mat/n4839_eeg.mat 839
+../../mat/n4840_eeg.mat 874
+../../mat/n4843_eeg.mat 959
+../../mat/n4844_eeg.mat 959
+../../mat/n4845_eeg.mat 1056
+../../mat/n4846_eeg.mat 779
+../../mat/n4847_eeg.mat 929
+../../mat/n4848_eeg.mat 1053
+../../mat/n4849_eeg.mat 1056
+../../mat/n4851_eeg.mat 1056
+../../mat/n4852_eeg.mat 734
+../../mat/n4853_eeg.mat 839
+../../mat/n4854_eeg.mat 1018
+../../mat/n4856_eeg.mat 1019
+../../mat/n4857_eeg.mat 1019
+../../mat/n4858_eeg.mat 839
+../../mat/n4859_eeg.mat 1053
+../../mat/n4860_eeg.mat 899
+../../mat/n4861_eeg.mat 899
+../../mat/n4862_eeg.mat 1054
+../../mat/n4864_eeg.mat 899
+../../mat/n4865_eeg.mat 1053
+../../mat/n4867_eeg.mat 1053
+../../mat/n4868_eeg.mat 959
+../../mat/n4870_eeg.mat 1019
+../../mat/n4871_eeg.mat 1049
+../../mat/n4873_eeg.mat 1053
+../../mat/n4875_eeg.mat 1053
+../../mat/n4876_eeg.mat 1053
+../../mat/n4877_eeg.mat 1053
+../../mat/n4878_eeg.mat 1053
+../../mat/n4881_eeg.mat 958
+../../mat/n4882_eeg.mat 1053
+../../mat/n4884_eeg.mat 959
+../../mat/n4885_eeg.mat 1053
+../../mat/n4886_eeg.mat 779
+../../mat/n4887_eeg.mat 779
+../../mat/n4889_eeg.mat 899
+../../mat/n4892_eeg.mat 1053
+../../mat/n4893_eeg.mat 906
+../../mat/n4894_eeg.mat 1053
+../../mat/n4899_eeg.mat 959
+../../mat/n4900_eeg.mat 959
+../../mat/n4901_eeg.mat 957
+../../mat/n4907_eeg.mat 959
+../../mat/n4908_eeg.mat 959
+../../mat/n4909_eeg.mat 1053
+../../mat/n4910_eeg.mat 991
+../../mat/n4911_eeg.mat 1053
+../../mat/n4915_eeg.mat 839
+../../mat/n4916_eeg.mat 869
+../../mat/n4917_eeg.mat 779
+../../mat/n4918_eeg.mat 959
+../../mat/n4919_eeg.mat 1052
+../../mat/n4920_eeg.mat 1053
+../../mat/n4922_eeg.mat 1019
+../../mat/n4923_eeg.mat 1019
+../../mat/n4924_eeg.mat 839
+../../mat/n4925_eeg.mat 1069
+../../mat/n4926_eeg.mat 954
+../../mat/n4927_eeg.mat 899
+../../mat/n4929_eeg.mat 1019
+../../mat/n4930_eeg.mat 983
+../../mat/n4931_eeg.mat 1053
+../../mat/n4932_eeg.mat 1016
+../../mat/n4933_eeg.mat 1053
+../../mat/n4935_eeg.mat 1053
+../../mat/n4937_eeg.mat 1053
+../../mat/n4938_eeg.mat 958
+../../mat/n4939_eeg.mat 839
+../../mat/n4940_eeg.mat 958
+../../mat/n4941_eeg.mat 1053
+../../mat/n4942_eeg.mat 899
+../../mat/n4943_eeg.mat 1019
+../../mat/n4944_eeg.mat 959
+../../mat/n4946_eeg.mat 1053
+../../mat/n4947_eeg.mat 899
+../../mat/n4948_eeg.mat 838
+../../mat/n4949_eeg.mat 956
+../../mat/n4950_eeg.mat 959
+../../mat/n4951_eeg.mat 813
+../../mat/n4953_eeg.mat 1053
+../../mat/n4954_eeg.mat 959
+../../mat/n4955_eeg.mat 1053
+../../mat/n4956_eeg.mat 959
+../../mat/n4957_eeg.mat 1053
+../../mat/n4959_eeg.mat 899
+../../mat/n4960_eeg.mat 899
+../../mat/n4961_eeg.mat 921
+../../mat/n4962_eeg.mat 899
+../../mat/n4964_eeg.mat 1053
+../../mat/n4965_eeg.mat 959
+../../mat/n4966_eeg.mat 959
+../../mat/n4968_eeg.mat 899
+../../mat/n4969_eeg.mat 1051
+../../mat/n4972_eeg.mat 1019
+../../mat/n4973_eeg.mat 1053
+../../mat/n4974_eeg.mat 899
+../../mat/n4975_eeg.mat 730
+../../mat/n4977_eeg.mat 779
+../../mat/n4978_eeg.mat 959
+../../mat/n4979_eeg.mat 959
+../../mat/n4981_eeg.mat 1053
+../../mat/n4982_eeg.mat 1052
+../../mat/n4985_eeg.mat 1019
+../../mat/n4986_eeg.mat 1053
+../../mat/n4992_eeg.mat 866
+../../mat/n4994_eeg.mat 988
+../../mat/n4995_eeg.mat 1053
+../../mat/n4999_eeg.mat 1053
+../../mat/n5000_eeg.mat 1050
+../../mat/n5004_eeg.mat 959
+../../mat/n5005_eeg.mat 1053
+../../mat/n5011_eeg.mat 867
+../../mat/n5012_eeg.mat 959
+../../mat/n5013_eeg.mat 989
+../../mat/n5014_eeg.mat 1053
+../../mat/n5015_eeg.mat 983
+../../mat/n5017_eeg.mat 1069
+../../mat/n5018_eeg.mat 959
+../../mat/n5021_eeg.mat 1053
+../../mat/n5023_eeg.mat 1053
+../../mat/n5025_eeg.mat 1053
+../../mat/n5026_eeg.mat 1053
+../../mat/n5029_eeg.mat 1053
+../../mat/n5031_eeg.mat 1053
+../../mat/n5032_eeg.mat 1053
+../../mat/n5033_eeg.mat 940
+../../mat/n5034_eeg.mat 1053
+../../mat/n5035_eeg.mat 1053
+../../mat/n5036_eeg.mat 1053
+../../mat/n5038_eeg.mat 1050
+../../mat/n5039_eeg.mat 1053
+../../mat/n5040_eeg.mat 1053
+../../mat/n5041_eeg.mat 839
+../../mat/n5042_eeg.mat 959
+../../mat/n5043_eeg.mat 1051
+../../mat/n5045_eeg.mat 902
+../../mat/n5046_eeg.mat 1004
+../../mat/n5047_eeg.mat 1053
+../../mat/n5048_eeg.mat 1053
+../../mat/n5050_eeg.mat 948
+../../mat/n5051_eeg.mat 959
+../../mat/n5052_eeg.mat 1053
+../../mat/n5053_eeg.mat 1053
+../../mat/n5054_eeg.mat 1053
+../../mat/n5055_eeg.mat 1053
+../../mat/n5056_eeg.mat 1053
+../../mat/n5058_eeg.mat 1053
+../../mat/n5059_eeg.mat 959
+../../mat/n5061_eeg.mat 1050
+../../mat/n5062_eeg.mat 980
+../../mat/n5063_eeg.mat 1051
+../../mat/n5064_eeg.mat 1053
+../../mat/n5066_eeg.mat 1053
+../../mat/n5067_eeg.mat 839
+../../mat/n5068_eeg.mat 882
+../../mat/n5069_eeg.mat 1019
+../../mat/n5072_eeg.mat 1053
+../../mat/n5075_eeg.mat 899
+../../mat/n5076_eeg.mat 1019
+../../mat/n5077_eeg.mat 899
+../../mat/n5078_eeg.mat 1053
+../../mat/n5079_eeg.mat 1053
+../../mat/n5080_eeg.mat 1053
+../../mat/n5081_eeg.mat 1019
+../../mat/n5082_eeg.mat 1019
+../../mat/n5085_eeg.mat 1053
+../../mat/n5086_eeg.mat 987
+../../mat/n5088_eeg.mat 1053
+../../mat/n5089_eeg.mat 1053
+../../mat/n5090_eeg.mat 1053
+../../mat/n5091_eeg.mat 1052
+../../mat/n5092_eeg.mat 992
+../../mat/n5093_eeg.mat 839
+../../mat/n5094_eeg.mat 1053
+../../mat/n5097_eeg.mat 1053
+../../mat/n5098_eeg.mat 959
+../../mat/n5099_eeg.mat 1053
+../../mat/n5101_eeg.mat 1019
+../../mat/n5103_eeg.mat 1053
+../../mat/n5104_eeg.mat 1053
+../../mat/n5105_eeg.mat 1068
+../../mat/n5106_eeg.mat 1049
+../../mat/n5107_eeg.mat 1053
+../../mat/n5108_eeg.mat 1053
+../../mat/n5110_eeg.mat 1053
+../../mat/n5111_eeg.mat 1053
+../../mat/n5112_eeg.mat 956
+../../mat/n5113_eeg.mat 1019
+../../mat/n5116_eeg.mat 1051
+../../mat/n5117_eeg.mat 1050
+../../mat/n5119_eeg.mat 1053
+../../mat/n5122_eeg.mat 1069
+../../mat/n5123_eeg.mat 1053
+../../mat/n5124_eeg.mat 1053
+../../mat/n5125_eeg.mat 1069
+../../mat/n5126_eeg.mat 1053
+../../mat/n5128_eeg.mat 1053
+../../mat/n5129_eeg.mat 1018
+../../mat/n5130_eeg.mat 1061
+../../mat/n5132_eeg.mat 1017
+../../mat/n5133_eeg.mat 1067
+../../mat/n5135_eeg.mat 1053
+../../mat/n5136_eeg.mat 1053
+../../mat/n5137_eeg.mat 959
+../../mat/n5138_eeg.mat 1053
+../../mat/n5140_eeg.mat 1019
+../../mat/n5142_eeg.mat 684
+../../mat/n5143_eeg.mat 1052
+../../mat/n5144_eeg.mat 1069
+../../mat/n5145_eeg.mat 1051
+../../mat/n5146_eeg.mat 1019
+../../mat/n5147_eeg.mat 959
+../../mat/n5148_eeg.mat 1067
+../../mat/n5149_eeg.mat 1053
+../../mat/n5150_eeg.mat 1047
+../../mat/n5151_eeg.mat 1069
+../../mat/n5153_eeg.mat 1053
+../../mat/n5154_eeg.mat 1053
+../../mat/n5156_eeg.mat 1053
+../../mat/n5157_eeg.mat 1053
+../../mat/n5162_eeg.mat 1053
+../../mat/n5163_eeg.mat 1050
+../../mat/n5164_eeg.mat 1053
+../../mat/n5165_eeg.mat 1053
+../../mat/n5166_eeg.mat 1068
+../../mat/n5167_eeg.mat 1053
+../../mat/n5169_eeg.mat 1019
+../../mat/n5170_eeg.mat 1053
+../../mat/n5172_eeg.mat 959
+../../mat/n5173_eeg.mat 1069
+../../mat/n5176_eeg.mat 1053
+../../mat/n5177_eeg.mat 1018
+../../mat/n5178_eeg.mat 1053
+../../mat/n5179_eeg.mat 1052
+../../mat/n5181_eeg.mat 1053
+../../mat/n5182_eeg.mat 803
+../../mat/n5183_eeg.mat 1053
+../../mat/n5185_eeg.mat 958
+../../mat/n5186_eeg.mat 1053
+../../mat/n5187_eeg.mat 844
+../../mat/n5189_eeg.mat 1053
+../../mat/n5192_eeg.mat 1053
+../../mat/n5195_eeg.mat 994
+../../mat/n5196_eeg.mat 1019
+../../mat/n5199_eeg.mat 959
+../../mat/n5200_eeg.mat 1053
+../../mat/n5201_eeg.mat 1052
+../../mat/n5202_eeg.mat 1069
+../../mat/n5204_eeg.mat 1053
+../../mat/n5205_eeg.mat 845
+../../mat/n5208_eeg.mat 1019
+../../mat/n5209_eeg.mat 860
+../../mat/n5210_eeg.mat 1050
+../../mat/n5211_eeg.mat 1015
+../../mat/n5213_eeg.mat 1053
+../../mat/n5215_eeg.mat 821
+../../mat/n5217_eeg.mat 958
+../../mat/n5218_eeg.mat 1069
+../../mat/n5219_eeg.mat 1053
+../../mat/n5220_eeg.mat 959
+../../mat/n5222_eeg.mat 1053
+../../mat/n5223_eeg.mat 1053
+../../mat/n5225_eeg.mat 834
+../../mat/n5226_eeg.mat 1069
+../../mat/n5227_eeg.mat 1053
+../../mat/n5229_eeg.mat 1051
+../../mat/n5230_eeg.mat 1032
+../../mat/n5231_eeg.mat 942
+../../mat/n5232_eeg.mat 1053
+../../mat/n5233_eeg.mat 1069
+../../mat/n5234_eeg.mat 1069
+../../mat/n5235_eeg.mat 1053
+../../mat/n5237_eeg.mat 959
+../../mat/n5238_eeg.mat 1019
+../../mat/n5241_eeg.mat 1069
+../../mat/n5242_eeg.mat 1069
+../../mat/n5243_eeg.mat 1053
+../../mat/n5244_eeg.mat 1053
+../../mat/n5245_eeg.mat 1053
+../../mat/n5249_eeg.mat 1069
+../../mat/n5250_eeg.mat 1053
+../../mat/n5251_eeg.mat 1017
+../../mat/n5252_eeg.mat 958
+../../mat/n5253_eeg.mat 1039
+../../mat/n5254_eeg.mat 1053
+../../mat/n5256_eeg.mat 1053
+../../mat/n5257_eeg.mat 1069
+../../mat/n5258_eeg.mat 1053
+../../mat/n5259_eeg.mat 1053
+../../mat/n5261_eeg.mat 1019
+../../mat/n5263_eeg.mat 1053
+../../mat/n5264_eeg.mat 1051
+../../mat/n5265_eeg.mat 1019
+../../mat/n5266_eeg.mat 1053
+../../mat/n5270_eeg.mat 1062
+../../mat/n5272_eeg.mat 1004
+../../mat/n5273_eeg.mat 1053
+../../mat/n5274_eeg.mat 1053
+../../mat/n5275_eeg.mat 1018
+../../mat/n5278_eeg.mat 1066
+../../mat/n5279_eeg.mat 1019
+../../mat/n5281_eeg.mat 1053
+../../mat/n5283_eeg.mat 1053
+../../mat/n5285_eeg.mat 1053
+../../mat/n5286_eeg.mat 1067
+../../mat/n5288_eeg.mat 1053
+../../mat/n5289_eeg.mat 958
+../../mat/n5290_eeg.mat 1053
+../../mat/n5292_eeg.mat 1069
+../../mat/n5294_eeg.mat 1051
+../../mat/n5295_eeg.mat 899
+../../mat/n5296_eeg.mat 1069
+../../mat/n5298_eeg.mat 1053
+../../mat/n5299_eeg.mat 897
+../../mat/n5300_eeg.mat 899
+../../mat/n5303_eeg.mat 1018
+../../mat/n5306_eeg.mat 1067
+../../mat/n5309_eeg.mat 929
+../../mat/n5312_eeg.mat 736
+../../mat/n5313_eeg.mat 1069
+../../mat/n5315_eeg.mat 1053
+../../mat/n5316_eeg.mat 1053
+../../mat/n5317_eeg.mat 851
+../../mat/n5320_eeg.mat 1069
+../../mat/n5322_eeg.mat 1053
+../../mat/n5323_eeg.mat 899
+../../mat/n5324_eeg.mat 1069
+../../mat/n5325_eeg.mat 959
+../../mat/n5329_eeg.mat 1053
+../../mat/n5330_eeg.mat 988
+../../mat/n5331_eeg.mat 1040
+../../mat/n5332_eeg.mat 1050
+../../mat/n5333_eeg.mat 1051
+../../mat/n5335_eeg.mat 1051
+../../mat/n5336_eeg.mat 1069
+../../mat/n5337_eeg.mat 1053
+../../mat/n5338_eeg.mat 1069
+../../mat/n5339_eeg.mat 1053
+../../mat/n5340_eeg.mat 1053
+../../mat/n5341_eeg.mat 959
+../../mat/n5343_eeg.mat 1069
+../../mat/n5344_eeg.mat 1069
+../../mat/n5348_eeg.mat 1053
+../../mat/n5350_eeg.mat 1069
+../../mat/n5351_eeg.mat 1051
+../../mat/n5352_eeg.mat 858
+../../mat/n5353_eeg.mat 1053
+../../mat/n5354_eeg.mat 922
+../../mat/n5355_eeg.mat 1069
+../../mat/n5356_eeg.mat 1069
+../../mat/n5357_eeg.mat 956
+../../mat/n5358_eeg.mat 1017
+../../mat/n5360_eeg.mat 1069
+../../mat/n5362_eeg.mat 1069
+../../mat/n5363_eeg.mat 1069
+../../mat/n5365_eeg.mat 1065
+../../mat/n5367_eeg.mat 837
+../../mat/n5370_eeg.mat 1069
+../../mat/n5371_eeg.mat 1066
+../../mat/n5372_eeg.mat 1069
+../../mat/n5373_eeg.mat 1069
+../../mat/n5374_eeg.mat 1067
+../../mat/n5376_eeg.mat 1067
+../../mat/n5377_eeg.mat 1069
+../../mat/n5379_eeg.mat 1019
+../../mat/n5382_eeg.mat 1067
+../../mat/n5385_eeg.mat 1069
+../../mat/n5386_eeg.mat 1069
+../../mat/n5387_eeg.mat 1069
+../../mat/n5389_eeg.mat 899
+../../mat/n5390_eeg.mat 1019
+../../mat/n5392_eeg.mat 737
+../../mat/n5396_eeg.mat 1065
+../../mat/n5397_eeg.mat 1069
+../../mat/n5399_eeg.mat 959
+../../mat/n5400_eeg.mat 1069
+../../mat/n5402_eeg.mat 1069
+../../mat/n5403_eeg.mat 1019
+../../mat/n5404_eeg.mat 1069
+../../mat/n5405_eeg.mat 1069
+../../mat/n5406_eeg.mat 1069
+../../mat/n5407_eeg.mat 1069
+../../mat/n5408_eeg.mat 1018
+../../mat/n5411_eeg.mat 1069
+../../mat/n5412_eeg.mat 1019
+../../mat/n5413_eeg.mat 1049
+../../mat/n5414_eeg.mat 1069
+../../mat/n5415_eeg.mat 1068
+../../mat/n5417_eeg.mat 958
+../../mat/n5418_eeg.mat 1018
+../../mat/n5419_eeg.mat 1069
+../../mat/n5420_eeg.mat 809
+../../mat/n5422_eeg.mat 1067
+../../mat/n5423_eeg.mat 959
+../../mat/n5425_eeg.mat 1069
+../../mat/n5426_eeg.mat 994
+../../mat/n5427_eeg.mat 1069
+../../mat/n5428_eeg.mat 994
+../../mat/n5430_eeg.mat 838
+../../mat/n5431_eeg.mat 1067
+../../mat/n5432_eeg.mat 1069
+../../mat/n5433_eeg.mat 839
+../../mat/n5434_eeg.mat 1048
+../../mat/n5435_eeg.mat 1069
+../../mat/n5436_eeg.mat 1069
+../../mat/n5438_eeg.mat 1069
+../../mat/n5439_eeg.mat 1069
+../../mat/n5443_eeg.mat 1069
+../../mat/n5444_eeg.mat 1068
+../../mat/n5445_eeg.mat 1067
+../../mat/n5446_eeg.mat 1067
+../../mat/n5447_eeg.mat 1069
+../../mat/n5448_eeg.mat 1019
+../../mat/n5449_eeg.mat 1068
+../../mat/n5450_eeg.mat 1068
+../../mat/n5452_eeg.mat 1069
+../../mat/n5454_eeg.mat 1069
+../../mat/n5455_eeg.mat 959
+../../mat/n5456_eeg.mat 1069
+../../mat/n5457_eeg.mat 1069
+../../mat/n5458_eeg.mat 784
+../../mat/n5459_eeg.mat 1069
+../../mat/n5460_eeg.mat 1069
+../../mat/n5461_eeg.mat 1019
+../../mat/n5463_eeg.mat 1017
diff --git a/data/shhs_preprocess.py b/data/shhs_preprocess.py
new file mode 100644
index 0000000000000000000000000000000000000000..6e122f3e6c8456dc5484ff9dc7230d79147f8167
--- /dev/null
+++ b/data/shhs_preprocess.py
@@ -0,0 +1,376 @@
+import os
+import shutil
+import numpy as np
+import matplotlib.pyplot as plt
+from tqdm import tqdm
+import shutil
+import librosa
+
+from scipy.signal import iirnotch, lfilter
+from data_utils import butter_bandpass_filter, correct_ecg_inversion
+import pickle
+import pandas as pd
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+NOTCH_FREQ = 60
+EEG_LOWCUT = 0.3
+EEG_HIGHCUT = 40
+EMG_LOWCUT = 10
+EMG_HIGHCUT = 1000
+ECG_LOWCUT = 0.3
+ECG_HIGHCUT = 60
+FLOW_LOWCUT = 0
+FLOW_HIGHCUT = 15
+
+
+
+NUM_PROCESS = 4
+
+import argparse
+import multiprocessing
+
+
+
+# SAMPLING_RATE = 250 if cfg.shhs2 else 125
+TARGET_RESAMPLE = 100
+
+# do_resample = (SAMPLING_RATE != TARGET_RESAMPLE)
+
+
+
+
+
+def process_ecg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, ECG_LOWCUT, ECG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+
+ filtered = filtered.reshape(-1, sampling_rate*30)
+ # filtered = librosa.resample(filtered, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ filtered_epochs = []
+
+ for epoch in filtered:
+ inv_epoch, _ = correct_ecg_inversion(epoch, TARGET_RESAMPLE)
+ filtered_epochs.append(inv_epoch)
+
+ filtered = np.stack(filtered_epochs, axis=0)
+
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = np.reshape(filtered, (-1,1))
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+
+def process_eeg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EEG_LOWCUT, EEG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_emg(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, EMG_LOWCUT, EMG_HIGHCUT, sampling_rate)
+ b_notch, a_notch = iirnotch(NOTCH_FREQ, 30, sampling_rate)
+ filtered = lfilter(b_notch, a_notch, filtered)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def process_flow(args):
+ sig, chn_grp, chn = args
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ data = data.reshape(-1, 1)
+ # Apply bandpass filter
+ filtered = butter_bandpass_filter(data, FLOW_LOWCUT, FLOW_HIGHCUT, sampling_rate)
+ if sampling_rate != TARGET_RESAMPLE:
+ filtered = librosa.resample(filtered, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+
+ # median filter?
+
+ filtered = filtered.reshape(-1, TARGET_RESAMPLE*30)
+
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, filtered.astype(np.float32))
+ return
+ else:
+ return filtered
+
+def save_mmap(results, sig_list, chn_grp, chn, split='train'):
+ signame_list = [sig.split('.')[0] for sig in sig_list]
+ epoch_lengths = [sig.shape[0] for sig in results]
+ metadata = dict()
+ sig_info = dict()
+ start, end = 0, 0
+ for signame, sig in zip(signame_list, results):
+ length = sig.shape[0]
+ end = start + length
+ info = dict()
+ info['pos'] = (start, end)
+ info['stats'] = {'sum': float(np.sum(sig)), 'sumsq': float(np.sum(sig ** 2))}
+ sig_info[signame] = info
+ start = end
+
+
+ mmap_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ signals_cat = np.concatenate(results, axis=0).astype(np.float32)
+ os.makedirs(os.path.dirname(mmap_path), exist_ok=True)
+ data = np.memmap(mmap_path, dtype=np.float32, mode='w+', shape=signals_cat.shape)
+ data[:] = signals_cat
+ data.flush()
+
+ metadata['sig_info'] = sig_info
+ metadata['data_shape'] = signals_cat.shape
+ info_path = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ with open(info_path, 'wb') as f:
+ pickle.dump(metadata, f)
+
+
+def preprocess(sig_list, chn_grp=None, chn=None, split='train'):
+ def _process(sig_list, chn_grp, chn, split):
+
+ print(f"Processing {chn_grp}/{chn}")
+ # if not (chn == "C4-A1" or chn == "AIRFLOW"): continue
+
+ if chn_grp in ['EEG','EOG']:
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_eeg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['EMG']:
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_emg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['ECG']:
+
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_ecg, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+ elif chn_grp in ['ABD', 'CHEST', 'AIRFLOW']:
+ # sig_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))
+ input_list = [(sig, chn_grp, chn) for sig in sig_list]
+ with multiprocessing.Pool(NUM_PROCESS) as pool:
+ results = list(tqdm(pool.imap(process_flow, input_list), total=len(input_list)))
+ if cfg.save_type == 'mmap':
+ save_mmap(results, sig_list, chn_grp, chn, split)
+
+
+ else:
+ results = []
+ # for sig in tqdm(sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))):
+ for sig in tqdm(sig_list):
+ sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ data = np.load(sig_path)
+ sampling_rate = data.shape[1] // (30)
+ if sampling_rate != TARGET_RESAMPLE or chn == 'SaO2':
+ # assuming 30s epochs
+ data = data.reshape(-1, 1)
+ if chn == 'SaO2':
+ data = librosa.resample(data, orig_sr=sampling_rate, target_sr=1, axis=0, res_type='soxr_qq')
+ data = data / 1e8 # data range 0 to 1e8
+ if np.max(data) > 1 or np.min(data) < 0:
+ print(f"Warning: SaO2 values out of range: {sig} with min {np.min(data)} and max {np.max(data)}")
+ data = data.reshape(-1, 1*30)
+ else:
+ data = librosa.resample(data, orig_sr=sampling_rate, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ data = data.reshape(-1, TARGET_RESAMPLE*30)
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # shutil.copy(sig_path, output_path)
+ if cfg.save_type == 'npy':
+ # Save processed data
+ output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ np.save(output_path, data)
+ elif cfg.save_type == 'mmap':
+ results.append(data)
+ # sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)))
+ save_mmap(results, sig_list, chn_grp, chn, split)
+ # for sig in tqdm(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn))):
+ # sig_path = os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn, sig)
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # # shutil.copy(sig_path, output_path)
+ # data = np.load(sig_path)
+ # data = data.reshape(-1, 1)
+ # data = librosa.resample(data, orig_sr=SAMPLING_RATE, target_sr=TARGET_RESAMPLE, axis=0, res_type='soxr_qq')
+ # data = data.reshape(-1, TARGET_RESAMPLE*30)
+
+ # # Save processed data
+ # output_path = os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn, sig)
+ # os.makedirs(os.path.dirname(output_path), exist_ok=True)
+ # np.save(output_path, data)
+
+ if chn_grp is not None and chn is not None:
+ _process(sig_list, chn_grp, chn, split)
+ return
+ else:
+ for chn_grp in os.listdir(os.path.join(BASE_PATH, cfg.data_dir)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ continue
+ for chn in os.listdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp)):
+ if not os.path.isdir(os.path.join(BASE_PATH, cfg.data_dir, chn_grp, chn)):
+ continue
+ _process(sig_list, chn_grp, chn, split)
+
+
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default='shhs1/signals_MAE', help='SHHS raw data location')
+parser.add_argument('--output_dir', default='shhs1/mmap_signals_MAE_processed', help='SHHS processed data location')
+parser.add_argument('--ann_split', action='store_true', help='To split annotation files into train/val/test')
+parser.add_argument('--save_type', default='mmap', help='Which data type to save. "npy" or "mmap"')
+parser.add_argument('--chn_grp', default=None, help='If specified, only preprocess this channel group')
+parser.add_argument('--chn', default=None, help='If specified, only preprocess this channel')
+parser.add_argument('--shhs2', action='store_true', help='SHHS2 preprocessing?')
+cfg = parser.parse_args()
+
+if __name__ == '__main__':
+
+ if not cfg.shhs2:
+ def get_shhs_lists(shhs_split_file):
+ ids = pd.read_csv(os.path.join("shhs_meta_data", shhs_split_file), header=None, names=['a'])
+ ids = ids['a'].values.tolist()
+ list_files = ["shhs1-20"+id[11:15] for id in ids]
+ return [id + ".npy" for id in list_files]
+
+ list_files_train = get_shhs_lists("train_list.txt")
+ list_files_val = get_shhs_lists("eval_list.txt")
+ list_files_test = get_shhs_lists("test_list.txt")
+
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, "EEG", "C3-A2")))
+
+ list_files_train = list(set(list_files_train).intersection(set(sig_list)))
+ list_files_val = list(set(list_files_val).intersection(set(sig_list)))
+ list_files_test = list(set(list_files_test).intersection(set(sig_list)))
+
+ print("Number of records in training set:", len(list_files_train))
+ print("Number of records in validation set:", len(list_files_val))
+ print("Number of records in test set:", len(list_files_test))
+ else:
+ # For SHHS2, use all data for preprocessing
+ sig_list = sorted(os.listdir(os.path.join(BASE_PATH, cfg.data_dir, "EEG", "C3-A2")))
+ list_files_train = sig_list
+ list_files_val = []
+ list_files_test = []
+
+ print("Processing training set...")
+ preprocess(list_files_train, cfg.chn_grp, cfg.chn, split='train')
+ print("Processing evaluation set...")
+ preprocess(list_files_val, cfg.chn_grp, cfg.chn, split='val')
+ print("Processing test set...")
+ preprocess(list_files_test, cfg.chn_grp, cfg.chn, split='test')
+
+
+ # Reorganize annotations files
+ # ANN_PATH = os.path.join(BASE_PATH, 'shhs1/annotations')
+ if cfg.ann_split and not cfg.shhs2:
+ ANN_PATH = os.path.join(os.path.dirname(os.path.join(BASE_PATH, cfg.data_dir)), 'annotations')
+ NEW_ANN_PATH = ANN_PATH.replace('annotations', 'annotations_split')
+ os.makedirs(NEW_ANN_PATH, exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'train'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'val'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_ANN_PATH,'test'), exist_ok=True)
+
+ for fname in tqdm(list_files_train):
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'train', ann_fname))
+ for fname in tqdm(list_files_val):
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'val', ann_fname))
+ for fname in tqdm(list_files_test):
+ ann_fname = fname.replace('.npy', '_ann.npy')
+ shutil.copy(os.path.join(ANN_PATH, ann_fname), os.path.join(NEW_ANN_PATH, 'test', ann_fname))
+
+ AH_PATH = os.path.join(BASE_PATH, 'shhs1/ah_labels')
+ NEW_AH_PATH = os.path.join(BASE_PATH, 'shhs1/ah_labels_split')
+ os.makedirs(NEW_AH_PATH, exist_ok=True)
+ os.makedirs(os.path.join(NEW_AH_PATH,'train'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_AH_PATH,'val'), exist_ok=True)
+ os.makedirs(os.path.join(NEW_AH_PATH,'test'), exist_ok=True)
+ for fname in tqdm(list_files_train):
+ ann_fname = fname.replace('.npy', '_ah.npy')
+ shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'train', ann_fname))
+ for fname in tqdm(list_files_val):
+ ann_fname = fname.replace('.npy', '_ah.npy')
+ shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'val', ann_fname))
+ for fname in tqdm(list_files_test):
+ ann_fname = fname.replace('.npy', '_ah.npy')
+ shutil.copy(os.path.join(AH_PATH, ann_fname), os.path.join(NEW_AH_PATH, 'test', ann_fname))
+
+
+ for split in ['train', 'val', 'test']:
+ # create link files to respiratory channels
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP'), exist_ok=True)
+ for chn_grp in ['ABD', 'AIRFLOW']:
+ chns = [f.split('.')[0] for f in os.listdir(os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp))]
+ for chn in chns:
+ src_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.mmap')
+ src_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, chn_grp, f'{chn}.pickle')
+ dst_mmap = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.mmap')
+ dst_pickle = os.path.join(BASE_PATH, cfg.output_dir, split, 'RESP', f'{chn}.pickle')
+ if not os.path.exists(dst_mmap):
+ os.symlink(src_mmap, dst_mmap)
+ if not os.path.exists(dst_pickle):
+ os.symlink(src_pickle, dst_pickle)
+
diff --git a/data/shhs_process_rawdata.py b/data/shhs_process_rawdata.py
new file mode 100644
index 0000000000000000000000000000000000000000..cd5df09283b4fa25a5be3470da5ee0c95f21f98d
--- /dev/null
+++ b/data/shhs_process_rawdata.py
@@ -0,0 +1,215 @@
+import os
+import scipy
+import numpy as np
+#!pip install wfdb
+import pandas as pd
+from mne.io import concatenate_raws, read_raw_edf
+import xml.etree.ElementTree as ET
+import multiprocessing
+
+BASE_PATH = os.path.join(os.path.dirname(os.path.dirname(os.path.abspath(__file__))), 'datasets')
+EPOCH_SEC_SIZE = 30
+# ALL_CHANNELS = ['SaO2', 'H.R.', 'EEG(sec)', 'ECG', 'EMG', 'EOG(L)', 'EOG(R)', 'EEG', 'THOR RES', 'ABDO RES', 'POSITION', 'LIGHT', 'NEW AIR', 'OX stat']
+AIRFLOW_NAMES = ["NEW AIR", "NEWAIR", "AIRFLOW", "AIRFLOW-0", "airflow", "new A/F", "New Air", "AUX"]
+EEG2_NAMES = ["EEG2", "EEG 2", "EEG(sec)", "EEG sec", "EEG(SEC)"]
+SELECT_CHNS = ['SaO2', 'ECG', 'EMG', 'EOG(L)', 'EOG(R)', 'EEG', 'ABDO RES'] + AIRFLOW_NAMES + EEG2_NAMES
+CHN_SAVE_DICT = {
+ 'SaO2': ('SaO2','SaO2'),
+ # 'EEG(sec)': ('EEG', 'C4-A1'),
+ # 'EEG2': ('EEG', 'C4-A1'),
+ # 'EEG 2': ('EEG', 'C4-A1'),
+ # 'EEG sec': ('EEG', 'C4-A1'),
+ 'ECG': ('ECG', 'ECG'),
+ 'EMG': ('EMG', 'EMG'),
+ 'EOG(L)': ('EOG', 'EOG-Diff'),
+ 'EOG(R)': ('EOG', 'EOG-Diff'),
+ 'EEG': ('EEG', 'C3-A2'),
+ 'ABDO RES': ('ABD', 'ABD'),
+ 'NEW AIR': ('AIRFLOW', 'AIRFLOW'),
+ 'AIRFLOW': ('AIRFLOW', 'AIRFLOW')
+}
+
+
+
+import argparse
+parser = argparse.ArgumentParser()
+parser.add_argument('--data_dir', default="#_SHHS/polysomnography/edfs/shhs1", help='SHHS1 raw data location')
+parser.add_argument('--output_dir', default='shhs1/signals_MAE', help='SHHS1 processed data location')
+parser.add_argument('--annotation_dir', default='#_SHHS/polysomnography/annotations-events-profusion/shhs1', help='SHHS1 annotations location')
+parser.add_argument('--shhs2', action='store_true', help='Use SHHS2 dataset')
+
+cfg = parser.parse_args()
+
+from tqdm.auto import tqdm
+
+def process_signal(raw, select_idx, chns, fname):
+ # sampling rate from instance
+ raw_sampling_rate = int(raw.info['sfreq'])
+ raw_df = raw.to_data_frame()
+ # print(raw_df.head())
+ print(raw_df.columns)
+ for chn in chns:
+ if chn == "EOG(L)":
+ raw_df['EOG-Diff'] = raw_df['EOG(L)'] - raw_df['EOG(R)']
+ raw_ch_df = raw_df['EOG-Diff']
+ elif chn == "EOG(R)":
+ continue
+ elif chn in AIRFLOW_NAMES:
+ if chn in raw_df.columns:
+ raw_ch_df = raw_df[chn]
+ else:
+ continue
+ elif chn in EEG2_NAMES:
+ if chn in raw_df.columns:
+ raw_ch_df = raw_df[chn]
+ else:
+ continue
+ else:
+ raw_ch_df = raw_df[chn]
+ raw_ch_df = raw_ch_df.to_frame()
+ raw_ch_df.set_index(np.arange(len(raw_ch_df)))
+
+ # Remove movement and unknown stages if any
+ raw_ch = raw_ch_df.values
+
+ # Verify that we can split into 30-s epochs
+ if len(raw_ch) % (EPOCH_SEC_SIZE * raw_sampling_rate) != 0:
+ print(f"Length of raw channel ({len(raw_ch)}) \
+ is not multiple of raw sampling rate and epoch size ({EPOCH_SEC_SIZE} * {raw_sampling_rate})")
+ return np.array([])
+
+ # get (# of epochs) = (# of datapoints) / (30sec * 100Hz)
+ n_epochs = len(raw_ch) / (EPOCH_SEC_SIZE * raw_sampling_rate)
+
+ # Get epochs and their corresponding labels
+ x = np.asarray(np.split(raw_ch, n_epochs)).astype(np.float32) # split epochs
+
+ x = x[select_idx]
+ x = x.reshape((-1, EPOCH_SEC_SIZE * raw_sampling_rate))
+
+ if chn in AIRFLOW_NAMES:
+ chn_grp, chn_rename = 'AIRFLOW', 'AIRFLOW'
+ elif chn in EEG2_NAMES:
+ chn_grp, chn_rename = 'EEG', 'C4-A1'
+ else:
+ chn_grp, chn_rename = CHN_SAVE_DICT[chn]
+ # chn_grp = CHN_SAVE_DICT[chn][0] if chn not in AIRFLOW_NAMES else 'AIRFLOW'
+ # chn_rename = CHN_SAVE_DICT[chn][1] if chn not in AIRFLOW_NAMES else 'AIRFLOW'
+ # print(chn_grp, chn_rename)
+ os.makedirs(os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn_rename), exist_ok=True)
+ np.save(os.path.join(BASE_PATH, cfg.output_dir, chn_grp, chn_rename, f"{fname}.npy"), x)
+
+def process_data(args):
+
+ ann_fname, edf_fname, file_id, shhs2 = args
+ print(args)
+
+ ann_filename = os.path.basename(edf_fname).replace(".edf", "_ann.npy")
+ # if os.path.exists(os.path.join(BASE_PATH, cfg.output_dir, "annotations", ann_filename)):
+ # return
+
+ labels = []
+
+ # Read annotation and its header
+ t = ET.parse(ann_fname)
+
+ r = t.getroot()
+ faulty_File = 0
+
+ for i in range(len(r[4])):
+ lbl = int(r[4][i].text)
+ # print(lbl)
+ if lbl == 4: # make stages N3, N4 same as N3
+ labels.append(3)
+ elif lbl == 5: # Assign label 4 for REM stage
+ labels.append(4)
+ else:
+ labels.append(lbl)
+ if lbl > 5: # some files may contain labels > 5 BUT not the selected ones.
+ faulty_File = 1
+
+ if faulty_File == 1:
+ print("Faulty labels found!!")
+ return -1
+
+ labels = np.asarray(labels) # label list to npaprray
+
+ # corresponding labels
+ y = labels.astype(np.int32)
+
+ # Select on sleep periods
+ w_edge_mins = 30
+ # get index of first not WAKE
+ nw_idx = np.where(y != 0)[0]
+ # start from 30min before first WAKE
+ start_idx = nw_idx[0] - (w_edge_mins * 2)
+ # end at 30min after first WAKE
+ end_idx = nw_idx[-1] + (w_edge_mins * 2)
+ if start_idx < 0:
+ start_idx = 0
+ if end_idx >= len(y):
+ end_idx = len(y) - 1
+
+ select_idx = np.arange(start_idx, end_idx + 1)
+
+ # only selected labels
+ y = y[select_idx]
+
+ # get RawEDF instance
+ # !!!!!!!!!!!!!!!!!! 12~13 sec
+ raw = read_raw_edf(edf_fname, preload=True, stim_channel=None, verbose=None)
+ process_signal(raw, select_idx, SELECT_CHNS, os.path.basename(edf_fname).split('.')[0])
+
+
+ ann_dir = os.path.join(BASE_PATH, 'shhs1' if not shhs2 else 'shhs2', "annotations")
+ os.makedirs(ann_dir, exist_ok=True)
+ np.save(os.path.join(ann_dir, ann_filename), arr=y)
+
+
+
+if __name__ == '__main__':
+
+ # data_dir = '/tf/00_data/kdpark/physionet_2018/physionet_rawdata'
+ file_list = os.listdir(os.path.join(BASE_PATH, cfg.data_dir))
+ file_list = [f for f in file_list if f.startswith('tr')]
+
+ filenames_edf = pd.read_csv("shhs_meta_data/filenames_edf.txt", header=None, names=['a'])
+ filenames_edf = filenames_edf['a'].values.tolist()
+ filenames_ann = pd.read_csv("shhs_meta_data/filenames_ann.txt", header=None, names=['a'])
+ filenames_ann = filenames_ann['a'].values.tolist()
+
+
+ if cfg.shhs2:
+ edf_fnames = [os.path.join(BASE_PATH, cfg.data_dir, f) for f in os.listdir(os.path.join(BASE_PATH, cfg.data_dir))]
+ ann_fnames = [os.path.join(BASE_PATH, cfg.annotation_dir, f) for f in os.listdir(os.path.join(BASE_PATH, cfg.annotation_dir))]
+ else:
+ # make actual file names for selected edf files and make a list
+ edf_fnames = [os.path.join(BASE_PATH, cfg.data_dir, filename_edf) for filename_edf in filenames_edf]
+ ann_fnames = [os.path.join(BASE_PATH, cfg.annotation_dir, filename_ann) for filename_ann in filenames_ann]
+
+ edf_fnames.sort() # sort edf file names list
+ ann_fnames.sort() # sort ann file names list
+
+
+ # sorted edf/ann file names list to nparray
+ # edf_fnames = np.asarray(edf_fnames)
+ # ann_fnames = np.asarray(ann_fnames)
+
+ input_list = zip(ann_fnames, edf_fnames, range(len(ann_fnames)), len(ann_fnames) * [cfg.shhs2])
+
+
+ # redo_list = ['shhs1-203353.npy', 'shhs1-203171.npy', 'shhs1-203301.npy', 'shhs1-203011.npy', 'shhs1-203300.npy', 'shhs1-203419.npy', 'shhs1-203286.npy', 'shhs1-203375.npy','shhs1-201820.npy']
+ # input_list = [args for args in input_list if os.path.basename(args[1]).replace('.edf', '.npy') in redo_list]
+ # print(len(input_list))
+ # exit(0)
+
+ # for args in input_list:
+ # ann_fname, edf_fname, file_id = args
+ # if 'shhs1-201820' in edf_fname:
+ # process_data(args)
+ # break
+
+ with multiprocessing.Pool(8) as pool:
+ list(tqdm(pool.imap(process_data, input_list), total=len(ann_fnames)))
+
+
diff --git a/evaluate.py b/evaluate.py
new file mode 100644
index 0000000000000000000000000000000000000000..081ea17f3509b0887b29c93b553ef7d17d984d8b
--- /dev/null
+++ b/evaluate.py
@@ -0,0 +1,502 @@
+from collections import defaultdict
+import pytorch_lightning as pl
+from pytorch_lightning.loggers import WandbLogger
+from torchmetrics import ConfusionMatrix, CohenKappa
+from torchmetrics.classification import Accuracy, Precision, Recall, F1Score
+import torch
+import torch.nn as nn
+import logging
+import sys
+
+
+
+import os
+
+from pytorch_lightning.callbacks import ModelCheckpoint
+import numpy as np
+
+import data.data_loader as data_loader
+import yaml
+
+import models
+from models.utils import cox_ph_loss, CIndex, AUROC
+from torchmetrics import MetricCollection
+
+import random
+import importlib
+import argparse
+from configs.global_cfg import TARGET_RESAMPLE
+from configs.global_cfg import TARGET_RESAMPLE, DATASET_PATH, CLASSIFICATION_TASKS, REGRESSION_TASKS
+import pickle
+from einops import rearrange
+import pandas as pd
+
+torch.manual_seed(42)
+torch.cuda.manual_seed(42)
+torch.cuda.manual_seed_all(42)
+torch.backends.cudnn.deterministic = True
+torch.backends.cudnn.benchmark = False
+np.random.seed(42)
+random.seed(42)
+
+# In H100 GPUs
+torch.backends.cuda.matmul.allow_tf32 = False
+torch.backends.cudnn.allow_tf32 = False
+
+
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+
+class EvalDataModule(pl.LightningDataModule):
+ def __init__(self,
+ data_root,
+ batch_size_v,
+ transforms_v,
+ num_workers,
+ proportion_v,
+ num_classes=5,
+ splits_set=None,
+ modalities=["EEG"],
+ sig_len_target=30,
+ ft_task='sleep_staging',
+ full_night=False,
+ seq_truncate=False
+ ):
+ super().__init__()
+
+ self.data_root = data_root
+ self.transforms_v = transforms_v
+ self.batch_size_v = batch_size_v
+ self.num_workers = num_workers
+ self.proportion_v = proportion_v
+ self.num_classes = num_classes
+ self.splits_set = splits_set
+ self.modalities = modalities
+ self.sig_len_target = sig_len_target
+ self.ft_task = ft_task
+ self.full_night = full_night
+ self.seq_truncate = seq_truncate
+
+
+ def setup(self, stage=None):
+
+ self.test_data_list = self.splits_set['test']
+
+
+ self.test_loader = data_loader.build_loader(
+ self.data_root, self.test_data_list,
+ batch_size=self.batch_size_v, shuffle=False,
+ transforms=self.transforms_v, sampler=None,
+ num_workers=self.num_workers, proportion=self.proportion_v,
+ split='test',
+ num_classes=self.num_classes, modalities=self.modalities,
+ sig_len_target=self.sig_len_target,
+ ft_task=self.ft_task, full_night=self.full_night, seq_truncate=self.seq_truncate)
+
+ print("Test loader ready")
+ print("Length of test_loader: ", len(self.test_loader))
+
+
+ def test_dataloader(self):
+ return self.test_loader
+
+from finetune import ConvMAE1d_Finetune
+
+class ConvMAE1d_Evaluate(ConvMAE1d_Finetune):
+ def __init__(self, *args, **kwargs):
+ super().__init__(*args, **kwargs)
+
+ self.save_results = self.cfg.get('save_results', False)
+ if self.save_results:
+ self.save_results_dir = "ft_results"
+ os.makedirs(self.save_results_dir, exist_ok=True)
+ # self.preds = defaultdict(list)
+ # self.gt = defaultdict(list)
+ self.results = defaultdict(dict) # Initialize nested dict for each PID
+
+ self.save_emb = self.cfg.get('save_emb', False)
+ if self.save_emb:
+ self.save_emb_dir = "ft_results/embeddings"
+ os.makedirs(self.save_emb_dir, exist_ok=True)
+ self.embeddings = defaultdict(dict)
+
+ self._peak_gpu_mem_bytes = None
+
+ def on_test_epoch_start(self):
+ if torch.cuda.is_available():
+ torch.cuda.synchronize()
+ torch.cuda.reset_peak_memory_stats()
+ self._peak_gpu_mem_bytes = None
+
+
+ def forward_epoch_level(self, batch, mode='test'):
+ inputs, labels, _, _, pids = batch
+
+ # signals = inputs["EEG"].to(self.device, non_blocking=True)
+ for key in inputs.keys():
+ inputs[key] = inputs[key].to(self.device, non_blocking=True)
+
+ pred = self(inputs)
+ if self.ft_task == 'apnea_seg':
+ pred = rearrange(pred, 'n l c -> n c l')
+
+ loss = self.criterion(pred, labels)
+ pred_cls = pred.argmax(dim=1)
+
+ if self.save_results:
+ pred_cls = pred_cls.detach().cpu().numpy()
+ labels = labels.detach().cpu().numpy()
+ for idx, pid in enumerate(pids):
+ if pid not in self.results:
+ self.results[pid] = {'pred': [], 'gt': [],}
+ self.results[pid]['pred'].append(pred_cls[idx])
+ self.results[pid]['gt'].append(labels[idx])
+
+ self.log_metrics(loss, pred_cls, labels, mode=mode)
+
+
+ return loss
+
+ def forward_full_night(self, batch, mode='test'):
+ inputs, labels, mask, demo, pids = batch
+
+ if self.ft_task in ['age','ahi']:
+ labels = demo[self.ft_task].to(self.device, dtype=torch.float32, non_blocking=True)
+ elif self.ft_task in ['sex']:
+ labels = demo[self.ft_task].to(self.device, dtype=torch.long, non_blocking=True) - 1
+
+ for key in inputs.keys():
+ inputs[key] = inputs[key].to(self.device, non_blocking=True)
+
+ if (mask is not None) and (mask.numel() > 0):
+ mask = mask.to(self.device, non_blocking=True)
+
+ if self.save_emb:
+ self.model.eval()
+ with torch.no_grad():
+ (feats_macro_f, feats_macro_r), feats_micro = self.model.forward_features(inputs, mask=mask)
+ from models.utils import flip_padded_sequences
+ feats_macro_r = flip_padded_sequences(feats_macro_r, mask)
+ feats_macro = torch.cat([feats_macro_f, feats_macro_r], dim=-1)
+
+ for idx, pid in enumerate(pids):
+ self.embeddings[pid] = {
+ 'macro': feats_macro[idx].detach().cpu().numpy(),
+ 'micro': feats_micro[idx].detach().cpu().numpy(),
+ 'mask': mask[idx].detach().cpu().numpy() if mask is not None and mask.numel() > 0 else None,
+ 'age': demo['age'][idx].detach().cpu().numpy(),
+ 'sex': demo['sex'][idx].detach().cpu().numpy(),
+ 'bmi': demo['bmi'][idx].detach().cpu().numpy(),
+ 'ahi': demo['ahi'][idx].detach().cpu().numpy()
+ }
+ return # Skip further processing if only saving embeddings
+
+ pred = self(inputs, mask=mask)
+
+ if self.ft_task == 'sleep_staging' and (mask is not None) and (mask.numel() > 0):
+ pred = pred.permute(0,2,1)[mask]
+ labels = labels[mask]
+
+ if self.ft_task in REGRESSION_TASKS:
+ pred = pred.squeeze()
+ loss = self.criterion(pred, labels)
+
+ if self.ft_task in CLASSIFICATION_TASKS:
+ pred = pred.argmax(dim=1)
+
+ if self.save_results:
+ self.update_results(pred, labels, pids, demo)
+ self.log_metrics(loss, pred, labels, mode=mode)
+
+ def forward_diagnosis(self, batch, mode='train'):
+ inputs, is_event, event_times, mask, demo, pids = batch
+
+ # signals = inputs["EEG"].to(self.device, non_blocking=True)
+ for key in inputs.keys():
+ inputs[key] = inputs[key].to(self.device, non_blocking=True)
+
+ for key in demo.keys():
+ demo[key] = demo[key].to(self.device, non_blocking=True)
+
+ if (mask is not None) and (mask.numel() > 0):
+ mask = mask.to(self.device, non_blocking=True)
+
+ pred = self(inputs, mask=mask, demo=demo)
+
+ loss = self.criterion(pred, event_times, is_event)
+ if mode == 'train':
+ self.log('train_loss', loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True)
+ self.train_cindex.update(pred.squeeze(), event_times, is_event)
+ self.train_auroc.update(pred.squeeze(), event_times, is_event)
+ elif mode == 'val':
+ self.log('val_loss', loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True, batch_size=self.cfg['batch_size_v'])
+ self.val_cindex.update(pred.squeeze(), event_times, is_event)
+ self.val_auroc.update(pred.squeeze(), event_times, is_event)
+ elif mode == 'test':
+ self.log('test_loss', loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True, batch_size=self.cfg['batch_size_v'])
+ self.test_cindex.update(pred.squeeze(), event_times, is_event)
+ self.test_auroc.update(pred.squeeze(), event_times, is_event)
+
+ if self.save_results:
+ labels = torch.stack([event_times, is_event], dim=1)
+ self.update_results(pred, labels, pids, demo)
+
+ return loss
+
+
+ def update_results(self, pred, labels, pids, demo):
+ def _to_numpy(x):
+ x = x.detach()
+ if x.dtype in (torch.bfloat16, torch.float16, torch.float32, torch.float64):
+ x = x.float()
+ return x.cpu().numpy()
+
+ pred_np = _to_numpy(pred)
+ labels_np = _to_numpy(labels)
+ for idx, pid in enumerate(pids):
+ if pid not in self.results:
+ self.results[pid] = {'pred': [],
+ 'gt': [],
+ 'age': _to_numpy(demo['age'][idx]),
+ 'sex': _to_numpy(demo['sex'][idx]),
+ 'bmi': _to_numpy(demo['bmi'][idx]),
+ 'ahi': _to_numpy(demo['ahi'][idx])
+ }
+ self.results[pid]['pred'].append(pred_np[idx])
+ self.results[pid]['gt'].append(labels_np[idx])
+
+
+
+ def on_test_epoch_end(self):
+ if torch.cuda.is_available():
+ torch.cuda.synchronize()
+ self._peak_gpu_mem_bytes = torch.cuda.max_memory_allocated()
+ peak_gb = self._peak_gpu_mem_bytes / (1024 ** 3)
+ self.log('test_peak_gpu_mem_gb', peak_gb, on_step=False, on_epoch=True, prog_bar=False)
+ print(f"Peak GPU memory allocated: {peak_gb:.3f} GB")
+
+ if self.ft_task == 'diagnosis':
+ cindex = self.test_cindex.compute()
+ auroc = self.test_auroc.compute()
+ for i in range(len(cindex)):
+ self.log(f'test_cindex_class_{i}', cindex[i], on_step=False, on_epoch=True, prog_bar=False)
+ self.log(f'test_auroc_class_{i}', auroc[i], on_step=False, on_epoch=True, prog_bar=False)
+ self.log('test_cindex', torch.mean(cindex), on_step=False, on_epoch=True, prog_bar=True)
+ self.log('test_auroc', torch.mean(auroc), on_step=False, on_epoch=True, prog_bar=True)
+ print("Test C-Index:\n", cindex)
+ print("Test AUROC:\n", auroc)
+
+ self.test_cindex.reset()
+ self.test_auroc.reset()
+ else:
+ self.log_dict(self.test_metrics.compute(), on_epoch=True, sync_dist=True)
+ print("Test Confusion Matrix:\n", self.test_conf_matrix.compute())
+
+ if self.save_results:
+ # with open(os.path.join(self.save_results_dir, f'preds_{self.cfg["experiment_name"]}.pickle'), 'wb') as f:
+ # pickle.dump(self.preds, f)
+
+ # with open(os.path.join(self.save_results_dir, f'gt_{self.cfg["experiment_name"]}.pickle'), 'wb') as f:
+ # pickle.dump(self.gt, f)
+
+ with open(os.path.join(self.save_results_dir, f'results_{self.cfg["experiment_name"]}.pickle'), 'wb') as f:
+ pickle.dump(self.results, f)
+
+ if self.save_emb:
+ for pid, emb in self.embeddings.items():
+ with open(os.path.join(self.save_emb_dir, f'embeddings_{self.cfg["experiment_name"]}_{pid}.pickle'), 'wb') as f:
+ pickle.dump(emb, f)
+
+def get_all_configs_from_yaml(file_path):
+ with open(file_path, 'r') as file:
+ configs = yaml.safe_load(file)
+ return configs
+ # return Config(configs)
+
+def main():
+
+ # Parse command-line arguments
+ parser = argparse.ArgumentParser(description="Train Perceiver Model")
+ parser.add_argument('--config', type=str, required=True, help="Name of the configuration file (without .py)")
+ parser.add_argument('--no_wandb', action='store_true', default=False, help="Disable Weights and Biases logging")
+ args = parser.parse_args()
+
+ all_configs = get_all_configs_from_yaml(os.path.join("configs", args.config + ".yaml"))
+ print(all_configs)
+
+ # Add transforms dynamically if needed
+ # args.transforms = get_transforms()
+ # print(args)
+
+ print("Starting Experiment: ", all_configs['experiment_name'])
+
+ config_save_path = os.path.join(all_configs['config_save_path'], all_configs['experiment_name'])
+
+ os.makedirs(config_save_path, exist_ok=True)
+ with open(os.path.join(config_save_path, 'config.yaml'), 'w') as file:
+ yaml.dump(all_configs, file)
+
+ # Set data paths
+ # data_root("datasets") directory should be in the same directory as this script
+ data_root = os.path.join(BASE_DIR, all_configs['data_root'])
+ datasets = all_configs.get('datasets', ['phy'])
+
+
+ # Load data
+ print("Loading Data")
+ splits_set = dict()
+ splits_set['train'] = []
+ splits_set['val'] = []
+ splits_set['test'] = []
+
+ for ds in datasets:
+ # Use Physionet 2018 dataset
+ if ds == 'kiss':
+
+ sample_modality = all_configs.get('modalities', ['EEG'])[0] # Make sure all modalities have the same number of subjects
+
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'test', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ test_split = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ if all_configs.get('save_emb',False):
+ test_split = test_split[:500] # For saving embeddings, limit to first 500 subjects only to save space
+
+ splits_set['test'].extend([('kiss',f) for f in test_split])
+
+ elif ds == 'shhs1':
+
+ sample_modality = all_configs.get('modalities', ['EEG'])[0] # Make sure all modalities have the same number of subjects
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'test', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+ test_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ def get_shhs_lists(shhs_split_file):
+ ids = pd.read_csv(os.path.join("data","shhs_meta_data", shhs_split_file), header=None, names=['a'])
+ ids = ids['a'].values.tolist()
+ list_files = ["shhs1-20"+id[11:15] for id in ids]
+ return list_files
+
+ list_files_test = get_shhs_lists("test_list.txt")
+ test_subjects = set(list_files_test) & set(test_subjects)
+ test_subjects = sorted(list(test_subjects))
+
+ if all_configs.get('save_emb',False):
+ test_subjects = test_subjects[:500] # For saving embeddings, limit to first 500 subjects only to save space
+ splits_set['test'].extend([('shhs1',f) for f in test_subjects])
+
+
+ elif 'isruc' in ds:
+
+ sample_modality = all_configs.get('modalities', ['EEG'])[0] # Make sure all modalities have the same number of subjects
+
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'test', sample_modality)
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+ test_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ splits_set['test'].extend([(ds,f) for f in test_subjects])
+
+ print("Number of test subjects: ", len(splits_set['test']))
+
+ if all_configs['pretrain_checkpoint']:
+ pretrain_exp_name = all_configs['pretrain_checkpoint'].split('-')[0]
+ pretrain_config = get_all_configs_from_yaml(os.path.join("experiments", pretrain_exp_name, "config.yaml"))
+ use_shared = pretrain_config.get('use_shared', all_configs.get('use_shared', True))
+ use_moe = pretrain_config.get('use_moe', all_configs.get('use_moe', True))
+ else:
+ use_shared = all_configs.get('use_shared', True)
+ use_moe = all_configs.get('use_moe', True)
+
+
+ sig_len_target = all_configs.get('sig_len_target', 60)
+ data_module = EvalDataModule(
+ data_root = all_configs['data_root'],
+ transforms_v = None,
+ batch_size_v = all_configs['batch_size_v'],
+ num_workers = all_configs['num_workers'],
+ proportion_v = all_configs['proportion_v'],
+ num_classes = all_configs['num_classes'],
+ splits_set = splits_set,
+ modalities = all_configs['modalities'],
+ sig_len_target=sig_len_target,
+ ft_task=all_configs.get('ft_task', 'sleep_staging'),
+ full_night=all_configs.get('full_night', False),
+ seq_truncate=all_configs.get('seq_truncate', False)
+ )
+ data_module.setup() # Setup the data module to prepare the datasets and dataloaders
+
+
+ print("Model Loading ...")
+ model = ConvMAE1d_Evaluate(
+ model_name=all_configs['model_name'],
+ num_classes = all_configs['num_classes'],
+ modalities = all_configs['modalities'],
+ num_experts = all_configs['num_experts'],
+ num_experts_per = all_configs['num_experts_per'],
+ loss = all_configs['loss'],
+ sig_len = sig_len_target * TARGET_RESAMPLE,
+ use_shared = use_shared,
+ use_moe = use_moe,
+ full_finetune=all_configs.get('full_finetune', False), # Default to False if not specified
+ use_revin = all_configs['use_revin'],
+ ft_task = all_configs.get('ft_task', 'sleep_staging'),
+ patch_size=all_configs.get('patch_size', 10),
+ from_seq_pretrain=all_configs.get('from_seq_pretrain', False),
+ full_night=all_configs.get('full_night', False),
+ cfg=all_configs
+ )
+
+ print("Model Loaded")
+
+ if all_configs['pretrain_checkpoint']:
+ ckpt_file = os.path.join('experiments', all_configs['pretrain_checkpoint'])
+ model.load_pretrained(ckpt_file)
+
+ # If a pure pretraining checkpoint is specified (not a lightning finetune checkpoint),
+ # keep the existing `load_pretrained` behavior so encoder weights are loaded.
+ if all_configs.get('pretrain_checkpoint') and not all_configs.get('previous_checkpoint') and not all_configs.get('test_checkpoint'):
+ ckpt_file = os.path.join('experiments', all_configs['pretrain_checkpoint'])
+ try:
+ model.load_pretrained(ckpt_file)
+ except Exception as e:
+ print(f"Warning: failed to load pretrained weights via load_pretrained(): {e}")
+
+ from pytorch_lightning.callbacks import DeviceStatsMonitor
+
+ monitor = DeviceStatsMonitor()
+
+ # Build a trainer for evaluation only
+ trainer = pl.Trainer(
+ devices=all_configs['gpus'],
+ accelerator='gpu',
+ logger=None,
+ precision='bf16-mixed',
+ callbacks=[monitor],
+ )
+
+ # Run test only (do not run training/finetuning)
+ # print(f"Running test with checkpoint: {ckpt_path}")
+ import time
+ start = time.time()
+ trainer.test(model=model, datamodule=data_module)
+ end = time.time()
+ print(f"Elapsed time for {len(data_module.test_loader.dataset)}:{end - start}")
+
+
+if __name__ == '__main__':
+ # Add optional CLI arg for specifying checkpoint path
+ if '--ckpt' not in sys.argv:
+ # no-op; argparse will ignore unknown args here because we've already parsed
+ pass
+ main()
+
+
+
diff --git a/finetune.py b/finetune.py
new file mode 100644
index 0000000000000000000000000000000000000000..675704b8a2ef2d1e6c02f0ef45398285e5269f0c
--- /dev/null
+++ b/finetune.py
@@ -0,0 +1,947 @@
+from collections import defaultdict
+import pytorch_lightning as pl
+from pytorch_lightning.loggers import WandbLogger
+from torchmetrics import ConfusionMatrix, CohenKappa, MeanAbsoluteError, MeanSquaredError
+from torchmetrics.classification import Accuracy, Precision, Recall, F1Score
+import torch
+import torch.nn as nn
+
+from torch.optim.lr_scheduler import CosineAnnealingLR
+import os
+
+from pytorch_lightning.callbacks import ModelCheckpoint, Callback
+import numpy as np
+
+import data.data_loader as data_loader
+import yaml
+import math
+# from models.movinets import build_MoViNet
+#os.environ["WANDB_MODE"]="disabled"
+
+import models
+from models.utils import cox_ph_loss, CIndex, AUROC, get_layer_decay_param_groups, WarmupCosineAnnealingLR
+from torchmetrics import MetricCollection
+
+import random
+import argparse
+from configs.global_cfg import TARGET_RESAMPLE, DATASET_PATH, CLASSIFICATION_TASKS, REGRESSION_TASKS
+import pickle
+from einops import rearrange
+import pandas as pd
+
+torch.manual_seed(42)
+torch.cuda.manual_seed(42)
+torch.cuda.manual_seed_all(42)
+torch.backends.cudnn.deterministic = True
+torch.backends.cudnn.benchmark = False
+np.random.seed(42)
+random.seed(42)
+
+# In H100 GPUs
+torch.backends.cuda.matmul.allow_tf32 = False
+torch.backends.cudnn.allow_tf32 = False
+
+
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+
+
+
+class FinetuneDataModule(pl.LightningDataModule):
+ def __init__(self,
+ data_root,
+ batch_size_t,
+ batch_size_v,
+ transforms_t,
+ transforms_v,
+ num_workers,
+ proportion_t,
+ proportion_v,
+ num_classes=5,
+ splits_set=None,
+ modalities=["EEG"],
+ sig_len_target=30,
+ ft_task='sleep_staging',
+ full_night=False,
+ seq_truncate=False
+ ):
+ super().__init__()
+
+ self.data_root = data_root
+ self.transforms_t = transforms_t
+ self.transforms_v = transforms_v
+ self.batch_size_t = batch_size_t
+ self.batch_size_v = batch_size_v
+ self.num_workers = num_workers
+ self.proportion_t = proportion_t
+ self.proportion_v = proportion_v
+ self.num_classes = num_classes
+ self.splits_set = splits_set
+ self.modalities = modalities
+ self.sig_len_target = sig_len_target
+ self.ft_task = ft_task
+ self.full_night = full_night
+ self.seq_truncate = seq_truncate
+
+
+ def setup(self, stage=None):
+ # Split data into train and validation sets
+ # all_data_list = os.listdir(self.video_path)
+
+ self.train_data_list = self.splits_set['train']
+ self.val_data_list = self.splits_set['val']
+ self.test_data_list = self.splits_set['test']
+
+ print("_"*50)
+ print("Number of training subjects: ", len(self.train_data_list))
+
+ self.train_loader = data_loader.build_loader(
+ self.data_root, self.train_data_list,
+ batch_size=self.batch_size_t, shuffle=True,
+ transforms=self.transforms_t, sampler=None,
+ num_workers=self.num_workers, proportion=self.proportion_t,
+ split='train',
+ num_classes=self.num_classes, modalities=self.modalities,
+ sig_len_target=self.sig_len_target,
+ ft_task=self.ft_task, full_night=self.full_night, seq_truncate=self.seq_truncate)
+ print("Train loader ready")
+ print("Length of train_loader: ", len(self.train_loader))
+
+ self.val_loader = data_loader.build_loader(
+ self.data_root, self.val_data_list,
+ batch_size=self.batch_size_v, shuffle=False,
+ transforms=self.transforms_v, sampler=None,
+ num_workers=self.num_workers, proportion=self.proportion_v,
+ split='val',
+ num_classes=self.num_classes, modalities=self.modalities,
+ sig_len_target=self.sig_len_target,
+ ft_task=self.ft_task, full_night=self.full_night, seq_truncate=self.seq_truncate)
+ print("Val loader ready")
+ print("Length of val_loader: ", len(self.val_loader))
+
+ self.test_loader = data_loader.build_loader(
+ self.data_root, self.test_data_list,
+ batch_size=self.batch_size_v, shuffle=False,
+ transforms=self.transforms_v, sampler=None,
+ num_workers=self.num_workers, proportion=self.proportion_v,
+ split='test',
+ num_classes=self.num_classes, modalities=self.modalities,
+ sig_len_target=self.sig_len_target,
+ ft_task=self.ft_task, full_night=self.full_night, seq_truncate=self.seq_truncate)
+
+ print("Test loader ready")
+ print("Length of test_loader: ", len(self.test_loader))
+
+ def train_dataloader(self):
+ return self.train_loader
+
+ def val_dataloader(self):
+ return self.val_loader
+
+ def test_dataloader(self):
+ return self.test_loader
+
+
+
+class ConvMAE1d_Finetune(pl.LightningModule):
+ def __init__(self,
+ model_name='classification_multi',
+ num_classes=5,
+ modalities=["EEG"],
+ num_experts=4,
+ num_experts_per=2,
+ loss='ce',
+ class_weights=np.ones(5),
+ sig_len=6000,
+ use_shared=True,
+ use_moe=True,
+ use_revin=False,
+ full_finetune=False,
+ optimizer_name='AdamW',
+ lr=0.0005,
+ weight_decay=1e-6,
+ scheduler_name='CosineAnnealingLR',
+ num_epochs=10,
+ ft_task='sleep_staging',
+ patch_size=10,
+ from_seq_pretrain=False,
+ full_night=False,
+ cfg=None
+ ):
+ super().__init__()
+ self.cfg = cfg
+ self.save_hyperparameters()
+ single_channel = True
+ self.num_classes = num_classes
+ self.modalities = modalities
+ self.num_experts = num_experts
+ self.num_experts_per = num_experts_per
+ self.sig_len = sig_len
+ self.use_shared = use_shared
+ self.use_moe = use_moe
+ self.full_finetune = full_finetune
+ self.use_revin = use_revin
+ self.ft_task = ft_task
+ self.patch_size = patch_size
+ self.from_seq_pretrain = from_seq_pretrain
+ self.full_night = full_night
+
+ kwargs = {}
+ if model_name == 'classification_multi_full_night':
+ kwargs = {'use_micro': cfg.get('use_micro', False),
+ 'use_lstm': cfg.get('use_lstm', False),
+ 'use_transformer': cfg.get('use_transformer', False),
+ 'bidi': False if cfg.get('use_transformer', False) else cfg.get('bidi', True)}
+
+ self.model = models.__dict__[model_name](modalities=self.modalities,
+ num_experts=self.num_experts,
+ num_experts_per=self.num_experts_per,
+ sig_len=self.sig_len,
+ use_shared=self.use_shared,
+ use_moe=self.use_moe,
+ use_revin=self.use_revin,
+ ft_task=ft_task,
+ patch_size=self.patch_size,
+ num_classes=self.num_classes,
+ **kwargs)
+ # Survival analysis
+ if self.ft_task == 'diagnosis':
+ assert loss == 'coxph', "Diagnosis task requires Cox Proportional Hazards loss."
+ self.criterion = cox_ph_loss
+ self.train_cindex = CIndex()
+ self.val_cindex = CIndex()
+ self.test_cindex = CIndex()
+ self.train_auroc = AUROC(num_classes=num_classes)
+ self.val_auroc = AUROC(num_classes=num_classes)
+ self.test_auroc = AUROC(num_classes=num_classes)
+
+ # Classification tasks
+ elif self.ft_task in CLASSIFICATION_TASKS:
+ if loss == 'ce':
+ self.criterion = nn.CrossEntropyLoss()
+
+ elif loss == 'wce':
+ class_weights = torch.tensor(class_weights, dtype=torch.float32)
+ self.criterion = nn.CrossEntropyLoss(weight=class_weights)
+ elif loss == 'mse':
+ self.criterion = nn.MSELoss()
+
+
+ # Metrics
+ self.train_metrics = MetricCollection(
+ {
+ "acc": Accuracy(task="multiclass", num_classes=num_classes),
+ "f1": F1Score(task="multiclass", num_classes=num_classes),
+ },
+ prefix="train_",
+ )
+
+ self.val_metrics = MetricCollection(
+ {
+ "acc": Accuracy(task="multiclass", num_classes=num_classes),
+ "f1": F1Score(task="multiclass", num_classes=num_classes, average='macro'),
+ "kappa": CohenKappa(task="multiclass", num_classes=num_classes),
+ "precision": Precision(task="multiclass", num_classes=num_classes, average='macro'),
+ "recall": Recall(task="multiclass", num_classes=num_classes, average='macro'),
+ },
+ prefix="val_",
+ )
+
+ self.test_metrics = MetricCollection(
+ {
+ "acc": Accuracy(task="multiclass", num_classes=num_classes),
+ "f1": F1Score(task="multiclass", num_classes=num_classes, average='macro'),
+ "kappa": CohenKappa(task="multiclass", num_classes=num_classes),
+ "precision": Precision(task="multiclass", num_classes=num_classes, average='macro'),
+ "recall": Recall(task="multiclass", num_classes=num_classes, average='macro'),
+ },
+ prefix="test_",
+ )
+ self.val_conf_matrix = ConfusionMatrix(task="multiclass", num_classes=num_classes)
+ self.test_conf_matrix = ConfusionMatrix(task="multiclass", num_classes=num_classes)
+ # Classification tasks
+ elif self.ft_task in REGRESSION_TASKS:
+ if loss == 'mse':
+ self.criterion = nn.MSELoss()
+ elif loss == 'mae':
+ self.criterion = nn.L1Loss()
+
+
+ # Metrics
+ self.train_metrics = MetricCollection(
+ {
+ "mae": MeanAbsoluteError(),
+ "mse": MeanSquaredError()
+ },
+ prefix="train_",
+ )
+
+ self.val_metrics = MetricCollection(
+ {
+ "mae": MeanAbsoluteError(),
+ "mse": MeanSquaredError()
+ },
+ prefix="val_",
+ )
+
+ self.test_metrics = MetricCollection(
+ {
+ "mae": MeanAbsoluteError(),
+ "mse": MeanSquaredError()
+ },
+ prefix="test_",
+ )
+
+
+ def load_pretrained(self, ckpt):
+ # Load the pretrained model checkpoint
+ checkpoint = torch.load(ckpt, map_location=self.device, weights_only=False)
+ new_state_dict = {}
+ for k in self.model.state_dict().keys():
+ if 'pos_embed' in k:
+ print("Skipping key (pos_embed): ", k)
+ continue
+ if k in checkpoint['state_dict']:
+ # print("Matching key: ", k)
+ new_state_dict[k] = checkpoint['state_dict'][k]
+ else:
+ # print(f"Missing key (Only in the current model), tries to find model.{k}")
+ if f"model.{k}" in checkpoint['state_dict']:
+ # print("Matching key, starts with 'model.' in the checkpoint, delete 'model. prefix': ", k)
+ new_state_dict[k] = checkpoint['state_dict'][f"model.{k}"] # Remove 'model.' prefix
+ else:
+ print("Missing key (Only in the current model): ", k)
+
+
+ for k in checkpoint['state_dict'].keys():
+ if not (k.startswith('model.') and k[6:] in self.model.state_dict()) and not k in self.model.state_dict():
+ print("Missing key (Only in the Checkpoint): ", k)
+
+ msg = self.model.load_state_dict(new_state_dict, strict=False)
+ print(f"Loaded pretrained model from {ckpt}")
+ print(msg)
+
+ def on_train_epoch_start(self):
+ if self.ft_task != 'diagnosis':
+ self.train_metrics.reset()
+
+ def on_validation_epoch_end(self):
+ if self.ft_task == 'diagnosis':
+ cindex = self.val_cindex.compute()
+ auroc = self.val_auroc.compute()
+ self.log('val_cindex', torch.mean(cindex), on_step=False, on_epoch=True, prog_bar=True)
+ self.log('val_auroc', torch.mean(auroc), on_step=False, on_epoch=True, prog_bar=True)
+ print("Validation C-Index:\n", cindex)
+ print("Validation AUROC:\n", auroc)
+
+ self.val_cindex.reset()
+ self.val_auroc.reset()
+ else:
+ self.log_dict(self.val_metrics.compute(), on_epoch=True, sync_dist=True)
+ self.val_metrics.reset()
+ if self.ft_task in CLASSIFICATION_TASKS:
+ print("Validation Confusion Matrix:\n", self.val_conf_matrix.compute())
+
+ def on_test_epoch_end(self):
+ if self.ft_task == 'diagnosis':
+ cindex = self.test_cindex.compute()
+ auroc = self.test_auroc.compute()
+ for i in range(len(cindex)):
+ self.log(f'test_cindex_class_{i}', cindex[i], on_step=False, on_epoch=True, prog_bar=False)
+ self.log(f'test_auroc_class_{i}', auroc[i], on_step=False, on_epoch=True, prog_bar=False)
+ self.log('test_cindex', torch.mean(cindex), on_step=False, on_epoch=True, prog_bar=True)
+ self.log('test_auroc', torch.mean(auroc), on_step=False, on_epoch=True, prog_bar=True)
+ print("Test C-Index:\n", cindex)
+ print("Test AUROC:\n", auroc)
+
+ self.test_cindex.reset()
+ self.test_auroc.reset()
+ else:
+ self.log_dict(self.test_metrics.compute(), on_epoch=True, sync_dist=True)
+ if self.ft_task in CLASSIFICATION_TASKS:
+ print("Test Confusion Matrix:\n", self.test_conf_matrix.compute())
+
+
+
+ def forward(self, s, mask=None, demo=None):
+ if self.full_night:
+ return self.model(s, mask=mask, demo=demo)
+ else:
+ return self.model(s)
+
+
+ def train(self, mode: bool = True):
+ """
+ Override the default .train() method to keep the encoder in eval mode.
+ """
+ # Set the train mode for the whole model (including head and encoder)
+ super().train(mode)
+
+ # Now, *force* the encoder back to eval mode
+ if not self.full_finetune:
+ self.model.encoder.eval()
+ self.model.fuser.eval()
+ if self.from_seq_pretrain and not self.cfg.get('use_micro', False):
+ self.model.proj.eval()
+ self.model.sequence_encoder.eval()
+
+ def log_metrics(self, loss, pred_cls, labels, mode='train'):
+
+ if mode == 'train':
+ batch_value = self.train_metrics(pred_cls, labels)
+ self.log_dict(batch_value, on_step=True, on_epoch=True, sync_dist=True)
+ self.log('learning_rate', self.trainer.optimizers[0].param_groups[0]['lr'], on_step=True, on_epoch=True, sync_dist=True)
+ self.log('train_loss', loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True)
+
+ elif mode == 'val':
+ self.val_metrics.update(pred_cls, labels)
+ if self.ft_task in CLASSIFICATION_TASKS:
+ self.val_conf_matrix.update(pred_cls, labels)
+ self.log('val_loss', loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True, batch_size=self.cfg['batch_size_v'])
+
+
+ elif mode == 'test':
+ # Log metrics
+ self.test_metrics.update(pred_cls, labels)
+ if self.ft_task in CLASSIFICATION_TASKS:
+ self.test_conf_matrix.update(pred_cls, labels)
+ self.log('test_loss', loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True, batch_size=self.cfg['batch_size_v'])
+
+ def forward_diagnosis(self, batch, mode='train'):
+ inputs, is_event, event_times, mask, demo, _ = batch
+
+ # signals = inputs["EEG"].to(self.device, non_blocking=True)
+ for key in inputs.keys():
+ inputs[key] = inputs[key].to(self.device, non_blocking=True)
+
+ for key in demo.keys():
+ demo[key] = demo[key].to(self.device, non_blocking=True)
+
+ if (mask is not None) and (mask.numel() > 0):
+ mask = mask.to(self.device, non_blocking=True)
+
+ pred = self(inputs, mask=mask, demo=demo)
+
+ loss = self.criterion(pred, event_times, is_event)
+ if mode == 'train':
+ self.log('train_loss', loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True)
+ self.train_cindex.update(pred.squeeze(), event_times, is_event)
+ self.train_auroc.update(pred.squeeze(), event_times, is_event)
+ elif mode == 'val':
+ self.log('val_loss', loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True, batch_size=self.cfg['batch_size_v'])
+ self.val_cindex.update(pred.squeeze(), event_times, is_event)
+ self.val_auroc.update(pred.squeeze(), event_times, is_event)
+ elif mode == 'test':
+ self.log('test_loss', loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True, batch_size=self.cfg['batch_size_v'])
+ self.test_cindex.update(pred.squeeze(), event_times, is_event)
+ self.test_auroc.update(pred.squeeze(), event_times, is_event)
+
+ return loss
+
+
+
+ def forward_epoch_level(self, batch, mode='train'):
+ inputs, labels, _, _, pids = batch
+
+ # signals = inputs["EEG"].to(self.device, non_blocking=True)
+ for key in inputs.keys():
+ inputs[key] = inputs[key].to(self.device, non_blocking=True)
+
+ pred = self(inputs)
+ if self.ft_task == 'apnea_seg':
+ pred = rearrange(pred, 'n l c -> n c l')
+
+ loss = self.criterion(pred, labels)
+ pred_cls = pred.argmax(dim=1)
+
+
+ self.log_metrics(loss, pred_cls, labels, mode=mode)
+
+ return loss
+
+ def forward_full_night(self, batch, mode='train'):
+ inputs, labels, mask, demo, pids = batch
+
+ if self.ft_task in ['age','ahi']:
+ labels = demo[self.ft_task].to(self.device, dtype=torch.float32, non_blocking=True)
+ elif self.ft_task in ['sex']:
+ labels = demo[self.ft_task].to(self.device, dtype=torch.long, non_blocking=True) - 1
+
+
+ # signals = inputs["EEG"].to(self.device, non_blocking=True)
+ for key in inputs.keys():
+ inputs[key] = inputs[key].to(self.device, non_blocking=True)
+
+ if (mask is not None) and (mask.numel() > 0):
+ mask = mask.to(self.device, non_blocking=True)
+
+ pred = self(inputs, mask=mask)
+
+ if self.ft_task == 'sleep_staging' and (mask is not None) and (mask.numel() > 0):
+ pred = pred.permute(0,2,1)[mask]
+ labels = labels[mask]
+
+ # labels /= 100
+ if self.ft_task in REGRESSION_TASKS:
+ pred = pred.squeeze()
+ loss = self.criterion(pred, labels)
+
+ if self.ft_task in CLASSIFICATION_TASKS:
+ pred = pred.argmax(dim=1)
+
+ self.log_metrics(loss, pred, labels, mode=mode)
+
+ return loss
+
+ def training_step(self, batch, batch_idx):
+ if self.ft_task == 'diagnosis':
+ loss = self.forward_diagnosis(batch, mode='train')
+ elif not self.full_night:
+ loss = self.forward_epoch_level(batch, mode='train')
+ else:
+ loss = self.forward_full_night(batch, mode='train')
+
+ return loss
+
+ def validation_step(self, batch, batch_idx):
+ if self.ft_task == 'diagnosis':
+ loss = self.forward_diagnosis(batch, mode='val')
+ elif not self.full_night:
+ loss = self.forward_epoch_level(batch, mode='val')
+ else:
+ loss = self.forward_full_night(batch, mode='val')
+
+ return loss
+
+ def test_step(self, batch, batch_idx):
+ if self.ft_task == 'diagnosis':
+ loss = self.forward_diagnosis(batch, mode='test')
+ elif not self.full_night:
+ loss = self.forward_epoch_level(batch, mode='test')
+ else:
+ loss = self.forward_full_night(batch, mode='test')
+
+ return loss
+
+ def configure_optimizers(self):
+ # Base learning rate and weight decay
+ base_lr = self.hparams.lr
+ weight_decay = self.hparams.weight_decay if hasattr(self.hparams, 'weight_decay') else 0.05
+ layer_decay = self.hparams.layer_decay if hasattr(self.hparams, 'layer_decay') else 1.0
+ if not self.full_finetune:
+ for param in self.model.encoder.parameters():
+ param.requires_grad = False
+ if self.use_revin:
+ for param in self.model.revin.parameters():
+ param.requires_grad = False
+ if self.use_shared:
+ for param in self.model.fuser.parameters():
+ param.requires_grad = False
+
+ if self.from_seq_pretrain and not self.cfg.get('use_micro', False):
+ for param in self.model.sequence_encoder.parameters():
+ param.requires_grad = False
+ for param in self.model.proj.parameters():
+ param.requires_grad = False
+
+ # Create parameter groups with layer-wise learning rate decay
+ param_groups = get_layer_decay_param_groups(self.model, base_lr, weight_decay, layer_decay)
+
+ optimizer = getattr(torch.optim, self.hparams.optimizer_name)(param_groups)
+
+ if self.hparams.scheduler_name == 'CosineAnnealingLR':
+ steps_per_epoch = len(self.trainer.datamodule.train_dataloader())
+ max_steps = int(steps_per_epoch * self.hparams.num_epochs / len(self.cfg['gpus'])) + 1
+ return{
+ "optimizer": optimizer,
+ "lr_scheduler": {
+ "scheduler": CosineAnnealingLR(optimizer, T_max=max_steps, eta_min=1e-8),
+ "interval": "step",
+ "frequency": 1
+ }
+ }
+ elif self.hparams.scheduler_name == 'WarmupCosineAnnealingLR':
+ steps_per_epoch = len(self.trainer.datamodule.train_dataloader())
+ max_steps = int(steps_per_epoch * self.hparams.num_epochs / len(self.cfg['gpus'])) + 1
+ warmup_steps = int(max_steps * 0.1) # 10% of total steps for warmup
+
+ scheduler = WarmupCosineAnnealingLR(
+ optimizer,
+ warmup_steps=warmup_steps, # Number of warmup steps
+ max_steps=max_steps,
+ eta_min=1e-8
+ )
+
+ return {
+ "optimizer": optimizer,
+ "lr_scheduler": {
+ "scheduler": scheduler,
+ "interval": "step",
+ "frequency": 1
+ }
+ }
+
+ else:
+ return optimizer
+
+
+def get_all_configs_from_yaml(file_path):
+ with open(file_path, 'r') as file:
+ configs = yaml.safe_load(file)
+ return configs
+ # return Config(configs)
+
+def main():
+
+ # Parse command-line arguments
+ parser = argparse.ArgumentParser(description="Train Perceiver Model")
+ parser.add_argument('--config', type=str, required=True, help="Name of the configuration file (without .py)")
+ parser.add_argument('--no_wandb', action='store_true', default=False, help="Disable Weights and Biases logging")
+ args = parser.parse_args()
+
+ all_configs = get_all_configs_from_yaml(os.path.join("configs", args.config + ".yaml"))
+ print(all_configs)
+
+ # Add transforms dynamically if needed
+ # args.transforms = get_transforms()
+ # print(args)
+
+ print("Starting Experiment: ", all_configs['experiment_name'])
+
+ config_save_path = os.path.join(all_configs['config_save_path'], all_configs['experiment_name'])
+
+ os.makedirs(config_save_path, exist_ok=True)
+ with open(os.path.join(config_save_path, 'config.yaml'), 'w') as file:
+ yaml.dump(all_configs, file)
+
+ # Set data paths
+ # data_root("datasets") directory should be in the same directory as this script
+ data_root = os.path.join(BASE_DIR, all_configs['data_root'])
+ # all_configs['signals_path'] = os.path.join(data_root, all_configs['signals_path'])
+ # all_configs['labels_path'] = os.path.join(data_root, all_configs['labels_path'])
+ datasets = all_configs.get('datasets', ['phy'])
+
+
+ # Load data
+ print("Loading Data")
+ splits_set = dict()
+ splits_set['train'] = []
+ splits_set['val'] = []
+ splits_set['test'] = []
+
+ for ds in datasets:
+ # Use Physionet 2018 dataset
+ if ds == 'phy-tr':
+ # Use Physionet 2018 dataset
+ sample_modality = all_configs.get('modalities', ['EEG'])[0]
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ all_subjects = [sub for sub in sig_info['sig_info'].keys()]
+ all_subjects.sort()
+
+ train_files = np.load(os.path.join("data", "physionet_2018_folds.npy"), allow_pickle=True)
+
+ new_train_files = []
+ for fold_id in range(1):
+ fnames = [f for f in train_files[fold_id] if f in all_subjects]
+ new_train_files.append(fnames)
+
+ train_split = sorted(list(set(all_subjects) - set(new_train_files[0])))[:-50] # Fold 0
+ val_split = sorted(list(set(all_subjects) - set(new_train_files[0])))[-50:]
+ test_split = sorted(new_train_files[0])
+
+ splits_set['train'].extend([('phy-tr',f) for f in train_split])
+ splits_set['val'].extend([('phy-tr',f) for f in val_split])
+ splits_set['test'].extend([('phy-tr',f) for f in test_split])
+
+ elif ds == 'kiss':
+
+ sample_modality = all_configs.get('modalities', ['EEG'])[0] # Make sure all modalities have the same number of subjects
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'train', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ train_split = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'val', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ val_split = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'test', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ test_split = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+
+ ## TEST: only use EM subjects
+ # train_split = [sub for sub in train_split if 'NX' in sub]
+ # val_split = [sub for sub in val_split if 'NX' in sub]
+ # test_split = [sub for sub in test_split if 'NX' in sub]
+
+ splits_set['train'].extend([('kiss',f) for f in train_split])
+ splits_set['val'].extend([('kiss',f) for f in val_split])
+ splits_set['test'].extend([('kiss',f) for f in test_split])
+
+ elif ds == 'shhs1':
+
+ sample_modality = all_configs.get('modalities', ['EEG'])[0] # Make sure all modalities have the same number of subjects
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'train', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ all_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'val', sample_modality)
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+ val_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'test', sample_modality)
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+ test_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ def get_shhs_lists(shhs_split_file):
+ ids = pd.read_csv(os.path.join("data","shhs_meta_data", shhs_split_file), header=None, names=['a'])
+ ids = ids['a'].values.tolist()
+ list_files = ["shhs1-20"+id[11:15] for id in ids]
+ return list_files
+
+ list_files_val = get_shhs_lists("eval_list.txt")
+ list_files_test = get_shhs_lists("test_list.txt")
+
+ missing_cases = ['shhs1-204709','shhs1-204806']
+
+ train_subjects = set(all_subjects) - set(list_files_val) - set(list_files_test) - set(missing_cases)
+ train_subjects = sorted(list(train_subjects))
+ val_subjects = set(list_files_val) & set(val_subjects)
+ test_subjects = set(list_files_test) & set(test_subjects)
+
+ val_subjects = sorted(list(val_subjects))
+ test_subjects = sorted(list(test_subjects))
+
+ splits_set['train'].extend([('shhs1',f) for f in train_subjects])
+ splits_set['val'].extend([('shhs1',f) for f in val_subjects])
+ splits_set['test'].extend([('shhs1',f) for f in test_subjects])
+
+
+ elif 'cfs' in ds or 'isruc' in ds or 'sof' in ds:
+
+ sample_modality = all_configs.get('modalities', ['EEG'])[0] # Make sure all modalities have the same number of subjects
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'train', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ train_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'val', sample_modality)
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+ val_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'test', sample_modality)
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+ test_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ splits_set['train'].extend([(ds,f) for f in train_subjects])
+ splits_set['val'].extend([(ds,f) for f in val_subjects])
+ splits_set['test'].extend([(ds,f) for f in test_subjects])
+
+
+ print("Number of train subjects: ", len(splits_set['train']))
+ print("Number of valid subjects: ", len(splits_set['val']))
+ print("Number of test subjects: ", len(splits_set['test']))
+
+ if all_configs['pretrain_checkpoint']:
+ pretrain_exp_name = all_configs['pretrain_checkpoint'].split('-')[0]
+ pretrain_config = get_all_configs_from_yaml(os.path.join("experiments", pretrain_exp_name, "config.yaml"))
+ use_shared = pretrain_config.get('use_shared', all_configs.get('use_shared', True))
+ use_moe = pretrain_config.get('use_moe', all_configs.get('use_moe', True))
+ else:
+ use_shared = all_configs.get('use_shared', True)
+ use_moe = all_configs.get('use_moe', True)
+
+
+ sig_len_target = all_configs.get('sig_len_target', 60)
+ data_module = FinetuneDataModule(
+ data_root = all_configs['data_root'],
+ transforms_t = None,
+ transforms_v = None,
+ batch_size_t = all_configs['batch_size_t'],
+ batch_size_v = all_configs['batch_size_v'],
+ num_workers = all_configs['num_workers'],
+ proportion_t = all_configs['proportion_t'],
+ proportion_v = all_configs['proportion_v'],
+ num_classes = all_configs['num_classes'],
+ splits_set = splits_set,
+ modalities = all_configs['modalities'],
+ sig_len_target=sig_len_target,
+ ft_task=all_configs.get('ft_task', 'sleep_staging'),
+ full_night=all_configs.get('full_night', False),
+ seq_truncate=all_configs.get('seq_truncate', False)
+ )
+ data_module.setup() # Setup the data module to prepare the datasets and dataloaders
+
+ if all_configs['loss'] == 'wce':
+ train_loader = data_module.train_dataloader()
+ labels = train_loader.dataset.get_all_labels()
+ class_count = np.zeros(all_configs['num_classes'], dtype=np.int64)
+ if all_configs.get('full_night', False) or all_configs.get('ft_task', 'sleep_staging') == 'apnea_seg':
+ # For full night training, labels is a list of arrays
+ labels = np.concatenate(labels, axis=0)
+ unique, counts = np.unique(labels, return_counts=True)
+ for i, cnt in zip(unique, counts):
+ class_count[i] += cnt
+ print("Class counts:", class_count)
+
+ ft_task = all_configs.get('ft_task', 'sleep_staging')
+ if ft_task == 'sleep_staging':
+ class_weights = np.emath.logn(all_configs['num_classes'], np.sum(class_count)/class_count)
+ class_weights = np.maximum(1.0, class_weights)
+ print("Class weights:", class_weights)
+
+ elif ft_task == 'apnea_seg':
+ class_count_adj = np.zeros(2, dtype=np.int64)
+ class_count_adj[0] = class_count[0]
+ class_count_adj[1] = np.sum(class_count[1:]) # Combine 1 and 2
+ class_weights = np.sum(class_count_adj)/class_count_adj
+ print("Class weights:", class_weights)
+
+
+ else:
+ class_weights = np.ones(all_configs['num_classes'])
+
+ print("Data Loaded")
+
+
+
+ print("Model Loading ...")
+ model = ConvMAE1d_Finetune(
+ model_name=all_configs['model_name'],
+ num_classes = all_configs['num_classes'],
+ modalities = all_configs['modalities'],
+ num_experts = all_configs['num_experts'],
+ num_experts_per = all_configs['num_experts_per'],
+ loss = all_configs['loss'],
+ class_weights = class_weights,
+ sig_len = sig_len_target * TARGET_RESAMPLE,
+ use_shared = use_shared,
+ use_moe = use_moe,
+ full_finetune=all_configs.get('full_finetune', False), # Default to False if not specified
+ optimizer_name = all_configs['optimizer_name'],
+ lr = all_configs['lr'],
+ weight_decay = float(all_configs.get('weight_decay', 0.05)),
+ scheduler_name = all_configs['scheduler_name'],
+ num_epochs = all_configs['num_epochs'],
+ use_revin = all_configs['use_revin'],
+ ft_task = all_configs.get('ft_task', 'sleep_staging'),
+ patch_size=all_configs.get('patch_size', 10),
+ from_seq_pretrain=all_configs.get('from_seq_pretrain', False),
+ full_night=all_configs.get('full_night', False),
+ cfg=all_configs
+ )
+
+ print("Model Loaded")
+
+ if all_configs['pretrain_checkpoint']:
+ ckpt_file = os.path.join('experiments', all_configs['pretrain_checkpoint'])
+ model.load_pretrained(ckpt_file)
+
+ ft_task = all_configs.get('ft_task', 'sleep_staging')
+ if ft_task == 'diagnosis':
+ main_metric = 'val_cindex'
+ elif ft_task in CLASSIFICATION_TASKS:
+ main_metric = 'val_f1'
+ elif ft_task in REGRESSION_TASKS:
+ main_metric = 'val_mae'
+
+ checkpoint_callback = ModelCheckpoint(
+ monitor=main_metric,
+ mode='max',
+ save_top_k=1,
+ dirpath=all_configs['ckpt_save_path'],
+ filename=all_configs['experiment_name'] + '-{epoch:02d}-{val_f1:.2f}',
+ verbose=True
+ )
+ class SaveLastEpochCheckpoint(Callback):
+ def on_train_end(self, trainer, pl_module):
+ # 마지막 epoch의 체크포인트 저장
+ final_checkpoint_path = f"{all_configs['ckpt_save_path']}/{all_configs['experiment_name']}-final.ckpt"
+ trainer.save_checkpoint(final_checkpoint_path)
+ print(f"Final checkpoint saved at {final_checkpoint_path}")
+
+ # if previous_run_id is not None, load the best model from the previous run
+ previous_run_id = all_configs['previous_run_id']
+ if args.no_wandb:
+ wandb_logger = None
+ elif previous_run_id:
+ wandb_logger = WandbLogger(
+ project=all_configs['project_name'],
+ entity='gundo0102',
+ name=all_configs['experiment_name'],
+ config=all_configs,
+ resume='must', # 이전 실험을 이어서 진행
+ id=previous_run_id # 이전 실험의 run_id
+ )
+ else:
+ wandb_logger = WandbLogger(
+ project=all_configs['project_name'],
+ entity='gundo0102',
+ name=all_configs['experiment_name'],
+ config=all_configs
+ )
+
+ trainer = pl.Trainer(
+ devices=all_configs['gpus'],
+ max_epochs=all_configs['num_epochs'],
+ accelerator='gpu',
+ logger=wandb_logger,
+ precision = 'bf16-mixed',
+ # gradient_clip_val=1.0,
+ callbacks=[checkpoint_callback, SaveLastEpochCheckpoint()],
+ # strategy= 'ddp', #'ddp_find_unused_parameters_true',
+ strategy='ddp_find_unused_parameters_true',
+ accumulate_grad_batches=all_configs['accumulate_grad_batches'],
+ # No sanity check
+ num_sanity_val_steps=1,
+ # val_check_interval=10,
+ check_val_every_n_epoch=1,
+ )
+
+ if all_configs['previous_checkpoint']:
+ trainer.fit(model, datamodule=data_module, ckpt_path=all_configs['previous_checkpoint'])
+ else:
+ trainer.fit(model, datamodule=data_module)
+
+ trainer.test(ckpt_path="best", datamodule=data_module)
+ # trainer.test(model, datamodule=data_module)
+
+ wandb_logger.experiment.finish()
+
+
+if __name__ == '__main__':
+ main()
+
+
+
diff --git a/models/__init__.py b/models/__init__.py
new file mode 100644
index 0000000000000000000000000000000000000000..fc0e6437bbb7543f7cc93f19e3dc015f6eb3e429
--- /dev/null
+++ b/models/__init__.py
@@ -0,0 +1,17 @@
+from .factory import (
+ convmae1d_multi,
+ classification_multi,
+ classification_multi_full_night
+)
+from .mae import MaskedAutoencoderConv1d, MultiMaskedAutoencoderConv1d
+from .classification import ClassificationMultiConv1d, ClassificationMultiConv1dMamba
+
+__all__ = [
+ 'convmae1d_multi',
+ 'classification_multi',
+ 'classification_multi_full_night',
+ 'MaskedAutoencoderConv1d',
+ 'MultiMaskedAutoencoderConv1d',
+ 'ClassificationMultiConv1d',
+ 'ClassificationMultiConv1dMamba',
+]
diff --git a/models/classification.py b/models/classification.py
new file mode 100644
index 0000000000000000000000000000000000000000..05a6a59a71478f55d7073058561b074c67211aac
--- /dev/null
+++ b/models/classification.py
@@ -0,0 +1,1021 @@
+from functools import partial
+import copy
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import numpy as np
+
+from models.encoders import MultiEncoderClassification
+from models.transformer_modules import RevIN
+from models.mamba_modules import SeqEncoder
+from models.fusion import FusionUpsampleBlock
+from models.utils import flip_padded_sequences
+from einops import rearrange
+from configs.global_cfg import TARGET_RESAMPLE
+
+
+class ClassificationMultiConv1d(nn.Module):
+ """ Masked Autoencoder with VisionTransformer backbone
+ """
+
+ def __init__(self, sig_len=6000, patch_size=10, in_chans=1,
+ embed_dim=[32,64,128], depth=[2,2,4], specific_depth=[2,2], num_heads=8,
+ fusion_heads=8, fusion_depth=2,
+ mlp_ratio=[4,4,4], norm_layer=nn.LayerNorm, num_classes=5,
+ modalities=["EEG","EOG"], num_experts=2, num_experts_per=1,
+ use_shared=True, use_moe=True, fusion_method='concat',
+ use_revin=False, pos_enc='sinusoidal', ft_task='sleep_staging'):
+
+ super().__init__()
+
+ self.sig_len = sig_len
+ self.patch_size = patch_size
+ self.modalities = modalities
+
+ self.num_experts = num_experts
+ self.num_experts_per = num_experts_per
+ self.use_shared = use_shared
+ self.use_moe = use_moe
+ self.fusion_method = fusion_method
+ self.embed_dim = embed_dim
+ self.depth = depth
+ self.pos_enc = pos_enc
+
+ self.encoder = MultiEncoderClassification(sig_len=sig_len, patch_size=patch_size, in_chans=in_chans,
+ embed_dim=embed_dim, depth=depth, num_heads=num_heads, specific_depth=specific_depth,
+ mlp_ratio=mlp_ratio, norm_layer=norm_layer,
+ modalities=self.modalities, num_experts=num_experts, num_experts_per=num_experts_per,
+ use_shared=use_shared, use_moe=use_moe, pos_enc=pos_enc)
+ # self.head = nn.Linear(embed_dim[-1], num_classes) if num_classes > 0 else nn.Identity()
+ self.num_patches = self.encoder.num_patches
+
+ self.fuser = FusionUpsampleBlock(dim_list=embed_dim[2:],
+ fusion_method=fusion_method,
+ fusion_depth=fusion_depth,
+ fusion_heads=fusion_heads,
+ mlp_ratio=mlp_ratio[0],
+ norm_layer=norm_layer,
+ pos_enc=pos_enc,
+ use_shared=use_shared,
+ use_upsample=True, # if ft_task=='apnea_seg' else False,
+ modalities=self.modalities)
+
+ self.ft_task = ft_task
+ if self.ft_task == 'sleep_staging':
+ post_fusion_dim = embed_dim[3] * len(self.modalities)
+ self.head = nn.Linear(post_fusion_dim, num_classes) if num_classes > 0 else nn.Identity()
+ elif self.ft_task == 'apnea_seg':
+ post_fusion_dim = embed_dim[2] * len(self.modalities)
+
+ self.patch_per_sec = TARGET_RESAMPLE // (self.patch_size * 2) # Encoder downsamples by 2 for consistency in pretrainng and finetuning
+ self.head = nn.Linear(post_fusion_dim, num_classes) # 1D conv for sequence labeling
+
+
+ self.use_revin = use_revin
+ if self.use_revin:
+ self.revin = nn.ModuleDict()
+ for m in self.modalities:
+ if m != 'SaO2':
+ self.revin[m] = RevIN(num_features=1, affine=False)
+
+
+
+ self.apply(self._init_weights)
+
+ def _init_weights(self, m):
+ if isinstance(m, nn.Linear):
+ # we use xavier_uniform following official JAX ViT:
+ torch.nn.init.xavier_uniform_(m.weight)
+ if isinstance(m, nn.Linear) and m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+
+ elif isinstance(m, nn.LayerNorm):
+ nn.init.constant_(m.bias, 0)
+ nn.init.constant_(m.weight, 1.0)
+
+ def forward_features(self, inputs):
+
+
+ modalities_to_use = sorted(list(inputs.keys()))
+
+ # latents_shared_lg: list of M x [N, L, lg_dim] tensors. M: # modalities
+ # latents_shared_sm: list of M x [N, L, sm_per_lg, sm_dim] tensors. M: # modalities
+ # latents_specific_lg: dictionary of [N, L, lg_dim] tensors. key: modality name
+ # latents_specific_sm: dictionary of [N*L, sm_per_lg, sm_dim] tensors. key: modality name
+ if self.use_revin:
+ for i, m in enumerate(modalities_to_use):
+ if m == 'SaO2':
+ inputs[m] = inputs[m][:, ::TARGET_RESAMPLE, :] # N,L* TARGET_RESAMPLE,1 -> N,L,1
+ else:
+ inputs[m] = self.revin[m](inputs[m], mode='norm')
+
+ latents_shared, latents_specific, gating_scores = self.encoder(inputs, modalities_to_use)
+
+ latents_fused, upsampled = self.fuser(latents_shared, latents_specific)
+
+ if self.ft_task == 'apnea_seg':
+ latents = torch.stack(upsampled, dim=0) # (M, N, L, D * 2 or 4)
+ latents = rearrange(latents, 'm n (l s) d -> n l s (m d)', s=self.patch_per_sec)
+ latents = latents.mean(2)
+ lengths = latents.shape[1]
+ if lengths > 30:
+ shift = (lengths - 30) // 2
+ latents = latents[:, shift:shift+30, :]
+ else:
+ # latents = torch.concat(latents_cat, dim=-1) # (M, N, L, D * 2 or 4)
+ latents = torch.stack(latents_fused, dim=0)
+ latents = rearrange(latents, 'm n l d -> n m l d')
+ latents = latents.mean(2)
+ latents = rearrange(latents, 'n m d -> n (m d)')
+ return latents
+
+ def forward(self, sig):
+ x = self.forward_features(sig)
+ x = self.head(x)
+ return x
+
+class ClassificationMultiConv1dMamba(nn.Module):
+ """ Masked Autoencoder with VisionTransformer backbone
+ """
+
+ def __init__(self, sig_len=6000, patch_size=10, in_chans=1,
+ embed_dim=[32,64,128], depth=[2,2,4], specific_depth=[2,2], num_heads=8,
+ seq_dim=512, seq_depth=2,
+ mlp_ratio=[4,4,4], norm_layer=nn.LayerNorm, num_classes=5,
+ modalities=["EEG","EOG"], num_experts=2, num_experts_per=1,
+ use_shared=True, use_moe=True, fusion_method='concat', fusion_depth=2, fusion_heads=8,
+ use_revin=False, pos_enc='sinusoidal',
+ ft_task='sleep_staging', d_state=16, d_conv=4, expand=2,
+ bidi=True, pretrain=False, use_micro=False,
+ demo_keys=['age','bmi','sex'], cycle_len=180, use_lstm=False, use_transformer=False,
+ simclr=False, simclr_temp=0.1,
+ dino=False, dino_student_temp=0.1, dino_teacher_temp=0.04,
+ dino_center_momentum=0.9, dino_momentum=0.996,
+ ):
+
+ super().__init__()
+
+ self.sig_len = sig_len
+ self.patch_size = patch_size
+ self.modalities = modalities
+ self.num_experts = num_experts
+ self.num_experts_per = num_experts_per
+ self.use_shared = use_shared
+ self.use_moe = use_moe
+ self.fusion_method = fusion_method
+ self.embed_dim = embed_dim
+ self.pos_enc = pos_enc
+ self.pretrain = pretrain
+ self.ft_task = ft_task
+ self.use_micro = use_micro
+ self.demo_keys = demo_keys
+ self.use_lstm = use_lstm
+ self.cycle_len = cycle_len
+ self.use_transformer = use_transformer
+ self.simclr = simclr
+ self.simclr_temp = simclr_temp
+ self.dino = dino
+ self.dino_student_temp = dino_student_temp
+ self.dino_teacher_temp = dino_teacher_temp
+ self.dino_center_momentum = dino_center_momentum
+ self.dino_momentum = dino_momentum
+
+ self.encoder = MultiEncoderClassification(sig_len=sig_len, patch_size=patch_size, in_chans=in_chans,
+ embed_dim=embed_dim, depth=depth, num_heads=num_heads, specific_depth=specific_depth,
+ mlp_ratio=mlp_ratio, norm_layer=norm_layer,
+ modalities=self.modalities, num_experts=num_experts, num_experts_per=num_experts_per,
+ use_shared=use_shared, use_moe=use_moe, pos_enc=pos_enc)
+
+ self.num_patches = self.encoder.num_patches
+
+
+ self.fuser = FusionUpsampleBlock(dim_list=embed_dim[2:],
+ fusion_method=fusion_method,
+ fusion_depth=fusion_depth,
+ fusion_heads=fusion_heads,
+ mlp_ratio=mlp_ratio[0],
+ norm_layer=norm_layer,
+ pos_enc=pos_enc,
+ use_shared=use_shared,
+ use_upsample=True,
+ modalities=self.modalities)
+
+ self.use_revin = use_revin
+ if self.use_revin:
+ self.revin = nn.ModuleDict()
+ for m in self.modalities:
+ if m != 'SaO2':
+ self.revin[m] = RevIN(num_features=1, affine=False)
+
+ if self.use_micro:
+ self.micro_head = nn.Linear(embed_dim[-1] * len(self.modalities), num_classes)
+
+ else:
+ self.bidi = bidi
+ self.proj = nn.Linear(embed_dim[-1] * len(self.modalities), seq_dim)
+ self.sequence_encoder = SeqEncoder(seq_dim=seq_dim,
+ depth=seq_depth,
+ d_state=d_state,
+ d_conv=d_conv,
+ expand=expand,
+ bidi=bidi,
+ use_transformer=use_transformer,
+ norm_layer=norm_layer)
+
+ out_dim = seq_dim * 2 if self.bidi else seq_dim
+ out_dim += embed_dim[-1] * len(self.modalities) # concat micro-fusion features
+
+ if self.pretrain:
+ # Projection head for contrastive learning
+ self.contr_head = nn.Sequential(
+ nn.Linear(seq_dim, seq_dim),
+ nn.ReLU(),
+ nn.Linear(seq_dim, seq_dim)
+ )
+
+ self.koleo_weight = 0.01
+ self.tau = 0.1
+ self.upsilon = 0.5
+
+ if self.dino:
+ self.teacher_contr_head = None
+ self.register_buffer('dino_center_f', torch.zeros(1, seq_dim))
+ self.register_buffer('dino_center_r', torch.zeros(1, seq_dim))
+ else:
+ if self.use_lstm:
+ if self.ft_task == 'diagnosis':
+ self.head = DiagnosisFinetuneFullLSTMCOXPHWithDemo(input_dim=out_dim,
+ embed_dim=128,
+ num_classes=num_classes)
+ else:
+ self.head = SleepEventLSTMClassifier(input_dim=out_dim,
+ embed_dim=128,
+ num_classes=num_classes,
+ num_heads=4,)
+ else:
+ self.head = nn.Linear(out_dim, num_classes)
+ # if self.use_disease_head:
+ # self.head = DiagnosisFinetuneFullLSTMCOXPHWithDemo(embed_dim=out_dim, num_classes=num_classes)
+ # else:
+ # # self.head = SleepEventLSTMClassifier(input_dim=out_dim,
+ # # embed_dim=128,
+ # # num_classes=num_classes,
+ # # num_heads=4,)
+ # self.head = nn.Linear(out_dim, num_classes)
+
+ self.apply(self._init_weights)
+ if self.pretrain and self.dino:
+ self.teacher_encoder = None
+ self.teacher_fuser = None
+ self.teacher_proj = None
+ self.teacher_sequence_encoder = None
+
+ def init_teacher(self):
+ if self.pretrain and self.dino:
+ self.teacher_encoder = copy.deepcopy(self.encoder)
+ self.teacher_fuser = copy.deepcopy(self.fuser)
+ self.teacher_proj = copy.deepcopy(self.proj) if hasattr(self, 'proj') else None
+ self.teacher_sequence_encoder = copy.deepcopy(self.sequence_encoder) if hasattr(self, 'sequence_encoder') else None
+ self.teacher_contr_head = copy.deepcopy(self.contr_head)
+ self._freeze_teacher()
+
+
+ def _init_weights(self, m):
+ if isinstance(m, nn.Linear):
+ torch.nn.init.xavier_uniform_(m.weight)
+ if isinstance(m, nn.Linear) and m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+
+ elif isinstance(m, nn.LayerNorm):
+ nn.init.constant_(m.bias, 0)
+ nn.init.constant_(m.weight, 1.0)
+
+
+
+ def forward_features(self, inputs, mask=None):
+ modalities_to_use = sorted(list(inputs.keys()))
+
+ m = modalities_to_use[0]
+ N, L, _ = inputs[m].shape
+ # N, L = mask.shape
+
+
+ if mask is not None:
+ nonmask_idx = torch.nonzero(mask.view(-1,)).squeeze(-1) # N*L_masked
+
+ for i, m in enumerate(modalities_to_use):
+ inputs[m] = inputs[m].view(-1, self.sig_len, inputs[m].shape[-1]) # add channel dim
+
+ if self.use_revin:
+ if m == 'SaO2':
+ inputs[m] = inputs[m][:, ::TARGET_RESAMPLE, :] # N,L* TARGET_RESAMPLE,1 -> N,L,1
+ else:
+ inputs[m] = self.revin[m](inputs[m], mode='norm')
+
+ if mask is not None:
+ inputs[m] = torch.gather(inputs[m], dim=0, index=nonmask_idx.unsqueeze(-1).unsqueeze(-1).repeat(1, inputs[m].shape[1], inputs[m].shape[2]))
+
+
+
+ latents_shared, latents_specific, _ = self.encoder(inputs, modalities_to_use)
+
+ latents_fused, upsampled = self.fuser(latents_shared, latents_specific)
+
+ latents_micro = torch.stack(latents_fused, dim=0) # (M, N, L, D)
+ latents_micro = rearrange(latents_micro, 'm n l d -> n l (m d)')
+
+ latents = latents_micro
+
+ # latents_micro = torch.stack(upsampled, dim=0) # (M, N, L, D)
+ # latents_micro = rearrange(latents_micro, 'm n l d -> n l (m d)')
+
+ if not self.pretrain:
+ latents_micro = latents_micro.mean(1)
+ dummy2 = torch.zeros((N*(L // self.sig_len), latents_micro.shape[-1]), device=latents_micro.device, dtype=latents_micro.dtype)
+ dummy2.scatter_(dim=0, index=nonmask_idx.unsqueeze(-1).repeat(1, latents_micro.shape[-1]), src=latents_micro)
+ latents_micro = dummy2
+ latents_micro = rearrange(latents_micro, '(n1 n2) d -> n1 n2 d', n1=N)
+
+ if self.use_micro:
+ return None, latents_micro
+
+ else:
+ latents = self.proj(latents)
+ latents = latents.mean(1)
+
+ dummy = torch.zeros((N*(L // self.sig_len), latents.shape[-1]), device=latents.device, dtype=latents.dtype)
+ dummy.scatter_(dim=0, index=nonmask_idx.unsqueeze(-1).repeat(1, latents.shape[-1]), src=latents)
+ latents = dummy
+ latents = rearrange(latents, '(n1 n2) d -> n1 n2 d', n1=N)
+
+ latents = self.sequence_encoder(latents, mask=mask)
+
+ return latents, latents_micro
+
+ def forward(self, sig, mask=None, demo=None):
+ if self.pretrain and self.dino:
+ if self.simclr:
+ raise ValueError("DINO and SimCLR cannot be enabled at the same time.")
+ if self.teacher_encoder is None:
+ raise ValueError("DINO teacher modules are not initialized. Call init_teacher() after loading checkpoints.")
+ if mask is None:
+ raise ValueError("DINO pretraining requires a valid mask.")
+ if isinstance(sig, (tuple, list)):
+ if len(sig) != 2:
+ raise ValueError("DINO expects exactly two views in a list/tuple.")
+ sig1, sig2 = sig
+ elif isinstance(sig, dict) and 'view1' in sig and 'view2' in sig:
+ sig1, sig2 = sig['view1'], sig['view2']
+ else:
+ raise ValueError("DINO expects inputs as (view1, view2) or a dict with 'view1'/'view2'.")
+
+ z1_f_s, z1_r_s = self._dino_representation(sig1, mask, use_teacher=False)
+ z2_f_s, z2_r_s = self._dino_representation(sig2, mask, use_teacher=False)
+
+ z1_f_s = self.contr_head(z1_f_s)
+ z1_r_s = self.contr_head(z1_r_s)
+ z2_f_s = self.contr_head(z2_f_s)
+ z2_r_s = self.contr_head(z2_r_s)
+
+ with torch.no_grad():
+ z1_f_t, z1_r_t = self._dino_representation(sig1, mask, use_teacher=True)
+ z2_f_t, z2_r_t = self._dino_representation(sig2, mask, use_teacher=True)
+ z1_f_t = self.teacher_contr_head(z1_f_t)
+ z1_r_t = self.teacher_contr_head(z1_r_t)
+ z2_f_t = self.teacher_contr_head(z2_f_t)
+ z2_r_t = self.teacher_contr_head(z2_r_t)
+ self._update_dino_center(torch.cat([z1_f_t.mean(1), z2_f_t.mean(1)], dim=0),
+ torch.cat([z1_r_t.mean(1), z2_r_t.mean(1)], dim=0))
+
+ num_seg = z2_f_s.shape[1]
+ loss_fwd, loss_bwd = 0.0, 0.0
+ for s in range(num_seg):
+ loss_fwd += self.dino_loss(z1_f_s[:,s], z2_f_t[:,s], fwd=True)
+ loss_fwd += self.dino_loss(z2_f_s[:,s], z1_f_t[:,s], fwd=True)
+ loss_bwd += self.dino_loss(z1_r_s[:,s], z2_r_t[:,s], fwd=False)
+ loss_bwd += self.dino_loss(z2_r_s[:,s], z1_r_t[:,s], fwd=False)
+ loss = (loss_fwd + loss_bwd) / 2 / 2
+
+ return loss
+
+ if self.pretrain and self.simclr:
+ if mask is None:
+ raise ValueError("SimCLR pretraining requires a valid mask.")
+ if isinstance(sig, (tuple, list)):
+ if len(sig) != 2:
+ raise ValueError("SimCLR expects exactly two views in a list/tuple.")
+ sig1, sig2 = sig
+ elif isinstance(sig, dict) and 'view1' in sig and 'view2' in sig:
+ sig1, sig2 = sig['view1'], sig['view2']
+ else:
+ raise ValueError("SimCLR expects inputs as (view1, view2) or a dict with 'view1'/'view2'.")
+
+ if self.bidi:
+ z1_f, z1_r = self._simclr_representation(sig1, mask)
+ z2_f, z2_r = self._simclr_representation(sig2, mask)
+
+ z1_f = self.contr_head(z1_f)
+ z1_r = self.contr_head(z1_r)
+ z2_f = self.contr_head(z2_f)
+ z2_r = self.contr_head(z2_r)
+
+ num_seg = z1_f.shape[1]
+ loss_fwd, loss_bwd = 0.0, 0.0
+ for s in range(num_seg):
+ loss_fwd += self.simclr_loss(z1_f[:,s], z2_f[:,s])
+ loss_bwd += self.simclr_loss(z1_r[:,s], z2_r[:,s])
+ loss = (loss_fwd + loss_bwd) / 2
+ else:
+ z1 = self._simclr_representation(sig1, mask)
+ z2 = self._simclr_representation(sig2, mask)
+ loss = self.simclr_loss(self.contr_head(z1), self.contr_head(z2))
+
+ return loss
+
+ feats = self.forward_features(sig, mask=mask)
+ # Pretraining
+ if self.pretrain:
+ if self.bidi:
+ (xf, xr), _ = feats
+ loss_fwd = self.forward_loss(xf, demo, mask)
+ loss_bwd = self.forward_loss(xr, demo, mask)
+ loss = (loss_fwd + loss_bwd) / 2
+ else:
+ xf, _ = feats
+ loss = self.forward_loss(xf, demo, mask)
+ return loss
+
+ # Inference / Finetuning
+ if not self.use_micro and self.bidi:
+ (x_macro_f, x_macro_r), x_micro = feats
+ x_macro_r = flip_padded_sequences(x_macro_r, mask)
+ x_macro = torch.cat([x_macro_f, x_macro_r], dim=-1)
+ else:
+ x_macro, x_micro = feats
+ # x = torch.cat([xf, x_micro], dim=-1)
+
+ if self.ft_task in ['diagnosis', 'age' ,'sex', 'ahi']:
+ B = x_micro.shape[0]
+ lengths = mask.sum(dim=1).long() # (B,)
+ if self.use_micro:
+ x_micro = torch.stack([x_micro[i, :lengths[i]].mean(dim=0) for i in range(B)])
+ x = self.micro_head(x_micro)
+ else:
+ x_mami = torch.cat([x_macro, x_micro], dim=-1)
+ if self.use_lstm:
+ x = self.head(x_mami, mask, demo)
+ else:
+ x_mami = torch.stack([x_mami[i, :lengths[i]].mean(dim=0) for i in range(B)])
+ x = self.head(x_mami)
+
+ # x = self.disease_head(x, mask, demo)
+ return x
+ else:
+ if self.use_micro:
+ x = self.micro_head(x_micro)
+ else:
+ x_mami = torch.cat([x_macro, x_micro], dim=-1)
+ # x = self.head(x_mami)
+ if self.use_lstm:
+ x = self.head(x_mami, mask)
+ else:
+ x = self.head(x_mami)
+ x = rearrange(x, 'n1 n2 d -> n1 d n2')
+ return x
+
+ def forward_loss(self, xf, demo, mask):
+ """
+ Calculate contrastive loss based on the difference of age.
+ When the corresponding ages between two sequences are distant, the representation should be distant
+ In constrast, if ages are close, the representation should be similar.
+ """
+
+ N, L, D = xf.shape
+ num_cycle = L // self.cycle_len
+
+ age = demo['age'] # mean 56.071731 std 16.131597 25% 45.0 50% 58.0 75% 68.0 max 120.0
+ sex = demo['sex']
+ bmi = demo['bmi'] # mean 27.095034 std 4.943150 25% 23.8 50% 26.456448 75% 29.70 max 50.800000
+
+ # age = (torch.clamp(age, 19, 86) - 19) / (86 - 19)
+ mu_age, std_age = 56.071731, 16.131597
+ mu_bmi, std_bmi = 27.095034, 4.943150
+ age = (age - mu_age) / std_age
+
+ age_t = age.unsqueeze(-1)
+ age = age.unsqueeze(0)
+ # distance = torch.maximum((age - age_t).abs(), torch.tensor(1.0/std_age, device=age.device))
+ distance_age = (age - age_t).abs()
+
+ # BMI adjustment
+
+ bmi = (bmi - mu_bmi) / std_bmi
+ bmi_t = bmi.unsqueeze(-1)
+ bmi = bmi.unsqueeze(0)
+ distance_bmi = (bmi - bmi_t).abs()
+
+ diff_sex_matrix = 1.0 - (sex.unsqueeze(0) == sex.unsqueeze(1)).float() # Same sex: 0, different sex: 1
+
+ distance = torch.zeros_like(distance_age)
+ if 'age' in self.demo_keys:
+ distance += distance_age
+
+ if 'bmi' in self.demo_keys:
+ distance += distance_bmi
+
+ if 'age' in self.demo_keys and 'bmi' in self.demo_keys:
+ distance = distance / 2
+
+ if 'sex' in self.demo_keys:
+ distance += diff_sex_matrix
+
+
+ distance += torch.eye(N, device=age.device) * 1e8
+
+ mask_seg = mask.view(N, -1, self.cycle_len).any(-1) # (N, num_seg)
+ distance = distance.unsqueeze(0).repeat(num_cycle,1,1) # (num_cycle, N, N)
+ mask1 = mask_seg.permute(1,0) # (num_cycle, N)
+ label = F.softmax((- distance / self.upsilon), dim=-1) # (num_cycle, N, N)
+
+ if mask is not None:
+ xf = xf.masked_fill(~mask.unsqueeze(-1), 0.0)
+
+ min_length = mask.sum(dim=1).min()
+ num_seg = min_length // self.cycle_len
+
+
+ if self.use_transformer:
+ # min_length = num_seg * self.cycle_len
+ # xf = xf[:, :min_length, :]
+ seq1 = xf.view(N, -1, self.cycle_len, D).mean(2) # (N, num_seg, D)
+ seq1 = self.contr_head(seq1)
+ seq1 = F.normalize(seq1, p=2, dim=-1) #
+ else:
+ # Last feature
+ if not min_length == L:
+ mask_len = mask.sum(dim=1)
+ seq1_last = xf[torch.arange(N, device=xf.device), mask_len - 1]
+ seq1_last = self.contr_head(seq1_last)
+ seq1_last = F.normalize(seq1_last, p=2, dim=-1)
+
+
+
+ if num_seg < 1:
+ seq1 = seq1_last.unsqueeze(1)
+ else:
+ min_length = num_seg * self.cycle_len
+
+ seq_trunc = xf[:, :min_length, :]
+ seq1 = seq_trunc[:,(self.cycle_len-1)::self.cycle_len]
+ B_temp, S_temp, D_temp = seq1.shape
+ seq1 = seq1.reshape(-1, D_temp) # flatten batch and segments
+ seq1 = self.contr_head(seq1)
+ seq1 = seq1.reshape(B_temp, S_temp, -1) # reshape back
+ seq1 = F.normalize(seq1, p=2, dim=-1) # (N, num_seg, D)
+
+ # Last feature
+ if not min_length == L:
+ seq1 = torch.cat([seq1, seq1_last.unsqueeze(1)], dim=1) # (N, num_seg+1, D)
+
+
+ koleo_loss = 0.0
+ for i in range(seq1.shape[1]):
+ koleo_loss += self.koleo_loss(seq1[i])
+
+ koleo_loss = koleo_loss / seq1.shape[1]
+ # Patient by patient similarity
+ seq1 = seq1.permute(1,0,2).contiguous() # (num_seg, N, D)
+ sims_pos = seq1 @ seq1.permute(0,2,1) - torch.eye(N, device=age.device).unsqueeze(0) * 1e8 # (num_seg, N, N)
+ sims = sims_pos / self.tau # (num_seg, N, N)
+ # print("## Similarity", sims[0,0])
+
+ loss1, cnt = 0, 0
+ for i in range(num_seg):
+ if mask1[i].sum() <= 4:
+ continue
+ sims1 = sims[i][mask1[i]].masked_fill(~mask1[i], -1e8)
+ label1 = label[i][mask1[i]].masked_fill(~mask1[i], 0.0)
+ loss1 += nn.CrossEntropyLoss(reduction='mean')(sims1, label1)
+ cnt += 1
+
+ if not self.use_transformer and not min_length == L:
+ loss1 += nn.CrossEntropyLoss(reduction='mean')(sims[-1], label[0])
+ cnt += 1
+
+ loss1 = loss1 / cnt if cnt > 0 else loss1
+ loss1 = loss1 + self.koleo_weight * koleo_loss
+ # print("## Loss1:", loss1.item(), " KoLeo:", koleo_loss.item())
+
+ return loss1
+
+ # def _simclr_representation(self, sig, mask):
+ # feats = self.forward_features(sig, mask=mask)
+
+ # x_macro, _ = feats
+ # if self.bidi:
+ # x_macro_f, x_macro_r = x_macro
+ # x = torch.cat([x_macro_f, x_macro_r], dim=-1)
+ # else:
+ # x = x_macro
+ # return self._masked_mean(x, mask)
+
+ def _simclr_representation(self, sig, mask):
+ feats = self.forward_features(sig, mask=mask)
+
+ x_macro, _ = feats
+ if self.bidi:
+ xf, xr = x_macro
+ xf = self._get_cycle_values(xf, mask)
+ xr = self._get_cycle_values(xr, mask)
+ return xf, xr
+ else:
+ return self._get_cycle_values(x_macro, mask)
+
+ def _get_cycle_values(self, xf, mask):
+ if mask is not None:
+ xf = xf.masked_fill(~mask.unsqueeze(-1), 0.0)
+
+ min_length = mask.sum(dim=1).min()
+ num_seg = min_length // self.cycle_len
+ N, L, D = xf.shape
+
+ # Last feature
+ if not min_length == L:
+ mask_len = mask.sum(dim=1)
+ seq1_last = xf[torch.arange(N, device=xf.device), mask_len - 1]
+ seq1_last = self.contr_head(seq1_last)
+ seq1_last = F.normalize(seq1_last, p=2, dim=-1)
+
+ if num_seg < 1:
+ seq1 = seq1_last.unsqueeze(1)
+ else:
+ min_length = num_seg * self.cycle_len
+
+ seq_trunc = xf[:, :min_length, :]
+ seq1 = seq_trunc[:,(self.cycle_len-1)::self.cycle_len]
+ B_temp, S_temp, D_temp = seq1.shape
+ seq1 = seq1.reshape(-1, D_temp) # flatten batch and segments
+ seq1 = self.contr_head(seq1)
+ seq1 = seq1.reshape(B_temp, S_temp, -1) # reshape back
+ seq1 = F.normalize(seq1, p=2, dim=-1) # (N, num_seg, D)
+
+ # Last feature
+ if not min_length == L:
+ seq1 = torch.cat([seq1, seq1_last.unsqueeze(1)], dim=1) # (N, num_seg+1, D)
+ return seq1
+
+ def _masked_mean(self, x, mask):
+ if mask is None:
+ return x.mean(1)
+ mask = mask.to(dtype=x.dtype)
+ denom = mask.sum(dim=1, keepdim=True).clamp(min=1.0)
+ return (x * mask.unsqueeze(-1)).sum(dim=1) / denom
+
+ def _dino_representation(self, sig, mask, use_teacher=False):
+ if use_teacher:
+ feats = self._forward_features_with_modules(sig, mask, self.teacher_encoder, self.teacher_fuser, self.teacher_proj, self.teacher_sequence_encoder)
+ else:
+ feats = self.forward_features(sig, mask=mask)
+
+ x_macro, _ = feats
+ if self.bidi:
+ xf, xr = x_macro
+ xf = self._get_cycle_values(xf, mask)
+ xr = self._get_cycle_values(xr, mask)
+ return xf, xr
+ else:
+ return self._get_cycle_values(x_macro, mask)
+
+
+ def _forward_features_with_modules(self, inputs, mask, encoder, fuser, proj, sequence_encoder):
+ modalities_to_use = sorted(list(inputs.keys()))
+
+ m = modalities_to_use[0]
+ N, L = mask.shape
+
+ if mask is not None:
+ nonmask_idx = torch.nonzero(mask.view(-1,)).squeeze(-1)
+
+ # for m in modalities_to_use:
+ # inputs[m] = inputs[m].view(-1, self.sig_len, inputs[m].shape[-1])
+ # if self.use_revin:
+ # if m == 'SaO2':
+ # inputs[m] = inputs[m][:, ::TARGET_RESAMPLE, :]
+ # else:
+ # inputs[m] = self.revin[m](inputs[m], mode='norm')
+ # if mask is not None:
+ # inputs[m] = torch.gather(
+ # inputs[m],
+ # dim=0,
+ # index=nonmask_idx.unsqueeze(-1).unsqueeze(-1).repeat(1, inputs[m].shape[1], inputs[m].shape[2])
+ # )
+
+ latents_shared, latents_specific, _ = encoder(inputs, modalities_to_use)
+ latents_fused, _ = fuser(latents_shared, latents_specific)
+
+ latents_micro = torch.stack(latents_fused, dim=0)
+ latents_micro = rearrange(latents_micro, 'm n l d -> n l (m d)')
+
+ if self.use_micro:
+ return None, latents_micro
+
+ latents = proj(latents_micro)
+ latents = latents.mean(1)
+
+
+ dummy = torch.zeros((N * L, latents.shape[-1]), device=latents.device, dtype=latents.dtype)
+ dummy.scatter_(dim=0, index=nonmask_idx.unsqueeze(-1).repeat(1, latents.shape[-1]), src=latents)
+ latents = dummy
+ latents = rearrange(latents, '(n1 n2) d -> n1 n2 d', n1=N)
+ latents = sequence_encoder(latents, mask=mask)
+ return latents, latents_micro
+
+ def dino_loss(self, student_out, teacher_out, fwd=False):
+ student_out = student_out / (self.dino_student_temp + 1e-8)
+ center = self.dino_center_f if fwd else self.dino_center_r
+ teacher_out = F.softmax((teacher_out - center) / (self.dino_teacher_temp + 1e-8), dim=-1)
+ return torch.sum(-teacher_out * F.log_softmax(student_out, dim=-1), dim=-1).mean()
+
+ @torch.no_grad()
+ def _update_dino_center(self, teacher_out_f, teacher_out_r):
+ batch_center_f = teacher_out_f.mean(dim=0, keepdim=True)
+ batch_center_r = teacher_out_r.mean(dim=0, keepdim=True)
+ self.dino_center_f.mul_(self.dino_center_momentum).add_(batch_center_f * (1.0 - self.dino_center_momentum))
+ self.dino_center_r.mul_(self.dino_center_momentum).add_(batch_center_r * (1.0 - self.dino_center_momentum))
+
+ @torch.no_grad()
+ def update_teacher(self, momentum=None):
+ if not self.dino or self.teacher_encoder is None:
+ return
+ m = self.dino_momentum if momentum is None else momentum
+ pairs = [
+ (self.encoder, self.teacher_encoder),
+ (self.fuser, self.teacher_fuser),
+ ]
+ if self.teacher_proj is not None:
+ pairs.append((self.proj, self.teacher_proj))
+ if self.teacher_sequence_encoder is not None:
+ pairs.append((self.sequence_encoder, self.teacher_sequence_encoder))
+ pairs.append((self.contr_head, self.teacher_contr_head))
+
+ for student, teacher in pairs:
+ for param_s, param_t in zip(student.parameters(), teacher.parameters()):
+ param_t.data.mul_(m).add_(param_s.data * (1.0 - m))
+
+ def _freeze_teacher(self):
+ for module in [self.teacher_encoder, self.teacher_fuser, self.teacher_proj, self.teacher_sequence_encoder, self.teacher_contr_head]:
+ if module is None:
+ continue
+ for param in module.parameters():
+ param.requires_grad = False
+ module.eval()
+
+ # def _masked_mean(self, x, mask):
+ # if mask is None:
+ # return x.mean(1)
+ # mask = mask.to(dtype=x.dtype)
+ # denom = mask.sum(dim=1, keepdim=True).clamp(min=1.0)
+ # return (x * mask.unsqueeze(-1)).sum(dim=1) / denom
+
+ def simclr_loss(self, z1, z2):
+ z1 = F.normalize(z1, p=2, dim=-1)
+ z2 = F.normalize(z2, p=2, dim=-1)
+ z = torch.cat([z1, z2], dim=0)
+ logits = torch.matmul(z, z.t()) / (self.simclr_temp + 1e-8)
+ logits = logits - torch.eye(logits.shape[0], device=logits.device, dtype=logits.dtype) * 1e9
+ batch_size = z1.shape[0]
+ targets = torch.arange(2 * batch_size, device=logits.device)
+ targets = (targets + batch_size) % (2 * batch_size)
+ return F.cross_entropy(logits, targets)
+
+
+ def koleo_loss(self, x, ys=None, eps=1e-8):
+ """
+ Compute KoLeo (Kozachenko-Leonenko) regularization loss.
+ Encourages uniform distribution of representations on the hypersphere.
+
+ Args:
+ x: Tensor of shape (N, D) where N is batch size and D is feature dimension
+ eps: Small constant for numerical stability
+
+ Returns:
+ KoLeo loss (scalar)
+ """
+ # Normalize representations to unit hypersphere
+ x = F.normalize(x, p=2, dim=-1)
+
+ # Compute pairwise distances
+ # Using efficient computation: ||a - b||^2 = ||a||^2 + ||b||^2 - 2
+ # Since normalized, ||a||^2 = ||b||^2 = 1, so ||a - b||^2 = 2 - 2
+ gram_matrix = torch.matmul(x, x.t()) # (N, N)
+ sq_distances = 2 - 2 * gram_matrix # (N, N)
+ sq_distances = torch.clamp(sq_distances, min=0) # numerical stability
+
+ # Set diagonal to infinity (exclude self-distance)
+ sq_distances = sq_distances + torch.eye(x.shape[0], device=x.device) * 1e10
+
+ if ys is not None:
+ for y in ys:
+ y = F.normalize(y, p=2, dim=-1)
+ y_distance = (x - y).pow(2).sum(dim=-1, keepdim=True) # (N, 1)
+ sq_distances = torch.cat([sq_distances, y_distance], dim=1) # (N, N + len(ys))
+
+ # Find minimum distance for each sample (nearest neighbor)
+ min_sq_distances, _ = torch.min(sq_distances, dim=1) # (N,)
+
+ # KoLeo loss is negative log of minimum distances
+ # We want to maximize minimum distances -> minimize negative log
+ distances = torch.sqrt(min_sq_distances + eps)
+ koleo_loss = -torch.log(distances + eps).mean()
+
+ return koleo_loss
+
+
+class SleepEventLSTMClassifier(nn.Module):
+ def __init__(self,
+ input_dim=384*6+512*2,
+ embed_dim=128,
+ num_heads=4,
+ num_layers=1,
+ num_classes=5,
+ pooling_head=4,
+ dropout=0.3,
+ max_seq_length=128):
+ super().__init__()
+
+ # Define spatial pooling
+ # self.spatial_pooling = AttentionPooling(embed_dim, num_heads=pooling_head, dropout=dropout)
+
+ # Set max sequence length
+ # if max_seq_length is None:
+ # max_seq_length = 20000
+
+ # self.positional_encoding = PositionalEncoding(max_seq_length, embed_dim)
+ self.layer_norm = nn.LayerNorm(input_dim)
+ self.proj = nn.Linear(input_dim, embed_dim)
+
+ # Transformer encoder for spatial modeling
+ encoder_layer = nn.TransformerEncoderLayer(d_model=embed_dim, nhead=num_heads, dropout=dropout, batch_first=True, norm_first=True)
+ self.transformer_encoder = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
+
+ # LSTM for temporal modeling
+ lstm_dropout = dropout if num_layers > 1 else 0.0
+ self.lstm = nn.LSTM(input_size=embed_dim, hidden_size=embed_dim//2, num_layers=num_layers, batch_first=True, dropout=lstm_dropout, bidirectional=True)
+
+ # Fully connected layer for classification
+ self.fc = nn.Linear(embed_dim, num_classes)
+
+ def forward(self, x, mask, demo=None):
+ # B, C, S, E = x.shape
+
+ # Rearrange for spatial pooling
+ # x = rearrange(x, 'b c s e -> (b s) c e')
+
+ # # Prepare the mask for spatial pooling
+ # mask_spatial = mask[:, :, 0]
+ # mask_spatial = mask_spatial.unsqueeze(1).expand(-1, S, -1)
+ # mask_spatial = rearrange(mask_spatial, 'b t c -> (b t) c')
+
+ # # Ensure the mask is boolean
+ # if mask_spatial.dtype != torch.bool:
+ # mask_spatial = mask_spatial.to(dtype=torch.bool)
+
+ # # Apply spatial pooling
+ # x = self.spatial_pooling(x, mask_spatial)
+
+ # Reshape to (B, S, E) after pooling
+ # x = x.view(B, S, E)
+
+ # Apply positional encoding and layer normalization
+ # x = self.positional_encoding(x)
+ x = self.layer_norm(x)
+ x = self.proj(x)
+
+ # Apply transformer encoder for spatial modeling
+ # mask_temporal = mask[:, 0, :]
+ mask_temporal = ~mask # 1 should be padding, 0 should be valid values
+ x = self.transformer_encoder(x, src_key_padding_mask=mask_temporal)
+
+ # Apply LSTM for temporal modeling
+ x, _ = self.lstm(x) # Shape: (B, S, E)
+
+ # Apply the final fully connected layer for classification
+ x = self.fc(x) # Shape: (B, S, num_classes)
+
+ return x # Return mask along temporal dimension
+
+
+
+# From SleepFM-clinical
+import torch.nn.utils.rnn as rnn_utils
+class DiagnosisFinetuneFullLSTMCOXPHWithDemo(nn.Module):
+ def __init__(self, input_dim, embed_dim=128, num_layers=2, num_classes=6, dropout=0.1):
+ super(DiagnosisFinetuneFullLSTMCOXPHWithDemo, self).__init__()
+
+ self.layer_norm = nn.LayerNorm(input_dim)
+ self.proj = nn.Linear(input_dim, embed_dim)
+ self.lstm = nn.LSTM(
+ input_size=embed_dim,
+ hidden_size=embed_dim // 2,
+ num_layers=num_layers,
+ batch_first=True,
+ bidirectional=True
+ )
+ self.demo_embedding = nn.Sequential(
+ nn.Linear(2, embed_dim // 4),
+ nn.ReLU(),
+ nn.Dropout(dropout)
+ )
+
+ # Update the input size of the disease head to account for embedded demo features
+ self.head = nn.Linear(embed_dim + embed_dim // 4, num_classes) # embed_dim // 4 from demo features
+
+ def forward(self, x, mask, demo):
+ # B, C, S, E = x.shape # C: Modalities
+
+ # # Rearrange for spatial pooling
+ # x = rearrange(x, 'b c s e -> (b s) c e')
+
+ # mask_spatial = mask[:, :, 0]
+ # mask_spatial = mask_spatial.unsqueeze(1).expand(-1, S, -1)
+ # mask_spatial = rearrange(mask_spatial, 'b t c -> (b t) c')
+
+ # # Ensure the mask is boolean
+ # mask_spatial = mask_spatial.to(dtype=torch.bool)
+
+ # # Apply spatial pooling
+ # x = self.spatial_pooling(x, mask_spatial)
+ # x = x.view(B, S, E)
+
+ # # Rearrange mask for temporal pooling
+ # # mask_temporal = mask[:, 0, :] # Use the mask along the temporal dimension
+
+ # # Compute the lengths for packing based on the mask
+ # lengths = (mask_temporal == 0).sum(dim=1).cpu()
+
+
+ x = self.layer_norm(x)
+ x = self.proj(x)
+ # lengths = (mask == 1).sum(dim=1).cpu() # (B,)
+ lengths = mask.sum(dim=1).long().cpu() # (B,)
+ B = x.shape[0]
+ # Pack the sequence for LSTM
+ packed_x = rnn_utils.pack_padded_sequence(x, lengths, batch_first=True, enforce_sorted=False)
+
+ # Pass the packed sequence through the LSTM
+ packed_out, _ = self.lstm(packed_x)
+
+ # Unpack the sequence
+ x, _ = rnn_utils.pad_packed_sequence(packed_out, batch_first=True)
+
+ # Apply mean pooling only over valid lengths
+ x = torch.stack([x[i, :lengths[i]].mean(dim=0) for i in range(B)])
+
+ age = (demo['age'] - 63.14)/11.22
+ age = torch.clamp(age, -3.0, 3.0)
+
+ sex = demo['sex'] - 1 # 0 or 1
+
+ demo_features = torch.cat([age.unsqueeze(1), sex.unsqueeze(1)], dim=1)
+ demo_features = demo_features.to(x.device, dtype=x.dtype)
+ # Embed the demo features
+ demo_embed = self.demo_embedding(demo_features) # (B, embed_dim // 4)
+
+ # Concatenate the demo features with the LSTM output
+ x = torch.cat([x, demo_embed], dim=1) # (B, embed_dim + embed_dim // 4)
+
+ # Apply the disease head to get hazards
+ hazards = self.head(x)
+
+ return hazards
+
+
+class DiagnosisFinetuneDemoOnly(nn.Module):
+ def __init__(self, embed_dim=128, num_layers=2, num_classes=6, dropout=0.1):
+ super().__init__()
+
+ self.demo_embedding = nn.Sequential(
+ nn.Linear(2, embed_dim // 4),
+ nn.ReLU(),
+ nn.Dropout(dropout)
+ )
+
+ # Update the input size of the disease head to account for embedded demo features
+ self.head = nn.Linear(embed_dim // 4, num_classes) # embed_dim // 4 from demo features
+
+ def forward(self, x, mask, demo):
+
+ age = (demo['age'] - 63.14)/11.22
+ age = torch.clamp(age, -3.0, 3.0)
+
+ sex = demo['sex'] - 1 # 0 or 1
+
+ demo_features = torch.cat([age.unsqueeze(1), sex.unsqueeze(1)], dim=1)
+ demo_features = demo_features.to(x.device, dtype=x.dtype)
+ # Embed the demo features
+ demo_embed = self.demo_embedding(demo_features) # (B, embed_dim // 4)
+
+ # Apply the disease head to get hazards
+ hazards = self.head(demo_embed)
+
+ return hazards
\ No newline at end of file
diff --git a/models/decoders.py b/models/decoders.py
new file mode 100644
index 0000000000000000000000000000000000000000..6f5fbaf8cb1ec367a6653d7037d3ee75fc4f740a
--- /dev/null
+++ b/models/decoders.py
@@ -0,0 +1,124 @@
+import torch
+import torch.nn as nn
+from util.pos_embed import get_1d_sincos_pos_embed
+from models.transformer_modules import BlockFlashAttn, freq_pos_enc
+
+class Decoder(nn.Module):
+ def __init__(self, num_patches=75, encoder_embed_dim=128, decoder_embed_dim=128, decoder_depth=8, decoder_num_heads=4,
+ mlp_ratio=4, norm_layer=nn.LayerNorm, decoder_pred_dim=40, fusion_method=None, pos_enc='sinusoidal'):
+ super().__init__()
+
+ # --------------------------------------------------------------------------
+ self.num_patches = num_patches
+ # ConvMAE decoder specifics
+ self.decoder_embed = nn.Linear(encoder_embed_dim, decoder_embed_dim, bias=True)
+
+ self.mask_token = nn.Parameter(torch.zeros(1, 1, decoder_embed_dim))
+
+ self.pos_enc = pos_enc
+ self.decoder_pos_embed = nn.Parameter(torch.zeros(1, self.num_patches, decoder_embed_dim), requires_grad=False) # fixed sin-cos embedding
+ if pos_enc == 'rope':
+ self.rope = freq_pos_enc(dim=decoder_embed_dim // decoder_num_heads, max_seq_len=num_patches)
+
+ self.decoder_blocks = nn.ModuleList([
+ BlockFlashAttn(decoder_embed_dim, decoder_num_heads, mlp_ratio, qkv_bias=True, qk_scale=None, norm_layer=norm_layer)
+ for i in range(decoder_depth)])
+
+ self.decoder_norm = norm_layer(decoder_embed_dim)
+
+ self.decoder_pred = nn.Linear(decoder_embed_dim, decoder_pred_dim, bias=True) # decoder to patch
+ # --------------------------------------------------------------------------
+
+ self.initialize_weights()
+
+ def initialize_weights(self):
+ # initialization
+ # initialize (and freeze) pos_embed by sin-cos embedding
+ decoder_pos_embed = get_1d_sincos_pos_embed(self.decoder_pos_embed.shape[-1], self.num_patches, cls_token=False)
+ self.decoder_pos_embed.data.copy_(torch.from_numpy(decoder_pos_embed).float().unsqueeze(0))
+
+ # timm's trunc_normal_(std=.02) is effectively normal_(std=0.02) as cutoff is too big (2.)
+# torch.nn.init.normal_(self.cls_token, std=.02)
+ torch.nn.init.normal_(self.mask_token, std=.02)
+
+ def forward_features(self, x, ids_keep, idx=0):
+ # embed tokens
+ x = self.decoder_embed(x)
+ N, L, d = x.shape
+
+ if self.num_patches > x.shape[1]:
+ # append mask tokens to sequence
+ masked = self.mask_token.repeat(N, self.num_patches, 1).to(dtype=x.dtype, device=x.device)
+ masked.scatter_(dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, d), src=x) # fill the mask tokens with the original tokens
+ x_ = masked
+ # if idx == 0:
+ # x_ = torch.cat([x, mask_tokens], dim=1)
+ # else:
+ # x_ = torch.cat([mask_tokens, x], dim=1)
+ else:
+ x_ = x
+ # x = torch.gather(x_, dim=1, index=ids_restore.unsqueeze(-1).repeat(1, 1, x.shape[2])) # unshuffle
+
+ # add pos embed
+ if self.pos_enc == 'sinusoidal':
+ x = x_ + self.decoder_pos_embed
+ else:
+ x = x_
+
+ # apply Transformer blocks
+ for blk in self.decoder_blocks:
+ if self.pos_enc == 'rope':
+ pe = self.rope.unsqueeze(0).to(dtype=x.dtype, device=x.device) # (1, max_seq_len, dim)
+ pe = pe.repeat(N, 1, 1) # (N, max_seq_len, dim)
+ else:
+ pe = None
+ x, _ = blk(x, rope=pe)
+ x = self.decoder_norm(x)
+
+ return x
+
+ def forward(self, x, ids_keep):
+ x = self.forward_features(x, ids_keep)
+
+ # predictor projection
+ x = self.decoder_pred(x)
+
+ return x
+
+class SpecificDecoder(Decoder):
+ def __init__(self, num_patches=75, encoder_embed_dim=128,
+ decoder_embed_dim=128, decoder_depth=8, decoder_num_heads=4,
+ mlp_ratio=4, norm_layer=nn.LayerNorm, decoder_pred_dim=40,
+ fusion_method='concat'):
+ super().__init__(num_patches=num_patches, encoder_embed_dim=encoder_embed_dim,
+ decoder_embed_dim=decoder_embed_dim, decoder_depth=decoder_depth, decoder_num_heads=decoder_num_heads,
+ mlp_ratio=mlp_ratio, norm_layer=norm_layer, decoder_pred_dim=decoder_pred_dim, fusion_method=fusion_method)
+
+ self.fusion_method = fusion_method
+ if self.fusion_method == 'concat':
+ self.prenorm = norm_layer(encoder_embed_dim * 2) # prenorm for the weighted sum features
+ self.merge = nn.Linear(encoder_embed_dim * 2, encoder_embed_dim)
+ elif self.fusion_method == 'cross_attn':
+ self.cross_attention = BlockFlashAttn(encoder_embed_dim, decoder_num_heads, mlp_ratio, norm_layer=norm_layer)
+ self.post_norm = norm_layer(encoder_embed_dim)
+
+ def forward(self, x, x_shared, ids_keep, weight_shared=0.5, idx=0):
+
+ # x = x * (1 - weight_shared) + x_shared * weight_shared
+ # x = x_shared
+ if self.fusion_method == 'concat':
+ x = self.prenorm(x) # apply prenorm before the forward_features
+ x = torch.cat([x, x_shared], dim=-1)
+ x = self.merge(x)
+ elif self.fusion_method == 'cross_attn':
+ x = self.cross_attention(x, x_shared)
+ x = self.post_norm(x)
+
+
+ x = self.forward_features(x, ids_keep, idx=idx)
+ # x = x * (1 - weight_shared) + x_shared * weight_shared
+
+ # predictor projection
+ x = self.decoder_pred(x)
+
+ return x
diff --git a/models/encoders.py b/models/encoders.py
new file mode 100644
index 0000000000000000000000000000000000000000..16b5a745e0677bede2aa4e25f97bf35d5760fbd9
--- /dev/null
+++ b/models/encoders.py
@@ -0,0 +1,436 @@
+from functools import partial
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import numpy as np
+
+from models.transformer_modules import Block, MoEBlockFlashAttn, BlockFlashAttn, \
+ PatchEmbed, PatchMergeConv, freq_pos_enc
+from models.utils import get_1d_sincos_pos_embed
+from einops import rearrange
+
+class MultiEncoder(nn.Module):
+ def __init__(self, sig_len=6000, patch_size=10, in_chans=1,
+ embed_dim=[16,32,64,128], depth=[2,2,4], num_heads=8,
+ specific_depth=[2,2,4],
+ mlp_ratio=[4,4,4], norm_layer=nn.LayerNorm,
+ modalities=["EEG","EOG"], num_experts=2, num_experts_per=1,
+ use_shared=True, use_moe=True, mask_ratio=0.5, pos_enc='sinusoidal'):
+ super().__init__()
+
+ self.conv_encoders = nn.ModuleDict()
+ self.modalities = modalities
+ self.patch_size = patch_size
+ self.use_shared = use_shared
+ self.use_moe = use_moe
+ self.mask_ratio = mask_ratio
+ self.pos_enc = pos_enc
+
+ self.depth = depth
+ self.specific_depth = specific_depth
+ self.num_heads = num_heads
+
+ for m in self.modalities:
+
+ if m == 'SaO2':
+ self.conv_encoders[m] = PatchEmbed(sig_len=sig_len,
+ conv_patch_sizes=[1, 1, 1],
+ in_chans=1,
+ embed_dim=[embed_dim[0], embed_dim[1], embed_dim[2]],
+ norm_layer=norm_layer)
+
+ else:
+ self.conv_encoders[m] = PatchEmbed(sig_len=sig_len,
+ conv_patch_sizes=[10, patch_size // 10, 1],
+ in_chans=1,
+ embed_dim=[embed_dim[0], embed_dim[1], embed_dim[2]],
+ norm_layer=norm_layer)
+
+
+ # (# small patches, # large patches)
+ self.num_patches = sig_len // self.patch_size
+
+ patch_dim = embed_dim[2]
+
+ self.pos_embed = nn.Parameter(torch.zeros(1, self.num_patches, patch_dim), requires_grad=False)
+ self.rope_lst = []
+
+ # max_seq_len = self.num_patches
+ max_seq_len = 60 * 2
+ self.num_merge = [5] + [2] * (len(self.specific_depth) - 1)
+ for idx, sd in enumerate(self.specific_depth):
+ self.rope_lst.append(freq_pos_enc(dim = embed_dim[2+idx] // num_heads, max_seq_len = max_seq_len))
+
+ if idx == 0:
+ max_seq_len = round(max_seq_len / self.num_merge[idx] * (1 - mask_ratio))
+ # max_seq_len = round(max_seq_len / (self.num_merge[idx]))
+ else:
+ max_seq_len = round(max_seq_len / self.num_merge[idx])
+
+ # (max_seq_len, dim)
+ # max_seq_len = round(max_seq_len / 2) if idx > 0 else round(max_seq_len / (5 * 2))
+ # max_seq_len = round(max_seq_len /2)
+
+ # self.rope_lst.append(freq_pos_enc(dim = embed_dim[2] // num_heads, max_seq_len = (64 * 2 * 0.5) // 4))
+
+
+
+ self.specific_encoders = nn.ModuleDict()
+ self.specific_norms = nn.ModuleDict()
+ self.specific_patch_merge = nn.ModuleDict()
+ for m in self.modalities:
+ block_list, patch_merge_list, norm_layer_list = [], [], []
+
+ for idx, sd in enumerate(self.specific_depth):
+ dim_curr = embed_dim[2+idx]
+ block_list.extend([
+ BlockFlashAttn(
+ dim=dim_curr, num_heads=num_heads, mlp_ratio=mlp_ratio[2], qkv_bias=True, qk_scale=None, norm_layer=norm_layer)
+ for i in range(sd)])
+ dw = self.num_merge[idx]
+ # dw = 2
+ if idx < len(self.specific_depth) - 1:
+ patch_merge_list.append(PatchMergeConv(embed_dim=dim_curr, exp_dim=embed_dim[2+idx+1], downsample=dw, norm_layer=norm_layer))
+ else:
+ patch_merge_list.append(nn.Identity())
+ # patch_merge_list.append(PatchMergeConv(embed_dim=dim_curr, exp_dim=dim_curr, downsample=dw, norm_layer=norm_layer))
+
+ norm_layer_list.append(norm_layer(dim_curr))
+ # no change in dim here
+ self.specific_encoders[m] = nn.ModuleList(block_list)
+ self.specific_patch_merge[m] = nn.ModuleList(patch_merge_list)
+ self.specific_norms[m] = nn.ModuleList(norm_layer_list)
+
+ if self.use_shared:
+ block = MoEBlockFlashAttn if self.use_moe else BlockFlashAttn
+
+ block_list, patch_merge_list, norm_layer_list = [], [], []
+ kwargs = dict(
+ num_experts=num_experts, num_experts_per=num_experts_per
+ ) if self.use_moe else {}
+
+ for idx, d in enumerate(self.depth):
+ dim_curr = embed_dim[2+idx]
+ block_list.extend([
+ block(
+ dim=dim_curr, num_heads=num_heads, mlp_ratio=mlp_ratio[2], qkv_bias=True, qk_scale=None, norm_layer=norm_layer,
+ **kwargs)
+ for i in range(d)])
+ norm_layer_list.append(norm_layer(dim_curr))
+ # dw = 5 if idx == 0 else 2
+ dw = self.num_merge[idx]
+ # dw = 2
+ if idx < len(self.depth) - 1:
+ patch_merge_list.append(PatchMergeConv(embed_dim=dim_curr, exp_dim=embed_dim[2+idx+1], downsample=dw, norm_layer=norm_layer))
+ else:
+ patch_merge_list.append(nn.Identity())
+
+ self.shared_encoder = nn.ModuleList(block_list)
+ self.shared_patch_merge = nn.ModuleList(patch_merge_list)
+ self.shared_norm = nn.ModuleList(norm_layer_list)
+
+
+ self.initialize_weights()
+
+ def initialize_weights(self):
+ # initialization
+
+ pos_embed = get_1d_sincos_pos_embed(self.pos_embed.shape[-1], self.num_patches, cls_token=False)
+ self.pos_embed.data.copy_(torch.from_numpy(pos_embed).float().unsqueeze(0))
+ # torch.nn.init.normal_(self.cls_token, std=.02)
+
+ def forward(self, inputs, mask_dict, ids_keep_dict, modalities_to_use):
+
+ conv_embeddings = []
+ ids_keep = []
+ latents_specific = []
+ latents_shared = None
+
+ pe_list_0 = []
+
+ for i, m in enumerate(modalities_to_use):
+ idx = (i % 2) + 1
+ x_raw, mask = inputs[m], mask_dict[m]
+ mask = mask.view(x_raw.shape[0], -1, 1) # (N, L, 1)
+ N = x_raw.shape[0]
+
+
+ # mask_lg = mask_dict[f'lg_m{idx}']
+ # mask_lg = mask_lg.view(x_raw.shape[0], -1, 1) # (N, L, 1)
+ x_proj = self.conv_encoders[m](x_raw)
+ if m == 'SaO2':
+ repeat_factor = 100 // self.patch_size
+ x_proj = x_proj.repeat_interleave(repeat_factor, dim=1)
+ x_proj = x_proj * (1.0 - mask)
+ ids_keep_m = ids_keep_dict[m]
+ # lg_ids_keep.append(lg_ids_keep_m)
+
+ # Will be combined with shared small
+ if self.pos_enc == 'sinusoidal':
+ x_proj = x_proj + self.pos_embed
+
+
+ x_proj = torch.gather(x_proj, dim=1, index=ids_keep_m.unsqueeze(-1).repeat(1, 1, x_proj.shape[-1])) # shuffle and filter # (N, number of keep large patches, projected dim)
+ conv_embeddings.append(x_proj)
+
+ ii= 0
+ latents = conv_embeddings
+ latents_sh = []
+ for j, curr_depth in enumerate(self.specific_depth):
+ specific_list = []
+ for i,m in enumerate(modalities_to_use):
+ x_proj = latents[i]
+ # latents_sh.append(self.specific_patch_merge[m][j](x_proj))
+ if j > 0:
+ x_proj = self.specific_patch_merge[m][j-1](x_proj)
+ if j == len(self.specific_depth) -1:
+ latents_sh.append(x_proj)
+ if self.pos_enc == 'rope':
+ pe = self.rope_lst[j].unsqueeze(0).to(dtype=x_proj.dtype, device=x_proj.device) # (1, max_seq_len, dim)
+ pe = pe.repeat(N, 1, 1) # (N, max_seq_len, dim)
+ if j == 0:
+ ids_keep_m = ids_keep_dict[m]
+ pe = torch.gather(pe, dim=1, index=ids_keep_m.unsqueeze(-1).repeat(1, 1, pe.shape[-1])) # filter only large patches
+ pe_list_0.append(pe)
+ else:
+ pe = None
+
+ for blk in self.specific_encoders[m][ii:ii+curr_depth]:
+ x_proj, _ = blk(x_proj, rope=pe)
+
+ x_proj = self.specific_norms[m][j](x_proj)
+ specific_list.append(x_proj)
+
+ latents = specific_list
+ ii += curr_depth
+
+ latents_specific.append(specific_list)
+
+ gating_scores = []
+ M = len(modalities_to_use)
+
+ if self.use_shared:
+ x_shared = torch.stack(latents_sh, dim=0) # (M ,N, L, D)
+ # x_shared = torch.stack(latents_sh, dim=1) # (N ,M, L, D)
+
+ ii = self.depth[0]
+ shared_list = []
+ for j, curr_depth in enumerate(self.depth):
+ if j < len(self.depth) - 1: continue
+ if self.pos_enc == 'rope':
+ pe = self.rope_lst[j].unsqueeze(0).to(dtype=x_shared.dtype, device=x_shared.device) # (1, max_seq_len, dim)
+ pe = pe.repeat(N * M, 1, 1) # (N, max_seq_len, dim)
+ # pe = pe.repeat(N, M, 1) # (N, max_seq_len, dim)
+ pe = rearrange(pe, '(n m) l d -> n (m l) d', m = M)
+
+ x_shared = rearrange(x_shared, 'm n l d -> n (m l) d', m = M)
+ # randomly shuffle x_shared before feeding and restore the order after the block; this is to prevent the model from relying on a specific order of modalities
+ # rand_inds = torch.randperm(x_shared.shape[1], device=x_shared.device)
+ # rand_inds = torch.arange(x_shared.shape[1], device=x_shared.device) # (L*M)
+ # x_shared = x_shared[:, rand_inds, :]
+ # x_shared = rearrange(x_shared, 'n m l d -> n (m l) d', m = M)
+ for blk in self.shared_encoder[ii:ii+curr_depth]:
+ x_shared, score = blk(x_shared, rope=pe if self.pos_enc == 'rope' else None)
+ gating_scores.append(score)
+ # x_shared = torch.scatter(x_shared, dim=1, index=rand_inds.unsqueeze(-1).expand_as(x_shared), src=x_shared) # restore original order
+ # print((F.normalize(x_shared.split(24, dim=1)[0], dim=-1) * F.normalize(x_shared.split(24, dim=1)[-1], dim=-1)).sum(-1))
+
+ x_shared = self.shared_norm[j](x_shared)
+ x_shared = rearrange(x_shared, 'n (m l) d -> m n l d', m = M)
+
+ shared_list.append(x_shared)
+
+ # for j, curr_depth in enumerate(self.depth):
+ # if j < len(self.depth) - 1: continue
+ # if self.pos_enc == 'rope':
+ # pe = self.rope_lst[j].unsqueeze(0).to(dtype=x_shared.dtype, device=x_shared.device) # (1, max_seq_len, dim)
+ # pe = pe.repeat(N * M, 1, 1) # (N, max_seq_len, dim)
+ # # pe = rearrange(pe, '(n m) l d -> n (m l) d', m = M)
+
+ # x_shared = rearrange(x_shared, 'm n l d -> (m n) l d', m = M)
+ # for blk in self.shared_encoder[ii:ii+curr_depth]:
+ # x_shared, score = blk(x_shared, rope=pe if self.pos_enc == 'rope' else None)
+ # gating_scores.append(score)
+
+ # x_shared = self.shared_norm[j](x_shared)
+ # x_shared = rearrange(x_shared, '(m n) l d -> m n l d', m = M)
+
+ # shared_list.append(x_shared)
+
+ latents_shared = shared_list
+
+ return latents_shared, latents_specific, gating_scores
+
+
+
+
+
+
+
+class MultiEncoderClassification(MultiEncoder):
+ def __init__(self, sig_len=6000, patch_size=10, in_chans=1,
+ embed_dim=[32,64,128], depth=[2,2,4], num_heads=8,
+ specific_depth=[2,2,2],
+ mlp_ratio=[4,4,4], norm_layer=nn.LayerNorm,
+ modalities=["EEG","EOG"], num_experts=2, num_experts_per=1,
+ use_shared=True, use_moe=True, pos_enc='sinusoidal'):
+ super().__init__(sig_len=sig_len, patch_size=patch_size, in_chans=in_chans,
+ embed_dim=embed_dim, depth=depth, num_heads=num_heads,
+ specific_depth=specific_depth,
+ mlp_ratio=mlp_ratio, norm_layer=norm_layer,
+ modalities=modalities, num_experts=num_experts, num_experts_per=num_experts_per,
+ use_shared=use_shared, use_moe=use_moe, pos_enc=pos_enc)
+
+ def forward(self, inputs, modalities_to_use):
+
+ conv_embeddings = []
+ latents_specific = []
+ gating_scores = []
+ latents_shared = []
+ M = len(modalities_to_use)
+
+ for i, m in enumerate(modalities_to_use):
+ x_raw = inputs[m]
+
+ x_proj = self.conv_encoders[m](x_raw)
+
+ if m == 'SaO2':
+ repeat_factor = 100 // self.patch_size
+ x_proj = x_proj.repeat_interleave(repeat_factor, dim=1)
+
+ # Will be combined with shared small
+ if self.pos_enc == 'sinusoidal':
+ x_proj = x_proj + self.pos_embed
+
+ conv_embeddings.append(x_proj)
+
+ ii = 0
+ latents = conv_embeddings
+ latents_sh = []
+ for j, curr_depth in enumerate(self.specific_depth):
+ specific_list = []
+ for i,m in enumerate(modalities_to_use):
+ x_proj = latents[i]
+ N, L, D = x_proj.shape
+ # latents_sh.append(self.specific_patch_merge[m][j](x_proj.view(N, -1, 2, D).mean(2)))
+
+ if j > 0:
+ x_proj = self.specific_patch_merge[m][j-1](x_proj)
+ if j == len(self.specific_depth) -1:
+ latents_sh.append(x_proj)
+
+ if self.pos_enc == 'rope':
+ pe = self.rope_lst[j].unsqueeze(0).to(dtype=x_proj.dtype, device=x_proj.device) # (1, max_seq_len, dim)
+ lj = x_proj.shape[1]
+ pe = pe[:, :lj]
+ pe = pe.repeat(N, 1, 1) # (N, max_seq_len, dim)
+
+ else:
+ pe = None
+
+ for blk in self.specific_encoders[m][ii:ii+curr_depth]:
+ x_proj, _ = blk(x_proj, rope=pe)
+ x_proj = self.specific_norms[m][j](x_proj)
+
+ if j == 0:
+ x_proj = x_proj.view(N, -1, 2, D).mean(2)
+ specific_list.append(x_proj)
+
+ # x_proj = self.specific_patch_merge[m][j](x_proj)
+
+ # latents_sh.append(x_proj)
+ latents = specific_list
+ ii += curr_depth
+
+ latents_specific.append(specific_list)
+
+ if self.use_shared:
+
+ x_shared = torch.stack(latents_sh, dim=0) # (M ,N, L, D)
+
+ ii = self.depth[0]
+ shared_list = []
+
+ for j, curr_depth in enumerate(self.depth):
+ if j < len(self.depth) - 1: continue
+ if self.pos_enc == 'rope':
+ pe = self.rope_lst[1].unsqueeze(0).to(dtype=x_shared.dtype, device=x_shared.device) # (1, max_seq_len, dim)
+ lj = x_shared.shape[2]
+ pe = pe[:, :lj]
+ pe = pe.repeat(N*M, 1, 1) # (N, max_seq_len, dim)
+ pe = rearrange(pe, '(n m) l d -> n (m l) d', m = M)
+
+ x_shared = rearrange(x_shared, 'm n l d -> n (m l) d') # (N*M, L, D)
+
+ for blk in self.shared_encoder[ii:ii+curr_depth]:
+ x_shared, _ = blk(x_shared, rope=pe if self.pos_enc == 'rope' else None)
+
+ x_shared = self.shared_norm[j](x_shared) # (N, M * L, D)
+ x_shared = rearrange(x_shared, 'n (m l) d -> m n l d', m = M)
+ latents_shared.append(x_shared)
+ # for j, curr_depth in enumerate(self.depth):
+ # if j < len(self.depth) - 1: continue
+ # if self.pos_enc == 'rope':
+ # pe = self.rope_lst[1].unsqueeze(0).to(dtype=x_shared.dtype, device=x_shared.device) # (1, max_seq_len, dim)
+ # lj = x_shared.shape[2]
+ # pe = pe[:, :lj]
+ # pe = pe.repeat(N*M, 1, 1) # (N, max_seq_len, dim)
+ # # pe = rearrange(pe, '(n m) l d -> n (m l) d', m = M)
+
+ # x_shared = rearrange(x_shared, 'm n l d -> (m n) l d') # (N*M, L, D)
+
+ # for blk in self.shared_encoder[ii:ii+curr_depth]:
+ # x_shared, _ = blk(x_shared, rope=pe if self.pos_enc == 'rope' else None)
+
+ # x_shared = self.shared_norm[j](x_shared) # (N, M * L, D)
+ # x_shared = rearrange(x_shared, '(m n) l d -> m n l d', m = M)
+ # latents_shared.append(x_shared)
+
+ return latents_shared, latents_specific, gating_scores
+
+
+
+class Encoder(nn.Module):
+ def __init__(self, sig_len=[3000,600,150], patch_sizes=[5,4,2], in_chans=1,
+ embed_dim=[32,64,128], depth=[2,2,11], num_heads=4,
+ mlp_ratio=[4,4,4], norm_layer=nn.LayerNorm):
+ super().__init__()
+
+ # forward conv encoder; pass through the provided `in_chans` and allow patch_sizes alias
+ self.conv_encoder = ConvEncoder(sig_len=sig_len, patch_sizes=patch_sizes, in_chans=in_chans,
+ embed_dim=embed_dim, depth=depth[:2],
+ mlp_ratio=mlp_ratio, norm_layer=norm_layer)
+
+ self.num_patches = self.conv_encoder.patch_embed3.num_patches
+
+ self.pos_embed = nn.Parameter(torch.zeros(1, self.num_patches, embed_dim[2]), requires_grad=False)
+
+ self.transformer_blocks = nn.ModuleList([
+ Block(
+ dim=embed_dim[2], num_heads=num_heads, mlp_ratio=mlp_ratio[2], qkv_bias=True, qk_scale=None, norm_layer=norm_layer)
+ for i in range(depth[2])])
+ self.norm = norm_layer(embed_dim[-1])
+
+ def initialize_weights(self):
+ # initialization
+ # initialize (and freeze) pos_embed by sin-cos embedding
+ pos_embed = get_1d_sincos_pos_embed(self.pos_embed.shape[-1], self.num_patches, cls_token=False)
+ self.pos_embed.data.copy_(torch.from_numpy(pos_embed).float().unsqueeze(0))
+
+ def forward(self, x, mask, ids_keep):
+
+ x, stage1_embed, stage2_embed = self.conv_encoder(x, mask)
+
+ x = x + self.pos_embed
+ x = torch.gather(x, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, x.shape[-1]))
+ stage1_embed = torch.gather(stage1_embed, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, stage1_embed.shape[-1]))
+ stage2_embed = torch.gather(stage2_embed, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, stage2_embed.shape[-1]))
+
+
+ # apply Transformer blocks
+ for blk in self.transformer_blocks:
+ x = blk(x)
+ x = x + stage1_embed + stage2_embed
+ x = self.norm(x)
+
+ return x
diff --git a/models/factory.py b/models/factory.py
new file mode 100644
index 0000000000000000000000000000000000000000..798a9c1d48a32029170c06c3086fe7be13a8d60b
--- /dev/null
+++ b/models/factory.py
@@ -0,0 +1,29 @@
+from functools import partial
+import torch.nn as nn
+
+from models.mae import MultiMaskedAutoencoderConv1d
+from models.classification import ClassificationMultiConv1d, ClassificationMultiConv1dMamba
+from models.transformer_modules import RMSNorm
+
+def convmae1d_multi(**kwargs):
+ model = MultiMaskedAutoencoderConv1d(
+ embed_dim=[32, 64, 128, 384], depth=[4, 4], specific_depth=[2, 2], num_heads=8,
+ decoder_embed_dim=64, decoder_depth=2, decoder_num_heads=4,
+ fusion_method='cross_attn', fusion_heads=8, fusion_depth=4,
+ mlp_ratio=[4, 4, 4], norm_layer=partial(RMSNorm, eps=1e-8), pos_enc='rope', **kwargs)
+ return model
+
+def classification_multi(**kwargs):
+ model = ClassificationMultiConv1d(
+ embed_dim=[32, 64, 128, 384], depth=[4, 4], specific_depth=[2, 2], num_heads=8,
+ fusion_method='cross_attn', fusion_heads=8, fusion_depth=4,
+ mlp_ratio=[4, 4, 4], norm_layer=partial(RMSNorm, eps=1e-8), pos_enc='rope', **kwargs)
+ return model
+
+def classification_multi_full_night(**kwargs):
+ model = ClassificationMultiConv1dMamba(
+ embed_dim=[32, 64, 128, 384], depth=[4, 4], specific_depth=[2, 2], num_heads=8,
+ fusion_method='cross_attn', fusion_heads=8, fusion_depth=4,
+ seq_dim=512, seq_depth=1,
+ mlp_ratio=[4, 4, 4], norm_layer=partial(RMSNorm, eps=1e-8), pos_enc='rope', **kwargs)
+ return model
\ No newline at end of file
diff --git a/models/fusion.py b/models/fusion.py
new file mode 100644
index 0000000000000000000000000000000000000000..1c77491e815c78ba2425735d9b9f826b37b0f331
--- /dev/null
+++ b/models/fusion.py
@@ -0,0 +1,104 @@
+import torch
+import torch.nn as nn
+from models.transformer_modules import BlockFlashAttn, Mlp, freq_pos_enc, PatchUpsample
+
+class FusionModule(nn.Module):
+ def __init__(self, encoder_embed_dim=128,
+ num_heads=4, mlp_ratio=4, norm_layer=nn.LayerNorm, fusion_depth=2,
+ fusion_method='concat', pos_enc='sinusoidal'):
+ super().__init__()
+ self.fusion_method = fusion_method
+ self.num_heads = num_heads
+
+ if self.fusion_method == 'concat':
+ self.prenorm = norm_layer(encoder_embed_dim * 2) # prenorm for the weighted sum features
+ # self.merge = nn.Linear(encoder_embed_dim * 2, encoder_embed_dim)
+ self.merge = Mlp(in_features=encoder_embed_dim * 2, out_features=encoder_embed_dim)
+ elif self.fusion_method == 'cross_attn':
+ self.cross_attention_blocks = nn.ModuleList([
+ BlockFlashAttn(encoder_embed_dim, num_heads, mlp_ratio, qkv_bias=True, qk_scale=None, norm_layer=norm_layer)
+ # BlockFlashAttn(encoder_embed_dim, num_heads, mlp_ratio, qkv_bias=True, qk_scale=None, norm_layer=norm_layer)
+ for i in range(fusion_depth)])
+ self.post_norm = norm_layer(encoder_embed_dim)
+
+ self.pos_enc = pos_enc
+ if pos_enc == 'rope':
+ self.rope = freq_pos_enc(dim=encoder_embed_dim // num_heads, max_seq_len=128)
+
+ def forward(self, x, y):
+
+ if self.fusion_method == 'concat':
+ x = torch.cat([x, y], dim=-1)
+ x = self.prenorm(x) # apply prenorm before the forward_features
+ x = self.merge(x)
+
+ elif self.fusion_method == 'cross_attn':
+
+ if self.pos_enc == 'rope':
+
+ pe = self.rope.unsqueeze(0).to(dtype=x.dtype, device=x.device) # (1, max_seq_len, dim)
+ pe = pe[:, :x.shape[1], :] # (1, seq_len, dim)
+ pe = pe.repeat(x.shape[0], 1, 1) # (N, max_seq_len, dim)
+ pe2 = None
+ if not x.shape[1] == y.shape[1]:
+ pe2 = freq_pos_enc(dim=y.shape[2] // self.num_heads, max_seq_len=y.shape[1])
+ pe2 = pe2.unsqueeze(0).to(dtype=x.dtype, device=x.device) # (1, max_seq_len, dim)
+ pe2 = pe2.repeat(x.shape[0], 1, 1) # (N, max_seq_len, dim)
+
+ else:
+ pe = None
+
+ for blk in self.cross_attention_blocks:
+ x, _ = blk(x, y, rope=pe, rope2=pe2)
+ x = self.post_norm(x)
+ return x
+
+class FusionUpsampleBlock(nn.Module):
+ def __init__(self, dim_list, fusion_method='cross_attn', fusion_depth=2, fusion_heads=4,
+ mlp_ratio=4., norm_layer=nn.LayerNorm, pos_enc='sinusoidal',
+ use_shared=True, use_upsample=True, modalities=["EEG","EOG"]):
+ super().__init__()
+
+ self.fusion_method = fusion_method
+ self.use_shared = use_shared
+ self.use_upsample = use_upsample
+ self.fusion = nn.ModuleDict()
+ self.upsampler = nn.ModuleDict()
+ self.dim_list = dim_list
+ self.modalities = modalities
+
+ for m in self.modalities:
+ if use_shared:
+ self.fusion[m] = FusionModule(encoder_embed_dim=dim_list[-1],
+ mlp_ratio=mlp_ratio, norm_layer=norm_layer,
+ fusion_method=fusion_method, fusion_depth=fusion_depth, num_heads=fusion_heads, pos_enc=pos_enc)
+
+ if use_upsample:
+ upsampler_list = []
+ for i in range(len(dim_list) - 1):
+ up = 2 if i > 0 else 5
+ upsampler_list.append(PatchUpsample(embed_dim=dim_list[1+i], up_dim=dim_list[i], upsample=up, norm_layer=norm_layer))
+
+ self.upsampler[m] = nn.ModuleList(upsampler_list)
+
+
+ def forward(self, x_shared, x_specific):
+
+ latents_fused = []
+ upsampled = []
+ for i, m in enumerate(self.modalities):
+ if self.use_shared:
+ # x_fused = self.fusion[m](x_shared[-1][i], x_specific[-1][i])
+ x_fused = self.fusion[m](x_specific[-1][i], x_shared[-1][i])
+ else:
+ x_fused = x_specific[-1][i]
+ latents_fused.append(x_fused)
+
+ if self.use_upsample:
+ for j in range(len(self.dim_list)-2, -1, -1):
+ x_fused = self.upsampler[m][j](x_fused, x_specific[j][i])
+ # x_fused = self.upsampler[m][j](x_fused)
+ upsampled.append(x_fused)
+
+ return latents_fused, upsampled
+
\ No newline at end of file
diff --git a/models/mae.py b/models/mae.py
new file mode 100644
index 0000000000000000000000000000000000000000..288f0eb7f33f738993dc33b1658e4d0898c3dac1
--- /dev/null
+++ b/models/mae.py
@@ -0,0 +1,546 @@
+from functools import partial
+import torch
+import torch.nn as nn
+import torch.nn.functional as F
+import numpy as np
+import random
+
+from models.encoders import Encoder, MultiEncoder, MultiEncoderClassification
+from models.decoders import Decoder
+from models.fusion import FusionModule, FusionUpsampleBlock
+from models.transformer_modules import RevIN, AttentionPooling
+from configs.global_cfg import TARGET_RESAMPLE
+from einops import rearrange, repeat
+
+
+class MultiMaskedAutoencoderConv1d(nn.Module):
+ """ Masked Autoencoder with VisionTransformer backbone
+ """
+ def __init__(self, sig_len=6000, patch_size=10, in_chans=1,
+ embed_dim=[32,64,128,256], depth=[2,2,4], specific_depth=[2,2,2], num_heads=8,
+ decoder_embed_dim=256, decoder_depth=6, decoder_num_heads=8,
+ mlp_ratio=[4,4,4], norm_layer=nn.LayerNorm,
+ modalities=["EEG","EOG"], num_experts=2, num_experts_per=1,
+ use_shared=True, use_moe=True,
+ fusion_method='concat', fusion_depth=2, fusion_heads=8,
+ use_revin=False,
+ mask_ratio=0.5,
+ contrastive_training=False, koleo_training=False, pos_enc='sinusoidal'):
+
+ super().__init__()
+ self.patch_size = patch_size
+ self.modalities = modalities
+ self.num_experts = num_experts
+ self.num_experts_per = num_experts_per
+ self.embed_dim = embed_dim
+ self.depth = depth
+ self.specific_depth = specific_depth
+ self.mask_ratio = mask_ratio
+ self.encoder = MultiEncoder(sig_len=sig_len, patch_size=patch_size, in_chans=in_chans,
+ embed_dim=embed_dim, depth=depth, num_heads=num_heads, specific_depth=specific_depth,
+ mlp_ratio=mlp_ratio, norm_layer=norm_layer,
+ modalities=self.modalities, num_experts=num_experts, num_experts_per=num_experts_per,
+ mask_ratio=mask_ratio, pos_enc=pos_enc)
+
+ self.num_patches = self.encoder.num_patches
+
+ self.use_revin = use_revin
+ if self.use_revin:
+ self.revin = nn.ModuleDict()
+ for m in self.modalities:
+ if m != 'SaO2':
+ self.revin[m] = RevIN(num_features=1, affine=False)
+
+ self.use_shared = use_shared
+ self.use_moe = use_moe
+ self.contrastive_temp = 0.07
+
+ # contrastive loss hyperparameters (InfoNCE style)
+ # temperature for scaling similarities and weight to combine with ortho_loss
+ self.contrastive_training = contrastive_training
+ self.koleo_training = koleo_training
+
+ self.fusion = nn.ModuleDict()
+ self.decoders = nn.ModuleDict()
+ self.upsampler = nn.ModuleDict()
+ # self.pooler1 = nn.ModuleDict()
+ # self.pooler2 = nn.ModuleDict()
+
+ self.fuser = FusionUpsampleBlock(dim_list=embed_dim[2:],
+ fusion_method=fusion_method,
+ fusion_depth=fusion_depth,
+ fusion_heads=fusion_heads,
+ mlp_ratio=mlp_ratio[0],
+ norm_layer=norm_layer,
+ pos_enc=pos_enc,
+ use_shared=use_shared,
+ use_upsample=True,
+ modalities=self.modalities)
+
+ for m in self.modalities:
+ decoder_pred_dim = self.patch_size if m != 'SaO2' else 1
+ self.decoders[m] = Decoder(num_patches=self.num_patches, encoder_embed_dim=embed_dim[2], decoder_embed_dim=decoder_embed_dim,
+ decoder_depth=decoder_depth, decoder_num_heads=decoder_num_heads,
+ mlp_ratio=mlp_ratio[0], norm_layer=norm_layer, decoder_pred_dim=decoder_pred_dim, pos_enc=pos_enc)
+ # self.pooler1[m] = AttentionPooling(embed_dim[2], num_heads=num_heads, norm_layer=norm_layer)
+ # self.pooler2[m] = AttentionPooling(embed_dim[2], num_heads=num_heads, norm_layer=norm_layer)
+
+
+
+ self.apply(self._init_weights)
+
+ def koleo_loss(self, x, ys=None, eps=1e-8):
+ """
+ Compute KoLeo (Kozachenko-Leonenko) regularization loss.
+ Encourages uniform distribution of representations on the hypersphere.
+
+ Args:
+ x: Tensor of shape (N, D) where N is batch size and D is feature dimension
+ ys: Optional list of tensors to also consider for distance computation
+ eps: Small constant for numerical stability
+
+ Returns:
+ KoLeo loss (scalar)
+ """
+ # Normalize representations to unit hypersphere
+ x = F.normalize(x, p=2, dim=-1)
+
+ # Compute pairwise distances
+ # Using efficient computation: ||a - b||^2 = ||a||^2 + ||b||^2 - 2
+ # Since normalized, ||a||^2 = ||b||^2 = 1, so ||a - b||^2 = 2 - 2
+ gram_matrix = torch.matmul(x, x.t()) # (N, N)
+ sq_distances = 2 - 2 * gram_matrix # (N, N)
+ sq_distances = torch.clamp(sq_distances, min=eps, max=4.0) # numerical stability, max distance on unit sphere is 2
+
+ # Set diagonal to large value (exclude self-distance)
+ sq_distances = sq_distances + torch.eye(x.shape[0], device=x.device) * 1e10
+
+ if ys is not None:
+ for y in ys:
+ y = F.normalize(y, p=2, dim=-1)
+ y_distance = (x - y).pow(2).sum(dim=-1, keepdim=True) # (N, 1)
+ y_distance = torch.clamp(y_distance, min=eps, max=4.0)
+ sq_distances = torch.cat([sq_distances, y_distance], dim=1) # (N, N + len(ys))
+
+ # Find minimum distance for each sample (nearest neighbor)
+ min_sq_distances, _ = torch.min(sq_distances, dim=1) # (N,)
+
+ # KoLeo loss is negative log of minimum distances
+ # We want to maximize minimum distances -> minimize negative log
+ distances = torch.sqrt(min_sq_distances)
+
+ # Additional clamping on distances before log
+ distances = torch.clamp(distances, min=eps)
+
+ koleo_loss = -torch.log(distances).mean()
+
+ return koleo_loss
+
+ def forward(self, inputs, mask_dict=None, ids_keep_dict=None):
+ # embed patches
+ # m1, m2 = self.modalities[0], self.modalities[1]
+ modalities_to_use = list(inputs.keys())
+ # random.shuffle(modalities_to_use)
+
+ m1, m2 = modalities_to_use[0], modalities_to_use[1]
+ if mask_dict is None or ids_keep_dict is None:
+ mask_dict, ids_keep_dict = self.random_masking(inputs[m1], self.mask_ratio)
+
+ # ids_shuffle, mask, ids_keep, ids_restore = self.random_masking(inputs[m1], mask_ratio)
+
+ N = inputs[m1].shape[0]
+ d = self.embed_dim[2]
+ inputs_ = dict()
+ if self.use_revin:
+ for i, m in enumerate(modalities_to_use):
+ # mask_m = mask_dict[m].reshape(N, -1, 1)
+ # mask_raw_m = torch.tile(mask_m, (1, 1, self.patch_size)).reshape(N, -1, 1)
+ if m == 'SaO2':
+ inputs_[m] = inputs[m][:, ::TARGET_RESAMPLE, :] # N,L* TARGET_RESAMPLE,1 -> N,L,1
+ else:
+ inputs_[m] = self.revin[m](inputs[m], None, mode='norm')
+ else:
+ inputs_ = inputs
+
+ preds = dict()
+ latents_shared, latents_specific, gating_scores = self.encoder(inputs_, mask_dict, ids_keep_dict, modalities_to_use)
+
+
+ ortho_loss = 0.0
+
+
+ latents_fused, upsampled = self.fuser(latents_shared, latents_specific)
+
+ if self.mask_ratio == 0:
+ losses = dict()
+ for m in modalities_to_use:
+ losses[m] = 0.0
+
+ else:
+ for i, m in enumerate(modalities_to_use):
+ ids_keep_m = ids_keep_dict[m] # (N, L * large portion)
+ preds[m] = self.decoders[m](upsampled[i], ids_keep_m)
+ # Compute reconstruction losses
+ losses = self.forward_loss(inputs_, preds, mask_dict, ids_keep_dict, modalities_to_use)
+
+ # Contrastive learning between latents_shared and latents_specific
+ # Positives: (latents_shared[m1], latents_shared[m2]) for the same timestep (index)
+ # Negatives: (latents_shared[m1], latents_specific[m1]) for the same timestep
+ contrastive_loss = 0.0
+ koleo_loss = 0.0
+ num_contrast_pairs = 0
+
+ ctrst_grp = 30 # (seconds)
+ ctrst_grp = (ctrst_grp * (100 / self.patch_size)) * (1 - self.mask_ratio) # 0.5 is mask ratio
+ # How many patches form a patch group for contrastive learning?
+ ctrst_grp = int(ctrst_grp // (5 * 2 ** (len(self.depth) - 2))) # The first downsampling is 5x, then 2x for each level
+
+
+ if self.contrastive_training:
+
+ z_shared, z_specific = [], []
+ for i, m in enumerate(modalities_to_use):
+ shared_m = latents_shared[-1][i]
+ N, L, D = shared_m.shape
+ Lm = shared_m.reshape(-1, ctrst_grp*D)
+ # Lm = self.pooler1[m](Lm)
+ Lm = F.normalize(Lm, dim=-1)
+ z_shared.append(Lm) # (N, L, D')
+
+ specific_m = latents_specific[-1][i]
+ # N, L, D = specific_m.shape
+ # specific_m = specific_m.reshape(N, L, 4, D).mean(dim=2)
+ Lm = specific_m.reshape(-1, ctrst_grp*D)
+ # Lm = self.pooler2[m](Lm)
+ Lm = F.normalize(Lm, dim=-1)
+ z_specific.append(Lm) # (N, L, D')
+
+
+ for i, m1 in enumerate(modalities_to_use):
+ shared_specific = []
+ z_anchor = z_shared[i]
+
+
+ sims_neg1 = z_anchor @ z_anchor.permute(1,0) # (N*L, N*L)
+ diag_idx = torch.arange(sims_neg1.size(1), device=sims_neg1.device)
+ sims_neg1[diag_idx, diag_idx] = float('-inf')
+
+
+ z_pos = [z for k, z in enumerate(z_shared) if k != i]
+ z_pos = torch.mean(torch.stack(z_pos, dim=0), dim=0) # Average over other modalities
+
+ sims_pos = torch.sum(z_anchor * z_pos, dim=-1, keepdim=True) # (N*L, 1)
+
+ if self.use_shared:
+ zs = z_specific[i]
+ sims_neg2 = torch.sum(z_anchor * zs, dim=-1, keepdim=True)
+ shared_specific.append(sims_neg2)
+ sims_neg2 = torch.cat(shared_specific, dim=-1) # (N*L, num_modalities)
+
+ logits = torch.cat([sims_pos, sims_neg1, sims_neg2], dim=-1) / (self.contrastive_temp + 1e-8)
+ else:
+ logits = torch.cat([sims_pos, sims_neg1], dim=-1) / (self.contrastive_temp + 1e-8)
+ # logits = torch.cat([sims_pos, sims_neg1, sims_neg2], dim=-1) * logit_scale
+ labels = torch.zeros(logits.shape[0], dtype=torch.long, device=logits.device)
+ loss_c = F.cross_entropy(logits, labels)
+ contrastive_loss = contrastive_loss + loss_c
+ num_contrast_pairs += 1
+
+
+ if num_contrast_pairs > 0:
+ contrastive_loss = contrastive_loss / float(num_contrast_pairs)
+
+ if self.koleo_training:
+ # Compute KoLeo regularization on shared representations
+ # This encourages uniform distribution of shared features on the hypersphere
+ # for i in range(len(modalities_to_use)):
+ # shared_flat = z_shared[i]
+
+
+ # specific_flats = [z_specific[i]]
+ # # combined_flat = torch.cat([shared_flat, specific_m1_flat, specific_m2_flat], dim=0)
+
+ # koleo_loss = koleo_loss + self.koleo_loss(shared_flat, ys=specific_flats)
+ koleo_loss = self.koleo_loss(torch.cat(z_shared, dim=0), ys=torch.cat(z_specific, dim=0))
+
+
+
+ aux_loss = self.load_balancing_loss(gating_scores)
+ # return losses, aux_loss_lg, aux_loss_sm, preds, mask_dict, ids_keep_dict
+ return losses, aux_loss, ortho_loss, contrastive_loss, koleo_loss, preds, mask_dict, ids_keep_dict
+
+ def _init_weights(self, m):
+ if isinstance(m, nn.Linear):
+ # we use xavier_uniform following official JAX ViT:
+ torch.nn.init.xavier_uniform_(m.weight)
+ if isinstance(m, nn.Linear) and m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+
+ elif isinstance(m, nn.LayerNorm):
+ nn.init.constant_(m.bias, 0)
+ nn.init.constant_(m.weight, 1.0)
+
+ def patchify(self, sig):
+ """
+ sig: (N, L, 1)
+ patchfied: (N, L, patch_size)
+ """
+ # p = self.patch_size
+ B, L, _ = sig.shape
+
+ num_patches = L // self.patch_size
+
+ x = sig.reshape(shape=(B, num_patches, self.patch_size))
+
+ return x
+
+ def random_masking(self, x, mask_ratio=0.5):
+ """
+ Perform per-sample random masking by per-sample shuffling.
+ Per-sample shuffling is done by argsort random noise.
+ x: [N, L, D], sequence
+ """
+
+ mask_dict, ids_keep_dict = dict(), dict()
+
+ # If no mask is used. Keep all patches.
+ if mask_ratio == 0:
+ for m in self.modalities:
+ mask_dict[m] = torch.zeros(x.shape[0], x.shape[1] // self.patch_size, device=x.device, dtype=x.dtype)
+ ids_keep_dict[m] = torch.arange(x.shape[1] // self.patch_size, device=x.device).unsqueeze(0).repeat([x.shape[0], 1])
+ return mask_dict, ids_keep_dict
+
+ N = x.shape[0]
+ L = x.shape[1] // self.patch_size # number of large patches
+
+
+ len_keep = int(L * (1 - mask_ratio)) # Number of keep large patches
+
+ # noise = torch.rand(N, L_lg, device=x.device) # noise in [0, 1]
+ # ids_shuffle = torch.argsort(noise, dim=1) # ascend: small is keep, large is remove
+
+ ids_ordered = torch.arange(L, device=x.device).unsqueeze(0).repeat([N, 1])
+ # ids_ordered = ids_ordered.view([N, L //2, 2])
+ rand_ids = torch.randint(0, 2, [N, len_keep, 1], device=x.device)
+ rand_ids2 = torch.randint(0, 2, [N, len_keep, 1], device=x.device)
+ ids_keep_m1 = torch.gather(ids_ordered.view([N, len_keep, -1]), index=rand_ids, dim=-1).view([N, -1])
+ ids_keep_m2 = torch.gather(ids_ordered.view([N, len_keep, -1]), index=rand_ids2, dim=-1).view([N, -1])
+
+ num_patches_slow = (200 // self.patch_size)
+ len_keep_slow = int((L // num_patches_slow) * (1 - mask_ratio)) # Number of keep large patches for slow modalities
+
+ rand_ids = torch.randint(0, 2, [N, len_keep_slow, 1], device=x.device)
+ ids_keep_slow = torch.gather(ids_ordered.view([N, len_keep_slow, -1, num_patches_slow]),
+ index=rand_ids.unsqueeze(-1).repeat([1,1,1,num_patches_slow]),
+ dim=2).view([N, -1])
+
+
+ # ids_keep_m1 = ids[:, 0::2] ## Large keep area, modality 1
+ # ids_keep_m2 = ids[:, 1::2] ## Large keep area, modality 2
+
+ # Mask construction for large modeling area
+ mask_m1 = torch.ones([N, L], device=x.device, dtype=x.dtype)
+ src = torch.zeros([N, len_keep], device=x.device, dtype=x.dtype)
+ mask_m1.scatter_(dim=1, index=ids_keep_m1, src=src) # 0 is keep, 1 is remove, Large mask + small modeling area masked
+
+ mask_m2 = torch.ones([N, L], device=x.device, dtype=x.dtype)
+ src = torch.zeros([N, L - len_keep], device=x.device, dtype=x.dtype)
+ mask_m2.scatter_(dim=1, index=ids_keep_m2, src=src) # 0 is keep, 1 is remove, Large mask + small modeling area masked
+
+ mask_slow = torch.ones([N, L], device=x.device, dtype=x.dtype)
+ src = torch.zeros([N, L - len_keep], device=x.device, dtype=x.dtype)
+ mask_slow.scatter_(dim=1, index=ids_keep_slow, src=src) # 0 is keep, 1 is remove, Large mask + small modeling area masked
+ # print(rand_ids)
+ # print(ids_keep_slow)
+
+
+ for i, m in enumerate(self.modalities):
+ idx = (i % 2) + 1
+ if m in ['RESP','SaO2']:
+ # if False:
+ ids_keep_dict[m] = ids_keep_slow
+ mask_dict[m] = mask_slow # Both use the same mask
+ else:
+ ids_keep_dict[m] = ids_keep_m1 if idx == 1 else ids_keep_m2
+ mask_dict[m] = mask_m1 if idx == 1 else mask_m2
+
+
+ return mask_dict, ids_keep_dict
+
+ def forward_loss(self, inputs, preds, mask_dict, ids_keep_dict, modalities_to_use):
+ """
+ inputs: m * [N, L]
+ pred: [N, L, p*p*3]
+ mask: [N, L], 0 is keep, 1 is remove,
+ """
+ losses = dict()
+ # lg_ids, sm_ids = ids_keep_dict['ids_lg'], ids_keep_dict['ids_sm']
+ # for m in inputs.keys():
+ for i, m in enumerate(modalities_to_use):
+
+ sig, pred, mask= inputs[m], preds[m], mask_dict[m]
+
+ N, L, _ = sig.shape
+
+ if m == 'SaO2':
+ repeat_factor = 100 // self.patch_size
+ target = sig.repeat_interleave(repeat_factor, dim=1)
+ pred = pred.view(target.shape)
+
+ loss = (pred - target) ** 2
+ loss = (loss.mean(dim=-1) * mask).sum() / mask.sum()
+
+ else:
+ target = self.patchify(sig) # (N, L, patch_size)
+ pred = pred.view(target.shape)
+
+ sig_smooth = F.avg_pool1d(sig.view(N, -1, L),
+ kernel_size=11,
+ stride=1,
+ padding=5,
+ count_include_pad=False).view(N, L, -1)
+
+ target_smooth = self.patchify(sig_smooth)
+ loss_smooth = (pred - target_smooth) ** 2
+ loss_smooth = (loss_smooth.mean(dim=-1) * mask).sum() / mask.sum()
+
+ loss = loss_smooth
+
+
+ losses[m] = loss
+ return losses
+
+ def load_balancing_loss(self, gating_scores):
+ """
+ Compute the load balancing loss for the gating scores.
+ ref: https://github.com/huggingface/transformers/blob/main/src/transformers/models/mixtral/modeling_mixtral.py#L591
+ """
+ num_moe = len(gating_scores)
+ if num_moe > 0:
+ overall_loss = 0.0
+ for i in range(num_moe):
+ gating_scores_i = gating_scores[i] # stop gradient
+ # gating_scores = torch.stack(gating_scores, dim=0) # [num_MoEblocks, B, num_experts]
+ routing_weights = gating_scores_i.softmax(dim=-1) # [B, L, num_experts]
+ _, selected_experts = torch.topk(routing_weights, self.num_experts_per, dim=-1) # Index of selected experts
+ expert_mask = torch.nn.functional.one_hot(selected_experts, self.num_experts) # [B, L, num_experts_per, num_experts]
+
+ # Compute the average number of data points routed to each experts
+ # tokens_per_expert = torch.mean(expert_mask.float(), dim=1) # [B, num_experts]
+
+ # # Compute the average probability of routing to these experts
+ # router_prob_per_expert = torch.mean(routing_weights, dim=0) # [num_experts]
+
+ # overall_loss += torch.sum(tokens_per_expert * router_prob_per_expert.unsqueeze(1))
+ tokens_per_expert = torch.mean(expert_mask.float(), dim=(0,1,2)) # [num_experts]
+ router_prob_per_expert = torch.mean(routing_weights, dim=(0,1)) # [num_experts]
+ overall_loss += torch.mean(tokens_per_expert * router_prob_per_expert)
+
+ return overall_loss / num_moe
+ else:
+ return 0.0
+
+
+ # def forward(self, inputs, mask_dict, ids_keep_dict, mask_ratio=0.5):
+
+
+class MaskedAutoencoderConv1d(nn.Module):
+ """ Masked Autoencoder with VisionTransformer backbone
+ """
+ def __init__(self, sig_len=[3000,600,150], patch_sizes=[5,4,2], in_chans=1,
+ embed_dim=[32,64,128], depth=[2,2,11], num_heads=4,
+ decoder_embed_dim=128, decoder_depth=8, decoder_num_heads=4,
+ mlp_ratio=[4,4,4], norm_layer=nn.LayerNorm, norm_pix_loss=False):
+
+ super().__init__()
+ self.patch_size = np.prod(patch_sizes)
+ self.encoder = Encoder(sig_len=sig_len, patch_sizes=patch_sizes, in_chans=in_chans,
+ embed_dim=embed_dim, depth=depth, num_heads=num_heads,
+ mlp_ratio=mlp_ratio, norm_layer=norm_layer)
+
+ num_patches = self.encoder.conv_encoder.patch_embed3.num_patches
+ self.decoder = Decoder(num_patches=num_patches, encoder_embed_dim=embed_dim[-1], decoder_embed_dim=decoder_embed_dim,
+ decoder_depth=decoder_depth, decoder_num_heads=decoder_num_heads,
+ mlp_ratio=mlp_ratio[0], norm_layer=nn.LayerNorm, decoder_pred_dim=self.patch_size)
+
+ self.norm_pix_loss = norm_pix_loss
+
+ self.apply(self._init_weights)
+
+ def _init_weights(self, m):
+ if isinstance(m, nn.Linear):
+ # we use xavier_uniform following official JAX ViT:
+ torch.nn.init.xavier_uniform_(m.weight)
+ if isinstance(m, nn.Linear) and m.bias is not None:
+ nn.init.constant_(m.bias, 0)
+
+ elif isinstance(m, nn.LayerNorm):
+ nn.init.constant_(m.bias, 0)
+ nn.init.constant_(m.weight, 1.0)
+
+ def patchify(self, sig):
+ """
+ imgs: (N, L, 1)
+ x: (N, L / 40, 40) (p1*p2*p3)
+ """
+ p = self.patch_size
+ B, L, _ = sig.shape
+
+ x = sig.reshape(shape=(B, L // p, p))
+
+ return x
+
+ def random_masking(self, x, mask_ratio):
+ """
+ Perform per-sample random masking by per-sample shuffling.
+ Per-sample shuffling is done by argsort random noise.
+ x: [N, L, D], sequence
+ """
+ N = x.shape[0]
+ L = self.num_patches
+# N, L, D = x.shape # batch, length, dim
+ len_keep = int(L * (1 - mask_ratio))
+
+ noise = torch.rand(N, L, device=x.device) # noise in [0, 1]
+
+ # sort noise for each sample
+ ids_shuffle = torch.argsort(noise, dim=1) # ascend: small is keep, large is remove
+ ids_restore = torch.argsort(ids_shuffle, dim=1)
+
+ # keep the first subset
+ ids_keep = ids_shuffle[:, :len_keep]
+# x_masked = torch.gather(x, dim=1, index=ids_keep.unsqueeze(-1).repeat(1, 1, D))
+
+ # generate the binary mask: 0 is keep, 1 is remove
+ mask = torch.ones([N, L], device=x.device)
+ mask[:, :len_keep] = 0
+ # unshuffle to get the binary mask
+ mask = torch.gather(mask, dim=1, index=ids_restore)
+
+ return ids_keep, mask, ids_restore
+
+ def forward_loss(self, sig, pred, mask):
+ """
+ imgs: [N, L, C]
+ pred: [N, L, p*p*3]
+ mask: [N, L], 0 is keep, 1 is remove,
+ """
+ target = self.patchify(sig)
+ if self.norm_pix_loss:
+ mean = target.mean(dim=-1, keepdim=True)
+ var = target.var(dim=-1, keepdim=True)
+ target = (target - mean) / (var + 1.e-6)**.5
+
+ loss = (pred - target) ** 2
+ loss = loss.mean(dim=-1) # [N, L], mean loss per patch
+
+ loss = (loss * mask).sum() / mask.sum() # mean loss on removed patches
+ return loss
+
+ def forward(self, sig, mask_ratio=0.5):
+ # embed patches
+ ids_keep, mask, ids_restore = self.random_masking(sig, mask_ratio)
+ latent = self.encoder(sig, mask, ids_keep)
+ pred = self.decoder(latent, ids_restore) # [N, L, p*p*3]
+ loss = self.forward_loss(sig, pred, mask)
+ return loss, pred, mask
\ No newline at end of file
diff --git a/models/mamba_modules.py b/models/mamba_modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..a52bdd60e7036c5eb032c1121e272759f222fcaf
--- /dev/null
+++ b/models/mamba_modules.py
@@ -0,0 +1,115 @@
+import torch
+import torch.nn as nn
+from functools import partial
+from mamba_ssm import Mamba
+from models.transformer_modules import Mlp, GatedMLP, Block
+from timm.models.layers import DropPath, to_2tuple, trunc_normal_
+from models.utils import flip_padded_sequences
+
+class MambaBlock(nn.Module):
+ """
+ Wrapper block around the Mamba SSM layer providing the usual
+ transformer-style residual + MLP structure.
+
+ If `mamba-ssm` is not installed, the block falls back to an
+ identity (no-op) for the SSM portion while still running the
+ feed-forward MLP path so networks remain usable.
+ """
+ def __init__(self, d_model, d_state=16, d_conv=4, expand=2,
+ mlp_ratio=4., drop=0.1, drop_path=0.1, act_layer=nn.GELU,
+ norm_layer=nn.LayerNorm):
+ super().__init__()
+ self.norm1 = norm_layer(d_model)
+ # Mamba SSM layer (state space model)
+ if Mamba is not None:
+ self.mamba = Mamba(d_model=d_model, d_state=d_state, d_conv=d_conv, expand=expand)
+ else:
+ self.mamba = nn.Identity()
+
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+ # self.norm2 = norm_layer(d_model)
+ # mlp_hidden_dim = int(d_model * mlp_ratio)
+ # self.mlp = GatedMLP(in_features=d_model, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
+
+
+ def forward(self, x, mask=None):
+ if mask is not None:
+ x = x.masked_fill(~mask.unsqueeze(-1), 0.0)
+ # x: (B, L, D)
+ # SSM (Mamba) path with residual
+ x_in = x
+ x = self.mamba(self.norm1(x))
+ if mask is not None:
+ x = x.masked_fill(~mask.unsqueeze(-1), 0.0)
+ x = x_in + self.drop_path(x)
+ # x = x + self.drop_path(self.mlp(self.norm2(x)))
+ # if mask is not None:
+ # x = x.masked_fill(~mask.unsqueeze(-1), 0.0)
+ return x
+
+class SeqEncoder(nn.Module):
+ def __init__(self,
+ seq_dim,
+ depth=2,
+ d_state=16,
+ d_conv=4,
+ expand=2,
+ bidi=True,
+ use_transformer=False,
+ norm_layer=nn.LayerNorm):
+ super().__init__()
+
+ self.bidi = bidi
+ self.use_transformer = use_transformer
+ if use_transformer:
+ assert not bidi, "Bidirectional mode is not supported with transformer encoder"
+ # encoder_layer = nn.TransformerEncoderLayer(d_model=seq_dim, nhead=8, dropout=0.1, batch_first=True, norm_first=True)
+ # self.seq_layers = nn.TransformerEncoder(encoder_layer, num_layers=depth*2)
+ self.seq_layers = nn.ModuleList([
+ Block(dim=seq_dim, num_heads=4, drop=0.1, drop_path=0.0, norm_layer=norm_layer)
+ for i in range(depth*2)
+ ])
+
+ else:
+ self.seq_layers = nn.ModuleList([
+ MambaBlock(d_model=seq_dim, d_state=d_state, d_conv=d_conv, expand=expand, norm_layer=norm_layer)
+ for i in range(depth)
+ ])
+ self.norm_fwd = norm_layer(seq_dim)
+ # self.post_norm_fwd = norm_layer(seq_dim)
+ if self.bidi:
+ self.seq_layers_bwd = nn.ModuleList([
+ MambaBlock(d_model=seq_dim, d_state=d_state, d_conv=d_conv, expand=expand, norm_layer=norm_layer)
+ for i in range(depth)
+ ])
+ self.norm_bwd = norm_layer(seq_dim)
+
+ # encoder_layer = nn.TransformerEncoderLayer(d_model=embed_dim, nhead=num_heads, dropout=dropout, batch_first=True, norm_first=True)
+ # self.transformer_encoder = nn.TransformerEncoder(encoder_layer, num_layers=num_layers)
+
+
+
+ def forward(self, x, mask=None):
+
+ if self.bidi:
+ # Process forward and backward paths independently
+ xr = flip_padded_sequences(x, mask)
+ mr = mask
+
+ for blk, blk_bwd in zip(self.seq_layers, self.seq_layers_bwd):
+ xf = blk(x, mask)
+ xr = blk_bwd(xr, mr)
+ xf = self.norm_fwd(xf)
+ xr = self.norm_bwd(xr)
+ return xf, xr
+ else:
+ if self.use_transformer:
+ mask = ~mask
+ # # For transformer, we need to provide a key padding mask
+ # x = self.seq_layers(x, src_key_padding_mask=~mask)
+ # else:
+ for blk in self.seq_layers:
+ x = blk(x, mask)
+
+ x = self.norm_fwd(x)
+ return x
\ No newline at end of file
diff --git a/models/transformer_modules.py b/models/transformer_modules.py
new file mode 100644
index 0000000000000000000000000000000000000000..0316a2c2ddcafd01917e66287b554240a7b04d97
--- /dev/null
+++ b/models/transformer_modules.py
@@ -0,0 +1,1013 @@
+# Copyright (c) 2022 Alpha-VL
+# --------------------------------------------------------
+# References:
+# timm: https://github.com/rwightman/pytorch-image-models/tree/master/timm
+# DeiT: https://github.com/facebookresearch/deit
+# --------------------------------------------------------
+import torch
+import torch.nn as nn
+from functools import partial
+
+# from timm.data import IMAGENET_DEFAULT_MEAN, IMAGENET_DEFAULT_STD
+# from timm.models.helpers import load_pretrained
+from timm.models.layers import DropPath, to_2tuple, trunc_normal_
+# from timm.models.resnet import resnet26d, resnet50d
+# from timm.models.registry import register_model
+
+import pdb
+from flash_attn import flash_attn_qkvpacked_func, flash_attn_func
+from einops import rearrange, repeat
+import math
+
+import torch.nn.functional as F
+
+
+# class CMlp(nn.Module):
+# # taken from https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py
+# def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.3):
+# super().__init__()
+# out_features = out_features or in_features
+# hidden_features = hidden_features or in_features
+# self.fc1 = nn.Conv2d(in_features, hidden_features, 1)
+# self.act = act_layer()
+# self.fc2 = nn.Conv2d(hidden_features, out_features, 1)
+# self.drop = nn.Dropout(drop)
+
+# def forward(self, x):
+# x = self.fc1(x)
+# x = self.act(x)
+# x = self.drop(x)
+# x = self.fc2(x)
+# x = self.drop(x)
+# return x
+
+# class CMlp1d(nn.Module):
+# def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.3):
+# super().__init__()
+# out_features = out_features or in_features
+# hidden_features = hidden_features or in_features
+# self.fc1 = nn.Conv1d(in_features, hidden_features, 1)
+# self.act = act_layer()
+# self.fc2 = nn.Conv1d(hidden_features, out_features, 1)
+# self.drop = nn.Dropout(drop)
+
+# def forward(self, x):
+# x = self.fc1(x)
+# x = self.act(x)
+# x = self.drop(x)
+# x = self.fc2(x)
+# x = self.drop(x)
+# return x
+
+class Mlp(nn.Module):
+ def __init__(self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, drop=0.1):
+ super().__init__()
+ out_features = out_features or in_features
+ hidden_features = hidden_features or in_features
+ self.fc1 = nn.Linear(in_features, hidden_features)
+ self.act = act_layer()
+ self.fc2 = nn.Linear(hidden_features, out_features)
+ self.drop = nn.Dropout(drop)
+
+ def forward(self, x):
+ x = self.fc1(x)
+ x = self.act(x)
+ x = self.drop(x)
+ x = self.fc2(x)
+ x = self.drop(x)
+ return x
+
+class GatedMLP(nn.Module):
+ def __init__(
+ self,
+ in_features,
+ hidden_features=None,
+ out_features=None,
+ act_layer=F.silu,
+ multiple_of=128,
+ drop=0.3
+ ):
+
+ super().__init__()
+ out_features = out_features if out_features is not None else in_features
+ hidden_features = (
+ hidden_features if hidden_features is not None else int(8 * in_features / 3)
+ )
+ hidden_features = (hidden_features + multiple_of - 1) // multiple_of * multiple_of
+ self.fc1 = nn.Linear(in_features, 2 * hidden_features)
+ self.act = act_layer()
+ self.fc2 = nn.Linear(hidden_features, out_features)
+ self.drop = nn.Dropout(drop)
+
+ def forward(self, x):
+ y = self.fc1(x)
+ y, gate = y.chunk(2, dim=-1)
+ y = y * self.act(gate)
+ y = self.drop(y)
+ y = self.fc2(y)
+ y = self.drop(y)
+ return y
+
+# class CBlock(nn.Module):
+# # taken from https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py
+# def __init__(self, dim, ksize=(5,5), mlp_ratio=4., drop=0.,
+# drop_path=0., act_layer=nn.GELU, norm_layer=nn.LayerNorm):
+# super().__init__()
+# self.norm1 = nn.LayerNorm(dim)
+# self.conv1 = nn.Conv2d(dim, dim, 1)
+# self.conv2 = nn.Conv2d(dim, dim, 1)
+# self.attn = nn.Conv2d(dim, dim, ksize, padding=2, groups=dim)
+# # self.attn = nn.Conv2d(dim, dim, 13, padding=6, groups=dim)
+# # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
+# self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+# self.norm2 = nn.LayerNorm(dim)
+# mlp_hidden_dim = int(dim * mlp_ratio)
+# self.mlp = CMlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
+
+# def forward(self, x, mask=None):
+# if mask is not None:
+# x = x + self.drop_path(self.conv2(self.attn(mask * self.conv1(self.norm1(x.permute(0, 2, 3, 1)).permute(0, 3, 1, 2)))))
+# else:
+# x = x + self.drop_path(self.conv2(self.attn(self.conv1(self.norm1(x.permute(0, 2, 3, 1)).permute(0, 3, 1, 2)))))
+# x = x + self.drop_path(self.mlp(self.norm2(x.permute(0, 2, 3, 1)).permute(0, 3, 1, 2)))
+# return x
+
+# class CBlock1d(nn.Module):
+# # taken from https://github.com/rwightman/pytorch-image-models/blob/master/timm/models/vision_transformer.py
+# def __init__(self, dim, mlp_ratio=4., drop=0.3,
+# drop_path=0.1, act_layer=nn.GELU, norm_layer=nn.LayerNorm):
+# super().__init__()
+# self.norm1 = nn.LayerNorm(dim)
+# self.conv1 = nn.Conv1d(dim, dim, 1)
+# self.conv2 = nn.Conv1d(dim, dim, 1)
+# self.attn = nn.Conv1d(dim, dim, 5, padding=2, groups=dim)
+# # self.attn = nn.Conv2d(dim, dim, 13, padding=6, groups=dim)
+# # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
+# self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+# self.norm2 = nn.LayerNorm(dim)
+# mlp_hidden_dim = int(dim * mlp_ratio)
+# self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
+
+# def forward(self, x, mask=None):
+# # Input: (B, L, c)
+# if mask is not None:
+# x = x + self.drop_path(self.conv2(self.attn(mask * self.conv1(self.norm1(x).permute(0, 2, 1))))).permute(0,2,1)
+# else:
+# x = x + self.drop_path(self.conv2(self.attn(self.conv1(self.norm1(x).permute(0, 2, 1))))).permute(0,2,1)
+# x = x + self.drop_path(self.mlp(self.norm2(x)))
+# return x
+
+
+class Attention(nn.Module):
+ def __init__(self, dim, num_heads=8, qkv_bias=False, qk_scale=None, attn_drop=0., proj_drop=0.):
+ super().__init__()
+ self.num_heads = num_heads
+ head_dim = dim // num_heads
+ # NOTE scale factor was wrong in my original version, can set manually to be compat with prev weights
+ self.scale = qk_scale or head_dim ** -0.5
+
+ self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
+ self.attn_drop = nn.Dropout(attn_drop)
+ self.proj = nn.Linear(dim, dim)
+ self.proj_drop = nn.Dropout(proj_drop)
+
+ def forward(self, x, mask=None):
+ B, N, C = x.shape
+ qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C // self.num_heads).permute(2, 0, 3, 1, 4)
+ q, k, v = qkv[0], qkv[1], qkv[2] # make torchscript happy (cannot use tensor as tuple)
+
+ attn = (q @ k.transpose(-2, -1)) * self.scale
+
+ # Apply mask if provided
+ if mask is not None:
+ # mask shape: (B, N) or (B, 1, 1, N) for broadcasting
+ if mask.dim() == 2:
+ mask = mask.unsqueeze(1).unsqueeze(1) # (B, 1, 1, N)
+ # Convert boolean mask to attention mask: False->0 (keep), True->-inf (mask out)
+ attn_mask = torch.where(mask, torch.tensor(float('-inf')), torch.tensor(0.0))
+ attn = attn + attn_mask
+
+ attn = attn.softmax(dim=-1)
+ attn = self.attn_drop(attn)
+
+ x = (attn @ v).transpose(1, 2).reshape(B, N, C)
+ x = self.proj(x)
+ x = self.proj_drop(x)
+ return x
+
+
+class Block(nn.Module):
+
+ def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0.1, attn_drop=0.1,
+ drop_path=0.1, act_layer=nn.GELU, norm_layer=nn.LayerNorm):
+ super().__init__()
+ self.norm1 = norm_layer(dim)
+ self.attn = Attention(
+ dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
+ # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+ self.norm2 = norm_layer(dim)
+ mlp_hidden_dim = int(dim * mlp_ratio)
+ self.mlp = Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
+ # self.mlp = GatedMLP(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
+
+ def forward(self, x, mask=None):
+ x = x + self.drop_path(self.attn(self.norm1(x), mask=mask))
+ x = x + self.drop_path(self.mlp(self.norm2(x)))
+ return x
+
+
+class MoEBlock(nn.Module):
+
+ def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0.1, attn_drop=0.1,
+ drop_path=0.1, act_layer=nn.GELU, norm_layer=nn.LayerNorm,
+ seq_len=375, num_experts=3, num_experts_per=2):
+ super().__init__()
+ self.norm1 = norm_layer(dim)
+ self.attn = Attention(
+ dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
+
+ # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+ self.norm2 = norm_layer(dim)
+ mlp_hidden_dim = int(dim * mlp_ratio)
+
+ self.num_experts = num_experts
+ self.num_experts_per = num_experts_per
+ self.gate = nn.Linear(
+ dim * seq_len, num_experts, bias=False)
+ # Patchwise gating, worse performance.
+ # self.gate = nn.Linear(
+ # dim, num_experts, bias=False)
+ self.experts = nn.ModuleList(
+ [Mlp(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
+ for _ in range(num_experts)])
+
+
+ def forward(self, x, mask=None):
+ x = x + self.drop_path(self.attn(self.norm1(x), mask=mask))
+ x_orig = x
+ x = self.norm2(x)
+ orig_shape = x.shape
+ x = x.view(x.shape[0], -1) #(B, L*C)
+ scores = self.gate(x) #(B, num_experts)
+ expert_weights, expert_indices = torch.topk(
+ scores, self.num_experts_per, dim=-1) #(B, #num_experts_per)
+
+ # Weights are normlaized
+ expert_weights = expert_weights.softmax(dim=-1) #(B, #num_experts_per)
+ expert_weights = expert_weights.unsqueeze(1).repeat(1, orig_shape[1], 1) #(B, L, #num_experts_per)
+ expert_indices = expert_indices.unsqueeze(1).repeat(1, orig_shape[1], 1) #(B, L, #num_experts_per)
+
+ x = x.view(orig_shape[0], orig_shape[1], 1, -1) # (B, L, 1, C)
+ x = x.repeat_interleave(self.num_experts_per, dim=2) # (B, L, num_experts_per, C)
+ y = torch.empty_like(x, dtype=x.dtype) #(B, L, num_experts_per, C)
+ for i, expert in enumerate(self.experts):
+ y[expert_indices == i] = expert(x[expert_indices == i]).to(x.dtype)
+
+ y = (y.view(*expert_weights.shape, -1) * expert_weights.unsqueeze(-1)).sum(dim=2)
+ x = x_orig + self.drop_path(y.view(*orig_shape))
+
+ return x, scores
+
+
+class BlockFlashAttn(nn.Module):
+
+ def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0.1, attn_drop=0.1,
+ drop_path=0.1, act_layer=nn.GELU, norm_layer=nn.LayerNorm):
+ super().__init__()
+ self.norm1_q = norm_layer(dim)
+ self.norm1_kv = norm_layer(dim)
+ # self.attn = Attention(
+ # dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
+ self.q_proj = nn.Linear(dim, dim, bias=qkv_bias)
+ self.k_proj = nn.Linear(dim, dim, bias=qkv_bias)
+ self.v_proj = nn.Linear(dim, dim, bias=qkv_bias)
+ self.attn_drop = attn_drop
+ self.num_heads = num_heads
+
+ # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+ self.norm2 = norm_layer(dim)
+ mlp_hidden_dim = int(dim * mlp_ratio)
+ self.mlp = GatedMLP(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
+
+ def forward(self, x, context=None, rope=None, rope2=None, mask=None):
+ dropout_p = self.attn_drop if self.training else 0.0
+ x_ = x
+
+ if context is None:
+ context = x
+ # Project queries, keys, values
+ q = self.q_proj(self.norm1_q(x))
+ k = self.k_proj(self.norm1_kv(context))
+ v = self.v_proj(self.norm1_kv(context))
+ # Reshape for flash attention: (batch, seqlen, nheads, headdim)
+ B, Lq, C = q.shape
+ B, Lkv, C = k.shape
+ q = q.reshape(B, Lq, self.num_heads, C // self.num_heads)
+ k = k.reshape(B, Lkv, self.num_heads, C // self.num_heads)
+ v = v.reshape(B, Lkv, self.num_heads, C // self.num_heads)
+ if rope is not None:
+ if len(rope.shape) == 3:
+ rope = rope.unsqueeze(1).to(dtype=q.dtype) # (B, 1, seq_len, dim)
+ q = rearrange(q, 'b l h d -> b h l d')
+ q = rotate(q, rope)
+ q = rearrange(q, 'b h l d -> b l h d')
+
+ if rope2 is not None:
+ if len(rope2.shape) == 3:
+ rope2 = rope2.unsqueeze(1).to(dtype=q.dtype) # (B, 1, seq_len, dim)
+ else:
+ rope2 = rope
+
+ k = rearrange(k, 'b l h d -> b h l d')
+ k = rotate(k, rope2)
+ k = rearrange(k, 'b h l d -> b l h d')
+
+ # Stack for flash_attn_func: (q, k, v)
+ # flash_attn_func expects (q, k, v) separately
+ out = flash_attn_func(q, k, v, dropout_p=dropout_p, causal=False)
+
+ out = out.reshape(B, Lq, -1)
+ x = x_ + self.drop_path(out)
+ x = x + self.drop_path(self.mlp(self.norm2(x)))
+ return x, None # For consistency
+
+class BlockFlashAttnPad(nn.Module):
+
+ def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0.1, attn_drop=0.1,
+ drop_path=0.1, act_layer=nn.GELU, norm_layer=nn.LayerNorm):
+ super().__init__()
+ self.norm1_q = norm_layer(dim)
+ self.norm1_kv = norm_layer(dim)
+ # self.attn = Attention(
+ # dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
+ self.q_proj = nn.Linear(dim, dim, bias=qkv_bias)
+ self.k_proj = nn.Linear(dim, dim, bias=qkv_bias)
+ self.v_proj = nn.Linear(dim, dim, bias=qkv_bias)
+ self.attn_drop = attn_drop
+ self.num_heads = num_heads
+
+ # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+ self.norm2 = norm_layer(dim)
+ mlp_hidden_dim = int(dim * mlp_ratio)
+ self.mlp = GatedMLP(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
+
+ def forward(self, x, mask=None):
+ dropout_p = self.attn_drop if self.training else 0.0
+ x_ = x
+
+ seq_lengths = mask.sum(-1).long() # (B,)
+ context = x
+ # Project queries, keys, values
+ q = self.q_proj(self.norm1_q(x))
+ k = self.k_proj(self.norm1_kv(context))
+ v = self.v_proj(self.norm1_kv(context))
+ # Reshape for flash attention: (batch, seqlen, nheads, headdim)
+ B, Lq, C = q.shape
+ B, Lkv, C = k.shape
+ q = q.reshape(B, Lq, self.num_heads, C // self.num_heads)
+ k = k.reshape(B, Lkv, self.num_heads, C // self.num_heads)
+ v = v.reshape(B, Lkv, self.num_heads, C // self.num_heads)
+ if rope is not None:
+ if len(rope.shape) == 3:
+ rope = rope.unsqueeze(1).to(dtype=q.dtype) # (B, 1, seq_len, dim)
+ q = rearrange(q, 'b l h d -> b h l d')
+ q = rotate(q, rope)
+ q = rearrange(q, 'b h l d -> b l h d')
+
+ k = rearrange(k, 'b l h d -> b h l d')
+ k = rotate(k, rope)
+ k = rearrange(k, 'b h l d -> b l h d')
+
+ # Stack for flash_attn_func: (q, k, v)
+ # flash_attn_func expects (q, k, v) separately
+ # out = flash_attn_func(q, k, v, dropout_p=dropout_p, causal=False)
+
+ q_flat = q.reshape(-1, q.shape[-2], q.shape[-1]) # (B*L1, Lq, headdim)
+ k_flat = k.reshape(-1, k.shape[-2], k.shape[-1]) # (B*L2, Lkv, headdim)
+ v_flat = v.reshape(-1, v.shape[-2], v.shape[-1])
+ cu_seqlens = torch.zeros(B + 1, dtype=torch.int32, device=x.device)
+ cu_seqlens[1:] = torch.cumsum(seq_lengths, dim=0).int()
+ # out: (batch_size, seqlen, nheads, headdim
+
+ out = flash_attn_varlen_func(
+ q_flat, k_flat, v_flat,
+ cu_seqlens_q=cu_seqlens,
+ cu_seqlens_k=cu_seqlens,
+ max_seqlen_q=1080, # The longest sequence in the batch
+ max_seqlen_k=1080,
+ causal=True
+ )
+
+ out = out.reshape(B, Lq, -1)
+ x = x_ + self.drop_path(out)
+ x = x + self.drop_path(self.mlp(self.norm2(x)))
+ return x, None # For consistency
+
+class MoEBlockFlashAttn(nn.Module):
+
+ def __init__(self, dim, num_heads, mlp_ratio=4., qkv_bias=False, qk_scale=None, drop=0.1, attn_drop=0.1,
+ drop_path=0.1, act_layer=nn.GELU, norm_layer=nn.LayerNorm,
+ seq_len=375, num_experts=3, num_experts_per=2):
+ super().__init__()
+ self.norm1 = norm_layer(dim)
+ # self.attn = Attention(
+ # dim, num_heads=num_heads, qkv_bias=qkv_bias, qk_scale=qk_scale, attn_drop=attn_drop, proj_drop=drop)
+ self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)
+ self.attn_drop = attn_drop
+ self.num_heads = num_heads
+
+ # NOTE: drop path for stochastic depth, we shall see if this is better than dropout here
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+ self.norm2 = norm_layer(dim)
+ mlp_hidden_dim = int(dim * mlp_ratio)
+
+ self.num_experts = num_experts
+ self.num_experts_per = num_experts_per
+ self.gate = nn.Linear(
+ dim, num_experts, bias=False)
+ # Patchwise gating, worse performance.
+ # self.gate = nn.Linear(
+ # dim, num_experts, bias=False)
+ self.experts = nn.ModuleList(
+ [GatedMLP(in_features=dim, hidden_features=mlp_hidden_dim, act_layer=act_layer, drop=drop)
+ for _ in range(num_experts)])
+
+
+ def forward(self, x, rope=None, mask=None):
+
+ # x = x + self.drop_path(self.attn(self.norm1(x)))
+ dropout_p = self.attn_drop if self.training else 0.0
+ x_ = x
+
+ x = self.qkv(self.norm1(x))
+
+ # Flash attention requires this shape: qkv: (batch_size, seqlen, 3, nheads, headdim)
+ x = x.reshape(x.shape[0], x.shape[1], 3, x.shape[-1] // 3)
+ x = x.reshape(x.shape[0], x.shape[1], 3, self.num_heads, x.shape[-1] // self.num_heads)
+
+ q = x[:,:,0] # (batch_size, seqlen, nheads, headdim)
+ k = x[:,:,1] # (batch_size, seqlen, nheads , headdim)
+ v = x[:,:,2] # (batch_size, seqlen, nheads , headdim)
+
+ if rope is not None:
+ if len(rope.shape) == 3:
+ rope = rope.unsqueeze(1).to(q.dtype) # (1, seq_len, 1, dim)
+ q = rearrange(q, 'b l h d -> b h l d')
+ q = rotate(q, rope)
+ q = rearrange(q, 'b h l d -> b l h d')
+ k = rearrange(k, 'b l h d -> b h l d')
+ k = rotate(k, rope)
+ k = rearrange(k, 'b h l d -> b l h d')
+
+ # x, lse, S_dmask = flash_attn_func(q, k, v, dropout_p=dropout_p, causal=False, return_attn_probs=True)
+ x= flash_attn_func(q, k, v, dropout_p=dropout_p, causal=False)
+
+ x = x.reshape(x.shape[0], x.shape[1], -1) # (B, L, C)
+
+ x = x_ + self.drop_path(x)
+ x_orig = x
+ x = self.norm2(x)
+ orig_shape = x.shape
+ # x = x.view(x.shape[0], -1) #(B, L*C)
+ # scores = torch.mean(self.gate(x), dim=1) #(B, num_experts)
+ scores = self.gate(x) #(B, L, num_experts)
+ # scores = self.gate(x[:,:512*60]) #(B, num_experts)
+ expert_weights, expert_indices = torch.topk(
+ scores, self.num_experts_per, dim=-1) #(B, L, num_experts_per)
+
+ # Weights are normlaized
+ expert_weights = expert_weights.softmax(dim=-1) #(B, L, num_experts_per)
+ # expert_weights = expert_weights.repeat(1, orig_shape[1], 1) #(B, L, #num_experts_per)
+ # expert_indices = expert_indices.repeat(1, orig_shape[1], 1) #(B, L, #num_experts_per)
+
+ x = x.view(orig_shape[0], orig_shape[1], 1, -1) # (B, L, 1, C)
+ x = x.repeat_interleave(self.num_experts_per, dim=2) # (B, L, num_experts_per, C)
+ y = torch.empty_like(x, dtype=x.dtype) #(B, L, num_experts_per, C)
+ for i, expert in enumerate(self.experts):
+ y[expert_indices == i] = expert(x[expert_indices == i]).to(x.dtype)
+
+ y = (y.view(*expert_weights.shape, -1) * expert_weights.unsqueeze(-1)).sum(dim=2)
+ x = x_orig + self.drop_path(y.view(*orig_shape))
+
+ return x, scores
+
+
+
+
+# class PatchEmbed(nn.Module):
+# """ Image to Patch Embedding
+# """
+# def __init__(self, img_size=224, patch_size=16, in_chans=3, embed_dim=768):
+# super().__init__()
+# img_size = to_2tuple(img_size)
+# patch_size = to_2tuple(patch_size)
+# num_patches = (img_size[1] // patch_size[1]) * (img_size[0] // patch_size[0])
+# self.img_size = img_size
+# self.patch_size = patch_size
+# self.num_patches = num_patches
+
+# self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)
+# self.norm = nn.LayerNorm(embed_dim)
+# self.act = nn.GELU()
+# def forward(self, x):
+# B, C, H, W = x.shape
+# # FIXME look at relaxing size constraints
+# assert H == self.img_size[0] and W == self.img_size[1], \
+# f"Input image size ({H}*{W}) doesn't match model ({self.img_size[0]}*{self.img_size[1]})."
+# x = self.proj(x)
+# x = self.norm(x.permute(0, 2, 3, 1)).permute(0, 3, 1, 2)
+# return self.act(x)
+
+
+# class PatchEmbed2d(nn.Module):
+# """ Image to Patch Embedding
+# """
+# def __init__(self, kernel_size=(8,8), in_chans=384, embed_dim=384):
+# super().__init__()
+
+# self.proj = nn.Conv2d(in_chans, embed_dim, kernel_size=kernel_size, stride=kernel_size)
+# self.norm = nn.LayerNorm(embed_dim)
+# self.act = nn.GELU()
+# def forward(self, x):
+
+# x = self.proj(x)
+# x = self.norm(x.permute(0, 2, 3, 1)).permute(0, 3, 1, 2)
+# return self.act(x)
+
+
+# class PatchEmbed1d(nn.Module):
+# """ Image to Patch Embedding
+# """
+# def __init__(self, conv_patch_size=2, in_chans=1, embed_dim=128, norm_layer=nn.LayerNorm):
+# super().__init__()
+
+# self.conv_patch_size = conv_patch_size
+
+# self.proj = nn.Conv1d(in_chans, embed_dim, kernel_size=conv_patch_size, stride=conv_patch_size)
+# self.norm = norm_layer(embed_dim)
+# self.act = nn.GELU()
+# def forward(self, x):
+# # B, L, C = x.shape
+# # # FIXME look at relaxing size constraints
+# # assert L == self.sig_len, \
+# # f"Input Signal length ({L}) doesn't match model ({self.sig_len})."
+
+# x = x.permute(0, 2, 1) # (B, C, L)
+# x = self.proj(x)
+# x = x.permute(0, 2, 1) # (B, L, C)
+
+# x = self.norm(x)
+# return self.act(x)
+
+class PatchEmbed(nn.Module):
+ """ Image to Patch Embedding
+ """
+ def __init__(self, sig_len=3000, conv_patch_sizes=[10,5,1], in_chans=1, embed_dim=[32,64,128], norm_layer=nn.LayerNorm):
+ super().__init__()
+
+ # num_patches = sig_len // conv_patch_size
+ self.sig_len = sig_len
+ self.conv_patch_sizes = conv_patch_sizes
+ # self.num_patches = num_patches
+
+ self.proj = nn.Conv1d(in_chans, embed_dim[0], kernel_size=self.conv_patch_sizes[0], stride=self.conv_patch_sizes[0])
+ self.norm = norm_layer(embed_dim[0])
+ self.act = nn.GELU()
+
+ self.proj2 = nn.Conv1d(embed_dim[0], embed_dim[1], kernel_size=self.conv_patch_sizes[1], stride=self.conv_patch_sizes[1])
+ self.norm2 = norm_layer(embed_dim[1])
+ # self.act2 = nn.GELU()
+
+ self.proj3 = nn.Conv1d(embed_dim[1], embed_dim[2], kernel_size=self.conv_patch_sizes[2], stride=self.conv_patch_sizes[2])
+ self.norm3 = norm_layer(embed_dim[2])
+ # self.act2 = nn.GELU()
+
+
+ def forward(self, x):
+ B, L, C = x.shape
+ # # FIXME look at relaxing size constraints
+ # assert L == self.sig_len, \
+ # f"Input Signal length ({L}) doesn't match model ({self.sig_len})."
+
+ x = x.permute(0, 2, 1) # (B, C, L)
+ x = self.proj(x)
+ x = x.permute(0, 2, 1) # (B, L, C)
+
+ x = self.act(self.norm(x))
+
+ x = x.permute(0, 2, 1) # (B, C, L)
+ x = self.proj2(x)
+ x = x.permute(0, 2, 1) # (B, L, C)
+
+ x = self.act(self.norm2(x))
+
+ x = x.permute(0, 2, 1) # (B, C, L)
+ x = self.proj3(x)
+ x = x.permute(0, 2, 1) # (B, L, C)
+
+ x = self.act(self.norm3(x))
+
+
+ return x
+
+class ConvNextBlock(nn.Module):
+ """ ConvNeXt Block
+ """
+ def __init__(self, dim, out_dim, kernel_size=7, drop_path=0.3, stride=1, layer_scale_init_value=1e-6, norm_layer=nn.LayerNorm):
+ super().__init__()
+ self.pwconv0 = nn.Linear(dim, out_dim)
+ self.dwconv = nn.Conv1d(out_dim, out_dim, kernel_size=kernel_size, stride=stride, groups=dim) # depthwise conv
+ self.norm = norm_layer(out_dim)
+ self.pwconv1 = nn.Linear(out_dim, 4 * out_dim) # pointwise/1x1 convs, implemented with linear layers
+ self.act = nn.GELU()
+ self.pwconv2 = nn.Linear(4 * out_dim, out_dim)
+ self.gamma = nn.Parameter(layer_scale_init_value * torch.ones((out_dim)),
+ requires_grad=True) if layer_scale_init_value > 0 else None
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+ self.stride = stride
+
+ def forward(self, x):
+
+ x = x.permute(0, 2, 1)
+ x = self.pwconv0(x)
+ x = x.permute(0, 2, 1)
+ x = self.dwconv(x)
+ _x = x
+ x = x.permute(0, 2, 1) # (B, L, C)
+ x = self.norm(x)
+ x = self.pwconv1(x)
+ x = self.act(x)
+ x = self.pwconv2(x)
+ if self.gamma is not None:
+ x = self.gamma.unsqueeze(0).unsqueeze(0) * x
+ x = x.permute(0, 2, 1) # (B, C, L)
+ x = _x + self.drop_path(x)
+ # if self.stride == 1:
+ # x = input + self.drop_path(x)
+ # input = input[:, :, ::self.stride]
+
+ # x = input + self.drop_path(x)
+ return x
+
+class PatchEmbed2(nn.Module):
+ """ Image to Patch Embedding
+ """
+ def __init__(self, sig_len=3000, conv_patch_sizes=[5,2], in_chans=1, embed_dim=[64,128]):
+ super().__init__()
+
+ # num_patches = sig_len // conv_patch_size
+ self.sig_len = sig_len
+ self.conv_patch_sizes = conv_patch_sizes
+ # self.num_patches = num_patches
+ self.conv1 = ConvNextBlock(in_chans, embed_dim[0], kernel_size=self.conv_patch_sizes[0], stride=self.conv_patch_sizes[0])
+ self.conv2 = ConvNextBlock(embed_dim[0], embed_dim[1], kernel_size=self.conv_patch_sizes[1], stride=self.conv_patch_sizes[1])
+
+ def forward(self, x):
+ B, L, C = x.shape
+ # FIXME look at relaxing size constraints
+ assert L == self.sig_len, \
+ f"Input Signal length ({L}) doesn't match model ({self.sig_len})."
+ x = self.conv1(x.permute(0,2,1)) # (B, C, L)
+ x = self.conv2(x) # (B, C, L)
+ x = x.permute(0,2,1) # (B, L, C)
+
+ return x
+
+class PatchUpsample(nn.Module):
+ """ Image to Patch Embedding
+ """
+ def __init__(self, embed_dim=256, up_dim=128, upsample=2, norm_layer=nn.LayerNorm):
+ super().__init__()
+
+ self.upsample = upsample
+ self.norm = norm_layer(embed_dim + up_dim)
+ self.merge = nn.Linear(embed_dim + up_dim, up_dim)
+
+ def forward(self, x1, x2):
+ """
+ x1: (B, L, C) From higher layer
+ x2: (B, 2L, C) From lower layer
+ """
+
+ x1 = x1.repeat_interleave(self.upsample, dim=1) # (B, downsample*L, C)
+
+ x = torch.cat([x1,x2], dim=-1)
+ x = self.norm(x)
+ x = self.merge(x)
+
+ return x
+
+# class PatchUpsample2(nn.Module):
+# """ Image to Patch Embedding
+# """
+# def __init__(self, embed_dim=256, up_dim=128, upsample=2, norm_layer=nn.LayerNorm):
+# super().__init__()
+
+# self.upsample = upsample
+# self.up_dim = up_dim
+# self.mlp = Mlp(in_features=embed_dim, hidden_features=up_dim * upsample, out_features=up_dim * upsample)
+# self.post_norm = norm_layer(up_dim)
+
+# def forward(self, x):
+# """
+# x1: (B, L, C) From higher layer
+# """
+# x = self.mlp(x)
+# x = x.view(x.shape[0], x.shape[1] * self.upsample, -1) # (B, L*upsample, C)
+# x = self.post_norm(x)
+
+# return x
+
+# class PatchUpsample3(nn.Module):
+# """ Image to Patch Embedding
+# """
+# def __init__(self, embed_dim=256, up_dim=128, upsample=2, norm_layer=nn.LayerNorm):
+# super().__init__()
+
+# self.upsample = upsample
+# self.up_dim = up_dim
+# # self.proj = nn.Linear(embed_dim, up_dim * upsample)
+# self.proj = nn.ConvTranspose1d(embed_dim, up_dim, kernel_size=upsample, stride=upsample)
+# self.post_norm = norm_layer(up_dim)
+
+# def forward(self, x):
+# """
+# x1: (B, L, C) From higher layer
+# """
+# x = x.permute(0, 2, 1) # (B, C, L)
+# x = self.proj(x)
+# x = x.permute(0, 2, 1) # (B, L, C)
+# x = self.post_norm(x)
+
+# return x
+
+
+# class PatchUpsampleConvNext(nn.Module):
+# """
+# Upsample patches from higher layer using ConvNext-style flow.
+# Upsamples by 2x via repeat_interleave and fuses with lower layer patches
+# using ConvNext-style MLP blocks (depthwise conv + pointwise conv pattern).
+
+# Args:
+# embed_dim: Embedding dimension
+# upsample: Upsample factor (default: 2)
+# mlp_ratio: Hidden dimension ratio for MLP (default: 4)
+# drop_path: Drop path rate (default: 0)
+# """
+# def __init__(self, embed_dim=256, upsample=2, mlp_ratio=4., drop_path=0.1):
+# super().__init__()
+# self.upsample = upsample
+# self.embed_dim = embed_dim
+
+# # Normalization before fusion
+# self.norm = nn.LayerNorm(embed_dim)
+
+# # ConvNext-style block: depthwise conv -> pointwise convs with GELU
+# # Adapted for sequence format (B, L, C)
+# # We'll use 1D convolutions treating the sequence as channels for a moment
+# hidden_dim = int(embed_dim * mlp_ratio)
+
+# # Depthwise convolution (groupwise, one group per channel)
+# self.dwconv = nn.Conv1d(embed_dim, embed_dim, kernel_size=7, padding=3, groups=embed_dim)
+
+# # Pointwise convolutions with expansion/contraction
+# self.pwconv1 = nn.Linear(embed_dim, hidden_dim)
+# self.act = nn.GELU()
+# self.pwconv2 = nn.Linear(hidden_dim, embed_dim)
+
+# # Drop path for stochastic depth
+# self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+
+# def forward(self, x_high, x_low):
+# """
+# x_high: (B, L, C) From higher (coarser) layer
+# x_low: (B, L*U, C) From lower (finer) layer, where U is upsample factor
+
+# Returns:
+# (B, L*U, C) Fused feature
+# """
+# # Upsample higher layer patches by repeating
+# x_high_up = x_high.repeat_interleave(self.upsample, dim=1) # (B, L*U, C)
+
+# # Concatenate upsampled high with low
+# x = torch.cat([x_high_up, x_low], dim=-1) # (B, L*U, 2C)
+
+# # Project concatenated features back to embed_dim using linear layer
+# # (simple fusion, can be extended to use attention)
+# x_fused = (x_high_up + x_low) / 2.0 # simple average for initial fusion
+
+# # Apply ConvNext-style block to the fused features
+# # Residual connection
+# shortcut = x_fused
+# x_fused = self.norm(x_fused) # (B, L*U, C)
+
+# # Rearrange for depthwise conv: (B, L*U, C) -> (B, C, L*U)
+# x_fused = x_fused.permute(0, 2, 1)
+# x_fused = self.dwconv(x_fused) # Depthwise conv
+# x_fused = x_fused.permute(0, 2, 1) # (B, L*U, C)
+
+# # Pointwise MLPs
+# x_fused = self.pwconv1(x_fused)
+# x_fused = self.act(x_fused)
+# x_fused = self.pwconv2(x_fused)
+
+# # Residual connection with drop path
+# x_fused = shortcut + self.drop_path(x_fused)
+
+# return x_fused
+
+
+# class PatchMerge(nn.Module):
+# """ Image to Patch Embedding
+# """
+# def __init__(self, embed_dim=256, downsample=4):
+# super().__init__()
+
+# self.downsample = downsample
+# self.norm = nn.LayerNorm(embed_dim * self.downsample)
+# self.merge = nn.Linear(embed_dim * self.downsample, embed_dim)
+
+# def forward(self, x):
+
+# xs = []
+# for i in range(self.downsample):
+# xs.append(x[:,i::self.downsample])
+
+# x = torch.cat(xs, dim=-1)
+# x = self.norm(x)
+# x = self.merge(x)
+
+# return x
+
+class PatchMergeConv(nn.Module):
+ """ Image to Patch Embedding
+ """
+ def __init__(self, embed_dim=128, exp_dim=256, downsample=2, norm_layer=nn.LayerNorm, drop_path = 0.1) :
+ super().__init__()
+
+ self.downsample = downsample
+ self.exp = nn.Conv1d(embed_dim, exp_dim, kernel_size=1)
+ kernel_size = downsample * 2
+ padding = math.ceil(downsample / 2)
+ self.dwconv = nn.Conv1d(exp_dim, exp_dim, kernel_size=kernel_size, groups=exp_dim, stride=downsample, padding=padding)
+
+ self.norm = norm_layer(exp_dim)
+ self.pwconv1 = nn.Linear(exp_dim, exp_dim * 4)
+ self.pwconv2 = nn.Linear(exp_dim * 4, exp_dim)
+ self.act = nn.GELU()
+
+ self.drop_path = DropPath(drop_path) if drop_path > 0. else nn.Identity()
+
+ def forward(self, x):
+
+ x = x.permute(0,2,1)
+ x = self.exp(x)
+ x = self.dwconv(x)
+ x = x.permute(0,2,1)
+ _x = x
+ x = self.norm(x)
+ x = self.pwconv1(x)
+ x = self.act(x)
+ x = self.pwconv2(x)
+ x = _x + self.drop_path(x)
+ # x = self.act(x)
+
+ return x
+
+
+class RevIN(nn.Module):
+ def __init__(self, num_features: int, eps=1e-8, affine=True):
+ """
+ :param num_features: the number of features or channels
+ :param eps: a value added for numerical stability
+ :param affine: if True, RevIN has learnable affine parameters
+ """
+ # super(RevIN, self).__init__()
+ super().__init__()
+ self.num_features = num_features
+ self.eps = eps
+ self.affine = affine
+ if self.affine:
+ self._init_params()
+
+ def forward(self, x, mask=None, mode:str='norm'):
+ if mode == 'norm':
+ self._get_statistics(x, mask)
+ x = self._normalize(x)
+ elif mode == 'denorm':
+ x = self._denormalize(x)
+ else: raise NotImplementedError
+ return x
+
+ def _init_params(self):
+ # initialize RevIN params: (C,)
+ self.affine_weight = nn.Parameter(torch.ones(self.num_features))
+ self.affine_bias = nn.Parameter(torch.zeros(self.num_features))
+
+ def _get_statistics(self, x, mask=None):
+ dim2reduce = tuple(range(1, x.ndim-1))
+ # if mask is not None:
+ # # mask = torch.where(mask==0)[0]
+ # # x_ = x[mask]
+ # x_ = x[(1 - mask).bool()].reshape(x.shape[0], -1, 1)
+ # else:
+ # x_ = x
+ x_ = x # No mask
+
+ self.mean = torch.mean(x_, dim=dim2reduce, keepdim=True).detach()
+ self.stdev = torch.sqrt(torch.var(x_, dim=dim2reduce, keepdim=True, unbiased=False) + self.eps).detach()
+
+
+ def _normalize(self, x):
+ x = x - self.mean
+ x = x / self.stdev
+ if self.affine:
+ x = x * self.affine_weight
+ x = x + self.affine_bias
+ return x
+
+ def _denormalize(self, x):
+ if self.affine:
+ x = x - self.affine_bias
+ x = x / (self.affine_weight + self.eps*self.eps)
+ x = x * self.stdev
+ x = x + self.mean
+ return x
+
+class RMSNorm(nn.Module):
+ def __init__(self, normalized_shape, eps=1e-8):
+ super().__init__()
+ self.eps = eps
+ self.gamma = nn.Parameter(torch.ones(normalized_shape))
+
+ def forward(self, x):
+ rms = torch.sqrt(torch.mean(x**2, dim=-1, keepdim=True))
+ x_norm = x / (rms + self.eps)
+ return self.gamma * x_norm
+
+# Attention pooling from SleepFM
+# https://github.com/zou-group/sleepfm-clinical/blob/main/sleepfm/models/models.py
+class AttentionPooling(nn.Module):
+ def __init__(self, input_dim, num_heads=4, norm_layer=nn.LayerNorm):
+ super().__init__()
+ self.transformer_layer = BlockFlashAttn(dim=input_dim, num_heads=num_heads, mlp_ratio=4.0, qkv_bias=True, norm_layer=norm_layer, drop_path=0.0)
+
+ def forward(self, x):
+
+ out, _ = self.transformer_layer(x)
+ pooled_output = out.mean(dim=1)
+
+ return pooled_output
+
+
+def freq_pos_enc(dim, max_seq_len):
+ # inverse frequencies [theta_1, theta_2, ..., theta_dim/2]
+ inv_freq = 1.0 / (10000 ** (torch.arange(0, dim, 2) / dim)) # (dim/2,)
+ # positions up to max_seq_len
+ pos = torch.arange(max_seq_len) # (max_seq_len,)
+ # frequency position encoding (outer product: pos x inv_freq)
+ pos_enc = torch.einsum("p, f -> p f", pos, inv_freq) # (max_seq_len, dim/2)
+ # duplicate each element along inverse frequency dimension
+ return repeat(pos_enc, "... f -> ... (f r)", r=2) # (max_seq_len, dim)
+
+def rotate_half(u):
+ # last dimension of u is [u1, u2, u3, u4, ...]
+ u = rearrange(u, '... (d r) -> ... d r', r=2)
+ u1, u2 = u.unbind(dim=-1)
+ u = torch.stack((-u2, u1), dim=-1)
+ # last dimension of result is [-u2, u1, -u4, u3, ...]
+ return rearrange(u, '... d r -> ... (d r)')
+
+
+def rotate(u, pos_enc):
+ num_tokens = u.shape[-2]
+ # pos_enc = pos_enc[:num_tokens]
+ return u * pos_enc.cos() + (rotate_half(u) * pos_enc.sin())
+
+
+"""
+batch_size = 2
+num_heads = 8
+seq_len = 64
+head_dim = 32
+
+# random queries and keys
+q = torch.randn(batch_size, num_heads, seq_len, head_dim)
+k = torch.randn(batch_size, num_heads, seq_len, head_dim)
+
+# frequency-encode positions 1 - 512
+pos_enc = freq_pos_enc(dim=head_dim, max_seq_len=512)
+
+# encode absolute positions into queries and keys
+q_rot = rotate(q, pos_enc)
+k_rot = rotate(k, pos_enc)
+
+# take inner product of queries and keys to obtain attention
+# matrices that have relative position information encoded
+attn = torch.einsum("b h i c, b h j c -> b h i j", q_rot, k_rot)
+assert attn.shape == (batch_size, num_heads, seq_len, seq_len)
+"""
\ No newline at end of file
diff --git a/models/utils.py b/models/utils.py
new file mode 100644
index 0000000000000000000000000000000000000000..b0097951bcffbe45370f7e073294899397053709
--- /dev/null
+++ b/models/utils.py
@@ -0,0 +1,360 @@
+# Copyright (c) Meta Platforms, Inc. and affiliates.
+# All rights reserved.
+
+# This source code is licensed under the license found in the
+# LICENSE file in the root directory of this source tree.
+# --------------------------------------------------------
+# Position embedding utils
+# --------------------------------------------------------
+
+import numpy as np
+import torch
+from lifelines.utils import concordance_index
+import math
+from torchmetrics import Metric, MetricCollection
+from torchmetrics.utilities import dim_zero_cat
+from torch.optim.lr_scheduler import StepLR, _LRScheduler
+
+
+# --------------------------------------------------------
+# 2D sine-cosine position embedding
+# References:
+# Transformer: https://github.com/tensorflow/models/blob/master/official/nlp/transformer/model_utils.py
+# MoCo v3: https://github.com/facebookresearch/moco-v3
+# --------------------------------------------------------
+def get_2d_sincos_pos_embed(embed_dim, grid_size, cls_token=False):
+ """
+ grid_size: int of the grid height and width
+ return:
+ pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token)
+ """
+ grid_h = np.arange(grid_size, dtype=np.float32)
+ grid_w = np.arange(grid_size, dtype=np.float32)
+ grid = np.meshgrid(grid_w, grid_h) # here w goes first
+ grid = np.stack(grid, axis=0)
+
+ grid = grid.reshape([2, 1, grid_size, grid_size])
+ pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid)
+ if cls_token:
+ pos_embed = np.concatenate([np.zeros([1, embed_dim]), pos_embed], axis=0)
+ return pos_embed
+
+def get_1d_sincos_pos_embed(embed_dim, grid_size, cls_token=False):
+ """
+ grid_size: int of the grid height and width
+ return:
+ pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token)
+ """
+ # grid = grid.reshape([2, 1, grid_size, grid_size])
+ grid = np.arange(grid_size, dtype=np.float32)
+ grid = grid.reshape([1, 1, grid_size])
+ pos_embed = get_1d_sincos_pos_embed_from_grid(embed_dim, grid)
+ if cls_token:
+ pos_embed = np.concatenate([np.zeros([1, embed_dim]), pos_embed], axis=0)
+ return pos_embed
+
+
+def get_2d_sincos_pos_embed_from_grid(embed_dim, grid):
+ assert embed_dim % 2 == 0
+
+ # use half of dimensions to encode grid_h
+ emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0]) # (H*W, D/2)
+ emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1]) # (H*W, D/2)
+
+ emb = np.concatenate([emb_h, emb_w], axis=1) # (H*W, D)
+ return emb
+
+
+def get_1d_sincos_pos_embed_from_grid(embed_dim, pos):
+ """
+ embed_dim: output dimension for each position
+ pos: a list of positions to be encoded: size (M,)
+ out: (M, D)
+ """
+ assert embed_dim % 2 == 0
+ omega = np.arange(embed_dim // 2, dtype=np.float32)
+ omega /= embed_dim / 2.
+ omega = 1. / 10000**omega # (D/2,)
+
+ pos = pos.reshape(-1) # (M,)
+ out = np.einsum('m,d->md', pos, omega) # (M, D/2), outer product
+
+ emb_sin = np.sin(out) # (M, D/2)
+ emb_cos = np.cos(out) # (M, D/2)
+
+ emb = np.concatenate([emb_sin, emb_cos], axis=1) # (M, D)
+ return emb
+
+
+# --------------------------------------------------------
+# Interpolate position embeddings for high-resolution
+# References:
+# DeiT: https://github.com/facebookresearch/deit
+# --------------------------------------------------------
+def interpolate_pos_embed(model, checkpoint_model):
+ if 'pos_embed' in checkpoint_model:
+ pos_embed_checkpoint = checkpoint_model['pos_embed']
+ embedding_size = pos_embed_checkpoint.shape[-1]
+ num_patches = model.patch_embed.num_patches
+ num_extra_tokens = model.pos_embed.shape[-2] - num_patches
+ # height (== width) for the checkpoint position embedding
+ orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)
+ # height (== width) for the new position embedding
+ new_size = int(num_patches ** 0.5)
+ # class_token and dist_token are kept unchanged
+ if orig_size != new_size:
+ print("Position interpolate from %dx%d to %dx%d" % (orig_size, orig_size, new_size, new_size))
+ extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]
+ # only the position tokens are interpolated
+ pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]
+ pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)
+ pos_tokens = torch.nn.functional.interpolate(
+ pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)
+ pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)
+ new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)
+ checkpoint_model['pos_embed'] = new_pos_embed
+
+
+def flip_padded_sequences(batch, mask):
+ """
+ Flips the valid part of each sequence in a padded batch, keeping pads at the end.
+
+ Args:
+ batch (Tensor): Input tensor of size (B, L).
+ lengths (Tensor, optional): Lengths of size (B,). If None, calc from mask.
+ padding_value (int): Value used for padding.
+
+ Returns:
+ Tensor: The flipped batch.
+ """
+ B, L, D = batch.shape
+ device = batch.device
+
+ # 1. Get Sequence Lengths
+ lengths = mask.sum(dim=1).long()
+
+ # 2. Generate Index Grid
+ # Shape: (L,) -> [0, 1, 2, ..., L-1]
+ range_tensor = torch.arange(L, device=device)
+
+ # Expand to (B, L)
+ # [[0, 1, ...], [0, 1, ...], ...]
+ idx_grid = range_tensor.unsqueeze(0).expand(B, L)
+
+ # 3. Calculate "Inverse" Indices for valid positions
+ # If len=3, indices [0, 1, 2] should become [2, 1, 0]
+ # Formula: flipped_index = (Length - 1) - current_index
+ lens_expanded = lengths.unsqueeze(1)
+ flipped_indices = (lens_expanded - 1) - idx_grid
+
+ # 4. Create the final Gather Indices
+ # We only want to use the flipped indices where the data is valid.
+ # Where it is padding, we keep the original index (so we just gather the 0s back).
+ mask = idx_grid < lens_expanded
+
+ # Use torch.where: if valid, use flipped_indices, else use original idx_grid
+ gather_indices = torch.where(mask, flipped_indices, idx_grid)
+
+ # 5. Gather
+ result = torch.gather(batch, 1, gather_indices.unsqueeze(-1).repeat(1, 1, D))
+
+ return result
+
+
+def cox_ph_loss(hazards, event_times, is_event):
+ # Sort event times and get corresponding indices for sorting other tensors
+ event_times, sorted_idx = event_times.sort(dim=0, descending=True)
+
+
+ # Make gathering robust: if sorted_idx is 1D and hazards/is_event are 2D,
+ # use advanced indexing; otherwise fall back to gather which requires
+ # the index tensor to have the same number of dimensions as input.
+ if sorted_idx.dim() == 1 and hazards.dim() == 2:
+ hazards = hazards[sorted_idx]
+ is_event = is_event[sorted_idx]
+ else:
+ hazards = hazards.gather(0, sorted_idx)
+ is_event = is_event.gather(0, sorted_idx)
+
+ log_cumulative_hazard = torch.logcumsumexp(hazards.float(), dim=0)
+
+ # Calculate losses for all labels simultaneously
+ losses = (hazards - log_cumulative_hazard) * is_event
+ losses = -losses # Negative for maximization
+
+ # Average loss per label
+ label_loss = losses.sum(dim=0) / (is_event.sum(dim=0) + 1e-9) # Avoid division by zero
+
+ # Average across labels
+ total_loss = label_loss.mean()
+
+ return total_loss
+
+
+def c_index_torch(scores, event_times, is_event):
+ return float(concordance_index(event_times, -scores, is_event))
+
+
+
+class CIndex(Metric):
+ def __init__(self, num_classes=6, **kwargs):
+ super().__init__(**kwargs)
+ self.add_state("scores", default=[], dist_reduce_fx="cat")
+ self.add_state("event_time", default=[], dist_reduce_fx="cat")
+ self.add_state("is_event", default=[], dist_reduce_fx="cat")
+ self.num_classes = num_classes
+
+ def update(self, score, t, e) -> None:
+ self.scores.append(score)
+ self.event_time.append(t)
+ self.is_event.append(e)
+
+ def compute(self):
+
+ # parse inputs
+ # Convert to float32 before numpy() since numpy doesn't support BFloat16
+ scores = dim_zero_cat(self.scores).detach().cpu().float().numpy()
+ event_time = dim_zero_cat(self.event_time).detach().cpu().float().numpy()
+ is_event = dim_zero_cat(self.is_event).detach().cpu().float().numpy()
+
+ from lifelines.utils import concordance_index
+ cindex = []
+ for i in range(self.num_classes):
+ try:
+ c = concordance_index(event_time[:,i], -scores[:,i], is_event[:,i])
+ cindex.append(c)
+ except (ZeroDivisionError, ValueError):
+ # Not enough admissible pairs (common during sanity check or with small batches)
+ # Return 0.5 (random predictor) as default
+ cindex.append(0.5)
+ return torch.tensor(cindex)
+
+class AUROC(Metric):
+ def __init__(self, num_classes=6, **kwargs):
+ super().__init__(**kwargs)
+ self.add_state("scores", default=[], dist_reduce_fx="cat")
+ self.add_state("event_time", default=[], dist_reduce_fx="cat")
+ self.add_state("is_event", default=[], dist_reduce_fx="cat")
+ self.num_classes = num_classes
+ self.measure_date = 365 * 6 # at 6 years
+
+ def update(self, score, t, e) -> None:
+ self.scores.append(score)
+ self.event_time.append(t)
+ self.is_event.append(e)
+
+ def compute(self):
+
+ # parse inputs
+ # Convert to float32 before numpy() since numpy doesn't support BFloat16
+ scores = dim_zero_cat(self.scores).detach().cpu().float().numpy()
+ event_time = dim_zero_cat(self.event_time).detach().cpu().float().numpy()
+ is_event = dim_zero_cat(self.is_event).detach().cpu().float().numpy()
+
+ from sklearn.metrics import roc_auc_score, roc_curve
+ # auroc = []
+ # # For each disease, calculate AUROC
+ # for i in range(self.num_classes):
+ # y_true = (event_time[:,i] <= self.measure_date).astype(int)
+ # y_scores = scores[:,i]
+ # try:
+ # c = roc_auc_score(y_true, y_scores)
+ # auroc.append(c)
+ # except (ZeroDivisionError, ValueError):
+ # # Not enough admissible pairs (common during sanity check or with small batches)
+ # # Return 0.5 (random predictor) as default
+ # auroc.append(0.5)
+ # return torch.tensor(auroc)
+ auroc = []
+ # For each disease, calculate AUROC at 6-year follow-up (time-dependent)
+ for i in range(self.num_classes):
+ # Filter out zero times (invalid entries)
+ valid_mask = event_time[:, i] > 0
+ if valid_mask.sum() < 2:
+ auroc.append(0.5)
+ continue
+
+ valid_scores = scores[valid_mask, i]
+ valid_times = event_time[valid_mask, i]
+ valid_events = is_event[valid_mask, i]
+
+ # Time-dependent AUROC at measure_date:
+ # - Samples with event before measure_date: y=1
+ # - Samples with no event and observed until after measure_date: y=0
+ # - Samples with censoring before measure_date: excluded (potentially informative censoring)
+
+ # Consider only samples observed until measure_date
+ observed_mask = valid_times >= self.measure_date
+ # Or event occurred before measure_date
+ event_before_mask = valid_events == 1
+
+ # Use all samples with valid time info for AUROC
+ # y_true: 1 if event before measure_date, 0 otherwise
+ y_true = (valid_events == 1) & (valid_times <= self.measure_date)
+ y_true = y_true.astype(int)
+ y_scores = valid_scores
+
+ try:
+ # Check if there's variation in labels
+ if len(np.unique(y_true)) < 2:
+ auroc.append(0.5)
+ else:
+ c = roc_auc_score(y_true, y_scores)
+ auroc.append(c)
+ except (ZeroDivisionError, ValueError) as e:
+ # Not enough admissible pairs
+ auroc.append(0.5)
+ return torch.tensor(auroc)
+
+
+def get_layer_decay_param_groups(model, base_lr, weight_decay, layer_decay):
+ """
+ Create parameter groups with layer-wise learning rate decay.
+ Args:
+ model: The model whose parameters are grouped.
+ base_lr: Base learning rate.
+ weight_decay: Weight decay for regularization.
+ layer_decay: Layer decay factor (e.g., 0.75).
+ Returns:
+ A list of parameter groups for the optimizer.
+ """
+ param_groups = []
+ num_layers = len(list(model.children())) # Number of layers in the model
+
+ for i, layer in enumerate(model.children()):
+ scale = layer_decay ** (num_layers - i - 1) # Scale learning rate for this layer
+ for param in layer.parameters():
+ if param.requires_grad:
+ param_groups.append({
+ 'params': param,
+ 'lr': base_lr * scale,
+ 'weight_decay': weight_decay
+ })
+
+ return param_groups
+
+class WarmupCosineAnnealingLR(_LRScheduler):
+ def __init__(self, optimizer, warmup_steps, max_steps, eta_min=1e-8, last_epoch=-1):
+ """
+ Step-based Warmup Cosine Annealing Learning Rate Scheduler.
+
+ Args:
+ optimizer: The optimizer for which to schedule the learning rate.
+ warmup_steps: Number of steps for the warmup phase.
+ max_steps: Total number of steps for the scheduler.
+ eta_min: Minimum learning rate at the end of the schedule.
+ last_epoch: The index of the last epoch (default: -1).
+ """
+ self.warmup_steps = warmup_steps
+ self.max_steps = max_steps
+ self.eta_min = eta_min
+ super(WarmupCosineAnnealingLR, self).__init__(optimizer, last_epoch)
+
+ def get_lr(self):
+ if self.last_epoch < self.warmup_steps:
+ # Linear warmup phase
+ return [base_lr * (self.last_epoch + 1) / self.warmup_steps for base_lr in self.base_lrs]
+ else:
+ # Cosine annealing phase
+ progress = (self.last_epoch - self.warmup_steps) / (self.max_steps - self.warmup_steps)
+ return [self.eta_min + (base_lr - self.eta_min) * (1 + math.cos(math.pi * progress)) / 2 for base_lr in self.base_lrs]
\ No newline at end of file
diff --git a/pretrain.py b/pretrain.py
new file mode 100644
index 0000000000000000000000000000000000000000..bb36e51f84dc9084cf07d506e47c7e6224a94a68
--- /dev/null
+++ b/pretrain.py
@@ -0,0 +1,470 @@
+import pytorch_lightning as pl
+from pytorch_lightning.loggers import WandbLogger
+import torch
+import torch.nn as nn
+import logging
+import sys
+import time
+from tqdm import tqdm
+from torch.optim.lr_scheduler import _LRScheduler, CosineAnnealingLR
+import os
+import wandb
+from pytorch_lightning.callbacks import ModelCheckpoint, Callback
+import numpy as np
+import data.data_loader as data_loader
+import yaml
+import math
+import pandas as pd
+import pickle
+
+import models
+
+import random
+import importlib
+import argparse
+from configs.global_cfg import TARGET_RESAMPLE, DATASET_PATH
+
+torch.manual_seed(42)
+torch.cuda.manual_seed(42)
+torch.cuda.manual_seed_all(42)
+torch.backends.cudnn.deterministic = True
+torch.backends.cudnn.benchmark = False
+np.random.seed(42)
+random.seed(42)
+
+
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+
+class WarmupCosineAnnealingLR(_LRScheduler):
+ def __init__(self, optimizer, warmup_epochs, max_epochs, eta_min=1e-8, last_epoch=-1):
+ self.warmup_epochs = warmup_epochs
+ self.max_epochs = max_epochs
+ self.eta_min = eta_min
+ super(WarmupCosineAnnealingLR, self).__init__(optimizer, last_epoch)
+
+ def get_lr(self):
+ if self.last_epoch < self.warmup_epochs:
+ # Linear warmup
+ return [base_lr * (self.last_epoch + 1) / self.warmup_epochs for base_lr in self.base_lrs]
+ else:
+ # Cosine annealing
+ progress = (self.last_epoch - self.warmup_epochs) / (self.max_epochs - self.warmup_epochs)
+ return [self.eta_min + (base_lr - self.eta_min) * (1 + math.cos(math.pi * progress)) / 2 for base_lr in self.base_lrs]
+
+
+class PretrainDataModule(pl.LightningDataModule):
+ def __init__(self,
+ data_root,
+ batch_size_t,
+ transforms_t,
+ num_workers,
+ proportion_t,
+ num_classes=5,
+ splits_set=None,
+ modalities=["EEG"],
+ sig_len_target=60
+ ):
+ super().__init__()
+ self.data_root = data_root
+ self.transforms_t = transforms_t
+ self.batch_size_t = batch_size_t
+ self.num_workers = num_workers
+ self.proportion_t = proportion_t
+ self.num_classes = num_classes
+ self.splits_set = splits_set
+ self.modalities = modalities
+ self.sig_len_target = sig_len_target
+
+ def setup(self, stage=None):
+ # Split data into train and validation sets
+ # all_data_list = os.listdir(self.video_path)
+
+ self.train_data_list = self.splits_set['train']
+
+ print("_"*50)
+ print("Number of training subjects: ", len(self.train_data_list))
+
+ self.train_loader = data_loader.build_loader(
+ self.data_root, self.train_data_list,
+ batch_size=self.batch_size_t, shuffle=True,
+ transforms=self.transforms_t, sampler=None,
+ num_workers=self.num_workers, proportion=self.proportion_t,
+ split='train', pretrain_micro=True,
+ num_classes=self.num_classes, modalities=self.modalities,
+ sig_len_target=self.sig_len_target
+ )
+
+ print("Loaders are ready")
+ print("Length of train_loader: ", len(self.train_loader))
+
+ def train_dataloader(self):
+ return self.train_loader
+
+
+
+class ConvMAE1d_Pretrain(pl.LightningModule):
+ def __init__(self,
+ cfg,
+ ):
+ super().__init__()
+ self.save_hyperparameters()
+ self.cfg = cfg
+ self.num_classes = self.cfg["num_classes"]
+ self.modalities = self.cfg["modalities"]
+ self.num_experts = self.cfg["num_experts"]
+ self.num_experts_per = self.cfg["num_experts_per"]
+ self.sig_len = self.cfg['sig_len_target'] * TARGET_RESAMPLE
+ self.use_shared = self.cfg["use_shared"]
+ self.use_moe = self.cfg["use_moe"]
+ self.use_revin = self.cfg["use_revin"]
+ self.patch_size = self.cfg["patch_size"]
+ self.loss_weights = self.cfg["loss_weights"]
+
+ kwargs = {'mask_ratio': cfg.get('mask_ratio', 0.5)}
+
+ self.model = models.__dict__[self.cfg["model_name"]](modalities=self.modalities,
+ num_experts=self.num_experts,
+ num_experts_per=self.num_experts_per,
+ sig_len=self.sig_len,
+ use_shared=self.use_shared,
+ use_moe=self.use_moe,
+ use_revin=self.use_revin,
+ patch_size=self.patch_size,
+ contrastive_training=(self.loss_weights['contrastive'] > 0.0),
+ koleo_training=(self.loss_weights['koleo'] > 0.0),
+ **kwargs
+ )
+
+ if self.cfg["loss"] == 'MSE':
+ self.criterion = nn.MSELoss()
+ elif self.cfg["loss"] == 'MAE':
+ self.criterion = nn.L1Loss()
+
+
+
+ print(self.model)
+
+
+ def forward(self, s) :
+ return self.model(s)
+
+ def training_step(self, batch, batch_idx):
+ inputs = batch
+
+ for key in inputs.keys():
+ inputs[key] = inputs[key].to(self.device, non_blocking=True)
+
+ losses, moe_loss, ortho_loss, contr_loss, koleo_loss, _, _, _ = self(inputs)
+
+ self.log('learning_rate', self.trainer.optimizers[0].param_groups[0]['lr'], on_step=True, on_epoch=True, sync_dist=True)
+ self.log('MoE_load_balancing_loss', moe_loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True)
+
+
+ loss = 0.0
+ for m in inputs.keys():
+ self.log(f'train_loss_{m}', losses[m], on_step=True, on_epoch=True, sync_dist=True, prog_bar=True)
+ loss += losses[m]
+ loss = loss / len(inputs.keys()) * self.loss_weights['mae']
+
+ loss += self.loss_weights['moe'] * moe_loss
+
+ # self.log('Orthogonality loss', ortho_loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True)
+ loss += self.loss_weights['ortho'] * ortho_loss
+
+ self.log('Contrastive loss', contr_loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True)
+ loss += self.loss_weights['contrastive'] * contr_loss
+
+ self.log('KoLeo loss', koleo_loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True)
+ loss += self.loss_weights['koleo'] *koleo_loss # koleo_loss is already weighted by self.koleo_weight in the model
+
+
+ self.log('train_loss', loss, on_step=True, on_epoch=True, sync_dist=True, prog_bar=True)
+
+ return loss
+
+ def configure_optimizers(self):
+
+ weight_decay = float(self.cfg["weight_decay"]) if hasattr(self.cfg, 'weight_decay') else 0.05
+ optimizer = getattr(torch.optim, self.cfg["optimizer_name"])(
+ filter(lambda p: p.requires_grad, self.parameters()), lr=self.cfg["lr"], weight_decay=weight_decay
+ # self.parameters(), lr=self.hparams.lr
+ )
+
+ if self.cfg["scheduler_name"] == 'CosineAnnealingLR':
+ steps_per_epoch = len(self.trainer.datamodule.train_dataloader())
+ max_steps = int(steps_per_epoch * self.cfg["num_epochs"] / len(self.cfg["gpus"])) + 1
+
+ return{
+ "optimizer": optimizer,
+ "lr_scheduler": {
+ "scheduler": CosineAnnealingLR(optimizer, T_max=max_steps, eta_min=1e-8),
+ "interval": "step",
+ "frequency": 1
+ }
+ }
+
+ elif self.hparams.scheduler_name == 'WarmupCosineAnnealingLR':
+ steps_per_epoch = len(self.trainer.datamodule.train_dataloader())
+ max_steps = int(steps_per_epoch * self.hparams.num_epochs / len(self.cfg['gpus'])) + 1
+ warmup_steps = int(max_steps * 0.1) # 10% of total steps for warmup
+
+ scheduler = WarmupCosineAnnealingLR(
+ optimizer,
+ warmup_steps=warmup_steps, # Number of warmup steps
+ max_steps=max_steps,
+ eta_min=1e-8
+ )
+
+ return {
+ "optimizer": optimizer,
+ "lr_scheduler": {
+ "scheduler": scheduler,
+ "interval": "step",
+ "frequency": 1
+ }
+ }
+
+ else:
+ return optimizer
+
+import yaml
+def get_all_configs_from_yaml(file_path):
+ with open(file_path, 'r') as file:
+ configs = yaml.safe_load(file)
+ return configs
+
+def main():
+
+ # Parse command-line arguments
+ parser = argparse.ArgumentParser(description="Pretrain singal convMAE Model")
+ parser.add_argument('--config', type=str, required=True, help="Name of the configuration file (without .py)")
+ parser.add_argument('--no_wandb', action='store_true', default=False, help="Disable Weights and Biases logging")
+
+ args = parser.parse_args()
+
+ all_configs = get_all_configs_from_yaml(os.path.join("configs", args.config + ".yaml"))
+ print(all_configs)
+
+
+
+ # Add transforms dynamically if needed
+ # args.transforms = get_transforms()
+ # print(args)
+
+ print("Starting Experiment: ", all_configs['experiment_name'])
+
+ config_save_path = os.path.join(all_configs['config_save_path'], all_configs['experiment_name'])
+
+ os.makedirs(config_save_path, exist_ok=True)
+ with open(os.path.join(config_save_path, 'config.yaml'), 'w') as file:
+ yaml.dump(all_configs, file)
+
+
+
+
+ # Set data paths
+ # data_root("datasets") directory should be in the same directory as this script
+ data_root = os.path.join(BASE_DIR, all_configs['data_root'])
+
+
+ # Load data
+ print("Loading Data")
+ splits_set = dict()
+ splits_set['train'] = []
+ datasets = all_configs.get('datasets', ['phy'])
+
+ # for sig_path, ann_path in zip(all_configs['signals_path'], all_configs['labels_path']):
+ for ds in datasets:
+ # Use Physionet 2018 dataset
+ if ds == 'phy-tr':
+ sample_modality = all_configs.get('modalities', ['EEG'])[0]
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ all_subjects = [sub for sub in sig_info['sig_info'].keys()]
+ all_subjects.sort()
+
+ # train_files = np.load(os.path.join("data", "physionet_2018_folds.npy"), allow_pickle=True)
+
+ # new_train_files = []
+ # for fold_id in range(1):
+ # fnames = [f for f in train_files[fold_id] if f in all_subjects]
+ # new_train_files.append(fnames)
+
+ # all_subjects = list(set(all_subjects) - set(new_train_files[0])) # Fold 0
+ splits_set['train'].extend([('phy-tr', f) for f in all_subjects])
+ elif ds in ['phy-te', 'mros1-val', 'mros1-te','mros2-val','mros2-te','mesa-val','mesa-te']:
+ sample_modality = all_configs.get('modalities', ['EEG'])[0]
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ all_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+ splits_set['train'].extend([(ds, f) for f in all_subjects])
+
+
+ elif ds == 'shhs1':
+ sample_modality = all_configs.get('modalities', ['EEG'])[0]
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'train', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ all_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ def get_shhs_lists(shhs_split_file):
+ ids = pd.read_csv(os.path.join("data","shhs_meta_data", shhs_split_file), header=None, names=['a'])
+ ids = ids['a'].values.tolist()
+ list_files = ["shhs1-20"+id[11:15] for id in ids]
+ return list_files
+
+ list_files_val = get_shhs_lists("eval_list.txt")
+ list_files_test = get_shhs_lists("test_list.txt")
+
+ all_subjects = set(all_subjects) - set(list_files_val) - set(list_files_test)
+ all_subjects = sorted(list(all_subjects))
+
+ splits_set['train'].extend([('shhs1', f) for f in all_subjects])
+
+
+ elif ds in ['kiss','kvss','shhs2', 'mros1','mros2','mesa']:
+ sample_modality = all_configs.get('modalities', ['EEG'])[0]
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'train', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ all_subjects = sorted([sub for sub in sig_info['sig_info'].keys()])
+
+ # all_subjects = [sub for sub in all_subjects if 'NX' in sub]
+ splits_set['train'].extend([(ds, f) for f in all_subjects])
+
+ print(f"Number of subjects in {ds}: ", len(all_subjects))
+
+ # splits_set['train'] = splits_set['train'][:20]
+ print("Number of train subjects: ", len(splits_set['train']))
+ # pd.DataFrame(splits_set['train']).to_csv('train_subjects.csv', index=False, header=False)
+
+
+ all_configs['sig_len_target'] = all_configs.get('sig_len_target', 60)
+ all_configs['patch_size'] = all_configs.get('patch_size', 10)
+ all_configs['loss_weights'] = all_configs.get('loss_weights', {'mae': 1.0,'moe': 0.001,'ortho': 0.0,'contrastive': 0.0, 'koleo': 0.0})
+ all_configs['use_shared'] = all_configs.get('use_shared', True)
+ all_configs['use_moe'] = all_configs.get('use_moe', True)
+ all_configs['use_revin'] = all_configs.get('use_revin', False)
+ all_configs['loss'] = all_configs.get('loss', 'MSE')
+
+
+ data_module = PretrainDataModule(
+ data_root = all_configs['data_root'],
+ transforms_t = None,
+ batch_size_t = all_configs['batch_size_t'],
+ num_workers = all_configs['num_workers'],
+ proportion_t = all_configs['proportion_t'],
+ num_classes = all_configs['num_classes'],
+ splits_set = splits_set,
+ modalities = all_configs['modalities'],
+ sig_len_target = all_configs['sig_len_target']
+ )
+
+ print("Data Loaded")
+
+
+ print("Model Loading ...")
+
+ if all_configs['pretrained']:
+ model = ConvMAE1d_Pretrain.load_from_checkpoint(
+ all_configs['pretrained'],
+ strict=False,
+ cfg=all_configs,
+ # **kwargs
+ )
+ else:
+ model = ConvMAE1d_Pretrain(
+ all_configs,
+ # **kwargs
+ )
+
+ print("Model Loaded")
+
+
+
+ # checkpoint_callback = ModelCheckpoint(
+ # monitor='train_loss',
+ # mode='min',
+ # save_top_k=1,
+ # dirpath=all_configs['ckpt_save_path'],
+ # filename=all_configs['experiment_name'] + '-{epoch:02d}-{train_loss:.2f}',
+ # verbose=True
+ # )
+
+ checkpoint_callback = ModelCheckpoint(
+ dirpath=all_configs['ckpt_save_path'],
+ filename=all_configs['experiment_name'] + '-{step:05d}-{train_loss:.2f}',
+ every_n_train_steps=5000, # Save every 5000 steps
+ save_top_k=-1, # Set to -1 to keep all checkpoints, or 1 for only the latest
+ )
+
+ class SaveLastEpochCheckpoint(Callback):
+ def on_train_end(self, trainer, pl_module):
+ # 마지막 epoch의 체크포인트 저장
+ final_checkpoint_path = f"{all_configs['ckpt_save_path']}/{all_configs['experiment_name']}-final.ckpt"
+ trainer.save_checkpoint(final_checkpoint_path)
+ print(f"Final checkpoint saved at {final_checkpoint_path}")
+
+ # if previous_run_id is not None, load the best model from the previous run
+ previous_run_id = all_configs['previous_run_id']
+
+ if args.no_wandb:
+ wandb_logger = None
+ elif previous_run_id:
+ wandb_logger = WandbLogger(
+ project=all_configs['project_name'],
+ entity='gundo0102',
+ name=all_configs['experiment_name'],
+ config=all_configs,
+ resume='must', # 이전 실험을 이어서 진행
+ id=previous_run_id # 이전 실험의 run_id
+ )
+ else:
+ wandb_logger = WandbLogger(
+ project=all_configs['project_name'],
+ entity='gundo0102',
+ name=all_configs['experiment_name'],
+ config=all_configs
+ )
+
+ trainer = pl.Trainer(
+ devices=all_configs['gpus'],
+ max_epochs=all_configs['num_epochs'],
+ accelerator='gpu',
+ logger=wandb_logger,
+ precision = 'bf16-mixed',
+ callbacks=[checkpoint_callback, SaveLastEpochCheckpoint()],
+ # strategy= 'ddp', #'ddp_find_unused_parameters_true',
+ strategy= 'ddp_find_unused_parameters_true',
+ accumulate_grad_batches=all_configs['accumulate_grad_batches'],
+ # No sanity check
+ num_sanity_val_steps=0,
+ # val_check_interval=10,
+ # check_val_every_n_epoch=1,
+ )
+ if all_configs['previous_checkpoint']:
+ trainer.fit(model, datamodule=data_module, ckpt_path=all_configs['previous_checkpoint'])
+ else:
+ trainer.fit(model, datamodule=data_module)
+
+ wandb_logger.experiment.finish()
+
+
+if __name__ == '__main__':
+ main()
+
+
diff --git a/pretrain_seq.py b/pretrain_seq.py
new file mode 100644
index 0000000000000000000000000000000000000000..7bf9fb3598f1942f35401906ed6db69d27fb658d
--- /dev/null
+++ b/pretrain_seq.py
@@ -0,0 +1,759 @@
+import pytorch_lightning as pl
+from pytorch_lightning.loggers import WandbLogger
+import torch
+import torch.nn as nn
+import logging
+import sys
+import time
+from tqdm import tqdm
+from torch.optim.lr_scheduler import _LRScheduler, CosineAnnealingLR
+import os
+from sklearn.metrics import classification_report
+import wandb
+from pytorch_lightning.callbacks import ModelCheckpoint, Callback
+import numpy as np
+import data.data_augments as data_augments
+import data.data_loader as data_loader
+import yaml
+import math
+import pandas as pd
+import pickle
+# from models.movinets import build_MoViNet
+#os.environ["WANDB_MODE"]="disabled"
+
+
+# import models_convmae1d
+import models
+
+import random
+import argparse
+from configs.global_cfg import TARGET_RESAMPLE, DATASET_PATH
+
+torch.manual_seed(42)
+torch.cuda.manual_seed(42)
+torch.cuda.manual_seed_all(42)
+torch.backends.cudnn.deterministic = True
+torch.backends.cudnn.benchmark = False
+np.random.seed(42)
+random.seed(42)
+
+
+from torch.optim.lr_scheduler import LambdaLR
+
+BASE_DIR = os.path.dirname(os.path.abspath(__file__))
+
+def get_layer_decay_param_groups(model, base_lr, weight_decay, layer_decay):
+ """
+ Create parameter groups with layer-wise learning rate decay.
+ Args:
+ model: The model whose parameters are grouped.
+ base_lr: Base learning rate.
+ weight_decay: Weight decay for regularization.
+ layer_decay: Layer decay factor (e.g., 0.75).
+ Returns:
+ A list of parameter groups for the optimizer.
+ """
+ param_groups = []
+ layers = list(model.children())
+ num_layers = len(layers)
+
+ # We use named_parameters to filter by name (e.g., A_log, dt, bias)
+ # But we need to map them back to their layer index for LR decay.
+ for i, layer in enumerate(layers):
+ layer_scale = layer_decay ** (num_layers - i - 1)
+ curr_lr = base_lr * layer_scale
+
+ # We split parameters in each layer into 'decay' and 'no_decay'
+ params_to_decay = []
+ params_no_decay = []
+
+ for name, param in layer.named_parameters():
+ if not param.requires_grad:
+ continue
+
+ # Check if it's a Mamba-specific parameter or a standard "no-decay" candidate
+ # Common Mamba names: A_log, D, dt_proj, x_proj, in_proj, conv1d
+ # Standard no-decay: bias, norm weights
+ is_ssm_param = any(ssm_name in name for ssm_name in ['A_log', 'D', 'dt', 'B', 'C'])
+ is_bias_or_norm = name.endswith("bias") or "norm" in name
+
+ if is_ssm_param or is_bias_or_norm:
+ params_no_decay.append(param)
+ else:
+ params_to_decay.append(param)
+
+ # Add groups for this specific layer
+ if params_to_decay:
+ param_groups.append({
+ "params": params_to_decay,
+ "lr": curr_lr,
+ "weight_decay": weight_decay,
+ })
+ if params_no_decay:
+ param_groups.append({
+ "params": params_no_decay,
+ "lr": curr_lr,
+ "weight_decay": 0.0,
+ })
+
+ return param_groups
+
+
+class WarmupCosineAnnealingLR(_LRScheduler):
+ def __init__(self, optimizer, warmup_epochs, max_epochs, eta_min=1e-8, last_epoch=-1):
+ self.warmup_epochs = warmup_epochs
+ self.max_epochs = max_epochs
+ self.eta_min = eta_min
+ super(WarmupCosineAnnealingLR, self).__init__(optimizer, last_epoch)
+
+ def get_lr(self):
+ if self.last_epoch < self.warmup_epochs:
+ # Linear warmup
+ return [base_lr * (self.last_epoch + 1) / self.warmup_epochs for base_lr in self.base_lrs]
+ else:
+ # Cosine annealing
+ progress = (self.last_epoch - self.warmup_epochs) / (self.max_epochs - self.warmup_epochs)
+ return [self.eta_min + (base_lr - self.eta_min) * (1 + math.cos(math.pi * progress)) / 2 for base_lr in self.base_lrs]
+
+
+class PretrainDataModule(pl.LightningDataModule):
+ def __init__(self,
+ data_root,
+ batch_size_t,
+ transforms_t,
+ num_workers,
+ proportion_t,
+ num_classes=5,
+ splits_set=None,
+ modalities=["EEG"],
+ sig_len_target=30,
+ seq_truncate=True,
+ dual_views=False
+ ):
+ super().__init__()
+ self.data_root = data_root
+ self.transforms_t = transforms_t
+ self.batch_size_t = batch_size_t
+ self.num_workers = num_workers
+ self.proportion_t = proportion_t
+ self.num_classes = num_classes
+ self.splits_set = splits_set
+ self.modalities = modalities
+ self.sig_len_target = sig_len_target
+ self.seq_truncate = seq_truncate
+ self.dual_views = dual_views
+
+ def setup(self, stage=None):
+ # Split data into train and validation sets
+ # all_data_list = os.listdir(self.video_path)
+
+ self.train_data_list = self.splits_set['train']
+
+ print("_"*50)
+ print("Number of training subjects: ", len(self.train_data_list))
+
+ is_distributed = self.trainer.num_devices > 1 and self.trainer.strategy.root_device.type == "cuda"
+
+ sampler = None
+
+ if is_distributed and not self.dual_views:
+ sampler = 'distributed'
+
+ self.train_loader = data_loader.build_loader(
+ self.data_root, self.train_data_list,
+ batch_size=self.batch_size_t, shuffle=False,
+ transforms=self.transforms_t, sampler=sampler,
+ num_workers=self.num_workers, proportion=self.proportion_t,
+ split='train',
+ num_classes=self.num_classes, modalities=self.modalities,
+ sig_len_target=self.sig_len_target,
+ full_night=True, pretrain_macro=True, seq_truncate=self.seq_truncate, dual_views=self.dual_views)
+
+ print("Train loader ready")
+ print("Length of train_loader: ", len(self.train_loader))
+
+ def train_dataloader(self):
+ return self.train_loader
+
+
+
+class ConvMAE1d_PretrainSeq(pl.LightningModule):
+ def __init__(self,
+ model_name='convmae1d_multi',
+ num_classes=5,
+ modalities=["EEG"],
+ num_experts=4,
+ num_experts_per=2,
+ sig_len=6000,
+ use_shared=True,
+ use_moe=True,
+ use_revin=False,
+ full_finetune=False,
+ optimizer_name='AdamW',
+ lr=0.0005,
+ weight_decay=0.05,
+ scheduler_name='CosineAnnealingLR',
+ num_epochs=10,
+ loss='MSE',
+ patch_size=10,
+ cfg=None
+ ):
+ super().__init__()
+ self.cfg = cfg
+ self.save_hyperparameters()
+ single_channel = True
+ self.num_classes = num_classes
+ self.modalities = modalities
+ self.num_experts = num_experts
+ self.num_experts_per = num_experts_per
+ self.sig_len = sig_len
+ self.use_shared = use_shared
+ self.use_moe = use_moe
+ self.use_revin = use_revin
+ self.patch_size = patch_size
+ self.full_finetune = full_finetune
+ self.simclr = cfg.get('simclr', False) if cfg is not None else False
+ self.dino = cfg.get('dino', False) if cfg is not None else False
+
+ kwargs = {'demo_keys': cfg.get('demo_keys', ['age','bmi','sex'])} if cfg is not None else {}
+ kwargs['cycle_len'] = cfg.get('cycle_len', 180)
+ kwargs['use_transformer'] = cfg.get('use_transformer', False)
+ kwargs['bidi'] = False if kwargs['use_transformer'] else cfg.get('bidi', True)
+ kwargs['simclr'] = self.simclr
+ kwargs['dino'] = self.dino
+
+ self.model = models.__dict__[model_name](modalities=self.modalities,
+ num_experts=self.num_experts,
+ num_experts_per=self.num_experts_per,
+ sig_len=self.sig_len,
+ use_shared=self.use_shared,
+ use_moe=self.use_moe,
+ use_revin=self.use_revin,
+ # ft_task=ft_task,
+ patch_size=self.patch_size,
+ num_classes=self.num_classes,
+ pretrain=True,
+ **kwargs)
+
+ def train(self, mode: bool = True):
+ """
+ Override the default .train() method to keep the encoder in eval mode.
+ """
+ # Set the train mode for the whole model (including head and encoder)
+ super().train(mode)
+
+ # Now, *force* the encoder back to eval mode
+ if not self.full_finetune:
+ self.model.encoder.eval()
+ self.model.fuser.eval()
+
+ def forward(self, s, mask=None, demo=None):
+ return self.model(s, mask=mask, demo=demo)
+
+ def training_step(self, batch, batch_idx):
+ inputs, labels, mask, demo, pids = batch
+
+ # signals = inputs["EEG"].to(self.device, non_blocking=True)
+
+ if self.simclr or self.dino:
+ inputs1, inputs2 = inputs
+ for key in inputs1.keys():
+ inputs1[key] = inputs1[key].to(self.device, non_blocking=True)
+ inputs2[key] = inputs2[key].to(self.device, non_blocking=True)
+ inputs = (inputs1, inputs2)
+ else:
+ for key in inputs.keys():
+ inputs[key] = inputs[key].to(self.device, non_blocking=True)
+
+ for key in demo.keys():
+ demo[key] = demo[key].to(self.device, non_blocking=True)
+
+ if (mask is not None) and (mask.numel() > 0):
+ mask = mask.to(self.device, non_blocking=True)
+
+ loss = self(inputs, mask=mask, demo=demo)
+
+
+ # print("loss", loss.item())
+ # print("Demographics: ", demo)
+ if loss.abs() > 1e4:
+ print("PIDs: ", pids)
+ # exit(0)
+
+ self.log('learning_rate', self.trainer.optimizers[0].param_groups[0]['lr'], on_step=True, on_epoch=True, sync_dist=True)
+ self.log('train_loss', loss, on_step=True, on_epoch=True, sync_dist=True)
+ # wandb.log({"train_loss_every_step": loss.item()})
+
+ return loss
+
+ def load_pretrained(self, ckpt):
+ # Load the pretrained model checkpoint
+ checkpoint = torch.load(ckpt, map_location=self.device, weights_only=False)
+ new_state_dict = {}
+ for k in self.model.state_dict().keys():
+ if 'pos_embed' in k:
+ print("Skipping key (pos_embed): ", k)
+ continue
+ if k in checkpoint['state_dict']:
+ # print("Matching key: ", k)
+ new_state_dict[k] = checkpoint['state_dict'][k]
+ else:
+ # print(f"Missing key (Only in the current model), tries to find model.{k}")
+ if f"model.{k}" in checkpoint['state_dict']:
+ # print("Matching key, starts with 'model.' in the checkpoint, delete 'model. prefix': ", k)
+ new_state_dict[k] = checkpoint['state_dict'][f"model.{k}"] # Remove 'model.' prefix
+ else:
+ print("Missing key (Only in the current model): ", k)
+
+
+ for k in checkpoint['state_dict'].keys():
+ if not (k.startswith('model.') and k[6:] in self.model.state_dict()) and not k in self.model.state_dict():
+ print("Missing key (Only in the Checkpoint): ", k)
+
+ msg = self.model.load_state_dict(new_state_dict, strict=False)
+ # Initialize teacher weights for DINO if applicable
+ if self.dino:
+ self.model.init_teacher()
+ print(f"Loaded pretrained model from {ckpt}")
+ print(msg)
+
+ def configure_optimizers(self):
+ # Base learning rate and weight decay
+ base_lr = self.hparams.lr
+ weight_decay = float(self.hparams.weight_decay) if hasattr(self.hparams, 'weight_decay') else 0.05
+ layer_decay = float(self.hparams.layer_decay) if hasattr(self.hparams, 'layer_decay') else 1.0
+ if not self.full_finetune:
+ for param in self.model.encoder.parameters():
+ param.requires_grad = False
+ if self.use_revin:
+ for param in self.model.revin.parameters():
+ param.requires_grad = False
+ if self.use_shared:
+ for param in self.model.fuser.parameters():
+ param.requires_grad = False
+
+
+ # Create parameter groups with layer-wise learning rate decay
+ param_groups = get_layer_decay_param_groups(self.model, base_lr, weight_decay, layer_decay)
+ optimizer = getattr(torch.optim, self.hparams.optimizer_name)(param_groups)
+
+ if self.hparams.scheduler_name == 'CosineAnnealingLR':
+ steps_per_epoch = len(self.trainer.datamodule.train_dataloader())
+ max_steps = int(steps_per_epoch * self.hparams.num_epochs) + 1
+ print("max steps", max_steps, steps_per_epoch, self.hparams.num_epochs)
+ return {
+ "optimizer": optimizer,
+ "lr_scheduler": {
+ "scheduler": CosineAnnealingLR(optimizer, T_max=max_steps, eta_min=1e-8),
+ "interval": "step",
+ "frequency": 1
+ }
+ }
+ elif self.hparams.scheduler_name == 'WarmupCosineAnnealingLR':
+ steps_per_epoch = len(self.trainer.datamodule.train_dataloader())
+ max_steps = steps_per_epoch * self.hparams.num_epochs
+ warmup_steps = int(max_steps * 0.1) # 10% of total steps for warmup
+
+ scheduler = WarmupCosineAnnealingLR(
+ optimizer,
+ warmup_epochs=warmup_steps, # Number of warmup steps
+ max_epochs=max_steps,
+ eta_min=1e-8
+ )
+
+ return {
+ "optimizer": optimizer,
+ "lr_scheduler": {
+ "scheduler": scheduler,
+ "interval": "step",
+ "frequency": 1
+ }
+ }
+
+ else:
+ return optimizer
+
+import yaml
+def get_all_configs_from_yaml(file_path):
+ with open(file_path, 'r') as file:
+ configs = yaml.safe_load(file)
+ return configs
+
+def main():
+
+ # Parse command-line arguments
+ parser = argparse.ArgumentParser(description="Pretrain singal convMAE Model")
+ parser.add_argument('--config', type=str, required=True, help="Name of the configuration file (without .py)")
+ parser.add_argument('--no_wandb', action='store_true', default=False, help="Disable Weights and Biases logging")
+
+ args = parser.parse_args()
+
+ all_configs = get_all_configs_from_yaml(os.path.join("configs", args.config + ".yaml"))
+ print(all_configs)
+
+
+ print("Starting Experiment: ", all_configs['experiment_name'])
+
+ config_save_path = os.path.join(all_configs['config_save_path'], all_configs['experiment_name'])
+
+ os.makedirs(config_save_path, exist_ok=True)
+ with open(os.path.join(config_save_path, 'config.yaml'), 'w') as file:
+ yaml.dump(all_configs, file)
+
+
+ # Set data paths
+ data_root = os.path.join(BASE_DIR, all_configs['data_root'])
+
+
+ # Load data
+ print("Loading Data")
+ splits_set = dict()
+ splits_set['train'] = []
+ datasets = all_configs.get('datasets', ['phy'])
+
+ for ds in datasets:
+ # Use Physionet 2018 dataset
+ if ds == 'phy-tr':
+ sample_modality = all_configs.get('modalities', ['EEG'])[0]
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ all_subjects = [sub for sub in sig_info['sig_info'].keys()]
+ all_subjects.sort()
+
+ train_files = np.load(os.path.join("data", "physionet_2018_folds.npy"), allow_pickle=True)
+
+ new_train_files = []
+ for fold_id in range(1):
+ fnames = [f for f in train_files[fold_id] if f in all_subjects]
+ new_train_files.append(fnames)
+
+ all_subjects = list(set(all_subjects) - set(new_train_files[0])) # Fold 0
+ splits_set['train'].extend([('phy-tr', f) for f in all_subjects])
+
+ elif ds in ['phy-te', 'mros1-val', 'mros1-te','mros2-val','mros2-te','mesa-val','mesa-te']:
+ sample_modality = all_configs.get('modalities', ['EEG'])[0]
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ all_subjects = [sub for sub in sig_info['sig_info'].keys()]
+ all_subjects.sort()
+
+ train_files = np.load(os.path.join("data", "physionet_2018_folds.npy"), allow_pickle=True)
+
+ splits_set['train'].extend([(ds, f) for f in all_subjects])
+
+ elif ds == 'shhs1':
+ sample_modality = all_configs.get('modalities', ['EEG'])[0]
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'train', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ all_subjects = [sub for sub in sig_info['sig_info'].keys()]
+ all_subjects.sort()
+
+ def get_shhs_lists(shhs_split_file):
+ ids = pd.read_csv(os.path.join("data","shhs_meta_data", shhs_split_file), header=None, names=['a'])
+ ids = ids['a'].values.tolist()
+ list_files = ["shhs1-20"+id[11:15] for id in ids]
+ return list_files
+
+ list_files_val = get_shhs_lists("eval_list.txt")
+ list_files_test = get_shhs_lists("test_list.txt")
+
+ all_subjects = set(all_subjects) - set(list_files_val) - set(list_files_test)
+ all_subjects = list(all_subjects)
+ all_subjects.sort()
+
+ splits_set['train'].extend([('shhs1', f) for f in all_subjects])
+
+
+ elif ds in ['shhs2', 'kiss','kvss','mros1','mros2','mesa']:
+ sample_modality = all_configs.get('modalities', ['EEG'])[0]
+ sample_dir = os.path.join(data_root, DATASET_PATH[ds], 'train', sample_modality)
+ chns = [f.split('.')[0] for f in os.listdir(sample_dir) if f.endswith('mmap')]
+ info_path = os.path.join(sample_dir, f'{chns[0]}.pickle')
+ with open(info_path, 'rb') as f:
+ sig_info = pickle.load(f)
+
+ all_subjects = [sub for sub in sig_info['sig_info'].keys()]
+ all_subjects.sort()
+
+ splits_set['train'].extend([(ds, f) for f in all_subjects])
+
+
+ # splits_set['train'] = splits_set['train'][:20]
+ print("Number of train subjects: ", len(splits_set['train']))
+
+ if all_configs['pretrain_checkpoint']:
+ pretrain_exp_name = all_configs['pretrain_checkpoint'].split('-')[0]
+ pretrain_config = get_all_configs_from_yaml(os.path.join("experiments", pretrain_exp_name, "config.yaml"))
+ use_shared = pretrain_config.get('use_shared', all_configs.get('use_shared', True))
+ use_moe = pretrain_config.get('use_moe', all_configs.get('use_moe', True))
+ else:
+ use_shared = all_configs.get('use_shared', True)
+ use_moe = all_configs.get('use_moe', True)
+
+
+ sig_len_target = all_configs.get('sig_len_target', 60)
+ data_module = PretrainDataModule(
+ data_root = all_configs['data_root'],
+ transforms_t = None,
+ batch_size_t = all_configs['batch_size_t'],
+ num_workers = all_configs['num_workers'],
+ proportion_t = all_configs['proportion_t'],
+ num_classes = all_configs['num_classes'],
+ splits_set = splits_set,
+ modalities = all_configs['modalities'],
+ sig_len_target = sig_len_target,
+ seq_truncate = all_configs.get('seq_truncate', True),
+ dual_views = all_configs.get('simclr', False) or all_configs.get('dino', False)
+ )
+
+ print("Data Loaded")
+
+
+ print("Model Loading ...")
+ kwargs = {
+ 'model_name': all_configs['model_name'],
+ 'num_classes': all_configs['num_classes'],
+ 'modalities': all_configs['modalities'],
+ 'num_experts': all_configs['num_experts'],
+ 'num_experts_per': all_configs['num_experts_per'],
+ 'sig_len': sig_len_target * TARGET_RESAMPLE,
+ 'use_shared': use_shared,
+ 'use_moe': use_moe,
+ 'full_finetune': all_configs.get('full_finetune', False),
+ 'optimizer_name': all_configs['optimizer_name'],
+ 'lr': all_configs['lr'],
+ 'weight_decay': all_configs.get('weight_decay', 0.05),
+ 'scheduler_name': all_configs['scheduler_name'],
+ 'num_epochs': all_configs['num_epochs'],
+ 'use_revin': all_configs.get('use_revin', False),
+ 'patch_size': all_configs.get('patch_size', 10),
+
+ }
+
+ model = ConvMAE1d_PretrainSeq(
+ **kwargs,
+ cfg=all_configs
+ )
+
+ if all_configs['pretrain_checkpoint']:
+ ckpt_file = os.path.join('experiments', all_configs['pretrain_checkpoint'])
+ model.load_pretrained(ckpt_file)
+
+ print("Model Loaded")
+
+ checkpoint_callback = ModelCheckpoint(
+ monitor='train_loss',
+ mode='min',
+ save_top_k=1,
+ dirpath=all_configs['ckpt_save_path'],
+ filename=all_configs['experiment_name'] + '-{epoch:02d}-{train_loss:.2f}',
+ verbose=True
+ )
+ class SaveLastEpochCheckpoint(Callback):
+ def on_train_end(self, trainer, pl_module):
+ # 마지막 epoch의 체크포인트 저장
+ final_checkpoint_path = f"{all_configs['ckpt_save_path']}/{all_configs['experiment_name']}-final.ckpt"
+ trainer.save_checkpoint(final_checkpoint_path)
+ print(f"Final checkpoint saved at {final_checkpoint_path}")
+
+ class ReshuffleDatasetCallback(pl.Callback):
+ def on_train_epoch_start(self, trainer, pl_module):
+ # Reshuffle the dataset at the start of each epoch
+ if hasattr(trainer.datamodule, 'train_loader') and hasattr(trainer.datamodule.train_loader.dataset, 'reshuffle_full_night_index'):
+ trainer.datamodule.train_loader.dataset.reshuffle_full_night_index()
+ print(f"Reshuffled full night index for epoch {trainer.current_epoch}")
+
+ class MemoryMonitorCallback(pl.Callback):
+ def __init__(self, log_every_n_steps=10, monitor_layers=None):
+ super().__init__()
+ self.log_every_n_steps = log_every_n_steps
+ self.monitor_layers = monitor_layers or {}
+ self.hooks = []
+ self.layer_memory_before = {} # Store memory BEFORE each layer
+ self.layer_memory = {}
+ self.layer_memory_bwd = {}
+ self.layer_memory_after_fwd = {}
+ self.layer_memory_bwd_only = {}
+ self.layer_memory_before_bwd = {}
+
+ def on_train_start(self, trainer, pl_module):
+ """Register hooks on specific layers"""
+ if torch.cuda.is_available():
+ torch.cuda.reset_peak_memory_stats()
+
+ # Register hooks for layers we want to monitor
+ for layer_name, layer in self.monitor_layers.items():
+ # Register pre-hook (before forward)
+ pre_hook = layer.register_forward_pre_hook(
+ self._make_pre_hook(layer_name)
+ )
+ self.hooks.append(pre_hook)
+
+ # Register post-hook (after forward)
+ post_hook = layer.register_forward_hook(
+ self._make_post_hook(layer_name)
+ )
+ self.hooks.append(post_hook)
+
+ # Register backward hook (after backward for this module)
+ bwd_pre_hook = layer.register_full_backward_pre_hook(
+ self._make_backward_pre_hook(layer_name)
+ )
+ self.hooks.append(bwd_pre_hook)
+
+ bwd_hook = layer.register_full_backward_hook(
+ self._make_backward_hook(layer_name)
+ )
+ self.hooks.append(bwd_hook)
+
+ def _make_pre_hook(self, layer_name):
+ """Hook that runs BEFORE layer forward pass"""
+ def pre_hook(module, input):
+ if torch.cuda.is_available():
+ torch.cuda.synchronize()
+ self.layer_memory_before[layer_name] = torch.cuda.memory_allocated() / 1024**3
+ return pre_hook
+
+ def _make_post_hook(self, layer_name):
+ """Hook that runs AFTER layer forward pass"""
+ def post_hook(module, input, output):
+ if torch.cuda.is_available():
+ torch.cuda.synchronize()
+ mem_after = torch.cuda.memory_allocated() / 1024**3
+ mem_before = self.layer_memory_before.get(layer_name, 0)
+ mem_used_by_layer = mem_after - mem_before
+
+ # mem_after is total memory, mem_before is memory before this layer
+ print(f"\n[{layer_name}] Memory Delta: {mem_used_by_layer:+.3f} GB")
+ print(f" Before: {mem_before:.3f} GB, After: {mem_after:.3f} GB (Total GPU)")
+ self.layer_memory[layer_name] = mem_used_by_layer
+ self.layer_memory_after_fwd[layer_name] = mem_after
+ return post_hook
+
+ def _make_backward_hook(self, layer_name):
+ """Hook that runs AFTER backward pass for the layer"""
+ def backward_hook(module, grad_input, grad_output):
+ if torch.cuda.is_available():
+ torch.cuda.synchronize()
+ mem_after = torch.cuda.memory_allocated() / 1024**3
+ mem_before = self.layer_memory_before.get(layer_name, 0)
+ mem_before_bwd = self.layer_memory_before_bwd.get(layer_name, mem_before)
+ mem_used_bwd = mem_after - mem_before
+ mem_used_bwd_only = mem_after - mem_before_bwd
+ print(f"\n[{layer_name}] {mem_before:+.3f} GB, {mem_before_bwd:+.3f} GB, {mem_after:+.3f} GB")
+ print(f"\n[{layer_name}] Memory Delta (FWD+BWD): {mem_used_bwd:+.3f} GB")
+ print(f"[{layer_name}] Memory Delta (BWD-only): {mem_used_bwd_only:+.3f} GB")
+ self.layer_memory_bwd[layer_name] = mem_used_bwd
+ self.layer_memory_bwd_only[layer_name] = mem_used_bwd_only
+ return backward_hook
+
+ def _make_backward_pre_hook(self, layer_name):
+ """Hook that runs BEFORE backward pass for the layer"""
+ def backward_pre_hook(module, grad_output):
+ if torch.cuda.is_available():
+ torch.cuda.synchronize()
+ self.layer_memory_before_bwd[layer_name] = torch.cuda.memory_allocated() / 1024**3
+ return backward_pre_hook
+
+ def on_train_batch_end(self, trainer, pl_module, outputs, batch, batch_idx):
+ if batch_idx % self.log_every_n_steps == 0 and torch.cuda.is_available():
+ mem_allocated = torch.cuda.memory_allocated() / 1024**3
+ mem_peak = torch.cuda.max_memory_allocated() / 1024**3
+
+ # Get batch size from the batch (batch is a tuple: inputs, labels, mask, demo, pids)
+ # The inputs is a dict, get first modality to determine batch size
+ inputs = batch[0]
+ first_modality = list(inputs.keys())[0]
+ batch_size = inputs[first_modality].shape[0]
+
+ # Use PyTorch Lightning's logging mechanism instead of direct wandb logging
+ if trainer.logger:
+ pl_module.log("memory/allocated_gb", mem_allocated, on_step=True, on_epoch=False, sync_dist=True, batch_size=batch_size)
+ pl_module.log("memory/peak_gb", mem_peak, on_step=True, on_epoch=False, sync_dist=True, batch_size=batch_size)
+ if 'SeqEncoder' in self.layer_memory:
+ pl_module.log("memory/SeqEncoder_fwd", self.layer_memory['SeqEncoder'], on_step=True, on_epoch=False, sync_dist=True, batch_size=batch_size)
+ if 'SeqEncoder' in self.layer_memory_bwd:
+ pl_module.log("memory/SeqEncoder_fwd_bwd", self.layer_memory_bwd['SeqEncoder'], on_step=True, on_epoch=False, sync_dist=True, batch_size=batch_size)
+ if 'SeqEncoder' in self.layer_memory_bwd_only:
+ pl_module.log("memory/SeqEncoder_bwd_only", self.layer_memory_bwd_only['SeqEncoder'], on_step=True, on_epoch=False, sync_dist=True, batch_size=batch_size)
+
+ print(f"Step {batch_idx} - Memory: {mem_allocated:.3f} GB (Peak: {mem_peak:.3f} GB)")
+
+ def on_train_end(self, trainer, pl_module):
+ """Remove all hooks"""
+ for hook in self.hooks:
+ hook.remove()
+
+ # Usage in main():
+ memory_callback = MemoryMonitorCallback(
+ log_every_n_steps=10,
+ monitor_layers={
+ 'SeqEncoder': model.model.sequence_encoder,
+ 'Encoder': model.model.encoder,
+ 'Fuser': model.model.fuser,
+ }
+ )
+
+
+ # if previous_run_id is not None, load the best model from the previous run
+ previous_run_id = all_configs['previous_run_id']
+
+ if args.no_wandb:
+ wandb_logger = None
+ elif previous_run_id:
+ wandb_logger = WandbLogger(
+ project=all_configs['project_name'],
+ entity='gundo0102',
+ name=all_configs['experiment_name'],
+ config=all_configs,
+ resume='must', # 이전 실험을 이어서 진행
+ id=previous_run_id # 이전 실험의 run_id
+ )
+ else:
+ wandb_logger = WandbLogger(
+ project=all_configs['project_name'],
+ entity='gundo0102',
+ name=all_configs['experiment_name'],
+ config=all_configs
+ )
+
+ trainer = pl.Trainer(
+ devices=all_configs['gpus'],
+ max_epochs=all_configs['num_epochs'],
+ accelerator='gpu',
+ logger=wandb_logger,
+ precision = 'bf16-mixed',
+ callbacks=[checkpoint_callback, SaveLastEpochCheckpoint(), ReshuffleDatasetCallback()],
+ # strategy= 'ddp', #'ddp_find_unused_parameters_true',
+ strategy= 'ddp_find_unused_parameters_true',
+ accumulate_grad_batches=all_configs['accumulate_grad_batches'],
+ # No sanity check
+ num_sanity_val_steps=0,
+ # val_check_interval=10,
+ # check_val_every_n_epoch=1,
+ log_every_n_steps=1
+ )
+ if all_configs['previous_checkpoint']:
+ trainer.fit(model, datamodule=data_module, ckpt_path=all_configs['previous_checkpoint'])
+ else:
+ trainer.fit(model, datamodule=data_module)
+
+ wandb_logger.experiment.finish()
+
+
+if __name__ == '__main__':
+ main()
+
+
diff --git a/requirements.txt b/requirements.txt
new file mode 100644
index 0000000000000000000000000000000000000000..0ef5a9854d6a4bce2bc8ab366a0049e3b77d39c9
--- /dev/null
+++ b/requirements.txt
@@ -0,0 +1,11 @@
+pytorch_lightning==2.6.0
+wandb==0.24.0
+h5py==3.15.1
+wfdb==4.3.0
+librosa==0.11.0
+timm==1.0.24
+mne==1.11.0
+lifelines==0.30.0
+scikit-survival==0.25.0
+umap-learn==0.5.11
+
diff --git a/train_script.sh b/train_script.sh
new file mode 100644
index 0000000000000000000000000000000000000000..81bca96d8cc068026070a5b88d0e38fb3eddf36d
--- /dev/null
+++ b/train_script.sh
@@ -0,0 +1,54 @@
+# python pretrain.py --config PT_6mod_9ds_CL
+# python finetune.py --config FT_6mod_CL
+
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night_abl1
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night_abl2
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night_abl3
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night_abl4
+# python finetune.py --config FT_6mod_CL_full_night
+# python finetune.py --config FT_6mod_CL_ah
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night2
+# python finetune.py --config FT_6mod_CL_full_night2
+# python finetune.py --config FT_6mod_diag
+# python finetune.py --config FT_6mod_CL_abl
+
+
+# python pretrain.py --config PT_6mod_9ds_CL_abl1
+# python finetune.py --config FT_6mod_CL_abl1
+# python pretrain.py --config PT_6mod_9ds_CL_abl2
+# python finetune.py --config FT_6mod_CL_abl2
+# python pretrain.py --config PT_6mod_9ds_CL_abl3
+# python finetune.py --config FT_6mod_CL_abl3
+# python pretrain.py --config PT_6mod_9ds_CL_abl4
+# python finetune.py --config FT_6mod_CL_abl4
+# python pretrain.py --config PT_6mod_9ds_CL_abl5
+# python finetune.py --config FT_6mod_CL_abl5
+# python finetune.py --config FT_6mod_CL_full_night_ahi
+# python finetune.py --config FT_6mod_CL_full_night_sex
+python pretrain_seq.py --config PTseq_6mod_CL_full_night_abl1
+python finetune.py --config FT_6mod_CL_full_night_abl1
+python pretrain_seq.py --config PTseq_6mod_CL_full_night_abl2
+python finetune.py --config FT_6mod_CL_full_night_abl2
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night_abl3
+# python finetune.py --config FT_6mod_CL_full_night_abl3
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night_abl4
+# python finetune.py --config FT_6mod_CL_full_night_abl4
+
+
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night
+# python finetune.py --config FT_6mod_CL_full_night
+
+# python pretrain.py --config PT_6mod_9ds_CL_abl6
+# python finetune.py --config FT_6mod_CL
+
+# python evaluate.py --config Eval_6mod_CL_full_night --no_wandb
+
+
+# python finetune.py --config FT_6mod_CL_full_night_fewshot
+
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night_simclr
+# python finetune.py --config FT_6mod_CL_full_night_simclr
+
+# python pretrain_seq.py --config PTseq_6mod_CL_full_night_dino
+# python finetune.py --config FT_6mod_CL_full_night_dino
\ No newline at end of file
diff --git a/util/pos_embed.py b/util/pos_embed.py
new file mode 100644
index 0000000000000000000000000000000000000000..9bf81251b364663b686e235af51d42b8716e3fd7
--- /dev/null
+++ b/util/pos_embed.py
@@ -0,0 +1,110 @@
+# Copyright (c) Meta Platforms, Inc. and affiliates.
+# All rights reserved.
+
+# This source code is licensed under the license found in the
+# LICENSE file in the root directory of this source tree.
+# --------------------------------------------------------
+# Position embedding utils
+# --------------------------------------------------------
+
+import numpy as np
+
+import torch
+
+# --------------------------------------------------------
+# 2D sine-cosine position embedding
+# References:
+# Transformer: https://github.com/tensorflow/models/blob/master/official/nlp/transformer/model_utils.py
+# MoCo v3: https://github.com/facebookresearch/moco-v3
+# --------------------------------------------------------
+def get_2d_sincos_pos_embed(embed_dim, grid_size, cls_token=False):
+ """
+ grid_size: int of the grid height and width
+ return:
+ pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token)
+ """
+ grid_h = np.arange(grid_size, dtype=np.float32)
+ grid_w = np.arange(grid_size, dtype=np.float32)
+ grid = np.meshgrid(grid_w, grid_h) # here w goes first
+ grid = np.stack(grid, axis=0)
+
+ grid = grid.reshape([2, 1, grid_size, grid_size])
+ pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid)
+ if cls_token:
+ pos_embed = np.concatenate([np.zeros([1, embed_dim]), pos_embed], axis=0)
+ return pos_embed
+
+def get_1d_sincos_pos_embed(embed_dim, grid_size, cls_token=False):
+ """
+ grid_size: int of the grid height and width
+ return:
+ pos_embed: [grid_size*grid_size, embed_dim] or [1+grid_size*grid_size, embed_dim] (w/ or w/o cls_token)
+ """
+ # grid = grid.reshape([2, 1, grid_size, grid_size])
+ grid = np.arange(grid_size, dtype=np.float32)
+ grid = grid.reshape([1, 1, grid_size])
+ pos_embed = get_1d_sincos_pos_embed_from_grid(embed_dim, grid)
+ if cls_token:
+ pos_embed = np.concatenate([np.zeros([1, embed_dim]), pos_embed], axis=0)
+ return pos_embed
+
+
+def get_2d_sincos_pos_embed_from_grid(embed_dim, grid):
+ assert embed_dim % 2 == 0
+
+ # use half of dimensions to encode grid_h
+ emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0]) # (H*W, D/2)
+ emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1]) # (H*W, D/2)
+
+ emb = np.concatenate([emb_h, emb_w], axis=1) # (H*W, D)
+ return emb
+
+
+def get_1d_sincos_pos_embed_from_grid(embed_dim, pos):
+ """
+ embed_dim: output dimension for each position
+ pos: a list of positions to be encoded: size (M,)
+ out: (M, D)
+ """
+ assert embed_dim % 2 == 0
+ omega = np.arange(embed_dim // 2, dtype=np.float32)
+ omega /= embed_dim / 2.
+ omega = 1. / 10000**omega # (D/2,)
+
+ pos = pos.reshape(-1) # (M,)
+ out = np.einsum('m,d->md', pos, omega) # (M, D/2), outer product
+
+ emb_sin = np.sin(out) # (M, D/2)
+ emb_cos = np.cos(out) # (M, D/2)
+
+ emb = np.concatenate([emb_sin, emb_cos], axis=1) # (M, D)
+ return emb
+
+
+# --------------------------------------------------------
+# Interpolate position embeddings for high-resolution
+# References:
+# DeiT: https://github.com/facebookresearch/deit
+# --------------------------------------------------------
+def interpolate_pos_embed(model, checkpoint_model):
+ if 'pos_embed' in checkpoint_model:
+ pos_embed_checkpoint = checkpoint_model['pos_embed']
+ embedding_size = pos_embed_checkpoint.shape[-1]
+ num_patches = model.patch_embed.num_patches
+ num_extra_tokens = model.pos_embed.shape[-2] - num_patches
+ # height (== width) for the checkpoint position embedding
+ orig_size = int((pos_embed_checkpoint.shape[-2] - num_extra_tokens) ** 0.5)
+ # height (== width) for the new position embedding
+ new_size = int(num_patches ** 0.5)
+ # class_token and dist_token are kept unchanged
+ if orig_size != new_size:
+ print("Position interpolate from %dx%d to %dx%d" % (orig_size, orig_size, new_size, new_size))
+ extra_tokens = pos_embed_checkpoint[:, :num_extra_tokens]
+ # only the position tokens are interpolated
+ pos_tokens = pos_embed_checkpoint[:, num_extra_tokens:]
+ pos_tokens = pos_tokens.reshape(-1, orig_size, orig_size, embedding_size).permute(0, 3, 1, 2)
+ pos_tokens = torch.nn.functional.interpolate(
+ pos_tokens, size=(new_size, new_size), mode='bicubic', align_corners=False)
+ pos_tokens = pos_tokens.permute(0, 2, 3, 1).flatten(1, 2)
+ new_pos_embed = torch.cat((extra_tokens, pos_tokens), dim=1)
+ checkpoint_model['pos_embed'] = new_pos_embed