|
import gradio as gr |
|
|
|
|
|
|
|
|
|
STVI_THRESHOLDS = { |
|
"N": { |
|
"Very Low": (0.00, 0.09), |
|
"Low": (0.091, 0.18), |
|
"Medium": (0.181, 0.27), |
|
"Optimum": (0.271, 0.36), |
|
"High": (0.361, 0.45), |
|
"Very High": (0.451, 999.999), |
|
}, |
|
"P": { |
|
|
|
"Very Low": (0.00, 6.0), |
|
"Low": (6.1, 12.0), |
|
"Medium": (12.1, 18.0), |
|
"Optimum": (18.1, 24.0), |
|
"High": (24.1, 30.0), |
|
"Very High": (30.1, 999.999), |
|
}, |
|
"K": { |
|
|
|
"Very Low": (0.00, 0.075), |
|
"Low": (0.076, 0.15), |
|
"Medium": (0.151, 0.225), |
|
"Optimum": (0.226, 0.30), |
|
"High": (0.31, 0.375), |
|
"Very High": (0.376, 999.999), |
|
}, |
|
"S": { |
|
|
|
"Very Low": (0.00, 9.0), |
|
"Low": (9.1, 18.0), |
|
"Medium": (18.1, 27.0), |
|
"Optimum": (27.1, 36.0), |
|
"High": (36.1, 45.0), |
|
"Very High": (45.1, 999.999), |
|
}, |
|
"Zn": { |
|
|
|
"Very Low": (0.00, 0.45), |
|
"Low": (0.451, 0.90), |
|
"Medium": (0.91, 1.35), |
|
"Optimum": (1.351, 1.80), |
|
"High": (1.81, 2.25), |
|
"Very High": (2.251, 999.999), |
|
}, |
|
"B": { |
|
|
|
"Very Low": (0.00, 0.15), |
|
"Low": (0.151, 0.30), |
|
"Medium": (0.31, 0.45), |
|
"Optimum": (0.451, 0.60), |
|
"High": (0.61, 0.75), |
|
"Very High": (0.751, 999.999), |
|
}, |
|
} |
|
|
|
|
|
|
|
|
|
aman_rice = { |
|
"N": { |
|
"Optimum": (0, 12), |
|
"Medium": (13, 24), |
|
"Low": (25, 36), |
|
"Very Low": (37, 48), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"P": { |
|
"Optimum": (0, 3), |
|
"Medium": (4, 6), |
|
"Low": (7, 9), |
|
"Very Low": (10, 12), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"K": { |
|
"Optimum": (0, 10), |
|
"Medium": (11, 20), |
|
"Low": (21, 30), |
|
"Very Low": (31, 40), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"S": { |
|
"Optimum": (0, 2), |
|
"Medium": (3, 4), |
|
"Low": (5, 6), |
|
"Very Low": (7, 8), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"Zn": { |
|
"Optimum": (0, 0), |
|
"Medium": (0, 0.5), |
|
"Low": (0.6, 1.0), |
|
"Very Low": (1.1, 1.5), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"B": { |
|
"Optimum": (0, 0), |
|
"Medium": (0, 0.5), |
|
"Low": (0.6, 1.0), |
|
"Very Low": (1.1, 1.5), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
} |
|
|
|
big_list_5_0 = { |
|
"N": { |
|
"Optimum": (0, 30), |
|
"Medium": (31, 60), |
|
"Low": (61, 90), |
|
"Very Low": (91, 120), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"P": { |
|
"Optimum": (0, 5), |
|
"Medium": (6, 10), |
|
"Low": (11, 15), |
|
"Very Low": (16, 20), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"K": { |
|
"Optimum": (0, 25), |
|
"Medium": (26, 50), |
|
"Low": (51, 75), |
|
"Very Low": (76, 100), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"S": { |
|
"Optimum": (0, 4), |
|
"Medium": (5, 8), |
|
"Low": (9, 12), |
|
"Very Low": (13, 16), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"Zn": { |
|
"Optimum": (0, 0), |
|
"Medium": (0, 0.8), |
|
"Low": (0.9, 1.6), |
|
"Very Low": (1.7, 2.4), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"B": { |
|
"Optimum": (0, 0), |
|
"Medium": (0, 0.8), |
|
"Low": (0.9, 1.6), |
|
"Very Low": (1.7, 2.4), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
} |
|
|
|
big_list_4_0 = { |
|
"N": { |
|
"Optimum": (0, 24), |
|
"Medium": (25, 48), |
|
"Low": (49, 72), |
|
"Very Low": (73, 96), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"P": { |
|
"Optimum": (0, 4), |
|
"Medium": (5, 8), |
|
"Low": (9, 12), |
|
"Very Low": (13, 16), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"K": { |
|
"Optimum": (0, 20), |
|
"Medium": (21, 40), |
|
"Low": (41, 60), |
|
"Very Low": (61, 80), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"S": { |
|
"Optimum": (0, 3), |
|
"Medium": (4, 6), |
|
"Low": (7, 9), |
|
"Very Low": (10, 12), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"Zn": { |
|
"Optimum": (0, 0), |
|
"Medium": (0, 0.7), |
|
"Low": (0.8, 1.4), |
|
"Very Low": (1.5, 2.1), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"B": { |
|
"Optimum": (0, 0), |
|
"Medium": (0, 0.7), |
|
"Low": (0.8, 1.4), |
|
"Very Low": (1.5, 2.1), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
} |
|
|
|
big_list_3_0 = { |
|
"N": { |
|
"Optimum": (0, 18), |
|
"Medium": (19, 36), |
|
"Low": (37, 54), |
|
"Very Low": (55, 72), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"P": { |
|
"Optimum": (0, 3), |
|
"Medium": (4, 6), |
|
"Low": (7, 9), |
|
"Very Low": (10, 12), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"K": { |
|
"Optimum": (0, 15), |
|
"Medium": (16, 30), |
|
"Low": (31, 45), |
|
"Very Low": (46, 60), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"S": { |
|
"Optimum": (0, 3), |
|
"Medium": (4, 6), |
|
"Low": (7, 9), |
|
"Very Low": (10, 12), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"Zn": { |
|
"Optimum": (0, 0), |
|
"Medium": (0, 0.6), |
|
"Low": (0.7, 1.2), |
|
"Very Low": (1.3, 1.8), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
"B": { |
|
"Optimum": (0, 0), |
|
"Medium": (0, 0.6), |
|
"Low": (0.7, 1.2), |
|
"Very Low": (1.3, 1.8), |
|
"High": (0, 0), |
|
"Very High": (0, 0), |
|
}, |
|
} |
|
|
|
VARIETY_OPTIONS = { |
|
"Aman Rice": aman_rice, |
|
"BR 11, BR 22, BR 23, BRRI dhan40, BRRI dhan41, BRRI dhan44, BRRI dhan46, BRRI dhan49,\n" |
|
"BRRI dhan51, BRRI dhan52, BRRI dhan53, BRRI dhan54, BRRI dhan56, BRRI dhan62,\n" |
|
"BRRI dhan66, BRRI dhan70, BRRI dhan71, BRRI dhan72, BRRI dhan73, BRRI dhan75\n" |
|
"BRRI dhan76, BRRI dhan78, BRRI dhan79, BRRI dhan80, BRRI hybrid dhan4, BRRI hybrid dhan6\n" |
|
"and Binadhan-4, Binadhan-7, Binadhan-11, Binadhan-12, Binadhan-15, Binadhan-16, Binadhan-17, Binadhan-20": big_list_5_0, |
|
"BR25, BRRI dhan33, BRRI dhan34, BRRI dhan37, BRRI dhan38,\nBRRI dhan39, BRRI dhan56, BRRI dhan57 and Binadhan-12, Binadhan-13": big_list_4_0, |
|
"BR5, Binadhan-9; LIV: Kataribhog, Kalijira, Chinigura etc": big_list_3_0, |
|
} |
|
|
|
|
|
|
|
|
|
FERTILIZER_CONVERSION = { |
|
"N": { |
|
"product": "Urea", |
|
"ratio": 2.17, |
|
}, |
|
"P": { |
|
"product": "TSP", |
|
"ratio": 5.0, |
|
}, |
|
"K": { |
|
"product": "MoP", |
|
"ratio": 2.0, |
|
}, |
|
"S": { |
|
"product": "Gypsum", |
|
"ratio": 5.55, |
|
}, |
|
"Zn": { |
|
"product": "Zinc sulphate (heptahydrate)", |
|
"ratio": 4.75, |
|
}, |
|
"B": { |
|
"product": "Boric acid", |
|
"ratio": 5.88, |
|
}, |
|
} |
|
|
|
|
|
def classify_soil_test(nutrient, value): |
|
""" |
|
Determine the STVI class (Very Low, Low, Medium, etc.) for a given nutrient |
|
based on the user-supplied soil test 'value'. |
|
""" |
|
if nutrient not in STVI_THRESHOLDS: |
|
return None |
|
|
|
thresholds = STVI_THRESHOLDS[nutrient] |
|
for stvi_class, (lo, hi) in thresholds.items(): |
|
if lo <= value <= hi: |
|
return stvi_class |
|
return None |
|
|
|
def calculate_F_r(Uf, Ci, Cs, St, Ls): |
|
""" |
|
Fertilizer requirement formula: |
|
F_r = U_f - (C_i / C_s) * (S_t - L_s) |
|
""" |
|
if Cs == 0: |
|
return Uf |
|
return Uf - (Ci / Cs) * (St - Ls) |
|
|
|
|
|
|
|
|
|
def fertilizer_calculator( |
|
soilN, soilP, soilK, soilS, soilZn, soilB, |
|
variety_choice |
|
): |
|
|
|
rec_dict = VARIETY_OPTIONS[variety_choice] |
|
results = [] |
|
|
|
def process_nutrient(nutrient_name, soil_value): |
|
if soil_value is None: |
|
return None |
|
|
|
stvi_class = classify_soil_test(nutrient_name, soil_value) |
|
if stvi_class is None: |
|
return f"{nutrient_name}: Soil test value {soil_value} out of range or no data." |
|
|
|
if nutrient_name not in rec_dict: |
|
return f"{nutrient_name}: No recommendation data for {variety_choice}." |
|
if stvi_class not in rec_dict[nutrient_name]: |
|
return f"{nutrient_name}: No recommended range for STVI class '{stvi_class}'." |
|
|
|
(range_lo, range_hi) = rec_dict[nutrient_name][stvi_class] |
|
|
|
Uf = range_hi |
|
Ci = range_hi - range_lo |
|
|
|
|
|
(class_lo, class_hi) = STVI_THRESHOLDS[nutrient_name][stvi_class] |
|
Ls = class_lo |
|
Cs = class_hi - class_lo |
|
St = soil_value |
|
|
|
|
|
Fr = calculate_F_r(Uf, Ci, Cs, St, Ls) |
|
Fr = max(0, Fr) |
|
|
|
if nutrient_name in FERTILIZER_CONVERSION: |
|
fert_prod = FERTILIZER_CONVERSION[nutrient_name]["product"] |
|
ratio = FERTILIZER_CONVERSION[nutrient_name]["ratio"] |
|
fert_amount = Fr * ratio |
|
return ( |
|
f"{nutrient_name} - STVI: {stvi_class} | " |
|
f"Recommended Nutrient = {Fr:.2f} kg/ha | " |
|
f"{fert_prod} needed ≈ {fert_amount:.2f} kg/ha" |
|
) |
|
else: |
|
return ( |
|
f"{nutrient_name} - STVI: {stvi_class} | " |
|
f"Recommended Nutrient = {Fr:.2f} kg/ha | " |
|
f"No fertilizer product data." |
|
) |
|
|
|
|
|
for nname, sval in [ |
|
("N", soilN), |
|
("P", soilP), |
|
("K", soilK), |
|
("S", soilS), |
|
("Zn", soilZn), |
|
("B", soilB), |
|
]: |
|
ans = process_nutrient(nname, sval) |
|
if ans: |
|
results.append(ans) |
|
|
|
if not results: |
|
return "No valid nutrient inputs given." |
|
return "\n".join(results) |
|
|
|
|
|
|
|
|
|
import gradio as gr |
|
import traceback |
|
|
|
|
|
def on_calculate(soilN, soilP, soilK, soilS, soilZn, soilB, variety_choice): |
|
try: |
|
|
|
return fertilizer_calculator(soilN, soilP, soilK, soilS, soilZn, soilB, variety_choice) |
|
except Exception as e: |
|
|
|
error_message = f"An error occurred:\n{traceback.format_exc()}" |
|
print(error_message) |
|
return error_message |
|
|
|
|
|
with gr.Blocks(title="Fertilizer Calculator 🌾🚜") as demo: |
|
gr.Markdown( |
|
""" |
|
# Fertilizer Calculator 🌾🚜 |
|
Enter your soil test values below (leave blank if unknown). |
|
Then select your rice variety to see recommended fertilizer requirements! |
|
""" |
|
) |
|
|
|
with gr.Row(): |
|
soilN = gr.Number(label="Nitrogen (%)", value=None, precision=4) |
|
soilP = gr.Number(label="Phosphorus (µg/g, Olsen)", value=None, precision=4) |
|
soilK = gr.Number(label="Potassium (meq/100g)", value=None, precision=4) |
|
soilS = gr.Number(label="Sulfur (µg/g)", value=None, precision=4) |
|
soilZn = gr.Number(label="Zinc (µg/g)", value=None, precision=4) |
|
soilB = gr.Number(label="Boron (µg/g)", value=None, precision=4) |
|
|
|
variety = gr.Dropdown( |
|
label="Select Rice Variety", |
|
choices=list(VARIETY_OPTIONS.keys()), |
|
value="Aman Rice" |
|
) |
|
|
|
calc_button = gr.Button("Calculate Fertilizer Requirements ✅") |
|
output_text = gr.Textbox( |
|
label="Results", |
|
lines=12, |
|
placeholder="Your fertilizer recommendation will appear here..." |
|
) |
|
|
|
calc_button.click( |
|
fn=on_calculate, |
|
inputs=[soilN, soilP, soilK, soilS, soilZn, soilB, variety], |
|
outputs=output_text |
|
) |
|
|
|
demo.launch() |
|
|
|
|