thomaswarford commited on
Commit
90f531c
·
verified ·
1 Parent(s): f8d9f88

Upload 77 files

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. .gitattributes +15 -0
  2. README.md +10 -3
  3. analysis/click_on_material_clean.ipynb +0 -0
  4. analysis/click_on_material_clean_using_all_materials.ipynb +3 -0
  5. analysis/compare_anupam_clusters/TH_and_Anupam_cluster_labels +0 -0
  6. analysis/compare_anupam_clusters/TH_and_Anupam_cluster_labels.csv +0 -0
  7. analysis/compare_anupam_clusters/click_on_mat_compare_anupam.ipynb +0 -0
  8. analysis/compare_anupam_clusters/comparing_with_anupam's_clusters.ipynb +0 -0
  9. analysis/compare_anupam_clusters/input_flat_materials_244 (2).csv +0 -0
  10. analysis/compare_anupam_clusters/input_indices_244.csv +1993 -0
  11. analysis/compare_anupam_clusters/materials_data_anupam's_fingerprints.csv +0 -0
  12. analysis/genetic_tree_plot.py +176 -0
  13. analysis/new_tree.nw +1 -0
  14. analysis/report_figures/2d_hist_hdbscan_params.png +0 -0
  15. analysis/report_figures/2d_hist_hdbscan_params2.png +0 -0
  16. analysis/report_figures/MCS=4_MS=4_clusters_big_table.png +3 -0
  17. analysis/report_figures/MCS=6_MS=2_clusters_big_table.png +3 -0
  18. analysis/report_figures/NEW_OLD_PRINT_MCS_4_MS_3_clusters_big_table.png +0 -0
  19. analysis/report_figures/OLD_PRINT_MCS_4_MS_3_clusters_big_table.png +0 -0
  20. analysis/report_figures/first print pipeline figure.png +0 -0
  21. analysis/report_figures/latent space.png +0 -0
  22. analysis/report_figures/old_print.png +0 -0
  23. analysis/report_figures/old_print_tree_plot.png +0 -0
  24. analysis/report_figures/old_print_tsne.png +0 -0
  25. analysis/report_figures/out1.png +0 -0
  26. analysis/report_figures/recon.png +0 -0
  27. analysis/report_figures/report pseudo flow diagram.png +0 -0
  28. analysis/report_figures/report pseudo flow diagram_2.png +0 -0
  29. analysis/report_figures/resnet_2_channel_L=96_tsne.png +0 -0
  30. analysis/report_figures/tsne_L96_noised_AE.png +0 -0
  31. autoencoder/model.py +597 -0
  32. autoencoder/resnet_train.ipynb +0 -0
  33. autoencoder/save_bandstructure_images.ipynb +507 -0
  34. fingerprint_creation/2dmatpedia.ipynb +0 -0
  35. fingerprint_creation/README.md +1 -0
  36. fingerprints/128x128_random_erase_resnet18_VAE_L=128_perplexity_30_length_128.csv +3 -0
  37. fingerprints/128x128_random_erase_resnet18_VAE_L=256_perplexity_30_length_256.csv +3 -0
  38. fingerprints/128x128_random_erase_resnet18_VAE_L=64_perplexity_30_length_64.csv +0 -0
  39. fingerprints/128x128_resnet_L=128_perplexity_30_length_128.csv +3 -0
  40. fingerprints/128x128_resnet_L=160_perplexity_30_length_160.csv +3 -0
  41. fingerprints/128x128_resnet_L=256_perplexity_30_length_256.csv +3 -0
  42. fingerprints/128x128_resnet_L=32_perplexity_30_length_32.csv +0 -0
  43. fingerprints/128x128_resnet_L=512_perplexity_30_length_512.csv +3 -0
  44. fingerprints/128x128_resnet_L=96_leaky_perplexity_30_length_96.csv +3 -0
  45. fingerprints/128x128_resnet_L=96_perplexity_30_length_96.csv +0 -0
  46. fingerprints/12_bands_encoder_L=128_perplexity_30_length_128.csv +3 -0
  47. fingerprints/12_bands_encoder_L=4_perplexity_30_length_4.csv +0 -0
  48. fingerprints/12_bands_encoder_perplexity_30_length_128.csv +3 -0
  49. fingerprints/224_2channel_resnet_L=98_perplexity_30_length_98.csv +0 -0
  50. fingerprints/224_2channel_resnet_L=98_perplexity_30_length_98_CORRECTED.csv +0 -0
.gitattributes CHANGED
@@ -33,3 +33,18 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ analysis/click_on_material_clean_using_all_materials.ipynb filter=lfs diff=lfs merge=lfs -text
37
+ analysis/report_figures/MCS=4_MS=4_clusters_big_table.png filter=lfs diff=lfs merge=lfs -text
38
+ analysis/report_figures/MCS=6_MS=2_clusters_big_table.png filter=lfs diff=lfs merge=lfs -text
39
+ fingerprints/12_bands_encoder_L=128_perplexity_30_length_128.csv filter=lfs diff=lfs merge=lfs -text
40
+ fingerprints/12_bands_encoder_perplexity_30_length_128.csv filter=lfs diff=lfs merge=lfs -text
41
+ fingerprints/128x128_random_erase_resnet18_VAE_L=128_perplexity_30_length_128.csv filter=lfs diff=lfs merge=lfs -text
42
+ fingerprints/128x128_random_erase_resnet18_VAE_L=256_perplexity_30_length_256.csv filter=lfs diff=lfs merge=lfs -text
43
+ fingerprints/128x128_resnet_L=128_perplexity_30_length_128.csv filter=lfs diff=lfs merge=lfs -text
44
+ fingerprints/128x128_resnet_L=160_perplexity_30_length_160.csv filter=lfs diff=lfs merge=lfs -text
45
+ fingerprints/128x128_resnet_L=256_perplexity_30_length_256.csv filter=lfs diff=lfs merge=lfs -text
46
+ fingerprints/128x128_resnet_L=512_perplexity_30_length_512.csv filter=lfs diff=lfs merge=lfs -text
47
+ fingerprints/128x128_resnet_L=96_leaky_perplexity_30_length_96.csv filter=lfs diff=lfs merge=lfs -text
48
+ fingerprints/all_k_branches_histogram_-8_to_8_normed_perplexity_30_length_120.csv filter=lfs diff=lfs merge=lfs -text
49
+ looser_solution_cluster_tables.png filter=lfs diff=lfs merge=lfs -text
50
+ misc/view_resnet_vae_latent_space.ipynb filter=lfs diff=lfs merge=lfs -text
README.md CHANGED
@@ -1,3 +1,10 @@
1
- ---
2
- license: mit
3
- ---
 
 
 
 
 
 
 
 
1
+ # Electronic Band Fingerprinting
2
+ ## Rules
3
+ - Each fingerprint has a corresponding dataframe.
4
+ - Fingerprint creation & clustering is performed in `fingerprint_creation`.
5
+ - Fingerprints are saved to `fingerprints`, with descriptive names.
6
+ - The last part of the fingerprint csv name is the fingerprint length.
7
+ - Analysis/plotting of fingerprints happens in `analyis`.
8
+ - .py files containing functions, ect go in `src`.
9
+ - Miscellaneous/messy files go in `misc`
10
+
analysis/click_on_material_clean.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
analysis/click_on_material_clean_using_all_materials.ipynb ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:8448be5dd8e9c72ef2fdf220506b7101ba3aa2ef0b988aae13c062f8d8ca70ba
3
+ size 15379800
analysis/compare_anupam_clusters/TH_and_Anupam_cluster_labels ADDED
The diff for this file is too large to render. See raw diff
 
analysis/compare_anupam_clusters/TH_and_Anupam_cluster_labels.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/compare_anupam_clusters/click_on_mat_compare_anupam.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
analysis/compare_anupam_clusters/comparing_with_anupam's_clusters.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
analysis/compare_anupam_clusters/input_flat_materials_244 (2).csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/compare_anupam_clusters/input_indices_244.csv ADDED
@@ -0,0 +1,1993 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ 3
2
+ 21
3
+ 22
4
+ 25
5
+ 29
6
+ 31
7
+ 32
8
+ 34
9
+ 56
10
+ 79
11
+ 85
12
+ 86
13
+ 89
14
+ 101
15
+ 103
16
+ 107
17
+ 111
18
+ 119
19
+ 121
20
+ 128
21
+ 129
22
+ 131
23
+ 138
24
+ 142
25
+ 144
26
+ 147
27
+ 149
28
+ 153
29
+ 155
30
+ 157
31
+ 161
32
+ 164
33
+ 165
34
+ 167
35
+ 169
36
+ 180
37
+ 183
38
+ 190
39
+ 192
40
+ 197
41
+ 202
42
+ 206
43
+ 209
44
+ 213
45
+ 214
46
+ 218
47
+ 222
48
+ 224
49
+ 229
50
+ 230
51
+ 231
52
+ 234
53
+ 248
54
+ 249
55
+ 250
56
+ 257
57
+ 258
58
+ 259
59
+ 263
60
+ 264
61
+ 269
62
+ 277
63
+ 292
64
+ 293
65
+ 300
66
+ 301
67
+ 303
68
+ 306
69
+ 308
70
+ 318
71
+ 319
72
+ 320
73
+ 321
74
+ 324
75
+ 325
76
+ 329
77
+ 335
78
+ 342
79
+ 356
80
+ 360
81
+ 361
82
+ 362
83
+ 365
84
+ 369
85
+ 371
86
+ 375
87
+ 379
88
+ 386
89
+ 387
90
+ 390
91
+ 394
92
+ 398
93
+ 399
94
+ 401
95
+ 411
96
+ 415
97
+ 419
98
+ 423
99
+ 428
100
+ 432
101
+ 433
102
+ 438
103
+ 439
104
+ 440
105
+ 441
106
+ 442
107
+ 448
108
+ 454
109
+ 455
110
+ 456
111
+ 457
112
+ 464
113
+ 470
114
+ 476
115
+ 477
116
+ 485
117
+ 490
118
+ 492
119
+ 494
120
+ 495
121
+ 499
122
+ 505
123
+ 511
124
+ 513
125
+ 517
126
+ 519
127
+ 526
128
+ 528
129
+ 529
130
+ 534
131
+ 537
132
+ 542
133
+ 545
134
+ 553
135
+ 562
136
+ 565
137
+ 570
138
+ 573
139
+ 576
140
+ 578
141
+ 584
142
+ 594
143
+ 595
144
+ 598
145
+ 603
146
+ 606
147
+ 608
148
+ 610
149
+ 614
150
+ 618
151
+ 628
152
+ 632
153
+ 636
154
+ 638
155
+ 641
156
+ 643
157
+ 644
158
+ 649
159
+ 651
160
+ 659
161
+ 665
162
+ 669
163
+ 673
164
+ 676
165
+ 679
166
+ 680
167
+ 681
168
+ 684
169
+ 687
170
+ 689
171
+ 690
172
+ 691
173
+ 697
174
+ 698
175
+ 710
176
+ 714
177
+ 717
178
+ 718
179
+ 720
180
+ 723
181
+ 726
182
+ 733
183
+ 736
184
+ 740
185
+ 744
186
+ 759
187
+ 761
188
+ 769
189
+ 771
190
+ 779
191
+ 786
192
+ 788
193
+ 791
194
+ 797
195
+ 801
196
+ 802
197
+ 803
198
+ 807
199
+ 810
200
+ 812
201
+ 815
202
+ 820
203
+ 822
204
+ 824
205
+ 826
206
+ 828
207
+ 836
208
+ 838
209
+ 847
210
+ 851
211
+ 853
212
+ 854
213
+ 857
214
+ 861
215
+ 873
216
+ 874
217
+ 875
218
+ 878
219
+ 880
220
+ 881
221
+ 882
222
+ 885
223
+ 887
224
+ 888
225
+ 889
226
+ 890
227
+ 893
228
+ 894
229
+ 898
230
+ 899
231
+ 900
232
+ 901
233
+ 902
234
+ 903
235
+ 904
236
+ 905
237
+ 909
238
+ 910
239
+ 911
240
+ 912
241
+ 913
242
+ 916
243
+ 920
244
+ 923
245
+ 925
246
+ 927
247
+ 930
248
+ 938
249
+ 940
250
+ 949
251
+ 955
252
+ 968
253
+ 969
254
+ 980
255
+ 982
256
+ 987
257
+ 991
258
+ 993
259
+ 996
260
+ 998
261
+ 1000
262
+ 1001
263
+ 1003
264
+ 1010
265
+ 1011
266
+ 1017
267
+ 1018
268
+ 1019
269
+ 1021
270
+ 1022
271
+ 1031
272
+ 1040
273
+ 1041
274
+ 1044
275
+ 1045
276
+ 1047
277
+ 1051
278
+ 1052
279
+ 1056
280
+ 1058
281
+ 1063
282
+ 1065
283
+ 1066
284
+ 1068
285
+ 1069
286
+ 1072
287
+ 1079
288
+ 1081
289
+ 1089
290
+ 1091
291
+ 1094
292
+ 1095
293
+ 1097
294
+ 1099
295
+ 1101
296
+ 1103
297
+ 1105
298
+ 1106
299
+ 1113
300
+ 1115
301
+ 1117
302
+ 1118
303
+ 1119
304
+ 1122
305
+ 1127
306
+ 1128
307
+ 1129
308
+ 1132
309
+ 1135
310
+ 1136
311
+ 1145
312
+ 1149
313
+ 1151
314
+ 1153
315
+ 1156
316
+ 1157
317
+ 1169
318
+ 1172
319
+ 1174
320
+ 1175
321
+ 1178
322
+ 1180
323
+ 1184
324
+ 1189
325
+ 1193
326
+ 1197
327
+ 1204
328
+ 1205
329
+ 1209
330
+ 1220
331
+ 1223
332
+ 1228
333
+ 1229
334
+ 1231
335
+ 1234
336
+ 1238
337
+ 1239
338
+ 1243
339
+ 1245
340
+ 1247
341
+ 1248
342
+ 1251
343
+ 1257
344
+ 1258
345
+ 1259
346
+ 1266
347
+ 1268
348
+ 1273
349
+ 1275
350
+ 1278
351
+ 1281
352
+ 1283
353
+ 1286
354
+ 1287
355
+ 1288
356
+ 1290
357
+ 1291
358
+ 1292
359
+ 1293
360
+ 1294
361
+ 1295
362
+ 1298
363
+ 1303
364
+ 1311
365
+ 1314
366
+ 1316
367
+ 1317
368
+ 1319
369
+ 1325
370
+ 1326
371
+ 1328
372
+ 1330
373
+ 1331
374
+ 1333
375
+ 1335
376
+ 1336
377
+ 1337
378
+ 1339
379
+ 1340
380
+ 1350
381
+ 1354
382
+ 1359
383
+ 1360
384
+ 1361
385
+ 1362
386
+ 1363
387
+ 1365
388
+ 1366
389
+ 1367
390
+ 1368
391
+ 1370
392
+ 1371
393
+ 1372
394
+ 1373
395
+ 1374
396
+ 1377
397
+ 1379
398
+ 1380
399
+ 1381
400
+ 1388
401
+ 1390
402
+ 1391
403
+ 1394
404
+ 1395
405
+ 1419
406
+ 1425
407
+ 1427
408
+ 1431
409
+ 1436
410
+ 1437
411
+ 1438
412
+ 1443
413
+ 1446
414
+ 1447
415
+ 1450
416
+ 1453
417
+ 1454
418
+ 1461
419
+ 1465
420
+ 1469
421
+ 1471
422
+ 1473
423
+ 1474
424
+ 1475
425
+ 1476
426
+ 1479
427
+ 1484
428
+ 1485
429
+ 1489
430
+ 1490
431
+ 1493
432
+ 1499
433
+ 1501
434
+ 1506
435
+ 1508
436
+ 1509
437
+ 1512
438
+ 1521
439
+ 1523
440
+ 1525
441
+ 1527
442
+ 1531
443
+ 1533
444
+ 1537
445
+ 1539
446
+ 1544
447
+ 1551
448
+ 1554
449
+ 1556
450
+ 1559
451
+ 1563
452
+ 1565
453
+ 1568
454
+ 1571
455
+ 1572
456
+ 1574
457
+ 1576
458
+ 1583
459
+ 1584
460
+ 1593
461
+ 1594
462
+ 1596
463
+ 1599
464
+ 1600
465
+ 1604
466
+ 1605
467
+ 1606
468
+ 1607
469
+ 1608
470
+ 1613
471
+ 1617
472
+ 1625
473
+ 1627
474
+ 1632
475
+ 1634
476
+ 1636
477
+ 1641
478
+ 1644
479
+ 1645
480
+ 1653
481
+ 1661
482
+ 1662
483
+ 1665
484
+ 1668
485
+ 1669
486
+ 1672
487
+ 1675
488
+ 1676
489
+ 1680
490
+ 1692
491
+ 1696
492
+ 1699
493
+ 1700
494
+ 1707
495
+ 1710
496
+ 1718
497
+ 1720
498
+ 1721
499
+ 1723
500
+ 1724
501
+ 1726
502
+ 1739
503
+ 1740
504
+ 1741
505
+ 1743
506
+ 1744
507
+ 1746
508
+ 1749
509
+ 1751
510
+ 1752
511
+ 1753
512
+ 1754
513
+ 1761
514
+ 1764
515
+ 1768
516
+ 1775
517
+ 1777
518
+ 1779
519
+ 1781
520
+ 1782
521
+ 1783
522
+ 1787
523
+ 1788
524
+ 1789
525
+ 1793
526
+ 1794
527
+ 1795
528
+ 1799
529
+ 1802
530
+ 1803
531
+ 1806
532
+ 1809
533
+ 1812
534
+ 1813
535
+ 1814
536
+ 1815
537
+ 1816
538
+ 1817
539
+ 1819
540
+ 1820
541
+ 1821
542
+ 1822
543
+ 1823
544
+ 1828
545
+ 1829
546
+ 1832
547
+ 1834
548
+ 1842
549
+ 1843
550
+ 1845
551
+ 1848
552
+ 1849
553
+ 1850
554
+ 1856
555
+ 1857
556
+ 1858
557
+ 1859
558
+ 1861
559
+ 1863
560
+ 1867
561
+ 1870
562
+ 1871
563
+ 1877
564
+ 1878
565
+ 1884
566
+ 1888
567
+ 1889
568
+ 1892
569
+ 1893
570
+ 1895
571
+ 1899
572
+ 1902
573
+ 1903
574
+ 1906
575
+ 1907
576
+ 1911
577
+ 1914
578
+ 1915
579
+ 1919
580
+ 1924
581
+ 1925
582
+ 1927
583
+ 1935
584
+ 1938
585
+ 1941
586
+ 1947
587
+ 1950
588
+ 1952
589
+ 1956
590
+ 1958
591
+ 1960
592
+ 1961
593
+ 1962
594
+ 1964
595
+ 1966
596
+ 1968
597
+ 1971
598
+ 1976
599
+ 1979
600
+ 1980
601
+ 1981
602
+ 1982
603
+ 1983
604
+ 1984
605
+ 1985
606
+ 1986
607
+ 1988
608
+ 1989
609
+ 1991
610
+ 1994
611
+ 1995
612
+ 1996
613
+ 1997
614
+ 1998
615
+ 2004
616
+ 2005
617
+ 2007
618
+ 2008
619
+ 2009
620
+ 2010
621
+ 2033
622
+ 2035
623
+ 2039
624
+ 2040
625
+ 2042
626
+ 2044
627
+ 2046
628
+ 2047
629
+ 2051
630
+ 2056
631
+ 2057
632
+ 2058
633
+ 2059
634
+ 2070
635
+ 2071
636
+ 2078
637
+ 2080
638
+ 2089
639
+ 2093
640
+ 2094
641
+ 2096
642
+ 2097
643
+ 2098
644
+ 2100
645
+ 2103
646
+ 2106
647
+ 2110
648
+ 2113
649
+ 2116
650
+ 2118
651
+ 2123
652
+ 2125
653
+ 2129
654
+ 2140
655
+ 2142
656
+ 2145
657
+ 2146
658
+ 2151
659
+ 2152
660
+ 2159
661
+ 2170
662
+ 2176
663
+ 2181
664
+ 2188
665
+ 2189
666
+ 2198
667
+ 2204
668
+ 2205
669
+ 2209
670
+ 2213
671
+ 2218
672
+ 2222
673
+ 2225
674
+ 2230
675
+ 2231
676
+ 2236
677
+ 2239
678
+ 2247
679
+ 2252
680
+ 2256
681
+ 2258
682
+ 2272
683
+ 2289
684
+ 2298
685
+ 2305
686
+ 2307
687
+ 2309
688
+ 2313
689
+ 2315
690
+ 2317
691
+ 2321
692
+ 2325
693
+ 2326
694
+ 2328
695
+ 2330
696
+ 2342
697
+ 2343
698
+ 2345
699
+ 2349
700
+ 2352
701
+ 2354
702
+ 2365
703
+ 2368
704
+ 2369
705
+ 2372
706
+ 2374
707
+ 2375
708
+ 2380
709
+ 2384
710
+ 2393
711
+ 2400
712
+ 2405
713
+ 2424
714
+ 2425
715
+ 2426
716
+ 2431
717
+ 2433
718
+ 2436
719
+ 2441
720
+ 2445
721
+ 2450
722
+ 2454
723
+ 2456
724
+ 2460
725
+ 2462
726
+ 2467
727
+ 2470
728
+ 2471
729
+ 2474
730
+ 2476
731
+ 2482
732
+ 2484
733
+ 2493
734
+ 2494
735
+ 2497
736
+ 2499
737
+ 2505
738
+ 2510
739
+ 2514
740
+ 2517
741
+ 2520
742
+ 2524
743
+ 2526
744
+ 2528
745
+ 2537
746
+ 2544
747
+ 2551
748
+ 2552
749
+ 2553
750
+ 2555
751
+ 2557
752
+ 2565
753
+ 2569
754
+ 2571
755
+ 2572
756
+ 2573
757
+ 2574
758
+ 2578
759
+ 2586
760
+ 2594
761
+ 2600
762
+ 2604
763
+ 2607
764
+ 2611
765
+ 2612
766
+ 2616
767
+ 2618
768
+ 2621
769
+ 2622
770
+ 2624
771
+ 2628
772
+ 2630
773
+ 2633
774
+ 2636
775
+ 2637
776
+ 2638
777
+ 2639
778
+ 2641
779
+ 2644
780
+ 2649
781
+ 2650
782
+ 2651
783
+ 2655
784
+ 2656
785
+ 2657
786
+ 2658
787
+ 2661
788
+ 2662
789
+ 2665
790
+ 2666
791
+ 2670
792
+ 2671
793
+ 2672
794
+ 2673
795
+ 2675
796
+ 2679
797
+ 2682
798
+ 2684
799
+ 2699
800
+ 2701
801
+ 2715
802
+ 2717
803
+ 2718
804
+ 2726
805
+ 2728
806
+ 2731
807
+ 2733
808
+ 2736
809
+ 2741
810
+ 2742
811
+ 2743
812
+ 2745
813
+ 2747
814
+ 2749
815
+ 2763
816
+ 2764
817
+ 2765
818
+ 2766
819
+ 2767
820
+ 2769
821
+ 2772
822
+ 2774
823
+ 2777
824
+ 2778
825
+ 2784
826
+ 2787
827
+ 2791
828
+ 2796
829
+ 2797
830
+ 2801
831
+ 2802
832
+ 2811
833
+ 2813
834
+ 2814
835
+ 2820
836
+ 2822
837
+ 2825
838
+ 2826
839
+ 2827
840
+ 2829
841
+ 2830
842
+ 2831
843
+ 2833
844
+ 2836
845
+ 2837
846
+ 2838
847
+ 2839
848
+ 2840
849
+ 2845
850
+ 2847
851
+ 2849
852
+ 2852
853
+ 2853
854
+ 2856
855
+ 2857
856
+ 2859
857
+ 2860
858
+ 2861
859
+ 2862
860
+ 2866
861
+ 2867
862
+ 2871
863
+ 2872
864
+ 2880
865
+ 2882
866
+ 2884
867
+ 2888
868
+ 2890
869
+ 2891
870
+ 2893
871
+ 2895
872
+ 2896
873
+ 2897
874
+ 2898
875
+ 2899
876
+ 2901
877
+ 2904
878
+ 2909
879
+ 2911
880
+ 2912
881
+ 2913
882
+ 2917
883
+ 2918
884
+ 2920
885
+ 2921
886
+ 2923
887
+ 2926
888
+ 2927
889
+ 2928
890
+ 2931
891
+ 2933
892
+ 2936
893
+ 2938
894
+ 2939
895
+ 2946
896
+ 2950
897
+ 2953
898
+ 2954
899
+ 2965
900
+ 2988
901
+ 3025
902
+ 3026
903
+ 3046
904
+ 3047
905
+ 3048
906
+ 3052
907
+ 3054
908
+ 3058
909
+ 3062
910
+ 3064
911
+ 3065
912
+ 3066
913
+ 3074
914
+ 3083
915
+ 3090
916
+ 3104
917
+ 3114
918
+ 3122
919
+ 3124
920
+ 3130
921
+ 3134
922
+ 3142
923
+ 3155
924
+ 3162
925
+ 3171
926
+ 3172
927
+ 3173
928
+ 3187
929
+ 3196
930
+ 3200
931
+ 3204
932
+ 3218
933
+ 3219
934
+ 3220
935
+ 3222
936
+ 3226
937
+ 3232
938
+ 3233
939
+ 3239
940
+ 3247
941
+ 3257
942
+ 3258
943
+ 3260
944
+ 3264
945
+ 3289
946
+ 3291
947
+ 3298
948
+ 3301
949
+ 3302
950
+ 3304
951
+ 3307
952
+ 3324
953
+ 3326
954
+ 3335
955
+ 3340
956
+ 3347
957
+ 3355
958
+ 3364
959
+ 3367
960
+ 3374
961
+ 3394
962
+ 3402
963
+ 3403
964
+ 3407
965
+ 3411
966
+ 3419
967
+ 3421
968
+ 3423
969
+ 3425
970
+ 3428
971
+ 3431
972
+ 3432
973
+ 3435
974
+ 3440
975
+ 3452
976
+ 3458
977
+ 3462
978
+ 3463
979
+ 3464
980
+ 3466
981
+ 3470
982
+ 3480
983
+ 3481
984
+ 3482
985
+ 3483
986
+ 3485
987
+ 3488
988
+ 3494
989
+ 3499
990
+ 3500
991
+ 3502
992
+ 3504
993
+ 3511
994
+ 3514
995
+ 3516
996
+ 3517
997
+ 3518
998
+ 3519
999
+ 3541
1000
+ 3545
1001
+ 3548
1002
+ 3549
1003
+ 3551
1004
+ 3558
1005
+ 3564
1006
+ 3569
1007
+ 3572
1008
+ 3576
1009
+ 3577
1010
+ 3578
1011
+ 3579
1012
+ 3580
1013
+ 3585
1014
+ 3589
1015
+ 3591
1016
+ 3593
1017
+ 3597
1018
+ 3602
1019
+ 3603
1020
+ 3610
1021
+ 3611
1022
+ 3616
1023
+ 3618
1024
+ 3621
1025
+ 3624
1026
+ 3628
1027
+ 3631
1028
+ 3635
1029
+ 3636
1030
+ 3637
1031
+ 3639
1032
+ 3642
1033
+ 3645
1034
+ 3646
1035
+ 3647
1036
+ 3649
1037
+ 3651
1038
+ 3652
1039
+ 3657
1040
+ 3658
1041
+ 3662
1042
+ 3663
1043
+ 3664
1044
+ 3668
1045
+ 3671
1046
+ 3672
1047
+ 3675
1048
+ 3676
1049
+ 3680
1050
+ 3681
1051
+ 3684
1052
+ 3689
1053
+ 3690
1054
+ 3691
1055
+ 3695
1056
+ 3697
1057
+ 3699
1058
+ 3701
1059
+ 3702
1060
+ 3703
1061
+ 3704
1062
+ 3712
1063
+ 3713
1064
+ 3715
1065
+ 3718
1066
+ 3720
1067
+ 3721
1068
+ 3722
1069
+ 3725
1070
+ 3741
1071
+ 3752
1072
+ 3753
1073
+ 3759
1074
+ 3760
1075
+ 3761
1076
+ 3765
1077
+ 3768
1078
+ 3770
1079
+ 3775
1080
+ 3776
1081
+ 3779
1082
+ 3783
1083
+ 3785
1084
+ 3786
1085
+ 3788
1086
+ 3789
1087
+ 3790
1088
+ 3798
1089
+ 3800
1090
+ 3803
1091
+ 3808
1092
+ 3813
1093
+ 3814
1094
+ 3817
1095
+ 3819
1096
+ 3822
1097
+ 3823
1098
+ 3825
1099
+ 3827
1100
+ 3828
1101
+ 3833
1102
+ 3836
1103
+ 3837
1104
+ 3839
1105
+ 3841
1106
+ 3842
1107
+ 3844
1108
+ 3845
1109
+ 3848
1110
+ 3853
1111
+ 3856
1112
+ 3857
1113
+ 3860
1114
+ 3861
1115
+ 3862
1116
+ 3864
1117
+ 3865
1118
+ 3868
1119
+ 3869
1120
+ 3872
1121
+ 3875
1122
+ 3878
1123
+ 3879
1124
+ 3886
1125
+ 3889
1126
+ 3891
1127
+ 3893
1128
+ 3898
1129
+ 3901
1130
+ 3905
1131
+ 3906
1132
+ 3907
1133
+ 3909
1134
+ 3910
1135
+ 3913
1136
+ 3914
1137
+ 3915
1138
+ 3919
1139
+ 3920
1140
+ 3922
1141
+ 3923
1142
+ 3925
1143
+ 3929
1144
+ 3930
1145
+ 3931
1146
+ 3933
1147
+ 3935
1148
+ 3939
1149
+ 3944
1150
+ 3948
1151
+ 3951
1152
+ 3957
1153
+ 3958
1154
+ 3960
1155
+ 3962
1156
+ 3963
1157
+ 3965
1158
+ 3966
1159
+ 3969
1160
+ 3970
1161
+ 3971
1162
+ 3972
1163
+ 3973
1164
+ 3974
1165
+ 3975
1166
+ 3976
1167
+ 3980
1168
+ 3981
1169
+ 3984
1170
+ 3986
1171
+ 3987
1172
+ 3988
1173
+ 3994
1174
+ 3995
1175
+ 3996
1176
+ 3998
1177
+ 3999
1178
+ 4003
1179
+ 4004
1180
+ 4005
1181
+ 4006
1182
+ 4008
1183
+ 4011
1184
+ 4013
1185
+ 4014
1186
+ 4015
1187
+ 4016
1188
+ 4018
1189
+ 4021
1190
+ 4025
1191
+ 4028
1192
+ 4030
1193
+ 4036
1194
+ 4037
1195
+ 4040
1196
+ 4043
1197
+ 4045
1198
+ 4049
1199
+ 4053
1200
+ 4054
1201
+ 4055
1202
+ 4056
1203
+ 4057
1204
+ 4059
1205
+ 4060
1206
+ 4061
1207
+ 4062
1208
+ 4065
1209
+ 4066
1210
+ 4067
1211
+ 4071
1212
+ 4072
1213
+ 4073
1214
+ 4074
1215
+ 4077
1216
+ 4079
1217
+ 4081
1218
+ 4086
1219
+ 4087
1220
+ 4088
1221
+ 4092
1222
+ 4093
1223
+ 4095
1224
+ 4096
1225
+ 4097
1226
+ 4099
1227
+ 4101
1228
+ 4104
1229
+ 4112
1230
+ 4117
1231
+ 4119
1232
+ 4120
1233
+ 4122
1234
+ 4124
1235
+ 4125
1236
+ 4127
1237
+ 4129
1238
+ 4130
1239
+ 4133
1240
+ 4135
1241
+ 4138
1242
+ 4139
1243
+ 4143
1244
+ 4147
1245
+ 4151
1246
+ 4154
1247
+ 4157
1248
+ 4159
1249
+ 4162
1250
+ 4164
1251
+ 4169
1252
+ 4170
1253
+ 4171
1254
+ 4173
1255
+ 4174
1256
+ 4180
1257
+ 4182
1258
+ 4189
1259
+ 4190
1260
+ 4194
1261
+ 4195
1262
+ 4196
1263
+ 4198
1264
+ 4200
1265
+ 4203
1266
+ 4206
1267
+ 4213
1268
+ 4214
1269
+ 4215
1270
+ 4216
1271
+ 4217
1272
+ 4221
1273
+ 4223
1274
+ 4226
1275
+ 4227
1276
+ 4230
1277
+ 4233
1278
+ 4234
1279
+ 4235
1280
+ 4236
1281
+ 4237
1282
+ 4239
1283
+ 4241
1284
+ 4249
1285
+ 4251
1286
+ 4254
1287
+ 4258
1288
+ 4259
1289
+ 4260
1290
+ 4268
1291
+ 4269
1292
+ 4271
1293
+ 4281
1294
+ 4283
1295
+ 4285
1296
+ 4288
1297
+ 4289
1298
+ 4291
1299
+ 4295
1300
+ 4299
1301
+ 4302
1302
+ 4311
1303
+ 4312
1304
+ 4314
1305
+ 4316
1306
+ 4319
1307
+ 4320
1308
+ 4322
1309
+ 4327
1310
+ 4331
1311
+ 4332
1312
+ 4336
1313
+ 4337
1314
+ 4338
1315
+ 4340
1316
+ 4350
1317
+ 4352
1318
+ 4353
1319
+ 4358
1320
+ 4359
1321
+ 4361
1322
+ 4363
1323
+ 4365
1324
+ 4375
1325
+ 4376
1326
+ 4381
1327
+ 4385
1328
+ 4386
1329
+ 4387
1330
+ 4389
1331
+ 4390
1332
+ 4391
1333
+ 4392
1334
+ 4393
1335
+ 4398
1336
+ 4399
1337
+ 4400
1338
+ 4401
1339
+ 4403
1340
+ 4404
1341
+ 4408
1342
+ 4410
1343
+ 4413
1344
+ 4414
1345
+ 4416
1346
+ 4418
1347
+ 4420
1348
+ 4421
1349
+ 4422
1350
+ 4426
1351
+ 4429
1352
+ 4433
1353
+ 4435
1354
+ 4436
1355
+ 4437
1356
+ 4438
1357
+ 4439
1358
+ 4441
1359
+ 4444
1360
+ 4448
1361
+ 4451
1362
+ 4457
1363
+ 4458
1364
+ 4468
1365
+ 4471
1366
+ 4472
1367
+ 4475
1368
+ 4484
1369
+ 4486
1370
+ 4487
1371
+ 4498
1372
+ 4501
1373
+ 4506
1374
+ 4507
1375
+ 4510
1376
+ 4513
1377
+ 4514
1378
+ 4520
1379
+ 4521
1380
+ 4522
1381
+ 4525
1382
+ 4526
1383
+ 4530
1384
+ 4534
1385
+ 4535
1386
+ 4536
1387
+ 4538
1388
+ 4539
1389
+ 4540
1390
+ 4541
1391
+ 4547
1392
+ 4548
1393
+ 4549
1394
+ 4550
1395
+ 4555
1396
+ 4560
1397
+ 4562
1398
+ 4568
1399
+ 4571
1400
+ 4578
1401
+ 4579
1402
+ 4581
1403
+ 4583
1404
+ 4591
1405
+ 4592
1406
+ 4597
1407
+ 4600
1408
+ 4603
1409
+ 4604
1410
+ 4605
1411
+ 4606
1412
+ 4613
1413
+ 4614
1414
+ 4615
1415
+ 4617
1416
+ 4619
1417
+ 4620
1418
+ 4623
1419
+ 4624
1420
+ 4626
1421
+ 4630
1422
+ 4635
1423
+ 4636
1424
+ 4637
1425
+ 4641
1426
+ 4642
1427
+ 4644
1428
+ 4645
1429
+ 4647
1430
+ 4648
1431
+ 4650
1432
+ 4651
1433
+ 4656
1434
+ 4657
1435
+ 4662
1436
+ 4663
1437
+ 4664
1438
+ 4666
1439
+ 4667
1440
+ 4672
1441
+ 4675
1442
+ 4677
1443
+ 4678
1444
+ 4679
1445
+ 4684
1446
+ 4689
1447
+ 4691
1448
+ 4694
1449
+ 4699
1450
+ 4704
1451
+ 4705
1452
+ 4708
1453
+ 4718
1454
+ 4719
1455
+ 4727
1456
+ 4730
1457
+ 4731
1458
+ 4732
1459
+ 4734
1460
+ 4736
1461
+ 4738
1462
+ 4740
1463
+ 4742
1464
+ 4751
1465
+ 4753
1466
+ 4757
1467
+ 4758
1468
+ 4759
1469
+ 4760
1470
+ 4770
1471
+ 4771
1472
+ 4774
1473
+ 4775
1474
+ 4777
1475
+ 4780
1476
+ 4781
1477
+ 4782
1478
+ 4785
1479
+ 4788
1480
+ 4789
1481
+ 4790
1482
+ 4791
1483
+ 4793
1484
+ 4795
1485
+ 4800
1486
+ 4802
1487
+ 4803
1488
+ 4804
1489
+ 4810
1490
+ 4812
1491
+ 4815
1492
+ 4821
1493
+ 4822
1494
+ 4824
1495
+ 4826
1496
+ 4827
1497
+ 4829
1498
+ 4830
1499
+ 4831
1500
+ 4832
1501
+ 4833
1502
+ 4835
1503
+ 4836
1504
+ 4840
1505
+ 4841
1506
+ 4842
1507
+ 4843
1508
+ 4845
1509
+ 4848
1510
+ 4849
1511
+ 4850
1512
+ 4851
1513
+ 4852
1514
+ 4853
1515
+ 4857
1516
+ 4858
1517
+ 4859
1518
+ 4867
1519
+ 4868
1520
+ 4869
1521
+ 4870
1522
+ 4873
1523
+ 4878
1524
+ 4881
1525
+ 4882
1526
+ 4884
1527
+ 4886
1528
+ 4887
1529
+ 4890
1530
+ 4892
1531
+ 4893
1532
+ 4894
1533
+ 4895
1534
+ 4905
1535
+ 4912
1536
+ 4916
1537
+ 4918
1538
+ 4919
1539
+ 4920
1540
+ 4921
1541
+ 4923
1542
+ 4925
1543
+ 4926
1544
+ 4927
1545
+ 4929
1546
+ 4930
1547
+ 4935
1548
+ 4936
1549
+ 4942
1550
+ 4943
1551
+ 4946
1552
+ 4949
1553
+ 4954
1554
+ 4955
1555
+ 4958
1556
+ 4962
1557
+ 4964
1558
+ 4967
1559
+ 4969
1560
+ 4974
1561
+ 4976
1562
+ 4978
1563
+ 4979
1564
+ 4980
1565
+ 4983
1566
+ 4984
1567
+ 4989
1568
+ 4990
1569
+ 4992
1570
+ 4993
1571
+ 4994
1572
+ 5000
1573
+ 5001
1574
+ 5005
1575
+ 5009
1576
+ 5011
1577
+ 5012
1578
+ 5014
1579
+ 5019
1580
+ 5021
1581
+ 5025
1582
+ 5029
1583
+ 5030
1584
+ 5031
1585
+ 5032
1586
+ 5033
1587
+ 5034
1588
+ 5036
1589
+ 5037
1590
+ 5042
1591
+ 5046
1592
+ 5047
1593
+ 5048
1594
+ 5049
1595
+ 5050
1596
+ 5053
1597
+ 5055
1598
+ 5056
1599
+ 5057
1600
+ 5058
1601
+ 5060
1602
+ 5061
1603
+ 5064
1604
+ 5065
1605
+ 5066
1606
+ 5068
1607
+ 5071
1608
+ 5072
1609
+ 5079
1610
+ 5080
1611
+ 5081
1612
+ 5084
1613
+ 5085
1614
+ 5087
1615
+ 5088
1616
+ 5089
1617
+ 5092
1618
+ 5094
1619
+ 5095
1620
+ 5097
1621
+ 5099
1622
+ 5100
1623
+ 5103
1624
+ 5105
1625
+ 5107
1626
+ 5108
1627
+ 5109
1628
+ 5113
1629
+ 5115
1630
+ 5117
1631
+ 5119
1632
+ 5121
1633
+ 5124
1634
+ 5135
1635
+ 5140
1636
+ 5148
1637
+ 5149
1638
+ 5152
1639
+ 5157
1640
+ 5158
1641
+ 5159
1642
+ 5160
1643
+ 5162
1644
+ 5163
1645
+ 5166
1646
+ 5167
1647
+ 5168
1648
+ 5170
1649
+ 5172
1650
+ 5173
1651
+ 5175
1652
+ 5177
1653
+ 5178
1654
+ 5180
1655
+ 5181
1656
+ 5182
1657
+ 5185
1658
+ 5186
1659
+ 5187
1660
+ 5188
1661
+ 5192
1662
+ 5193
1663
+ 5194
1664
+ 5196
1665
+ 5201
1666
+ 5203
1667
+ 5205
1668
+ 5206
1669
+ 5209
1670
+ 5212
1671
+ 5213
1672
+ 5215
1673
+ 5220
1674
+ 5222
1675
+ 5224
1676
+ 5227
1677
+ 5229
1678
+ 5234
1679
+ 5237
1680
+ 5239
1681
+ 5240
1682
+ 5243
1683
+ 5244
1684
+ 5245
1685
+ 5246
1686
+ 5248
1687
+ 5253
1688
+ 5256
1689
+ 5259
1690
+ 5260
1691
+ 5261
1692
+ 5264
1693
+ 5265
1694
+ 5267
1695
+ 5272
1696
+ 5274
1697
+ 5275
1698
+ 5277
1699
+ 5278
1700
+ 5279
1701
+ 5281
1702
+ 5283
1703
+ 5284
1704
+ 5285
1705
+ 5287
1706
+ 5290
1707
+ 5292
1708
+ 5295
1709
+ 5297
1710
+ 5298
1711
+ 5300
1712
+ 5302
1713
+ 5303
1714
+ 5306
1715
+ 5310
1716
+ 5311
1717
+ 5312
1718
+ 5316
1719
+ 5324
1720
+ 5325
1721
+ 5329
1722
+ 5332
1723
+ 5334
1724
+ 5337
1725
+ 5338
1726
+ 5340
1727
+ 5341
1728
+ 5342
1729
+ 5343
1730
+ 5344
1731
+ 5346
1732
+ 5347
1733
+ 5348
1734
+ 5354
1735
+ 5355
1736
+ 5358
1737
+ 5365
1738
+ 5367
1739
+ 5368
1740
+ 5369
1741
+ 5379
1742
+ 5381
1743
+ 5382
1744
+ 5384
1745
+ 5388
1746
+ 5389
1747
+ 5393
1748
+ 5394
1749
+ 5395
1750
+ 5396
1751
+ 5397
1752
+ 5398
1753
+ 5400
1754
+ 5401
1755
+ 5403
1756
+ 5406
1757
+ 5407
1758
+ 5408
1759
+ 5409
1760
+ 5410
1761
+ 5411
1762
+ 5412
1763
+ 5413
1764
+ 5414
1765
+ 5417
1766
+ 5418
1767
+ 5419
1768
+ 5420
1769
+ 5421
1770
+ 5422
1771
+ 5423
1772
+ 5424
1773
+ 5425
1774
+ 5426
1775
+ 5427
1776
+ 5428
1777
+ 5429
1778
+ 5430
1779
+ 5433
1780
+ 5434
1781
+ 5436
1782
+ 5438
1783
+ 5441
1784
+ 5444
1785
+ 5445
1786
+ 5446
1787
+ 5447
1788
+ 5450
1789
+ 5452
1790
+ 5453
1791
+ 5458
1792
+ 5459
1793
+ 5460
1794
+ 5461
1795
+ 5463
1796
+ 5466
1797
+ 5469
1798
+ 5470
1799
+ 5471
1800
+ 5472
1801
+ 5473
1802
+ 5474
1803
+ 5477
1804
+ 5479
1805
+ 5480
1806
+ 5484
1807
+ 5488
1808
+ 5489
1809
+ 5493
1810
+ 5494
1811
+ 5495
1812
+ 5496
1813
+ 5497
1814
+ 5498
1815
+ 5500
1816
+ 5505
1817
+ 5507
1818
+ 5513
1819
+ 5519
1820
+ 5520
1821
+ 5521
1822
+ 5526
1823
+ 5530
1824
+ 5536
1825
+ 5538
1826
+ 5539
1827
+ 5540
1828
+ 5541
1829
+ 5550
1830
+ 5553
1831
+ 5555
1832
+ 5556
1833
+ 5558
1834
+ 5560
1835
+ 5567
1836
+ 5568
1837
+ 5570
1838
+ 5571
1839
+ 5573
1840
+ 5575
1841
+ 5576
1842
+ 5577
1843
+ 5578
1844
+ 5579
1845
+ 5580
1846
+ 5585
1847
+ 5587
1848
+ 5588
1849
+ 5589
1850
+ 5591
1851
+ 5592
1852
+ 5594
1853
+ 5595
1854
+ 5599
1855
+ 5600
1856
+ 5602
1857
+ 5605
1858
+ 5606
1859
+ 5608
1860
+ 5609
1861
+ 5611
1862
+ 5613
1863
+ 5614
1864
+ 5615
1865
+ 5617
1866
+ 5618
1867
+ 5621
1868
+ 5624
1869
+ 5625
1870
+ 5626
1871
+ 5628
1872
+ 5631
1873
+ 5638
1874
+ 5641
1875
+ 5642
1876
+ 5643
1877
+ 5644
1878
+ 5645
1879
+ 5646
1880
+ 5647
1881
+ 5648
1882
+ 5649
1883
+ 5654
1884
+ 5655
1885
+ 5657
1886
+ 5658
1887
+ 5660
1888
+ 5664
1889
+ 5667
1890
+ 5668
1891
+ 5673
1892
+ 5674
1893
+ 5678
1894
+ 5679
1895
+ 5682
1896
+ 5683
1897
+ 5690
1898
+ 5691
1899
+ 5693
1900
+ 5695
1901
+ 5697
1902
+ 5702
1903
+ 5703
1904
+ 5705
1905
+ 5706
1906
+ 5709
1907
+ 5713
1908
+ 5715
1909
+ 5717
1910
+ 5718
1911
+ 5721
1912
+ 5722
1913
+ 5724
1914
+ 5725
1915
+ 5726
1916
+ 5728
1917
+ 5733
1918
+ 5735
1919
+ 5736
1920
+ 5738
1921
+ 5740
1922
+ 5742
1923
+ 5746
1924
+ 5750
1925
+ 5752
1926
+ 5753
1927
+ 5754
1928
+ 5755
1929
+ 5757
1930
+ 5759
1931
+ 5760
1932
+ 5762
1933
+ 5763
1934
+ 5768
1935
+ 5770
1936
+ 5771
1937
+ 5772
1938
+ 5774
1939
+ 5781
1940
+ 5782
1941
+ 5784
1942
+ 5786
1943
+ 5787
1944
+ 5789
1945
+ 5792
1946
+ 5793
1947
+ 5794
1948
+ 5798
1949
+ 5802
1950
+ 5804
1951
+ 5809
1952
+ 5810
1953
+ 5814
1954
+ 5817
1955
+ 5819
1956
+ 5821
1957
+ 5828
1958
+ 5836
1959
+ 5837
1960
+ 5838
1961
+ 5839
1962
+ 5840
1963
+ 5841
1964
+ 5843
1965
+ 5844
1966
+ 5846
1967
+ 5847
1968
+ 5848
1969
+ 5936
1970
+ 5953
1971
+ 5956
1972
+ 5961
1973
+ 5962
1974
+ 5965
1975
+ 5976
1976
+ 5978
1977
+ 6370
1978
+ 6386
1979
+ 6390
1980
+ 6396
1981
+ 6397
1982
+ 6404
1983
+ 6409
1984
+ 6423
1985
+ 6425
1986
+ 6426
1987
+ 6427
1988
+ 6432
1989
+ 6436
1990
+ 6444
1991
+ 6447
1992
+ 6449
1993
+ 6450
analysis/compare_anupam_clusters/materials_data_anupam's_fingerprints.csv ADDED
The diff for this file is too large to render. See raw diff
 
analysis/genetic_tree_plot.py ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ # coding: utf-8
3
+
4
+ # In[1]:
5
+
6
+
7
+ #get_ipython().system('pip install hdbscan')
8
+ #get_ipython().system('pip install pymatgen')
9
+
10
+
11
+ # In[2]:
12
+
13
+
14
+ import hdbscan
15
+ import pandas as pd
16
+ import numpy as np
17
+ #%matplotlib ipympl
18
+ #%matplotlib notebook
19
+ import matplotlib
20
+ import matplotlib.pyplot as plt
21
+ from sklearn import manifold
22
+ from ipywidgets import interact, Output
23
+ from IPython.display import clear_output
24
+
25
+
26
+ from sklearn import manifold
27
+ from sklearn import decomposition
28
+ from sklearn import metrics
29
+ from functools import partial
30
+ import hdbscan
31
+ #from s_dbw import S_Dbw
32
+ #from internal_validation import internalIndex
33
+ import matplotlib.pyplot as plt
34
+ from matplotlib.pyplot import figure
35
+ import pandas
36
+ import networkx as nx
37
+ #import seaborn as sns
38
+ #from scipy.spatial.distance import euclidean
39
+ from matplotlib.colors import LinearSegmentedColormap
40
+ from ete3 import Tree, TreeStyle, NodeStyle
41
+
42
+ print ('import_complete')
43
+
44
+
45
+ FINGERPRINT_LENGTH = 60
46
+
47
+ #FINGERPRINT_NAME = "functional_10dpi_bernoulli_VAE_L={0}".format(FINGERPRINT_LENGTH)
48
+ #FINGERPRINT_NAME = "224_2channel_resnet_L={0}".format(FINGERPRINT_LENGTH)
49
+ FINGERPRINT_NAME = "all_k_branches_histogram_-8_to_8".format(FINGERPRINT_LENGTH)
50
+ #FINGERPRINT_NAME = "128x128_random_erase_resnet18_VAE_L={0}".format(FINGERPRINT_LENGTH)
51
+
52
+ PERPLEXITY = 30
53
+ FLAT_ONLY = True
54
+ BORING_COLUMNS = ["flat_segments", "flatness_score", "binary_flatness", "horz_flat_seg", "exfoliation_eg", "A", "B", "C", "D", "E", "F"]
55
+ INPUT_NAME = f"{FINGERPRINT_NAME}_perplexity_{PERPLEXITY}_length_{FINGERPRINT_LENGTH}.csv"
56
+
57
+
58
+ # ## Load Data
59
+
60
+
61
+ df = pd.read_csv(f"{INPUT_NAME}", index_col="ID")
62
+ if FLAT_ONLY:
63
+ df = df[df.horz_flat_seg>0]
64
+ df.head()
65
+
66
+
67
+
68
+
69
+
70
+ # ## Cluster
71
+ ###################################
72
+ #### HDBSCAN
73
+ MS=4
74
+ SS=3
75
+
76
+ fingerprint_cols = [str(i) for i in range(FINGERPRINT_LENGTH)]
77
+ BORING_COLUMNS += fingerprint_cols
78
+
79
+
80
+ # ML print
81
+ # clusterer = hdbscan.HDBSCAN(algorithm='best', alpha=1.0, approx_min_span_tree=True,\
82
+ # gen_min_span_tree=False, leaf_size=40, metric='minkowski', cluster_selection_method='leaf', min_cluster_size=6, min_samples=2, p=0.2, cluster_selection_epsilon=0.0)
83
+ # #clusterer.fit(30*np.tanh(df[fingerprint_cols])/30)
84
+ # clusterer.fit(df[fingerprint_cols])
85
+
86
+ # DOS old print
87
+ clusterer = hdbscan.HDBSCAN(algorithm='best', alpha=1.0, approx_min_span_tree=True,\
88
+ gen_min_span_tree=True, leaf_size=40, metric='minkowski', cluster_selection_method='leaf', min_cluster_size=4, min_samples=3, p=0.2)
89
+
90
+
91
+
92
+
93
+ db = clusterer.fit(df[fingerprint_cols])
94
+ labels = db.labels_
95
+
96
+ df["labels"] = db.labels_
97
+ df["member_strength"] = db.probabilities_
98
+ print(len(df[df.labels==-1]))
99
+ #################
100
+ #### plot objects
101
+ cond_tree=db.condensed_tree_
102
+ plot_obj=cond_tree.get_plot_data()
103
+ #single_link_tree=db.single_linkage_tree_
104
+
105
+
106
+ #########################################
107
+ ############## Colormap
108
+ ##############################
109
+ import matplotlib
110
+ cmap = plt.cm.get_cmap('turbo')
111
+ norm = matplotlib.colors.Normalize(vmin=min(labels), vmax=max(labels))
112
+
113
+ ##################################
114
+ ###### Pandas data
115
+ ##################################
116
+ panda_data=cond_tree.to_pandas()
117
+ #print(G.number_of_nodes())
118
+ #print(panda_data)
119
+ selected_clusters=cond_tree._select_clusters()
120
+ G1 = panda_data[panda_data['child_size'] > 1]
121
+ #New_Nx=nx.from_pandas_edgelist(G1,'parent','child',['lambda_val', 'child_size'])
122
+ #nx.write_edgelist(New_Nx,'New_edgelist', encoding = 'latin-1')
123
+
124
+ len_G1=[]
125
+ cluster_id=[]
126
+ for ind1 in G1.index:
127
+ len_G1.append(0.1)
128
+ if G1.at[ind1,'child'] in selected_clusters:
129
+ cluster_id.append(str(selected_clusters.index(G1.at[ind1,'child'])))
130
+ else:
131
+ cluster_id.append('-1')
132
+ print(cluster_id)
133
+ G1.insert(4, 'dist_G1', len_G1)
134
+ G1.insert(5, 'cluster_id', cluster_id)
135
+ G2=G1.copy()
136
+ print(G2)
137
+ del G1['cluster_id']
138
+ del G1['lambda_val']
139
+ del G1['child_size']
140
+ g1_list=G1.values.tolist()
141
+
142
+ # In[ ]:
143
+
144
+
145
+
146
+ ##############################
147
+ ################ ETE treee from parent child relations
148
+ tree = Tree.from_parent_child_table(g1_list)
149
+ #tree.write(format=9,outfile='new_tree.nw')
150
+ print(G2)
151
+ for node in tree.traverse():
152
+ nstyle = NodeStyle()
153
+ if node.is_leaf():
154
+ index1=G2.index[G2['child'] == int(node.name)]
155
+ node.name=G2.at[index1[0],'cluster_id']
156
+ #nstyle = NodeStyle()
157
+ #print(int(node.name))
158
+ #print(matplotlib.colors.rgb2hex(cmap(norm(int(node.name)))))
159
+ nstyle["fgcolor"] = str(matplotlib.colors.rgb2hex(cmap(norm(int(node.name)))))
160
+ #nstyle['fgcolor']='#FF0000'
161
+ nstyle["size"] = G2.at[index1[0],'child_size']/2
162
+ else:
163
+ nstyle["fgcolor"] ='black'
164
+ node.set_style(nstyle)
165
+ tree.write(format=1,outfile='new_tree.nw')
166
+ #################################
167
+ ################### Plot
168
+ ts = TreeStyle()
169
+ ts.mode='c'
170
+ ts.arc_start = -180 # 0 degrees = 3 o'clock
171
+ ts.arc_span = 360
172
+ ts.scale = 40
173
+ ts.show_leaf_name=True
174
+ tree.show(tree_style=ts)
175
+
176
+
analysis/new_tree.nw ADDED
@@ -0,0 +1 @@
 
 
1
+ (((((0:0.1,(((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((1:0.1,((((((((((((((((((((((((((((((((((((((((((((((((((((((((((((2:0.1,3:0.1)5743.0:0.1,(4:0.1,5:0.1)5744.0:0.1)5741.0:0.1,6:0.1)5739.0:0.1,7:0.1)5731.0:0.1,8:0.1)5727.0:0.1,(9:0.1,10:0.1)5728.0:0.1)5711.0:0.1,((11:0.1,12:0.1)5719.0:0.1,13:0.1)5712.0:0.1)5709.0:0.1,((14:0.1,15:0.1)5717.0:0.1,16:0.1)5710.0:0.1)5707.0:0.1,17:0.1)5705.0:0.1,18:0.1)5701.0:0.1,(19:0.1,((20:0.1,21:0.1)5713.0:0.1,(((22:0.1,23:0.1)5723.0:0.1,(24:0.1,25:0.1)5724.0:0.1)5715.0:0.1,26:0.1)5714.0:0.1)5704.0:0.1)5702.0:0.1)5699.0:0.1,27:0.1)5697.0:0.1,28:0.1)5693.0:0.1,(29:0.1,30:0.1)5694.0:0.1)5691.0:0.1,31:0.1)5683.0:0.1,(32:0.1,((33:0.1,34:0.1)5687.0:0.1,35:0.1)5686.0:0.1)5684.0:0.1)5681.0:0.1,36:0.1)5679.0:0.1,37:0.1)5671.0:0.1,((38:0.1,(39:0.1,40:0.1)5676.0:0.1)5673.0:0.1,41:0.1)5672.0:0.1)5669.0:0.1,42:0.1)5667.0:0.1,43:0.1)5665.0:0.1,44:0.1)5663.0:0.1,45:0.1)5661.0:0.1,46:0.1)5659.0:0.1,47:0.1)5657.0:0.1,48:0.1)5655.0:0.1,49:0.1)5653.0:0.1,50:0.1)5651.0:0.1,51:0.1)5649.0:0.1,52:0.1)5647.0:0.1,53:0.1)5645.0:0.1,54:0.1)5643.0:0.1,55:0.1)5641.0:0.1,56:0.1)5639.0:0.1,57:0.1)5637.0:0.1,58:0.1)5635.0:0.1,59:0.1)5633.0:0.1,60:0.1)5631.0:0.1,61:0.1)5629.0:0.1,62:0.1)5627.0:0.1,63:0.1)5623.0:0.1,(64:0.1,65:0.1)5624.0:0.1)5613.0:0.1,(((66:0.1,67:0.1)5617.0:0.1,68:0.1)5615.0:0.1,(69:0.1,70:0.1)5616.0:0.1)5614.0:0.1)5609.0:0.1,(71:0.1,72:0.1)5610.0:0.1)5605.0:0.1,(73:0.1,74:0.1)5606.0:0.1)5603.0:0.1,75:0.1)5601.0:0.1,76:0.1)5599.0:0.1,77:0.1)5597.0:0.1,78:0.1)5595.0:0.1,79:0.1)5593.0:0.1,80:0.1)5589.0:0.1,(81:0.1,82:0.1)5590.0:0.1)5585.0:0.1,83:0.1)5579.0:0.1,84:0.1)5577.0:0.1,85:0.1)5567.0:0.1,((86:0.1,(87:0.1,((88:0.1,(89:0.1,90:0.1)5584.0:0.1)5581.0:0.1,91:0.1)5576.0:0.1)5574.0:0.1)5571.0:0.1,92:0.1)5568.0:0.1)5565.0:0.1,(93:0.1,94:0.1)5566.0:0.1)5561.0:0.1,(95:0.1,96:0.1)5562.0:0.1)5557.0:0.1,(97:0.1,98:0.1)5558.0:0.1)5553.0:0.1,(99:0.1,100:0.1)5554.0:0.1)5546.0:0.1)5541.0:0.1,101:0.1)5535.0:0.1,102:0.1)5529.0:0.1,103:0.1)5525.0:0.1,104:0.1)5521.0:0.1,105:0.1)5519.0:0.1,(106:0.1,107:0.1)5520.0:0.1)5517.0:0.1,108:0.1)5515.0:0.1,109:0.1)5509.0:0.1,110:0.1)5505.0:0.1,111:0.1)5503.0:0.1,112:0.1)5497.0:0.1,113:0.1)5495.0:0.1,114:0.1)5493.0:0.1,115:0.1)5491.0:0.1,116:0.1)5485.0:0.1,(117:0.1,118:0.1)5486.0:0.1)5479.0:0.1,119:0.1)5477.0:0.1,120:0.1)5465.0:0.1,121:0.1)5463.0:0.1,122:0.1)5459.0:0.1,123:0.1)5457.0:0.1,124:0.1)5449.0:0.1,125:0.1)5445.0:0.1,(((126:0.1,127:0.1)5451.0:0.1,128:0.1)5447.0:0.1,129:0.1)5446.0:0.1)5441.0:0.1,((130:0.1,131:0.1)5453.0:0.1,(((((132:0.1,((((133:0.1,(((((((((134:0.1,135:0.1)5547.0:0.1,(136:0.1,137:0.1)5548.0:0.1)5543.0:0.1,138:0.1)5531.0:0.1,(139:0.1,(140:0.1,(141:0.1,142:0.1)5538.0:0.1)5534.0:0.1)5532.0:0.1)5527.0:0.1,143:0.1)5513.0:0.1,144:0.1)5511.0:0.1,145:0.1)5507.0:0.1,146:0.1)5501.0:0.1,147:0.1)5500.0:0.1)5489.0:0.1,148:0.1)5483.0:0.1,149:0.1)5481.0:0.1,150:0.1)5476.0:0.1)5473.0:0.1,151:0.1)5471.0:0.1,152:0.1)5469.0:0.1,153:0.1)5467.0:0.1,154:0.1)5454.0:0.1)5442.0:0.1)5439.0:0.1,(155:0.1,156:0.1)5440.0:0.1)5437.0:0.1,157:0.1)5435.0:0.1,158:0.1)5433.0:0.1,159:0.1)5431.0:0.1,160:0.1)5429.0:0.1,161:0.1)5423.0:0.1,162:0.1)5419.0:0.1,(163:0.1,((164:0.1,165:0.1)5425.0:0.1,166:0.1)5422.0:0.1)5420.0:0.1)5413.0:0.1,((167:0.1,168:0.1)5415.0:0.1,169:0.1)5414.0:0.1)5405.0:0.1,(170:0.1,(171:0.1,172:0.1)5408.0:0.1)5406.0:0.1)5401.0:0.1,173:0.1)5399.0:0.1,174:0.1)5395.0:0.1,(((175:0.1,176:0.1)5403.0:0.1,177:0.1)5397.0:0.1,178:0.1)5396.0:0.1)5393.0:0.1,179:0.1)5391.0:0.1,180:0.1)5389.0:0.1,181:0.1)5387.0:0.1,182:0.1)5385.0:0.1,183:0.1)5379.0:0.1,(184:0.1,(185:0.1,186:0.1)5382.0:0.1)5380.0:0.1)5375.0:0.1,(187:0.1,188:0.1)5376.0:0.1)5373.0:0.1,189:0.1)5371.0:0.1,190:0.1)5369.0:0.1,191:0.1)5365.0:0.1,(192:0.1,193:0.1)5366.0:0.1)5363.0:0.1,194:0.1)5361.0:0.1,195:0.1)5359.0:0.1,196:0.1)5357.0:0.1,197:0.1)5355.0:0.1,198:0.1)5353.0:0.1,199:0.1)5349.0:0.1,(200:0.1,201:0.1)5350.0:0.1)5347.0:0.1,202:0.1)5345.0:0.1,203:0.1)5343.0:0.1,204:0.1)5341.0:0.1,205:0.1)5339.0:0.1,206:0.1)5337.0:0.1,207:0.1)5335.0:0.1,208:0.1)5327.0:0.1,((209:0.1,210:0.1)5329.0:0.1,(211:0.1,212:0.1)5330.0:0.1)5328.0:0.1)5325.0:0.1,213:0.1)5323.0:0.1,214:0.1)5321.0:0.1,215:0.1)5319.0:0.1,216:0.1)5317.0:0.1,217:0.1)5315.0:0.1,218:0.1)5313.0:0.1,219:0.1)5311.0:0.1,220:0.1)5309.0:0.1,221:0.1)5307.0:0.1,222:0.1)5305.0:0.1,223:0.1)5303.0:0.1,224:0.1)5299.0:0.1,(225:0.1,226:0.1)5300.0:0.1)5297.0:0.1,227:0.1)5295.0:0.1,228:0.1)5293.0:0.1,229:0.1)5291.0:0.1,230:0.1)5289.0:0.1,231:0.1)5287.0:0.1,232:0.1)5285.0:0.1,233:0.1)5283.0:0.1,234:0.1)5281.0:0.1,235:0.1)5280.0:0.1)5277.0:0.1,236:0.1)5275.0:0.1,237:0.1)5273.0:0.1,238:0.1)5271.0:0.1,239:0.1);
analysis/report_figures/2d_hist_hdbscan_params.png ADDED
analysis/report_figures/2d_hist_hdbscan_params2.png ADDED
analysis/report_figures/MCS=4_MS=4_clusters_big_table.png ADDED

Git LFS Details

  • SHA256: 641fdf83f903fbc849207736c819c1ec9b85d65a47eb7c3d936feec66522bc19
  • Pointer size: 132 Bytes
  • Size of remote file: 4.54 MB
analysis/report_figures/MCS=6_MS=2_clusters_big_table.png ADDED

Git LFS Details

  • SHA256: feb9cbecfa69ad483413035fe6a2ab5e859bedf18665cc217805b80c8171f037
  • Pointer size: 132 Bytes
  • Size of remote file: 2.19 MB
analysis/report_figures/NEW_OLD_PRINT_MCS_4_MS_3_clusters_big_table.png ADDED
analysis/report_figures/OLD_PRINT_MCS_4_MS_3_clusters_big_table.png ADDED
analysis/report_figures/first print pipeline figure.png ADDED
analysis/report_figures/latent space.png ADDED
analysis/report_figures/old_print.png ADDED
analysis/report_figures/old_print_tree_plot.png ADDED
analysis/report_figures/old_print_tsne.png ADDED
analysis/report_figures/out1.png ADDED
analysis/report_figures/recon.png ADDED
analysis/report_figures/report pseudo flow diagram.png ADDED
analysis/report_figures/report pseudo flow diagram_2.png ADDED
analysis/report_figures/resnet_2_channel_L=96_tsne.png ADDED
analysis/report_figures/tsne_L96_noised_AE.png ADDED
autoencoder/model.py ADDED
@@ -0,0 +1,597 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python
2
+ """
3
+ Resnet based autoencoder models.
4
+
5
+ File originally from https://github.com/Horizon2333/imagenet-autoencoder/blob/main/models/resnet.py.
6
+
7
+ Modifications:
8
+ - Adding `sigmoid` argument so `nn.BCEWithLogitsLoss` can be used
9
+ - Z_channels argument to fingerprint size can be varied
10
+ - Create ResNetVAE class (which performed worse for clustering unfortunately).
11
+ """
12
+
13
+ import torch
14
+ import torch.nn as nn
15
+
16
+ def BuildAutoEncoder(arch, sigmoid=False, z_channels=None):
17
+ if arch in ["resnet18", "resnet34", "resnet50", "resnet101", "resnet152"]:
18
+ configs, bottleneck = get_configs(arch)
19
+ return ResNetAutoEncoder(configs, bottleneck, sigmoid, z_channels=z_channels)
20
+ return None
21
+
22
+ def get_configs(arch='resnet50'):
23
+
24
+ # True or False means wether to use BottleNeck
25
+
26
+ if arch == 'resnet18':
27
+ return [2, 2, 2, 2], False
28
+ elif arch == 'resnet34':
29
+ return [3, 4, 6, 3], False
30
+ elif arch == 'resnet50':
31
+ return [3, 4, 6, 3], True
32
+ elif arch == 'resnet101':
33
+ return [3, 4, 23, 3], True
34
+ elif arch == 'resnet152':
35
+ return [3, 8, 36, 3], True
36
+ else:
37
+ raise ValueError("Undefined model")
38
+
39
+ class ResNetAutoEncoder(nn.Module):
40
+
41
+ def __init__(self, configs, bottleneck, sigmoid, z_channels=None):
42
+
43
+ super(ResNetAutoEncoder, self).__init__()
44
+
45
+ self.encoder = ResNetEncoder(configs=configs, bottleneck=bottleneck, z_channels=z_channels)
46
+ self.decoder = ResNetDecoder(configs=configs[::-1], bottleneck=bottleneck, sigmoid=sigmoid, z_channels=z_channels)
47
+
48
+ def forward(self, x):
49
+
50
+ x = self.encoder(x)
51
+ x = self.decoder(x)
52
+
53
+ return x
54
+
55
+ class ResnetVAE(ResNetAutoEncoder):
56
+ def __init__(self, configs, bottleneck, sigmoid, z_channels):
57
+
58
+ super(ResnetVAE, self).__init__(configs, bottleneck, sigmoid)
59
+
60
+ self.z_channels = z_channels
61
+ self.z_dim = z_channels * 4 * 4 # for 128x128 images
62
+
63
+
64
+ self.encoder = ResNetEncoder(configs=configs, bottleneck=bottleneck, z_channels=z_channels*2)
65
+ self.decoder = ResNetDecoder(configs=configs[::-1], bottleneck=bottleneck, sigmoid=sigmoid, z_channels=z_channels)
66
+
67
+ self.flatten = nn.Flatten()
68
+
69
+ def forward(self, x):
70
+ x = self.encoder(x)
71
+ mu_logvar = self.flatten(x)
72
+ mu = mu_logvar[:, :self.z_dim]
73
+ logvar = mu_logvar[:, self.z_dim:]
74
+
75
+ z = self.reparametrize(mu, logvar)
76
+ res = z.view(z.shape[0], self.z_channels, 4, 4)
77
+ x_recon = self.decoder(res)
78
+
79
+ return x_recon, mu, logvar
80
+
81
+ def reparametrize(self, mu, logvar):
82
+ std = torch.exp(0.5 * logvar)
83
+ eps = torch.randn_like(std)
84
+ return eps * std + mu
85
+
86
+
87
+ class ResNet(nn.Module):
88
+ """
89
+ Normal resnet for classification - not used
90
+ """
91
+ def __init__(self, configs, bottleneck=False, num_classes=1000):
92
+ super(ResNet, self).__init__()
93
+
94
+ self.encoder = ResNetEncoder(configs, bottleneck)
95
+
96
+ self.avpool = nn.AdaptiveAvgPool2d((1,1))
97
+
98
+ if bottleneck:
99
+ self.fc = nn.Linear(in_features=2048, out_features=num_classes)
100
+ else:
101
+ self.fc = nn.Linear(in_features=512, out_features=num_classes)
102
+
103
+ for m in self.modules():
104
+ if isinstance(m, nn.Conv2d):
105
+ nn.init.kaiming_normal_(m.weight, mode="fan_in", nonlinearity="relu")
106
+ if m.bias is not None:
107
+ nn.init.constant_(m.bias, 0)
108
+ elif isinstance(m, nn.BatchNorm2d):
109
+ nn.init.constant_(m.weight, 1)
110
+ nn.init.constant_(m.bias, 0)
111
+ elif isinstance(m, nn.Linear):
112
+ nn.init.kaiming_normal_(m.weight, mode="fan_in", nonlinearity="relu")
113
+ nn.init.constant_(m.bias, 0)
114
+
115
+ def forward(self, x):
116
+
117
+ x = self.encoder(x)
118
+
119
+ x = self.avpool(x)
120
+
121
+ x = torch.flatten(x, 1)
122
+
123
+ x = self.fc(x)
124
+
125
+ return x
126
+
127
+
128
+ class ResNetEncoder(nn.Module):
129
+
130
+ def __init__(self, configs, bottleneck=False, z_channels=None):
131
+ super(ResNetEncoder, self).__init__()
132
+
133
+ if len(configs) != 4:
134
+ raise ValueError("Only 4 layers can be configued")
135
+
136
+ self.conv1 = nn.Sequential(
137
+ nn.Conv2d(in_channels=3, out_channels=64, kernel_size=7, stride=2, padding=3, bias=False),
138
+ nn.BatchNorm2d(num_features=64),
139
+ nn.ReLU(inplace=True),
140
+ )
141
+
142
+ if not z_channels:
143
+ if bottleneck: z_channels = 2048
144
+ else: z_channels = 512
145
+
146
+ if bottleneck:
147
+
148
+ self.conv2 = EncoderBottleneckBlock(in_channels=64, hidden_channels=64, up_channels=256, layers=configs[0], downsample_method="pool")
149
+ self.conv3 = EncoderBottleneckBlock(in_channels=256, hidden_channels=128, up_channels=512, layers=configs[1], downsample_method="conv")
150
+ self.conv4 = EncoderBottleneckBlock(in_channels=512, hidden_channels=256, up_channels=1024, layers=configs[2], downsample_method="conv")
151
+ self.conv5 = EncoderBottleneckBlock(in_channels=1024, hidden_channels=512, up_channels=z_channels, layers=configs[3], downsample_method="conv")
152
+
153
+ else:
154
+
155
+ self.conv2 = EncoderResidualBlock(in_channels=64, hidden_channels=64, layers=configs[0], downsample_method="pool")
156
+ self.conv3 = EncoderResidualBlock(in_channels=64, hidden_channels=128, layers=configs[1], downsample_method="conv")
157
+ self.conv4 = EncoderResidualBlock(in_channels=128, hidden_channels=256, layers=configs[2], downsample_method="conv")
158
+ self.conv5 = EncoderResidualBlock(in_channels=256, hidden_channels=z_channels, layers=configs[3], downsample_method="conv")
159
+
160
+ def forward(self, x):
161
+
162
+ x = self.conv1(x)
163
+ x = self.conv2(x)
164
+ x = self.conv3(x)
165
+ x = self.conv4(x)
166
+ x = self.conv5(x)
167
+
168
+ return x
169
+
170
+ class ResNetDecoder(nn.Module):
171
+
172
+ def __init__(self, configs, bottleneck=False, sigmoid=False, z_channels=None):
173
+ super(ResNetDecoder, self).__init__()
174
+
175
+ if len(configs) != 4:
176
+ raise ValueError("Only 4 layers can be configued")
177
+
178
+ if not z_channels:
179
+ if bottleneck: z_channels = 2048
180
+ else: z_channels = 512
181
+
182
+ if bottleneck:
183
+
184
+ self.conv1 = DecoderBottleneckBlock(in_channels=z_channels, hidden_channels=512, down_channels=1024, layers=configs[0])
185
+ self.conv2 = DecoderBottleneckBlock(in_channels=1024, hidden_channels=256, down_channels=512, layers=configs[1])
186
+ self.conv3 = DecoderBottleneckBlock(in_channels=512, hidden_channels=128, down_channels=256, layers=configs[2])
187
+ self.conv4 = DecoderBottleneckBlock(in_channels=256, hidden_channels=64, down_channels=64, layers=configs[3])
188
+
189
+
190
+ else:
191
+
192
+ self.conv1 = DecoderResidualBlock(hidden_channels=z_channels, output_channels=256, layers=configs[0])
193
+ self.conv2 = DecoderResidualBlock(hidden_channels=256, output_channels=128, layers=configs[1])
194
+ self.conv3 = DecoderResidualBlock(hidden_channels=128, output_channels=64, layers=configs[2])
195
+ self.conv4 = DecoderResidualBlock(hidden_channels=64, output_channels=64, layers=configs[3])
196
+
197
+ self.conv5 = nn.Sequential(
198
+ nn.BatchNorm2d(num_features=64),
199
+ nn.ReLU(inplace=True),
200
+ nn.ConvTranspose2d(in_channels=64, out_channels=3, kernel_size=7, stride=2, padding=3, output_padding=1, bias=False),
201
+ )
202
+
203
+ if sigmoid:
204
+ self.gate = nn.Sigmoid()
205
+ else:
206
+ self.gate = nn.Identity()
207
+
208
+ def forward(self, x):
209
+
210
+ x = self.conv1(x)
211
+ x = self.conv2(x)
212
+ x = self.conv3(x)
213
+ x = self.conv4(x)
214
+ x = self.conv5(x)
215
+ x = self.gate(x)
216
+
217
+ return x
218
+
219
+ class EncoderResidualBlock(nn.Module):
220
+
221
+ def __init__(self, in_channels, hidden_channels, layers, downsample_method="conv"):
222
+ super(EncoderResidualBlock, self).__init__()
223
+
224
+ if downsample_method == "conv":
225
+
226
+ for i in range(layers):
227
+
228
+ if i == 0:
229
+ layer = EncoderResidualLayer(in_channels=in_channels, hidden_channels=hidden_channels, downsample=True)
230
+ else:
231
+ layer = EncoderResidualLayer(in_channels=hidden_channels, hidden_channels=hidden_channels, downsample=False)
232
+
233
+ self.add_module('%02d EncoderLayer' % i, layer)
234
+
235
+ elif downsample_method == "pool":
236
+
237
+ maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
238
+
239
+ self.add_module('00 MaxPooling', maxpool)
240
+
241
+ for i in range(layers):
242
+
243
+ if i == 0:
244
+ layer = EncoderResidualLayer(in_channels=in_channels, hidden_channels=hidden_channels, downsample=False)
245
+ else:
246
+ layer = EncoderResidualLayer(in_channels=hidden_channels, hidden_channels=hidden_channels, downsample=False)
247
+
248
+ self.add_module('%02d EncoderLayer' % (i+1), layer)
249
+
250
+ def forward(self, x):
251
+
252
+ for name, layer in self.named_children():
253
+
254
+ x = layer(x)
255
+
256
+ return x
257
+
258
+ class EncoderBottleneckBlock(nn.Module):
259
+
260
+ def __init__(self, in_channels, hidden_channels, up_channels, layers, downsample_method="conv"):
261
+ super(EncoderBottleneckBlock, self).__init__()
262
+
263
+ if downsample_method == "conv":
264
+
265
+ for i in range(layers):
266
+
267
+ if i == 0:
268
+ layer = EncoderBottleneckLayer(in_channels=in_channels, hidden_channels=hidden_channels, up_channels=up_channels, downsample=True)
269
+ else:
270
+ layer = EncoderBottleneckLayer(in_channels=up_channels, hidden_channels=hidden_channels, up_channels=up_channels, downsample=False)
271
+
272
+ self.add_module('%02d EncoderLayer' % i, layer)
273
+
274
+ elif downsample_method == "pool":
275
+
276
+ maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)
277
+
278
+ self.add_module('00 MaxPooling', maxpool)
279
+
280
+ for i in range(layers):
281
+
282
+ if i == 0:
283
+ layer = EncoderBottleneckLayer(in_channels=in_channels, hidden_channels=hidden_channels, up_channels=up_channels, downsample=False)
284
+ else:
285
+ layer = EncoderBottleneckLayer(in_channels=up_channels, hidden_channels=hidden_channels, up_channels=up_channels, downsample=False)
286
+
287
+ self.add_module('%02d EncoderLayer' % (i+1), layer)
288
+
289
+ def forward(self, x):
290
+
291
+ for name, layer in self.named_children():
292
+
293
+ x = layer(x)
294
+
295
+ return x
296
+
297
+ class DecoderResidualBlock(nn.Module):
298
+
299
+ def __init__(self, hidden_channels, output_channels, layers):
300
+ super(DecoderResidualBlock, self).__init__()
301
+
302
+ for i in range(layers):
303
+
304
+ if i == layers - 1:
305
+ layer = DecoderResidualLayer(hidden_channels=hidden_channels, output_channels=output_channels, upsample=True)
306
+ else:
307
+ layer = DecoderResidualLayer(hidden_channels=hidden_channels, output_channels=hidden_channels, upsample=False)
308
+
309
+ self.add_module('%02d EncoderLayer' % i, layer)
310
+
311
+ def forward(self, x):
312
+
313
+ for name, layer in self.named_children():
314
+
315
+ x = layer(x)
316
+
317
+ return x
318
+
319
+ class DecoderBottleneckBlock(nn.Module):
320
+
321
+ def __init__(self, in_channels, hidden_channels, down_channels, layers):
322
+ super(DecoderBottleneckBlock, self).__init__()
323
+
324
+ for i in range(layers):
325
+
326
+ if i == layers - 1:
327
+ layer = DecoderBottleneckLayer(in_channels=in_channels, hidden_channels=hidden_channels, down_channels=down_channels, upsample=True)
328
+ else:
329
+ layer = DecoderBottleneckLayer(in_channels=in_channels, hidden_channels=hidden_channels, down_channels=in_channels, upsample=False)
330
+
331
+ self.add_module('%02d EncoderLayer' % i, layer)
332
+
333
+
334
+ def forward(self, x):
335
+
336
+ for name, layer in self.named_children():
337
+
338
+ x = layer(x)
339
+
340
+ return x
341
+
342
+ class EncoderResidualLayer(nn.Module):
343
+
344
+ def __init__(self, in_channels, hidden_channels, downsample):
345
+ super(EncoderResidualLayer, self).__init__()
346
+
347
+ if downsample:
348
+ self.weight_layer1 = nn.Sequential(
349
+ nn.Conv2d(in_channels=in_channels, out_channels=hidden_channels, kernel_size=3, stride=2, padding=1, bias=False),
350
+ nn.BatchNorm2d(num_features=hidden_channels),
351
+ nn.ReLU(inplace=True),
352
+ )
353
+ else:
354
+ self.weight_layer1 = nn.Sequential(
355
+ nn.Conv2d(in_channels=in_channels, out_channels=hidden_channels, kernel_size=3, stride=1, padding=1, bias=False),
356
+ nn.BatchNorm2d(num_features=hidden_channels),
357
+ nn.ReLU(inplace=True),
358
+ )
359
+
360
+ self.weight_layer2 = nn.Sequential(
361
+ nn.Conv2d(in_channels=hidden_channels, out_channels=hidden_channels, kernel_size=3, stride=1, padding=1, bias=False),
362
+ nn.BatchNorm2d(num_features=hidden_channels),
363
+ )
364
+
365
+ if downsample:
366
+ self.downsample = nn.Sequential(
367
+ nn.Conv2d(in_channels=in_channels, out_channels=hidden_channels, kernel_size=1, stride=2, padding=0, bias=False),
368
+ nn.BatchNorm2d(num_features=hidden_channels),
369
+ )
370
+ else:
371
+ self.downsample = None
372
+
373
+ self.relu = nn.Sequential(
374
+ nn.ReLU(inplace=True)
375
+ )
376
+
377
+ def forward(self, x):
378
+
379
+ identity = x
380
+
381
+ x = self.weight_layer1(x)
382
+ x = self.weight_layer2(x)
383
+
384
+ if self.downsample is not None:
385
+ identity = self.downsample(identity)
386
+
387
+ x = x + identity
388
+
389
+ x = self.relu(x)
390
+
391
+ return x
392
+
393
+ class EncoderBottleneckLayer(nn.Module):
394
+
395
+ def __init__(self, in_channels, hidden_channels, up_channels, downsample):
396
+ super(EncoderBottleneckLayer, self).__init__()
397
+
398
+ if downsample:
399
+ self.weight_layer1 = nn.Sequential(
400
+ nn.Conv2d(in_channels=in_channels, out_channels=hidden_channels, kernel_size=1, stride=2, padding=0, bias=False),
401
+ nn.BatchNorm2d(num_features=hidden_channels),
402
+ nn.ReLU(inplace=True),
403
+ )
404
+ else:
405
+ self.weight_layer1 = nn.Sequential(
406
+ nn.Conv2d(in_channels=in_channels, out_channels=hidden_channels, kernel_size=1, stride=1, padding=0, bias=False),
407
+ nn.BatchNorm2d(num_features=hidden_channels),
408
+ nn.ReLU(inplace=True),
409
+ )
410
+
411
+ self.weight_layer2 = nn.Sequential(
412
+ nn.Conv2d(in_channels=hidden_channels, out_channels=hidden_channels, kernel_size=3, stride=1, padding=1, bias=False),
413
+ nn.BatchNorm2d(num_features=hidden_channels),
414
+ nn.ReLU(inplace=True),
415
+ )
416
+
417
+ self.weight_layer3 = nn.Sequential(
418
+ nn.Conv2d(in_channels=hidden_channels, out_channels=up_channels, kernel_size=1, stride=1, padding=0, bias=False),
419
+ nn.BatchNorm2d(num_features=up_channels),
420
+ )
421
+
422
+ if downsample:
423
+ self.downsample = nn.Sequential(
424
+ nn.Conv2d(in_channels=in_channels, out_channels=up_channels, kernel_size=1, stride=2, padding=0, bias=False),
425
+ nn.BatchNorm2d(num_features=up_channels),
426
+ )
427
+ elif (in_channels != up_channels):
428
+ self.downsample = None
429
+ self.up_scale = nn.Sequential(
430
+ nn.Conv2d(in_channels=in_channels, out_channels=up_channels, kernel_size=1, stride=1, padding=0, bias=False),
431
+ nn.BatchNorm2d(num_features=up_channels),
432
+ )
433
+ else:
434
+ self.downsample = None
435
+ self.up_scale = None
436
+
437
+ self.relu = nn.Sequential(
438
+ nn.ReLU(inplace=True)
439
+ )
440
+
441
+ def forward(self, x):
442
+
443
+ identity = x
444
+
445
+ x = self.weight_layer1(x)
446
+ x = self.weight_layer2(x)
447
+ x = self.weight_layer3(x)
448
+
449
+ if self.downsample is not None:
450
+ identity = self.downsample(identity)
451
+ elif self.up_scale is not None:
452
+ identity = self.up_scale(identity)
453
+
454
+ x = x + identity
455
+
456
+ x = self.relu(x)
457
+
458
+ return x
459
+
460
+ class DecoderResidualLayer(nn.Module):
461
+
462
+ def __init__(self, hidden_channels, output_channels, upsample):
463
+ super(DecoderResidualLayer, self).__init__()
464
+
465
+ self.weight_layer1 = nn.Sequential(
466
+ nn.BatchNorm2d(num_features=hidden_channels),
467
+ nn.ReLU(inplace=True),
468
+ nn.Conv2d(in_channels=hidden_channels, out_channels=hidden_channels, kernel_size=3, stride=1, padding=1, bias=False),
469
+ )
470
+
471
+ if upsample:
472
+ self.weight_layer2 = nn.Sequential(
473
+ nn.BatchNorm2d(num_features=hidden_channels),
474
+ nn.ReLU(inplace=True),
475
+ nn.ConvTranspose2d(in_channels=hidden_channels, out_channels=output_channels, kernel_size=3, stride=2, padding=1, output_padding=1, bias=False)
476
+ )
477
+ else:
478
+ self.weight_layer2 = nn.Sequential(
479
+ nn.BatchNorm2d(num_features=hidden_channels),
480
+ nn.ReLU(inplace=True),
481
+ nn.Conv2d(in_channels=hidden_channels, out_channels=output_channels, kernel_size=3, stride=1, padding=1, bias=False),
482
+ )
483
+
484
+ if upsample:
485
+ self.upsample = nn.Sequential(
486
+ nn.BatchNorm2d(num_features=hidden_channels),
487
+ nn.ReLU(inplace=True),
488
+ nn.ConvTranspose2d(in_channels=hidden_channels, out_channels=output_channels, kernel_size=1, stride=2, output_padding=1, bias=False)
489
+ )
490
+ else:
491
+ self.upsample = None
492
+
493
+ def forward(self, x):
494
+
495
+ identity = x
496
+
497
+ x = self.weight_layer1(x)
498
+ x = self.weight_layer2(x)
499
+
500
+ if self.upsample is not None:
501
+ identity = self.upsample(identity)
502
+
503
+ x = x + identity
504
+
505
+ return x
506
+
507
+ class DecoderBottleneckLayer(nn.Module):
508
+
509
+ def __init__(self, in_channels, hidden_channels, down_channels, upsample):
510
+ super(DecoderBottleneckLayer, self).__init__()
511
+
512
+ self.weight_layer1 = nn.Sequential(
513
+ nn.BatchNorm2d(num_features=in_channels),
514
+ nn.ReLU(inplace=True),
515
+ nn.Conv2d(in_channels=in_channels, out_channels=hidden_channels, kernel_size=1, stride=1, padding=0, bias=False),
516
+ )
517
+
518
+ self.weight_layer2 = nn.Sequential(
519
+ nn.BatchNorm2d(num_features=hidden_channels),
520
+ nn.ReLU(inplace=True),
521
+ nn.Conv2d(in_channels=hidden_channels, out_channels=hidden_channels, kernel_size=3, stride=1, padding=1, bias=False),
522
+ )
523
+
524
+ if upsample:
525
+ self.weight_layer3 = nn.Sequential(
526
+ nn.BatchNorm2d(num_features=hidden_channels),
527
+ nn.ReLU(inplace=True),
528
+ nn.ConvTranspose2d(in_channels=hidden_channels, out_channels=down_channels, kernel_size=1, stride=2, output_padding=1, bias=False)
529
+ )
530
+ else:
531
+ self.weight_layer3 = nn.Sequential(
532
+ nn.BatchNorm2d(num_features=hidden_channels),
533
+ nn.ReLU(inplace=True),
534
+ nn.Conv2d(in_channels=hidden_channels, out_channels=down_channels, kernel_size=1, stride=1, padding=0, bias=False)
535
+ )
536
+
537
+ if upsample:
538
+ self.upsample = nn.Sequential(
539
+ nn.BatchNorm2d(num_features=in_channels),
540
+ nn.ReLU(inplace=True),
541
+ nn.ConvTranspose2d(in_channels=in_channels, out_channels=down_channels, kernel_size=1, stride=2, output_padding=1, bias=False)
542
+ )
543
+ elif (in_channels != down_channels):
544
+ self.upsample = None
545
+ self.down_scale = nn.Sequential(
546
+ nn.BatchNorm2d(num_features=in_channels),
547
+ nn.ReLU(inplace=True),
548
+ nn.Conv2d(in_channels=in_channels, out_channels=down_channels, kernel_size=1, stride=1, padding=0, bias=False)
549
+ )
550
+ else:
551
+ self.upsample = None
552
+ self.down_scale = None
553
+
554
+ def forward(self, x):
555
+
556
+ identity = x
557
+
558
+ x = self.weight_layer1(x)
559
+ x = self.weight_layer2(x)
560
+ x = self.weight_layer3(x)
561
+
562
+ if self.upsample is not None:
563
+ identity = self.upsample(identity)
564
+ elif self.down_scale is not None:
565
+ identity = self.down_scale(identity)
566
+
567
+ x = x + identity
568
+
569
+ return x
570
+
571
+ # put in place of final relu of resnet encoder (for vae)
572
+ class ResidualLayer(nn.Module):
573
+ def __init__(self):
574
+ super().__init__()
575
+ self.conv = nn.Conv2d(32, 32, 1)
576
+ def forward(self, x):
577
+ return x + self.conv(x)
578
+
579
+ if __name__ == "__main__":
580
+
581
+ configs, bottleneck = get_configs("resnet152")
582
+
583
+ encoder = ResNetEncoder(configs, bottleneck)
584
+
585
+ input = torch.randn((5,3,224,224))
586
+
587
+ print(input.shape)
588
+
589
+ output = encoder(input)
590
+
591
+ print(output.shape)
592
+
593
+ decoder = ResNetDecoder(configs[::-1], bottleneck)
594
+
595
+ output = decoder(output)
596
+
597
+ print(output.shape)
autoencoder/resnet_train.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
autoencoder/save_bandstructure_images.ipynb ADDED
@@ -0,0 +1,507 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "id": "ee7b27ff-1a8f-4fbe-bae8-e4a34f18a70d",
7
+ "metadata": {},
8
+ "outputs": [],
9
+ "source": [
10
+ "import pandas as pd\n",
11
+ "import matplotlib.pyplot as plt\n",
12
+ "import numpy as np\n",
13
+ "from skimage import io\n",
14
+ "from skimage.transform import resize\n",
15
+ "from skimage.color import rgb2gray\n",
16
+ "import json\n",
17
+ "\n",
18
+ "from fastai.vision.all import Path, Image\n",
19
+ "\n",
20
+ "import numpy as np"
21
+ ]
22
+ },
23
+ {
24
+ "cell_type": "code",
25
+ "execution_count": 25,
26
+ "id": "681dd136-1246-44c5-b576-6877f429043a",
27
+ "metadata": {},
28
+ "outputs": [],
29
+ "source": [
30
+ "# IMAGE_DIRECTORY = Path('/storage/2dmatpedia/images/no_dos_bw/low_dpi_bands')\n",
31
+ "OUTPUT_DIMENSIONS = (64, 64)\n",
32
+ "DATA_DIRECTORY = Path(\"../../../storage/2dmatpedia\")\n",
33
+ "LINEWIDTH = 3\n",
34
+ "output_name = f\"dpi_none_thickness_{LINEWIDTH}_{OUTPUT_DIMENSIONS[0]}x{OUTPUT_DIMENSIONS[1]}_binary\""
35
+ ]
36
+ },
37
+ {
38
+ "cell_type": "markdown",
39
+ "id": "2f620e3b-5b0e-4a5a-a564-9eddd9db5598",
40
+ "metadata": {
41
+ "tags": []
42
+ },
43
+ "source": [
44
+ "## High DPI"
45
+ ]
46
+ },
47
+ {
48
+ "cell_type": "code",
49
+ "execution_count": 26,
50
+ "id": "233b6f20-9473-44c8-bf79-17e3e76d5056",
51
+ "metadata": {},
52
+ "outputs": [
53
+ {
54
+ "data": {
55
+ "image/png": "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\n",
56
+ "text/plain": [
57
+ "<Figure size 576x576 with 1 Axes>"
58
+ ]
59
+ },
60
+ "metadata": {
61
+ "needs_background": "light"
62
+ },
63
+ "output_type": "display_data"
64
+ }
65
+ ],
66
+ "source": [
67
+ "fig, ax = plt.subplots(figsize=(8, 8))\n",
68
+ "\n",
69
+ "bands_dict=json.load(open(DATA_DIRECTORY/\"bands/2dm-4000.json\"))\n",
70
+ "energies_minus_efermi = np.array(bands_dict[\"bands\"][\"1\"]) - bands_dict[\"efermi\"]\n",
71
+ "ax.set_ylim([-4, +4])\n",
72
+ "ax.set_xlim([0, energies_minus_efermi.shape[1]-1])\n",
73
+ "\n",
74
+ "\n",
75
+ "for band in energies_minus_efermi:\n",
76
+ " ax.plot(band, c=\"black\", linewidth=LINEWIDTH)\n",
77
+ "\n",
78
+ "# If we haven't already shown or saved the plot, then we need to\n",
79
+ "# draw the figure first...\n",
80
+ "ax.axis(\"off\")\n",
81
+ "fig.canvas.draw()\n",
82
+ "\n",
83
+ "# Now we can save it to a numpy array.\n",
84
+ "data = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)\n",
85
+ "data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))\n",
86
+ "\n",
87
+ "# now crop out axis, resize & grayscale:\n",
88
+ "data = data[70:-72, 72:-58]\n",
89
+ "image = Image.fromarray(data)\n",
90
+ "\n",
91
+ "\n",
92
+ "# # and replot:\n",
93
+ "# fig, ax = plt.subplots(figsize=(8, 8))\n",
94
+ "# ax.imshow(data)"
95
+ ]
96
+ },
97
+ {
98
+ "cell_type": "markdown",
99
+ "id": "64aece99-25fb-4fed-92d9-e7e04c20a8f0",
100
+ "metadata": {},
101
+ "source": [
102
+ "# Save them"
103
+ ]
104
+ },
105
+ {
106
+ "cell_type": "code",
107
+ "execution_count": 6,
108
+ "id": "86aef83a-77b8-4b65-b27a-9e9631c693c5",
109
+ "metadata": {},
110
+ "outputs": [
111
+ {
112
+ "data": {
113
+ "text/plain": [
114
+ "<matplotlib.image.AxesImage at 0x7fcb510804f0>"
115
+ ]
116
+ },
117
+ "execution_count": 6,
118
+ "metadata": {},
119
+ "output_type": "execute_result"
120
+ },
121
+ {
122
+ "data": {
123
+ "image/png": "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\n",
124
+ "text/plain": [
125
+ "<Figure size 88x88 with 1 Axes>"
126
+ ]
127
+ },
128
+ "metadata": {
129
+ "needs_background": "light"
130
+ },
131
+ "output_type": "display_data"
132
+ },
133
+ {
134
+ "data": {
135
+ "image/png": "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JtZDz1e7du3MbPr06fmfWBn3zjvvJNat50SSKlasaGZ9+/Y1s9CSidgWL15sZkOHDjWz8ePHJ9ZPOukkc8yzzz5rZq1btzazsij0PRDaicZaNvPee++ZY+655x4z69+/v5m98sorZvbVV1+ZmaVLly5m9u6777JsBgCAokJDBQAgAhoqAAAR0FABAIiAhgoAQAQ0VAAAIsjoshnnnHmyww47zBz34IMPJtavvPLKtOZx6aWXmtmf//xnM1u4cGFiPbRTx9ixY82sefPmZvbCCy+YWZs2bcwsto4dO5rZ5MmTE+v169c3x7z66qtmlsl/14HKWk4jhZfUVKlSxcxCr7PHH388fxOLILSkxtpVJrRjT8uWLc0stNPICSecYGalmfV6lqTrrrvOzLp3725mjRs3Tqzfeeed5pgrrrjCzEK7B5133nlmNmPGjMR66Odznz59zGzXrl0smwEAoKjQUAEAiICGCgBABDRUAAAioKECABABDRUAgAjKZ/Jkxx9/vLnE5OCDDzbHVa9evcDnatu2rZmFLtmuV69egTPr0nBJ2r59u5m9+eabZhba/WPcuHGJ9WbNmpljQpe2f//992Y2c+ZMM/vHP/6RWK9cubI5hl08ilbnzp3N7I033jCzCy64wMxGjx5tZhUqVEisW0vdCiP0Onv44YcT6z/99JM5JrRLSs+ePc3srbfeMrOjjz7azEq6NWvWmJm1ZFCSfvjhhwKf69tvvzWz0I5ftWrVMrNnnnnGzLp165ZYD32fTpw40czOPPPMxDrvUAEAiICGCgBABDRUAAAioKECABABDRUAgAgyenP87Oxsn5OTk5itX7/eHHfGGWck1p1z5pjQTdiPO+44M4vt66+/NrOrr77azN5//30za9KkSWK9atWq5pjPP//czHbv3m1m1vMlccVuabNr1y4zC11xfvHFF5vZoYcemlg/9thj8z+xfLrhhhvMzLoqfunSpeaY0M3PP/30UzMLXU0/ZcqUxHro6tRM+uSTT8ws9HgsW7Ys6jyGDBliZrfccouZHX744Wmdz/qZ+dVXX5ljQleIV65cmZvjAwBQVGioAABEQEMFACACGioAABHQUAEAiICGCgBABBldNtO6dWtvXbbdokULc5x1aXO7du3MMdOnTy/Y5IrBihUrzKxXr15m9vHHHxf4XJMnTzaz0CX9zZs3L/C5UPrs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\n",
136
+ "text/plain": [
137
+ "<Figure size 576x576 with 1 Axes>"
138
+ ]
139
+ },
140
+ "metadata": {
141
+ "needs_background": "light"
142
+ },
143
+ "output_type": "display_data"
144
+ }
145
+ ],
146
+ "source": [
147
+ "fig, ax = plt.subplots(figsize=(8, 8), dpi=11)\n",
148
+ "\n",
149
+ "bands_dict=json.load(open(DATA_DIRECTORY/\"bands/2dm-4.json\"))\n",
150
+ "energies_minus_efermi = np.array(bands_dict[\"bands\"][\"1\"]) - bands_dict[\"efermi\"]\n",
151
+ "ax.set_ylim([-4, +4])\n",
152
+ "ax.set_xlim([0, energies_minus_efermi.shape[1]-1])\n",
153
+ "\n",
154
+ "LINEWIDTH = 3\n",
155
+ "\n",
156
+ "for band in energies_minus_efermi:\n",
157
+ " ax.plot(band, c=\"black\", linewidth=LINEWIDTH)\n",
158
+ "\n",
159
+ "# If we haven't already shown or saved the plot, then we need to\n",
160
+ "# draw the figure first...\n",
161
+ "ax.axis(\"off\")\n",
162
+ "fig.canvas.draw()\n",
163
+ "\n",
164
+ "# Now we can save it to a numpy array.\n",
165
+ "data = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)\n",
166
+ "data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))\n",
167
+ "\n",
168
+ "# now crop out axis, resize & grayscale:\n",
169
+ "# data = data[70:-72, 72:-58]\n",
170
+ "data = data[11:-11, 11:-9]\n",
171
+ "data = resize(data, OUTPUT_DIMENSIONS)\n",
172
+ "\n",
173
+ "# and replot:\n",
174
+ "fig, ax = plt.subplots(figsize=(8, 8))\n",
175
+ "ax.imshow(data)"
176
+ ]
177
+ },
178
+ {
179
+ "cell_type": "code",
180
+ "execution_count": 34,
181
+ "id": "d19610e6-2f22-4d8e-853f-e7c7187d36a9",
182
+ "metadata": {},
183
+ "outputs": [
184
+ {
185
+ "data": {
186
+ "text/html": [
187
+ "<div>\n",
188
+ "<style scoped>\n",
189
+ " .dataframe tbody tr th:only-of-type {\n",
190
+ " vertical-align: middle;\n",
191
+ " }\n",
192
+ "\n",
193
+ " .dataframe tbody tr th {\n",
194
+ " vertical-align: top;\n",
195
+ " }\n",
196
+ "\n",
197
+ " .dataframe thead th {\n",
198
+ " text-align: right;\n",
199
+ " }\n",
200
+ "</style>\n",
201
+ "<table border=\"1\" class=\"dataframe\">\n",
202
+ " <thead>\n",
203
+ " <tr style=\"text-align: right;\">\n",
204
+ " <th></th>\n",
205
+ " <th>formula</th>\n",
206
+ " <th>gen_formula</th>\n",
207
+ " <th>space_group</th>\n",
208
+ " <th>segments</th>\n",
209
+ " <th>flat_segments</th>\n",
210
+ " <th>flatness_score</th>\n",
211
+ " <th>discovery</th>\n",
212
+ " <th>binary_flatness</th>\n",
213
+ " <th>horz_flat_seg</th>\n",
214
+ " <th>exfoliation_eg</th>\n",
215
+ " <th>...</th>\n",
216
+ " <th>A</th>\n",
217
+ " <th>B</th>\n",
218
+ " <th>C</th>\n",
219
+ " <th>D</th>\n",
220
+ " <th>E</th>\n",
221
+ " <th>F</th>\n",
222
+ " <th>radio</th>\n",
223
+ " <th>f_orb</th>\n",
224
+ " <th>sg_sto_group</th>\n",
225
+ " <th>percentage_flat</th>\n",
226
+ " </tr>\n",
227
+ " <tr>\n",
228
+ " <th>ID</th>\n",
229
+ " <th></th>\n",
230
+ " <th></th>\n",
231
+ " <th></th>\n",
232
+ " <th></th>\n",
233
+ " <th></th>\n",
234
+ " <th></th>\n",
235
+ " <th></th>\n",
236
+ " <th></th>\n",
237
+ " <th></th>\n",
238
+ " <th></th>\n",
239
+ " <th></th>\n",
240
+ " <th></th>\n",
241
+ " <th></th>\n",
242
+ " <th></th>\n",
243
+ " <th></th>\n",
244
+ " <th></th>\n",
245
+ " <th></th>\n",
246
+ " <th></th>\n",
247
+ " <th></th>\n",
248
+ " <th></th>\n",
249
+ " <th></th>\n",
250
+ " </tr>\n",
251
+ " </thead>\n",
252
+ " <tbody>\n",
253
+ " <tr>\n",
254
+ " <th>2dm-1</th>\n",
255
+ " <td>IrF2</td>\n",
256
+ " <td>AB2</td>\n",
257
+ " <td>164</td>\n",
258
+ " <td>3</td>\n",
259
+ " <td>0</td>\n",
260
+ " <td>0.095102</td>\n",
261
+ " <td>bottom-up</td>\n",
262
+ " <td>0</td>\n",
263
+ " <td>0</td>\n",
264
+ " <td>0.234620</td>\n",
265
+ " <td>...</td>\n",
266
+ " <td>F</td>\n",
267
+ " <td>Ir</td>\n",
268
+ " <td>NaN</td>\n",
269
+ " <td>NaN</td>\n",
270
+ " <td>NaN</td>\n",
271
+ " <td>NaN</td>\n",
272
+ " <td>non-radioactive</td>\n",
273
+ " <td>no-f-in-valence</td>\n",
274
+ " <td>NaN</td>\n",
275
+ " <td>NaN</td>\n",
276
+ " </tr>\n",
277
+ " <tr>\n",
278
+ " <th>2dm-2</th>\n",
279
+ " <td>Ba2Sb</td>\n",
280
+ " <td>AB2</td>\n",
281
+ " <td>164</td>\n",
282
+ " <td>3</td>\n",
283
+ " <td>1</td>\n",
284
+ " <td>0.387410</td>\n",
285
+ " <td>bottom-up</td>\n",
286
+ " <td>0</td>\n",
287
+ " <td>0</td>\n",
288
+ " <td>0.210650</td>\n",
289
+ " <td>...</td>\n",
290
+ " <td>Ba</td>\n",
291
+ " <td>Sb</td>\n",
292
+ " <td>NaN</td>\n",
293
+ " <td>NaN</td>\n",
294
+ " <td>NaN</td>\n",
295
+ " <td>NaN</td>\n",
296
+ " <td>non-radioactive</td>\n",
297
+ " <td>no-f-in-valence</td>\n",
298
+ " <td>NaN</td>\n",
299
+ " <td>NaN</td>\n",
300
+ " </tr>\n",
301
+ " <tr>\n",
302
+ " <th>2dm-3</th>\n",
303
+ " <td>TlS</td>\n",
304
+ " <td>AB</td>\n",
305
+ " <td>2</td>\n",
306
+ " <td>4</td>\n",
307
+ " <td>4</td>\n",
308
+ " <td>0.846460</td>\n",
309
+ " <td>bottom-up</td>\n",
310
+ " <td>1</td>\n",
311
+ " <td>3</td>\n",
312
+ " <td>0.095794</td>\n",
313
+ " <td>...</td>\n",
314
+ " <td>S</td>\n",
315
+ " <td>Tl</td>\n",
316
+ " <td>NaN</td>\n",
317
+ " <td>NaN</td>\n",
318
+ " <td>NaN</td>\n",
319
+ " <td>NaN</td>\n",
320
+ " <td>non-radioactive</td>\n",
321
+ " <td>no-f-in-valence</td>\n",
322
+ " <td>276.0</td>\n",
323
+ " <td>24.2</td>\n",
324
+ " </tr>\n",
325
+ " <tr>\n",
326
+ " <th>2dm-4</th>\n",
327
+ " <td>MoCl2</td>\n",
328
+ " <td>AB2</td>\n",
329
+ " <td>166</td>\n",
330
+ " <td>5</td>\n",
331
+ " <td>4</td>\n",
332
+ " <td>0.713760</td>\n",
333
+ " <td>bottom-up</td>\n",
334
+ " <td>0</td>\n",
335
+ " <td>0</td>\n",
336
+ " <td>-0.055818</td>\n",
337
+ " <td>...</td>\n",
338
+ " <td>Cl</td>\n",
339
+ " <td>Mo</td>\n",
340
+ " <td>NaN</td>\n",
341
+ " <td>NaN</td>\n",
342
+ " <td>NaN</td>\n",
343
+ " <td>NaN</td>\n",
344
+ " <td>non-radioactive</td>\n",
345
+ " <td>no-f-in-valence</td>\n",
346
+ " <td>NaN</td>\n",
347
+ " <td>NaN</td>\n",
348
+ " </tr>\n",
349
+ " <tr>\n",
350
+ " <th>2dm-6</th>\n",
351
+ " <td>RuI2</td>\n",
352
+ " <td>AB2</td>\n",
353
+ " <td>164</td>\n",
354
+ " <td>3</td>\n",
355
+ " <td>1</td>\n",
356
+ " <td>0.264930</td>\n",
357
+ " <td>bottom-up</td>\n",
358
+ " <td>0</td>\n",
359
+ " <td>0</td>\n",
360
+ " <td>0.084831</td>\n",
361
+ " <td>...</td>\n",
362
+ " <td>I</td>\n",
363
+ " <td>Ru</td>\n",
364
+ " <td>NaN</td>\n",
365
+ " <td>NaN</td>\n",
366
+ " <td>NaN</td>\n",
367
+ " <td>NaN</td>\n",
368
+ " <td>non-radioactive</td>\n",
369
+ " <td>no-f-in-valence</td>\n",
370
+ " <td>NaN</td>\n",
371
+ " <td>NaN</td>\n",
372
+ " </tr>\n",
373
+ " </tbody>\n",
374
+ "</table>\n",
375
+ "<p>5 rows × 24 columns</p>\n",
376
+ "</div>"
377
+ ],
378
+ "text/plain": [
379
+ " formula gen_formula space_group segments flat_segments \\\n",
380
+ "ID \n",
381
+ "2dm-1 IrF2 AB2 164 3 0 \n",
382
+ "2dm-2 Ba2Sb AB2 164 3 1 \n",
383
+ "2dm-3 TlS AB 2 4 4 \n",
384
+ "2dm-4 MoCl2 AB2 166 5 4 \n",
385
+ "2dm-6 RuI2 AB2 164 3 1 \n",
386
+ "\n",
387
+ " flatness_score discovery binary_flatness horz_flat_seg \\\n",
388
+ "ID \n",
389
+ "2dm-1 0.095102 bottom-up 0 0 \n",
390
+ "2dm-2 0.387410 bottom-up 0 0 \n",
391
+ "2dm-3 0.846460 bottom-up 1 3 \n",
392
+ "2dm-4 0.713760 bottom-up 0 0 \n",
393
+ "2dm-6 0.264930 bottom-up 0 0 \n",
394
+ "\n",
395
+ " exfoliation_eg ... A B C D E F radio \\\n",
396
+ "ID ... \n",
397
+ "2dm-1 0.234620 ... F Ir NaN NaN NaN NaN non-radioactive \n",
398
+ "2dm-2 0.210650 ... Ba Sb NaN NaN NaN NaN non-radioactive \n",
399
+ "2dm-3 0.095794 ... S Tl NaN NaN NaN NaN non-radioactive \n",
400
+ "2dm-4 -0.055818 ... Cl Mo NaN NaN NaN NaN non-radioactive \n",
401
+ "2dm-6 0.084831 ... I Ru NaN NaN NaN NaN non-radioactive \n",
402
+ "\n",
403
+ " f_orb sg_sto_group percentage_flat \n",
404
+ "ID \n",
405
+ "2dm-1 no-f-in-valence NaN NaN \n",
406
+ "2dm-2 no-f-in-valence NaN NaN \n",
407
+ "2dm-3 no-f-in-valence 276.0 24.2 \n",
408
+ "2dm-4 no-f-in-valence NaN NaN \n",
409
+ "2dm-6 no-f-in-valence NaN NaN \n",
410
+ "\n",
411
+ "[5 rows x 24 columns]"
412
+ ]
413
+ },
414
+ "execution_count": 34,
415
+ "metadata": {},
416
+ "output_type": "execute_result"
417
+ }
418
+ ],
419
+ "source": [
420
+ "material_df = pd.read_csv(\"material_flatness_scores_anupam.csv\", index_col=\"ID\")\n",
421
+ "material_df.head()"
422
+ ]
423
+ },
424
+ {
425
+ "cell_type": "code",
426
+ "execution_count": 36,
427
+ "id": "d6fefe98-4412-4269-9374-59272afaa2a8",
428
+ "metadata": {},
429
+ "outputs": [],
430
+ "source": [
431
+ "!mkdir {DATA_DIRECTORY}/images/grayscale_4ev_linewidth3"
432
+ ]
433
+ },
434
+ {
435
+ "cell_type": "code",
436
+ "execution_count": null,
437
+ "id": "2afcf01f-ee0c-4b36-9486-01eea0c49595",
438
+ "metadata": {},
439
+ "outputs": [
440
+ {
441
+ "name": "stdout",
442
+ "output_type": "stream",
443
+ "text": [
444
+ "0 / 5270\n",
445
+ "100 / 5270\n"
446
+ ]
447
+ }
448
+ ],
449
+ "source": [
450
+ "output = np.zeros((len(material_df), *OUTPUT_DIMENSIONS))\n",
451
+ " \n",
452
+ "for i, material_id in enumerate(material_df.index):\n",
453
+ " bands_dict=json.load(open(DATA_DIRECTORY/f\"bands/{material_id}.json\"))\n",
454
+ " output_path = DATA_DIRECTORY/f\"images/grayscale_4ev_linewidth3/{material_id}.png\"\n",
455
+ " energies_minus_efermi = np.array(bands_dict[\"bands\"][\"1\"]) - bands_dict[\"efermi\"]\n",
456
+ " \n",
457
+ " if i % 100 == 0:\n",
458
+ " print(i, \"/\", len(material_df))\n",
459
+ " \n",
460
+ " fig, ax = plt.subplots(figsize=(8, 8))\n",
461
+ " ax.set_ylim([-4, +4])\n",
462
+ " ax.set_xlim([0, energies_minus_efermi.shape[1]-1])\n",
463
+ "\n",
464
+ "\n",
465
+ " for band in energies_minus_efermi:\n",
466
+ " ax.plot(band, c=\"black\", linewidth=LINEWIDTH)\n",
467
+ "\n",
468
+ " # If we haven't already shown or saved the plot, then we need to\n",
469
+ " # draw the figure first...\n",
470
+ " ax.axis(\"off\")\n",
471
+ " fig.canvas.draw()\n",
472
+ "\n",
473
+ " # Now we can save it to a numpy array.\n",
474
+ " data = np.frombuffer(fig.canvas.tostring_rgb(), dtype=np.uint8)\n",
475
+ " data = data.reshape(fig.canvas.get_width_height()[::-1] + (3,))\n",
476
+ "\n",
477
+ " # now crop out axis, resize & grayscale:\n",
478
+ " data = data[70:-72, 72:-58]\n",
479
+ " image = Image.fromarray(data)\n",
480
+ " image.save(output_path)\n",
481
+ " \n",
482
+ " plt.close()"
483
+ ]
484
+ }
485
+ ],
486
+ "metadata": {
487
+ "kernelspec": {
488
+ "display_name": "Python 3 (ipykernel)",
489
+ "language": "python",
490
+ "name": "python3"
491
+ },
492
+ "language_info": {
493
+ "codemirror_mode": {
494
+ "name": "ipython",
495
+ "version": 3
496
+ },
497
+ "file_extension": ".py",
498
+ "mimetype": "text/x-python",
499
+ "name": "python",
500
+ "nbconvert_exporter": "python",
501
+ "pygments_lexer": "ipython3",
502
+ "version": "3.9.13"
503
+ }
504
+ },
505
+ "nbformat": 4,
506
+ "nbformat_minor": 5
507
+ }
fingerprint_creation/2dmatpedia.ipynb ADDED
The diff for this file is too large to render. See raw diff
 
fingerprint_creation/README.md ADDED
@@ -0,0 +1 @@
 
 
1
+ Add fingerprints to "fingerprints/template.csv" and save a new CSV file for each fingerprint so they can be accessed elsewhere for clustering.
fingerprints/128x128_random_erase_resnet18_VAE_L=128_perplexity_30_length_128.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:1d872e34094281d5dd00fad95acf7e137f5f18f28baf65a8a103c3d78b825f1b
3
+ size 14725629
fingerprints/128x128_random_erase_resnet18_VAE_L=256_perplexity_30_length_256.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f8b36a6da65c8e08e576621cfca7c2b6bbe9296377894ee05a6d9e81531cbfd4
3
+ size 28423284
fingerprints/128x128_random_erase_resnet18_VAE_L=64_perplexity_30_length_64.csv ADDED
The diff for this file is too large to render. See raw diff
 
fingerprints/128x128_resnet_L=128_perplexity_30_length_128.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:91d45a5130b884cbbacc91f3283f613d1f5f8cfbd0a1d70d56fcf825770854cf
3
+ size 11099858
fingerprints/128x128_resnet_L=160_perplexity_30_length_160.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f9d7de525bcf145f974a0d673107ca28261f28afc02202c2f45a66f05cfeb217
3
+ size 16861296
fingerprints/128x128_resnet_L=256_perplexity_30_length_256.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:725c7cab95e80f20d6f2f3df03d5ea00ca40c726e68e183532d14d59a3e5899b
3
+ size 24706740
fingerprints/128x128_resnet_L=32_perplexity_30_length_32.csv ADDED
The diff for this file is too large to render. See raw diff
 
fingerprints/128x128_resnet_L=512_perplexity_30_length_512.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b2caa450d8ccd32d11edf8c85985228c13b0582e700bd62c2062b1dea530ab66
3
+ size 48976124
fingerprints/128x128_resnet_L=96_leaky_perplexity_30_length_96.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:e6594453caceec32dbe700396e72abbc747810b39bc024cb8271c661c25f67c2
3
+ size 10502117
fingerprints/128x128_resnet_L=96_perplexity_30_length_96.csv ADDED
The diff for this file is too large to render. See raw diff
 
fingerprints/12_bands_encoder_L=128_perplexity_30_length_128.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:b02c83d84d75904c54588ecf6a630780df2461bc131301a8cc6ba9141f7929bc
3
+ size 15225102
fingerprints/12_bands_encoder_L=4_perplexity_30_length_4.csv ADDED
The diff for this file is too large to render. See raw diff
 
fingerprints/12_bands_encoder_perplexity_30_length_128.csv ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:cfe2f6f11c92fddd328d7c204679764306d153b27b86270d8aa61cb3f27406e8
3
+ size 15170730
fingerprints/224_2channel_resnet_L=98_perplexity_30_length_98.csv ADDED
The diff for this file is too large to render. See raw diff
 
fingerprints/224_2channel_resnet_L=98_perplexity_30_length_98_CORRECTED.csv ADDED
The diff for this file is too large to render. See raw diff