fidanka.isofit package
Submodules
fidanka.isofit.fit module
- fidanka.isofit.fit.bol_correct_iso(iso: ndarray[Any, dtype[ScalarType]], bc: BolometricCorrector, filters: Tuple[str, str, str] = ('F606W', 'F814W', 'F606W'), Av: float = 0, distance: float = 0) Tuple[ndarray[Any, dtype[ScalarType]], ndarray[Any, dtype[ScalarType]]]
Bolometrically correct an isochrone and return the color and magnitude arrays. The isochrone must be in the correct format (i.e. the MIST format).
- Parameters:
iso (np.ndarray) – The isochrone to bolometrically corerect, must be a numpy representation of a MIST format isochrone with EEPs in the 0th column, effective temperature (NOT log Teff) in the 1st, logg in the 2nd, and logL in the 3rd.
bc (BolometricCorrector) – An already instantiaed bolometric corrector object.
filters (Tuple[str, str, str], default=("F606W", "F814W", "F606W")) – The filters to use for the color and magnitude. The first two are the color filters and the last is the magnitude filter.
Av (float, default=0) – The color excess.
distance (float, default=0) – The distance modulus.
- Returns:
isoColor (np.ndarray) – The bolometrically corrected color.
isoMag (np.ndarray) – The bolometrically corrected magnitude.
- fidanka.isofit.fit.fit_isochrone_to_population(fiducialSequences: List[ndarray[Any, dtype[[numpy.ndarray[Any, numpy.dtype[numpy.float64]], numpy.ndarray[Any, numpy.dtype[numpy.float64]]]]]], ISOs: dict[str, dict[float, dict[float, pandas.core.frame.DataFrame]]], filters: Tuple[str, str, str], fiducialLookup: dict[str, int]) dict[str, Union[dict[str, Tuple[float, Tuple[float, float, float], str, float, float]], dict[str, dict[float, dict[float, dict[str, Any]]]]]]
Take a set of isochrones which vary in population, helium mass fraction, and alpha enhancement and fit them to a fiducial line using chi2 minimization. Then order those isochrones into their best fit version
- Parameters:
fiducialSequences (List[np.ndarray[[np.ndarray[float64], np.ndarray[float64]]]]) – list of Fiducual lines in the format output by the fiducual function. Where fiducialLine[:, 0] are the colors of each fiducual point and fiducialLine[:, 1] are the magniudes of each fiducual point. Each element of the list is a differenet fiducual line for a differenet population. If you only have one population this will be a single element list.
ISOs (dict[str, dict[float, dict[float, pd.DataFrame]]]) – dictionary of isochrones indexed by population name, helium mass fraction, and alpha enhancement. If loaded and bolometrically corrected using pysep then this will be in the correct format. Otherwise make sure that it includes filters called “WFC3_UVIS_filter[0..2]_MAG” which have your filters in them. In future this will be cleaned up to allow for more general filters.
filters (Tuple[str, str, str], default=("F606W", "F814W", "F606W")) – Filter names to use (which will get injcected to form the column names used to get the color and mag. The color is defined as filter[0] - filter[1] and the mag is filter[2]
fiducialLookup (dict[str, int]) – Mapping between ISOs and fiducialSequences. If your ISOs contains for example 1 populations called main then fiducial lookup would have to be {“main”: 0}
- Returns:
out – This is a dictionary summarizing the entire minimization process the key bf has the orderd optimization results. The key r has the more detailed resutls of each chi2 minimization that took place. The tuples in bf allow you to lookup anything in r
- Return type:
dict
- fidanka.isofit.fit.get_ISO_CMD_Chi2(iso: DataFrame, fiducialLine: ndarray[Any, dtype[[numpy.ndarray[Any, numpy.dtype[numpy.float64]], numpy.ndarray[Any, numpy.dtype[numpy.float64]]]]], bc: BolometricCorrector, fFid: Callable, filters: Tuple[str, str, str] = ('F606W', 'F814W', 'F606W'), distance: float = 0, Av: float = 0, age: float = None, n: int = 100, verbose: bool = False) float
Calculate the reduced chi2 value between an isochrone and a fiducialLine at a given distance in parsecs and color excess. The Chi2 is calculated as the sum of the squares of the distance between equivilent evolutionary points as detected by dynamic time warping.
- Parameters:
iso (pd.DataFrame) – The isochrone. If loaded and bolometrically corrected using pysep then this will be in the correct format. Otherwise make sure that it includes filters called “WFC3_UVIS_filter[0..2]_MAG” which have your filters in them. In future this will be cleaned up to allow for more general filters.
fiducialLine (np.ndarray[[np.ndarray[float64], np.ndarray[float64]]]) – Fiducual line in the format output by the fiducual function. Where fiducialLine[:, 0] are the colors of each fiducual point and fiducialLine[:, 1] are the magniudes of each fiducual point.
fFid (Callable) – The fiducial line function. This function must take a magnitude and return a color.
filters (Tuple[str, str, str], default=("F606W", "F814W", "F606W")) – Filter names to use (which will get injcected to form the column names used to get the color and mag. The color is defined as filter[0] - filter[1] and the mag is filter[2])
distance (float, default = 0) – Distance in parsecs to shift isochrone by when calculating the chi2 value
Av (float, default = 0) – Color excess to shift isochrone by when calculating the chi2 value
age (float, default = None) – The Age Currently being optimized. Not used here directly; however, if passed will be used as an additional debug output.
n (int, default = 100) – The number of points to use when calculating the interpolation used for the final dtw distance match (which is used to calculate the final chi2).
verbose (bool, default = False) – Flag controlling whether verbose output will be used. This can be helpful for debugging; however, it may slow down the code.
- Returns:
chi2nu – Reduced chi2 value. Calculated from the sum of the squares of the distances between EEPs between the fiducual line and isochrone as identified by dtw. Chi2 reduction is preformed then by dividing the chi2 value by the number of points used to calculate it.
- Return type:
float
- fidanka.isofit.fit.get_init_mu_guess(iso: ndarray[Any, dtype[ScalarType]], fiducialLine: ndarray[Any, dtype[ScalarType]], bc: BolometricCorrector, filters: Tuple[str, str, str]) Tuple[float, Tuple[ndarray[Any, dtype[ScalarType]], ndarray[Any, dtype[ScalarType]]]]
Make a first pass guess at the distance modulus using mean alignment of the magnitude at Av=0. Further optimization will have to be done but this preprocessing allows other algorithms such as the cross dtw algorithm to work
- Parameters:
iso (np.ndarray) – The isochrones (MIST format). This must have the temperature as the 2nd column, the logg as the third, and the log L as the first (the first column should be the EEPs; however, those are not actually used in this function).
fiducualLine (np.ndarray) – The fiducial line to be fit to. This should be a 2D array where the first column is the color of each fiducial point and the second column is the magnitude of each fiducial point. Therefore the shape will be (nx2) where n is the number of fiducial points.
bc (BolometricCorrector) – A bolometric corrector object which will be used to shift the isochrone into apparent magnitude space.
filters (Tuple[str, str, str]) – A tuple of string representing the two magnitudes used to make color and the magnitude for the vertical axis. The reason there are three and not two is to allow for easily swapping the order of which color component is the magnitude (as for example is common in the F275-F814W CMD). The color will be filter[0]-filter[1] and the mag will be filter[3].
- Returns:
shift (float) – The guessed distance modulus based on the mean magnitude alignment of the fiducial line and the bolometrically corrected isochrone
isoMag (np.ndarray) – The bolometrically corrected magnitude shifted by the distance modulus guess.
isoColor (np.ndarray) – The bolometrically corrected color.
- fidanka.isofit.fit.guess_mu(fIso: Callable, fFid: Callable, isoMagRange: Tuple[float, float], fidMagRange: Tuple[float, float], nMin: int = 5, nMax: int = 20, mMin: float = -10, mMax: float = 10, pbar: bool = False) Tuple[float, float]
Use Dynamic Time Warping to estimate the mu adjustment between the fiducial line and isochrone optimization. This algorithm is somewhat convoluted; however, it works well. The steps are as follows
Generate a grid of ns. These represent the number of points which will be used to run a latter interpolation step. The reason for this approach as compared to just using one larger n is that the scaling of dtw is O(n^2). However, by averaging the subsequent results over many small ns, we can get a good estimate.
At each n we run something similar to a cross-correlation. However, instead of the peasron correlation we calculate the dtw distance and path between the two functions. 2a. Using the path, which will connect equivilent features such as the MSTO
from the isochrone to the fiducial line, we can calculate the average euclidian shift between equivilent points on the two functions.
We take magnitude shift which results in the best (lowest) average euclidian disttance between the two functions.
Over all ns we average these best magitude shits.
I’ve tested this algorithm on a large number of cases, some of which are quite gnarlly. And it seems to work well. It is also quite fast. The only downside is that it is the initial location of the curves must be somewhat close. This can be easily achived using mean magnitude alignment.
- Parameters:
fIso (Callable) – The isochrone function. This function must take a magnitude and return a color.
fFid (Callable) – The fiducial line function. This function must take a magnitude and return a color.
isoMagRange (Tuple[float, float]) – The magnitude range of the isochrone.
fidMagRange (Tuple[float, float]) – The magnitude range of the fiducial line.
nMin (int, default=5) – The minimum number of points to use in the interpolation.
nMax (int, default=20) – The maximum number of points to use in the interpolation.
mMin (float, default=-10) – The minimum magnitude shift to consider.
mMax (float, default=10) – The maximum magnitude shift to consider.
pbar (bool, default=False) – Whether or not to show a progress bar.
- Returns:
mean (float) – The mean magnitude shift.
std (float) – The standard deviation of the magnitude shift.
- fidanka.isofit.fit.iterative_objective(r, bc, iso, fiducial, domain, ageChi2=False, filters=('WFC3_UVIS_F606W', 'WFC3_UVIS_F814W'), rFilterOrder=True)
- fidanka.isofit.fit.iterative_optimize(bounds, iso, fiducial, domain, bc, filters=('WFC3_UVIS_F275W', 'WFC3_UVIS_F814W'), rFilterOrder=True, getChi2Dist=False)
- fidanka.isofit.fit.limit_mu_space(iso: ndarray[Any, dtype[ScalarType]], fiducialLine: ndarray[Any, dtype[ScalarType]], bc: BolometricCorrector, filters: Tuple[str, str, str], fFid: Callable, pbar: bool = False) Tuple[float, float]
Use the two step, mean mangitude alignment and dtw cross correlation to guess the distance modulus which should be applied to some isochchrone. Also guess the scatter in this distance modulus. This can be used to limit the search space for latter true optimization algorithms.
- Parameters:
iso (np.ndarray) – The isochrones (MIST format). This must have the temperature as the 2nd column, the logg as the third, and the log L as the first (the first column should be the EEPs; however, those are not actually used in this function).
fiducualLine (np.ndarray) – The fiducial line to be fit to. This should be a 2D array where the first column is the color of each fiducial point and the second column is the magnitude of each fiducial point. Therefore the shape will be (nx2) where n is the number of fiducial points.
bc (BolometricCorrector) – A bolometric corrector object which will be used to shift the isochrone into apparent magnitude space.
filters (Tuple[str, str, str]) – A tuple of string representing the two magnitudes used to make color and the magnitude for the vertical axis. The reason there are three and not two is to allow for easily swapping the order of which color component is the magnitude (as for example is common in the F275-F814W CMD). The color will be filter[0]-filter[1] and the mag will be filter[3].
fFid (Callable) – The fiducial line function. This function must take a magnitude and return a color.
pbar (bool, default=False) – Whether or not to show a progress bar.
- Returns:
totalShift (float) – The distance modulus (not guarrenteed to have the correct sign, you may have to take the absoulte value) which best minimized the dtw cross correlation function on average
magStd (float) – The one sigma standard deviation in the distance modulus optimization
- fidanka.isofit.fit.optimize(fiducial: ndarray[Any, dtype[[numpy.ndarray[Any, numpy.dtype[numpy.float64]], numpy.ndarray[Any, numpy.dtype[numpy.float64]]]]], isochrone: Tuple[ndarray[Any, dtype[ScalarType]], ndarray[Any, dtype[ScalarType]], ndarray[Any, dtype[ScalarType]]], bolTables: str | List[str], FeH: float, filters: Tuple[str, str, str] = ('F606W', 'F814W', 'F606W'), verbose: bool = False, muSigSize: float = 3, muAge: float = 10) dict[str, Any]
Run Chi2 optimization results on photometry and isochrone minimizing the age, distance, and reddining needed to fit the isochrone to the fiducial line.
- Parameters:
fiducialLine (np.ndarray[[np.ndarray[float64], np.ndarray[float64]]]) – Fiducual line in the format output by the fiducual function. Where fiducialLine[:, 0] are the colors of each fiducual point and fiducialLine[:, 1] are the magniudes of each fiducual point.
isochrone (dict[pd.DataFrame]) – The isochrone. If loaded and bolometrically corrected using pysep then this will be in the correct format. Otherwise make sure that it includes filters called “WFC3_UVIS_filter[0..2]_MAG” which have your filters in them. In future this will be cleaned up to allow for more general filters.
bolTables (Union[str, List[str]]) – The bolometric correction tables to use. If a list is passed then the tables will be read from disk (each list element is a path to a table). If a string is passed then the appropriate tables will be fetched from the MIST website and used.
filters (Tuple[str, str, str], default=("F606W", "F814W", "F606W")) – Filter names to use (which will get injcected to form the column names used to get the color and mag). The color is defined as filter[0] - filter[1] and the mag is filter[2]
FeH (float) – The [Fe/H] value to use when bolometrically correcting isochrones.
verbose (bool, default = False) – Flag controlling whether verbose output will be used. This can be helpful for debugging; however, it may slow down the code.
muSigSize (float, default = 3) – The width of the sigma distribution above and below the central mu guess to be explored. Large values will allow for more leway in the E(B-V) value optimized. However, they will also slow down the optimizer and may increase the likelyhood of falling into a local minima
muAge (float, default=10) – The age at which to estimate the distance modulus in Gyr.
- Returns:
optimized – The optimization results
- Return type:
OptimizeResult
- fidanka.isofit.fit.order_best_fit_result(optimizationResults: dict[str, dict[float, dict[float, dict[str, Any]]]]) dict[str, List[Tuple[float, Tuple[float, float, float], str, float, float]]]
Order the best fit optimization results so that they are easy to parse. Ordering is done based on the fun attribure of the OptimizeResult object.
- Parameters:
optimizationResults (dict[str, dict[float, dict[float, CHI2R]]]) – Where CHI2R is the return type of the optimize function. This is a dictionary of those indexed based on population name, helium mass fraction, and alpha enhancement.
- Returns:
comparison – Where ORT is a Tuple continuing the chi2nu minimal result, the input vector x attaining that result (in the order of age, distance, Av), the population name, the helium mass fraction, and the alpha enhancement. The dict comparison is broken into two keys, one A and one E for the two populations of NGC 2808.
TODO: Make this more general so that it does not depend on the two populations of 2808. This should be pretty trivial to do
- Return type:
dict[str, List[ORT]]
- fidanka.isofit.fit.parallel_optimize(bounds, isopath_list, fiducialLine, bc, filters=('WFC3_UVIS_F275W', 'WFC3_UVIS_F814W'), rFilterOrder=True, getChi2Dist=False)
- fidanka.isofit.fit.shortest_distance_from_point_to_function(x, y, f)
Computes the shortest distance from a point (x, y) to the curve defined by function f. Returns the distance and the closest point on the function.
- Parameters:
x (float) – The x-coordinate of the point.
y (float) – The y-coordinate of the point.
f (callable) – Function of one variable.
- Returns:
distance (float) – The shortest distance from the point to the curve.
closest_point (tuple) – The closest point on the curve, as a tuple (x, f(x)).
- fidanka.isofit.fit.shortest_distance_with_endpoints(f1, f2, domain)
Compute the pointwise shortest distance and endpoints between two functions over a domain.
- Parameters:
f1 (callable) – Function of one variable.
f2 (callable) – Function of one variable.
domain (tuple) – Tuple containing (start, end, num_points), which defines the range and discretization.
- Returns:
distances (ndarray) – Pointwise shortest distances between the two functions over the domain.
endpoints (list of tuple) – Each tuple contains the starting and ending point of the shortest line segment.
fidanka.isofit.fitSingle module
- fidanka.isofit.fitSingle.estimate_single_star_age(starColor, starMag, isochrones, FeH, f1Key, f2Key, rFilterOrder=False, bcFilterSystem=None, mu=0, Av=0, Rv=3.1, ageBounds=[5, 15])
- fidanka.isofit.fitSingle.get_dist_between_iso_and_star_at_age(iso, age, starColor, starMag, fKey1, fKey2, rFilterOrder=False)
- fidanka.isofit.fitSingle.get_init_age_guess(iso, starColor, starMag, fKey1, fKey2, rFilterOrder=False)
- fidanka.isofit.fitSingle.get_point_iso_dist(starColor, starMag, isoAtAge, fKey1, fKey2, rFilterOrder=False)
- fidanka.isofit.fitSingle.identify_FeH_bounding_paths(isochroneSet, FeH)
- fidanka.isofit.fitSingle.interpolate_iso_to_single_star_FeH(isochroneSet, FeH)
fidanka.isofit.models module
- class fidanka.isofit.models.BolCorOp(isoDict, bc, filters, fiducial)
Bases:
Op
- itypes: Sequence['Type'] | None = [TensorType(float64, shape=(None,))]
- otypes: Sequence['Type'] | None = [TensorType(float64, shape=())]
- perform(node, inputs, outputs)
Calculate the function on the inputs and put the variables in the output storage.
- Parameters:
node – The symbolic Apply node that represents this computation.
inputs – Immutable sequence of non-symbolic/numeric inputs. These are the values of each Variable in
node.inputs
.output_storage – List of mutable single-element lists (do not change the length of these lists). Each sub-list corresponds to value of each Variable in
node.outputs
. The primary purpose of this method is to set the values of these sub-lists.params – A tuple containing the values of each entry in
Op.__props__
.
Notes
The output_storage list might contain data. If an element of output_storage is not
None
, it has to be of the right type, for instance, for a TensorVariable, it has to be a NumPyndarray
with the right number of dimensions and the correct dtype. Its shape and stride pattern can be arbitrary. It is not guaranteed that such pre-set values were produced by a previous call to thisOp.perform()
; they could’ve been allocated by another Op’s perform method. An Op is free to reuse output_storage as it sees fit, or to discard it and allocate new memory.