def setVariableOrFloats(self, value): """ Set variable @ In, value, str or float or list, the value of given variable @ Out, ret, str or float or numpy.array, the recasted value """ ret = None # multi-entry or single-entry? if len(value) == 1: # single entry should be either a float (price) or string (raven variable) value = value[0] if utils.isAString(value) or utils.isAFloatOrInt(value): ret = value else: raise IOError( 'Unrecognized alpha/driver type: "{}" with type "{}"'. format(value, type(value))) else: # should be floats; InputData assures the entries are the same type already if not utils.isAFloatOrInt(value[0]): raise IOError( 'Multiple non-number entries for alpha/driver found, but require either a single variable name or multiple float entries: {}' .format(value)) ret = np.asarray(value) return ret
def loadFromVariables(self, need, variables, cashflows, lifetime): """ Load the values of parameters from variables @ In, need, dict, the dict of parameters @ In, variables, dict, the dict of parameters that is provided from other sources @ In, cashflows, dict, dict of cashflows @ In, lifetime, int, the given life time @ Out, need, dict, the dict of parameters updated with variables """ # load variable values from variables or other cash flows, as needed (ha!) for name, source in need.items(): if utils.isAString(source): # as a string, this is either from the variables or other cashflows # look in variables first value = variables.get(source, None) if value is None: # since not found in variables, try among cashflows if '|' not in source: raise KeyError( 'Looking for variable "{}" to fill "{}" but not found among variables or other cashflows!' .format(source, name)) comp, cf = source.split('|') value = cashflows[comp][cf][:] need[name] = np.atleast_1d(value) # now, each is already a float or an array, so in case they're a float expand them ## NOTE this expects the correct keys (namely alpha, driver) to expand, right? need = self.extendParameters(need, lifetime) return need
def convert(cls, value): """ Converts value from string to an integer. @ In, value, string, the value to convert @ Out, convert, int, the converted value """ if mathUtils.isAString(value): value = float(value) #XXX Is this a bug? #(tho' this does allow converting something like "1.0" to an integer, #but that would fail the xsd check.) return int(value)
def registerIdentifier(self, name): """ Establishes an identifying attribute for a job run. Assures no conflicts with existing identifiers. @ In, name, str, identifier to register @ Out, None """ assert mathUtils.isAString(name) assert name not in self._registeredIdentifiers # don't allow adding identifiers if existing jobs are already running, I think? assert not self._prefixToIdentifiers self._registeredIdentifiers.add(name)
def addMetaKeys(self, args, params={}): """ Adds keywords to a list of expected metadata keys. @ In, args, list(str), keywords to register @ In, params, dict, optional, {key:[indexes]}, keys of the dictionary are the variable names, values of the dictionary are lists of the corresponding indexes/coordinates of given variable @ Out, None """ if any(not mathUtils.isAString(a) for a in args): self.raiseAnError('Arguments to addMetaKeys were not all strings:', args) self.metadataKeys = self.metadataKeys.union(set(args)) self.metadataParams.update(params)
def _initializeLSpp(self, runInfo, inputs, initDict): """ Method to initialize the LS post processor (create grid, etc.) @ In, runInfo, dict, dictionary of run info (e.g. working dir, etc) @ In, inputs, list, list of inputs @ In, initDict, dict, dictionary with initialization options @ Out, None """ PostProcessor.initialize(self, runInfo, inputs, initDict) self.gridEntity = GridEntities.returnInstance("MultiGridEntity",self,self.messageHandler) self.externalFunction = self.assemblerDict['Function'][0][3] if 'ROM' not in self.assemblerDict.keys(): self.ROM = LearningGate.returnInstance('SupervisedGate','SciKitLearn', self, **{'SKLtype':'neighbors|KNeighborsClassifier',"n_neighbors":1, 'Features':','.join(list(self.parameters['targets'])), 'Target':[self.externalFunction.name]}) else: self.ROM = self.assemblerDict['ROM'][0][3] self.ROM.reset() self.indexes = -1 for index, inp in enumerate(self.inputs): if mathUtils.isAString(inp) or isinstance(inp, bytes): self.raiseAnError(IOError, 'LimitSurface PostProcessor only accepts Data(s) as inputs. Got string type!') if inp.type == 'PointSet': self.indexes = index if self.indexes == -1: self.raiseAnError(IOError, 'LimitSurface PostProcessor needs a PointSet as INPUT!!!!!!') #else: # # check if parameters are contained in the data # inpKeys = self.inputs[self.indexes].getParaKeys("inputs") # outKeys = self.inputs[self.indexes].getParaKeys("outputs") # self.paramType = {} # for param in self.parameters['targets']: # if param not in inpKeys + outKeys: # self.raiseAnError(IOError, 'LimitSurface PostProcessor: The param ' + param + ' not contained in Data ' + self.inputs[self.indexes].name + ' !') # if param in inpKeys: # self.paramType[param] = 'inputs' # else: # self.paramType[param] = 'outputs' if self.bounds == None: dataSet = self.inputs[self.indexes].asDataset() self.bounds = {"lowerBounds":{},"upperBounds":{}} for key in self.parameters['targets']: self.bounds["lowerBounds"][key], self.bounds["upperBounds"][key] = min(dataSet[key].values), max(dataSet[key].values) #self.bounds["lowerBounds"][key], self.bounds["upperBounds"][key] = min(self.inputs[self.indexes].getParam(self.paramType[key],key,nodeId = 'RecontructEnding')), max(self.inputs[self.indexes].getParam(self.paramType[key],key,nodeId = 'RecontructEnding')) if utils.compare(round(self.bounds["lowerBounds"][key],14),round(self.bounds["upperBounds"][key],14)): self.bounds["upperBounds"][key]+= abs(self.bounds["upperBounds"][key]/1.e7) self.gridEntity.initialize(initDictionary={"rootName":self.name,'constructTensor':True, "computeCells":initDict['computeCells'] if 'computeCells' in initDict.keys() else False, "dimensionNames":self.parameters['targets'], "lowerBounds":self.bounds["lowerBounds"],"upperBounds":self.bounds["upperBounds"], "volumetricRatio":self.tolerance ,"transformationMethods":self.transfMethods}) self.nVar = len(self.parameters['targets']) # Total number of variables self.axisName = self.gridEntity.returnParameter("dimensionNames",self.name) # this list is the implicit mapping of the name of the variable with the grid axis ordering self.axisName[i] = name i-th coordinate self.testMatrix[self.name] = np.zeros(self.gridEntity.returnParameter("gridShape",self.name)) # grid where the values of the goalfunction are stored
def loadVariables(self, need, inputDict): """ Load the values of variables that is generated by RAVEN @ In, need, dict, the dict of parameters @ In, inputDict, dict, the dict of parameters that is provided from other sources @ Out, need, dict, the dict of parameters updated with variables """ # load variable values from variables as needed for key, val in need.items(): if utils.isAString(val): value = inputDict.get(val, None) if value is None: raise KeyError('Looking for variable "{}" to fill "{}" but not found among variables!'.format(val, key)) need[key] = np.atleast_1d(value) return need
def convert(cls, value): """ Converts value from string to a listi with string, integer, or float type. @ In, value, string, the value to convert @ Out, convert, list, the converted value """ values = value.split(",") base = utils.partialEval(values[0].strip()) # three possibilities: string, integer, or float if mathUtils.isAString(base): conv = str elif mathUtils.isAnInteger(base): conv = int else: #float conv = float return [conv(x.strip()) for x in values]
def calculateCashflow(self, variables, lifetimeCashflows, lifetime, verbosity): """ sets up the COMPONENT LIFETIME cashflows, and calculates yearly for the comp life @ In, variables, dict, the dict of parameters that is provided from other sources @ In, lifetimeCashflows, dict, dict of cashflows @ In, lifetime, int, the given life time @ In, verbosity, int, used to control the output information @ Out, ret, dict, the dict of caculated cashflow """ ## FIXME what if I have set the values already? # get variable values, if needed need = {'alpha': self._alpha, 'driver': self._driver} # load alpha, driver from variables if need be need = self.loadFromVariables(need, variables, lifetimeCashflows, lifetime) # for Capex, use m * alpha * (D/D')^X alpha = need['alpha'] driver = need['driver'] reference = self.getParam('reference') if reference is None: reference = 1.0 scale = self.getParam('scale') if scale is None: scale = 1.0 mult = self.getMultiplier() if mult is None: mult = 1.0 elif utils.isAString(mult): mult = float(variables[mult]) result = mult * alpha * (driver / reference)**scale if verbosity > 1: ret = {'result': result} else: ret = { 'result': result, 'alpha': alpha, 'driver': driver, 'reference': reference, 'scale': scale, 'mult': mult } return ret
def computeYearlyCashflow(self, alpha, driver): """ Computes the yearly summary of recurring interactions, and sets them to self._yearlyCashflow Use this when you need to collapse one-point-per-year alpha and one-point-per-year driver into one-point-per-year summaries Note this is more for once-per-year recurring cashflows @ In, alpha, np.array, array of "prices" (one entry per YEAR) @ In, driver, np.array, array of "quantities sold" (one entry per YEAR) @ Out, None """ mult = self.getMultiplier() if mult is None: mult = 1.0 elif utils.isAString(mult): raise NotImplementedError try: self._yearlyCashflow = mult * (alpha * driver) except ValueError as e: print( 'Error while computing yearly cash flow! Check alpha shape ({}) and driver shape ({})' .format(alpha.shape, driver.shape)) raise e
def checkParamLengths(self, lifetime, compName=None): """ Check the length of some parameters @ In, lifetime, int, the given life time @ In, compName, str, name of component @ Out, None """ for param in ['alpha', 'driver']: val = self.getParam(param) # if a string, then it's probably a variable, so don't check it now if utils.isAString(val): continue # if it's valued, then it better be the same length as the lifetime (which is comp lifetime + 1) elif len(val) != lifetime: preMsg = 'Component "{comp}" '.format( compName) if compName is not None else '' raise IOError((preMsg + 'cashflow "{cf}" node <{param}> should have {correct} '+\ 'entries (1 + lifetime), but only found {found}!') .format(cf=self.name, correct=lifetime, param=param, found=len(val)))
def saveDataToFile(self, source): """ Saves the given data as database to file. @ In, source, DataObjects.DataObject, object to write to file @ Out, None """ ds, meta = source.getData() # we actually just tell the DataSet to write out as netCDF path = self.get_fullpath() # TODO set up to use dask for on-disk operations # convert metadata into writeable for key, xml in meta.items(): ds.attrs[key] = xmlUtils.prettify(xml.getRoot()) # get rid of "object" types for var in ds: if ds[var].dtype == np.dtype(object): # is it a string? if mathUtils.isAString(ds[var].values[0]): ds[var] = ds[var].astype(str) # is there existing data? Read it in and merge it, if so # -> we've already wiped the file in initializeDatabase if it's in write mode if os.path.isfile(path): exists = xr.load_dataset(path) if 'RAVEN_sample_ID' in exists: floor = int(exists['RAVEN_sample_ID'].values[-1]) + 1 new = ds['RAVEN_sample_ID'].values + floor ds = ds.assign_coords(RAVEN_sample_ID=new) # NOTE order matters! This preserves the sampling order in which data was inserted # into this database ds = xr.concat((exists, ds), 'RAVEN_sample_ID') # if this is open somewhere else, we can't write to it # TODO is there a way to check if it's writable? I can't find one ... try: ds.to_netcdf(path, engine=self._format) except PermissionError: self.raiseAnError( PermissionError, f'NetCDF file "{path}" denied RAVEN permission to write! Is it open in another program?' )
def extendParameters(self, toExtend, t): """ Extend values of parameters to the length of lifetime t @ In, toExtend, dict, the dict of parameters that need to extend @ In, t, int, the given life time @ Out, None """ # unlike normal capex, for amortization we expand the driver to all nonzero entries and keep alpha as is # TODO forced driver values for now driver = toExtend['driver'] # how we treat the driver depends on if this is the amortizer or the depreciator if self.name.split('_')[-2] == 'amortize': if not utils.isAString(driver): toExtend['driver'] = np.ones(t) * driver[0] * -1.0 toExtend['driver'][0] = 0.0 for name, value in toExtend.items(): if name.lower() in ['driver']: if utils.isAFloatOrInt(value) or ( len(value) == 1 and utils.isAFloatOrInt(value[0])): new = np.zeros(t) new[1:] = float(value) toExtend[name] = new return toExtend
def computeIntrayearCashflow(self, year, alpha, driver): """ Computes the yearly summary of recurring interactions, and sets them to self._yearlyCashflow Use this when you need to collapse a year's worth of activity to a single year point Note this is more for intrayear (e.g. hourly) cash flows @ In, year, int, the index of the project year for this summary @ In, alpha, np.array, array of "prices" (all entries WITHIN one year [e.g. hourly]) @ In, driver, np.array, array of "quantities sold" (all entries WITHIN one year [e.g. hourly]) @ Out, None """ mult = self.getMultiplier() if mult is None: mult = 1.0 elif utils.isAString(mult): raise NotImplementedError try: self._yearlyCashflow[year] = mult * ( alpha * driver).sum() # +1 is for initial construct year except ValueError as e: print( 'Error while computing yearly cash flow! Check alpha shape ({}) and driver shape ({})' .format(alpha.shape, driver.shape)) raise e
mathUtils.isSingleValued(np.nan, nanOk=False), False) checkAnswer('isSingleValued inf ok', mathUtils.isSingleValued(np.inf, nanOk=True), True) checkAnswer('isSingleValued nan ok', mathUtils.isSingleValued(np.nan, nanOk=True), True) checkAnswer('isSingleValued array', mathUtils.isSingleValued([1]), False) checkAnswer('isSingleValued set', mathUtils.isSingleValued((1, )), False) checkAnswer('isSingleValued nparray', mathUtils.isSingleValued(np.array([1])), False) checkAnswer('isSingleValued dict', mathUtils.isSingleValued({1: 2}), False) # isAString # TODO how to get a string (not unicode) after import unicode literals? #checkAnswer('isAString string',mathUtils.isAString(bytes_to_native_str(b'alpha')),True) checkAnswer('isAString strish', mathUtils.isAString('alpha'), True) checkAnswer('isAString unicode', mathUtils.isAString(u'beta'), True) checkAnswer('isAString float', mathUtils.isAString(1.0), False) checkAnswer('isAString int', mathUtils.isAString(1), False) checkAnswer('isAString bool', mathUtils.isAString(True), False) # isAFloatOrInt checkAnswer('isAFloatOrInt 0', mathUtils.isAFloatOrInt(0), True) checkAnswer('isAFloatOrInt 1', mathUtils.isAFloatOrInt(1), True) checkAnswer('isAFloatOrInt 3.14', mathUtils.isAFloatOrInt(3.14), True) checkAnswer('isAFloatOrInt str', mathUtils.isAFloatOrInt('gamma'), False) checkAnswer('isAFloatOrInt bool', mathUtils.isAFloatOrInt(True), False) checkAnswer('isAFloatOrInt nan ok', mathUtils.isAFloatOrInt(np.nan), True) checkAnswer('isAFloatOrInt inf ok', mathUtils.isAFloatOrInt(np.inf), True) checkAnswer('isAFloatOrInt nan not ok',