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