#!/usr/bin/ python3
#TODO EVERYTIME THERE ARE ACTUAL CHANGES, RERUN THE INSTALL COMMAND TO MAKE IT ACTUALLY WORK AS A UNIX COMMAND. ALSO CHANGE THE IMPORT TO "from . "
import argparse
from . import KnownMotif
#import KnownMotif
import os
from pyfaidx import Fasta
import sys
import math
import argparse
import random

genome = None
nucs = {"A": 0, "C": 1, "G": 2, "T": 3}

class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKCYAN = '\033[96m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'

def ERROR(msg):
	"""
	Print an error message and die

	Parameters
	----------
	msg : str
	   Error message to print
	"""
	sys.stderr.write(bcolors.FAIL + "[ERROR]: " + bcolors.ENDC + "{msg}\n".format(msg=msg) )
	sys.exit(1)

def sysMessage(message):
    sys.stdout.write(bcolors.OKCYAN + message + bcolors.ENDC)

def writeMessage(str, output_file = sys.stdout):
    output_file.write(str)

def main():
    parser = argparse.ArgumentParser(
		prog="mrsoftware",
		description="Command-line script to perform  motif recognition from BED file"
	)

	# Input files
        # input Bed File
    parser.add_argument("bed", help="path to .BED file with the peaks", type=str)
        # input meme file of known motifs
    parser.add_argument("-m", "--meme", help="path to .meme file containing nucleotide probability matrices for motifs to test for enrichment", type=str, metavar="FILE", required=True)
        # input the reference genome to use
    parser.add_argument("-g","--genome", help="Path to the reference genome that peaks will be pulled from", type=str, metavar="FILE", required=True)

	# Output file to write to
    parser.add_argument("-o", "--out", help="Write output to file. Default: stdout", metavar="FILE", type=str, required=False)

	# Other options
    #parser.add_argument("--version", help="Print the version and quit", action="version", version = '{version}'.format(version=__version__))

    # Parse args
    args = parser.parse_args()

	# Set up output file
    if args.out is None:
        outf = sys.stdout
    else:
        outf = open(args.out, "w")

    #Check file integrity
    sysMessage("Initializing by checking argument validity\n")
    # genome
    if args.genome is not None:
        if not os.path.exists(args.genome):
            ERROR("{genome} does not exist".format(genome=args.genome))
        genome_path = args.genome
        global genome
        genome = Fasta(genome_path)
    else:
        ERROR("Path to Genome not provided :O")
        print(":(")
        return # Just quit and give up

    # meme
    if args.meme is not None:
        if not os.path.exists(args.meme):
            ERROR("{meme} does not exist".format(meme=args.meme) )
        meme_path = args.meme
    else:
        ERROR("Path to meme file not provided >:(")
        return # Just quit and give up

    # bed
    if args.bed is not None:
        if not os.path.exists(args.bed):
            ERROR("{bed} does not exist".format(meme=args.bed) )
        bed_path = args.bed
    else:
        ERROR("Path to bed file not provided :(")
        return # Just quit and give up

    out_file = None
    if args.out is not None:
        out_file = open(args.out, 'w')
    else:
        out_file = sys.stdout

    #~~~~~~~~~~~~~~~~~~~~~~~ BEGIN PIPELINE ~~~~~~~~~~~~~~~~~~~~~~~~#
    #get the sequences of all the peaks
    writeMessage("Optimizing for provided .fa")
    needs_chr = determineIfNeedCHR(genome_path)
    writeMessage("Needs to add \"chr\" is " + str(needs_chr) + "\n")

    writeMessage("Getting peak sequences\n")
    writeMessage("Collecting random sequences from the genome\n")
    peak_seq_list, random_background_seqs_list = getListOfPeakSeqFromBed(bed_path, need_chr = needs_chr)
    writeMessage("There are " + str(len(peak_seq_list)) + " peaks. \n")
    writeMessage("We are using " + str(len(random_background_seqs_list)) + " random sequences\n")

    # Get motifs
    writeMessage("Calculating random backgrounds\n")
    backgroundFreqs = calculateBackgroundFrequencies(random_background_seqs_list)
    writeMessage("Background frequency is: " + str(backgroundFreqs) + "\n")
    writeMessage("Motifs from the meme file\n")
    known_motifs = makeKnownMotifObjs(meme_path, backgroundFreqs)
    writeMessage("We are using " + str(len(known_motifs)) + " motifs\n")
    writeMessage("Creating new randomly generated sequences\n")
    amount = len(peak_seq_list)
    length_of_random = len(peak_seq_list[0])
    random_generated_seqs_list = createArrOfRandomlyGeneratedSeqs(amount, backgroundFreqs, length_of_random)
    writeMessage("Done creating " + str(amount) + " random sequenceis of length " + str(length_of_random) +"\n")
    for motif in known_motifs:
        if motif != None:
            motif.scoreAllGetThresholdScoreCalcPValue(peak_seq_list, random_generated_seqs_list) #MAKE THE PWM SOON

    known_motifs.sort(key = KnownMotif.KnownMotif.getPval)
    for motif in known_motifs:
        writeMessage(str(motif) + "\n", output_file=out_file)
    #returnMotifsWithLowestPval(known_motifs, 4)
    sysMessage("DONE :] \n\n")
    out_file.close()

def determineIfNeedCHR(genome_path):
    """
    returns True if you need to add "chr" to the chromosome name
    """
    file = open(genome_path + ".fai")
    if str.isdigit(file.readline().split("\t")[0]):
        return False
    return True

def generateRandomSeqsFromChr(chr, num, length):
    """
    Get <num> random sequences from chromosome <chr>

    Parameters:
    -----------
        chr: Chromosome to get the sequence from
        num: How many to get
        length:

    Returns:
    --------
        backgroundSeqs:
    """
    backgroundSeqs = []
    for i in range(num):
        toAdd = getRandomBackgroundSeq(chr, length)
        if toAdd != None:
            backgroundSeqs.append(toAdd)
    return backgroundSeqs

def returnMotifsWithLowestPval(motif_array, num_of_motifs):
    """
    will return the top motifs with the lowest p values

    Parameters:
    -----------
        motif_array: list of arrays
        num_of_motifs: number of top motifs to return

    Returns:
    --------
        list of top motifs (length num_of_motifs)

    """
    sorted_motifs = motif_array[0]
    #motif_array.sort(key = KnownMotif.KnownMotif.getPval)
    i = 0
    while i < len(motif_array):
        j = 0
        while j < len(sorted_motifs):
            if motif_array[i].getPval < sorted_motifs[j].getPval:
                sorted_motifs.insert(j, motif_array[i])
                break
            j+=1
        if j == len(sorted_motifs):
            sorted_motifs.append(motif_array[i])
        i+=1
    return sorted_motifs[:num_of_motifs]

def randomSeqFromFrequencies(frequencies, length):
    """
    Given the frequencies and desiered length, generate a random sequence to fit the request.
    """
    sequence = ""
    nuceleotides = ["A", "C", "G", "T"]
    for i in range(length):
        sequence += random.choices(nuceleotides,weights=frequencies)[0]
    return sequence

def createArrOfRandomlyGeneratedSeqs(num, frequencies,length):
    """
    Given a number of sequences to generate, the frequencies at which those appear, and the length of the sequence, return an array of sequences
    """
    return [randomSeqFromFrequencies(frequencies, length) for i in range(num)]

def getSeqFromGenome(chromosome, start, end):
    """
    Returns sequence of peak from genome

    Parameters:
    ------------
    chromosome : string (what chromosome number)
    start: int (start of peak)
    end: int (end of peak)

    Returns:
    string of nucleotides
    """

    #genes = Fasta(genome)
    #chromosome = str(chromosome).removeprefix("chr")
    if chromosome in genome: # if chromosome is in the same format as the indexing
        return str(genome[chromosome][start:end])
    elif ("chr"+str(chromosome)) in genome: # if you need to add "chr" to the chromosome number to get it to match
        return str(genome["chr"+str(chromosome)][start:end])
    else:
        print("CHROMOSOME NOT FOUND!!!!! in getSeqFromGenome >:[ Params were: " + str(chromosome) +" at "+ str(start) +":"+ str(end)) # TODO CHANGE THIS to a REAL ERROR Rather than this print

def getPeaksFromBed(bed_path):
    """
    Helper function
    Returns a list of locations of peaks in the format {chr, start, stop} from a bed file containing peaks

    Description

    Parameters:
    -----------
        bed_path : path to the bed file

    Returns:
    --------
        peaks: list of locations of peaks in the format {chr, start, stop}

    """
    peaks = []
    file = open(bed_path)
    for line in file.readlines():
        if '#' not in line:
            peaks.append(line.split('\t')[0:3])

    file.close()
    return peaks

def getListOfPeakSeqFromBed(bed_path, need_chr = True):
    """
    Returns a list of all the peak sequences
    Calls getPeaksFromBed

    Parameters:
    -----------
        bed_path : path to the bed file

    Returns:
    --------
        peak_list : list of peaks (nucleotide sequence)
        random_seq_list : list of random ones from that genome
    """
    peak_list = []
    random_list = []
    ent_list = getPeaksFromBed(bed_path)
    has_chr = "chr" in ent_list[0][0]
    print("There are " + str(len(ent_list)) + " peaks")
    for ent in ent_list:
        if need_chr and has_chr: # can go ahead and access easily
            temp_seq = getSeqFromGenome(ent[0], int(ent[1]), int(ent[2]))
            temp_rand = getRandomBackgroundSeq(ent[0], int(ent[2])-int(ent[1]))
        elif need_chr and not has_chr: # needs chr but doesnt have chr already, must add chr
            temp_seq = getSeqFromGenome("chr"+ent[0], int(ent[1]), int(ent[2]))
            temp_rand = getRandomBackgroundSeq("chr"+ent[0], int(ent[2])-int(ent[1]))
        elif not need_chr and has_chr: # doesnt need chr but has chr, must remove chr
            temp_seq = getSeqFromGenome(ent[0][3:], int(ent[1]), int(ent[2]))
            temp_rand = getRandomBackgroundSeq(ent[0][3:], int(ent[2])-int(ent[1]))
        else: # doesnt need and doesnt have
            temp_seq = getSeqFromGenome(ent[0], int(ent[1]), int(ent[2]))
            temp_rand = getRandomBackgroundSeq(ent[0], int(ent[2])-int(ent[1]))
        if temp_seq != None: # will be None if the chromosome isnt available
            peak_list.append(str(temp_seq)) # add the string of the sequence
            random_list.append(str(temp_rand))
    return peak_list, random_list

def makeKnownMotifObjs(meme_path, background_freqs):
    """
    makes list of KnownMotif objects from the meme file

    Parameters:
    -----------
        meme_path : path to the meme file

    Returns:
    --------
        known_motifs_list : list of known motifs
    """
    known_motifs_list = []
    file = open(meme_path)
    lines = file.readlines()
    i = 0
    while i < len(lines):
        if 'MOTIF' in lines[i]:
            pwm_index_start = 0
            if 'letter-probability matrix' not in lines[i+1]: # empty line in case motif doesnt start yet
                pwm_index_start = i+3
            else:
                pwm_index_start = i+2
            name = lines[i][6:].strip() # name of the motif
            alength = 4
            w_str = 'w= '
            w_index =  lines[pwm_index_start-1].index(w_str)
            nsites_index = lines[pwm_index_start-1].index(' nsites')
            w = int(lines[pwm_index_start-1][w_index + len(w_str) : nsites_index])
            j = pwm_index_start
            k = 0
            temp_pwm = [[0 for i in range(w)] for j in range(alength)]
            while j < len(lines):
                if 'URL' in lines[j] or len(lines[j]) == 0:
                    break
                temp_line = lines[j].split()
                if len(temp_line) == 0:
                    break
                pseudocount = 0.00001

                A_val = math.log2(float(temp_line[0].strip())/background_freqs[0]+pseudocount)
                C_val = math.log2(float(temp_line[1].strip())/background_freqs[1]+pseudocount)
                G_val = math.log2(float(temp_line[2].strip())/background_freqs[2]+pseudocount)
                T_val = math.log2(float(temp_line[3].strip())/background_freqs[3]+pseudocount)

                temp_pwm[0][k] = float(A_val)
                temp_pwm[1][k] = float(C_val)
                temp_pwm[2][k] = float(G_val)
                temp_pwm[3][k] = float(T_val)
                k+=1
                j+=1
            i = j

            known_motifs_list.append(KnownMotif.KnownMotif(name, alength, w, temp_pwm))
        i+=1
    return known_motifs_list

def calculateBackgroundFrequencies(background_seqs):
    freqs = [0,0,0,0] # compute frequency of A, C, G, T
    counts = [0,0,0,0]
    for seq in background_seqs:
        temp_seq = str(seq)
        counts[0] += temp_seq.count("A")
        counts[1] += temp_seq.count("C")
        counts[2] += temp_seq.count("G")
        counts[3] += temp_seq.count("T")
    total =  sum(counts)
    for i in range(len(freqs)):
        freqs[i] = counts[i]/total
    return freqs

def getRandomBackgroundSeq(chr, length):
    """
    Given a chromosome, get a random sequence of that length

    Parameters:
    -----------
        chr: chromosome number of random seq
        length: length of random seq that will be generated

    Returns:
    --------
        str: the sequence of nucleotides
    """
    length_of_chromosome = -1
    if chr in genome: # if chromosome is in the same format as the indexing
        length_of_chromosome = len(genome[chr])
    elif ("chr"+str(chr)) in genome: # if you need to add "chr" to the chromosome number to get it to match
        length_of_chromosome = len(str(genome["chr"+str(chr)]))
    elif str(chr).removeprefix("chr") in genome: # if you need to remove "chr" from the chromosome name to get it to match the index
        length_of_chromosome = len(str(genome[str(chr).removeprefix("chr")]))
    else:
        print("CHROMOSOME NOT FOUND!!!!! >:[ ") # TODO CHANGE THIS to a REAL ERROR Rather than this print
    start = random.randint(0, length_of_chromosome-length)
    return getSeqFromGenome(chr, start, start + length)

def generateListOfRandomSeqsFromPeaks(peaks_info):
    """
    Creates a list of random sequences from function getPeaksFromBed

    Parameters:
    -----------
    peaks_info:
        list of known motifs

    Returns:
    --------

    """

    #peaks_info from getPeaksFromBed
    random_seqs = []
    for ent in peaks_info:
        length = int(ent[2])-int(ent[1])
        chr = ent[0]
        random_seqs.append(getRandomBackgroundSeq(chr,length))
    return random_seqs

# Run Main
if __name__ == "__main__":
    main()


from background_task import background
from newjw.sharedoc.forms import sharePostForm, shareUserForm, shareDataCollectionForm, shareExcelJsonDataForm
from newjw.sharedoc.models import post, user, data_collection, excel_json_data

def sharePostSave(*args, **kwargs):
    shareArr = args[0]
    form = sharePostForm(shareArr)

    if form.is_valid():
        record = form.save()
        return record.id

    return 0

# @background(schedule=1)
def shareExcelJsonDataSave(*args, **kwargs):
    shareArrJsonLoad = args[0]
    shareExcelform = shareExcelJsonDataForm(shareArrJsonLoad)

    if shareExcelform.is_valid():
        shareExcelform.save()

@background(schedule=1)
def shareDataCellSave(*args, **kwargs):

    id = args[0]
    excelJsonData = args[1]

    #데이터 셀 저장
    listexcelJsonData = list(excelJsonData)
    cell_row = 0
    cell_line = 0

    for forData in listexcelJsonData[0] :
        cell_row = cell_row+1
        cell_line = 0

        for rs in forData :

            cell_line = cell_line+1
            cell_type = "cell"
            if cell_row == 1 or cell_row == 2 :
                cell_type = "header"

            arrDataCollection = {"post":id,"cell_row":cell_row,"cell_line":cell_line,"data":rs,"cell_type":cell_type}
            formDataCollection = shareDataCollectionForm(arrDataCollection)

            if formDataCollection.is_valid():
                formDataCollection.save()


import requests

# caching is provided accross the system as opposed to as a separate module
# thus the caching module has little code
# nonetheless here I provide methods to aid in client side caching

def is_stale_file(file_server_addr, file_id, user_id, sessions_mgr):
    r = requests.get(file_server_addr, params=sessions_mgr.encrypt_msg({
            'operation': 'poll',
            'file_id': file_id,
            'user_id': user_id
            }, 'file server'))
    res = sessions_mgr.decrypt_msg(r.json(), 'file server')

    return res.get('is_stale_copy')


from __future__ import print_function
from six.moves import range
from PIL import Image

import torch.backends.cudnn as cudnn
import torch
import torch.nn as nn
from torch.autograd import Variable
import torch.optim as optim
import os
import time
import pdb
import numpy as np
import torchfile

from miscc.config import cfg
from miscc.utils import mkdir_p
from miscc.utils import weights_init
from miscc.utils import save_story_results, save_model
from miscc.utils import KL_loss
from miscc.utils import compute_discriminator_loss, compute_generator_loss, save_test_samples

from shutil import copyfile

class GANTrainer(object):
    def __init__(self, output_dir, ratio = 1.0, test_dir = None):
        self.model_dir = os.path.join(output_dir, 'Model')
        self.image_dir = os.path.join(output_dir, 'Image')
        self.log_dir = os.path.join(output_dir, 'Log')
        mkdir_p(self.model_dir)
        mkdir_p(self.image_dir)
        mkdir_p(self.log_dir)
        self.video_len = cfg.VIDEO_LEN
        self.max_epoch = cfg.TRAIN.MAX_EPOCH
        self.snapshot_interval = cfg.TRAIN.SNAPSHOT_INTERVAL
        self.test_dir = test_dir
        s_gpus = cfg.GPU_ID.split(',')
        self.gpus = [int(ix) for ix in s_gpus]
        self.num_gpus = len(self.gpus)
        self.imbatch_size = cfg.TRAIN.IM_BATCH_SIZE * self.num_gpus
        self.stbatch_size = cfg.TRAIN.ST_BATCH_SIZE * self.num_gpus
        self.ratio = ratio
        torch.cuda.set_device(self.gpus[0])
        cudnn.benchmark = True

    # ############# For training stageI GAN #############
    def load_networks(self):
        from model import StoryGAN, D_IMG, D_STY
        netG = StoryGAN(self.video_len)
        netG.apply(weights_init)
        print(netG)
        netD_im = D_IMG()
        netD_im.apply(weights_init)
        netD_st = D_STY()
        netD_st.apply(weights_init)
        print(netD_im)
        print(netD_st)

        if cfg.NET_G != '':
            state_dict = \
                torch.load(cfg.NET_G,
                           map_location=lambda storage, loc: storage)
            netG.load_state_dict(state_dict)
            print('Load from: ', cfg.NET_G)
        if cfg.NET_D != '':
            state_dict = \
                torch.load(cfg.NET_D,
                           map_location=lambda storage, loc: storage)
            netD.load_state_dict(state_dict)
            print('Load from: ', cfg.NET_D)
        if cfg.CUDA:
            netG.cuda()
            netD_im.cuda()
            netD_st.cuda()
        return netG, netD_im, netD_st

    def sample_real_image_batch(self):
        if self.imagedataset is None:
            self.imagedataset = enumerate(self.imageloader)
        batch_idx, batch = next(self.imagedataset)
        b = batch
        if cfg.CUDA:
            for k, v in batch.items():
                if k == 'text':
                    continue
                else:
                    b[k] = v.cuda()

        if batch_idx == len(self.imageloader) - 1:
            self.imagedataset = enumerate(self.imageloader)
        return b

    def train(self, imageloader, storyloader, testloader):
        self.imageloader = imageloader
        self.testloader = testloader
        self.imagedataset = None
        self.testdataset = None
        netG, netD_im, netD_st = self.load_networks()

        im_real_labels = Variable(torch.FloatTensor(self.imbatch_size).fill_(1))
        im_fake_labels = Variable(torch.FloatTensor(self.imbatch_size).fill_(0))
        st_real_labels = Variable(torch.FloatTensor(self.stbatch_size).fill_(1))
        st_fake_labels = Variable(torch.FloatTensor(self.stbatch_size).fill_(0))
        if cfg.CUDA:
            im_real_labels, im_fake_labels = im_real_labels.cuda(), im_fake_labels.cuda()
            st_real_labels, st_fake_labels = st_real_labels.cuda(), st_fake_labels.cuda()

        generator_lr = cfg.TRAIN.GENERATOR_LR
        discriminator_lr = cfg.TRAIN.DISCRIMINATOR_LR

        lr_decay_step = cfg.TRAIN.LR_DECAY_EPOCH
        im_optimizerD = \
            optim.Adam(netD_im.parameters(),
                       lr=cfg.TRAIN.DISCRIMINATOR_LR, betas=(0.5, 0.999))

        st_optimizerD = \
            optim.Adam(netD_st.parameters(),
                       lr=cfg.TRAIN.DISCRIMINATOR_LR, betas=(0.5, 0.999))

        netG_para = []
        for p in netG.parameters():
            if p.requires_grad:
                netG_para.append(p)
        optimizerG = optim.Adam(netG_para, lr=cfg.TRAIN.GENERATOR_LR,
                                betas=(0.5, 0.999))

        for epoch in range(self.max_epoch):
            start_t = time.time()
            if epoch % lr_decay_step == 0 and epoch > 0:
                generator_lr *= 0.5
                for param_group in optimizerG.param_groups:
                    param_group['lr'] = generator_lr
                discriminator_lr *= 0.5
                for param_group in st_optimizerD.param_groups:
                    param_group['lr'] = discriminator_lr
                for param_group in im_optimizerD.param_groups:
                    param_group['lr'] = discriminator_lr

            for i, data in enumerate(storyloader, 0):
                ######################################################
                # (1) Prepare training data
                ######################################################
                im_batch = self.sample_real_image_batch()
                st_batch = data

                im_real_cpu = im_batch['images']
                im_motion_input = im_batch['description']
                im_content_input = im_batch['content']
                im_content_input = im_content_input.mean(1).squeeze()
                im_catelabel = im_batch['label']
                im_real_imgs = Variable(im_real_cpu)
                im_motion_input = Variable(im_motion_input)
                im_content_input = Variable(im_content_input)

                st_real_cpu = st_batch['images']
                st_motion_input = st_batch['description']
                st_content_input = st_batch['description']
                st_catelabel = st_batch['label']
                st_real_imgs = Variable(st_real_cpu)
                st_motion_input = Variable(st_motion_input)
                st_content_input = Variable(st_content_input)

                if cfg.CUDA:
                    st_real_imgs = st_real_imgs.cuda()
                    im_real_imgs = im_real_imgs.cuda()
                    st_motion_input = st_motion_input.cuda()
                    im_motion_input = im_motion_input.cuda()
                    st_content_input = st_content_input.cuda()
                    im_content_input = im_content_input.cuda()
                    im_catelabel = im_catelabel.cuda()
                    st_catelabel = st_catelabel.cuda()
                #######################################################
                # (2) Generate fake stories and images
                ######################################################

                im_inputs = (im_motion_input, im_content_input)
                #_, im_fake, im_mu, im_logvar = \
                #    nn.parallel.data_parallel(netG.sample_images, im_inputs, self.gpus)
                # _, im_fake, im_mu, im_logvar = netG.sample_images(im_motion_input, im_content_input)
                _, im_fake, im_mu, im_logvar =netG.sample_images(im_motion_input, im_content_input)

                st_inputs = (st_motion_input, st_content_input)
                #_, st_fake, c_mu, c_logvar, m_mu, m_logvar = \
                #    nn.parallel.data_parallel(netG.sample_videos, st_inputs, self.gpus)
                # _, st_fake, c_mu, c_logvar, m_mu, m_logvar = netG.sample_videos(st_motion_input, st_content_input)
                _, st_fake, c_mu, c_logvar, m_mu, m_logvar=netG.sample_videos( st_motion_input, st_content_input)

                ############################
                # (3) Update D network
                ###########################
                netD_im.zero_grad()
                netD_st.zero_grad()

                im_errD, im_errD_real, im_errD_wrong, im_errD_fake, accD = \
                    compute_discriminator_loss(netD_im, im_real_imgs, im_fake,
                                               im_real_labels, im_fake_labels, im_catelabel,
                                               im_mu, self.gpus)

                st_errD, st_errD_real, st_errD_wrong, st_errD_fake, _ = \
                    compute_discriminator_loss(netD_st, st_real_imgs, st_fake,
                                               st_real_labels, st_fake_labels, st_catelabel,
                                               c_mu, self.gpus)

                im_errD.backward()
                st_errD.backward()

                im_optimizerD.step()
                st_optimizerD.step()

                ############################
                # (2) Update G network
                ###########################
                for g_iter in range(2):
                    netG.zero_grad()

                    _, st_fake, c_mu, c_logvar, m_mu, m_logvar = netG.sample_videos(
                        st_motion_input, st_content_input)

                    # st_mu = m_mu.view(cfg.TRAIN.ST_BATCH_SIZE, cfg.VIDEO_LEN, m_mu.shape[1])
                    # st_mu = st_mu.contiguous().view(-1, cfg.VIDEO_LEN * m_mu.shape[1])

                    _, im_fake, im_mu, im_logvar = netG.sample_images(im_motion_input, im_content_input)

                    im_errG, accG = compute_generator_loss(netD_im, im_fake,
                                                  im_real_labels, im_catelabel, im_mu, self.gpus)
                    st_errG, _ = compute_generator_loss(netD_st, st_fake,
                                                  st_real_labels, st_catelabel, c_mu, self.gpus)
                    im_kl_loss = KL_loss(im_mu, im_logvar)
                    st_kl_loss = KL_loss(m_mu, m_logvar)
                    errG = im_errG + self.ratio * st_errG

                    kl_loss = im_kl_loss + self.ratio * st_kl_loss
                    errG_total = im_errG + self.ratio * st_errG + kl_loss
                    errG_total.backward()
                    optimizerG.step()

                if i % 100 == 0:
                    # save the image result for each epoch
                    lr_fake, fake, _, _, _, _ = netG.sample_videos(st_motion_input, st_content_input)
                    save_story_results(st_real_cpu, fake, epoch, self.image_dir)
                    if lr_fake is not None:
                        save_story_results(None, lr_fake, epoch, self.image_dir)

            end_t = time.time()
            print('''[%d/%d][%d/%d] Loss_D: %.4f Loss_G: %.4f
                     Loss_real: %.4f Loss_wrong:%.4f Loss_fake %.4f
                     accG: %.4f accD: %.4f
                     Total Time: %.2fsec
                  '''
                  % (epoch, self.max_epoch, i, len(storyloader),
                     st_errD.data, st_errG.data,
                     st_errD_real, st_errD_wrong, st_errD_fake, accG, accD,
                     (end_t - start_t)))

            if epoch % self.snapshot_interval == 0:
                save_model(netG, netD_im, netD_st, epoch, self.model_dir)
                save_test_samples(netG, self.testloader, self.test_dir)
        #
        save_model(netG, netD_im, netD_st, self.max_epoch, self.model_dir)
    #


from django.urls import path
from . import views

app_name='cart'

urlpatterns=[
    path('',views.cart,name='cart'),
    path('checkout/',views.check_out,name='checkout'),
    path('update_cart/<int:product_id>/<str:action>/',views.update_cart,name='update_cart'),
    path('add_to_cart/<int:product_id>/',views.add_to_cart,name='add_to_cart'),
    path('hx_menu_cart/',views.hx_menu_cart,name='hx_menu_cart'),
    path('hx_cart_total/',views.hx_cart_total,name='hx_cart_total')
]


class Settings:

    def __init__(self):
        # settings for the game's window size and background color
        self.screen_width = 1920
        self.screen_height = 1080
        self.bg_color = (230, 230, 230)
        # setting for ship's speed
        self.ship_speed = 1.5
        # settings for bullets
        self.ship_limit = 3
        self.bullet_speed = 1.5
        self.bullet_width = 3
        self.bullet_height = 15
        self.bullet_color = (60, 60, 60)
        self.bullets_allowed = 5
        self.alien_speed = 1.0
        self.fleet_drop_speed = 10
        self.fleet_direction = 1


# -*- coding: utf-8 -*-

"""This module contains utilities to call the Lydia tool from Python."""
import glob
import os
from pathlib import Path

def _get_latest_model(path: Path):
    """Get the Rasa latest model."""
    if not path:
        return None
    list_of_files = glob.glob(os.path.join(path, "*.tar.gz"))
    if len(list_of_files) == 0:
        return None
    return max(list_of_files, key=os.path.getctime)


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Fri Apr 22 09:58:47 2022

@author: lucas
"""

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import xarray as xr
import geopandas as gpd

#%%
# =============================================================================
# maipo
# =============================================================================

H0_mm = pd.read_csv('datos/stodomingo/isoterma0.csv',
                    index_col=0)
H0_mm.index = pd.to_datetime(H0_mm.index)-pd.Timedelta(hours=4)

SL_mm = pd.read_csv('datos/snowlimits_maipomanzano.csv',index_col=0)
SL_mm.index = pd.to_datetime(SL_mm.index)

SCA_mm = pd.read_csv('datos/snowcovers_maipomanzano.csv',index_col=0)
SCA_mm.index = pd.to_datetime(SCA_mm.index)

datos_dgf = pd.read_csv('datos/estaciones/dgf/DATOSUTC_2004-2019.csv',index_col=0)
datos_dgf.index = pd.to_datetime(datos_dgf.index)-pd.Timedelta(hours=4)

pr_dgf = datos_dgf.iloc[:,9]

#%%
# =============================================================================
# basins
# =============================================================================
from glob import glob
names = glob('datos/era5/horarias/*.csv')
names = [n.split("/")[-1].split("_")[1] for n in names]
H0_era5 = [pd.read_csv(p,index_col=0) for p in glob('datos/era5/horarias/*.csv')]
H0_era5 = pd.concat(H0_era5,axis=1)
H0_era5.index = pd.to_datetime(H0_era5.index)-pd.Timedelta(hours=4)
H0_era5.columns = names

basins = names
#%%
names = glob('datos/estaciones/dga/qinst_*.csv')
names = [n.split("/")[-1].split("_")[1].split(".")[0] for n in names]
runoff = [pd.read_csv(p,index_col=0) for p in glob('datos/estaciones/dga/qinst_*.csv')]
runoff = pd.concat(runoff,axis=1)
runoff.index = pd.to_datetime(runoff.index)
runoff.columns = names
runoff['RioMauleEnArmerillo'] = runoff.RioMeladoEnElSalto
runoff = runoff[basins]

#%%
names = glob('datos/topography/basins/hypso/*.csv')
hypso = [pd.read_csv(p) for p in names]

names = [n.split("/")[-1].split("_")[0].split(".")[0] for n in names]
hypso = pd.concat(hypso,axis=1,keys=names).T
hypso = hypso.loc[basins]

#%%
from scipy.interpolate import interp1d
int_func = [interp1d(hypso.loc[b].T.height,hypso.loc[b].T.fArea)
            for b in basins]
int_func = pd.Series(int_func,index=basins)

pluv_area = [int_func.loc[b](H0_era5[b]-300) for b in basins]
pluv_area = pd.DataFrame(pluv_area,columns=H0_era5.index,index=basins).T
#%%
names = glob('datos/ianigla/*_SCA_*.csv')
SCA = [pd.read_csv(p,index_col=0).iloc[:,1] for p in names]

names = [n.split("/")[-1].split("_")[0].split(".")[0] for n in names]
SCA = pd.concat(SCA,axis=1,keys=names).T
SCA.columns = pd.to_datetime(SCA.columns)
SCA = SCA.loc[basins].T.dropna()
SCA = SCA.resample('h').interpolate('cubicspline')

#%%
names = glob('datos/estaciones/cr2met/pr*.csv')
pr_cr2met = [pd.read_csv(p,index_col=0) for p in names]
names = [n.split("/")[-1].split("_")[1].split(".")[0] for n in names]
pr_cr2met = pd.concat(pr_cr2met,axis=1)
pr_cr2met.columns = basins
pr_cr2met.index = pd.to_datetime(pr_cr2met.index)
pr_cr2met = pr_cr2met.resample('h').ffill()/24
# pr_cr2met = pr_cr2met.reindex(SCA.index)q
#%%
pluv_area = pluv_area.where(pr_cr2met>10/24)
ros_area = SCA/100-(1-pluv_area)
ros_area = ros_area.where(ros_area>0).where(pr_cr2met>10/24)

#%%
from scipy.ndimage import gaussian_filter

interval = slice("2008-06-02","2008-06-06")

cuenca = gpd.read_file('datos/vector/basins/mains/RioMaipoEnElManzano.shp')
dem = xr.open_dataset('datos/topography/basins/RioMaipoEnElManzano.nc')

fig,ax = plt.subplots(1,1,sharex=True,sharey=True)

# for axis in [ax]:
ax.axis('off')
cuenca.boundary.plot(ax=ax,color='k')

ax.contourf(dem.lon,dem.lat,dem.Band1,colors='royalblue',
               levels=[SL_mm.IANIGLA_HYPSO["2008-06-02"],
                       7000])

ax.contourf(dem.lon,dem.lat,dem.Band1,colors='tab:red',
               levels=[0,
                       H0_mm.squeeze().resample('d').mean()["2008-06-03":"2008-06-04"].mean()-300])

ax.contourf(dem.lon,dem.lat,dem.Band1,colors='cadetblue',
               levels=[SL_mm.IANIGLA_HYPSO["2008-06-02"],
                       H0_mm.squeeze().resample('d').mean()["2008-06-03":"2008-06-04"].mean()-300])

ax.scatter([],[],color='royalblue',marker='s',label='Snow area')
ax.scatter([],[],color='tab:red',marker='s',label='Pluvial area')
ax.scatter([],[],color='cadetblue',marker='s',label='ROS area')
ax.scatter([],[],color='gold',marker='s',label='Melted area')
ax.legend(frameon=False,loc=(1,0.5))

# ax[1].contourf(dem.lon,dem.lat,dem.Band1,colors='royalblue',
#                levels=[SL_mm.IANIGLA_HYPSO["2008-06-06"],
#                        7000])
ax.contourf(dem.lon,dem.lat,dem.Band1,colors='gold',
               levels=[SL_mm.IANIGLA_HYPSO["2008-06-02"],
                       SL_mm.IANIGLA_HYPSO["2008-06-06"]],
               linewidths=0.5)

# ax.contour(dem.lon,dem.lat,dem.Band1,colors='k',
#            levels=[SL_mm.IANIGLA_HYPSO["2008-06-02"],SL_mm.IANIGLA_HYPSO["2008-06-06"],
#                    H0_mm.squeeze().resample('d').mean()["2008-06-03":"2008-06-04"].mean()-300,
#                    ],linewidths=0.2)

# ax[1].contour(dem.lon,dem.lat,dem.Band1,colors='tab:blue',
#                levels=[]],
#                linewidths=0.5, linestyle="--")