def load_scenarios( self, fps_d=None, #container of filepaths base_dir=None, #base directory to add ): #======================================================================= # defaults #======================================================================= log = self.logger.getChild('load_scenarios') if fps_d is None: fps_d = self.fps_d if base_dir is None: base_dir = self.base_dir log.info('on %i scenarios' % len(fps_d)) #======================================================================= # precheck #======================================================================= assert len(fps_d) >= 2 assert isinstance(fps_d, dict) assert len(fps_d.values()) == len(set( fps_d.values())), 'must specify unique Control filepaths' #======================================================================= # relatives #======================================================================= if not self.absolute_fp: fps_d = {k: os.path.join(base_dir, v) for k, v in fps_d.items()} for k, fp in fps_d.items(): assert isinstance(fp, str) assert os.path.exists(fp), 'bad filepath: %s' % (fp) #======================================================================= # build each scenario---- #======================================================================= """needs to be a strong reference or the workers die!""" d = dict() #start a weak reference container for i, (tag, fp) in enumerate(fps_d.items()): log.debug('loading %i/%i' % (i + 1, len(fps_d))) # build/load the children sWrkr = Scenario(self, cf_fp=fp, absolute_fp=self.absolute_fp, base_dir=os.path.dirname(fp), tag=tag).setup() # add to family assert sWrkr.name not in d, 'scenario \'%s\' already loaded!' % sWrkr.name d[sWrkr.name] = sWrkr log.debug('loaded \'%s\'' % sWrkr.name) self.sWrkr_d = d log.info('compiled %i scenarios: %s' % (len(self.sWrkr_d), list(self.sWrkr_d.keys()))) return wdict(self.sWrkr_d)
def cf_compare( self, #compare control file values between Scenarios sWrkr_d=None, logger=None): if logger is None: logger = self.logger log = logger.getChild('cf_compare') if sWrkr_d is None: sWrkr_d = wdict(self.sWrkr_d) assert len(sWrkr_d) >= 2 #======================================================================= # collect all the parameters from the children #======================================================================= first = True for childName, sWrkr in sWrkr_d.items(): log.debug('extracting variables from %s' % childName) #=================================================================== # collect values from this child #=================================================================== firstC = True for sectName, svars_d in sWrkr.cfPars_d.items(): if len(svars_d) == 0: continue #skip blank sections sdf = pd.DataFrame.from_dict(svars_d, orient='index') sdf.columns = [childName] #collapse the field names sdf.index = pd.Series(np.full(len(sdf), sectName)).str.cat( pd.Series(sdf.index), sep='.') if firstC: cdf = sdf firstC = False else: cdf = cdf.append(sdf) #add the control file path itself cdf.loc['cf_fp', childName] = sWrkr.cf_fp #=================================================================== # update library #=================================================================== if first: mdf = cdf first = False else: mdf = mdf.join(cdf) #======================================================================= # compare values #======================================================================= #determine if all values match by row mdf['compare'] = mdf.eq(other=mdf.iloc[:, 0], axis=0).all(axis=1) log.info( 'finished w/ %i (of %i) parameters matching between %i scenarios' % (mdf['compare'].sum(), len(mdf.index), len(mdf.columns))) return mdf
def riskCurves( self, #plot a risk curve comparing all the scenarios sWrkr_d=None, #container of scenario works to plot curve comparison logger=None, #plot keys y1lab='AEP', #yaxis label and plot type c ontrol #plot formatters val_str='*no', **plotKwargs): #======================================================================= # defaults #======================================================================= if logger is None: logger = self.logger log = logger.getChild('riskCurves') if sWrkr_d is None: sWrkr_d = wdict(self.sWrkr_d) #======================================================================= # collect data from children #======================================================================= plotPars_d = dict() #loop through each first = True for childName, sWrkr in sWrkr_d.items(): log.debug('preping %s' % childName) plotPars_d[childName] = { 'ttl_df': sWrkr.data_d['r_ttl'], 'ead_tot': sWrkr.ead_tot, 'impStyle_d': sWrkr.impStyle_d.copy(), } if first: self.impact_name = sWrkr.impact_name first = False return self.plot_mRiskCurves(plotPars_d, y1lab=y1lab, impactFmtFunc=self.impactFmtFunc, val_str=val_str, logger=log, **plotKwargs)
def build_composite( self, #merge data from a collection of asset models sWrkr_d=None, #container of scenario works to plot curve comparison new_wrkr=True, #whether to build a new worker ): log = self.logger.getChild('collect_ttls') if sWrkr_d is None: sWrkr_d = wdict(self.sWrkr_d) #more logicla for single plots self.name = self.tag #======================================================================= # collect data #======================================================================= mdf = None ead_d = dict() for childName, sWrkr in sWrkr_d.items(): dfi_raw = sWrkr.data_d['r_ttl'].copy() #set by prep_ttl() dfi = dfi_raw.loc[:, 'impacts'].rename(childName).astype( float).to_frame() ead_d[childName] = sWrkr.ead_tot if mdf is None: #pull some from the first self.impact_name = sWrkr.impact_name self.rtail, self.ltail = sWrkr.rtail, sWrkr.ltail mindex = pd.MultiIndex.from_frame( dfi_raw.loc[:, ['aep', 'ari', 'note', 'plot']]) mdf = dfi else: mdf = mdf.join(dfi) #======================================================================= # build new worker #======================================================================= if new_wrkr: cWrkr = sWrkr.copy(name='%s_%i_composite' % (self.tag, len(sWrkr_d))) #start with a copy #=================================================================== # convert the data to standard ttl format #=================================================================== cttl_df = dfi_raw.drop(['impacts', 'ari'], axis=1).copy() cttl_df[self.impact_name] = mdf.sum(axis=1) #fix order """ prep_ttl() is column location senstigvite """ l = cttl_df.columns.to_list() l.remove(self.impact_name) l = [l[0], self.impact_name] + l[1:] cttl_df = cttl_df.loc[:, l] #add the ead row at the bottom cWrkr.data_d['r_ttl'] = cttl_df.append(pd.Series({ 'aep': 'ead', 'note': 'integration', 'plot': False, self.impact_name: sum(ead_d.values()) }), ignore_index=True) """this function isnt set up very well.. easier to do it ourselves here #get just the combined impacts (drop tails) bx = dfi_raw['note']=='impact_sum' cttl_df = dfi_raw.loc[bx, 'aep'].to_frame().join(pd.Series(mdf[bx].sum(axis=1), name='impacts')) cWrkr.data_d['r_ttl'] = dfi_raw #set this for pulling handles cWrkr.data_d['r_ttl'], ead_tot = cWrkr.get_ttl(cttl_df, logger=log, cols_include=['note', 'plot'])""" #======================================================================= # wrap #======================================================================= mdf.index = mindex """ view(mdf) """ log.info('collected %i' % len(mdf.columns)) self.cdxind = mdf self.ead_d = ead_d self.ead_tot = sum(ead_d.values()) return self.cdxind, cWrkr