Blue loop Analyzer and Cross Counter
- mesalab.bluelooptools.blue_loop_analyzer.safe_duration(start, end)[source]
Safely computes the duration between two time points, ensuring both are valid and ordered.
- Parameters:
start (float) – Starting time value (e.g., age in years).
end (float) – Ending time value.
- Returns:
Duration (end - start) if both values are non-NaN and end > start; otherwise NaN.
- Return type:
float
- mesalab.bluelooptools.blue_loop_analyzer.is_in_instability_strip(log_Teff, log_L)[source]
Checks if a given stellar point (log_Teff, log_L) is inside the predefined Instability Strip.
The instability strip is defined by a hardcoded polygon (instability_path) in the HR Diagram (log_Teff vs log_L). The log_Teff axis is assumed to be inverted as is common in HR diagrams.
- Parameters:
log_Teff (float) – Logarithm of the effective temperature (log10(Teff)).
log_L (float) – Logarithm of the luminosity (log10(L/L_solar)).
- Returns:
True if the point is inside the instability strip, False otherwise.
- Return type:
bool
Example
>>> # Assuming instability_path is globally defined or accessible >>> # (defined at the module level in this file) >>> is_in_instability_strip(3.7, 3.0) # Example point inside the strip True >>> is_in_instability_strip(4.0, 3.0) # Example point outside False
- mesalab.bluelooptools.blue_loop_analyzer.compute_true_instability_duration(df: DataFrame, is_in_is_series: Series) float[source]
Computes the total time the star spends inside the Instability Strip, by summing all entry-exit intervals within the provided phase.
- Parameters:
df (pd.DataFrame) – DataFrame containing ‘star_age’ column.
is_in_is_series (pd.Series) – Boolean Series indicating IS membership per row.
- Returns:
Total duration spent inside the Instability Strip (in years).
- Return type:
float
- mesalab.bluelooptools.blue_loop_analyzer.analyze_blue_loop_and_instability(history_df: DataFrame, initial_mass: float, initial_Z: float, initial_Y: float)[source]
Analyzes MESA history data for blue loop characteristics and Instability Strip crossings, applying physical criteria to differentiate true blue loops from other IS crossings.
- Parameters:
history_df (pd.DataFrame) – DataFrame containing MESA history data. Must include ‘log_Teff’, ‘log_L’, ‘center_h1’, ‘star_age’, ‘model_number’, ‘log_g’, ‘center_he4’.
initial_mass (float) – Initial mass of the star.
initial_Z (float) – Initial metallicity (Z) of the star.
initial_Y (float) – Initial helium abundance (Y) of the star.
- Returns:
- A dictionary containing analysis results, including:
’crossing_count’: Number of times the star enters the Instability Strip during its relevant phase.
’state_times’: Dictionary of specific ages (MS end, min Teff post-MS, IS entries/exits).
- ’blue_loop_detail_df’: DataFrame with detailed data points during the relevant blue loop phase,
filtered to include only points inside or to the blue of the IS.
Returns a dictionary with NaN values if analysis cannot be performed (e.g., missing columns, no relevant phase).
- Return type:
dict
Example
>>> from mesalab.bluelooptools.blue_loop_analyzer import analyze_blue_loop_and_instability >>> import pandas as pd >>> import os # Load data from a MESA history.data file for a star that exhibits a blue loop. # This is the recommended approach for this function. # For this example, we'll assume 'history.data' is a pre-existing, valid file. >>> file_path = 'path/to/your/history.data' >>> if os.path.exists(file_path): ... history_df = pd.read_csv(file_path, delim_whitespace=True, skiprows=5) ... # Set initial parameters based on the MESA run, like: ... initial_mass = 5.0 ... initial_Z = 0.006 ... initial_Y = 0.28 ... result = analyze_blue_loop_and_instability(history_df, initial_mass, initial_Z, initial_Y) ... print(f"Crossing count: {result['crossing_count']}") ... else: ... print("MESA history.data file not found. Please provide a valid file.")
Blue loop CMD Plotting and Bolometric Corrections
- mesalab.bluelooptools.blue_loop_cmd_plotter.z_to_feh(Z)[source]
Converts metallicity Z to [Fe/H] (logarithmic iron-to-hydrogen ratio).
Uses a solar metallicity (Z_sun = 0.0152). Returns NaN for non-positive Z values.
- Parameters:
Z (float) – The metallicity value (mass fraction of elements heavier than H and He).
- Returns:
The [Fe/H] value, or np.nan if Z is not positive.
- Return type:
float
Example
>>> from mesalab.bluelooptools import z_to_feh >>> z_to_feh(0.0152) 0.0 >>> z_to_feh(0.0076) -0.3010299956639812 >>> z_to_feh(0) nan
- mesalab.bluelooptools.blue_loop_cmd_plotter.generate_blue_loop_plots_with_bc(combined_df_all_data, output_dir, output_type_label='all_blue_loop_data', plot_cfg=None)[source]
Analyzes MESA history data for stellar blue loop characteristics and Instability Strip crossings, and generates HRD, CMD, and LogL-LogG plots with bolometric corrections.
This function expects a DataFrame that combines MESA history data from one or more evolutionary tracks. It requires specific columns to perform its analysis and plotting.
- Parameters:
combined_df_all_data (pandas.DataFrame) – DataFrame containing combined MESA history data. Required columns are: - ‘log_Teff’ (Logarithm of effective temperature) - ‘log_L’ (Logarithm of luminosity in solar units) - ‘log_g’ (Logarithm of surface gravity) - ‘initial_Z’ (or ‘Z’ as a fallback, Initial metallicity) - Other MESA history columns are useful but not strictly required.
output_dir (str) – The directory where the generated plots will be saved.
output_type_label (str) – A label used in the filenames to categorize the output plots.
plot_cfg (dict, optional) – A dictionary of plotting configurations. If None, default configurations from ‘plot_config.py’ will be used.
Example
>>> import pandas as pd >>> import os >>> from mesalab.bluelooptools import generate_blue_loop_plots_with_bc >>> # Create a simple, yet realistic, dummy DataFrame. >>> # The rows simulate a short evolutionary phase. >>> dummy_data = { ... 'log_Teff': [3.78, 3.82, 3.75], ... 'log_L': [2.8, 3.0, 3.2], ... 'log_g': [3.5, 3.2, 3.0], ... 'initial_Z': [0.008, 0.008, 0.008] ... } >>> dummy_df = pd.DataFrame(dummy_data) >>> # Call the function with the data and an output directory. >>> generate_blue_loop_plots_with_bc(dummy_df, "temp_plot_output") Calculating BCs serially: 100%|███████████████████████████████████████| 3/3 [00:04<00:00, 1.65s/it]
- mesalab.bluelooptools.blue_loop_cmd_plotter.load_and_group_data(input_dir)[source]
This function expects CSV files to contain stellar evolution data. It checks for ‘initial_Z’ or ‘Z’ and ‘initial_mass’ columns.
- Parameters:
input_dir (str) – The path to the directory containing the CSV files.
- Returns:
- A concatenated DataFrame of all valid CSV data, or an empty
DataFrame if no files are found or critical columns are missing.
- Return type:
pd.DataFrame
Example
>>> import pandas as pd >>> import os >>> import tempfile >>> from mesalab.bluelooptools import blue_loop_cmd_plotter as bcmd >>> # Create a temporary directory and some dummy CSV files for the example >>> with tempfile.TemporaryDirectory() as temp_dir: ... # File 1: Correct data ... df1 = pd.DataFrame({'initial_mass': [1.0], 'initial_Z': [0.014], 'log_Teff': [3.7]}) ... df1.to_csv(os.path.join(temp_dir, 'run_1.csv'), index=False) ... # File 2: Missing 'initial_Z', but has 'Z' ... df2 = pd.DataFrame({'initial_mass': [1.5], 'Z': [0.008], 'log_Teff': [3.8]}) ... df2.to_csv(os.path.join(temp_dir, 'run_2.csv'), index=False) ... # Load and process the data ... combined_df = bcmd.load_and_group_data(temp_dir) ... # The combined DataFrame should have 2 rows and 3 columns ... print(f"Combined DataFrame shape: {combined_df.shape}") ... print(f"Columns: {combined_df.columns.tolist()}") ... print(f"First row's mass: {combined_df['initial_mass'].iloc[0]}") ... Combined DataFrame shape: (2, 4) Columns: ['initial_mass', 'initial_Z', 'log_Teff'] First row's mass: 1.0