Spaces:
Sleeping
Sleeping
import streamlit as st | |
import pandas as pd | |
import plotly.express as px | |
# Set page configurations | |
st.set_page_config(page_title="GreenLens-AI", layout="wide") | |
# Page title and description | |
st.markdown("<h1 style='text-align: center; color: #4CAF50;'>GreenLens-AI</h1>", unsafe_allow_html=True) | |
st.markdown( | |
""" | |
<p style='text-align: center; color: #4CAF50;'> | |
A Tool for Calculating Water, Energy, and Carbon Footprints of Textile Products 🌍 | |
</p> | |
""", | |
unsafe_allow_html=True, | |
) | |
# Sidebar for file upload | |
st.sidebar.header("Step 1: Upload Dataset") | |
uploaded_file = st.sidebar.file_uploader("Upload your Excel file (.xlsx)", type=["xlsx"]) | |
# Initialize data containers | |
fiber_impact_data = None | |
transport_impact_data = None | |
washing_impact_data = None | |
# Function to process the uploaded Excel file | |
def process_excel(file): | |
try: | |
excel_content = pd.ExcelFile(file) | |
fiber_data = pd.read_excel(file, sheet_name="Fiber Impact Data") | |
transport_data = pd.read_excel(file, sheet_name="Transport Impact Data") | |
washing_data = pd.read_excel(file, sheet_name="Washing Data") | |
# Convert into dictionaries for dynamic calculations | |
fiber_impact_data = fiber_data.set_index("Fiber Type")[["Water (L/kg)", "Energy (MJ/kg)", "Carbon (kg CO2e/kg)"]].to_dict(orient="index") | |
transport_impact_data = transport_data.set_index("Transport Mode")["CFP (kg CO2e/km)"].to_dict() | |
washing_impact_data = washing_data.set_index("Washing Temperature")[["Water (L/kg)", "Energy Use (MJ/wash)", "Carbon (kg CO2e/wash)", "Dryer CFP (kg CO2e/cycle)"]].to_dict(orient="index") | |
return fiber_impact_data, transport_impact_data, washing_impact_data | |
except Exception as e: | |
st.error(f"Error processing the file: {e}") | |
return None, None, None | |
# Process uploaded file | |
if uploaded_file: | |
fiber_impact_data, transport_impact_data, washing_impact_data = process_excel(uploaded_file) | |
# Function to calculate footprints | |
def calculate_footprints(weight, composition, lifecycle_inputs): | |
water_fp, energy_fp, carbon_fp = 0, 0, 0 | |
for fiber, percentage in composition.items(): | |
if fiber in fiber_impact_data: | |
data = fiber_impact_data[fiber] | |
fraction = percentage / 100 | |
water_fp += data["Water (L/kg)"] * weight * fraction | |
energy_fp += data["Energy (MJ/kg)"] * weight * fraction | |
carbon_fp += data["Carbon (kg CO2e/kg)"] * weight * fraction | |
if lifecycle_inputs["transport_mode"] in transport_impact_data: | |
carbon_fp += transport_impact_data[lifecycle_inputs["transport_mode"]] * lifecycle_inputs["transport_distance"] * weight | |
if lifecycle_inputs["washing_temperature"] in washing_impact_data: | |
washing_data = washing_impact_data[lifecycle_inputs["washing_temperature"]] | |
washing_water = washing_data["Water (L/kg)"] * lifecycle_inputs["washing_cycles"] | |
washing_energy = washing_data["Energy Use (MJ/wash)"] * lifecycle_inputs["washing_cycles"] | |
washing_carbon = washing_data["Carbon (kg CO2e/wash)"] * lifecycle_inputs["washing_cycles"] | |
dryer_carbon = washing_data["Dryer CFP (kg CO2e/cycle)"] if lifecycle_inputs["use_dryer"] else 0 | |
water_fp += washing_water | |
energy_fp += washing_energy | |
carbon_fp += washing_carbon + (dryer_carbon * lifecycle_inputs["washing_cycles"]) | |
# Convert water footprint from liters to kiloliters for visualization | |
water_fp_kL = water_fp / 1000 # Convert liters to kiloliters | |
return water_fp_kL, energy_fp, carbon_fp | |
# Sidebar inputs for all scenarios | |
def get_inputs(key_prefix): | |
product_weight = st.sidebar.number_input(f"{key_prefix} - Product Weight (kg)", min_value=0.01, step=0.01, value=0.5, key=f"{key_prefix}_weight") | |
st.sidebar.subheader(f"{key_prefix} - Material Composition (%)") | |
cotton = st.sidebar.number_input("Conventional Cotton (%)", min_value=0, max_value=100, value=50, step=1, key=f"{key_prefix}_cotton") | |
polyester = st.sidebar.number_input("Polyester (%)", min_value=0, max_value=100, value=30, step=1, key=f"{key_prefix}_polyester") | |
nylon = st.sidebar.number_input("Nylon 6 (%)", min_value=0, max_value=100, value=10, step=1, key=f"{key_prefix}_nylon") | |
acrylic = st.sidebar.number_input("Acrylic (%)", min_value=0, max_value=100, value=5, step=1, key=f"{key_prefix}_acrylic") | |
viscose = st.sidebar.number_input("Viscose (%)", min_value=0, max_value=100, value=5, step=1, key=f"{key_prefix}_viscose") | |
total_percentage = cotton + polyester + nylon + acrylic + viscose | |
if total_percentage != 100: | |
st.sidebar.error(f"Total composition for {key_prefix} must be 100%!") | |
composition = { | |
"Conventional Cotton": cotton, | |
"Polyester": polyester, | |
"Nylon 6": nylon, | |
"Acrylic": acrylic, | |
"Viscose": viscose, | |
} | |
st.sidebar.subheader(f"{key_prefix} - Lifecycle Inputs") | |
washing_cycles = st.sidebar.number_input(f"{key_prefix} - Washing Cycles", min_value=0, step=1, value=30, key=f"{key_prefix}_wash_cycles") | |
washing_temperature = st.sidebar.selectbox(f"{key_prefix} - Washing Temperature", list(washing_impact_data.keys()), key=f"{key_prefix}_wash_temp") | |
use_dryer = st.sidebar.checkbox(f"{key_prefix} - Use Tumble Dryer?", key=f"{key_prefix}_use_dryer") | |
transport_mode = st.sidebar.selectbox(f"{key_prefix} - Transport Mode", list(transport_impact_data.keys()), key=f"{key_prefix}_transport_mode") | |
transport_distance = st.sidebar.number_input(f"{key_prefix} - Transport Distance (km)", min_value=0, step=10, value=100, key=f"{key_prefix}_transport_distance") | |
lifecycle_inputs = { | |
"washing_temperature": washing_temperature, | |
"washing_cycles": washing_cycles, | |
"use_dryer": use_dryer, | |
"transport_mode": transport_mode, | |
"transport_distance": transport_distance, | |
} | |
return product_weight, composition, lifecycle_inputs | |
# Main interface | |
if uploaded_file and fiber_impact_data and transport_impact_data and washing_impact_data: | |
comparison_mode = st.sidebar.checkbox("Enable Comparison Mode") | |
if comparison_mode: | |
# Input for two assessments | |
col1, col2 = st.columns(2) | |
with col1: | |
st.subheader("Assessment 1") | |
product_weight_1, composition_1, lifecycle_inputs_1 = get_inputs("Assessment 1") | |
with col2: | |
st.subheader("Assessment 2") | |
product_weight_2, composition_2, lifecycle_inputs_2 = get_inputs("Assessment 2") | |
# Calculations for both assessments | |
water_fp_1, energy_fp_1, carbon_fp_1 = calculate_footprints(product_weight_1, composition_1, lifecycle_inputs_1) | |
water_fp_2, energy_fp_2, carbon_fp_2 = calculate_footprints(product_weight_2, composition_2, lifecycle_inputs_2) | |
# Combined visualization with line chart | |
st.subheader("Comparison of Assessments") | |
assessment_data = pd.DataFrame({ | |
"Footprint Type": ["Water (kL)", "Energy (MJ)", "Carbon (kg CO2e)"], | |
"Assessment 1": [water_fp_1, energy_fp_1, carbon_fp_1], | |
"Assessment 2": [water_fp_2, energy_fp_2, carbon_fp_2], | |
}) | |
fig = px.line( | |
assessment_data.melt(id_vars="Footprint Type", var_name="Assessment", value_name="Value"), | |
x="Footprint Type", | |
y="Value", | |
color="Assessment", | |
markers=True, | |
title="Footprint Trends: Assessment 1 vs. Assessment 2" | |
) | |
st.plotly_chart(fig) | |
else: | |
# Input for single calculation | |
product_weight, composition, lifecycle_inputs = get_inputs("") | |
water_fp, energy_fp, carbon_fp = calculate_footprints(product_weight, composition, lifecycle_inputs) | |
# Display results | |
st.subheader("Results") | |
st.markdown(f"- **Water Footprint**: {water_fp:.2f} kL") | |
st.markdown(f"- **Energy Footprint**: {energy_fp:.2f} MJ") | |
st.markdown(f"- **Carbon Footprint**: {carbon_fp:.2f} kg CO2e") | |
# Visualization for single scenario | |
result_data = pd.DataFrame({ | |
"Footprint Type": ["Water (kL)", "Energy (MJ)", "Carbon (kg CO2e)"], | |
"Value": [water_fp, energy_fp, carbon_fp], | |
}) | |
fig = px.line(result_data, x="Footprint Type", y="Value", markers=True, title="Footprint Trends") | |
st.plotly_chart(fig) | |
else: | |
st.info("Please upload a dataset to proceed.") | |