Skip to content
Snippets Groups Projects
backend5.py 27.06 KiB
import streamlit as st
import pandas as pd
from bokeh.plotting import ColumnDataSource, figure, output_file, show
from glob import glob
import numpy as np
import io
from PIL import Image
from datetime import datetime, time, timedelta
from bokeh.models import HoverTool
from bokeh.io import export_png
from selenium import webdriver
from bokeh.io.export import get_screenshot_as_png
from bokeh.models import Range1d
from IPython.display import display
import hvplot.pandas
import hvplot.dask
import logging
import base64

#calculate each reflectance factor for band 01-06
def set_reflectance(df: pd.DataFrame, summary: str):
  refl = summary + "_reflFactor"
  radiance = summary + "_radiance_value_of_valid_pixels"
  df[radiance] = df[radiance].astype(float)
  df['kappa0'] = df['kappa0'].astype(float)
  df[refl] = df[radiance] * df['kappa0']

#calculate all reflectance factor for band 01-06
def set_all_reflectance(df: pd.DataFrame):
  #calculate max refelctance factor
  set_reflectance(df, "max")
  #calculate min refelctance factor
  set_reflectance(df, "min")
  #calculate mean refelctance factor
  set_reflectance(df, "mean")
  #calculate standard deviation refelctance factor
  set_reflectance(df, "std_dev")

#calculate each temperature
def set_temperature(df: pd.DataFrame, summary: str):
  temp = summary + "_temp"
  radiance = summary + "_radiance_value_of_valid_pixels"
  df[temp] = (df['planck_fk2'].astype(float) / (np.log((df['planck_fk1'].astype(float) / df[radiance].astype(float)) + 1)) - df['planck_bc1'].astype(float)) / df['planck_bc2'].astype(float)

#calculate all temperature for band 07-16
def set_all_temperature(df: pd.DataFrame):
  #calculate max temp
  set_temperature(df, "max")
  #calculate min temp
  set_temperature(df, "min")
  #calculate mean temp
  set_temperature(df, "mean")
  #calculate standard deviation temp
  set_temperature(df, "std_dev")

#calculate differneces of reflectance factor from CMIP.txt and Rad.txt for band01-06
def set_refl_difference(df: pd.DataFrame, df2: pd.DataFrame):
  # max difference
  df["max_refl_dif"] = df['max_reflFactor'].astype(float) - df2['max_reflectance_factor'].astype(float)
  # min difference
  df["min_refl_dif"] = df['min_reflFactor'].astype(float) - df2['min_reflectance_factor'].astype(float)
  # mean difference
  df["mean_refl_dif"] = df['mean_reflFactor'].astype(float) - df2['mean_reflectance_factor'].astype(float)
  # standard deviation difference
  df["std_dev_refl_dif"] = df['std_dev_reflFactor'].astype(float) - df2['std_dev_reflectance_factor'].astype(float)

#calculate differneces of temp from CMIP.txt and Rad.txt for band07-16
def set_temp_difference(df: pd.DataFrame, df2: pd.DataFrame):
  # max difference
  df["max_temp_dif"] = df['max_temp'].astype(float) - df2['max_brightness_temperature'].astype(float)
  # min difference
  df["min_temp_dif"] = df['min_temp'].astype(float) - df2['min_brightness_temperature'].astype(float)
  # mean difference
  df["mean_temp_dif"] = df['mean_temp'].astype(float) - df2['mean_brightness_temperature'].astype(float)
  # standard deviation difference
  df["std_dev_temp_dif"] = df['std_dev_temp'].astype(float) - df2['std_dev_brightness_temperature'].astype(float)

#save file
def save_file(var: str, satellite: str, sector: str, product: str, band: int, statistics: str, start_date: str, end_date: str, p: figure):
  png = get_screenshot_as_png(p, width = 2000, height = 1000)
  image = io.BytesIO()
  png.save(image, format='PNG')
  btn = st.download_button(
  label="Download figure",
  data=image,
  file_name= f'{satellite}-{sector}-{product}-{band}-{statistics}-{start_date}-{end_date}.png', 
  mime="image/png"
  )

#name statistics for filename
def get_statistics(var: str):
  if var in ["min_temp", "min_brightness_temperature", "min_temp_dif"]:
    statistics = "minTemp"

  elif var in ["max_temp", "max_brightness_temperature", "max_temp_dif"]:
    statistics = "maxTemp"

  elif var in ["mean_temp", "mean_brightness_temperature", "mean_temp_dif"]:
    statistics = "meanTemp"

  elif var in ["std_dev_temp", "std_dev_brightness_temperature", "std_dev_temp_dif"]:
    statistics = "stdTemp"

  elif var in ["min_reflectance_factor", "min_reflFactor", "min_refl_dif"]:
    statistics = "minRefl"

  elif var in ["max_reflectance_factor", "max_reflFactor", "max_refl_dif"]:
    statistics = "maxRefl"

  elif var in ["mean_reflectance_factor", "mean_reflFactor", "mean_refl_dif"]:
    statistics = "meanRefl"

  elif var in ["std_dev_reflectance_factor", "std_dev_reflFactor", "std_dev_refl_dif"]:
    statistics = "stdRefl"

  elif(var == "min_radiance_value_of_valid_pixels" ):
    statistics = "minRad"

  elif(var == "max_radiance_value_of_valid_pixels"):
    statistics = "maxRad"

  elif(var == "mean_radiance_value_of_valid_pixels"):
    statistics = "meanRad"

  elif(var == "std_dev_radiance_value_of_valid_pixels"):
    statistics = "stdRad"

  return statistics 

#User can choose band, product
def get_selection(band_index: int, product_index: int, satellite_index: int, sector_index: int):
  band = st.sidebar.selectbox('ABI Band', ('01: Visible - "Blue" (0.47µm)', '02: Visible - "Red" (0.64µm)', '03: Near-IR - "Veggie" (0.86µm)', '04: Near-IR - "Cirrus" (1.37µm)', '05: Near-IR - "Snow/Ice" (1.6µm)', '06: Near-IR - "Cloud Particle Size" (2.2µm)', '07: IR - "Shortwave Window" (3.9µm)', '08: IR - "Upper-Level Trop. Water Vapor" (6.2µm)', '09: IR - "Mid-Level Trop. Water Vapor" (6.9µm)', '10: IR - "Lower-Level Water Vapor" (7.3µm)', '11: IR - "Cloud-Top Phase" (8.4µm)', '12: IR - "Ozone" (9.6µm)', '13: IR - "Clean Longwave Window" (10.3µm) ', '14: IR - "Longwave Window" (11.2µm)', '15: IR - "Dirty Longwave Window" (12.3µm)', '16: IR - "CO2 Longwave" (13.3µm)'), index = band_index, key = 'band_number', on_change=st.experimental_set_query_params, kwargs=st.session_state)
  band_num = int(band[0:2])
  product = st.sidebar.selectbox('Product', ('From CMIP', 'Calculated From Rad', 'Difference', 'Compare', 'Radiance From Rad'), index = product_index, key = 'product_type', on_change=st.experimental_set_query_params, kwargs=st.session_state)
  satellite = st.sidebar.selectbox("Satellite type", ('GOES-16', 'GOES-17', 'GOES-18'), index = satellite_index, key = 'satellite_name', on_change=st.experimental_set_query_params, kwargs=st.session_state)
  satellite_num = satellite[5:7]
  sector = st.sidebar.selectbox('Sector', ('Full Disk', 'CONUS', 'Mesoscale 1', 'Mesoscale 2'), index = sector_index, key = 'sector_type', on_change=st.experimental_set_query_params, kwargs=st.session_state)
  sector_char = sector[0:1]

  return [band_num, product, satellite, satellite_num, sector, sector_char]

#set the y range
def set_range(defaultMin: float, defaultMax: float, statistics: str, p):
  with st.expander("Set y plot range"):
    minNumber = st.number_input('Choose y min range', value = defaultMin, key = statistics)
    maxNumber = st.number_input('Choose y max range', value = defaultMax, key = statistics)
    p.y_range = Range1d(minNumber, maxNumber)

#set hover
def set_hover(product: str, p, var, band, var2):
  if(product == "Difference"):
    tag = "Difference"
    point = 1.1111
  elif(product == "Radiance From Rad"):
    tag = "Radiance"
    point = 1.111 
  elif(product in ["Calculated From Rad", "From CMIP"] and band < 7):
    tag = "Reflectance_factor" 
    point = 1.11
  elif(product in ["Calculated From Rad", "From CMIP"] and band >= 7):
    tag = "Temperature"
    point = 1.1
  elif(product == "Compare" and band < 7):
    tag1 = "Reflectance_factor_RAD"
    tag2 = "Reflectance_factor_CMIPF"
    point = 1.11
  elif(product == "Compare" and band >= 7):
    tag1 = "Temperature_RAD"
    tag2 = "Temperature_CMIPF" 
    point = 1.1

  hover = HoverTool(tooltips = """
    <div>
        <div>
            <span style="font-size: 15px;">Time</span>
            <span style="font-size: 10px; color: #696;">$var2</span>
        </div>
        <div>
            <span style="font-size: 15px;">tag</span>
            <span style="font-size: 10px; color: #696;">$tag</span>
        </div>
    </div>
""")

  hover.mode = 'vline'
  if(product != "Compare"):
    #hover.tooltips = [('Time', '@var2{%Y-%m-%d %H:%M:%S}'), (tag, '@tag{point}')]
    hover.tooltips = [('Time', '@var2{%Y-%m-%d %H:%M:%S}'), (tag, '@tag{point}')]
    hover.formatters = {var2: 'datetime', tag: 'printf'}
  else:
    hover.tooltips = [('Time', '@Time{%Y-%m-%d %H:%M:%S}'), (tag1, '@tag1{point}'), (tag2, '@tag2{point}')]
    hover.formatters = {'@Time': 'datetime', tag1: 'printf', tag2: 'printf'}
  p.add_tools(hover) 

#JASON Nan value error
#remove Nan
def remove_nan(df, var):
  df3=df[var]
  df3 = df3.dropna()
  df3 = df3.reset_index(drop=True) 
  return df3

#set date detail
def get_date(start, start_time, end, end_time):
  year1 = start.strftime("%Y")
  month1 = start.strftime("%m")
  day1 = start.strftime("%d")
  time1 = start_time

  year2 = end.strftime("%Y")
  month2 = end.strftime("%m")
  day2 = end.strftime("%d")
  time2 = end_time

  return [year1, month1, day1, time1, year2, month2, day2, time2] 

#get date range
def get_dateRange(year1, month1, day1, time1, year2, month2, day2, time2):
  start_date = f'{year1}-{month1}-{day1}T{time1}'
  end_date = f'{year2}-{month2}-{day2}T{time2}'
  return [start_date, end_date] 

#plot p
def plot_p(p, color1, color2, source, label, var_x, var_y):
  p.line(var_x, var_y, color = color1, legend_label = label, source = source)
  circle = p.circle(var_x, var_y, color = color2, source = source)
  p.legend.label_text_font="times"
  p.legend.location = "top_right"
  p.toolbar.logo = None
  return circle

#show detailed table
def show_table(band, header, df, var1, var2, var3, var4, var5, var6, var7, var8):
  if(band < 7):
    st.subheader(header)
    return df[[var1,var2, var3, var4]]
  else:
    st.subheader(header)
    return df[[var5, var6, var7, var8]]

#show label
def show_label(band, xLabel, yLabel, yLabel2):
  if band < 7:
    x_axis_label = xLabel
    y_axis_label = yLabel
  else:
    x_axis_label = xLabel
    y_axis_label = yLabel2

#default time for end_time
def get_defaultTime(end, start, now, start_time, latestTime):
  if(end == start and end == now.date()):
    minTime = start_time
    maxTime = latestTime
    defaultTime = latestTime
  elif(end == start and  end != now.date()):
    minTime = start_time
    maxTime = time(23, 58)
    defaultTime = time(23, 58)
  elif(end != start and end == now.date()):
    minTime = (time(00, 00))
    maxTime = latestTime
    defaultTime = latestTime
  else:
    minTime = (time(00, 00))
    maxTime = (time(23, 58))
    defaultTime = (time(23, 58))
 
  return [minTime, maxTime, defaultTime]

#start and end time for today
def get_timeToday(now, latestTime):
  start = now
  start_time = time(00, 00)
  end = now
  end_time = latestTime 
  return [start, start_time, end, end_time]

#maxTime for choose date selection
def get_maxTime_chooseDate(start, now, latestTime):
  if(start == now.date()):
    maxTime = latestTime
  else:
    maxTime = (time(23,58))  
  return maxTime

#show all time sliderbar and get start, end, start_date, end_date when user chooses "choose date yourself"
def get_timeDate_chooseDate(now, start_default, min_start_value, max_start_value, startTime_default, end_default, endTime_default, latestTime):
  start = st.sidebar.date_input("Date: From", value = start_default, min_value = min_start_value, max_value = max_start_value, on_change=st.experimental_set_query_params, kwargs=st.session_state, key = 'first')
  maxTime = get_maxTime_chooseDate(start, now, latestTime)
  start_time = st.sidebar.slider("Choose time to start:", value = startTime_default, max_value = maxTime, step = timedelta(minutes=10), on_change=st.experimental_set_query_params, kwargs=st.session_state, key = 'first_time')

  start_int = int(str(start)[0:4] + str(start)[5:7] + str(start)[8:10])
  end_default_int = int(str(end_default)[0:4] + str(end_default)[5:7] + str(end_default)[8:10])
  max_start_value_int = int(str(max_start_value)[0:4] + str(max_start_value)[5:7] + str(max_start_value)[8:10])

  if(start_int > end_default_int or end_default_int > max_start_value_int):
    end = st.sidebar.date_input("Date: To", value = start, min_value = start, max_value = max_start_value, on_change=st.experimental_set_query_params, kwargs=st.session_state, key = 'final') 
  else:
    end = st.sidebar.date_input("Date: To", value = end_default, min_value = start, max_value = max_start_value, on_change=st.experimental_set_query_params, kwargs=st.session_state, key = 'final')

  [minTime, maxTime, defaultTime] = get_defaultTime(end, start, now, start_time, latestTime)
  if(endTime_default == 0):
    endTime_default = defaultTime

  end_time = st.sidebar.slider("Choose time to end:", value = endTime_default, min_value = minTime, max_value = maxTime, step = timedelta(minutes=10), on_change=st.experimental_set_query_params, kwargs=st.session_state, key = 'final_time')
 
  [year1, month1, day1, time1, year2, month2, day2, time2] = get_date(start, start_time.strftime("%H:%M:%S"), end, end_time.strftime("%H:%M:%S"))
  [start_date, end_date] = get_dateRange(year1, month1, day1, time1, year2, month2, day2, time2)
  return [start, end, start_date, end_date, start_time, end_time]

#show all time sliderbar and get start, end, start_date, end_date, start_time, end_time when user chooses "Today"
def get_timeDate_today(now, latestTime):
  [start, start_time, end, end_time] = get_timeToday(now, latestTime)
  [year1, month1, day1, time1, year2, month2, day2, time2] = get_date(now, "00:00:00", now, now.strftime("%H:%M:%S"))
  [start_date, end_date] = get_dateRange(year1, month1, day1, time1, year2, month2, day2, time2)
  return [start, end, start_time, end_time, start_date, end_date]

#make dataframe as user chooses
def make_dataframe(dfs, start_date, end_date):
  df = pd.concat(dfs, ignore_index=True)
  df['time'] = df['time'].astype(str)
  df['time'] = df['time'].str.zfill(6)
  df['time']
  df['time'] = pd.to_timedelta(df['time'].str[:2] + ':' + df['time'].str[2:4] + ':' + df['time'].str[4:6])
  df = df.sort_values(['day','time'])
  df['date'] = pd.to_datetime(df['day'], format='%Y%j')
  df['date'] = df['date'] + df['time']
  df = df.drop('day', axis=1)
  df = df.drop('time', axis=1)
  df.set_index('date', inplace=True)
  df = df.loc[start_date:end_date]
  return df


#data generation
#@st.cache
def generate_data(sector, satellite_num, band, file_type, start_date, end_date): 

  #year, month, and day are same
  if((str(end_date)[0:4] == str(start_date)[0:4]) and (str(end_date)[5:7] == str(start_date)[5:7]) and (str(end_date)[8:10] == str(start_date)[8:10])):
    date_glob = str(end_date)[0:4] + str(end_date)[5:7] + str(end_date)[8:10]

  #year and month are same
  elif((str(end_date)[0:4] == str(start_date)[0:4]) and (str(end_date)[5:7] == str(start_date)[5:7])):
    date_glob = str(end_date)[0:4] + str(end_date)[5:7] + "??"

  #year is same
  elif(str(end_date)[0:4] == str(start_date)[0:4]):
    #month starts with 0
    if(end_date[5:6] == "0" and start_date[5:6] == "0"):
      date_glob = str(end_date)[0:4] + "0???"
    #month starts with 1
    if(end_date[5:6] == "1" and start_date[5:6] == "1"):
      date_glob = str(end_date)[0:4] + "1???"

  else:
    date_glob = "202?????"

  #RadF
  if(sector == "Full Disk"):
    paths = glob(f'/scratch/gops/amqpfind/FD/{date_glob}/GOES{satellite_num}_imagery_statistics_{file_type}F_*_band{band:02d}.txt')
  #RadC
  elif(sector == "CONUS"):
    paths = glob(f'/scratch/gops/amqpfind/CONUS/{date_glob}/GOES{satellite_num}_imagery_statistics_{file_type}C_20?????_band{band:02d}.txt')
  elif(sector == "Mesoscale 1"):
    paths = glob(f'/scratch/gops/amqpfind/M1/{date_glob}/GOES{satellite_num}_imagery_statistics_{file_type}M1_20?????_band{band:02d}.txt')
  elif(sector == "Mesoscale 2"):
    paths = glob(f'/scratch/gops/amqpfind/M2/{date_glob}/GOES{satellite_num}_imagery_statistics_{file_type}M2_20?????_band{band:02d}.txt')

  cols = ['day', 'time'] + [col.split(',')[1] for col in pd.read_csv(paths[0], header=1, nrows=0, delimiter=':').columns[1:]]
  dfs = []
  tempDf = []
  for path in paths:
    if(path in glob(f'/scratch/gops/amqpfind/FD/20220223/GOES??_imagery_statistics_{file_type}F_2022054_band??.txt')):
      tempDf.append(pd.read_csv(path, header=1, names=cols, na_values=-999999, usecols=range(len(cols))))
      #Delete wrong data since some file has weired data
      num = 0
      for i in range(len(tempDf[0])):
        if((tempDf[0].iloc[num]['time'] in ["CMIPF", "RadF", "0"]) or (tempDf[0].iloc[num]['day'] == "#2022054") or (len(str(tempDf[0].iloc[num]['day']).strip()) == 4)):
          tempDf[0] = tempDf[0].drop(i)
          num = num - 1
        num = num + 1

      dfs.append(tempDf[0])

    else:
      dfs.append(pd.read_csv(path, header = 1, names=cols, na_values=-999999, usecols=range(len(cols))))

  return dfs

#data generation2
#@st.cache
def generate_data2(sector, satellite_num, band, file_type, start_date, end_date):

  if(sector == "Full Disk"):
    paths = glob(f'/scratch/gops/amqpfind/FD/20??????/GOES{satellite_num}_imagery_statistics_{file_type}F_*_band{band:02d}.txt')
  elif(sector == "CONUS"):
    paths = glob(f'/scratch/gops/amqpfind/CONUS/20??????/GOES{satellite_num}_imagery_statistics_{file_type}C_20?????_band{band:02d}.txt')
  elif(sector == "Mesoscale 1"):
    paths = glob(f'/scratch/gops/amqpfind/M1/20??????/GOES{satellite_num}_imagery_statistics_{file_type}M1_20?????_band{band:02d}.txt')
  elif(sector == "Mesoscale 2"):
    paths = glob(f'/scratch/gops/amqpfind/M2/20??????/GOES{satellite_num}_imagery_statistics_{file_type}M2_20?????_band{band:02d}.txt')

  cols = ['day', 'time'] + [col.split(',')[1] for col in pd.read_csv(paths[0], header=1, nrows=0, delimiter=':').columns[1:]]
  dfs = []
  tempDf = []
  for path in paths:
    if(path in glob(f'/scratch/gops/amqpfind/FD/20220223/GOES??_imagery_statistics_{file_type}F_2022054_band??.txt')):
      tempDf.append(pd.read_csv(path, header=1, names=cols, na_values=-999999, usecols=range(len(cols))))
      #Delete wrong data since some file has weired data
      num = 0
      for i in range(len(tempDf[0])):
        if((tempDf[0].iloc[num]['time'] in ["CMIPF", "RadF", "0"]) or (tempDf[0].iloc[num]['day'] == "#2022054") or (len(str(tempDf[0].iloc[num]['day']).strip()) == 4)):
          tempDf[0] = tempDf[0].drop(i)
          num = num - 1
        num = num + 1

      dfs.append(tempDf[0])

    else:
      dfs.append(pd.read_csv(path, header = 1, names=cols, na_values=-999999, usecols=range(len(cols))))

  return dfs

#hovertool
def set_hover(p, circle, TOOLTIPS, x, y):
  hover = HoverTool(renderers = [circle])
  hover.tooltips = TOOLTIPS
  hover.formatters = {'@x': 'datetime', 'y' : 'printf',  'y1' : 'printf'}
  p.add_tools(hover)

def page2():
  st.markdown("""
    <style>
    .overview {
      font-size:30px !important;
      color: Malachite;
      border-style: double;
      background-color: black;
      text-align:center;
      font-family: "Gill Sans", sans-serif;    
    }
    </style>
     """, unsafe_allow_html=True)

  st.markdown('<p class="overview">Overview<p class="detail">On this interactive website, you can visually compare the minimum, maximum, mean, and standard deviation of reflectance factors or temperatures sent from the GOES-R Series in real-time and download the generated figures. <br>You can also compare the temperature/reflectance factor converted from radiance in the Rad file with the existing temperature/reflectance factor in the CMIP file.</p></p>', unsafe_allow_html=True)

  st.markdown('<p class="empty"> </p>', unsafe_allow_html=True)
  st.markdown('<p class="empty"></p>', unsafe_allow_html=True)
  st.markdown('<p class="website">User Guide</p>', unsafe_allow_html=True)
  st.markdown("""
    <style>
    .detail {
      font-size:15px !important;
      color: white;
      background-color: black;
      text-align:left;
      font-family: "Gill Sans", sans-serif;    

    }

    .website {
      font-size:16px !important;
      color: green;
      border-style: double;
      background-color: black;
      text-align:center;
      font-family: "Gill Sans", sans-serif;    
    }

    .language {
      font-size:15px !important;
      color: white;
      paddling: 0;
      background-color: black;
      text-align:left;
      font-family: "Gill Sans", sans-serif;    

    }

    .guide {
      font-size:15px !important;
      color: black;
      paddling: 0;
      background-color: white;
      text-align:left;
      font-family: "Gill Sans", sans-serif;    

    }
    </style>
     """, unsafe_allow_html=True)

  with st.expander("What Are GOES-R Series"):
    st.markdown('<p class="guide"><br>The GOES-R series of satellites are developed and acquired by the National Oceanic and Atmospheric Administration and NASA to provide continuous imagery of atmospheric observations and space weather forecasts of the earth.<br>Our website visualizes data sent by GOES-16, 17, and 18.</p>', unsafe_allow_html=True)
    st.video("https://youtu.be/6Q7Leqvzfg4")

  with st.expander("What Is ABI Band"):
    st.markdown('<p class="guide">The Advanced Baseline Imager(ABI) is the flagship instrument in the GOES-R Series, imaging the weather, oceans, and environment. <br>ABI has 16 different spectral bands.<br>Band1-2: &nbsp;&nbsp; visible channels<br>Band 3-6: &nbsp;&nbsp;near-infrared channels<br>Band 7-16: &nbsp;&nbsp;infrared channels</p>', unsafe_allow_html=True)
    st.video("https://youtu.be/K-5aJJP_QyU")


  with st.expander("What Is Sector"):
    st.markdown('<p class="guide">You can choose geographic coverage by using sector button on the sidebar.<br>"Full-Disk": &nbsp;&nbsp;circular image covering the Western Hemisphere almost completely.<br>"CONUS": &nbsp;&nbsp; 3,000 (latitude) x 5,000 (longitude) km rectangular image depicting the continental United States.<br>"Mesoscale": &nbsp;&nbsp; 1,000 x 1,000 km rectangular image.</p>', unsafe_allow_html=True)
    col1, col2, col3 = st.columns(3)
    with col1:
      st.markdown('<p class="guide">Full-Disk</p>', unsafe_allow_html=True)
      st.video("https://youtu.be/7XlfE0ndv_g")
    with col2:
      st.markdown('<p class="guide">CONUS</p>', unsafe_allow_html=True)
      st.video("https://youtu.be/0w-ovGPSLpQ")
    with col3:
      st.markdown('<p class="guide">Mesoscale</p>', unsafe_allow_html=True)
      st.video("https://youtu.be/ZdJSa9FW-Ms")

  with st.expander("How To Choose Product"):
    st.markdown('<p class="guide">"From CMIP"&nbsp; :&nbsp;&nbsp;You can visually compare statistics of temperature(ABI band from 1 through 6)/reflectance factor(ABI band from 7 through 16) in CMIP files.</p>', unsafe_allow_html=True)
    st.markdown('<p class="guide">"Calculated From Rad"&nbsp; :&nbsp;&nbsp;Our website calculates temperatures/reflectance factors based on radiance values in Rad files. &nbsp; Then you can visually compare statistics of temperature(ABI band from 1 through 6)/reflectance factor(ABI band from 7 through 16) in Rad files.</p>', unsafe_allow_html=True)
    st.markdown('<p class="guide">"Difference"&nbsp; :&nbsp;&nbsp;Our website calculates each difference of temperatures/reflectance factors in Rad and CMIP files(Rad files - in CMIP files). &nbsp; Then you can visually compare the each difference of calculated statistics.</p>', unsafe_allow_html=True)
    st.markdown('<p class="guide">"Compare"&nbsp; :&nbsp;&nbsp;Our website calculates temperatures/reflectance factors based on radiance values in Rad files. &nbsp; Then you can visually compare statistics of temperature(ABI band from 1 through 6)/reflectance factor(ABI band from 7 through 16) in CMIP files and Rad files.</p>', unsafe_allow_html=True)
    st.markdown('<p class="guide">"Radiance From Rad"&nbsp; :&nbsp;&nbsp;You can visually compare statistics of radiance values in Rad files.</p>', unsafe_allow_html=True)

  st.markdown('<p class="empty"> </p>', unsafe_allow_html=True)
  st.markdown('<p class="empty"></p>', unsafe_allow_html=True) 
  st.markdown('<p class="website">For More About Our Website<p class="language">Programming Language:&nbsp;&nbsp;Python, HTML, CSS, JavaScript<br>Package:&nbsp;&nbsp;Numpy, Pandas, Streamlit, Bokeh<br>Gitlab:&nbsp;&nbsp;  <input type="image" src="https://w7.pngwing.com/pngs/535/202/png-transparent-gitlab-logo-version-control-company-react-others-miscellaneous-angle-company-thumbnail.png" width="25" height="25"/><a href="https://gitlab.ssec.wisc.edu/msuzuki/cmipf_rad" data-show-count="false">Gitlab Link</a><script async src="https://gitlab.ssec.wisc.edu/msuzuki/cmipf_rad" charset="utf-8"></script></p></p>',
unsafe_allow_html=True)
 
  return 1

#default y range for band1-6
def default_y_range(band, var, defaultMin, defaultMax):
  if((band < 7) and (var not in ["std_dev_reflectance_factor", "std_dev_reflFactor", "std_dev_refl_dif", "std_dev_reflFactor"])): 
    defaultMin =  -0.2
    defaultMax =  1.2
  if((band < 7) and (var in ["std_dev_reflectance_factor", "std_dev_reflFactor", "std_dev_refl_dif", "std_dev_reflFactor"])):
    defaultMin = -1.0
    defaultMax = 1.0

  return [defaultMin, defaultMax]


def address():
  with st.sidebar:
    st.markdown("""
    <style>
    .address {
      font-size:13px !important;
      color: white;
      text-align:center;
      font-family: "Gill Sans", sans-serif;    
    }
    .address1 {
      font-size:13px !important;
      color: white;
      text-align:center;
      font-family: "Gill Sans", sans-serif;    
    }
    .twitter-share-button {
      font-size:16px !important;
      color: blue;
      image-size: 3px;
      border-radius: 3px;
      background: white;
      text-align:center;
      font-family: "Gill Sans", sans-serif;    
    }
    .twitter-timeline {
      font-size:16px !important;
      color: blue;
      border-radius: 3px;
      background: white;
      text-align:center;
      font-family: "Gill Sans", sans-serif;    
    }
    </style>
     """, unsafe_allow_html=True)

    st.markdown('<p class="empty"></p>', unsafe_allow_html=True)
    st.markdown('<p class="empty"></p>', unsafe_allow_html=True)
    st.markdown('<p class="empty"></p>', unsafe_allow_html=True)
    st.markdown('<input type="image" src="https://twemoji.twitter.com/content/dam/twemoji-twitter/Twitter_Social_Icon_Circle_Color.png.twimg.1920.png" width="25" height="25"/><a href="https://twitter.com/share?ref_src=twsrc%5Etfw" class="twitter-share-button" data-show-count="false">Share on Twitter</a><script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>', unsafe_allow_html=True)
    st.markdown('<input type="image" src="https://twemoji.twitter.com/content/dam/twemoji-twitter/Twitter_Social_Icon_Circle_Color.png.twimg.1920.png" width="25" height="25"/><a class="twitter-timeline" href="https://twitter.com/UWSSEC?ref_src=twsrc%5Etfw">Follow UWSSEC</a> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>', unsafe_allow_html=True)
    st.markdown('<p class="empty"></p>', unsafe_allow_html=True)
    st.markdown('<p class="empty"></p>', unsafe_allow_html=True)
    st.markdown('<p class="empty"></p>', unsafe_allow_html=True)
    st.markdown('<p class="address">Space Science and Engineering Center (SSEC) & University of Wisconsin-Madison</p>', unsafe_allow_html=True)
    st.markdown('<p class="address1">1225 W. Dayton St. Madison, WI 53706</p>', unsafe_allow_html=True)
    st.markdown('<p class="Last"></p>', unsafe_allow_html=True)


def get_oldestDate(paths1):
  st.write(paths1[-1])


#if there is no data for today
def get_latestDate(paths1): 
  return paths1[0]
 

# backend5.py