3 import basic_plot_functions 
as bpf
 
    4 import binning_utils 
as bu
 
    5 import predefined_configs 
as pconf
 
    6 from collections.abc 
import Iterable
 
    7 from collections 
import defaultdict
 
    8 from copy 
import deepcopy
 
   11 import diag_utils 
as du
 
   14 import multiprocessing 
as mp
 
   16 from pathlib 
import Path
 
   17 import plot_utils 
as pu
 
   20 import stat_utils 
as su
 
   21 import StatisticsDatabase 
as sdb
 
   22 import var_utils 
as vu
 
   25 for x 
in su.sampleableAggStats:
 
   26     if x != 
'Count': bootStrapStats.append(x)
 
   29 figureFileType = 
'pdf'  
   35   return DiagSpace+
'_analyses' 
   41     def __init__(self, db, analysisType, diagnosticGroupings = {}):
 
   70         for (varName, varUnits) 
in zip(self.
varNamesvarNames, self.
dbdb.varUnitss):
 
   72             if varUnits != vu.miss_s:
 
   73                 label = label+
' ('+varUnits+
')' 
   74             varLabels.append(label)
 
  106         wd = CWD.split(
'/')[-1]
 
  112         self.
myFigPathmyFigPath.mkdir(parents=
True, exist_ok=
True)
 
  116         Format the binMethod for file naming 
  121                 binMethodFile = 
'_'+binMethod
 
  123                 binMethodFile = binMethod+
'_' 
  129         Format the diagnosticGroup for forecast analysisType's 
  131         fcDiagName = diagnosticGroup
 
  132         if self.
fcTDeltasfcTDeltas[-1] > dt.timedelta(0):
 
  133             fcDiagName = fcDiagName.replace(
'omm',
'omf')
 
  134             fcDiagName = fcDiagName.replace(
'omb',
'omf')
 
  135             fcDiagName = fcDiagName.replace(
'bmo',
'fmo')
 
  136             fcDiagName = fcDiagName.replace(
'mmo',
'fmo')
 
  137             fcDiagName = fcDiagName.replace(
'hmo',
'fmo')
 
  138             fcDiagName = fcDiagName.replace(
'bak',
'fc')
 
  142                            allDiagnosticNames = None):
 
  144         Define plotting attributes for the combination of diagnosticGroup and statName 
  146         ommDiagnostics = [
'omb', 
'oma', 
'omm', 
'omf']
 
  147         mmoDiagnostics = [
'bmo', 
'amo', 
'mmo', 
'fmo', 
'mmgfsan']
 
  148         truncateDiagnostics = ommDiagnostics+mmoDiagnostics
 
  149         diagnosticGroup_ = diagnosticGroup
 
  150         for diag 
in truncateDiagnostics:
 
  151             if diag 
in diagnosticGroup_:
 
  152                 diagnosticGroup_ = diag
 
  155         if statName 
in [
'Count']+du.CRStatNames:
 
  156             statDiagLabel = statName
 
  157             fcstatDiagLabel = statName
 
  159             statDiagLabel = statName+
'('+diagnosticGroup_+
')' 
  160             fcstatDiagLabel = statName+
'('+fcDiagName+
')' 
  164         allDiagnosticNames_ = deepcopy(allDiagnosticNames)
 
  165         if allDiagnosticNames_ 
is None:
 
  166             cntrlDiagnosticName = diagnosticGroup_
 
  167             allDiagnosticNames_ = [diagnosticGroup_]
 
  169             cntrlDiagnosticName = allDiagnosticNames_[0]
 
  171         for diag 
in truncateDiagnostics:
 
  172             if diag 
in cntrlDiagnosticName:
 
  173                 cntrlDiagnosticName = diag
 
  174             for idiag, adiag 
in enumerate(allDiagnosticNames_):
 
  176                     allDiagnosticNames_[idiag] = diag
 
  179         fcstatDiagDiffLabel = statName+
'('+fcDiagName+
'): [EXP - '+cntrlExpDiagnosticLabel+
']' 
  180         if statName == 
'Mean':
 
  181             if diagnosticGroup_ 
in ommDiagnostics:
 
  183                 fcstatDiagDiffLabel = statName+
': ['+cntrlExpDiagnosticLabel+
' - EXP]' 
  184             if diagnosticGroup_ 
in mmoDiagnostics:
 
  186                 fcstatDiagDiffLabel = statName+
': [EXP - '+cntrlExpDiagnosticLabel+
']' 
  188         sciTicks = (statName == 
'Count')
 
  190         return statDiagLabel, fcstatDiagLabel, fcstatDiagDiffLabel, sciTicks, signDefinite
 
  194         Determine the union of cyDTimes available between 
  195         the control and each other experiment at each fcTDelta 
  197         cntrlLoc = deepcopy(myLoc)
 
  202             cntrlLoc[
'fcTDelta'] = fcTDelta
 
  203             cntrlCYDTimes = set(dfw.levels(
'cyDTime', cntrlLoc))
 
  205             expLoc = deepcopy(cntrlLoc)
 
  206             for expName 
in self.
expNamesexpNames:
 
  207                 expLoc[
'expName'] = expName
 
  208                 expCYDTimes = set(dfw.levels(
'cyDTime', expLoc))
 
  209                 expsCYDTimes[(expName, fcTDelta)] = list(cntrlCYDTimes & expCYDTimes)
 
  210                 if len(cntrlCYDTimes) != len(expCYDTimes):
 
  211                     self.
loggerlogger.warning(self.
cntrlExpNamecntrlExpName+
' and '+expName+
' have different number of CYDTimes at forecast length ', fcTDelta, 
' Only using common CYDTimes for CI calculation.')
 
  215         self.
loggerlogger.info(
'analyze()')
 
  230         raise NotImplementedError()
 
  234     if len(allDiagnosticNames) > 1:
 
  235         return expName+
'-'+diagnosticName
 
  242     Utility function for providing an ordered list of 
  243     pairs of binVals and associated labels for 
  244     category binMethods in the context of a DFWrapper 
  247     binVar = vu.varDictAll[fullBinVar][1]
 
  249     dbSelect1DBinVals = dfw.levels(
'binVal')
 
  250     binUnitss = dfw.uniquevals(
'binUnits')
 
  253     assert (len(binUnitss) != 0 
and len(dbSelect1DBinVals) > 0), 
'ERROR: categoryBinValsAttributes received invalid binVar/binMethod' 
  255     binUnits = binUnitss[0]
 
  259     tmp = deepcopy(pconf.binVarConfigs.get(
 
  262         'values', dbSelect1DBinVals))
 
  264     if (
not isinstance(tmp, Iterable) 
or 
  265         isinstance(tmp, str)):
 
  266         select1DBinVals += [tmp]
 
  268         select1DBinVals += tmp
 
  269     for Bin 
in dbSelect1DBinVals:
 
  270         if Bin 
not in select1DBinVals:
 
  271             select1DBinVals.append(Bin)
 
  272     for Bin 
in list(select1DBinVals):
 
  273         if Bin 
not in dbSelect1DBinVals:
 
  274             select1DBinVals.remove(Bin)
 
  277     for binVal 
in select1DBinVals:
 
  278         if pu.isfloat(binVal) 
or pu.isint(binVal):
 
  279             t = 
' @ '+binVar+
'='+binVal
 
  280             if binUnits != vu.miss_s:
 
  286     binValsMap = list(zip(select1DBinVals, binTitles))
 
  296     Base class used to analyze statistics across binMethods with zero-dimensioned or 
  297       category binValues, e.g., QC flag, named latitude band, cloudiness regime, surface type 
  299     def __init__(self, db, analysisType, diagnosticGroupings):
 
  300         super().
__init__(db, analysisType, diagnosticGroupings)
 
  306             (vu.obsVarQC, bu.goodQCMethod): {
'binVarTier': 1},
 
  307             (vu.obsVarLat, bu.latbandsMethod): {
'binVarTier': 1},
 
  308             (vu.obsVarCldFrac, bu.cloudbandsMethod): {
'binVarTier': 1},
 
  310             (vu.noBinVar, bu.noBinMethod): {
'binVarTier': 1},
 
  311             (vu.obsRegionBinVar, bu.geoirlatlonboxMethod): {
'binVarTier': 2},
 
  312             (vu.modelRegionBinVar, bu.geoirlatlonboxMethod): {
'binVarTier': 2},
 
  313             (vu.obsVarPrs, bu.PjetMethod): {
'binVarTier': 3},
 
  314             (vu.obsVarAlt, bu.altjetMethod): {
'binVarTier': 3},
 
  315             (vu.obsVarLandFrac, bu.surfbandsMethod): {
'binVarTier': 3},
 
  321         if len(binValsMap) > 1:
 
  322             nxplots = len(binValsMap)
 
  323             nyplots = self.
nVarsnVars
 
  324             nsubplots = nxplots * nyplots
 
  326             nsubplots = self.
nVarsnVars
 
  327             nxplots = np.int(np.ceil(np.sqrt(nsubplots)))
 
  328             nyplots = np.int(np.ceil(np.true_divide(nsubplots, nxplots)))
 
  330         return nxplots, nyplots, nsubplots
 
  339         diagnosticGrouped = {}
 
  341             diagnosticGrouped[diag] = 
False 
  344         for group 
in list(diagnosticGroupings.keys()):
 
  345             diags = diagnosticGroupings[group]
 
  348                 del diagnosticGroupings[group]
 
  350             for diag 
in diags: diagnosticGrouped[diag] = 
True 
  353             if not diagnosticGrouped[diag]:
 
  354                 diagnosticGroupings[diag] = [diag]
 
  356         for diagnosticGroup, diagnosticNames 
in diagnosticGroupings.items():
 
  358             if len(set(diagnosticNames) & set(self.
availableDiagnosticsavailableDiagnostics)) == 0: 
continue 
  359             diagnosticConfigs = {}
 
  360             analysisStatistics = set([])
 
  361             for diagnosticName 
in diagnosticNames:
 
  362                 diagnosticConfigs[diagnosticName] = deepcopy(self.
diagnosticConfigsdiagnosticConfigs[diagnosticName])
 
  363                 analysisStatistics = set(list(analysisStatistics) +
 
  364                                          diagnosticConfigs[diagnosticName][
'analysisStatistics'])
 
  365             if not set(self.
requiredStatisticsrequiredStatistics).issubset(analysisStatistics): 
continue 
  367             diagLoc = {
'diagName': diagnosticNames}
 
  368             diagBinVars = self.
dbdb.dfw.levels(
'binVar', diagLoc)
 
  369             diagBinMethods = self.
dbdb.dfw.levels(
'binMethod', diagLoc)
 
  370             for (fullBinVar, binMethod), options 
in self.
binVarDictbinVarDict.items():
 
  371                 if options.get(
'binVarTier', 10) > self.
maxBinVarTiermaxBinVarTier: 
continue 
  372                 binVar = vu.varDictAll[fullBinVar][1]
 
  373                 if (binVar 
not in diagBinVars 
or 
  374                     binMethod 
not in diagBinMethods): 
continue 
  376                 self.
loggerlogger.info(diagnosticGroup+
', '+binVar+
', '+binMethod)
 
  380                         args = (diagnosticGroup, diagnosticConfigs, fullBinVar, binMethod, analysisStatistics, options))
 
  383                         diagnosticGroup, diagnosticConfigs, fullBinVar, binMethod, analysisStatistics, options)
 
  386         diagnosticGroup, diagnosticConfigs, fullBinVar, binMethod, analysisStatistics, options):
 
  388         binVar = vu.varDictAll[fullBinVar][1]
 
  392         myLoc[
'binVar'] = binVar
 
  393         myLoc[
'binMethod'] = binMethod
 
  395         mydfwDict = {
'dfw': self.
dbdb.loc(myLoc)}
 
  399             mydfwDict[
'agg'] = sdb.DFWrapper.fromAggStats(mydfwDict[
'dfw'], [
'cyDTime'])
 
  400             sdb.createORreplaceDerivedDiagnostics(mydfwDict[
'agg'], diagnosticConfigs)
 
  405         myLoc[
'diagName'] = list(diagnosticConfigs.keys())
 
  406         for key 
in mydfwDict.keys():
 
  407             mydfwDict[key] = sdb.DFWrapper.fromLoc(mydfwDict[key], myLoc)
 
  410             mydfwDict[
'dfw'], fullBinVar, binMethod, options)
 
  414         for statName 
in analysisStatistics:
 
  415             if statName 
not in options.get(
'onlyStatNames', analysisStatistics): 
continue 
  418                 mydfwDict, diagnosticGroup, myLoc, statName, binValsMap, options,
 
  419                 nsubplots, nxplots, nyplots)
 
  422         dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options,
 
  423         nsubplots, nxplots, nyplots):
 
  427         raise NotImplementedError()
 
  432     Creates a timeseries figure between firstCycleDTime and lastCycleDTime 
  433       for each forecast length between fcTDeltaFirst and fcTDeltaLast 
  434       -  x-axis: cycle initial time 
  435       -    line: per experiment 
  436       - subplot: combination of DiagSpace variable and binVal 
  437       -    file: combination of binVar, statistic, and FC lead time (if applicable) 
  439     def __init__(self, db, analysisType, diagnosticGroupings):
 
  440         super().
__init__(db, analysisType, diagnosticGroupings)
 
  446         dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options,
 
  447         nsubplots, nxplots, nyplots):
 
  449         if self.
nCYnCY < 2: 
return 
  451         bgstatDiagLabel, fcstatDiagLabel, fcstatDiagDiffLabel, sciTicks, signDefinite = \
 
  454         myPath = self.
myFigPathmyFigPath/diagnosticGroup
 
  455         myPath.mkdir(parents=
True, exist_ok=
True)
 
  461         for (fcTDelta, fcTDelta_totmin) 
in self.
fcMapfcMap:
 
  462             lineLoc[
'fcTDelta'] = fcTDelta
 
  463             axisLimitsLoc[
'fcTDelta'] = fcTDelta
 
  470             for (varName, varLabel) 
in self.
varMapvarMap:
 
  471                 lineLoc[
'varName'] = varName
 
  472                 axisLimitsLoc[
'varName'] = varName
 
  475                 for binVal, binTitle 
in binValsMap:
 
  476                     lineLoc[
'binVal'] = binVal
 
  477                     axisLimitsLoc[
'binVal'] = binVal
 
  480                     if statName == 
'Count':
 
  483                         dmin = dfwDict[
'dfw'].min(axisLimitsLoc, statName)
 
  484                     dmax = dfwDict[
'dfw'].max(axisLimitsLoc, statName)
 
  490                     for expName 
in self.
expNamesexpNames:
 
  491                         lineLoc[
'expName'] = expName
 
  492                         for diagnosticName 
in myLoc[
'diagName']:
 
  493                             linesGroup.append(expName)
 
  495                                 expName, diagnosticName, myLoc[
'diagName']))
 
  497                             lineLoc[
'diagName'] = diagnosticName
 
  499                             lineCYDTimes = dfwDict[
'dfw'].levels(
'cyDTime', lineLoc)
 
  501                             lineVals = np.full(self.
nCYnCY, np.NaN)
 
  502                             cyLoc = deepcopy(lineLoc)
 
  503                             for cyDTime 
in lineCYDTimes:
 
  504                                 icy = self.
cyDTimescyDTimes.index(cyDTime)
 
  505                                 cyLoc[
'cyDTime'] = cyDTime
 
  506                                 lineVals[icy] = dfwDict[
'dfw'].loc(cyLoc, statName)
 
  507                             linesVals.append(lineVals)
 
  510                     title = varLabel+binTitle
 
  515                         self.
cyDTimescyDTimes, linesVals, linesLabel,
 
  516                         title, bgstatDiagLabel,
 
  517                         sciTicks, 
False, signDefinite,
 
  518                         nyplots, nxplots, nsubplots, iplot,
 
  519                         dmin = dmin, dmax = dmax,
 
  520                         interiorLabels = interiorLabels)
 
  529             filename = myPath/(
'%s%s_TSeries_%smin_%s_%s_%s'%(
 
  533             pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels)
 
  540     Creates a timeseries figure between fcTDeltaFirst and fcTDeltaLast containing 
  541       aggregated statistics for the period between firstCycleDTime and lastCycleDTime 
  542       -  x-axis: forecast duration 
  543       -    line: per experiment 
  544       - subplot: combination of DiagSpace variable and binVal 
  545       -    file: combination of binVar and statistic 
  547     def __init__(self, db, analysisType, diagnosticGroupings):
 
  548         super().
__init__(db, analysisType, diagnosticGroupings)
 
  556         dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options,
 
  557         nsubplots, nxplots, nyplots):
 
  559         if self.
nFCnFC < 2: 
return 
  561         bgstatDiagLabel, fcstatDiagLabel, fcstatDiagDiffLabel, sciTicks, signDefinite = \
 
  565         myPath = self.
myFigPathmyFigPath/fcDiagName
 
  566         myPath.mkdir(parents=
True, exist_ok=
True)
 
  576         for (varName, varLabel) 
in self.
varMapvarMap:
 
  577             lineLoc[
'varName'] = varName
 
  578             axisLimitsLoc[
'varName'] = varName
 
  581             for binVal, binTitle 
in binValsMap:
 
  582                 lineLoc[
'binVal'] = binVal
 
  583                 axisLimitsLoc[
'binVal'] = binVal
 
  586                 if statName == 
'Count':
 
  589                     dmin = dfwDict[
'agg'].min(axisLimitsLoc, statName)
 
  590                 dmax = dfwDict[
'agg'].max(axisLimitsLoc, statName)
 
  596                 for expName 
in self.
expNamesexpNames:
 
  597                     lineLoc[
'expName'] = expName
 
  598                     for diagnosticName 
in myLoc[
'diagName']:
 
  599                         linesGroup.append(expName)
 
  601                             expName, diagnosticName, myLoc[
'diagName']))
 
  602                         lineLoc[
'diagName'] = diagnosticName
 
  604                         lineFCTDeltas = dfwDict[
'agg'].levels(
'fcTDelta', lineLoc)
 
  606                         lineVals = np.full(self.
nFCnFC, np.NaN)
 
  607                         fcLoc = deepcopy(lineLoc)
 
  608                         for fcTDelta 
in lineFCTDeltas:
 
  609                             ifc = self.
fcTDeltasfcTDeltas.index(fcTDelta)
 
  610                             fcLoc[
'fcTDelta'] = fcTDelta
 
  611                             lineVals[ifc] = dfwDict[
'agg'].loc(fcLoc, statName)
 
  612                         linesVals.append(lineVals)
 
  615                 title = varLabel+binTitle
 
  620                     self.
fcTDeltasfcTDeltas, linesVals, linesLabel,
 
  621                     title, fcstatDiagLabel,
 
  622                     sciTicks, 
False, signDefinite,
 
  623                     nyplots, nxplots, nsubplots, iplot,
 
  624                     dmin = dmin, dmax = dmax,
 
  625                     interiorLabels = interiorLabels)
 
  634         filename = myPath/(
'%s%s_TSeries_%s-%smin_%s_%s_%s'%(
 
  639         pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels)
 
  644     Similar to FCAxisExpLines, except 
  645       - shows difference between experiment(s) and control 
  646       - control is selected using cntrlExpIndex 
  647       - statistics are narrowed down by bootStrapStats 
  648       - confidence intervals (CI) are shown at each lead time 
  649       -    line+shaded region: per experiment 
  650       - subplot: combination of DiagSpace variable and binVal 
  651       -    file: combination of binVar and statistic 
  653     def __init__(self, db, analysisType, diagnosticGroupings):
 
  654         super().
__init__(db, analysisType, diagnosticGroupings)
 
  663             if 'onlyStatNames' in self.
binVarDictbinVarDict[key]:
 
  664                 self.
binVarDictbinVarDict[key][
'onlyStatNames'] += bootStrapStats
 
  666                 self.
binVarDictbinVarDict[key][
'onlyStatNames'] = bootStrapStats
 
  669         dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options,
 
  670         nsubplots, nxplots, nyplots):
 
  672         if self.
nFCnFC < 2: 
return 
  673         if self.
nExpnExp * len(myLoc[
'diagName']) < 2: 
return 
  674         if self.
cntrlExpNamecntrlExpName 
not in dfwDict[
'dfw'].levels(
'expName'): 
return 
  676         bgstatDiagLabel, fcstatDiagLabel, fcstatDiagDiffLabel, sciTicks, signDefinite = \
 
  680         myPath = self.
myFigPathmyFigPath/fcDiagName
 
  681         myPath.mkdir(parents=
True, exist_ok=
True)
 
  693         for (varName, varLabel) 
in self.
varMapvarMap:
 
  694             binValLoc[
'varName'] = varName
 
  697             for binVal, binTitle 
in binValsMap:
 
  698                 binValLoc[
'binVal'] = binVal
 
  701                 tempdfw = sdb.DFWrapper.fromLoc(dfwDict[
'dfw'], binValLoc)
 
  703                 cntrlLoc = deepcopy(binValLoc)
 
  707                 title = varLabel+binTitle
 
  709                 linesVals = defaultdict(list)
 
  712                 cntrlLoc[
'diagName'] = myLoc[
'diagName'][0]
 
  713                 for expName 
in self.
expNamesexpNames:
 
  714                     for diagnosticName 
in myLoc[
'diagName']:
 
  715                         if (expName == cntrlLoc[
'expName'] 
and 
  716                             diagnosticName == cntrlLoc[
'diagName']): 
continue 
  717                         linesGroup.append(expName)
 
  719                             expName, diagnosticName, myLoc[
'diagName']))
 
  721                         lineVals = defaultdict(list)
 
  723                             cntrlLoc[
'cyDTime'] = myExpsCYDTimes[(expName, fcTDelta)]
 
  724                             cntrlLoc[
'fcTDelta'] = fcTDelta
 
  726                             expLoc = deepcopy(cntrlLoc)
 
  727                             expLoc[
'diagName'] = diagnosticName
 
  728                             expLoc[
'expName'] = expName
 
  730                             X = tempdfw.loc(expLoc)
 
  731                             Y = tempdfw.loc(cntrlLoc)
 
  733                             ciVals = su.bootStrapClusterFunc(
 
  736                                          statNames = [statName])
 
  738                             for trait 
in su.ciTraits:
 
  739                                 lineVals[trait] += [ciVals[statName][trait][0]]
 
  741                         for trait 
in su.ciTraits:
 
  742                             linesVals[trait].append(lineVals[trait])
 
  745                 dmin = np.nanmin(linesVals[su.cimin])
 
  746                 dmax = np.nanmax(linesVals[su.cimax])
 
  751                     self.
fcTDeltasfcTDeltas, linesVals[su.cimean],
 
  756                     nyplots, nxplots, nsubplots, iplot,
 
  757                     linesValsMinCI = linesVals[su.cimin],
 
  758                     linesValsMaxCI = linesVals[su.cimax],
 
  759                     dmin = dmin, dmax = dmax,
 
  760                     lineAttribOffset = 1,
 
  761                     interiorLabels = interiorLabels)
 
  769         filename = myPath/(
'%s%s_TSeries_%s-%smin_%s_%s_%s'%(
 
  774         pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels)
 
  779     Similar to CYAxisExpLines, except 
  780       each line is for a different forecast lead time and 
  781       each experiment is in a different file 
  782       -  x-axis: valid time of forecast 
  783       -    line: per FC lead time 
  784       - subplot: combination of DiagSpace variable and binVal 
  785       -    file: combination of binVar, statistic, and experiment 
  786       - self.MAX_FC_LINES determines number of FC lead time lines to include 
  788     def __init__(self, db, analysisType, diagnosticGroupings):
 
  789         super().
__init__(db, analysisType, diagnosticGroupings)
 
  797         dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options,
 
  798         nsubplots, nxplots, nyplots):
 
  800         if self.
nFCnFC < 2 
or self.
nCYnCY < 2: 
return 
  802         bgstatDiagLabel, fcstatDiagLabel, fcstatDiagDiffLabel, sciTicks, signDefinite = \
 
  806         myPath = self.
myFigPathmyFigPath/fcDiagName
 
  807         myPath.mkdir(parents=
True, exist_ok=
True)
 
  813         for expName 
in self.
expNamesexpNames:
 
  814             lineLoc[
'expName'] = expName
 
  821             for (varName, varLabel) 
in self.
varMapvarMap:
 
  822                 lineLoc[
'varName'] = varName
 
  823                 axisLimitsLoc[
'varName'] = varName
 
  826                 for binVal, binTitle 
in binValsMap:
 
  827                     lineLoc[
'binVal'] = binVal
 
  828                     axisLimitsLoc[
'binVal'] = binVal
 
  831                     if statName == 
'Count':
 
  834                         dmin = dfwDict[
'dfw'].min(axisLimitsLoc, statName)
 
  835                     dmax = dfwDict[
'dfw'].max(axisLimitsLoc, statName)
 
  842                         lineLoc[
'fcTDelta'] = fcTDelta
 
  846                         for cyDTime 
in self.
cyDTimescyDTimes:
 
  847                             xVals.append(cyDTime+fcTDelta)
 
  854                             pu.timeDeltaTicks(fcTDelta.total_seconds(),0))
 
  856                         lineCYDTimes = dfwDict[
'dfw'].levels(
'cyDTime', lineLoc)
 
  858                         lineVals = np.full(self.
nCYnCY, np.NaN)
 
  859                         cyLoc = deepcopy(lineLoc)
 
  860                         for cyDTime 
in lineCYDTimes:
 
  861                             icy = self.
cyDTimescyDTimes.index(cyDTime)
 
  862                             cyLoc[
'cyDTime'] = cyDTime
 
  863                             lineVals[icy] = dfwDict[
'dfw'].loc(cyLoc, statName)
 
  865                         linesVals.append(lineVals)
 
  868                     title = varLabel+binTitle
 
  874                         title, bgstatDiagLabel,
 
  875                         sciTicks, 
False, signDefinite,
 
  876                         nyplots, nxplots, nsubplots, iplot,
 
  877                         dmin = dmin, dmax = dmax,
 
  878                         interiorLabels = interiorLabels)
 
  885             expFileName = re.sub(
'\.', 
'', re.sub(
'\s+', 
'-', expName))
 
  886             filename = myPath/(
'%s%s_TSeries_%s_%s_%s_%s'%(
 
  890             pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels)
 
  900     def __init__(self, db, analysisType, diagnosticGroupings):
 
  901         super().
__init__(db, analysisType, diagnosticGroupings)
 
  912             (vu.obsVarQC, bu.badQCMethod): {
 
  913                 'onlyStatNames': [
'Count'],
 
  916             (vu.obsVarQC, bu.allQCMethod): {
 
  917                 'onlyStatNames': [
'Count'],
 
  920             (vu.obsVarLat, bu.latbandsMethod): {
'binVarTier': 1},
 
  922             (vu.obsVarCldFrac, bu.cloudbandsMethod): {
'binVarTier': 1},
 
  923             (vu.obsVarLandFrac, bu.surfbandsMethod): {
'binVarTier': 3},
 
  933     Similar to CYAxisExpLines, except 
  934       each line is for a different binVal (e.g., latitude band, cloudiness, etc.) 
  935       -    line: binVals for named bins (e.g., NXTro, Tro, SXTro for latitude) 
  936       - subplot: column by experiment, row by DiagSpace variable 
  937       -    file: combination of statistic and forecast length 
  939     def __init__(self, db, analysisType, diagnosticGroupings):
 
  940         super().
__init__(db, analysisType, diagnosticGroupings)
 
  948         dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options,
 
  949         nsubplots, nxplots, nyplots):
 
  951         if self.
nCYnCY < 2: 
return 
  953         bgstatDiagLabel, fcstatDiagLabel, fcstatDiagDiffLabel, sciTicks, signDefinite = \
 
  957         myPath = self.
myFigPathmyFigPath/diagnosticGroup
 
  958         myPath.mkdir(parents=
True, exist_ok=
True)
 
  962         for binVal, binTitle 
in binValsMap: binVals.append(binVal)
 
  963         lineLoc[
'binVal'] = binVals
 
  965         axisLimitsLoc = deepcopy(lineLoc)
 
  968         for (fcTDelta, fcTDelta_totmin) 
in self.
fcMapfcMap:
 
  969             lineLoc[
'fcTDelta'] = fcTDelta
 
  970             axisLimitsLoc[
'fcTDelta'] = fcTDelta
 
  978             for (varName, varLabel) 
in self.
varMapvarMap:
 
  979                 lineLoc[
'varName'] = varName
 
  980                 axisLimitsLoc[
'varName'] = varName
 
  983                 if statName == 
'Count':
 
  986                     dmin = dfwDict[
'dfw'].min(axisLimitsLoc, statName)
 
  987                 dmax = dfwDict[
'dfw'].max(axisLimitsLoc, statName)
 
  990                 for expName 
in self.
expNamesexpNames:
 
  991                     lineLoc[
'expName'] = expName
 
  995                     for binVal 
in binVals:
 
  996                         lineLoc[
'binVal'] = binVal
 
  997                         lineCYDTimes = dfwDict[
'dfw'].levels(
'cyDTime', lineLoc)
 
  999                         lineVals = np.full(self.
nCYnCY, np.NaN)
 
 1000                         cyLoc = deepcopy(lineLoc)
 
 1001                         for cyDTime 
in lineCYDTimes:
 
 1002                             icy = self.
cyDTimescyDTimes.index(cyDTime)
 
 1003                             cyLoc[
'cyDTime'] = cyDTime
 
 1005                             lineVals[icy] = dfwDict[
'dfw'].loc(cyLoc, statName)
 
 1007                         linesVals.append(lineVals)
 
 1012                     title = expName+
'\n'+varLabel
 
 1017                         self.
cyDTimescyDTimes, linesVals, binVals,
 
 1018                         title, bgstatDiagLabel,
 
 1019                         sciTicks, 
False, signDefinite,
 
 1020                         nyplots, nxplots, nsubplots, iplot,
 
 1021                         dmin = dmin, dmax = dmax,
 
 1022                         interiorLabels = interiorLabels)
 
 1030             filename = myPath/(
'%s%s_TSeries_%smin_%s_%s_%s'%(
 
 1033                        diagnosticGroup, statName))
 
 1035             pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels)
 
 1048     Base class used to analyze statistics across binMethods with one-dimensional binValues 
 1049       that are assigned numerical values, e.g., altitude, pressure, latitude, cloud fraction 
 1051     def __init__(self, db, analysisType, diagnosticGroupings):
 
 1052         super().
__init__(db, analysisType, diagnosticGroupings)
 
 1058             vu.obsVarAlt: {
'profilefunc': bpf.plotProfile, 
'binVarTier': 1},
 
 1059             vu.obsVarACI: {
'profilefunc': bpf.plotSeries, 
'binVarTier': 2},
 
 1060             vu.obsVarCldFrac: {
'profilefunc': bpf.plotSeries, 
'binVarTier': 1},
 
 1061             vu.obsVarLat: {
'profilefunc': bpf.plotProfile, 
'binVarTier': 1},
 
 1062             vu.obsVarPrs: {
'profilefunc': bpf.plotProfile, 
'binVarTier': 1},
 
 1063             vu.obsVarSCI: {
'profilefunc': bpf.plotSeries, 
'binVarTier': 2},
 
 1065             vu.modVarLev: {
'profilefunc': bpf.plotProfile, 
'binVarTier': 1},
 
 1066             vu.obsVarGlint: {
'profilefunc': bpf.plotSeries, 
'binVarTier': 3},
 
 1067             vu.obsVarLandFrac: {
'profilefunc': bpf.plotSeries, 
'binVarTier': 3},
 
 1068             vu.obsVarLT: {
'profilefunc': bpf.plotSeries, 
'binVarTier': 3},
 
 1069             vu.obsVarSenZen: {
'profilefunc': bpf.plotSeries, 
'binbinVarTier': 3},
 
 1075         diagnosticGrouped = {}
 
 1077             diagnosticGrouped[diag] = 
False 
 1080         for group 
in list(diagnosticGroupings.keys()):
 
 1081             diags = diagnosticGroupings[group]
 
 1084                 del diagnosticGroupings[group]
 
 1086             for diag 
in diags: diagnosticGrouped[diag] = 
True 
 1089             if not diagnosticGrouped[diag]:
 
 1090                 diagnosticGroupings[diag] = [diag]
 
 1092         for diagnosticGroup, diagnosticNames 
in diagnosticGroupings.items():
 
 1094             if len(set(diagnosticNames) & set(self.
availableDiagnosticsavailableDiagnostics)) == 0: 
continue 
 1095             diagnosticConfigs = {}
 
 1096             analysisStatistics = set([])
 
 1097             for diagnosticName 
in diagnosticNames:
 
 1098                 diagnosticConfigs[diagnosticName] = deepcopy(self.
diagnosticConfigsdiagnosticConfigs[diagnosticName])
 
 1099                 analysisStatistics = set(list(analysisStatistics) +
 
 1100                                          diagnosticConfigs[diagnosticName][
'analysisStatistics'])
 
 1101             if not set(self.
requiredStatisticsrequiredStatistics).issubset(analysisStatistics): 
continue 
 1103             diagBinVars = self.
dbdb.dfw.levels(
'binVar', {
'diagName': diagnosticNames})
 
 1105             for fullBinVar, options 
in self.
binVarDictbinVarDict.items():
 
 1106                 if options.get(
'binVarTier', 10) > self.
maxBinVarTiermaxBinVarTier: 
continue 
 1107                 binVar = vu.varDictAll[fullBinVar][1]
 
 1108                 if (binVar 
not in diagBinVars): 
continue 
 1111                 binVarLoc[
'diagName'] = diagnosticNames
 
 1112                 binVarLoc[
'binVar'] = binVar
 
 1116                 binMethods = self.
dbdb.dfw.levels(
'binMethod', binVarLoc)
 
 1117                 for binMethod 
in binMethods:
 
 1119                     self.
loggerlogger.info(diagnosticGroup+
', '+binVar+
', '+binMethod)
 
 1123                             args = (diagnosticGroup, diagnosticConfigs, binVar, binMethod, analysisStatistics, options))
 
 1126                             diagnosticGroup, diagnosticConfigs, binVar, binMethod, analysisStatistics, options)
 
 1129         diagnosticGroup, diagnosticConfigs, binVar, binMethod, analysisStatistics, options):
 
 1132         myLoc[
'binVar'] = binVar
 
 1134         myLoc[
'binMethod'] = binMethod
 
 1137         mydfwDict = {
'dfw': self.
dbdb.loc(myLoc)}
 
 1141             mydfwDict[
'agg'] = sdb.DFWrapper.fromAggStats(mydfwDict[
'dfw'], [
'cyDTime'])
 
 1142             sdb.createORreplaceDerivedDiagnostics(mydfwDict[
'agg'], diagnosticConfigs)
 
 1147         myLoc[
'diagName'] = list(diagnosticConfigs.keys())
 
 1148         for key 
in mydfwDict.keys():
 
 1149             mydfwDict[key] = sdb.DFWrapper.fromLoc(mydfwDict[key], myLoc)
 
 1152         binVals = mydfwDict[
'dfw'].levels(
'binVal')
 
 1153         binUnits = mydfwDict[
'dfw'].uniquevals(
'binUnits')[0]
 
 1157         if binUnits != vu.miss_s:
 
 1158             indepLabel = indepLabel+
' ('+binUnits+
')' 
 1162         for binVal 
in binVals:
 
 1163             ibin = self.
allBinValsallBinVals.index(binVal)
 
 1164             binNumVals.append(self.
binNumValsbinNumVals[ibin])
 
 1167             pressure_dict = vu.varDictAll.get(vu.obsVarPrs,[
'',
''])
 
 1168             invert_ind_axis = (pressure_dict[1] == binVar)
 
 1171         indices = list(range(len(binNumVals)))
 
 1172         indices.sort(key=binNumVals.__getitem__)
 
 1173         binNumVals = list(map(binNumVals.__getitem__, indices))
 
 1174         binVals = list(map(binVals.__getitem__, indices))
 
 1178             'values': binNumVals,
 
 1179             'indepLabel': indepLabel,
 
 1180             'invert_ind_axis': invert_ind_axis,
 
 1182         if len(binVals) < 2: 
return 
 1187         for (varName, varLabel) 
in self.
varMapvarMap:
 
 1188           countDF = mydfwDict[
'dfw'].loc({
'varName': varName}, 
'Count')
 
 1189           if countDF.shape[0] > 0:
 
 1190             counts = countDF.to_numpy()
 
 1191             if np.nansum(counts) > 0:
 
 1193               varMapLoc.append((varName, varLabel))
 
 1195         for statName 
in analysisStatistics:
 
 1196             if statName 
not in options.get(
'onlyStatNames', analysisStatistics): 
continue 
 1199                 mydfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options)
 
 1202         dfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options):
 
 1206         raise NotImplementedError()
 
 1211     Creates raster maps with binVar binVals on y-axis 
 1212       - only applicable to binned diagnostics (e.g., vertical dimension, latitude, zenith angle) 
 1213       - subplot: column by experiment, row by DiagSpace variable 
 1214       -    file: combination of binVar, binMethod, statistic, and FC lead time 
 1216     def __init__(self, db, analysisType, diagnosticGroupings):
 
 1217         super().
__init__(db, analysisType, diagnosticGroupings)
 
 1225         dfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options):
 
 1227         if self.
nCYnCY < 2: 
return 
 1229         bgstatDiagLabel, fcstatDiagLabel, fcstatDiagDiffLabel, scilogScale, signDefinite = \
 
 1232         myPath = self.
myFigPathmyFigPath/diagnosticGroup
 
 1233         myPath.mkdir(parents=
True, exist_ok=
True)
 
 1235         nxplots = self.
nExpnExp
 
 1237         nsubplots = nxplots * nyplots
 
 1243         for (fcTDelta, fcTDelta_totmin) 
in self.
fcMapfcMap:
 
 1244             planeLoc[
'fcTDelta'] = fcTDelta
 
 1252             for (varName, varLabel) 
in varMapLoc:
 
 1253                 planeLoc[
'varName'] = varName
 
 1254                 axisLimitsLoc[
'varName'] = varName
 
 1257                 if statName == 
'Count':
 
 1260                     dmin = dfwDict[
'dfw'].min(axisLimitsLoc, statName)
 
 1261                 dmax = dfwDict[
'dfw'].max(axisLimitsLoc, statName)
 
 1265                 for expName 
in self.
expNamesexpNames:
 
 1266                     planeLoc[
'expName'] = expName
 
 1267                     planeCYDTimes = dfwDict[
'dfw'].levels(
'cyDTime', planeLoc)
 
 1269                     planeVals = np.full((len(myBinConfigs[
'str']), self.
nCYnCY), np.NaN)
 
 1270                     binLoc = deepcopy(planeLoc)
 
 1271                     for ibin, binVal 
in enumerate(myBinConfigs[
'str']):
 
 1272                         binLoc[
'binVal'] = binVal
 
 1273                         tmp = dfwDict[
'dfw'].loc(binLoc, statName).to_numpy()
 
 1274                         for jcy, cyDTime 
in enumerate(planeCYDTimes):
 
 1275                             if jcy > len(tmp)-1: 
continue 
 1276                             icy = self.
cyDTimescyDTimes.index(cyDTime)
 
 1277                             planeVals[ibin, icy] = tmp[jcy]
 
 1280                     title = expName+
'\n'+varLabel
 
 1283                     bpf.plotTimeSeries2D(
 
 1285                         self.
cyDTimescyDTimes, myBinConfigs[
'values'], planeVals,
 
 1286                         title, bgstatDiagLabel,
 
 1287                         scilogScale, scilogScale, signDefinite,
 
 1288                         myBinConfigs[
'indepLabel'], myBinConfigs[
'invert_ind_axis'],
 
 1289                         nyplots, nxplots, nsubplots, iplot,
 
 1290                         dmin = dmin, dmax = dmax,
 
 1291                         interiorLabels = interiorLabels)
 
 1295             filename = myPath/(
'%s%s_BinValAxisTSeries_%smin_%s_%s_%s'%(
 
 1298                        diagnosticGroup, statName))
 
 1300             pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels)
 
 1307     Creates raster maps with binVar binVals on y-axis 
 1308       - only applicable to binned diagnostics (e.g., vertical dimension, latitude, zenith angle) 
 1309       - subplot: column by experiment, row by DiagSpace variable 
 1310       -    file: combination of binVar, binMethod, and statistic 
 1313     def __init__(self, db, analysisType, diagnosticGroupings):
 
 1314         super().
__init__(db, analysisType, diagnosticGroupings)
 
 1324         dfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options):
 
 1326         if self.
nFCnFC < 2: 
return 
 1328         bgstatDiagLabel, fcstatDiagLabel, fcstatDiagDiffLabel, scilogScale, signDefinite = \
 
 1332         myPath = self.
myFigPathmyFigPath/fcDiagName
 
 1333         myPath.mkdir(parents=
True, exist_ok=
True)
 
 1335         nxplots = self.
nExpnExp
 
 1337         nsubplots = nxplots * nyplots
 
 1347         for (varName, varLabel) 
in varMapLoc:
 
 1348             planeLoc[
'varName'] = varName
 
 1349             axisLimitsLoc[
'varName'] = varName
 
 1352             if statName == 
'Count':
 
 1355                 dmin = dfwDict[
'agg'].min(axisLimitsLoc, statName)
 
 1356             dmax = dfwDict[
'agg'].max(axisLimitsLoc, statName)
 
 1360             for expName 
in self.
expNamesexpNames:
 
 1361                 planeLoc[
'expName'] = expName
 
 1362                 planeFCTDeltas = dfwDict[
'agg'].levels(
'fcTDelta', planeLoc)
 
 1364                 planeVals = np.full((len(myBinConfigs[
'str']), self.
nFCnFC), np.NaN)
 
 1365                 binLoc = deepcopy(planeLoc)
 
 1366                 for ibin, binVal 
in enumerate(myBinConfigs[
'str']):
 
 1367                     binLoc[
'binVal'] = binVal
 
 1368                     tmp = dfwDict[
'agg'].loc(binLoc, statName).to_numpy()
 
 1369                     for jfc, fcTDelta 
in enumerate(planeFCTDeltas):
 
 1370                         if jfc > len(tmp)-1: 
continue 
 1371                         ifc = self.
fcTDeltasfcTDeltas.index(fcTDelta)
 
 1372                         planeVals[ibin, ifc] = tmp[jfc]
 
 1375                 title = expName+
'\n'+varLabel
 
 1378                 bpf.plotTimeSeries2D(
 
 1380                     self.
fcTDeltasfcTDeltas, myBinConfigs[
'values'], planeVals,
 
 1381                     title, fcstatDiagLabel,
 
 1382                     scilogScale, scilogScale, signDefinite,
 
 1383                     myBinConfigs[
'indepLabel'], myBinConfigs[
'invert_ind_axis'],
 
 1384                     nyplots, nxplots, nsubplots, iplot,
 
 1385                     dmin = dmin, dmax = dmax,
 
 1386                     interiorLabels = interiorLabels)
 
 1391         filename = myPath/(
'%s%s_BinValAxisTSeries_%s-%smin_%s_%s_%s'%(
 
 1396         pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels)
 
 1401     Similar to FCandBinValAxes2D, except 
 1402       - each vertical column of raster points is plotted as a profile on 
 1403         a separate set of axes instead of in 2-D color 
 1404       - therefore this is a valid plot even for a single forecast length (omb) 
 1405       -    line: per experiment 
 1406       - subplot: column by lead time, row by DiagSpace variable 
 1407       -    file: combination of binVar, binMethod, and statistic 
 1408       - self.MAX_FC_SUBFIGS determines number of FC lead times to include 
 1410     def __init__(self, db, analysisType, diagnosticGroupings):
 
 1411         super().
__init__(db, analysisType, diagnosticGroupings)
 
 1419         dfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options):
 
 1421         bgstatDiagLabel, fcstatDiagLabel, fcstatDiagDiffLabel, scilogScale, signDefinite = \
 
 1425         myPath = self.
myFigPathmyFigPath/fcDiagName
 
 1426         myPath.mkdir(parents=
True, exist_ok=
True)
 
 1431             nsubplots = nxplots * nyplots
 
 1433             nsubplots = nVarsLoc
 
 1434             nxplots = np.int(np.ceil(np.sqrt(nsubplots)))
 
 1435             nyplots = np.int(np.ceil(np.true_divide(nsubplots, nxplots)))
 
 1445         for (varName, varLabel) 
in varMapLoc:
 
 1446             ptLoc[
'varName'] = varName
 
 1447             axisLimitsLoc[
'varName'] = varName
 
 1450             for fcTDelta 
in self.
fcTDeltasfcTDeltas:
 
 1451                 ptLoc[
'fcTDelta'] = fcTDelta
 
 1452                 axisLimitsLoc[
'fcTDelta'] = fcTDelta
 
 1459                 if statName == 
'Count':
 
 1462                     dmin = dfwDict[
'agg'].min(axisLimitsLoc, statName)
 
 1463                 dmax = dfwDict[
'agg'].max(axisLimitsLoc, statName)
 
 1472                 for expName 
in self.
expNamesexpNames:
 
 1473                     ptLoc[
'expName'] = expName
 
 1474                     for diagnosticName 
in myLoc[
'diagName']:
 
 1475                         linesGroup.append(expName)
 
 1477                             expName, diagnosticName, myLoc[
'diagName']))
 
 1479                         ptLoc[
'diagName'] = diagnosticName
 
 1482                         for binVal 
in myBinConfigs[
'str']:
 
 1483                             ptLoc[
'binVal'] = binVal
 
 1484                             pt = dfwDict[
'agg'].loc(ptLoc, statName).to_numpy()
 
 1486                               lineVals.append(pt[0])
 
 1488                               lineVals.append(np.NaN)
 
 1490                         linesVals.append(lineVals)
 
 1493                 title = varLabel+
' @ '+str(float(fcTDelta.total_seconds()) / 3600.0 / 24.0)+
'days' 
 1496                 options[
'profilefunc'](
 
 1498                     linesVals, myBinConfigs[
'values'],
 
 1500                     title, fcstatDiagLabel,
 
 1501                     scilogScale, scilogScale, signDefinite,
 
 1502                     myBinConfigs[
'indepLabel'], myBinConfigs[
'invert_ind_axis'],
 
 1503                     nyplots, nxplots, nsubplots, iplot,
 
 1504                     dmin = dmin, dmax = dmax,
 
 1505                     interiorLabels = interiorLabels)
 
 1511         filename = myPath/(
'%s%s_BinValAxis_%s-%smin_%s_%s_%s'%(
 
 1516         pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels, 
True)
 
 1521     Similar to BinValAxisProfile, except 
 1522       shows difference between experiment(s) and control 
 1523       - control is selected using cntrlExpIndex 
 1524       - statistics are narrowed down by bootStrapStats 
 1525       - confidence intervals (CI) are shown at each lead time and binVal 
 1526       -    line+shaded region: per experiment 
 1527       - subplot: column by lead time, row by DiagSpace variable 
 1528       -    file: combination of binVar, binMethod, and statistic 
 1529       - self.MAX_FC_SUBFIGS determines number of FC lead times to include 
 1531     def __init__(self, db, analysisType, diagnosticGroupings):
 
 1532         super().
__init__(db, analysisType, diagnosticGroupings)
 
 1538             if 'onlyStatNames' in self.
binVarDictbinVarDict[key]:
 
 1539                 self.
binVarDictbinVarDict[key][
'onlyStatNames'] += bootStrapStats
 
 1541                 self.
binVarDictbinVarDict[key][
'onlyStatNames'] = bootStrapStats
 
 1547         dfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options):
 
 1549         if self.
nExpnExp * len(myLoc[
'diagName']) < 2: 
return 
 1550         if self.
cntrlExpNamecntrlExpName 
not in dfwDict[
'dfw'].levels(
'expName'): 
return 
 1552         bgstatDiagLabel, fcstatDiagLabel, fcstatDiagDiffLabel, scilogScale, signDefinite = \
 
 1556         myPath = self.
myFigPathmyFigPath/fcDiagName
 
 1557         myPath.mkdir(parents=
True, exist_ok=
True)
 
 1562             nsubplots = nxplots * nyplots
 
 1564             nsubplots = nVarsLoc
 
 1565             nxplots = np.int(np.ceil(np.sqrt(nsubplots)))
 
 1566             nyplots = np.int(np.ceil(np.true_divide(nsubplots, nxplots)))
 
 1578         for (varName, varLabel) 
in varMapLoc:
 
 1579             fcLoc[
'varName'] = varName
 
 1582             for fcTDelta 
in self.
fcTDeltasfcTDeltas:
 
 1583                 fcLoc[
'fcTDelta'] = fcTDelta
 
 1586                 tempdfw = sdb.DFWrapper.fromLoc(dfwDict[
'dfw'], fcLoc)
 
 1588                 cntrlLoc = deepcopy(fcLoc)
 
 1594                 linesVals = defaultdict(list)
 
 1597                 cntrlLoc[
'diagName'] = myLoc[
'diagName'][0]
 
 1598                 for expName 
in self.
expNamesexpNames:
 
 1599                     for diagnosticName 
in myLoc[
'diagName']:
 
 1600                         if (expName == cntrlLoc[
'expName'] 
and 
 1601                             diagnosticName == cntrlLoc[
'diagName']): 
continue 
 1602                         cntrlLoc[
'cyDTime'] = myExpsCYDTimes[(expName, fcTDelta)]
 
 1603                         linesGroup.append(expName)
 
 1605                             expName, diagnosticName, myLoc[
'diagName']))
 
 1607                         lineVals = defaultdict(list)
 
 1609                         for binVal 
in myBinConfigs[
'str']:
 
 1610                             cntrlLoc[
'binVal'] = binVal
 
 1611                             expLoc = deepcopy(cntrlLoc)
 
 1612                             expLoc[
'diagName'] = diagnosticName
 
 1613                             expLoc[
'expName'] = expName
 
 1615                             X = tempdfw.loc(expLoc)
 
 1616                             Y = tempdfw.loc(cntrlLoc)
 
 1618                             ciVals = su.bootStrapClusterFunc(
 
 1621                                          statNames = [statName])
 
 1623                             for trait 
in su.ciTraits:
 
 1624                                 lineVals[trait] += [ciVals[statName][trait][0]]
 
 1626                         for trait 
in su.ciTraits:
 
 1627                             linesVals[trait].append(lineVals[trait])
 
 1630                 title = varLabel+
' @ '+str(float(fcTDelta.total_seconds()) / 3600.0 / 24.0)+
'days' 
 1633                 dmin = np.nanmin(linesVals[su.cimin])
 
 1634                 dmax = np.nanmax(linesVals[su.cimax])
 
 1637                 options[
'profilefunc'](
 
 1639                     linesVals[su.cimean], myBinConfigs[
'values'],
 
 1642                     fcstatDiagDiffLabel,
 
 1643                     scilogScale, scilogScale, 
False,
 
 1644                     myBinConfigs[
'indepLabel'], myBinConfigs[
'invert_ind_axis'],
 
 1645                     nyplots, nxplots, nsubplots, iplot,
 
 1646                     linesValsMinCI = linesVals[su.cimin],
 
 1647                     linesValsMaxCI = linesVals[su.cimax],
 
 1648                     dmin = dmin, dmax = dmax,
 
 1649                     lineAttribOffset = 1,
 
 1650                     interiorLabels = interiorLabels)
 
 1655         filename = myPath/(
'%s%s_BinValAxis_%s-%smin_%s_%s_%s'%(
 
 1660         pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels, 
True)
 
 1665     Similar to BinValAxisProfile, except 
 1666       uses Count statistic to analyze a PDF across binVals 
 1668       -    line: per binMethod 
 1669       - subplot: combination of FC lead time and DiagSpace variable 
 1670       -    file: per experiment (if applicable) 
 1672     def __init__(self, db, analysisType, diagnosticGroupings):
 
 1673         super().
__init__(db, analysisType, diagnosticGroupings)
 
 1678             vu.obsVarNormErr: {
'pdffunc': bpf.plotPDF},
 
 1689         for diagnosticName, diagnosticConfig 
in self.
diagnosticConfigsdiagnosticConfigs.items():
 
 1690             if diagnosticName 
not in self.
dbdb.dfw.levels(
'diagName'): 
continue 
 1691             analysisStatistics = diagnosticConfig[
'analysisStatistics']
 
 1694             diagBinVars = self.
dbdb.dfw.levels(
'binVar', {
'diagName': diagnosticName})
 
 1696             for fullBinVar, options 
in self.
binVarDictbinVarDict:
 
 1697                 binVar = vu.varDictAll[fullBinVar][1]
 
 1698                 if binVar 
not in diagBinVars: 
continue 
 1701                 myLoc[
'diagName'] = diagnosticName
 
 1702                 myLoc[
'binVar'] = binVar
 
 1706                 mydfwDict = {
'dfw': self.
dbdb.loc(myLoc)}
 
 1710                     mydfwDict[
'agg'] = sdb.DFWrapper.fromAggStats(mydfwDict[
'dfw'], [
'cyDTime'])
 
 1713                 binMethods = mydfwDict[
'dfw'].levels(
'binMethod')
 
 1714                 binVals = mydfwDict[
'dfw'].levels(
'binVal')
 
 1715                 binUnits = mydfwDict[
'dfw'].uniquevals(
'binUnits')[0]
 
 1719                 if binUnits != vu.miss_s:
 
 1720                     indepLabel = indepLabel+
' ('+binUnits+
')' 
 1724                 for binVal 
in binVals:
 
 1725                     ibin = self.
allBinValsallBinVals.index(binVal)
 
 1726                     binNumVals.append(self.
binNumValsbinNumVals[ibin])
 
 1729                 indices = list(range(len(binNumVals)))
 
 1730                 indices.sort(key=binNumVals.__getitem__)
 
 1731                 binNumVals = list(map(binNumVals.__getitem__, indices))
 
 1732                 binVals = list(map(binVals.__getitem__, indices))
 
 1734                 if len(binVals) < 2: 
continue 
 1736                 self.
loggerlogger.info(
'binVar=>'+binVar)
 
 1739                 myPath = self.
myFigPathmyFigPath/fcDiagName
 
 1740                 myPath.mkdir(parents=
True, exist_ok=
True)
 
 1744                     nyplots = self.
nVarsnVars
 
 1745                     nsubplots = nxplots * nyplots
 
 1747                     nsubplots = self.
nVarsnVars
 
 1748                     nxplots = np.int(np.ceil(np.sqrt(nsubplots)))
 
 1749                     nyplots = np.int(np.ceil(np.true_divide(nsubplots, nxplots)))
 
 1751                 ptLoc = deepcopy(myLoc)
 
 1754                 for expName 
in self.
expNamesexpNames:
 
 1755                     ptLoc[
'expName'] = expName
 
 1763                     for (varName, varLabel) 
in self.
varMapvarMap:
 
 1764                         ptLoc[
'varName'] = varName
 
 1767                         for fcTDelta 
in self.
fcTDeltasfcTDeltas:
 
 1768                             ptLoc[
'fcTDelta'] = fcTDelta
 
 1775                             binMethodLabels = []
 
 1776                             for binMethod 
in binMethods:
 
 1777                                 ptLoc[
'binMethod'] = binMethod
 
 1780                                 if binMethod == bu.identityBinMethod:
 
 1781                                     binMethodLabels.append(
'ObsSpace')
 
 1783                                     binMethodLabels.append(binMethod)
 
 1786                                 for binVal 
in binVals:
 
 1787                                     ptLoc[
'binVal'] = binVal
 
 1788                                     lineVals.append(dfwDict[
'agg'].loc(ptLoc,
'Count'))
 
 1790                                 linesVals.append(lineVals)
 
 1793                             title = varLabel+
' @ '+str(float(fcTDelta.total_seconds()) / 3600.0 / 24.0)+
'days' 
 1798                                 linesVals, binNumVals,
 
 1802                                 nyplots, nxplots, nsubplots, iplot,
 
 1803                                 interiorLabels = interiorLabels)
 
 1812                     filename = myPath/(
'%s_BinValAxis_%s-%smin_%s_%s_%s'%(
 
 1816                     pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels, 
True)
 
 1824     Similar to BinValAxisProfile, except 
 1825       all statistics (Count, Mean, RMS, STD) are placed on the same axis 
 1827       -    line: per statistic 
 1828       - subplot: per DiagSpace variable 
 1829       -    file: combination of FC lead time, experiment, and binMethod (if applicable) 
 1831     def __init__(self, db, analysisType, diagnosticGroupings):
 
 1832         super().
__init__(db, analysisType, diagnosticGroupings)
 
 1837             vu.obsVarSCI: {
'statsfunc': bpf.plotfitRampComposite},
 
 1852         for diagnosticName, diagnosticConfig 
in self.
diagnosticConfigsdiagnosticConfigs.items():
 
 1853             if diagnosticName 
not in self.
dbdb.dfw.levels(
'diagName'): 
continue 
 1854             analysisStatistics = diagnosticConfig[
'analysisStatistics']
 
 1857             diagBinVars = self.
dbdb.dfw.levels(
'binVar', {
'diagName': diagnosticName})
 
 1859             for fullBinVar, options 
in self.
binVarDictbinVarDict.items():
 
 1860                 binVar = vu.varDictAll[fullBinVar][1]
 
 1861                 if (binVar 
not in diagBinVars): 
continue 
 1864                 myLoc[
'diagName'] = diagnosticName
 
 1865                 myLoc[
'binVar'] = binVar
 
 1869                 mydfwDict = {
'dfw': self.
dbdb.loc(myLoc)}
 
 1873                     mydfwDict[
'agg'] = sdb.DFWrapper.fromAggStats(mydfwDict[
'dfw'], [
'cyDTime'])
 
 1876                 binMethods = mydfwDict[
'dfw'].levels(
'binMethod')
 
 1877                 binVals = mydfwDict[
'dfw'].levels(
'binVal')
 
 1878                 binUnits = mydfwDict[
'dfw'].uniquevals(
'binUnits')[0]
 
 1882                 if binUnits != vu.miss_s:
 
 1883                     indepLabel = indepLabel+
' ('+binUnits+
')' 
 1887                 for binVal 
in binVals:
 
 1888                     ibin = self.
allBinValsallBinVals.index(binVal)
 
 1889                     binNumVals.append(self.
binNumValsbinNumVals[ibin])
 
 1892                 indices = list(range(len(binNumVals)))
 
 1893                 indices.sort(key=binNumVals.__getitem__)
 
 1894                 binNumVals = list(map(binNumVals.__getitem__, indices))
 
 1895                 binVals = list(map(binVals.__getitem__, indices))
 
 1897                 nBins = len(binVals)
 
 1898                 if nBins < 2: 
continue 
 1901                 myPath = self.
myFigPathmyFigPath/fcDiagName
 
 1902                 myPath.mkdir(parents=
True, exist_ok=
True)
 
 1904                 nsubplots = self.
nVarsnVars
 
 1905                 nxplots = np.int(np.ceil(np.sqrt(nsubplots)))
 
 1906                 nyplots = np.int(np.ceil(np.true_divide(nsubplots, nxplots)))
 
 1911                 for binMethod 
in binMethods:
 
 1912                     ptLoc[
'binMethod'] = binMethod
 
 1914                     self.
loggerlogger.info(
'binVar=>'+binVar+
', binMethod=>'+binMethod)
 
 1917                     for expName 
in self.
expNamesexpNames:
 
 1918                         ptLoc[
'expName'] = expName
 
 1921                         for (fcTDelta, fcTDelta_totmin) 
in self.
fcMapfcMap:
 
 1922                             ptLoc[
'fcTDelta'] = fcTDelta
 
 1932                             for (varName, varLabel) 
in self.
varMapvarMap:
 
 1933                                 ptLoc[
'varName'] = varName
 
 1936                                 countsVals = np.full(nBins,0)
 
 1937                                 meansVals  = np.full(nBins, np.NaN)
 
 1938                                 rmssVals   = np.full(nBins, np.NaN)
 
 1939                                 stdsVals   = np.full(nBins, np.NaN)
 
 1941                                 for ibin, binVal 
in enumerate(binVals):
 
 1942                                     ptLoc[
'binVal'] = binVal
 
 1943                                     countsVals[ibin] = mydfwDict[
'agg'].loc(ptLoc,
'Count').to_numpy()
 
 1944                                     meansVals[ibin] = mydfwDict[
'agg'].loc(ptLoc,
'Mean').to_numpy()
 
 1945                                     rmssVals[ibin] = mydfwDict[
'agg'].loc(ptLoc,
'RMS').to_numpy()
 
 1946                                     stdsVals[ibin] = mydfwDict[
'agg'].loc(ptLoc,
'STD').to_numpy()
 
 1952                                 FitParams = options[
'statsfunc'](
 
 1960                                     'STATS('+fcDiagName+
')',
 
 1962                                     nyplots, nxplots, nsubplots, iplot,
 
 1963                                     interiorLabels = interiorLabels)
 
 1965                                 paramKey = self.
chlistchlist[iplot]
 
 1966                                 if paramKey == 
'': paramKey = varName
 
 1967                                 ERRParams[self.
DiagSpaceNameDiagSpaceName][(paramKey, binMethod)] = FitParams
 
 1972                             print(
'\n#For binning_params:')
 
 1973                             for key 
in sorted(ERRParams[self.
DiagSpaceNameDiagSpaceName]):
 
 1974                                 print(binVar+
"ErrParams['"+self.
DiagSpaceNameDiagSpaceName+
"'][", key, 
"]   = ",
 
 1976                                 for param, val 
in ERRParams[self.
DiagSpaceNameDiagSpaceName][key][
'YAML'].items():
 
 1977                                     if param 
not in YAMLParams: YAMLParams[param] = []
 
 1978                                     YAMLParams[param] += val
 
 1979                             print(
'\n#For UFO YAML config:')
 
 1980                             for param, val 
in YAMLParams.items():
 
 1981                                 print(
'#  '+param+
':', val)
 
 1984                             filename = myPath/(
'%s%s_BinValAxis_%smin_%s_%s_%s'%(
 
 1988                             pu.finalize_fig(fig, str(filename), figureFileType, interiorLabels, 
True)
 
 2002     Calculate gross statistics for specified category binMethods at first forecast length 
 2003       NOTE: currently only calculates statistics at self.fcTDeltas[0] 
 2004             adjust minimum forecast length in order to calculate 
 2005             for non-zero forecast lengths, assuming those lengths 
 2008     def __init__(self, db, analysisType, diagnosticGroupings):
 
 2009         super().
__init__(db, analysisType, diagnosticGroupings)
 
 2018             (vu.obsVarQC, bu.goodQCMethod): {},
 
 2019             (vu.obsVarCldFrac, bu.cloudbandsMethod): {},
 
 2023         for diagnosticName, diagnosticConfig 
in self.
diagnosticConfigsdiagnosticConfigs.items():
 
 2024             if diagnosticName 
not in self.
dbdb.dfw.levels(
'diagName'): 
continue 
 2025             analysisStatistics = diagnosticConfig[
'analysisStatistics']
 
 2026             if not set(self.
requiredStatisticsrequiredStatistics).issubset(set(analysisStatistics)): 
continue 
 2028             diagLoc = {
'diagName': diagnosticName}
 
 2029             diagBinVars = self.
dbdb.dfw.levels(
'binVar', diagLoc)
 
 2030             diagBinMethods = self.
dbdb.dfw.levels(
'binMethod', diagLoc)
 
 2032             for (fullBinVar, binMethod), options 
in self.
binVarDictbinVarDict.items():
 
 2033                 binVar = vu.varDictAll[fullBinVar][1]
 
 2034                 if (binVar 
not in diagBinVars 
or 
 2035                     binMethod 
not in diagBinMethods): 
continue 
 2039                 myLoc[
'binVar'] = binVar
 
 2040                 myLoc[
'binMethod'] = binMethod
 
 2043                 mydfwDict = {
'dfw': self.
dbdb.loc(myLoc)}
 
 2046                     mydfwDict[
'agg'] = sdb.DFWrapper.fromAggStats(mydfwDict[
'dfw'], [
'cyDTime'])
 
 2047                     sdb.createORreplaceDerivedDiagnostics(mydfwDict[
'agg'], {diagnosticName: diagnosticConfig})
 
 2052                 myLoc[
'diagName'] = diagnosticName
 
 2053                 for key 
in mydfwDict.keys():
 
 2054                     mydfwDict[key] = sdb.DFWrapper.fromLoc(mydfwDict[key], myLoc)
 
 2056                 print(
' Calculate gross statistics: binVar=>'+binVar+
', binMethod=>'+binMethod)
 
 2059                     mydfwDict[
'dfw'], fullBinVar, binMethod, options)
 
 2061                 print(
' at FC length ', self.
fcTDeltasfcTDeltas[0])
 
 2064                 statsLoc[
'fcTDelta'] = self.
fcTDeltasfcTDeltas[0]
 
 2065                 for binVal, binTitle 
in binValsMap:
 
 2066                     statsLoc[
'binVal'] = binVal
 
 2068                     for varName 
in self.
varNamesvarNames:
 
 2069                         statsLoc[
'varName'] = varName
 
 2070                         for expName 
in self.
expNamesexpNames:
 
 2071                             statsLoc[
'expName'] = expName
 
 2072                             statsDFW = sdb.DFWrapper.fromLoc(mydfwDict[
'agg'], statsLoc)
 
 2073                             for statName 
in analysisStatistics:
 
 2074                                 GrossValues[(statName, expName, varName)] = statsDFW.var(statName).to_numpy()
 
 2075                     for expName 
in self.
expNamesexpNames:
 
 2076                         print(
'Gross statistics for')
 
 2077                         print(
'experiment=>'+expName)
 
 2078                         if len(binValsMap) > 1:
 
 2079                             print(
'binVal=>'+binVal)
 
 2080                         print(
' variables: ', self.
varNamesvarNames)
 
 2082                         for statName 
in analysisStatistics:
 
 2084                             tmp = np.asarray([])
 
 2085                             for varName 
in self.
varNamesvarNames:
 
 2086                                 tmp = np.append(tmp, GrossValues[(statName, expName, varName)])
 
 2089 AnalysisTypeDict = {
 
 2091     'CYAxisExpLines': CYAxisExpLines,
 
 2092     'FCAxisExpLines': FCAxisExpLines,
 
 2093     'FCAxisExpLinesDiffCI': FCAxisExpLinesDiffCI,
 
 2094     'CYAxisFCLines': CYAxisFCLines,
 
 2095     'CYAxisBinValLines': CYAxisBinValLines,
 
 2097     'CYandBinValAxes2D': CYandBinValAxes2D,
 
 2098     'FCandBinValAxes2D': FCandBinValAxes2D,
 
 2099     'BinValAxisProfile': BinValAxisProfile,
 
 2100     'BinValAxisProfileDiffCI': BinValAxisProfileDiffCI,
 
 2104     'BinValAxisPDF': BinValAxisPDF,
 
 2105     'BinValAxisStatsComposite': BinValAxisStatsComposite,
 
 2106     'GrossValues': GrossValues,
 
 2116     myClass = AnalysisTypeDict.get(analysisType, 
None)
 
 2117     assert (myClass 
is not None and inspect.isclass(myClass)), \
 
 2118         (
'\n\nERROR: AnalysisFactory cannot construct ', analysisType, 
' without instructions in AnalysisTypeDict')
 
 2119     return myClass(db, analysisType, diagnosticGroupings)
 
 2123     def __init__(self, db, analysisTypes, diagnosticGroupings = {}, nproc = 1):
 
 2124         self.
nprocnproc = nproc
 
 2126         for anType 
in analysisTypes:
 
 2128         self.
loggerlogger = logging.getLogger(__name__+
'.'+db.DiagSpaceName)
 
 2129         self.
loggerlogger.info(
'Analyses Constructed')
 
 2132         self.
loggerlogger.info(
"Entering Analyses.analyze()")
 
 2134         if self.
nprocnproc > 1:
 
 2135             workers = mp.Pool(self.
nprocnproc)
 
 2142         if workers 
is not None:
 
 2146         self.
loggerlogger.info(
"Exiting Analyses.analyze()")
 
def __init__(self, db, analysisTypes, diagnosticGroupings={}, nproc=1)
 
Base class for all analysisTypes.
 
blocking
Establish default configuration.
 
DiagSpacePath
Setup paths.
 
def statPlotAttributes(self, diagnosticGroup, statName, allDiagnosticNames=None)
 
def __init__(self, db, analysisType, diagnosticGroupings={})
 
def binMethodFile(self, binMethod, before=True)
 
def fcName(self, diagnosticGroup)
 
def analyze_(self, workers=None)
 
def UNIONcntrlANDexpCYDTimes(self, dfw, myLoc={})
 
def analyze(self, workers=None)
 
db
Extract useful variables from the database.
 
def analyze_(self, workers=None)
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options)
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options)
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
def analyze_(self, workers=None)
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
Figures with individual lines per binVal.
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
def subplotArrangement(self, dummy)
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options, nsubplots, nxplots, nyplots)
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
maxDiagnosticsPerAnalysis
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options, nsubplots, nxplots, nyplots)
 
maxDiagnosticsPerAnalysis
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options, nsubplots, nxplots, nyplots)
 
maxDiagnosticsPerAnalysis
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options)
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options, nsubplots, nxplots, nyplots)
 
maxDiagnosticsPerAnalysis
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
def analyze_(self, workers=None)
 
def subplotArrangement(self, binValsMap)
 
def innerloopsWrapper(self, diagnosticGroup, diagnosticConfigs, fullBinVar, binMethod, analysisStatistics, options)
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options, nsubplots, nxplots, nyplots)
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, binValsMap, options, nsubplots, nxplots, nyplots)
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
maxDiagnosticsPerAnalysis
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options)
 
def analyze_(self, workers=None)
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
Figures with binVal on one axis, i.e., 2D and profiles.
 
def analyze_(self, workers=None)
 
def __init__(self, db, analysisType, diagnosticGroupings)
 
maxDiagnosticsPerAnalysis
 
def innerloops(self, dfwDict, diagnosticGroup, myLoc, statName, nVarsLoc, varMapLoc, myBinConfigs, options)
 
def innerloopsWrapper(self, diagnosticGroup, diagnosticConfigs, binVar, binMethod, analysisStatistics, options)
 
def AnalysisFactory(db, analysisType, diagnosticGroupings)
 
def anWorkingDir(DiagSpace)
 
def categoryBinValsAttributes(dfw, fullBinVar, binMethod, options)
 
def expDiagnosticLabel(expName, diagnosticName, allDiagnosticNames)