Source code for slugpy.combine_cluster

Function to combine cluster data from multiple SLUG2 runs, treating
each input run as a separate set of trials. Note that trial and unique
ID numbers are not preserved by this operation.

from collections import namedtuple
import numpy as np
from warnings import warn

[docs]def combine_cluster(data): """ Function to combine cluster data from multiple SLUG2 runs, treating each input run as a separate set of trials. Trial and cluster unique ID numbers are altered as necessary to avoid duplication between the merged data sets. Parameters: data : list_like A list containing the cluster data for each run, as returned by read_cluster Returns: combined_data : namedtuple The combined data, in the same format as each object in data """ # Construct list of common fields, and issue warning if fields are # not identical s = set(data[0]._fields) warned = False for i in range(len(data)-1): if data[i]._fields != data[i+1]._fields and not warned: warnstr = "data to be combined does not have identical " + \ "fields; only common fields will be kept" warn(warnstr) s &= set(data[i+1]._fields) # List of fields for which we need only one copy, because they're # the same for every cluster single_fields = ['wl', 'wl_neb', 'wl_ex', 'wl_neb_ex', 'wl_r', 'filter_names', 'filter_units', 'filter_wl', 'filter_wl_eff', 'filter_response', 'filter_beta', 'filter_wl_c', 'isotope_name', 'isotope_Z', 'isotope_A', 'cloudy_linelabel', 'cloudy_linewl', 'cloudy_wl', 'cloudy_filter_names', 'cloudy_filter_units', 'cloudy_filter_wl_eff', 'cloudy_filter_wl', 'cloudy_filter_response', 'cloudy_filter_beta', 'cloudy_filter_wl_c','line_names'] # Combine fields new_fields = [] for f in s: if f == 'id': # ID field requires special handling cluster_id = data[0].id for j in range(1,len(data)): if len(cluster_id) > 0: cluster_id = np.append( cluster_id, data[j].id+np.amax(cluster_id)) else: cluster_id = np.append(cluster_id, data[j].id) new_fields.append(cluster_id) elif f == 'trial': # Trial field requires special handling; note that this is # slightly different from the ID field, because the ID # field is 1 offset and the trial number is 0 offset trial = data[0].trial for j in range(1,len(data)): if len(trial) > 0: trial = np.append( trial, data[j].trial+np.amax(trial)+1) else: trial = np.append( trial, data[j].trial) new_fields.append(trial) # For the following fields we just need one copy elif f in single_fields: new_fields.append(getattr(data[0], f)) # All other fields can just be concatenated else: joined_field = np.concatenate([getattr(d, f) for d in data]) new_fields.append(joined_field) # Create new output object out_type = namedtuple('cluster_data', s) combined_data = out_type._make(new_fields) # Return return combined_data