Example #1
0
def work(modelDir, inputDict):
    """ Run the model in its directory."""
    outData = {}
    rawData = []
    actual = []

    # write input file to modelDir sans carriage returns
    with open(pJoin(modelDir, "demandTemp.csv"), "w") as demandTempFile:
        demandTempFile.write(inputDict["demandTemp"].replace("\r", ""))

    try:
        with open(pJoin(modelDir, 'hist.csv'), 'w') as f:
            f.write(inputDict['nn'].replace('\r', ''))
        df = pd.read_csv(pJoin(modelDir, 'hist.csv'))
        assert df.shape[0] >= 26280  # must be longer than 3 years
        if 'dates' not in df.columns:
            df['dates'] = df.apply(lambda x: dt(int(x['year']), int(x[
                'month']), int(x['day']), int(x['hour'])),
                                   axis=1)
    except:
        raise Exception("Neural Net CSV file is incorrect format.")

    # neural net time
    all_X = loadForecast.makeUsefulDf(df)
    all_y = df["load"]
    nn_pred, nn_accuracy = loadForecast.neural_net_predictions(all_X, all_y)
    outData["actual_nn"] = df['load'][-8760:].tolist()

    # read it in as a list of lists
    try:
        with open(pJoin(modelDir, "demandTemp.csv")) as inFile:
            df = pd.read_csv(inFile, header=None)
            df.columns = ["load", "tempc"]
            df["dates"] = pd.date_range(start=inputDict["simStartDate"],
                                        freq="H",
                                        periods=df.shape[0])
            print df.shape[0]
    except ZeroDivisionError:
        errorMessage = "CSV file is incorrect format. Please see valid format definition at <a target='_blank' href = 'https://github.com/dpinney/omf/wiki/Models-~-storagePeakShave#demand-file-csv-format'>\nOMF Wiki storagePeakShave - Demand File CSV Format</a>"
        raise Exception(errorMessage)

    rawData = df[["load", "tempc"]].fillna(0).values.tolist()
    del df
    """
	# None -> 0, float-> string
	for i in range(len(rawData)):
		rawData[i] = [a if a else 0 for a in rawData[i]]
	rawData = list(np.float_(rawData))
	"""

    # populate actual list
    for x in range(len(rawData)):
        actual.append(float(rawData[x][0]))

    (forecasted,
     MAPE) = loadForecast.rollingDylanForecast(rawData,
                                               float(inputDict["upBound"]),
                                               float(inputDict["lowBound"]))

    (exp, exp_MAPE) = loadForecast.exponentiallySmoothedForecast(
        rawData, float(inputDict["alpha"]), float(inputDict["beta"]))

    # parse json params for nextDayPeakKatrina
    try:
        params = json.loads(inputDict.get("katSpec", "{}"))
    except ValueError:
        params = {}

    pred_demand = loadForecast.nextDayPeakKatrinaForecast(
        rawData, inputDict["simStartDate"], modelDir, params)
    pred_demand = np.transpose(np.array(pred_demand)).tolist()

    # zucc it up
    prophet_partitions = int(inputDict.get("prophet", 0))
    if prophet_partitions > 1:
        prophet, prophet_low, prophet_high = loadForecast.prophetForecast(
            rawData, inputDict["simStartDate"], modelDir, inputDict["prophet"])

        # write our outData
    outData["startDate"] = inputDict["simStartDate"]
    outData["actual"] = actual
    outData["forecasted"] = forecasted
    outData["doubleExp"] = exp
    outData["neuralNet"] = nn_pred
    outData["MAPE"] = "%0.2f%%" % (MAPE * 100)
    outData["MAPE_exp"] = "%0.2f%%" % (exp_MAPE * 100)
    outData["MAPE_nn"] = "%0.2f%%" % nn_accuracy["test"]
    outData["peakDemand"] = pred_demand
    if prophet_partitions > 1:
        outData["prophet"] = prophet
        outData["prophetLow"] = prophet_low
        outData["prophetHigh"] = prophet_high
    return outData
Example #2
0
def forecastWork(modelDir, ind):
    ''' Run the model in its directory.'''

    (cellCapacity, dischargeRate, chargeRate, cellQuantity, cellCost) = \
     [float(ind[x]) for x in ('cellCapacity', 'dischargeRate', 'chargeRate', 'cellQuantity', 'cellCost')]
    demandCharge = float(ind['demandCharge'])
    retailCost = float(ind['retailCost'])

    battEff = float(ind.get("batteryEfficiency")) / 100.0
    dodFactor = float(ind.get('dodFactor')) / 100.0
    projYears = int(ind.get('projYears'))
    batteryCycleLife = int(ind.get('batteryCycleLife'))
    battCapacity = cellQuantity * float(ind['cellCapacity']) * dodFactor

    o = {}

    try:
        with open(pJoin(modelDir, 'hist.csv'), 'w') as f:
            f.write(ind['histCurve'].replace('\r', ''))
        df = pd.read_csv(pJoin(modelDir, 'hist.csv'), parse_dates=['dates'])
        df['month'] = df['dates'].dt.month
        df['dayOfYear'] = df['dates'].dt.dayofyear
        assert df.shape[0] >= 26280  # must be longer than 3 years
        assert df.shape[1] == 5
    except:
        raise Exception("CSV file is incorrect format.")

    confidence = float(ind['confidence']) / 100

    # ---------------------- MAKE PREDICTIONS ------------------------------- #
    # train model on previous data
    all_X = fc.makeUsefulDf(df)
    all_y = df['load']
    predictions = fc.neural_net_predictions(all_X, all_y)

    dailyLoadPredictions = [
        predictions[i:i + 24] for i in range(0, len(predictions), 24)
    ]
    weather = df['tempc'][-8760:]
    dailyWeatherPredictions = [
        weather[i:i + 24] for i in range(0, len(weather), 24)
    ]
    month = df['month'][-8760:]

    dispatched = [False] * 365
    # decide to implement VBAT every day for a year
    VB_power, VB_energy = [], []
    for i, (load24, temp24, m) in enumerate(
            zip(dailyLoadPredictions, dailyWeatherPredictions, month)):
        peak = max(load24)
        if fc.shouldDispatchPS(peak, m, df, confidence):
            dispatched[i] = True
            vbp, vbe = fc.pulp24hrBattery(load24, dischargeRate * cellQuantity,
                                          cellCapacity * cellQuantity, battEff)
            VB_power.extend(vbp)
            VB_energy.extend(vbe)
        else:
            VB_power.extend([0] * 24)
            VB_energy.extend([0] * 24)

    # -------------------- MODEL ACCURACY ANALYSIS -------------------------- #
    o['predictedLoad'] = predictions
    o['trainAccuracy'] = 0  #round(model.score(X_train, y_train) * 100, 2)
    o['testAccuracy'] = 0  #round(model.score(X_test, y_test) * 100, 2)

    # PRECISION AND RECALL
    maxDays = []
    for month in range(1, 13):
        test = df[df['month'] == month]
        maxDays.append(test.loc[test['load'].idxmax()]['dayOfYear'])

    shouldHaveDispatched = [False] * 365
    for day in maxDays:
        shouldHaveDispatched[day] = True

    truePositive = len([
        b
        for b in [i and j for (i, j) in zip(dispatched, shouldHaveDispatched)]
        if b
    ])
    falsePositive = len([
        b for b in
        [i and (not j) for (i, j) in zip(dispatched, shouldHaveDispatched)]
        if b
    ])
    falseNegative = len([
        b for b in [(not i) and j
                    for (i, j) in zip(dispatched, shouldHaveDispatched)] if b
    ])
    o['precision'] = round(
        truePositive / float(truePositive + falsePositive) * 100, 2)
    o['recall'] = round(
        truePositive / float(truePositive + falseNegative) * 100, 2)
    o['number_of_dispatches'] = len([i for i in dispatched if i])
    o['MAE'] = round(
        sum([
            abs(l - m) / m * 100
            for l, m in zip(predictions, list(all_y[-8760:]))
        ]) / 8760., 2)

    # ---------------------- FINANCIAL ANALYSIS ----------------------------- #

    # Calculate monthHours
    year = df[-8760:].copy()
    year.reset_index(inplace=True)
    year['hour'] = list(year.index)
    start = list(year.groupby('month').first()['hour'])
    finish = list(year.groupby('month').last()['hour'])
    monthHours = [(s, f + 1) for (s, f) in zip(start, finish)]

    demand = list(all_y[-8760:])
    peakDemand = [max(demand[s:f]) for s, f in monthHours]
    demandAdj = [d + p for d, p in zip(demand, VB_power)]
    peakDemandAdj = [max(demandAdj[s:f]) for s, f in monthHours]
    discharges = [f if f < 0 else 0 for f in VB_power]

    # Monthly Cost Comparison Table
    o['monthlyDemand'] = peakDemand
    o['monthlyDemandRed'] = peakDemandAdj
    o['ps'] = [p - s for p, s in zip(peakDemand, peakDemandAdj)]
    o['benefitMonthly'] = [x * demandCharge for x in o['ps']]

    # Demand Before and After Storage Graph
    o['demand'] = demand
    o['demandAfterBattery'] = demandAdj
    o['batteryDischargekW'] = VB_power
    o['batteryDischargekWMax'] = max(VB_power)

    batteryCycleLife = float(ind['batteryCycleLife'])
    # Battery State of Charge Graph
    # Turn dc's SoC into a percentage, with dodFactor considered.

    o['batterySoc'] = SoC = [100 - (e / battCapacity * 100) for e in VB_energy]

    # Estimate number of cyles the battery went through. Sums the percent of SoC.
    cycleEquivalents = sum([
        SoC[i] - SoC[i + 1]
        for i, x in enumerate(SoC[:-1]) if SoC[i + 1] < SoC[i]
    ]) / 100.0
    o['cycleEquivalents'] = cycleEquivalents
    o['batteryLife'] = batteryCycleLife / cycleEquivalents

    # Cash Flow Graph
    # inserting battery efficiency only into the cashflow calculation
    # cashFlowCurve is $ in from peak shaving minus the cost to recharge the battery every day of the year
    cashFlowCurve = [sum(o['ps']) * demandCharge for year in range(projYears)]
    cashFlowCurve.insert(0, -1 * cellCost *
                         cellQuantity)  # insert initial investment
    # simplePayback is also affected by the cost to recharge the battery every day of the year
    o['SPP'] = (cellCost * cellQuantity) / (sum(o['ps']) * demandCharge)
    o['netCashflow'] = cashFlowCurve
    o['cumulativeCashflow'] = [
        sum(cashFlowCurve[:i + 1]) for i, d in enumerate(cashFlowCurve)
    ]
    o['NPV'] = npv(float(ind['discountRate']), cashFlowCurve)

    battCostPerCycle = cellQuantity * cellCost / batteryCycleLife
    lcoeTotCost = cycleEquivalents * retailCost + battCostPerCycle * cycleEquivalents
    o['LCOE'] = lcoeTotCost / (cycleEquivalents * battCapacity)

    # Other
    o['startDate'] = '2011-01-01'  # dc[0]['datetime'].isoformat()
    o['stderr'] = ''
    # Seemingly unimportant. Ask permission to delete.
    o['stdout'] = 'Success'
    o['months'] = [
        "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct",
        "Nov", "Dec"
    ]

    return o
Example #3
0
def forecastWork(modelDir, ind):
    import tensorflow as tf
    ''' Run the model in its directory.'''
    (cellCapacity, dischargeRate, chargeRate, cellQuantity, cellCost) = \
     [float(ind[x]) for x in ('cellCapacity', 'dischargeRate', 'chargeRate', 'cellQuantity', 'cellCost')]
    demandCharge = float(ind['demandCharge'])
    retailCost = float(ind['retailCost'])

    battEff = float(ind.get("batteryEfficiency")) / 100.0
    dodFactor = float(ind.get('dodFactor')) / 100.0
    projYears = int(ind.get('projYears'))
    batteryCycleLife = int(ind.get('batteryCycleLife'))
    battCapacity = cellQuantity * float(ind['cellCapacity']) * dodFactor

    o = {}

    try:
        with open(pJoin(modelDir, 'hist.csv'), 'w') as f:
            f.write(ind['histCurve'].replace('\r', ''))
        df = pd.read_csv(pJoin(modelDir, 'hist.csv'))
        assert df.shape[0] >= 26280  # must be longer than 3 years
        if df.shape[1] == 6:
            df['dates'] = df.apply(lambda x: dt(int(x['year']), int(x[
                'month']), int(x['day']), int(x['hour'])),
                                   axis=1)
        else:
            df = pd.read_csv(pJoin(modelDir, 'hist.csv'),
                             parse_dates=['dates'])
            df['month'] = df.dates.dt.month
        df['dayOfYear'] = df['dates'].dt.dayofyear
    except:
        raise Exception("CSV file is incorrect format.")

    # ---------------------- MAKE PREDICTIONS ------------------------------- #
    # train model on previous data
    all_X = fc.makeUsefulDf(df)
    all_y = df['load']
    if ind['newModel'] == 'True':
        model = None
    else:
        with open(pJoin(modelDir, 'neural_net.h5'), 'wb') as f:
            f.write(ind['model'].decode('base64'))
        model = tf.keras.models.load_model(pJoin(modelDir, 'neural_net.h5'))
        # model = tf.keras.models.load_model(ind['model'])
    predictions, accuracy = fc.neural_net_predictions(
        all_X,
        all_y,
        epochs=int(ind['epochs']),
        model=model,
        save_file=pJoin(modelDir, 'neural_net_model.h5'))

    dailyLoadPredictions = [
        predictions[i:i + 24] for i in range(0, len(predictions), 24)
    ]
    weather = df['tempc'][-8760:]
    dailyWeatherPredictions = [
        weather[i:i + 24] for i in range(0, len(weather), 24)
    ]

    # decide to implement VBAT every day for a year
    VB_power, VB_energy = [], []
    for i, (load24, temp24) in enumerate(
            zip(dailyLoadPredictions, dailyWeatherPredictions)):
        vbp, vbe = pulp24hrBattery(load24, dischargeRate * cellQuantity,
                                   cellCapacity * cellQuantity, battEff)
        VB_power.extend(vbp)
        VB_energy.extend(vbe)

    # -------------------- MODEL ACCURACY ANALYSIS -------------------------- #
    o['predictedLoad'] = predictions
    o['trainAccuracy'] = 100 - round(accuracy['train'], 1)
    o['testAccuracy'] = 100 - round(accuracy['test'], 1)
    # ---------------------- FINANCIAL ANALYSIS ----------------------------- #

    # Calculate monthHours
    year = df[-8760:].copy()
    year.reset_index(inplace=True)
    year['hour'] = list(year.index)
    start = list(year.groupby('month').first()['hour'])
    finish = list(year.groupby('month').last()['hour'])
    monthHours = [(s, f + 1) for (s, f) in zip(start, finish)]

    demand = list(df['load'][-8760:])
    peakDemand = [max(demand[s:f]) for s, f in monthHours]
    demandAdj = [d + p for d, p in zip(demand, VB_power)]
    peakDemandAdj = [max(demandAdj[s:f]) for s, f in monthHours]

    # Monthly Cost Comparison Table
    o['monthlyDemand'] = peakDemand
    o['monthlyDemandRed'] = peakDemandAdj
    o['ps'] = [p - s for p, s in zip(peakDemand, peakDemandAdj)]
    o['benefitMonthly'] = [x * demandCharge for x in o['ps']]

    # Demand Before and After Storage Graph
    o['demand'] = demand
    o['demandAfterBattery'] = demandAdj
    o['batteryDischargekW'] = VB_power
    o['batteryDischargekWMax'] = max(VB_power)

    batteryCycleLife = float(ind['batteryCycleLife'])
    o['batterySoc'] = SoC = [100 - (e / battCapacity * 100) for e in VB_energy]
    cycleEquivalents = sum([
        SoC[i] - SoC[i + 1]
        for i, x in enumerate(SoC[:-1]) if SoC[i + 1] < SoC[i]
    ]) / 100.0
    o['cycleEquivalents'] = cycleEquivalents
    o['batteryLife'] = batteryCycleLife / (cycleEquivalents + 10)

    # Cash Flow Graph
    cashFlowCurve = [sum(o['ps']) * demandCharge for year in range(projYears)]
    cashFlowCurve.insert(0, -1 * cellCost *
                         cellQuantity)  # insert initial investment
    o['SPP'] = (cellCost * cellQuantity) / (sum(o['ps']) * demandCharge)
    o['netCashflow'] = cashFlowCurve
    o['cumulativeCashflow'] = [
        sum(cashFlowCurve[:i + 1]) for i, d in enumerate(cashFlowCurve)
    ]
    o['NPV'] = npv(float(ind['discountRate']), cashFlowCurve)

    battCostPerCycle = cellQuantity * cellCost / batteryCycleLife
    lcoeTotCost = cycleEquivalents * retailCost + battCostPerCycle * cycleEquivalents
    o['LCOE'] = lcoeTotCost / (cycleEquivalents * battCapacity + 10)

    model

    # Other
    o['startDate'] = '2011-01-01'
    o['stderr'] = ''
    o['stdout'] = 'Success'

    return o