# -*- coding: utf-8 -*- 
# http://scipy-lectures.github.com


#---------------------------------------------------
#Import důležitých součástí
#---------------------------------------------------
import numpy as np
import scipy as sp
import pylab as plt
from scipy import signal
import matplotlib as mat


SirkaZP = 342
VyskaZP = 258

#---------------------------------------------------
#Funkce na tvorbu matice prvotniho sumu
#---------------------------------------------------
# Vstupem funkce pro tvorbu bázového šumu jsou rozměry zorného pole a frekvence tvořeného šumu 
def TvorbaPodsumu(VyslednaVelikost=[VyskaZP,SirkaZP], Frekvence=0.1): 
    PocatecniVelikost = [0,0]                                         # Definování počáteční matice, která bude roztahována
    for i in range (2):                                               #
        PocatecniVelikost[i]=int(VyslednaVelikost[i]*Frekvence + 0.5) # Matice se roztahuje stejně v obou rozměrech - šířce i výšce
    NahodnePole = sp.rand(PocatecniVelikost[0], PocatecniVelikost[1]) # Vytvoření pole náhodných čísel o požadovaných rozměrech
    Sum2 = NahodnePole
    for i in range(2):    
        Sum2 = signal.resample(Sum2, VyslednaVelikost[i], axis=i)     # Roztáhnutí tohoto pole pomocí funkce "resample"
    return Sum2


#---------------------------------------------------
#Funkce na prahovani
#---------------------------------------------------
def PrahovaniSumu(Sum2,UrovenPrahovani=0.1):     # Pokud uživatel nezadá jinak, bude hodnota prahování 0.1
    Sum2[Sum2<UrovenPrahovani] = UrovenPrahovani # Všem hodnotám pole menším než hodnota prahování je přirozeno číslo hodnoty prahování
    Sum2 = Sum2 - UrovenPrahovani                # Aby byla nejmenší hodnota pole 0, odečte se ode všech pole hodnota prahování
    return Sum2
    
    
#---------------------------------------------------
#Funkce na tvorbu matice vysledneho sumu
#---------------------------------------------------
def TvorbaSumu(VyslednaVelikost=[VyskaZP,SirkaZP], Frekvence=[0.1,0.2,0.4,0.6], UrovenPrahovani=[0.2,0.15,0.12,0.1], VahaSouctu=[4,3,2,1]):
   SoucetVahSouctu = sum(VahaSouctu)    # Zjištění čísla, kterým bude třeba podělit všechny prvky "šumu" po součtu vytvořených polí
   SeznamSumu = []                      # Definování pole, do kterého budou vkládány vytvořené šumy
   for i in range (len(Frekvence)):     # Vytvoření N polí šumu
        SeznamSumu.append(TvorbaPodsumu(VyslednaVelikost, Frekvence=Frekvence[i])) # Zprahovaní těchto polí                                        
        SeznamSumu[i] = PrahovaniSumu(SeznamSumu[i], UrovenPrahovani[i]) # Ohodnocení jednotlivých šumů - kvůli pozdějšímu výpočtu váženého průměru                                     
        SeznamSumu[i] = SeznamSumu[i]*VahaSouctu[i]
   SoucetSumu = 0
   for i in range (len(Frekvence)):
        SoucetSumu = SoucetSumu + SeznamSumu[i]                             # Výpočet váženého
   ZprumerovanySum = SoucetSumu/(float(SoucetVahSouctu))                    # průměru   
   return ZprumerovanySum                                                   # návrat výsledné matice šumu


#---------------------------------------------------
#Tvorba šumu 1 a šumu mu podobnému
#--------------------------------------------------
VahaSouctu1 = [4,3,2,1]                                     # Váhy podšumů u výchozího šumu - šumu 1
VahaSouctu2 = [3,2,1.3,0.7]                                 # Váhy podšumů u přídavného šumu
SoucetVahySouctu1 = sum(VahaSouctu1)                        # Součet vah podšumů u výchozí šumu
SoucetVahySouctu2 = sum(VahaSouctu2)                        # Součet vah podšumů u přídavného šumu
SoucetSouctuVah = SoucetVahySouctu1 + SoucetVahySouctu2     # Součet obou těchto součtů
VV = [VyskaZP, SirkaZP]                                     # Velikost výsledného šumu

#Tvorba výchozího šumu
VychoziSum = TvorbaSumu(VyslednaVelikost=VV, Frekvence=[0.1,0.2,0.4,0.6], UrovenPrahovani=[0.2,0.15,0.12,0.1], VahaSouctu=VahaSouctu1)
NejvetsiPrvek = np.max(VychoziSum)          # Zjištění jeho největší hodnoty - chceme hodnoty normovat
VychoziSum = VychoziSum/NejvetsiPrvek       # Normování výchozího šumu na 1

#Tvorba přídavného šumu
PridavnySum = TvorbaSumu(VyslednaVelikost=VV, Frekvence=[0.1,0.2,0.4,0.6], UrovenPrahovani=[0.2,0.15,0.12,0.1], VahaSouctu=VahaSouctu2)

# Trorba upraveného šumu
UpravenySum = (SoucetVahySouctu1*VychoziSum+SoucetVahySouctu2*PridavnySum)/SoucetSouctuVah
UpravenySum = PrahovaniSumu(UpravenySum, 0.1)   # Zprahování upraveného šumu
NejvetsiPrvek = np.max(UpravenySum)             # Zjištění jeho největší hodnoty - chceme hodnoty normovat
UpravenySum = UpravenySum/NejvetsiPrvek         # Normování upraveného šumu na 1


#---------------------------------------------------------------------------
#Funkce pro vyvolání šumu v čase - kdykoli mezi výchozím šumem a šumem upraveným
#---------------------------------------------------------------------------
PocatecniCas = 0
KoncovyCas = 1
NasCas = 0.3

def SumVCase(Cas=NasCas, PocatecniSum=VychoziSum, KoncovySum=UpravenySum):  # Funkce na volání šumu v čase
   VahaPocatecnihoSumu = KoncovyCas - Cas               # Zjištění, jak moc bude při sčítání důležitý počáteční šum
   VahaKoncovehoSumu = Cas - PocatecniCas               # a jak moc koncový šum
   PocatecniSum = PocatecniSum * VahaPocatecnihoSumu
   KoncovySum = KoncovySum * VahaKoncovehoSumu  
   SumVCase = (PocatecniSum + KoncovySum)/(KoncovyCas-PocatecniCas)         # Výpočet šumu v čase
   SumVCase = PrahovaniSumu(SumVCase)
   NejvetsiPrvek = np.max(SumVCase)                     # a jeho normování k 1.
   SumVCase = SumVCase/float(NejvetsiPrvek)    
   return SumVCase                                      # Výstupem je normovaný šum v čase