def project_nmx(kt, ax, bx, ageCutoff, kt_resid=None, bx_resid=None, numAgeWidths=LCFIT_DEFAULT_NO_AGEWIDTHS): """ Convert 2-d array of kt forward innovations into 3-d array of nmxs To get a particular age profile after running the function, need to pick a run and a timestep, eg self.nmx_projected[10, 12, :] gives 10th run, t=12, all the age spec rates. 'Kx' and 'Bx' are for coherent. """ # Make sure kt_resid and bx_resid are either both None or are the # right dimensions for the residual (Coherent) process if kt_resid is None and bx_resid is None: # Normal case without coherent isCoherent = False kt_resid = N.zeros_like(kt) bx_resid = N.zeros_like(bx) pass elif (kt_resid.shape == kt.shape) and (bx_resid.shape == bx.shape): # Coherent isCoherent = True pass else: raise "Weird mix of kt's and bx's. \n\nkt: %s. \n\nkt_resid: %s \n\nbx: %s \n\nbx_resid: %s\n" % \ (kt, kt_resid, bx, bx_resid) # Fill 3d matrix of nmx if get 2-d matrix of kt (corresponding to run by year if len(kt.shape) == 2: numRuns, stepsForward = kt.shape[0], kt.shape[1] nmx_projected = N.zeros([numRuns, stepsForward, numAgeWidths], N.float64) # 3-d matrix to fill in for runIndex in range(0,numRuns): for stepIndex in range(0,stepsForward): nmxTmp = N.zeros((1,numAgeWidths), N.float64).ravel() nmxTmp[0:len(bx)] = N.exp(kt[runIndex,stepIndex]*bx + kt_resid[runIndex,stepIndex]*bx_resid + ax) nmx_projected[runIndex, stepIndex, :] = LcExtension.extendMx(nmxTmp, ageCutoff=ageCutoff) pass pass return nmx_projected # Fill 2d matrix of nmx if have 1-d matrix of kt elif len(kt.shape) == 1: # nmx_projected=N.zeros((kt.shape[0], numAgeWidths), N.float64) for yearIndex in range(0, kt.shape[0]): nmxTmp = N.zeros((1,numAgeWidths), N.float64).ravel() nmxTmp[0:len(bx)] = N.exp(kt[yearIndex]*bx + kt_resid[yearIndex]*bx_resid + ax) nmxTmpExtended = LcExtension.extendMx(nmxTmp, ageCutoff=ageCutoff) nmx_projected[yearIndex, :] = nmxTmpExtended return nmx_projected # Fill 1d matrix of mx for single kt number elif len(kt.shape) == 0 and kt.size == 1: nmx_projected=N.zeros(numAgeWidths, N.float64) nmxTmp = N.zeros(numAgeWidths, N.float64) nmxTmp[0:len(bx)] = N.exp(kt*bx + kt_resid*bx_resid + ax) nmxTmpExtended = LcExtension.extendMx(nmxTmp, ageCutoff=ageCutoff) nmx_projected[:] = nmxTmpExtended return nmx_projected else: raise LcException, "Unexpected kt.shape: %r. kt: %r. kt.size: %r" % ([kt.shape],kt, kt.size)
def _dealWithRates(self, rates, **kwargs): """Parses the rates. Sets up datastructures for missing data.""" # Save code version info with instance. Here because I think # it is screwing up based on # some weird scoping thing in MF self.LcObjectINFO = LcObjectINFO assert type(rates) == types.StringType, \ AssertionError("Rates should be as string for input. Instead: %s." % type(rates)) # Get rates from text, extend ... self.rates_text = rates self.nmx = LcUtil.parseRates(self.rates_text) # ... handle missing data: if there are nans after parsing, # determine which years (rows) they are in ... self.nmxNans = N.isnan(self.nmx) self.goodRowsBool = (~self.nmxNans).any(axis=1) self.goodRowsNum = N.where(self.goodRowsBool)[0].tolist() # weird numpy.where() return self.yearIndices = N.arange(1, self.nmx.shape[0]+1, dtype=N.int0) # XXX 1 indexed for missing data formulas # ... extend everything ... self.nmxExtended = LcUtil.emptyLikeWithNans(self.nmx) tmp = LcExtension.extendMx(self.nmx[self.goodRowsNum,:], ageCutoff=self.ageCutoff) assert self.nmxExtended[self.goodRowsNum,:].shape == tmp.shape, \ AssertionError("orig shape: %s. extended shape: %s" \ % (tmp.shape, self.nmxExtended[self.goodRowsNum,:].shape)) self.nmxExtended[self.goodRowsNum,:] = tmp assert (self.nmxExtended[self.goodRowsNum,:] > 0.0).all() and (N.isfinite(self.nmxExtended[self.goodRowsNum,:])).all(), \ AssertionError("%s" % self.nmxExtended) # ... asserts, and hopefully fall of the end (only update object state). self.nmxInfs = N.isinf(self.nmx) assert not self.nmxInfs.any(), \ AssertionError("why are there infs in nmx???:\n %r" % N.round_(self.nmx, 2)) return None
def multiKt2e0(kt, ax, bx, lifeTableParams, numAgeWidths = LCFIT_DEFAULT_NO_AGEWIDTHS): e0s = [0] * len(kt) for i, k in enumerate(kt): nmxTmp = N.zeros((1,numAgeWidths), N.float64).ravel() nmxTmp[0:len(bx)] = N.exp(k * bx + ax) nmxTmp = LcExtension.extendMx(nmxTmp, ageCutoff=lifeTableParams['ageCutoff']) e0s[i] = lifeTable(nmxTmp, **lifeTableParams) del nmxTmp return e0s
def multiKt2e0(kt, ax, bx, lifeTableParams, numAgeWidths=LCFIT_DEFAULT_NO_AGEWIDTHS): e0s = [0] * len(kt) for i, k in enumerate(kt): nmxTmp = N.zeros((1, numAgeWidths), N.float64).ravel() nmxTmp[0:len(bx)] = N.exp(k * bx + ax) nmxTmp = LcExtension.extendMx(nmxTmp, ageCutoff=lifeTableParams['ageCutoff']) e0s[i] = lifeTable(nmxTmp, **lifeTableParams) del nmxTmp return e0s
def lifeTable(nmxp, ageCutoff=None, extensionMethod=LCFIT_DEFAULT_EXTENSION_METHOD, ltFuncType='ex', beginFuncParam=0, endFuncParam=0, numAgeWidths=LCFIT_DEFAULT_NO_AGEWIDTHS, gender='combined', ax_calc_alg='graduated', ageWidth=5, qxMax=.7, qx0_intercept=0.93, qx0_slope=1.7): ''' From a given nMx schedule, calc and return a functional or the full LT. The columns for a full LT are nmx, nqx, lx, nLx, Ex. extensionMethod=[LCFIT_DEFAULT_EXTENSION_METHOD] ltFuncType=["ex", "lx", "lxPercent", "depRatio", "full"] closeRate must be an age with "ex" and "lx"; a percentile with "lxPercent", a pair of ages (young and old) with "depRatio". XXX Full of magic numbers! ''' #lcfitlogger.debug( 'gender: %s' % gender) assert N.isfinite(nmxp).all(), AssertionError("%s" % pprint.pformat(locals())) assert len(nmxp.shape) == 1, AssertionError( "Bad shape for nmxp: %s. Should be %s" % (str(nmxp.shape), '(x,)')) if gender not in ('combined', 'male', 'female'): raise LcException("Bad value for gender in lifeTable(): %s" % gender) if N.isnan(nmxp).any() or N.isinf(nmxp).any(): raise "Bad mx: %s" % nmxp # Copy nmx to avoid modifying a reference nmx = nmxp.copy() # set nmx's that creep in as inf to something big nmx[N.isinf(nmx)] = LCFIT_INF_NMX_REPLACEMENT assert N.isfinite(nmx).all(), AssertionError("%s" % pprint.pformat(locals())) # extend nmx out to appropriate age widths. Filling with stuff to # make it break if they are not replaced in the Kannisto # extension thing neededSlots = numAgeWidths - nmx.shape[0] if neededSlots > 0: nmx.resize(numAgeWidths) # Set up data structures nqx = N.array([1.0] * numAgeWidths, N.float64) lx = N.array([0.0] * numAgeWidths, N.float64) nLx = N.array([0.0] * numAgeWidths, N.float64) ndx = N.array([0.0] * numAgeWidths, N.float64) Ex = N.array([0.0] * numAgeWidths, N.float64) Tx = N.array([0.0] * numAgeWidths, N.float64) ax = N.array([0.0] * numAgeWidths, N.float64) # Extend bad data ages if ageCutoff: nmxOld = copy.copy(nmx) nmx = LcExtension.extendMx(nmx, extName=extensionMethod, ageCutoff=ageCutoff) assert N.isfinite(nmx).all() and (nmx>0).all(), \ AssertionError("%s" % pprint.pformat(locals())) # Graduate and get important stuff (ax, qx, dx, lx) = adjustAx(nmx, gender=gender) #raise pprint.pformat((ax, qx, dx, lx)) # Everything -> nLx if ax_calc_alg == 'LiNan': # Default for i in range(len(nLx) - 1): nLx[i] = (lx[i] - lx[i + 1]) / nmx[i] pass nLx[-1] = lx[-1] / nmx[-1] pass elif ax_calc_alg == 'graduated': # Not usually entered nLx[0] = lx[0] - ax[0] * ndx[0] nLx[1] = lx[1] - ax[1] * ndx[1] nLx[2:-1] = (lx[2:-1] * 5) - ( ndx[2:-1] * ax[2:-1] ) # Magic numbers 5, 2.5: age width and multiplier nLx[-1] = lx[-1] / nmx[-1] nLx[N.where(abs(lx) < .0001)] = 0.0 # coarse elif ax_calc_alg == 'empirical': pass else: raise Exception('Unknown ax_calc_alg: %s' % ax_calc_ag) # Do strange adjustment for lx where x >= 10, from lfexpt.m # Set up datastructures ... if False: c = N.zeros_like(nLx) nLLx = N.zeros_like(nLx) llx = lx.copy() qqx = N.zeros_like(nLx) # ... compute adjustment "c" for each age ... for age in range(3, len(nLLx) - 1): if nLx[age] > 0.000001: c[age] = (1/(48*nLx[age])) * \ (nLx[age-1]-nLx[age+1]) * \ (nmx[age+1] - nmx[age-1]) else: c[age] = c[age - 1] pass pass # ... recalculate lx with adj and mort rates ... for age in range(3, len(nLLx) - 1): llx[age + 1] = llx[age] * N.exp(-5 * (nmx[age] + c[age])) # ... recalculate Lx and qx ... for age in range(0, len(nLLx) - 1): nLLx[age] = (llx[age] - llx[age + 1]) / nmx[age] qqx[age] = (llx[age] - llx[age + 1]) / llx[age] qqx[-1] = 1.0 nLLx[-1] = nLLx[-2] # ... copy to lx and nLx, then Finis. lx = llx.copy() nLx = nLLx.copy() pass # nLx -> Tx Tx = N.cumsum(nLx[::-1])[::-1] # Double reverse by indexing stride # Tx + lx -> ex Ex = Tx / lx Ex[N.isnan(Ex)] = 0 Ex[-1] = 1 / nmx[-1] # Sanity if not (10 < Ex[0] < 100): raise LcException("Unreasonable LifeExp: %s. %s" % (Ex[0], pprint.pformat(locals()))) # Decide what to return. For the functionals, use the parameters # to figure out what parts of the lifetable want. if ltFuncType == 'ex': xTmp = LCFIT_AGE_INDICES[beginFuncParam] assert 0 <= xTmp <= max(LCFIT_AGES), "Bad age: %s" % beginFuncParam return (float(Ex[xTmp])) elif ltFuncType == 'lx': xTmp = LCFIT_AGE_INDICES[beginFuncParam] assert 0 <= xTmp <= max(LCFIT_AGES), "Bad age: %s" % beginFuncParam return (float(lx[xTmp])) elif ltFuncType == 'lxPercent': lxTmp = beginFuncParam / 100.0 assert 0.0 < lxTmp <= 1.0, \ AssertionError("Bad percentile: %s." % beginFuncParam) lxInterp = scipy.interpolate.interp1d( lx[::-1], LCFIT_AGES[::-1]) # both x and lx reversed return lxInterp(lxTmp).ravel()[0] elif ltFuncType == 'depRatio': xTmpYoung = LCFIT_AGE_INDICES[beginFuncParam] xTmpOld = LCFIT_AGE_INDICES[endFuncParam] assert 0 <= xTmpYoung < xTmpOld <= max(LCFIT_AGES), \ AssertionError ("Bad ages: Young: %s, Old: %s" % (beginFuncParam, endFuncParam)) ppyYoung = N.sum(nLx[0:xTmpYoung]) # Total person years ppyWorking = N.sum(nLx[xTmpYoung:xTmpOld]) ppyOld = N.sum(nLx[xTmpOld:]) return ppyWorking / (ppyYoung + ppyOld) elif ltFuncType == 'full': return (S.array(zip(nmx, nqx, lx, nLx, Ex))) else: raise Exception, "unknown ltFuncType: %s" % str(locals())
#!/usr/bin/python ''' This module provides the home for LcSinglePopObject, which takes data in the form of text, runs an Lee-Carter infeence procedure on it, does some forecasting, and makes some nice pictures. This module also contains a number of module functions to support this. ''' ## Imports ################################################ from LcConfig import * # Imports numpy and friends from LcLog import lcfitlogger from LcAnnotation import * import LcExtension LcExtension.setExtensionName(LCFIT_DEFAULT_EXTENSION_METHOD) import LcUtil from LcUtil import Diagnose as D from LcUtil import listTypes as LT sys.path.append('./TESTING') # For test data ## Module Variables ###### LcObjectINFO ='Single Population object' # Project/misc information # Image constants LC_IMAGE_NAME = 'lc-model.png' # Image with kt, ax, bx, e0u FC_IMAGE_NAME = 'lc-forecast.png' # Image with forecasted stuff LNMX_IMAGE_NAME = 'lc-lognmx.png' # Emprical log nmx at various ages MORTP_IMAGE_NAME = 'lc-mortp.png' # Mortality profiles at begin, end, end proj
def lifeTable (nmxp, ageCutoff=None, extensionMethod=LCFIT_DEFAULT_EXTENSION_METHOD, ltFuncType='ex', beginFuncParam=0, endFuncParam=0, numAgeWidths = LCFIT_DEFAULT_NO_AGEWIDTHS, gender='combined', ax_calc_alg='graduated', ageWidth=5, qxMax=.7, qx0_intercept=0.93, qx0_slope=1.7): ''' From a given nMx schedule, calc and return a functional or the full LT. The columns for a full LT are nmx, nqx, lx, nLx, Ex. extensionMethod=[LCFIT_DEFAULT_EXTENSION_METHOD] ltFuncType=["ex", "lx", "lxPercent", "depRatio", "full"] closeRate must be an age with "ex" and "lx"; a percentile with "lxPercent", a pair of ages (young and old) with "depRatio". XXX Full of magic numbers! ''' #lcfitlogger.debug( 'gender: %s' % gender) assert N.isfinite(nmxp).all(), AssertionError("%s" % pprint.pformat(locals())) assert len(nmxp.shape) == 1, AssertionError( "Bad shape for nmxp: %s. Should be %s" % (str(nmxp.shape), '(x,)')) if gender not in ('combined', 'male', 'female'): raise LcException("Bad value for gender in lifeTable(): %s" % gender) if N.isnan(nmxp).any() or N.isinf(nmxp).any(): raise "Bad mx: %s" % nmxp # Copy nmx to avoid modifying a reference nmx = nmxp.copy() # set nmx's that creep in as inf to something big nmx[N.isinf(nmx)] = LCFIT_INF_NMX_REPLACEMENT assert N.isfinite(nmx).all(), AssertionError("%s" % pprint.pformat(locals())) # extend nmx out to appropriate age widths. Filling with stuff to # make it break if they are not replaced in the Kannisto # extension thing neededSlots = numAgeWidths - nmx.shape[0] if neededSlots > 0: nmx.resize(numAgeWidths) # Set up data structures nqx = N.array([1.0] * numAgeWidths, N.float64) lx = N.array([0.0] * numAgeWidths, N.float64) nLx = N.array([0.0] * numAgeWidths, N.float64) ndx = N.array([0.0] * numAgeWidths, N.float64) Ex = N.array([0.0] * numAgeWidths, N.float64) Tx = N.array([0.0] * numAgeWidths, N.float64) ax = N.array([0.0] * numAgeWidths, N.float64) # Extend bad data ages if ageCutoff: nmxOld = copy.copy(nmx) nmx = LcExtension.extendMx(nmx, extName=extensionMethod, ageCutoff=ageCutoff) assert N.isfinite(nmx).all() and (nmx>0).all(), \ AssertionError("%s" % pprint.pformat(locals())) # Graduate and get important stuff (ax, qx, dx, lx) = adjustAx(nmx, gender=gender) #raise pprint.pformat((ax, qx, dx, lx)) # Everything -> nLx if ax_calc_alg == 'LiNan': # Default for i in range(len(nLx)-1): nLx[i] = (lx[i] - lx[i+1])/nmx[i] pass nLx[-1] = lx[-1]/nmx[-1] pass elif ax_calc_alg == 'graduated': # Not usually entered nLx[0] = lx[0] - ax[0] * ndx[0] nLx[1] = lx[1] - ax[1] * ndx[1] nLx[2:-1] = (lx[2:-1] * 5) - (ndx[2:-1] * ax[2:-1]) # Magic numbers 5, 2.5: age width and multiplier nLx[-1] = lx[-1] / nmx[-1] nLx[N.where(abs(lx)<.0001)] = 0.0 # coarse elif ax_calc_alg == 'empirical': pass else: raise Exception ('Unknown ax_calc_alg: %s' % ax_calc_ag) # Do strange adjustment for lx where x >= 10, from lfexpt.m # Set up datastructures ... if False: c = N.zeros_like(nLx) nLLx = N.zeros_like(nLx) llx = lx.copy() qqx = N.zeros_like(nLx) # ... compute adjustment "c" for each age ... for age in range(3, len(nLLx)-1): if nLx[age] > 0.000001: c[age] = (1/(48*nLx[age])) * \ (nLx[age-1]-nLx[age+1]) * \ (nmx[age+1] - nmx[age-1]) else: c[age] = c[age-1] pass pass # ... recalculate lx with adj and mort rates ... for age in range(3, len(nLLx)-1): llx[age+1] = llx[age]*N.exp(-5*(nmx[age]+c[age])) # ... recalculate Lx and qx ... for age in range(0, len(nLLx)-1): nLLx[age] = (llx[age] - llx[age+1]) / nmx[age] qqx[age] = (llx[age] - llx[age+1]) / llx[age] qqx[-1] = 1.0 nLLx[-1] = nLLx[-2] # ... copy to lx and nLx, then Finis. lx = llx.copy() nLx = nLLx.copy() pass # nLx -> Tx Tx = N.cumsum(nLx[::-1])[::-1] # Double reverse by indexing stride # Tx + lx -> ex Ex = Tx/lx Ex[N.isnan(Ex)] = 0 Ex[-1] = 1/nmx[-1] # Sanity if not (10 < Ex[0] < 100): raise LcException ("Unreasonable LifeExp: %s. %s" % (Ex[0], pprint.pformat(locals()))) # Decide what to return. For the functionals, use the parameters # to figure out what parts of the lifetable want. if ltFuncType == 'ex': xTmp = LCFIT_AGE_INDICES[beginFuncParam] assert 0 <= xTmp <= max(LCFIT_AGES), "Bad age: %s" % beginFuncParam return (float(Ex[xTmp])) elif ltFuncType == 'lx': xTmp = LCFIT_AGE_INDICES[beginFuncParam] assert 0 <= xTmp <= max(LCFIT_AGES), "Bad age: %s" % beginFuncParam return (float(lx[xTmp])) elif ltFuncType == 'lxPercent': lxTmp = beginFuncParam / 100.0 assert 0.0 < lxTmp <= 1.0, \ AssertionError("Bad percentile: %s." % beginFuncParam) lxInterp = scipy.interpolate.interp1d(lx[::-1], LCFIT_AGES[::-1]) # both x and lx reversed return lxInterp(lxTmp).ravel()[0] elif ltFuncType == 'depRatio': xTmpYoung = LCFIT_AGE_INDICES[beginFuncParam] xTmpOld = LCFIT_AGE_INDICES[endFuncParam] assert 0 <= xTmpYoung < xTmpOld <= max(LCFIT_AGES), \ AssertionError ("Bad ages: Young: %s, Old: %s" % (beginFuncParam, endFuncParam)) ppyYoung = N.sum(nLx[0:xTmpYoung]) # Total person years ppyWorking = N.sum(nLx[xTmpYoung:xTmpOld]) ppyOld = N.sum(nLx[xTmpOld:]) return ppyWorking / (ppyYoung + ppyOld) elif ltFuncType == 'full': return (S.array(zip( nmx, nqx, lx, nLx, Ex))) else: raise Exception, "unknown ltFuncType: %s" % str(locals())
def _dealWithRates(self, populations, mortRates, labels='', **kwargs): """ Store the population and rate data. Create the combined rates matrix. """ # Save code version info with instance. Here because I think # it is screwing up based on # some weird scoping thing in MF self.LcObjectINFO = LcObjectINFO # Age cutoff self.ageCutoffIndex = LCFIT_AGE_INDICES[self.ageCutoff] + 1 # Population data self.populationText = re.sub('\n', '\n', populations) self.populationText = re.sub('\r', '', self.populationText).strip() self.populationText = re.sub('\n+$', '', self.populationText) self.populationText = re.sub('^\n+', '', self.populationText) if LCFIT_EMPTY_ALL_RE.search(self.populationText): self.useWeightedMx = False self.populationTextList = [] self.populationList = [] else: self.useWeightedMx = True self.populationTextList = re.split('\n\n+', self.populationText) self.populationList = [LcUtil.parseRates(pops) for pops in self.populationTextList] # Mortality data self.mortRatesText = re.sub('\n', '\n', mortRates) self.mortRatesText = re.sub('\r', '', mortRates) self.mortRatesText = re.sub('\n+$', '', self.mortRatesText) self.mortRatesText = re.sub('^\n+', '', self.mortRatesText) if LCFIT_EMPTY_ALL_RE.search(self.mortRatesText): raise LcException("empty rates data") self.mortRatesTextList = re.split('\n\n+', self.mortRatesText) # self.mortRatesList = [LcUtil.parseRates(rates) for rates in self.mortRatesTextList] # Go over each data matrix, check input: no weird numbers, same size. shapeList = [] shapeShape = self.mortRatesList[0].shape for i, data in enumerate(self.populationList + self.mortRatesList): if data.shape != shapeShape: raise LcException("Inconsistent rate matrix shapes. First matrix shape: %r, current matrix [%r] shape: %r\nData: %r" % \ (shapeShape, i, data.shape, data[0,:].tolist())) shapeList.append(data.shape) pass if self.useWeightedMx: if len(self.populationList) != len(self.mortRatesList): raise LcException("Must have pop and mx of same length. Pop = %i, Mort = %i." % \ (len(self.populationList), len(self.mortRatesList))) # CG and takes logs of each of the rates self.mortRatesListLog = [] for i, mxMatrix in enumerate(self.mortRatesList): self.mortRatesList[i] = LcExtension.extendMx(mxData=mxMatrix, ageCutoff=LCFIT_DEFAULT_AGE_CUTOFF) self.mortRatesListLog.append(N.log(self.mortRatesList[i])) # Labels if labels == '': self.labels = map(str,range(1, len(self.mortRatesListLog)+1)) else: self.labels = re.split('\s+', labels.strip()) if len(self.labels) < len(self.mortRatesListLog): labelExtraNumbers = range(len(self.labels)+1, len(self.mortRatesListLog)+1) labelExtra = map(str, labelExtraNumbers) self.labels = self.labels + labelExtra elif len(self.labels) > len(self.mortRatesListLog): self.labels = self.labels[0:(len(self.mortRatesListLog))] # Years self.yearIndices = N.arange(1, self.mortRatesList[0].shape[0]+1, dtype=N.int0) years_end = self.start_year + self.mortRatesList[-1].shape[0] self.years = N.array(range(self.start_year, years_end)) assert len(self.years) >= 1, AssertionError("years: %s" % self.years) self.years_fcst = N.array(range(years_end-1, years_end + self.stepsForward)) # Create an average mx matrix. If populations empty, no # weights; if there is data for populations (1) check for # reasonableness in size and number and (2) use population as # weights and do the averaging. if self.useWeightedMx: self.totalWeightedMx = N.zeros_like(self.mortRatesList[0]) self.totalPop = N.zeros_like(self.populationList[0]) for (mx, pop) in zip(self.mortRatesList, self.populationList): self.totalWeightedMx = self.totalWeightedMx + (mx*pop) self.totalPop = self.totalPop + pop pass self.averagedMx = self.totalWeightedMx/self.totalPop else: temp_mx = N.zeros_like(self.mortRatesList[0]) for mx in self.mortRatesList: temp_mx += mx self.averagedMx = temp_mx / len(self.mortRatesList) self.averagedMx = LcExtension.extendMx(mxData=self.averagedMx, ageCutoff=LCFIT_DEFAULT_AGE_CUTOFF) self.averagedMxLog = N.log(self.averagedMx) # Check data for ok-ness in mortality (not population, since # that might be non-CG'ed and have nans). for i, data in enumerate(self.mortRatesList + self.mortRatesListLog + [self.averagedMxLog, self.averagedMx]): assert N.isfinite(data).all(), \ AssertionError("Bad data in mx[%r]:\n %r" % (N.round_(data, 2), i)) # Check for weird (ie > 1.0) numbers for i, data in enumerate(self.mortRatesList + [self.averagedMx]): if not (data<1.2).all(): raise LcException("Weird mx: \n%s\n%s" % (data[data<1.2], i))
kt against the combined kt. ''' ## Imports ############################################### from LcLog import lcfitlogger from LcConfig import * # This imports numpy and friends from LcAnnotation import * from LcSinglePopObject import * sys.path.append('./TESTING') # For test data import LcUtil from LcUtil import Diagnose as D import LcExtension LcExtension.setExtensionName(LCFIT_DEFAULT_EXTENSION_METHOD) ## Module Variables ###### LcObjectINFO ='LcCoherentPopObject' # Project/misc information # Image constants FC_IMAGE_NAME = 'lc-forecast.png' # Image with forecasted stuff E0S_IMAGE_NAME = 'lc-e0s.png' # Empirical e0s for each subpopulation E0S_FCST_IMAGE_NAME = 'lc-e0s-fcst.png' # Forecasted e0s for each subpop and combined LNMX_IMAGE_NAME = 'lc-lognmx.png' # Emprical log nmx at various ages LC_IMAGE_NAME = 'lc-model.png' # Image with kt, ax, bx, e0u IMGH = 150 # Height of all images IMGW = 200 # Width of all images ############################################################################################