from collections import defaultdict
import random
import sys

import numpy as np
import matplotlib.pyplot as plt

from weather_model import fft, read_daily, simulate_temp, snowfall_rainfall_model, simulate_precip, simulate_wind_speed
from weather_model import wind_chill_model, wind_chill_transaction_probability, rainfall_transaction_probability
from weather_model import snowfall_transaction_probability, wind_speed_transaction_probability
from weather_model import weather_transaction_probability, autocorr

RECORDS = ["201110", "201111", "201112", "201201", "201202", "201203", "201204", "201205", "201206", "201207", "201208", 
	"201209", "201210", "201211", "201212", "201301", "201302", "201303", "201304", "201305", "201306", "201307", "201308",
	"201309", "201310", "201311", "201312", "201401", "201402", "201403", "201404", "201405", "201406", "201407", "201408",
	"201409"]

def plot_sim_autocorr(flname, temps, sim_temps):
	t_corr = autocorr(temps)
	st_corr = autocorr(sim_temps)
	plt.clf()
	plt.hold(True)
	plt.plot(t_corr, color="c", label="Real")
	plt.plot(st_corr, color="k", label="Simulated")
	plt.legend()
	plt.ylim([-1.0, 1.0])
	plt.xlabel("Time Lag (days)", fontsize=16)
	plt.ylabel("Correlation Coefficient", fontsize=16)
	plt.xlim([0, len(temps)])
	plt.savefig(flname, DPI=300)

def plot_sim_fft(flname, real, simulated):
	real_freq, real_amplitudes, _ = fft(autocorr(real))
	sim_freq, sim_amp, _ = fft(autocorr(simulated))

	n_real_samples = len(real)
	n_sim_samples = len(simulated)
	plt.clf()
	plt.hold(True)
	plt.plot(real_freq[1:(n_real_samples+1)/2], real_amplitudes[1:(n_real_samples+1)/2], color="c", label="Real")
	plt.plot(sim_freq[1:(n_sim_samples+1)/2], sim_amp[1:(n_sim_samples+1)/2], color="k", alpha=0.7, label="Simulated")
	plt.xlabel("Frequency (cycles/day)", fontsize=16)
	plt.ylabel("Amplitude", fontsize=16)
	plt.legend(loc="upper right")
	plt.xlim([0, 0.05])
	plt.savefig(flname, DPI=300)

def plot_sim_vel(flname, vel, sim_vel):
	plt.clf()
	plt.hold(True)
	plt.plot(sim_vel, color="k", label="Simulated")
	plt.plot(vel, color="c", label="Real")
	plt.xlabel("Time (Days)", fontsize=16)
	plt.ylabel("dT/dt (F)", fontsize=16)
	plt.legend()
	plt.xlim([0, len(vel)])
	plt.savefig(flname, DPI=300)

def plot_vel(flname, vel):
	plt.clf()
	plt.plot(vel, color="c")
	plt.xlabel("Time (Days)", fontsize=16)
	plt.ylabel("dT/dt (F)", fontsize=16)
	plt.xlim([0, len(vel)])
	plt.savefig(flname, DPI=300)

def plot_hist_sim_vel(flname, vel, sim_vel):
	plt.clf()
	plt.hold(True)
	bins = np.linspace(-40.0, 40.0, 40.0)
	plt.hist(vel, bins=bins, color="c", label="Real")
	plt.hist(sim_vel, bins=bins, color="k", label="Simulated", alpha=0.7)
	plt.ylabel("Occurrences (Days)", fontsize=16)
	plt.xlabel("dT/dt (F)", fontsize=16)
	plt.legend()
	plt.savefig(flname, DPI=300)

def plot_sim_temps(flname, temps, sim_temps):
	plt.clf()
	plt.hold(True)
	plt.plot(temps, color="c", label="Real")
	plt.plot(sim_temps, color="k", label="Simulated")
	plt.xlabel("Time (Days)", fontsize=16)
	plt.ylabel("Temperature (F)", fontsize=16)
	plt.xlim([0, len(temps)])
	plt.legend(fontsize=14)
	plt.savefig(flname, DPI=300)

def hist_temps(flname, temps, sim_temps):
	plt.clf()
	plt.hold(True)
	bins = np.linspace(-20.0, 100.0, 30.0)
	plt.hist(temps, bins=bins, color="c", label="Real")
	plt.hist(sim_temps, bins=bins, color="k", alpha=0.7, label="Simulated")
	plt.ylabel("Occurrences (Days)", fontsize=16)
	plt.xlabel("Temperature (F)", fontsize=16)
	plt.legend(loc="upper right")
	plt.savefig(flname, DPI=300)

def plot_precip(flname, precip, sim_precip):
	plt.clf()
	plt.hold(True)
	plt.plot(precip[:, 2], color="c", label="Real")
	plt.plot(sim_precip, color="k", label="Simulated")
	plt.xlabel("Time (Days)", fontsize=16)
	plt.ylabel("Total Precipitation (in)", fontsize=16)
	plt.legend()
	plt.savefig(flname, DPI=300)

def plot_hist_precip(flname, precip, sim_precip):
	plt.clf()
	plt.hold(True)

	bins = np.linspace(0.0, 2.0, 20.0)
	plt.hist(precip[:, 2], bins=bins, color="c", label="Real")
	plt.hist(sim_precip, bins=bins, color="k", alpha=0.7, label="Simulated")

	plt.ylabel("Occurrences (Days)", fontsize=16)
	plt.xlabel("Total Precipitation (in)", fontsize=16)
	plt.xlim([0.0, 2.0])
	plt.legend()
	plt.savefig(flname, DPI=300)

def plot_snowfall(flname, precip, sim_snowfall):
	plt.clf()
	plt.hold(True)
	plt.plot(precip[:, 0], color="c", alpha=0.7, label="Real")
	plt.plot(sim_snowfall, color="k", alpha=0.7, label="Simulated")
	plt.xlabel("Time (Days)", fontsize=16)
	plt.ylabel("Snowfall (in)", fontsize=16)
	plt.legend()
	plt.savefig(flname, DPI=300)

def plot_hist_snowfall(flname, precip, sim_snowfall):
	plt.clf()
	plt.hold(True)

	bins = np.linspace(0.0, 16.0, 32.0)
	plt.hist(precip[:, 0], bins=bins, color="c", alpha=0.7, label="Real")
	plt.hist(sim_snowfall, bins=bins, color="k", alpha=0.7, label="Simulated")

	plt.ylabel("Occurrences (Days)", fontsize=16)
	plt.xlabel("Snowfall (in)", fontsize=16)
	#plt.xlim([0.0, 2.0])
	plt.legend()
	plt.savefig(flname, DPI=300)

def plot_rainfall(flname, precip, sim_rainfall):
	plt.clf()
	plt.hold(True)
	plt.plot(precip[:, 1], color="c", alpha=0.7, label="Real")
	plt.plot(sim_rainfall, color="k", alpha=0.7, label="Simulated")
	plt.xlabel("Time (Days)", fontsize=16)
	plt.ylabel("Rainfall (in)", fontsize=16)
	plt.legend()
	plt.savefig(flname, DPI=300)

def plot_hist_rainfall(flname, precip, sim_rainfall):
	plt.clf()
	plt.hold(True)

	bins = np.linspace(0.0, 3.0, 30.0)
	plt.hist(precip[:, 1], bins=bins, color="c", alpha=0.7, label="Real")
	plt.hist(sim_rainfall, bins=bins, color="k", alpha=0.7, label="Simulated")

	plt.ylabel("Occurrences (Days)", fontsize=16)
	plt.xlabel("Rainfall (in)", fontsize=16)
	#plt.xlim([0.0, 2.0])
	plt.legend()
	plt.savefig(flname, DPI=300)

def plot_wind_chill_probability(flname):
	plt.clf()
	temps = np.linspace(-20.0, 90.0, 180.0)
	probability = wind_chill_transaction_probability(temps)
	plt.plot(temps, probability, color="c")
	plt.grid(True)
	plt.xlabel("Wind Chill (F)", fontsize=16)
	plt.ylabel("Probability", fontsize=16)
	plt.ylim([0.0, 1.0])
	plt.legend()
	plt.savefig(flname, DPI=300)

def plot_wind_chill_prob_hist(flname, temps, sim_temps):
	plt.clf()
	plt.hold(True)

	wc_prob = wind_chill_transaction_probability(temps)
	sim_wc_prob = wind_chill_transaction_probability(sim_temps)

	bins = np.linspace(0.0, 1.0, 20.0)
	plt.hist(wc_prob, bins=bins, color="c", label="Real")
	plt.hist(sim_wc_prob, bins=bins, color="k", alpha = 0.7, label="Simulated")

	plt.ylabel("Frequency", fontsize=16)
	plt.xlabel("Probability", fontsize=16)
	plt.xlim([0.0, 1.0])
	plt.grid(True)
	plt.legend(loc="upper left")
	plt.savefig(flname, DPI=300)

def plot_snowfall_trans_prob(flname):
	plt.clf()
	snowfall = np.linspace(0.0, 12.0, 60.0)
	quality = snowfall_transaction_probability(snowfall)
	plt.plot(snowfall, quality, color="c")
	plt.grid(True)
	plt.xlabel("Snowfall (in)", fontsize=16)
	plt.ylabel("Probability", fontsize=16)
	plt.ylim([0.0, 1.0])
	plt.savefig(flname, DPI=300)

def plot_hist_snowfall_trans_prob(flname, precip, sim_snowfall):
	plt.clf()
	plt.hold(True)

	bins = np.linspace(0.0, 1.0, 20.0)
	plt.hist(snowfall_transaction_probability(precip[:, 0]), bins=bins, color="c", alpha=0.7, label="Real")
	plt.hist(snowfall_transaction_probability(sim_snowfall), bins=bins, color="k", alpha=0.7, label="Simulated")

	plt.ylabel("Days (Frequency)", fontsize=16)
	plt.xlabel("Probability", fontsize=16)
	plt.xlim([0.0, 1.0])
	plt.grid(True)
	plt.legend(loc="upper left")
	plt.savefig(flname, DPI=300)

def plot_rainfall_trans_prob(flname):
	plt.clf()
	rainfall = np.linspace(0.0, 6.0, 60.0)
	prob = rainfall_transaction_probability(rainfall)
	plt.plot(rainfall, prob, color="c")
	plt.grid(True)
	plt.xlabel("Rainfall (in)", fontsize=16)
	plt.ylabel("Probability", fontsize=16)
	plt.ylim([0.0, 1.0])
	plt.savefig(flname, DPI=300)

def plot_hist_rainfall_trans_prob(flname, precip, sim_rainfall):
	plt.clf()
	plt.hold(True)

	bins = np.linspace(0.0, 1.0, 20.0)
	plt.hist(rainfall_transaction_probability(precip[:, 1]), bins=bins, color="c", alpha=0.7, label="Real")
	plt.hist(rainfall_transaction_probability(sim_rainfall), bins=bins, color="k", alpha=0.7, label="Simulated")

	plt.ylabel("Days (Frequency)", fontsize=16)
	plt.xlabel("Probability", fontsize=16)
	plt.xlim([0.0, 1.0])
	plt.grid(True)
	plt.legend(loc="upper left")
	plt.savefig(flname, DPI=300)

def plot_scatter_temp_precip(flname, temp, precip, a=0.4, b=27.0):
	plt.clf()
	percent = []
	for snowfall, rainfall, total_precip in precip:
		if total_precip > 0.0:
			percent.append(rainfall / total_precip)
		else:
			percent.append(0.0)
	temp_percent = np.array([(temp, precip) for temp, precip in zip(temp, percent) if precip > 0.0 and precip < 1.0])
	ts = np.linspace(0.0, 60.0, 120.0)
	predicted = [1.0 / (1.0 + np.exp(-a * (T - b))) for T in ts]
	plt.scatter(temp_percent[:, 0], temp_percent[:, 1])
	plt.hold(True)
	plt.plot(ts, predicted)
	plt.ylim([0.0, 1.0])
	plt.xlabel("Temperature (F)", fontsize=16)
	plt.ylabel("Rainfall (% of Precip)", fontsize=16)
	plt.savefig(flname, DPI=300)

def plot_wind_speed(flname, wind_speed, sim_wind_speed=None):
	plt.clf()
	plt.hold(True)
	plt.plot(wind_speed, color="c", label="Real")
	if sim_wind_speed != None:
		plt.plot(sim_wind_speed, color="k", label="Simulated")
	plt.xlabel("Time (Days)", fontsize=16)
	plt.ylabel("Wind Speed (mph)", fontsize=16)
	plt.legend()
	plt.savefig(flname, DPI=300)

def plot_hist_wind_speed(flname, wind_speed, sim_wind_speed=None):
	plt.clf()
	plt.hold(True)

	bins = np.linspace(0.0, 30.0, 30.0)

	plt.hist(wind_speed, bins=bins, color="c", alpha=0.7, label="Real")
	if sim_wind_speed != None:
		plt.hist(sim_wind_speed, bins=bins, color="k", alpha=0.7, label="Simulated")

	plt.ylabel("Occurrences (Days)", fontsize=16)