astro-nest 0.7.2.dev2__tar.gz → 0.7.2.dev4__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. astro_nest-0.7.2.dev4/NEST/cmaps.npz +0 -0
  2. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/core.py +78 -34
  3. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/PKG-INFO +1 -1
  4. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/astro_nest.egg-info/PKG-INFO +1 -1
  5. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/astro_nest.egg-info/SOURCES.txt +1 -0
  6. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/pyproject.toml +2 -2
  7. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/__init__.py +0 -0
  8. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/_version.py +0 -0
  9. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/domain.pkl +0 -0
  10. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI.mlp +0 -0
  11. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI.sav +0 -0
  12. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI.scaler +0 -0
  13. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI_BPRP.mlp +0 -0
  14. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI_BPRP.sav +0 -0
  15. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI_BPRP.scaler +0 -0
  16. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI_HST_enhanced.mlp +0 -0
  17. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI_HST_enhanced.sav +0 -0
  18. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI_HST_enhanced.scaler +0 -0
  19. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI_HST_enhanced_BPRP.mlp +0 -0
  20. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI_HST_enhanced_BPRP.sav +0 -0
  21. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/BaSTI_HST_enhanced_BPRP.scaler +0 -0
  22. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Dartmouth.mlp +0 -0
  23. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Dartmouth.sav +0 -0
  24. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Dartmouth.scaler +0 -0
  25. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Dartmouth_BPRP.mlp +0 -0
  26. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Dartmouth_BPRP.sav +0 -0
  27. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Dartmouth_BPRP.scaler +0 -0
  28. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Geneva.mlp +0 -0
  29. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Geneva.sav +0 -0
  30. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Geneva.scaler +0 -0
  31. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Geneva_BPRP.mlp +0 -0
  32. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Geneva_BPRP.sav +0 -0
  33. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/Geneva_BPRP.scaler +0 -0
  34. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/MIST.mlp +0 -0
  35. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/MIST.sav +0 -0
  36. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/MIST.scaler +0 -0
  37. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/MIST_BPRP.mlp +0 -0
  38. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/MIST_BPRP.sav +0 -0
  39. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/MIST_BPRP.scaler +0 -0
  40. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_BaSTI.json +0 -0
  41. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_BaSTI_BPRP.json +0 -0
  42. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_BaSTI_HST_BPRP.json +0 -0
  43. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_BaSTI_HST_enhanced.json +0 -0
  44. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_BaSTI_HST_enhanced_BPRP.json +0 -0
  45. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_Dartmouth.json +0 -0
  46. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_Dartmouth_BPRP.json +0 -0
  47. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_Geneva.json +0 -0
  48. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_Geneva_BPRP.json +0 -0
  49. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_MIST.json +0 -0
  50. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_MIST_BPRP.json +0 -0
  51. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_PARSEC.json +0 -0
  52. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_PARSEC_BPRP.json +0 -0
  53. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_SYCLIST_BPRP.json +0 -0
  54. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_YaPSI.json +0 -0
  55. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/NN_YaPSI_BPRP.json +0 -0
  56. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/PARSEC.mlp +0 -0
  57. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/PARSEC.sav +0 -0
  58. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/PARSEC.scaler +0 -0
  59. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/PARSEC_BPRP.mlp +0 -0
  60. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/PARSEC_BPRP.sav +0 -0
  61. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/PARSEC_BPRP.scaler +0 -0
  62. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/YaPSI.mlp +0 -0
  63. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/YaPSI.sav +0 -0
  64. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/YaPSI.scaler +0 -0
  65. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/YaPSI_BPRP.mlp +0 -0
  66. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/YaPSI_BPRP.sav +0 -0
  67. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/models/YaPSI_BPRP.scaler +0 -0
  68. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/NEST/tutorial.ipynb +0 -0
  69. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/astro_nest.egg-info/dependency_links.txt +0 -0
  70. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/astro_nest.egg-info/top_level.txt +0 -0
  71. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/readme.md +0 -0
  72. {astro_nest-0.7.2.dev2 → astro_nest-0.7.2.dev4}/setup.cfg +0 -0
Binary file
@@ -14,6 +14,8 @@ except ImportError:
14
14
  has_requests = False
15
15
  try:
16
16
  import matplotlib.pyplot as plt
17
+ from matplotlib.patches import Polygon
18
+ from matplotlib.colors import ListedColormap
17
19
  has_matplotlib = True
18
20
  except ImportError:
19
21
  has_matplotlib = False
@@ -33,6 +35,16 @@ def custom_warning(message, category, filename, lineno, file=None, line=None):
33
35
 
34
36
  warnings.showwarning = custom_warning
35
37
 
38
+ def import_cmaps():
39
+ cmaps = {}
40
+ if has_matplotlib:
41
+ cmaps_colors = dict(np.load(os.path.join(NEST_DIR, 'cmaps.npz')))
42
+ for name, colors in cmaps_colors.items():
43
+ cmaps[name] = ListedColormap(colors)
44
+ return cmaps
45
+
46
+ cmaps = import_cmaps()
47
+
36
48
  def sanitize_input(input):
37
49
  if input is not None and type(input) is not list:
38
50
  if hasattr(input,'ndim') and input.ndim == 0:
@@ -153,6 +165,8 @@ class AgeModel:
153
165
  self.means = None
154
166
  self.modes = None
155
167
  self.stds = None
168
+ self.pop_age = None
169
+ self.pop_age_std = None
156
170
  self.load_neural_network(self.model_name)
157
171
 
158
172
  def __repr__(self):
@@ -391,7 +405,7 @@ class AgeModel:
391
405
 
392
406
  return in_domain
393
407
 
394
- def population_age(self,nbins=280,min_age=0,max_age=14,check_domain=True,n_mc=100):
408
+ def population_age(self,nbins=280,min_age=0,max_age=14,check_domain=True,n_mc=100,use_tqdm=True):
395
409
  if self.ages is None:
396
410
  raise ValueError('No samples have been stored yet. Make sure to run ages_prediction() with store_samples=True')
397
411
 
@@ -407,15 +421,19 @@ class AgeModel:
407
421
  ages = self.ages
408
422
 
409
423
  ages = np.array([age for age in ages if np.any(np.isnan(age)) == False])
424
+
425
+ if len(ages) == 0:
426
+ raise ValueError('No valid age samples available to compute population age (maybe all stars are out of domain ?)')
410
427
 
411
428
  if ages.shape[1] == 1:
412
429
  return np.median(ages)
413
430
 
414
431
  pdfs = []
432
+ best_ages = []
415
433
  loop = range(n_mc)
416
- if self.use_tqdm:
434
+ if self.use_tqdm and use_tqdm:
417
435
  loop = tqdm(loop)
418
- min_offset = 0.1
436
+ epsilon = np.clip(1/ages.shape[0],0.001,0.1)
419
437
  for i in loop:
420
438
  random_star_indices = np.random.choice(list(range(ages.shape[0])), size=ages.shape[0], replace=True)
421
439
  random_star_indices = random_star_indices.astype(int)
@@ -425,15 +443,24 @@ class AgeModel:
425
443
  age = random_star_ages[j]
426
444
  pdf, bins = np.histogram(age,bins=nbins,range=(min_age,max_age))
427
445
  pdf = pdf.astype(float)
428
- pdf += min_offset
446
+ pdf += epsilon
429
447
  global_pdf *= pdf
430
448
  best_age = bins[np.argmax(global_pdf)] + (bins[1]-bins[0])/2
431
449
  if best_age != bins[0]+(bins[1]-bins[0])/2:
450
+ best_ages.append(best_age)
432
451
  pdfs.append(bins[np.argmax(global_pdf)] + (bins[1]-bins[0])/2)
433
452
 
453
+ if len(pdfs) == 0:
454
+ warnings.warn('No valid population age could be computed from the samples')
455
+ return np.nan
456
+
434
457
  population_age = np.median(pdfs)
458
+ population_age_std = np.std(best_ages)
435
459
 
436
- return population_age
460
+ self.pop_age = population_age
461
+ self.pop_age_std = population_age_std
462
+
463
+ return population_age, population_age_std
437
464
 
438
465
  def propagate(self,X,neural_network,scaler):
439
466
  if self.use_sklearn:
@@ -499,7 +526,14 @@ class AgeModel:
499
526
  self.stds = np.std(self.ages,axis=1)
500
527
  return self.stds
501
528
 
502
- def HR_diagram(self,isochrone_met=0,plot_isochrone=True,plot_stars=True,age_type='median',check_domain=True,fig=None,ax=None,**kwargs):
529
+ def HR_diagram(self,
530
+ isochrone_met=0,
531
+ plot_isochrone=True,plot_stars=True,
532
+ isochrone_ages=None,isochrone_ages_std=None,
533
+ age_type='median',
534
+ check_domain=True,
535
+ fig=None,ax=None,
536
+ **kwargs):
503
537
  if has_matplotlib == False:
504
538
  raise ImportError('matplotlib is required for HR diagram plotting')
505
539
 
@@ -584,6 +618,8 @@ class AgeModel:
584
618
  kwargs['color'] = 'k'
585
619
  if 'lw' not in kwargs and 'linewidth' not in kwargs:
586
620
  kwargs['linewidth'] = 0.5
621
+ if 'alpha' not in kwargs:
622
+ kwargs['alpha'] = 0.25
587
623
  for i,isochrone in enumerate(isochrones):
588
624
  iso_age = isochrone['age']
589
625
  iso_mag = isochrone['MG']
@@ -599,7 +635,6 @@ class AgeModel:
599
635
  ages.append(iso_age)
600
636
  colors.append('k')
601
637
 
602
- isochrone_ages = []
603
638
  vmin = None
604
639
  vmax = None
605
640
  cb = None
@@ -609,37 +644,39 @@ class AgeModel:
609
644
  col,
610
645
  mag,
611
646
  c=age,
612
- cmap='viridis',
647
+ cmap=cmaps['tempo_R'],
613
648
  zorder=4,
614
649
  marker='*'
615
650
  )
616
651
  ages_arr = np.array(age)
617
652
  data_vmin = np.nanmin(ages_arr)
618
653
  data_vmax = np.nanmax(ages_arr)
619
- # If any values fall outside [0,14], restrict the colorbar to [0,14]
654
+
620
655
  if data_vmin < 0 or data_vmax > 14:
621
656
  vmin, vmax = 0.0, 14.0
622
657
  else:
623
658
  vmin, vmax = float(data_vmin), float(data_vmax)
624
- # Ensure a valid range
659
+
625
660
  if vmin >= vmax:
626
661
  vmin, vmax = max(0.0, vmin - 0.5), min(14.0, vmax + 0.5)
627
662
  if vmin >= vmax:
628
663
  vmin, vmax = 0.0, 14.0
629
664
  scatter.set_clim(vmin, vmax)
630
665
  cb = plt.colorbar(scatter, label='Age [Gyr]')
631
- if (type(plot_isochrone) is bool and plot_isochrone != False) or type(plot_isochrone) in (float,int,list):
632
- #if self.model_name != 'BaSTI':
633
- #raise ValueError('Plotting individual isochrones is only available for the BaSTI model at the moment')
634
- if type(plot_isochrone) is bool and plot_isochrone:
635
- if self.ages is not None and self.ages.shape[1] > 1:
636
- isochrone_ages = [self.population_age()]
637
- else:
638
- isochrone_ages = [np.median(age)]
639
- if type(plot_isochrone) is float or type(plot_isochrone) is int:
640
- isochrone_ages = [float(plot_isochrone)]
641
- elif type(plot_isochrone) is list:
642
- isochrone_ages = plot_isochrone
666
+
667
+ if plot_isochrone and isochrone_ages is None and isochrone_ages_std is None:
668
+ if self.ages is not None and self.ages.shape[1] > 1:
669
+ if self.pop_age is None:
670
+ self.population_age(check_domain=check_domain,use_tqdm=False)
671
+ isochrone_ages = [self.pop_age]
672
+ isochrone_ages_std = [self.pop_age_std]
673
+ else:
674
+ isochrone_ages = [np.median(age)]
675
+ isochrone_ages_std = [np.std(age)]
676
+ if type(isochrone_ages) is float or type(isochrone_ages) is int:
677
+ isochrone_ages = [float(isochrone_ages)]
678
+ if type(isochrone_ages_std) is float or type(isochrone_ages_std) is int:
679
+ isochrone_ages_std = [float(isochrone_ages_std)]
643
680
 
644
681
  if len(isochrone_ages) > 0:
645
682
  if vmin is None or vmax is None:
@@ -649,30 +686,37 @@ class AgeModel:
649
686
  else:
650
687
  vmin = max(0, isochrone_ages[0] - 0.5)
651
688
  vmax = min(14, isochrone_ages[0] + 0.5)
652
- for isochrone_age in isochrone_ages:
689
+ for i,isochrone_age in enumerate(isochrone_ages):
653
690
  isochrone = self.get_closest_isochrone(isochrone_age)
654
- norm = plt.Normalize(vmin, vmax)
655
- cmap = plt.get_cmap('viridis')
656
- color = cmap(norm(isochrone_age))
691
+ color = cmaps['acton']((i+1)/(len(isochrone_ages)+1))
692
+
693
+ if isochrone_ages_std is not None and len(isochrone_ages_std) == len(isochrone_ages):
694
+ isochrone_age_std = isochrone_ages_std[isochrone_ages.index(isochrone_age)]
695
+ label = r'$\tau$' + f'={isochrone_age:.2f} ' + r'$\pm$' + f' {isochrone_age_std:.2f} Gyr'
696
+ isochrone_low = self.get_closest_isochrone(isochrone_age - isochrone_age_std)
697
+ isochrone_upp = self.get_closest_isochrone(isochrone_age + isochrone_age_std)
698
+ verts = np.concatenate([
699
+ np.column_stack([isochrone_low['BP-RP'], isochrone_low['MG']]),
700
+ np.column_stack([isochrone_upp['BP-RP'][::-1], isochrone_upp['MG'][::-1]])
701
+ ])
702
+ poly = Polygon(verts, closed=True, facecolor=color, alpha=0.25, edgecolor=None, zorder=6)
703
+ ax.add_patch(poly)
704
+ else:
705
+ label = r'$\tau$' + f'={isochrone_age:.2f} Gyr'
706
+
657
707
  line, = ax.plot(
658
708
  isochrone['BP-RP'],
659
709
  isochrone['MG'],
660
710
  color=color,
661
711
  linewidth=2,
662
712
  zorder=5,
663
- label=f'Isochrone (age={isochrone_age:.2f} Gyr)'
713
+ label=label
664
714
  )
715
+
665
716
  has_labels = True
666
717
  lines.append(line)
667
718
  ages.append(isochrone_age)
668
719
  colors.append(color)
669
-
670
- if cb is None:
671
- norm = plt.Normalize(vmin, vmax)
672
- mappable = plt.cm.ScalarMappable(norm=norm, cmap='viridis')
673
- mappable.set_array([vmin,vmax])
674
- cb = plt.colorbar(mappable, ax=ax, label='Age [Gyr]')
675
- has_labels = True
676
720
 
677
721
  annot = ax.annotate("", xy=(0,0), xytext=(0,15), textcoords="offset points",
678
722
  ha='center',
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: astro-nest
3
- Version: 0.7.2.dev2
3
+ Version: 0.7.2.dev4
4
4
  Summary: A python package that provides neural networks to estimate ages of stars.
5
5
  Author-email: Tristan Boin <tristan.boin@obspm.fr>
6
6
  License-Expression: MIT
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: astro-nest
3
- Version: 0.7.2.dev2
3
+ Version: 0.7.2.dev4
4
4
  Summary: A python package that provides neural networks to estimate ages of stars.
5
5
  Author-email: Tristan Boin <tristan.boin@obspm.fr>
6
6
  License-Expression: MIT
@@ -2,6 +2,7 @@ pyproject.toml
2
2
  readme.md
3
3
  NEST/__init__.py
4
4
  NEST/_version.py
5
+ NEST/cmaps.npz
5
6
  NEST/core.py
6
7
  NEST/domain.pkl
7
8
  NEST/tutorial.ipynb
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "astro-nest"
7
- version = "0.7.2dev2"
7
+ version = "0.7.2dev4"
8
8
  authors = [
9
9
  { name="Tristan Boin", email="tristan.boin@obspm.fr" },
10
10
  ]
@@ -27,4 +27,4 @@ include = ["NEST"]
27
27
  Homepage = "https://star-age.github.io/NEST-docs/"
28
28
 
29
29
  [tool.setuptools.package-data]
30
- NEST = ["NEST.py","models/**/*","domain.pkl","tutorial.ipynb"]
30
+ NEST = ["NEST.py","models/**/*","domain.pkl","tutorial.ipynb","cmaps.npz"]