Open In Colab

Berdasarkan isu #96: Pemodelan FJ Mock

Referensi Isu:

  • hidrokit.contrib.taruma.hk89. (manual/notebook). Pemodelan NRECA
  • Handout 1: Perhitungan Debit Limpasan dengan Metode F.J. Mock oleh Ir. Edy Anto Soentoro, MASc., PhD.

Deskripsi permasalahan:

  • Memperoleh nilai debit dari model FJ Mock.

Strategi penyelesaian:

  • Pengembangan fungsi akan serupa dengan fungsi model_NRECA di taruma.hk89.
  • Kalibrasi parameter menggunakan fungsi calibration di taruma.hk90.

Catatan:

  • Untuk membuat rekapan data harian untuk data masukan model F.J. Mock bisa menggunakan modul taruma.hk98 buat ringkasan/rekap data deret waktu (manual).

PERSIAPAN DAN DATASET

In [0]:
import numpy as np
import pandas as pd
In [0]:
!wget -O sample.xlsx "https://taruma.github.io/assets/hidrokit_dataset/fjmock_sample.xlsx" -q
dataset_path = 'sample.xlsx'
In [0]:
dataset = pd.read_excel(dataset_path)
dataset.index = pd.date_range('20050101', '20160101', freq='MS', closed='left')
dataset
Out[0]:
PRECIP NRAIN NDAYS PET
2005-01-01 74.945240 19 31 2.988970
2005-02-01 52.917729 12 28 3.145340
2005-03-01 93.692801 17 31 3.213324
2005-04-01 93.327242 19 30 3.474628
2005-05-01 11.805463 7 31 3.597509
... ... ... ... ...
2015-08-01 0.000000 0 31 4.500466
2015-09-01 10.175476 3 30 4.827330
2015-10-01 30.292786 12 31 4.858545
2015-11-01 161.871088 25 30 3.916633
2015-12-01 104.403805 25 31 3.133179

132 rows × 4 columns

KODE

In [0]:
def _EPM(NDAYS, EP):
    return NDAYS * EP

def _RATEPM(EXSURF, NRAIN):
    return (EXSURF / 100 / 20) * (18 - NRAIN)

def _DELTAE(RATEPM, EPM):
    return RATEPM * EPM

def _EA(EPM, DELTAE):
    return EPM - DELTAE

def _PEA(PRECIP, EA):
    return PRECIP - EA

def _SMS(PEA, SMC_prev):
    return PEA + SMC_prev

def _SMC(PEA, SMS):
    return 200 if PEA >= 0 else SMS

def _SS(PEA):
    return 0 if PEA >=0 else PEA

def _WATSUR(PEA, SS):
    return PEA - SS

def _I(WATSUR, IF):
    return WATSUR * IF

def _CAL0(K, I):
    return 1/2 * (1 + K) * I

def _CALGS(K, GS_prev):
    return K * GS_prev

def _GS(CAL0, CALGS):
    return CAL0 + CALGS

def _DGS(GS, GS_prev):
    return GS - GS_prev

def _BFLOW(I, DGS):
    return I - DGS

def _DRO(WATSUR, I):
    return WATSUR - I

def _SRO(PRECIP, PF):
    return 0 if PRECIP >= 200 else PRECIP * PF

def _TRO(BFLOW, DRO, SRO):
    return BFLOW + DRO + SRO

def _FLOW(TRO, AREA, NDAYS):
    return (TRO / 1000) * AREA / (NDAYS * 24 * 3600)
In [0]:
def model_FJMOCK(df, precip_col, ep_col, nrain_col, ndays_col,
                 EXSURF, IF, K, PF, ISMC, GSOM, AREA,
                 as_df=True, report='flow'):
    
    # sub_df
    data = df.loc[:, [precip_col, nrain_col, ndays_col, ep_col]]
    data_array = data.values

    # info_df
    nrows = data.shape[0]

    # initialization
    (
        epm, ratepm, deltae, ea, pea, sms, smc, ss, watsur,
        i, cal0, calgs, gs, dgs, bflow, dro, sro, tro, flow
    ) = (np.zeros(nrows) for _ in range(19))

    # calculation
    precip = data_array[:, 0]
    nrain = data_array[:, 1]
    ndays = data_array[:, 2]
    ep = data_array[:, 3]

    for j in range(nrows):

        epm[j]      = _EPM(ndays[j], ep[j])
        ratepm[j]   = _RATEPM(EXSURF, nrain[j])
        deltae[j]   = _DELTAE(ratepm[j], epm[j])
        ea[j]       = _EA(epm[j], deltae[j])
        pea[j]      = _PEA(precip[j], ea[j])
        
        if j == 0: 
            sms[j]  = _SMS(pea[j], ISMC)
        else:
            sms[j]  = _SMS(pea[j], smc[j-1])

        smc[j]      = _SMC(pea[j], sms[j])
        ss[j]       = _SS(pea[j])
        watsur[j]   = _WATSUR(pea[j], ss[j])
        i[j]        = _I(watsur[j], IF)

        cal0[j]     = _CAL0(K, i[j])

        if j == 0:
            calgs[j]= _CALGS(K, GSOM)
        else:
            calgs[j]= _CALGS(K, gs[j-1])
        
        gs[j]       = _GS(cal0[j], calgs[j])

        if j == 0:
            dgs[j]  = _DGS(gs[j], GSOM)
        else:
            dgs[j]  = _DGS(gs[j], gs[j-1])
        
        bflow[j]    = _BFLOW(i[j], dgs[j])
        dro[j]      = _DRO(watsur[j], i[j])
        sro[j]      = _SRO(precip[j], PF)
        tro[j]      = _TRO(bflow[j], dro[j], sro[j])
        flow[j]     = _FLOW(tro[j], AREA, ndays[j])
    
    # results
    if report.lower() == 'full':
        results = np.stack((
            precip, nrain, ndays, ep, epm, ratepm, deltae,
            ea, pea, sms, smc, ss, watsur, i, cal0, calgs, gs,
            dgs, bflow, dro, sro, tro, flow
        ), axis=1)
        columns_name = [
            'PRECIP', 'NRAIN', 'NDAYS', 'EP', 'EPM', 'RATEPM',
            'DELTAE', 'EA', 'PEA', 'SMS', 'SMC', 'SS', 'WATSUR', 'I',
            'CAL0', 'CALGS', 'GS', 'DGS', 'BFLOW', 'DRO', 'SRO',
            'TRO', 'FLOW' 
        ]
    elif report.lower() == 'partial':
        results = np.stack((
            precip, nrain, ndays, ep, ea, sms, ss, gs, tro, flow 
        ), axis=1)
        columns_name = [
            'PRECIP', 'NRAIN', 'NDAYS', 'EP', 'EA', 'SMS', 'SS', 'GS',
            'TRO', 'FLOW'
        ]
    elif report.lower() == 'tro':
        results = tro
        columns_name = ['TRO']
    elif report.lower() == 'flow':
        results = flow
        columns_name = ['FLOW']
    else:
        raise ValueError(
            str(report) + ' not identified. ' +
            'Use full / partial / tro / flow.'
        )
    
    if as_df:
        return pd.DataFrame(
            data=results, index=data.index, columns=columns_name
        )
    else:
        return results

MODEL F.J. Mock (1973)

Diagram model_FJMOCK

Karena pengerjaan model ini dapat beragam tergantung pembuatnya, berikut diagram yang dijadikan acuan pada pengembangan fungsi model_FJMOCK(). Diagram ini mengacu pada Handout 1: Perhitungan Debit Limpasan dengan Metode F.J. Mock oleh Ir. Edy Anto Soentoro, MASc., PhD. Jika menemui kekeliruan, mohon buat isu pada github hidrokit. Pengembangan model ini cukup terbatas dari sisi referensi.

DIAGRAM FJMOCK

Diagram ini bisa diunduh dengan kualitas terbaik disini. Diagram ini dibuat oleh taruma menggunakan draw.io dengan lisensi CC-BY-SA-4.0.

Daftar peubah dalam model_FJMOCK

Berikut daftar peubah yang digunakan dalam model_FJMOCK:

Jenis Peubah Keterangan Satuan
DATA MASUKAN PRECIP Curah Hujan / Presipitasi $\frac{mm}{period}$
. EP Evapotranspirasi $^{mm}/_{day}$
. NRAIN Jumlah hari hujan dalam periode $\{\left[0, 31\right] \in\mathbb{N}\}$
. NDAYS Jumlah hari dalam periode $\{\left[1, 31\right] \in\mathbb{N}\}$
PARAMETER EXSURF Exposed Surface $\%, \{\left[0, 50\right] \in\mathbb{N}\}$
. IF Infiltration Coefficient $\{\left(0, 1\right) \in\mathbb{R}\}$
. K Monthly Flow Recession Constant $\{\left(0, 1\right) \in\mathbb{R}\}$
. PF Percentage Factor $\{\left(0, 1\right) \in\mathbb{R}\}$
. ISMC Initial Soil Moisture Capacity $\frac{mm}{period}$
. GSOM Initial Groundwater Storage $\frac{mm}{period}$
. AREA Catchment Area $m^2$
PERHITUNGAN EPM Evapotranspirasi per periode $\frac{mm}{period}$
. RATEPM* Kalkulasi EXSURF dan NRAIN $\{\left(-1, 1\right) \in\mathbb{R}\}$
. DELTA* Delta evapotranspirasi $\frac{mm}{period}$
. EA Evapotranspirasi Actual $\frac{mm}{period}$
. PEA* Kalkulasi P dan EA $\frac{mm}{period}$
. SMS Soil Moisture Storage $\frac{mm}{period}$
. SMC Soil Moisture Capacity $\frac{mm}{period}$
. SS Soil Storage $\frac{mm}{period}$
. I Infiltration $\frac{mm}{period}$
. CAL0* Kalkulasi K dan I $\frac{mm}{period}$
. CALGS* Kalkulasi K dan GS_PREV/GSOM $\frac{mm}{period}$
. GS Groundwater Storage $\frac{mm}{period}$
. DGS Delta Groundwater Storage $\frac{mm}{period}$
. BFLOW Base Flow $\frac{mm}{period}$
. DRO Direct Runoff $\frac{mm}{period}$
. SRO Storm Runoff $\frac{mm}{period}$
. TRO Total Runoff $\frac{mm}{period}$
. FLOW Stream Flow $\frac{m^{3}}{second}$

Catatan:

  • _PREV: Nilai pada iterasi sebelumnya $(j-1)$.
  • *: Nama peubah ini dibuat khusus untuk fungsi model_FJMOCK (tidak mengikuti/ada pada referensi).

FUNGSI

Fungsi model_FJMOCK

Fungsi model_FJMOCK membangkitkan nilai debit menggunakan model yang dikembangkan oleh Dr. F. J. Mock (Mock 1973). Untuk mengetahui masing-masing batasan model ini, harap melihat pada referensi topik terkait. Dalam notebook ini hanya fokus pada penggunaan fungsi.

Fungsi memiliki 12 argumen yang harus diisi, dan 2 argumen opsional. Dibagi menjadi 3 bagian argumen yaitu:

  • Argumen untuk dataset:
    • df: dataset dalam objek pandas.DataFrame.
    • precip_col: nama kolom curah hujan (presipitasi).
    • ep_col: nama kolom evapotranspirasi.
    • nrain_col: nama kolom jumlah hari hujan dalam periode.
    • ndays_col: nama kolom jumlah hari dalam periode.
  • Argumen untuk parameter model:
    • EXSURF: Exposed Surface.
    • IF: Infiltration Coefficient.
    • K: Monthly Flow Recession Constant.
    • PF: Percentage Factor.
    • ISMC: Initial Soil Moisture Capacity.
    • GSOM: Initial Groundwater Storage.
    • AREA: Catchment Area.
  • Argumen opsional untuk fungsi:
    • as_df: True (default), keluaran berupa pandas.DataFrame. Keluaran berupa numpy.ndarray jika False.
    • report: 'flow' (default), terdapat beberapa nilai yang diterima oleh argumen report:
      • full: keluaran akan menyertakan seluruh peubah yang dihitung dalam model.
      • partial: keluaran hanya menyertakan kolom PRECIP, NRAIN, NDAYS, EP, EA, SMS, SS, GS, TRO, FLOW.
      • tro: keluaran hanya menyertakan kolom TRO.
      • flow: keluaran hanya menyertakan kolom FLOW.

as_df=True, report='flow' (default)

Keluaran berupa pandas.DataFrame.

In [0]:
model_FJMOCK(dataset,
             precip_col='PRECIP', ep_col='PET', nrain_col='NRAIN', 
             ndays_col='NDAYS',
             EXSURF=40, IF=0.7, K=0.6, PF=0.2, ISMC=200, GSOM=215.8, 
             AREA=291.83e6).head()
Out[0]:
FLOW
2005-01-01 11.038314
2005-02-01 7.524411
2005-03-01 5.427550
2005-04-01 4.200750
2005-05-01 1.476165

sebagian argumen bisa disimpan dalam bentuk dictionary.

In [0]:
parameter = {
    'EXSURF': 40,
    'IF': 0.7,
    'K': 0.6,
    'PF': 0.2,
    'ISMC': 200,
    'GSOM': 215.8,
    'AREA': 291.83e6
}

dataset_params = {
    'precip_col': 'PRECIP',
    'ep_col': 'PET',
    'nrain_col': 'NRAIN',
    'ndays_col': 'NDAYS'
}

model_FJMOCK(dataset,
             **dataset_params,
             **parameter).head()
Out[0]:
FLOW
2005-01-01 11.038314
2005-02-01 7.524411
2005-03-01 5.427550
2005-04-01 4.200750
2005-05-01 1.476165

as_df=False

Keluaran berupa numpy.ndarray

In [0]:
model_FJMOCK(dataset, **dataset_params, **parameter,
             as_df=False)
Out[0]:
array([11.03831372,  7.52441118,  5.42754989,  4.20074969,  1.4761652 ,
        1.33453689,  1.02392803,  0.99639442,  0.31482649,  0.96645418,
        0.63746247,  4.39633798,  6.71094135,  7.20975475,  3.60403751,
        3.40811612,  1.89545724,  0.57464413,  0.26752973,  0.16051784,
        0.09952106,  0.32607131,  1.19601734,  1.97546623,  0.78477441,
        1.40605689,  3.96837248,  2.74163501,  0.82829662,  0.33280309,
        0.15150419,  0.17996924,  0.17930671,  0.60706392,  1.42338245,
        4.51935998,  5.48703509,  7.86158518,  6.66854605,  4.61270398,
        1.80639153,  1.05273253,  0.55782402,  0.60313774,  0.86819483,
        1.56157215,  2.58970373,  2.53405371,  2.42960495,  3.33457675,
        2.18728535,  1.7071079 ,  1.36990622,  1.67615626,  0.11338267,
        0.03593304,  0.65775625,  0.6697543 ,  0.86505161,  2.17619576,
        1.70680932,  0.91144292,  3.44637769,  3.19805379,  5.71876288,
        2.28340161,  1.16355342,  1.21896099,  1.97557412,  3.34579081,
        1.92074562,  4.33700229,  2.73683673,  2.9936993 ,  2.29876246,
        1.83275104,  1.42160582,  0.46468883,  0.16007029,  0.0408782 ,
        0.68439159,  1.24573648,  6.0382106 ,  3.82709625,  6.98086936,
        4.04282714,  2.94190223,  2.25193748,  1.00004163,  0.75235851,
        0.1507685 ,  0.0904611 ,  0.08961692,  0.83990998,  4.64925624,
        3.68580346,  3.87585627,  2.26932747,  1.97068683,  1.56419699,
        1.81200324,  3.66691915,  1.99050686,  1.0237562 ,  0.97876111,
        1.80306937,  4.62827508,  7.05110499,  9.87122757,  5.9298505 ,
        2.34081328,  3.21261903,  1.91956054,  3.96141509,  2.7031486 ,
        1.36212155,  1.00132982,  4.06325897,  1.16137442,  4.18293059,
        8.3877247 , 10.95612413,  9.73624701,  8.70589257,  3.78714981,
        3.53442349,  1.40204959,  0.6562682 ,  0.63601507,  0.8963778 ,
        5.17469187,  3.04163336])

report

report='full'

In [0]:
model_FJMOCK(dataset, **dataset_params, **parameter,
             report='full')
Out[0]:
PRECIP NRAIN NDAYS EP EPM RATEPM DELTAE EA PEA SMS SMC SS WATSUR I CAL0 CALGS GS DGS BFLOW DRO SRO TRO FLOW
2005-01-01 74.945240 19.0 31.0 2.988970 92.658055 -0.02 -1.853161 94.511216 -19.565977 180.434023 180.434023 -19.565977 0.000000 0.000000 0.00000 129.480000 129.480000 -86.320000 86.320000 0.000000 14.989048 101.309048 11.038314
2005-02-01 52.917729 12.0 28.0 3.145340 88.069526 0.12 10.568343 77.501183 -24.583454 155.850569 155.850569 -24.583454 0.000000 0.000000 0.00000 77.688000 77.688000 -51.792000 51.792000 0.000000 10.583546 62.375546 7.524411
2005-03-01 93.692801 17.0 31.0 3.213324 99.613029 0.02 1.992261 97.620768 -3.927967 151.922602 151.922602 -3.927967 0.000000 0.000000 0.00000 46.612800 46.612800 -31.075200 31.075200 0.000000 18.738560 49.813760 5.427550
2005-04-01 93.327242 19.0 30.0 3.474628 104.238826 -0.02 -2.084777 106.323603 -12.996361 138.926241 138.926241 -12.996361 0.000000 0.000000 0.00000 27.967680 27.967680 -18.645120 18.645120 0.000000 18.665448 37.310568 4.200750
2005-05-01 11.805463 7.0 31.0 3.597509 111.522784 0.22 24.535012 86.987771 -75.182309 63.743933 63.743933 -75.182309 0.000000 0.000000 0.00000 16.780608 16.780608 -11.187072 11.187072 0.000000 2.361093 13.548165 1.476165
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
2015-08-01 0.000000 0.0 31.0 4.500466 139.514446 0.36 50.225201 89.289246 -89.289246 -82.313604 -82.313604 -89.289246 0.000000 0.000000 0.00000 9.034791 9.034791 -6.023194 6.023194 0.000000 0.000000 6.023194 0.656268
2015-09-01 10.175476 3.0 30.0 4.827330 144.819900 0.30 43.445970 101.373930 -91.198454 -173.512058 -173.512058 -91.198454 0.000000 0.000000 0.00000 5.420875 5.420875 -3.613916 3.613916 0.000000 2.035095 5.649012 0.636015
2015-10-01 30.292786 12.0 31.0 4.858545 150.614905 0.12 18.073789 132.541117 -102.248331 -275.760389 -275.760389 -102.248331 0.000000 0.000000 0.00000 3.252525 3.252525 -2.168350 2.168350 0.000000 6.058557 8.226907 0.896378
2015-11-01 161.871088 25.0 30.0 3.916633 117.498997 -0.14 -16.449860 133.948856 27.922231 -247.838158 200.000000 0.000000 27.922231 19.545562 15.63645 1.951515 17.587965 14.335440 5.210122 8.376669 32.374218 45.961009 5.174692
2015-12-01 104.403805 25.0 31.0 3.133179 97.128563 -0.14 -13.597999 110.726562 -6.322757 193.677243 193.677243 -6.322757 0.000000 0.000000 0.00000 10.552779 10.552779 -7.035186 7.035186 0.000000 20.880761 27.915947 3.041633

132 rows × 23 columns

report='partial'

In [0]:
model_FJMOCK(dataset, **dataset_params, **parameter,
             report='partial')
Out[0]:
PRECIP NRAIN NDAYS EP EA SMS SS GS TRO FLOW
2005-01-01 74.945240 19.0 31.0 2.988970 94.511216 180.434023 -19.565977 129.480000 101.309048 11.038314
2005-02-01 52.917729 12.0 28.0 3.145340 77.501183 155.850569 -24.583454 77.688000 62.375546 7.524411
2005-03-01 93.692801 17.0 31.0 3.213324 97.620768 151.922602 -3.927967 46.612800 49.813760 5.427550
2005-04-01 93.327242 19.0 30.0 3.474628 106.323603 138.926241 -12.996361 27.967680 37.310568 4.200750
2005-05-01 11.805463 7.0 31.0 3.597509 86.987771 63.743933 -75.182309 16.780608 13.548165 1.476165
... ... ... ... ... ... ... ... ... ... ...
2015-08-01 0.000000 0.0 31.0 4.500466 89.289246 -82.313604 -89.289246 9.034791 6.023194 0.656268
2015-09-01 10.175476 3.0 30.0 4.827330 101.373930 -173.512058 -91.198454 5.420875 5.649012 0.636015
2015-10-01 30.292786 12.0 31.0 4.858545 132.541117 -275.760389 -102.248331 3.252525 8.226907 0.896378
2015-11-01 161.871088 25.0 30.0 3.916633 133.948856 -247.838158 0.000000 17.587965 45.961009 5.174692
2015-12-01 104.403805 25.0 31.0 3.133179 110.726562 193.677243 -6.322757 10.552779 27.915947 3.041633

132 rows × 10 columns

report='tro'

In [0]:
model_FJMOCK(dataset, **dataset_params, **parameter,
             report='tro')
Out[0]:
TRO
2005-01-01 101.309048
2005-02-01 62.375546
2005-03-01 49.813760
2005-04-01 37.310568
2005-05-01 13.548165
... ...
2015-08-01 6.023194
2015-09-01 5.649012
2015-10-01 8.226907
2015-11-01 45.961009
2015-12-01 27.915947

132 rows × 1 columns

report='flow' (default)

In [0]:
model_FJMOCK(dataset, **dataset_params, **parameter,
             report='flow')
Out[0]:
FLOW
2005-01-01 11.038314
2005-02-01 7.524411
2005-03-01 5.427550
2005-04-01 4.200750
2005-05-01 1.476165
... ...
2015-08-01 0.656268
2015-09-01 0.636015
2015-10-01 0.896378
2015-11-01 5.174692
2015-12-01 3.041633

132 rows × 1 columns

Changelog

- 20191218 - 1.1.0 - Initial

Copyright © 2019 Taruma Sakti Megariansyah

Source code in this notebook is licensed under a MIT License. Data in this notebook is licensed under a Creative Common Attribution 4.0 International.