text:
#!/usr/bin/env python3

import os, time
import torch
import torch.nn.functional as F
import numpy as np
import json
import torchvision.transforms as transforms
import matplotlib.pyplot as plt
import matplotlib.cm as cm
import skimage.transform
import argparse
# from scipy.misc import imread, imresize
import imageio
from PIL import Image
# import transformer, models

def caption_image_beam_search(args, encoder, decoder, image_path, word_map):
    """
    Reads an image and captions it with beam search.

    :param encoder: encoder model
    :param decoder: decoder model
    :param image_path: path to image
    :param word_map: word map
    :param beam_size: number of sequences to consider at each decode-step
    :return: caption, weights for visualization
    """

    k = args.beam_size
    Caption_End = False
    vocab_size = len(word_map)
    # Read image and process
    img = imageio.imread(image_path)
    # img = imread(image_path)
    if len(img.shape) == 2:
        img = img[:, :, np.newaxis]
        img = np.concatenate([img, img, img], axis=2)
    img = np.array(Image.fromarray(img).resize((256, 256)))
    # img = imresize(img, (256, 256))
    img = img.transpose(2, 0, 1)
    img = img / 255.
    img = torch.FloatTensor(img).to(device)
    normalize = transforms.Normalize(mean=[0.485, 0.456, 0.406],
                                     std=[0.229, 0.224, 0.225])
    transform = transforms.Compose([normalize])
    image = transform(img)  # (3, 256, 256)

    # Encode
    image = image.unsqueeze(0)  # (1, 3, 256, 256)
    encoder_out = encoder(image)  # (1, enc_image_size, enc_image_size, encoder_dim)
    enc_image_size = encoder_out.size(1)
    encoder_dim = encoder_out.size(-1)
    # Flatten encoding
    encoder_out = encoder_out.view(1, -1, encoder_dim)  # [1, num_pixels=196, encoder_dim]
    num_pixels = encoder_out.size(1)
    # We'll treat the problem as having a batch size of k
    encoder_out = encoder_out.expand(k, num_pixels, encoder_dim)  # (k, num_pixels, encoder_dim)

    # Tensor to store top k previous words at each step; now they're just <start>
    if args.decoder_mode == "lstm":
        k_prev_words = torch.LongTensor([[word_map['<start>']]] * k).to(device)  # (k, 1)
    elif args.decoder_mode == "transformer":
        k_prev_words = torch.LongTensor([[word_map['<start>']] * 52] * k).to(device)  # (k, 52)

    # Tensor to store top k sequences; now they're just <start>
    seqs = torch.LongTensor([[word_map['<start>']]] * k).to(device)  # (k, 1)
    # Tensor to store top k sequences' scores; now they're just 0
    top_k_scores = torch.zeros(k, 1).to(device)  # (k, 1)
    # Tensor to store top k sequences' alphas; now they're just 1s
    seqs_alpha = torch.ones(k, 1, enc_image_size, enc_image_size).to(device)  # (k, 1, enc_image_size, enc_image_size)
    # Lists to store completed sequences, their alphas and scores
    complete_seqs = list()
    complete_seqs_alpha = list()
    complete_seqs_scores = list()

    # Start decoding
    step = 1
    if args.decoder_mode == "lstm":
        h, c = decoder.init_hidden_state(encoder_out)

    # s is a number less than or equal to k, because sequences are removed from this process once they hit <end>
    while True:
        if args.decoder_mode == "lstm":
            embeddings = decoder.embedding(k_prev_words).squeeze(1)  # (s, embed_dim)
            awe, alpha = decoder.attention(encoder_out, h)  # (s, encoder_dim), (s, num_pixels)
            alpha = alpha.view(-1, enc_image_size, enc_image_size).unsqueeze(1)  # (s, 1, enc_image_size, enc_image_size)
            gate = decoder.sigmoid(decoder.f_beta(h))  # gating scalar, (s, encoder_dim)
            awe = gate * awe
            h, c = decoder.lstm(torch.cat([embeddings, awe], dim=1), (h, c))  # (s, decoder_dim)
            scores = decoder.fc(h)  # (s, vocab_size)
        elif args.decoder_mode == "transformer":
            cap_len = torch.LongTensor([52]).repeat(k, 1)  # [s, 1]
            scores, _, _, alpha_dict, _ = decoder(encoder_out, k_prev_words, cap_len)
            scores = scores[:, step - 1, :].squeeze(1)  # [s, 1, vocab_size] -> [s, vocab_size]
            # choose the last layer, transformer decoder is comosed of a stack of 6 identical layers.
            alpha = alpha_dict["dec_enc_attns"][-1]  # [s, n_heads=8, len_q=52, len_k=196]
            # TODO: AVG Attention to Visualize
            # for i in range(len(alpha_dict["dec_enc_attns"])):
            #     n_heads = alpha_dict["dec_enc_attns"][i].size(1)
            #     for j in range(n_heads):
            #         pass
            # the second dim corresponds to the Multi-head attention = 8, now 0
            # the third dim corresponds to cur caption position
            alpha = alpha[:, 0, step-1, :].view(k, 1, enc_image_size, enc_image_size)  # [s, 1, enc_image_size, enc_image_size]

        scores = F.log_softmax(scores, dim=1)
        # Add
        scores = top_k_scores.expand_as(scores) + scores  # (s, vocab_size)
        # For the first step, all k points will have the same scores (since same k previous words, h, c)
        if step == 1:
            top_k_scores, top_k_words = scores[0].topk(k, 0, True, True)  # (s)
        else:
            # Unroll and find top scores, and their unrolled indices
            top_k_scores, top_k_words = scores.view(-1).topk(k, 0, True, True)  # (s)

        # Convert unrolled indices to actual indices of scores
        prev_word_inds = top_k_words // vocab_size  # (s)
        next_word_inds = top_k_words % vocab_size  # (s)
        # Add new words to sequences, alphas
        seqs = torch.cat([seqs[prev_word_inds], next_word_inds.unsqueeze(1)], dim=1)  # (s, step+1)
        seqs_alpha = torch.cat([seqs_alpha[prev_word_inds], alpha[prev_word_inds]], dim=1)  # (s, step+1, enc_image_size, enc_image_size)

        # Which sequences are incomplete (didn't reach <end>)?
        incomplete_inds = [ind for ind, next_word in enumerate(next_word_inds) if
                           next_word != word_map['<end>']]
        complete_inds = list(set(range(len(next_word_inds))) - set(incomplete_inds))
        # Set aside complete sequences
        if len(complete_inds) > 0:
            Caption_End = True
            complete_seqs.extend(seqs[complete_inds].tolist())
            complete_seqs_alpha.extend(seqs_alpha[complete_inds].tolist())
            complete_seqs_scores.extend(top_k_scores[complete_inds])
        k -= len(complete_inds)  # reduce beam length accordingly

        # Proceed with incomplete sequences
        if k == 0:
            break
        seqs = seqs[incomplete_inds]
        seqs_alpha = seqs_alpha[incomplete_inds]
        encoder_out = encoder_out[prev_word_inds[incomplete_inds]]
        top_k_scores = top_k_scores[incomplete_inds].unsqueeze(1)
        if args.decoder_mode == "lstm":
            h = h[prev_word_inds[incomplete_inds]]
            c = c[prev_word_inds[incomplete_inds]]
            k_prev_words = next_word_inds[incomplete_inds].unsqueeze(1)
        elif args.decoder_mode == "transformer":
            k_prev_words = k_prev_words[incomplete_inds]
            k_prev_words[:, :step + 1] = seqs  # [s, 52]
            # k_prev_words[:, step] = next_word_inds[incomplete_inds]  # [s, 52]

        # Break if things have been going on too long
        if step > 50:
            break
        step += 1

    assert Caption_End
    i = complete_seqs_scores.index(max(complete_seqs_scores))
    seq = complete_seqs[i]
    alphas = complete_seqs_alpha[i]

    return seq, alphas

def visualize_att(image_path, seq, alphas, rev_word_map, path, smooth=True):
    """
    Visualizes caption with weights at every word.
    Adapted from paper authors' repo: https://github.com/kelvinxu/arctic-captions/blob/master/alpha_visualization.ipynb

    :param image_path: path to image that has been captioned
    :param seq: caption
    :param alphas: weights
    :param rev_word_map: reverse word mapping, i.e. ix2word
    :param smooth: smooth weights?
    """
    image = Image.open(image_path)
    image = image.resize([14 * 24, 14 * 24], Image.LANCZOS)

    words = [rev_word_map[ind] for ind in seq]
    print(words)

    for t in range(len(words)):
        if t > 50:
            break
        plt.subplot(np.ceil(len(words) / 5.), 5, t + 1)

        plt.text(0, 1, '%s' % (words[t]), color='black', backgroundcolor='white', fontsize=12)
        plt.imshow(image)
        current_alpha = alphas[t, :]
        if smooth:
            alpha = skimage.transform.pyramid_expand(current_alpha.numpy(), upscale=24, sigma=8)
        else:
            alpha = skimage.transform.resize(current_alpha.numpy(), [14 * 24, 14 * 24])
        if t == 0:
            plt.imshow(alpha, alpha=0)
        else:
            plt.imshow(alpha, alpha=0.8)
        plt.set_cmap(cm.Greys_r)
        plt.axis('off')
    print(path)
    plt.savefig(path)
    plt.show()

if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='Image_Captioning')
    parser.add_argument('--img', '-i', default="./dataset/val2014/COCO_val2014_000000581886.jpg", help='path to image, file or folder')
    parser.add_argument('--checkpoint', '-m', default="./BEST_checkpoint_coco_5_cap_per_img_5_min_word_freq.pth.tar", help='path to model')
    parser.add_argument('--word_map', '-wm', default="./dataset/generated_data/WORDMAP_coco_5_cap_per_img_5_min_word_freq.json",
                        help='path to word map JSON')
    parser.add_argument('--decoder_mode', default="transformer", help='which model does decoder use?')  # lstm or transformer
    parser.add_argument('--save_img_dir', '-p', default="./caption", help='path to save annotated img.')
    parser.add_argument('--beam_size', '-b', type=int, default=3, help='beam size for beam search')
    parser.add_argument('--dont_smooth', dest='smooth', action='store_false', help='do not smooth alpha overlay')
    args = parser.parse_args()

    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    # transformer.device = torch.device("cpu")
    # models.device = torch.device("cpu")
    print(device)

    # Load model
    checkpoint = torch.load(args.checkpoint, map_location=str(device))
    decoder = checkpoint['decoder']
    decoder = decoder.to(device)
    decoder.eval()
    encoder = checkpoint['encoder']
    encoder = encoder.to(device)
    encoder.eval()
    # print(encoder)
    # print(decoder)

    # Load word map (word2ix)
    with open(args.word_map, 'r') as j:
        word_map = json.load(j)
    rev_word_map = {v: k for k, v in word_map.items()}  # ix2word

    # Encode, decode with attention and beam search
    if os.path.isdir(args.img):
        for file in os.listdir(args.img):
            file = os.path.join(args.img, file)
            with torch.no_grad():
                seq, alphas = caption_image_beam_search(args, encoder, decoder, file, word_map)
                alphas = torch.FloatTensor(alphas)

            if not (os.path.exists(args.save_img_dir) and os.path.isdir(args.save_img_dir)):
                os.makedirs(args.save_img_dir)
            timestamp = str(int(time.time()))
            path = args.save_img_dir + "/" + timestamp + ".png"
            # Visualize caption and attention of best sequence
            visualize_att(file, seq, alphas, rev_word_map, path, args.smooth)
    else:
        with torch.no_grad():
            seq, alphas = caption_image_beam_search(args, encoder, decoder, args.img, word_map)
            alphas = torch.FloatTensor(alphas)

        if not (os.path.exists(args.save_img_dir) and os.path.isdir(args.save_img_dir)):
            os.makedirs(args.save_img_dir)
        timestamp = str(int(time.time()))
        path = args.save_img_dir + "/" + timestamp + ".png"
        # Visualize caption and attention of best sequence
        visualize_att(args.img, seq, alphas, rev_word_map, path, args.smooth)

ext: py

max_stars_repo_name: cnrblm/Image-Caption

max_issues_repo_name: bozliu/Image-Caption

max_forks_repo_name: bozliu/Image-Caption

reason: import numpy,from scipy


text:
from matplotlib import pyplot as plt
import numpy as np
import math
from heapq import PriorityQueue
import time
import pickle

INF = 99999999999999999999999.0

# return the journey time of a road and its capacity
def get_time_cap(road,length):
    road = int(road)
    speed = 30.0
    cap = 500
    if road == 2:
        speed = 50.0
        cap = 750
    if road == 3:
        speed = 50.0
        cap = 1000
    if road == 4:
        speed = 70.0
        cap = 1500
    if road == 5:
        speed = 70.0
        cap = 2000
    if road == 6:
        speed = 90.0
        cap = 4000
    length = float(length)/1000.0
    road_time = length/speed
    return road_time,cap

# load a weighted directed graph from file
# [u][v][time,cap]
def load_graph(file):
    graph = dict()
    with open(file,'r') as f:
        for line in f.readlines():
            if line[0] != '#':
                info = line.split()
                if info[0] not in graph:
                    graph[info[0]] = dict()
                if info[1] not in graph:
                    graph[info[1]] = dict()
                road_time,cap = get_time_cap(info[3],info[2])
                graph[info[0]][info[1]] = {"time":road_time,"cap":cap}
    return graph

# initialize graph for dijkstra
def initSSSP(graph,sourc):
    for x in graph:
        graph[x]['d'] = INF
        graph[x]['p'] = None
    graph[sourc]['d'] = 0

# update weights for dijkstra
def relax(graph,u,v):
    graph[v]['d'] = graph[u]['d']+graph[u][v]["time"]
    graph[v]['p'] = u

# find minimal paths from source to all nodes
def dijkstra(graph,sourc):
    t = time.time()
    initSSSP(graph,sourc)
    q = PriorityQueue(graph)
    stop = False
    while (not q.empty()) and (not stop):
        u = q.extractMin()
        if graph[u]['d'] >= INF:
            stop = True
        else:
            for v in graph[u].keys():
                if not v in ['d','p','pos']:
                    if ((graph[u]['d'])+(graph[u][v]["time"]))<(graph[v]['d']):
                        relax(graph,u,v)
                        q.changeKey(graph[v]['pos'],graph[v]['d'])
    print("[ Dijkstra Time:",time.time()-t,"s ]")

# extract the minimal path from source to destination if it is executed
# after the function dijkstra
def find_min_path(graph,sourc,dest):
    if graph[dest]['p'] == None:
        return None,INF
    path = [dest]
    path_time = graph[dest]['d']
    current = dest
    while current != None:
        current = graph[current]['p']
        if current != None:
            path.insert(0,current)
    return path,path_time

# return a plan that maximize the flow from a set of resources and
# a set of destination (considering capacity)
def ccrp(graph,sourc,dest):
    s0 = 's0'
    graph[s0] = dict()
    for x in sourc:
        graph[s0][x] = {"time":0.0,"cap":9999999999999999999999999}
    plan = []
    while True:
        path = None
        road_time = INF
        dijkstra(graph,s0)
        for vk in dest:
            p,t = find_min_path(graph,s0,vk)
            if t<road_time:
                path = p
                road_time = t
        if path == None:
            return plan
        flow = min([graph[path[i]][path[i+1]]["cap"] for i in range(len(path)-1)])
        plan.append((path,flow,road_time))
        for i in range(len(path)-1):
            graph[path[i]][path[i+1]]["cap"] -= flow
            if graph[path[i]][path[i+1]]["cap"] == 0:
                graph[path[i]].pop(path[i+1],None)

# plot capacity and time of a plan in function of
# the number of paths considered
def plot_plan_stats(plan):
    captot = []
    timetot = []
    for i in range(1,len(plan)):
        cap = 0
        tm = 0
        for j in range(i):
            cap += plan[j][1]
            t = plan[j][2]
            if t > tm:
                tm = t
        captot.append(cap)
        timetot.append(tm)
    plt.plot(captot,timetot)
    plt.show()

def cap_sourc(graph,sources):
    cap_tot = 0
    cap = dict()
    for x in sources:
        cap[x] = 0
        for v in graph[x].keys():
            cap[x] += graph[x][v]['cap']
            cap_tot += graph[x][v]['cap']
    return cap_tot,cap

def cap_dest(graph,dest):
    cap_tot = 0
    cap = dict()
    for x in graph:
        for d in dest:
            if d in graph[x]:
                if d in cap:
                    cap[d] += graph[x][d]['cap']
                else:
                    cap[d] = graph[x][d]['cap']
                cap_tot += graph[x][d]['cap']
    return (cap_tot,cap)

def cap_plan(plan):
    cap = 0
    for j in range(len(plan)):
        cap += plan[j][1]
    return cap

def find_bottlenek(sources,dests,plan):
    scap = dict()
    dcap = dict()
    for path in range(len(plan)):
        s = plan[path][0][1]
        d = plan[path][0][len(plan[path][0])-1]
        if s in scap:
            scap[s] += plan[path][1]
        else:
            scap[s] = plan[path][1]
        if d in dcap:
            dcap[d] += plan[path][1]
        else:
            dcap[d] = plan[path][1]
    return scap,dcap

if __name__ == '__main__':
    graph = load_graph("SFroad.txt")
    sources = ['3718987342','915248218','65286004']
    destinations = ['261510687','3522821903','65319958','65325408','65295403','258913493']
    t = time.time()
    sctot,sc = cap_sourc(graph,sources)
    dctot,dc = cap_dest(graph,destinations)
    print("Sources capacity:",sctot)
    print(sc)
    print("Destinations capacity:",dctot)
    print(dc)
    plan = ccrp(graph,sources,destinations)
    # with open("plan.pickle",'rb') as f:
    #     plan = pickle.load(f)
    # print("Plan:",plan)
    print("Plan capacity:",cap_plan(plan))
    scb,dcb = find_bottlenek(sources,destinations,plan)
    print("Plan Sources Capacity Distribution:")
    print(scb)
    print("Plan Destinations Capacity Distribution:")
    print(dcb)
    print("[ Execution Time:",(time.time()-t),"s ]")
    plot_plan_stats(plan)

reason: import numpy


text:
from __future__ import absolute_import, division
from typing import Tuple

import torch
import torch.nn as nn
import numpy as np
import math
import torch.nn.functional as F

from ac import utils
import config

domain_sym = config.AUGMENTED_TRANS_SET[0]

class ac_conv(nn.Conv2d):
    _pd = 2
    def __init__(self,*args, **kwargs):
        super(ac_conv, self).__init__(*args, **kwargs)

        self.register_buffer('efficient_inference', torch.tensor([0.0], dtype=torch.float32), persistent=False)
        self.register_buffer('entropy', torch.tensor([1.0],dtype=torch.float32), persistent=False)
        self.register_buffer('normalize', torch.tensor([1.0], dtype=torch.float32), persistent=False)
        self._generate_trans()

    def _generate_trans(self):

        trans, trans_inv = utils.domain_trans(domain_sym)
        self.register_buffer('domain_trans', torch.stack(trans, 0) if len(trans) > 0 else None, persistent=False)
        self.register_buffer('domain_trans_inv', torch.stack(trans_inv, 0) if len(trans_inv) > 0 else None, persistent=False)

    def _apply_conv(self, data: torch.Tensor, weight: torch.Tensor) -> torch.Tensor:
        sw = ((self.weight.shape[-1]) // 2) + ac_conv._pd
        return F.conv2d(data, weight, self.bias, self.stride, sw, self.dilation, self.groups)

    def _covar_measure(self, orbit1: torch.Tensor, orbit2: torch.Tensor) -> torch.Tensor:
        return F.cosine_similarity(torch.flatten(orbit1, -2), torch.flatten(orbit2, -2), -1)

    def stable_response(self, data: torch.Tensor) -> torch.Tensor:
        intersections, score = self.response_variation(data)
        score = torch.softmax(self.entropy * score, 0) if self.normalize else torch.exp(self.entropy * score)
        score_ext = torch.unsqueeze(torch.unsqueeze(score, -1), -1)
        return torch.sum(torch.mul(intersections, score_ext), 0)

    def response_variation(self, data: torch.Tensor) -> Tuple[torch.Tensor, torch.Tensor] :
        score, intersections = [], []
        i = 0
        while self.domain_trans is not None and i < len(self.domain_trans):
            response2transforms = self._apply_conv(self.domain_transform(data, self.domain_trans[i]), self.pdstream(self.weight))
            response2originals  = self.domain_transform(self._apply_conv(data, self.pdstream(self.weight)), self.domain_trans[i])
            score.append(self._covar_measure(response2transforms, response2originals))
            intersections.append(self._apply_conv(data, self.domain_transform(self.pdstream(self.weight), self.domain_trans_inv[i])))
            i += 1
        return torch.stack(intersections, 0), torch.stack(score, 0)

    def domain_transform(self, data: torch.Tensor, trans: torch.Tensor):
        g2 = trans.expand(data.shape[0], -1, -1)
        Res = F.affine_grid(g2, data.size())
        return F.grid_sample(data, Res)  # interpolation with bilinear method

    def pdstream(self, input: torch.Tensor) -> torch.Tensor:
        sw = ac_conv._pd
        return F.pad(input, pad=(sw,sw,sw,sw))

    def forward(self, data: torch.Tensor) -> torch.Tensor:
        if self.efficient_inference:
            return F.conv2d(data, self.weight, self.bias, self.stride, 1, self.dilation, self.groups)
        else:
            return self.stable_response(data)

"""
 Extended AC: derived class from ac_conv
"""


text:
#  Copyright (c) 2019 PaddlePaddle Authors. All Rights Reserve.
#
#Licensed under the Apache License, Version 2.0 (the "License");
#you may not use this file except in compliance with the License.
#You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
#Unless required by applicable law or agreed to in writing, software
#distributed under the License is distributed on an "AS IS" BASIS,
#WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
#See the License for the specific language governing permissions and
#limitations under the License.
"""
Contains proposal functions
"""

from __future__ import absolute_import
from __future__ import division
from __future__ import print_function

import numpy as np
import paddle.fluid as fluid

from utils.config import cfg

__all__ = ["boxes3d_to_bev", "box_overlap_rotate", "boxes3d_to_bev", "box_iou", "box_nms"]

def boxes3d_to_bev(boxes3d):
    """
    Args:
        boxes3d: [N, 7], (x, y, z, h, w, l, ry)
    Return:
        boxes_bev: [N, 5], (x1, y1, x2, y2, ry)
    """
    boxes_bev = np.zeros((boxes3d.shape[0], 5), dtype='float32')

    cu, cv = boxes3d[:, 0], boxes3d[:, 2]
    half_l, half_w = boxes3d[:, 5] / 2, boxes3d[:, 4] / 2
    boxes_bev[:, 0], boxes_bev[:, 1] = cu - half_l, cv - half_w
    boxes_bev[:, 2], boxes_bev[:, 3] = cu + half_l, cv + half_w
    boxes_bev[:, 4] = boxes3d[:, 6]
    return boxes_bev

def rotate_around_center(center, angle_cos, angle_sin, corners):
    new_x = (corners[:, 0] - center[0]) * angle_cos + \
            (corners[:, 1] - center[1]) * angle_sin + center[0]
    new_y = -(corners[:, 0] - center[0]) * angle_sin + \
            (corners[:, 1] - center[1]) * angle_cos + center[1]
    return np.concatenate([new_x[:, np.newaxis], new_y[:, np.newaxis]], axis=-1)

def check_rect_cross(p1, p2, q1, q2):
    return min(p1[0], p2[0]) <= max(q1[0], q2[0]) and \
           min(q1[0], q2[0]) <= max(p1[0], p2[0]) and \
           min(p1[1], p2[1]) <= max(q1[1], q2[1]) and \
           min(q1[1], q2[1]) <= max(p1[1], p2[1])

def cross(p1, p2, p0):
    return (p1[0] - p0[0]) * (p2[1] - p0[1]) - (p2[0] - p0[0]) * (p1[1] - p0[1]);

def cross_area(a, b):
    return a[0] * b[1] - a[1] * b[0]

def intersection(p1, p0, q1, q0):
    if not check_rect_cross(p1, p0, q1, q0):
        return None

    s1 = cross(q0, p1, p0)
    s2 = cross(p1, q1, p0)
    s3 = cross(p0, q1, q0)
    s4 = cross(q1, p1, q0)
    if not (s1 * s2 > 0 and s3 * s4 > 0):
        return None

    s5 = cross(q1, p1, p0)
    if np.abs(s5 - s1) > 1e-8:
        return np.array([(s5 * q0[0] - s1 * q1[0]) / (s5 - s1),
                (s5 * q0[1] - s1 * q1[1]) / (s5 - s1)], dtype='float32')
    else:
        a0 = p0[1] - p1[1]
        b0 = p1[0] - p0[0]
        c0 = p0[0] * p1[1] - p1[0] * p0[1]
        a0 = q0[1] - q1[1]
        b0 = q1[0] - q0[0]
        c0 = q0[0] * q1[1] - q1[0] * q0[1]
        D = a0 * b1 - a1 * b0
        return np.array([(b0 * c1 - b1 * c0) / D, (a1 * c0 - a0 * c1) / D], dtype='float32')

def check_in_box2d(box, p):
    center_x = (box[0] + box[2]) / 2.
    center_y = (box[1] + box[3]) / 2.
    angle_cos = np.cos(-box[4])
    angle_sin = np.sin(-box[4])
    rot_x = (p[0] - center_x) * angle_cos + (p[1] - center_y) * angle_sin + center_x
    rot_y = -(p[0] - center_x) * angle_sin + (p[1] - center_y) * angle_cos + center_y
    return rot_x > box[0] - 1e-5 and rot_x < box[2] + 1e-5 and \
            rot_y > box[1] - 1e-5 and rot_y < box[3] + 1e-5

def point_cmp(a, b, center):
    return np.arctan2(a[1] - center[1], a[0] - center[0]) > \
            np.arctan2(b[1] - center[1], b[0] - center[0])

def box_overlap_rotate(cur_box, boxes):
    """
    Calculate box overlap with rotate, box: [x1, y1, x2, y2, angle]
    """
    areas = np.zeros((len(boxes), ), dtype='float32')
    cur_center = [(cur_box[0] + cur_box[2]) / 2., (cur_box[1] + cur_box[3]) / 2.]
    cur_corners = np.array([
            [cur_box[0], cur_box[1]], # (x1, y1)
            [cur_box[2], cur_box[1]], # (x2, y1)
            [cur_box[2], cur_box[3]], # (x2, y2)
            [cur_box[0], cur_box[3]], # (x1, y2)
            [cur_box[0], cur_box[1]], # (x1, y1)
            ], dtype='float32')
    cur_angle_cos = np.cos(cur_box[4])
    cur_angle_sin = np.sin(cur_box[4])
    cur_corners = rotate_around_center(cur_center, cur_angle_cos, cur_angle_sin, cur_corners)

    for i, box in enumerate(boxes):
        box_center = [(box[0] + box[2]) / 2., (box[1] + box[3]) / 2.]
        box_corners = np.array([
                [box[0], box[1]],
                [box[2], box[1]],
                [box[2], box[3]],
                [box[0], box[3]],
                [box[0], box[1]],
                ], dtype='float32')
        box_angle_cos = np.cos(box[4])
        box_angle_sin = np.sin(box[4])
        box_corners = rotate_around_center(box_center, box_angle_cos, box_angle_sin, box_corners)

        cross_points = np.zeros((16, 2), dtype='float32')
        cnt = 0
        # get intersection of lines
        for j in range(4):
            for k in range(4):
                inters = intersection(cur_corners[j + 1], cur_corners[j],
                                      box_corners[k + 1], box_corners[k])
                if inters is not None:
                    cross_points[cnt, :] = inters
                    cnt += 1
        # check corners
        for l in range(4):
            if check_in_box2d(cur_box, box_corners[l]):
                cross_points[cnt, :] = box_corners[l]
                cnt += 1
            if check_in_box2d(box, cur_corners[l]):
                cross_points[cnt, :] = cur_corners[l]
                cnt += 1

        if cnt > 0:
            poly_center = np.sum(cross_points[:cnt, :], axis=0) / cnt
        else:
            poly_center = np.zeros((2,))

        # sort the points of polygon
        for j in range(cnt - 1):
            for k in range(cnt - j - 1):
                if point_cmp(cross_points[k], cross_points[k + 1], poly_center):
                    cross_points[k], cross_points[k + 1] = \
                            cross_points[k + 1].copy(), cross_points[k].copy()

        # get the overlap areas
        area = 0.
        for j in range(cnt - 1):
            area += cross_area(cross_points[j] - cross_points[0],
                               cross_points[j + 1] - cross_points[0])
        areas[i] = np.abs(area) / 2.

    return areas

def box_iou(cur_box, boxes, box_type='normal'):
    cur_S = (cur_box[2] - cur_box[0]) * (cur_box[3] - cur_box[1])
    boxes_S = (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])

    if box_type == 'normal':
        inter_x1 = np.maximum(cur_box[0], boxes[:, 0])
        inter_y1 = np.maximum(cur_box[1], boxes[:, 1])
        inter_x2 = np.minimum(cur_box[2], boxes[:, 2])
        inter_y2 = np.minimum(cur_box[3], boxes[:, 3])
        inter_w = np.maximum(inter_x2 - inter_x1, 0.)
        inter_h = np.maximum(inter_y2 - inter_y1, 0.)
        inter_area = inter_w * inter_h
    elif box_type == 'rotate':
        inter_area = box_overlap_rotate(cur_box, boxes)
    else:
        raise NotImplementedError

    return inter_area / np.maximum(cur_S + boxes_S - inter_area, 1e-8)

def box_nms(boxes, scores, proposals, thresh, topk, nms_type='normal'):
    assert nms_type in ['normal', 'rotate'], \
            "unknown nms type {}".format(nms_type)
    order = np.argsort(-scores)
    boxes = boxes[order]
    scores = scores[order]
    proposals = proposals[order]

    nmsed_scores = []
    nmsed_proposals = []
    cnt = 0
    while boxes.shape[0]:
        nmsed_scores.append(scores[0])
        nmsed_proposals.append(proposals[0])
        cnt +=1
        if cnt >= topk or boxes.shape[0] == 1:
            break
        iou = box_iou(boxes[0], boxes[1:], nms_type)
        boxes = boxes[1:][iou < thresh]
        scores = scores[1:][iou < thresh]
        proposals = proposals[1:][iou < thresh]
    return nmsed_scores, nmsed_proposals

def box_nms_eval(boxes, scores, proposals, thresh, nms_type='rotate'):
    assert nms_type in ['normal', 'rotate'], \
            "unknown nms type {}".format(nms_type)
    order = np.argsort(-scores)
    boxes = boxes[order]
    scores = scores[order]
    proposals = proposals[order]

    nmsed_scores = []
    nmsed_proposals = []
    while boxes.shape[0]:
        nmsed_scores.append(scores[0])
        nmsed_proposals.append(proposals[0])
        iou = box_iou(boxes[0], boxes[1:], nms_type)
        inds = iou < thresh
        boxes = boxes[1:][inds]
        scores = scores[1:][inds]
        proposals = proposals[1:][inds]
    nmsed_scores = np.asarray(nmsed_scores)
    nmsed_proposals = np.asarray(nmsed_proposals)
    return nmsed_scores, nmsed_proposals

def boxes_iou3d(boxes1, boxes2):
    boxes1_bev = boxes3d_to_bev(boxes1)
    boxes2_bev = boxes3d_to_bev(boxes2)

    # bev overlap
    overlaps_bev = np.zeros((boxes1_bev.shape[0], boxes2_bev.shape[0]))
    for i in range(boxes1_bev.shape[0]):
        overlaps_bev[i, :] = box_overlap_rotate(boxes1_bev[i], boxes2_bev)

    # height overlap
    boxes1_height_min = (boxes1[:, 1] - boxes1[:, 3]).reshape(-1, 1)
    boxes1_height_max = boxes1[:, 1].reshape(-1, 1)
    boxes2_height_min = (boxes2[:, 1] - boxes2[:, 3]).reshape(1, -1)
    boxes2_height_max = boxes2[:, 1].reshape(1, -1)

    max_of_min = np.maximum(boxes1_height_min, boxes2_height_min)
    min_of_max = np.minimum(boxes1_height_max, boxes2_height_max)
    overlaps_h = np.maximum(min_of_max - max_of_min, 0.)

    # 3d iou
    overlaps_3d = overlaps_bev * overlaps_h

    vol_a = (boxes1[:, 3] * boxes1[:, 4] * boxes1[:, 5]).reshape(-1, 1)
    vol_b = (boxes2[:, 3] * boxes2[:, 4] * boxes2[:, 5]).reshape(1, -1)
    iou3d = overlaps_3d / np.maximum(vol_a + vol_b - overlaps_3d, 1e-7)

    return iou3d

max_stars_repo_name: suytingwan/models

max_issues_repo_name: suytingwan/models

max_forks_repo_name: suytingwan/models


text:
import subprocess
import requests
import json
import os
import uuid
import urllib
import numpy as np
from flask import Flask, render_template, request, redirect, url_for, flash, jsonify, session, g
from flask_bootstrap import Bootstrap
from pprint import pprint
from datetime import datetime, timedelta
from flask_jwt import JWT, jwt_required, current_identity
from werkzeug.security import safe_str_cmp
from werkzeug.utils import secure_filename
from functools import wraps
import hashlib, uuid
import configparser
import atexit
from apscheduler.scheduler import Scheduler

# GLOBAL VARIABLES
GLOBALPATH = "/BDOHarmonization/BigDataOcean-Harmonization"

GLOBALURLJWT = ""
UPLOAD_FOLDER = GLOBALPATH+'/Backend/AddDatasets'
ALLOWED_EXTENSIONS = set(['nc', 'csv', 'xlsx', 'xls'])

#JWT authorization (parser and handler)
# BDO.ini where JWT token is saved
config = configparser.ConfigParser()
config.read(GLOBALPATH + '/Backend/bdodatasets/bdo.ini')

AUTHORIZATION = config['DEFAULT']['AUTHORIZATION_JWT']

# Authentication JWT for APIs
# Class for security authentication JWT
class User(object):
	def __init__(self, id, username, password, salt):
		self.id = id
		self.username = username
		self.password = password
		self.salt = salt

	def __str__(self):
		return "User(id='%s')" % self.id

users = [
	User(1, 'admin', '', ''),
	User(2, 'test', '', '')
]

username_table = {u.username: u for u in users}
userid_table = {u.id: u for u in users}

app = Flask(__name__)
bootstrap = Bootstrap(app)
# configuring the path of the upload folder
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER
app.config['SECRET_KEY'] = 'super-secret'
app.config['JWT_EXPIRATION_DELTA'] = timedelta(seconds = 3720) # Expiration time of JWT token is for 62 minutes

# Function that sync JWT token of parser tool when flask runs
def syncwhenrunflask():
	tokencommand = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/fetchJWTToken'
	print (subprocess.check_output([tokencommand], shell="True"))
	config.read(GLOBALPATH + '/Backend/bdodatasets/bdo.ini')
	global AUTHORIZATION
	AUTHORIZATION = config['DEFAULT']['AUTHORIZATION_JWT']

# Thread in background to update every year the JWT Authorization Token (Parser tool)
cron = Scheduler(daemon=True)
# Explicitly kick off the background thread
cron.start()

# Command = Thread in background to update every hour the JWT Authorization Token (Parser tool)
@cron.interval_schedule(seconds=3600)
def fetchtoken():
	syncwhenrunflask()

# Shutdown your cron thread if the web process is stopped
atexit.register(lambda: cron.shutdown(wait=False))

# Authentication JWT for APIs
def authenticate(username, password):
    user = username_table.get(username, None)
    hashed_password = hashlib.sha512(password.encode('utf-8') + user.salt.encode('utf-8')).hexdigest()
    if user and safe_str_cmp(user.password.encode('utf-8'), hashed_password.encode('utf-8')):
        return user

def identity(payload):
    user_id = payload['identity']
    return userid_table.get(user_id, None)

jwt = JWT(app, authenticate, identity)

# check if an extension is valid
def allowed_file(filename):
    return '.' in filename and \
           filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

# Routing to index
@app.route('/')
def index():
	extractdatafromhandler()
	# Calls shell listDatasets to get all the datasets stored on jena fuseki
	command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/listDatasets'
	try:
		process = subprocess.check_output([command], shell="True")
		# other column settings -> http://bootstrap-table.wenzhixin.net.cn/documentation/#column-options
		columns = [{
		"field": "storageTable", # which is the field's name of data key
		"title": "Storage Table", # display as the table header's name
		"sortable": True,
		},{
		"field": "title", # which is the field's name of data key
		"title": "Title", # display as the table header's name
		"sortable": True,
		},
		{
		"field": "description",
		"title": "Description",
		"sortable": True,
		},
		{
		"field": "formats",
		"title": "Formats",
		"sortable": True,
		"visible": False,
		}]
		# print (process.decode('utf-8'))
		parsed_output = json.loads(process.decode('utf-8'))
		data = parsed_output
		return render_template('index.html',
			data=data,
			columns=columns)
	except subprocess.CalledProcessError as e:
		print(e)
		return render_template('500.html')
	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

@app.before_request
def get_current_user():
    g.user = None
    username = session.get('user_id')
    if username is not None:
        g.user = username

# login required decorator
def login_required(f):
    @wraps(f)
    def wrap(*args, **kwargs):
        if 'user_id' in session:
            return f(*args, **kwargs)
        else:
            flash('You need to login first.')
            return redirect(url_for('login'))
    return wrap

@app.route('/login', methods=['GET', 'POST'])
def login():
	error = None
	flag = False
	if request.method == 'POST':
		inputusername = request.form['username']
		inputpassword = request.form['password']
		for u in users:
			if u.username == inputusername:
				hashed_password = hashlib.sha512(inputpassword.encode('utf-8') + u.salt.encode('utf-8')).hexdigest()
				if u.password == hashed_password:
					flag = True
					break

		if flag == False:
			error = 'Invalid Credentials. Please try again.'
		else:
			session['user_id'] = inputusername
			flash('You are log in.')
			return redirect('/')
	return render_template('login.html', error=error)

@app.route('/logout')
def logout():
    session.pop('user_id', None)
    flash('You are log out.')
    return redirect('/')

# List of files that does not have metadata
@app.route('/list')
def list():
	try:
		parsed_output = requests.get(GLOBALURLJWT + 'fileHandler/file/metadata/empty', headers={'Authorization': AUTHORIZATION})
		columns = [{
		"field": "id",
		"title": "FileId",
		"sortable": True,
		},
		{
		"field": "fileName",
		"title": "Title",
		"sortable": True,
		},
		{
		"field": "hdfsFullURI",
		"title": "URI",
		"sortable": True,
		},
		{
		"field": "storedAt",
		"title": "Stored Date",
		"sortable": True,
		}]
		data = json.loads(parsed_output.content.decode('utf-8'))
		if parsed_output.status_code == 200:
			return render_template('listFiles.html',
					data=data,
					columns=columns)
		else:
			return render_template('500.html')
	except requests.exceptions.RequestException as e:
		print(e)
		return render_template('500.html', error='We could not connect with FileHandler')

# Routing to addMetadata form
@app.route('/addMetadata', methods=['GET', 'POST'])
@login_required
def parse():
	try:
		extractdatafromhandler()

		if request.method == 'POST':
			return render_template('addMetadata.html', dataset='', idFile='')
		elif request.method == 'GET':
			idfile = request.args['idFile']
			return render_template('addMetadata.html', dataset='', idFile=idfile)
	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

@app.route('/addMetadata/Copernicus', methods=['GET', 'POST'])
@login_required
def addcopernicus():
	try:
		extractdatafromhandler()
		if request.method == 'POST':
			uri = request.form['uri']
			# if adding a Copernicus dataset, the shell suggest is called to parse the xml file and get metadata
			command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/suggest "%s" Coppernicus' %uri
			try:
				process = subprocess.check_output([command], shell="True")
			except subprocess.CalledProcessError as e:
				print(e)
				return render_template('500.html')
			# metadata parsed is converted into json class DatasetInfo to be used inside the html form
			parsed_output = json.loads(process.decode('utf-8'))
			dataset = DatasetInfo(**parsed_output)

			return render_template('addMetadata.html', dataset=dataset, idFile='')
		elif request.method == 'GET':
			uri = request.args['uri']
			print (uri)
			# if adding a Copernicus dataset, the shell suggest is called to parse the xml file and get metadata
			command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/suggest "%s" Coppernicus' %uri
			print (command)
			try:
				process = subprocess.check_output([command], shell="True")
			except subprocess.CalledProcessError as e:
				print(e)
				return render_template('500.html')
			# metadata parsed is converted into json class DatasetInfo to be used inside the html form
			parsed_output = json.loads(process.decode('utf-8'))
			dataset = DatasetInfo(**parsed_output)

			return render_template('addMetadata.html', dataset=dataset, idFile='')
	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

@app.route('/addMetadata/NetCDF', methods=['GET', 'POST'])
@login_required
def addnetcdf():
	try:
		extractdatafromhandler()
		if request.method == 'POST':
			file = request.files['fileNetcdf']
			if file.filename != '':
				# Verify if the file is .nc
				if file and allowed_file(file.filename):
					# Create a general filename
					filename = file.filename
					# Saving the file in the UPLOAD_FOLDER with the filename
					file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
					path_file_netcdf = UPLOAD_FOLDER + "/" + filename
					# print (path_file_netcdf)
					command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/suggest "%s" FileNetcdf' %path_file_netcdf
					try:
						process = subprocess.check_output([command], shell="True")
					except subprocess.CalledProcessError as e:
						print(e)
						return render_template('500.html')
					# metadata parsed is converted into json class DatasetInfo to be used inside the html form
					parsed_output = json.loads(process.decode('utf-8'))
					dataset = DatasetInfo(**parsed_output)

					return render_template('addMetadata.html', dataset=dataset, idFile='')

		elif request.method == 'GET':
			file = request.args['file']
			idfile = request.args['idFile']
			command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/suggest "%s" Netcdf' %file
			try:
				process = subprocess.check_output([command], shell="True")
			except subprocess.CalledProcessError as e:
				print(e)
				return render_template('500.html')
			# parsing output from maven script, to avoid log comments
			process = process.split(b'\n')
			# metadata parsed is converted into json class DatasetInfo to be used inside the html form
			parsed_output = json.loads(process[1].decode('utf-8'))
			dataset = DatasetInfo(**parsed_output)

			return render_template('addMetadata.html', dataset=dataset, idFile=idfile)
	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

@app.route('/addMetadata/CSV', methods=['GET', 'POST'])
@login_required
def addcsv():
	try:
		extractdatafromhandler()
		if request.method == 'POST':
			file = request.files['fileCsv']
			if file.filename != '':
				# Verify if the file is .csv
				if file and allowed_file(file.filename):
					# Create a general filename
					filename = file.filename
					# Saving the file in the UPLOAD_FOLDER with the filename
					file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
					path_file_csv = UPLOAD_FOLDER + "/" + filename
					# print (path_file_netcdf)
					command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/suggest "%s" FileCSV' %path_file_csv
					try:
						process = subprocess.check_output([command], shell="True")
					except subprocess.CalledProcessError as e:
						print(e)
						return render_template('500.html')
					# metadata parsed is converted into json class DatasetInfo to be used inside the html form
					parsed_output = json.loads(process.decode('utf-8'))
					dataset = DatasetInfo(**parsed_output)

					return render_template('addMetadata.html', dataset=dataset, idFile='')

		elif request.method == 'GET':
			file = request.args['file']
			idfile = request.args['idFile']
			command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/suggest "%s" CSV' %file
			try:
				process = subprocess.check_output([command], shell="True")
			except subprocess.CalledProcessError as e:
				print(e)
				return render_template('500.html')
			# parsing output from maven script, to avoid log comments
			process = process.split(b'\n')
			# metadata parsed is converted into json class DatasetInfo to be used inside the html form
			parsed_output = json.loads(process[1].decode('utf-8'))
			dataset = DatasetInfo(**parsed_output)

			return render_template('addMetadata.html', dataset=dataset, idFile=idfile)
	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

@app.route('/addMetadata/EXCEL', methods=['GET', 'POST'])
@login_required
def addexcel():
	try:
		extractdatafromhandler()
		if request.method == 'POST':
			file = request.files['fileExcel']
			if file.filename != '':
				# Verify if the file is excel
				if file and allowed_file(file.filename):
					# Create a general filename
					filename = file.filename
					# Saving the file in the UPLOAD_FOLDER with the filename
					file.save(os.path.join(app.config['UPLOAD_FOLDER'], filename))
					path_file_excel = UPLOAD_FOLDER + "/" + filename
					# print (path_file_excel)
					command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/suggest "%s" FileExcel' %path_file_excel
					try:
						process = subprocess.check_output([command], shell="True")
					except subprocess.CalledProcessError as e:
						print(e)
						return render_template('500.html')
					# metadata parsed is converted into json class DatasetInfo to be used inside the html form
					parsed_output = json.loads(process.decode('utf-8'))
					dataset = DatasetInfo(**parsed_output)

					return render_template('addMetadata.html', dataset=dataset, idFile='')

		elif request.method == 'GET':
			file = request.args['file']
			idfile = request.args['idFile']
			command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/suggest "%s" Excel' %file
			try:
				process = subprocess.check_output([command], shell="True")
			except subprocess.CalledProcessError as e:
				print(e)
				return render_template('500.html')
			# parsing output from maven script, to avoid log comments
			process = process.split(b'\n')
			# metadata parsed is converted into json class DatasetInfo to be used inside the html form
			parsed_output = json.loads(process[1].decode('utf-8'))
			dataset = DatasetInfo(**parsed_output)

			return render_template('addMetadata.html', dataset=dataset, idFile=idfile)
	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

# Routing to save new dataset
@app.route('/save', methods=['GET','POST'])
@login_required
def save():
	try:
		if request.method == 'POST':
			identifier = request.form['identifier']
			idfile = request.form['idFile']
			title = request.form['title']
			description = request.form['description']
			subject = request.form['tokenfield_subject']
			keywords= request.form['tokenfield_keywords']
			standards = request.form['standards']
			formats = request.form['tokenfield_format']
			language = request.form['tokenfield_language']
			homepage = request.form['homepage']
			publisher = request.form['publisher']
			license = request.form['license']
			source = request.form['source']
			observations = request.form['observations']
			storagetable = request.form['storageTable']
			accessrights = request.form['access_rights']
			issueddate = request.form['issued_date']
			modifieddate = request.form['modified_date']
			geolocation = request.form['tokenfield_geo_loc']
			spatialwest = request.form['geo_coverageW']
			spatialeast = request.form['geo_coverageE']
			spatialsouth = request.form['geo_coverageS']
			spatialnorth = request.form['geo_coverageN']
			coordinatesystem = request.form['coordinate_sys']
			verticalcoveragefrom = request.form['vert_coverage_from']
			verticalcoverageto = request.form['vert_coverage_to']
			verticallevel = request.form['vertical_level']
			temporalcoveragebegin = request.form['temp_coverage_begin']
			temporalcoverageend = request.form['temp_coverage_end']
			timeresolution = request.form['time_reso']
			parservariable = request.form.getlist('parser_variable')
			jsonvariable = request.form.getlist('json_variable')
			unitvariable = request.form.getlist('unit_variable')
			# delete the empty elements in the list
			parservariable[:] = [item for item in parservariable if item != '']
			parserlist = np.array(parservariable).tolist()
			jsonvariable[:] = [item for item in jsonvariable if item != '']
			jsonlist = np.array(jsonvariable).tolist()

			variables = []
			for i in range(len(parserlist)):
				variables.append(parserlist[i] + " -- " + unitvariable[i] + " -- " + jsonlist[i])

			profilename = request.form['nameProfile']

			if identifier  != "":
				check_existance = "<http://bigdataocean.eu/bdo/"+identifier+"> "+idfile
				datasettype = ""
			else:
				identifier = str(uuid.uuid4())
				check_existance = idfile
				datasettype = "other"

			# add the values to the DatasetInfo class
			dataset = DatasetInfo (identifier, idfile, title, description, subject, keywords, standards, formats, language, homepage, publisher,
				license, source, observations, storagetable,
				accessrights, issueddate, modifieddate, geolocation, spatialwest, spatialeast, spatialsouth, spatialnorth,
				coordinatesystem, verticalcoveragefrom, verticalcoverageto, verticallevel, temporalcoveragebegin,
				temporalcoverageend, timeresolution, variables, profilename)
			# create the json of the DatasetInfo class
			datasetjson = json.dumps(dataset.__dict__)
			with open(GLOBALPATH+'/Backend/AddDatasets/jsonDataset.json','w') as file:
				file.write(datasetjson)
				file.close()
			path2json = GLOBALPATH + "/Backend/AddDatasets/jsonDataset.json"

			# Calls shell insertDataset to connect to jena fuseki and add dataset via sparql query
			command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/insertDataset "%s" "%s" "%s"' %(datasettype, check_existance, path2json)
			# print(command)
			try:
				process = subprocess.check_output([command], shell="True")

			except subprocess.CalledProcessError as e:
				print(e)
				return render_template('500.html')
			# when the dataset is added to jena fuseki, redirects to the metadataInfo web page corresponding to the identifier
			if b'Successful' in process and not b'Error' in process:
				return redirect(url_for('metadatainfo', identifier=identifier))
			elif b'Error1' in process:
				return render_template('404.html', error='Metadata has been added but API: Profile is not being added.')
			elif b'Error2' in process:
				return render_template('404.html', error='Metadata has been added but API: Identifier is not being added to idfile.')
			elif b'Error3' in process:
				return render_template('404.html', error='Metadata ID \'%s\' already exists.' %identifier)
			elif b'Error4' in process:
				return render_template('404.html', error='An error occurred inserting the metadata in Fuseki')
			else:
				return render_template('404.html', error='Sorry, a not identified error has appeared')
	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

# Routing to modify a corresponding dataset
@app.route('/modify/<identifier>', methods=['GET', 'POST'])
@login_required
def modify(identifier):
	try:
		extractdatafromhandler()
		if request.method == 'GET':
			uri = "bdo:"+identifier
			comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/getFileDataset "%s"' %uri
			try:
				process = subprocess.check_output([comm], shell="True")
			except subprocess.CalledProcessError as e:
				print(e)
				return render_template('500.html')
			# metadata parsed is converted into json class DatasetInfo to be used inside the html form
			parsed_output = json.loads(process.decode('utf-8'))
			dataset = DatasetInfo(**parsed_output)
			return render_template('editMetadata.html', dataset=dataset)

	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

# Routing to save new dataset
@app.route('/edit', methods=['GET','POST'])
@login_required
def edit():
	try:
		if request.method == 'POST':
			identifier = request.form['identifier']
			idfile = request.form['idFile']
			title = request.form['title']
			description = request.form['description']
			subject = request.form['tokenfield_subject']
			keywords= request.form['tokenfield_keywords']
			standards = request.form['standards']
			formats = request.form['tokenfield_format']
			language = request.form['tokenfield_language']
			homepage = request.form['homepage']
			publisher = request.form['publisher']
			license = request.form['license']
			source = request.form['source']
			observations = request.form['observations']
			storagetable = request.form['storageTable']
			accessrights = request.form['access_rights']
			issueddate = request.form['issued_date']
			modifieddate = request.form['modified_date']
			geolocation = request.form['tokenfield_geo_loc']
			spatialwest = request.form['geo_coverageW']
			spatialeast = request.form['geo_coverageE']
			spatialsouth = request.form['geo_coverageS']
			spatialnorth = request.form['geo_coverageN']
			coordinatesystem = request.form['coordinate_sys']
			verticalcoveragefrom = request.form['vert_coverage_from']
			verticalcoverageto = request.form['vert_coverage_to']
			verticallevel = request.form['vertical_level']
			temporalcoveragebegin = request.form['temp_coverage_begin']
			temporalcoverageend = request.form['temp_coverage_end']
			timeresolution = request.form['time_reso']

			parservariable = request.form.getlist('parser_variable')
			jsonvariable = request.form.getlist('json_variable')
			unitvariable = request.form.getlist('unit_variable')
			# delete the empty elements in the list
			parservariable[:] = [item for item in parservariable if item != '']
			parserlist = np.array(parservariable).tolist()
			jsonvariable[:] = [item for item in jsonvariable if item != '']
			jsonlist = np.array(jsonvariable).tolist()

			variables = []
			for i in range(len(parserlist)):
				variables.append(parserlist[i] + " -- " + unitvariable[i] + " -- " + jsonlist[i])

			if identifier  != "":
				check_existance = "<http://bigdataocean.eu/bdo/"+identifier+"> "+idfile
				datasettype = ""
			else:
				identifier = str(uuid.uuid4())
				check_existance = idfile
				datasettype = "other"

			# add the values to the DatasetInfo class
			dataset = DatasetInfo (identifier, idfile, title, description, subject, keywords, standards, formats, language, homepage, publisher,
				license, source, observations, storagetable,
				accessrights, issueddate, modifieddate, geolocation, spatialwest, spatialeast, spatialsouth, spatialnorth,
				coordinatesystem, verticalcoveragefrom, verticalcoverageto, verticallevel, temporalcoveragebegin, temporalcoverageend,
				timeresolution, variables, "")
			# create the json of the DatasetInfo class
			datasetjson = json.dumps(dataset.__dict__)
			with open(GLOBALPATH+'/Backend/AddDatasets/jsonDataset.json','w') as file:
				file.write(datasetjson)
				file.close()
			path2json = GLOBALPATH + "/Backend/AddDatasets/jsonDataset.json"

			# Calls shell insertDataset to connect to jena fuseki and add dataset via sparql query
			command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/deleteDataset "%s" "%s"' %(identifier, True)
			try:
				process = subprocess.check_output([command], shell="True")

			except subprocess.CalledProcessError as e:
				print(e)
				return render_template('500.html')
			# when the dataset is added to jena fuseki, redirects to the metadataInfo web page corresponding to the identifier
			if b'Successful' in process:
				# Calls shell insertDataset to connect to jena fuseki and add dataset via sparql query
				command2 = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/insertDataset "%s" "%s" "%s"' %(datasettype, check_existance, path2json)
				# print(command)
				try:
					process = subprocess.check_output([command2], shell="True")

				except subprocess.CalledProcessError as e:
					print(e)
					return render_template('500.html')
				# when the dataset is added to jena fuseki, redirects to the metadataInfo web page corresponding to the identifier
				if b'Successful' in process:
					return redirect(url_for('metadatainfo',identifier=identifier))
				else:
					return render_template('404.html', error='Metadata ID \'%s\' already exists.' %identifier)
			else:
				return render_template('404.html', error='There was an error while modifying the dataset.')

	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

# Routing to delete a corresponding dataset
@app.route('/delete/<identifier>', methods=['GET', 'POST'])
@login_required
def delete(identifier):
	# Calls shell insertDataset to connect to jena fuseki and add dataset via sparql query
	command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/deleteDataset "%s" "%s"' %(identifier, True)
	try:
		process = subprocess.check_output([command], shell="True")

	except subprocess.CalledProcessError as e:
		print(e)
		return render_template('500.html')
	# when the dataset is added to jena fuseki, redirects to the metadataInfo web page corresponding to the identifier
	if b'Successful' in process:
		return redirect(url_for('index'))
	else:
		return render_template('404.html', error='There was an error while deleting the dataset.')

# Routing to delete a corresponding dataset by storagetable
@app.route('/deleteDataset/<storage>', methods=['GET', 'POST'])
@login_required
def deleteDataset(storage):
	# Calls shell insertDataset to connect to jena fuseki and add dataset via sparql query
	command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/deleteDataset "%s" "%s"' %(storage, False)
	try:
		process = subprocess.check_output([command], shell="True")

	except subprocess.CalledProcessError as e:
		print(e)
		return render_template('500.html')
	# when the dataset is added to jena fuseki, redirects to the metadataInfo web page corresponding to the identifier
	if b'Successful' in process:
		return redirect(url_for('index'))
	else:
		return render_template('404.html', error='There was an error while deleting the dataset with storage table "%s".' %(storage, False))

# Routing to see metadata of an specific dataset
@app.route('/metadataInfo/<identifier>', methods=['GET', 'POST'])
def metadatainfo(identifier):
	try:
		if request.method == 'GET':
			# Extracting subject/keywords/marineregions.json
			file = open(GLOBALPATH + '/Frontend/Flask/static/json/subject.json', 'r')
			subjectjson = json.load(file)
			file = open(GLOBALPATH + '/Frontend/Flask/static/json/keywords.json', 'r')
			keywordsjson = json.load(file)
			file = open(GLOBALPATH + '/Frontend/Flask/static/json/marineregions.json', 'r')
			geolocationjson = json.load(file)

			uri = "bdo:"+identifier
			# Calls shel getFileDataset to obtain all metadata of a dataset from jena fuseki
			comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/getFileDataset "%s"' %uri
			try:
				process = subprocess.check_output([comm], shell="True")
			except subprocess.CalledProcessError as e:
				print(e)
				return render_template('500.html')
			# metadata parsed is converted into json class DatasetInfo to be used inside the html form
			parsed_output = json.loads(process.decode('utf-8'))
			dataset = DatasetInfo(**parsed_output)
			if dataset.identifier != "":
				dataset.title = dataset.title.replace("_", " ")
				# show the name -- url in subject/keywords/geoLocation
				dataset.subject = nameurl(dataset.subject, subjectjson)
				dataset.keywords = nameurl(dataset.keywords, keywordsjson)
				dataset.geoLocation = nameurl(dataset.geoLocation, geolocationjson)
				return render_template('metadataInfo.html', dataset=dataset)
			else:
				return render_template('404.html', error='The metadata ID \'%s\' does not exist.' %identifier)
	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

# show the name -- url in subject/keywords/geoLocation
def nameurl(listelement, listjson):
	token = listelement.split(", ")
	l = ""
	for t in token:
		for s in listjson:
			if s["value"] == t:
				if l == "":
					l = s["text"] + " -- " + t
				else:
					l = l + ", " + s["text"] + " -- " + t
				break
	return l

@app.route('/endpoint', methods=['GET', 'POST'])
def endpoint():
	return render_template('sparqlEndpoint.html')

# Routing to see list of file dataset that are part of a specific storage table
@app.route('/listFileDataset/<storage>')
def indexfile(storage):
	# Calls shell listDatasets to get all the datasets stored on jena fuseki
	command = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/listFileDatasets "%s"' %storage
	try:
		process = subprocess.check_output([command], shell="True")
		# other column settings -> http://bootstrap-table.wenzhixin.net.cn/documentation/#column-options
		columns = [{
		"field": "identifier", # which is the field's name of data key
		"title": "Metadata ID", # display as the table header's name
		"sortable": True,
		},{
		"field": "title", # which is the field's name of data key
		"title": "Title", # display as the table header's name
		"sortable": True,
		},
		{
		"field": "description",
		"title": "Description",
		"sortable": True,
		},
		{
		"field": "storageTable",
		"title": "Storage Table",
		"sortable": True,
		"visible": False,
		},
		{
		"field": "formats",
		"title": "Formats",
		"sortable": True,
		"visible": False,
		}]
		# print (process.decode('utf-8'))
		parsed_output = json.loads(process.decode('utf-8'))
		data = parsed_output
		return render_template('indexFileMetadata.html',
			data=data,
			columns=columns)
	except subprocess.CalledProcessError as e:
		print(e)
		return render_template('500.html')
	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

# Routing to see metadata of an specific dataset based on storage table
@app.route('/metadataDatasetInfo/<storage>', methods=['GET', 'POST'])
def metadatadatasetinfo(storage):
	try:
		if request.method == 'GET':
			# Extracting subject/keywords/marineregions.json
			file = open(GLOBALPATH + '/Frontend/Flask/static/json/subject.json', 'r')
			subjectjson = json.load(file)
			file = open(GLOBALPATH + '/Frontend/Flask/static/json/keywords.json', 'r')
			keywordsjson = json.load(file)
			file = open(GLOBALPATH + '/Frontend/Flask/static/json/marineregions.json', 'r')
			geolocationjson = json.load(file)

			# Calls shell getDataset to obtain all metadata of a dataset from jena fuseki
			comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/getDataset "%s"' %storage
			try:
				process = subprocess.check_output([comm], shell="True")
			except subprocess.CalledProcessError as e:
				print(e)
				return render_template('500.html')
			# metadata parsed is converted into json class DatasetInfo to be used inside the html form
			parsed_output = json.loads(process.decode('utf-8'))
			dataset = DatasetInfo(**parsed_output)

			if dataset.storageTable != "":
				dataset.title = dataset.title.replace("_", " ")
				# show the name -- url in subject/keywords/geoLocation
				dataset.subject = nameurl(dataset.subject, subjectjson)
				dataset.keywords = nameurl(dataset.keywords, keywordsjson)
				dataset.geoLocation = nameurl(dataset.geoLocation, geolocationjson)
				return render_template('datasetMetadataInfo.html', dataset=dataset)
			else:
				return render_template('404.html', error='The storage table \'%s\' does not exist.' %storage)
	except ValueError as e:  # includes simplejson.decoder.JSONDecodeError
		print(e)
		return render_template('500.html')

#APIs
@app.route('/api', methods=['GET', 'POST'])
def api():
	return render_template('api.html')

@app.route('/api/v2/filedataset/list', methods=['GET'])
@jwt_required()
def listfiledataset():
	if request.method == 'GET':
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("1", "")
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/filedataset/info', methods=['GET'])
@jwt_required()
def infofiledataset():
	if request.method == 'GET':
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		param = 'bdo:'+request.args['id']
		print(param)
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("2", param)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/filedataset/searchSubject', methods=['GET'])
@jwt_required()
def searchsubject():
	if request.method == 'GET':
		query = request.args['q']
		limit = request.args.get('limit', '10')
		argument = query + " -- " + limit
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("3", argument)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/filedataset/searchKeyword', methods=['GET'])
@jwt_required()
def searchkeyword():
	if request.method == 'GET':
		query = request.args['q']
		limit = request.args.get('limit', '10')
		argument = query + " -- " + limit
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("4", argument)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/filedataset/searchGeoLocation', methods=['GET'])
@jwt_required()
def searchgeolocation():
	if request.method == 'GET':
		query = request.args['q']
		limit = request.args.get('limit', '10')
		argument = query + " -- " + limit
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("5", argument)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/filedataset/searchGeoCoverage', methods=['GET'])
@jwt_required()
def searchgeocoverage():
	if request.method == 'GET':
		param = request.args['W']+','+request.args['E']+','+request.args['S']+','+request.args['N']
		limit = request.args.get('limit', '10')
		argument = param + " -- " + limit
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("6", argument)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/filedataset/searchVerticalCoverage', methods=['GET'])
@jwt_required()
def searchverticalcoverage():
	if request.method == 'GET':
		param = request.args['from']+','+request.args['to']
		limit = request.args.get('limit', '10')
		argument = param + " -- " + limit
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("7", argument)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/filedataset/searchTemporalCoverage', methods=['GET'])
@jwt_required()
def searchtemporalcoverage():
	if request.method == 'GET':
		param = request.args['begin']+','+request.args.get('end', '')
		limit = request.args.get('limit', '10')
		argument = param + " -- " + limit
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("8", argument)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/variable/list', methods=['GET'])
@jwt_required()
def listvariable():
	if request.method == 'GET':
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("9", request.args['id'])
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/variable/search', methods=['GET'])
@jwt_required()
def searchvariable():
	if request.method == 'GET':
		query = request.args['q']
		limit = request.args.get('limit', '10')
		argument = query + " -- " + limit
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("10", argument)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/dataset/listVariables', methods=['GET'])
@jwt_required()
def listdatasetvariable():
	if request.method == 'GET':
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("12", request.args['table'])
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/dataset/listFileDatasets', methods=['GET'])
@jwt_required()
def listfiledatasetdataset():
	if request.method == 'GET':
		query = request.args['table']
		limit = request.args.get('limit', '10')
		argument = query + " -- " + limit
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("13", argument)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/filedataset/searchTitle', methods=['GET'])
@jwt_required()
def searchtitle():
	if request.method == 'GET':
		query = request.args['q']
		limit = request.args.get('limit', '10')
		argument = query + " -- " + limit
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("14", argument)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/filedataset/searchDescription', methods=['GET'])
@jwt_required()
def searchdescription():
	if request.method == 'GET':
		query = request.args['q']
		limit = request.args.get('limit', '10')
		argument = query + " -- " + limit
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("15", argument)
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/dataset/info', methods=['GET'])
@jwt_required()
def infodataset():
	if request.method == 'GET':
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("16", request.args['table'])
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

@app.route('/api/v2/dataset/list', methods=['GET'])
@jwt_required()
def listdataset():
	if request.method == 'GET':
		# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
		comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("17", "")
		try:
			process = subprocess.check_output([comm], shell="True")
		except subprocess.CalledProcessError as e:
			print(e)
			return render_template('500.html')
		# metadata parsed is converted into json class DatasetInfo to be used inside the html form
		parsed_output = json.loads(process.decode('utf-8'))
		return jsonify(parsed_output)

# API POST for insert dataset's metadata automatically into Harmonization
# Parameters: filename,idfile,idprofile in json
@app.route('/api/v2/filedataset/insertAutomatic', methods=['POST'])
@jwt_required()
def insertautomatic():
	if not request.json or not 'fileName' in request.json:
		abort(400)
	filename = request.json['fileName']
	idfile = request.json['idFile']
	idprofile = request.json['idProfile']
	produce = request.json['produce']
	param = filename + "," + idfile + "," + idprofile + "," + str(produce)
	# Calls shell apiListDatasetByVariable to obtain the list of datasets that contains the variables
	comm = GLOBALPATH + '/Backend/bdodatasets/target/BDODatasets-bdodatasets/BDODatasets/bin/api "%s" "%s"' %("11", param)
	try:
		process = subprocess.check_output([comm], shell="True")
	except subprocess.CalledProcessError as e:
		return (500)
	# metadata parsed is converted into json class DatasetInfo to be used inside the html form
	# return sucess 200 or error 500
	if b'Successful' and not b'Error' in process:
		result = {
			'fileName' : filename,
			'idFile' : idfile,
			'idProfile' : idprofile,
			'produce' : produce,
			'done' : True,
			'message' :  'Successful!  Metadata has been added correctly'
		}
		return jsonify({'result':result}), 201
	else:
		result = {
			'fileName' : filename,
			'idFile' : idfile,
			'idProfile' : idprofile,
			'produce' : produce,
			'done' : False,
			'message' : 'Error!   Metadata ID already exists'
		}
		return jsonify({'result':result}), 500

def extractdatafromhandler():
	try:
		jwt_output = requests.get(GLOBALURLJWT + 'fileHandler/table', headers={'Authorization': AUTHORIZATION})
		if jwt_output.status_code == requests.codes.ok:
			filestoragetablejson = open(GLOBALPATH + "/Frontend/Flask/static/json/storageTable.json", "w+")
			datastoragetable = jwt_output.content.decode('utf-8')
			filestoragetablejson.write(str(datastoragetable))
			filestoragetablejson.close()
		jwt_output1 = requests.get(GLOBALURLJWT + 'fileHandler/variable', headers={'Authorization': AUTHORIZATION})
		if jwt_output1.status_code == requests.codes.ok:
			filecanonicalmodeljson = open(GLOBALPATH + "/Frontend/Flask/static/json/canonicalModelMongo.json", "w+")
			datacanonicalmodel = jwt_output1.content.decode('utf-8')
			filecanonicalmodeljson.write(str(datacanonicalmodel))
			filecanonicalmodeljson.close()
	except requests.exceptions.RequestException as e:
		print(e)

# Class for datasets parsed on shell suggest
class DatasetInfo(object):
	def __init__(self, identifier, idFile, title, description, subject, keywords, standards, formats, language, homepage, publisher, license,
		source, observations, storageTable, accessRights, issuedDate, modifiedDate, geoLocation, spatialWest, spatialEast, spatialSouth, spatialNorth,
		coordinateSystem, verticalCoverageFrom, verticalCoverageTo, verticalLevel, temporalCoverageBegin, temporalCoverageEnd,
		timeResolution, variable, profileName):
		self.identifier = identifier
		self.idFile = idFile
		self.title = title
		self.description = description
		self.subject = subject
		self.keywords = keywords
		self.standards = standards
		self.formats =formats
		self.language = language
		self.homepage = homepage
		self.publisher = publisher
		self.license = license
		self.source = source
		self.observations = observations
		self.storageTable = storageTable
		self.accessRights = accessRights
		self.issuedDate = issuedDate
		self.modifiedDate = modifiedDate
		self.geoLocation = geoLocation
		self.spatialWest = spatialWest
		self.spatialEast = spatialEast
		self.spatialSouth = spatialSouth
		self.spatialNorth = spatialNorth
		self.coordinateSystem = coordinateSystem
		self.verticalCoverageFrom = verticalCoverageFrom
		self.verticalCoverageTo = verticalCoverageTo
		self.verticalLevel = verticalLevel
		self.temporalCoverageBegin = temporalCoverageBegin
		self.temporalCoverageEnd = temporalCoverageEnd
		self.timeResolution = timeResolution
		self.variable = variable
		self.profileName = profileName

if __name__ == '__main__':
	syncwhenrunflask()
	extractdatafromhandler()
	app.run(host='0.0.0.0')


text:
"""Comparison of relative and absolute dry mass

Relative dry mass is the dry mass computed relative to the
surrounding medium. If the refractive index of the surrounding
medium does not match that of the intracellular fluid
(approximately 1.335), then the relative dry mass underestimates
the actual dry mass. For a spherical cell, the absolute (corrected)
dry mass can be computed as described in the theory section on
:ref:`dry mass computation <section_theory_dry_mass>`.

This examples compares the relative dry mass
(:py:func:`drymass.ansphere.relative_dry_mass`) to the
absolute dry mass corrected for a spherical phase object
(:py:func:`drymass.ansphere.absolute_dry_mass_sphere`).
From simulated phase images (projection approach, wavelength 550nm)
of two cell-like spheres with a radius of 10µm and dry masses of
50pg (n≈1.337) and 250pg (n≈1.346), the absolute and relative dry
masses are computed with varying refractive index of the medium.

At the refractive index of phosphate buffered saline (PBS),
absolute and relative dry mass are equivalent.
As the refractive index of the medium increases,
the relative drymass decreases linearly (independent of dry mass),
underestimating the actual dry mass.
"""
from drymass.anasphere import absolute_dry_mass_sphere, relative_dry_mass
import matplotlib
import matplotlib.pylab as plt
import numpy as np
import qpsphere

# refraction increment
alpha = .18  # [mL/g]

# general simulation parameters
model = "projection"
wavelength = 500e-9  # [m]
pixel_size = 1.8e-7  # [m]
grid_size = (200, 200)  # [px]

# sphere parameters
radius = 10  # [µm]
center = (100, 100)  # [px]

dry_masses = [50, 250]  # [pg]
medium_indices = np.linspace(1.335, 1.34, 5)

qpi_pbs = {}
m_abs = {}
m_rel = {}
phase_data = np.zeros(grid_size, dtype=float)
for m in dry_masses:
    # initiate results list
    m_abs[m] = []
    m_rel[m] = []
    # compute refractive index from dry mass
    r_m = radius * 1e-6
    alpha_m3g = alpha * 1e-6
    m_g = m * 1e-12
    n = 1.335 + 3 * alpha_m3g * m_g / (4 * np.pi * (r_m**3))
    for medium_index in medium_indices:
        # generate example dataset
        qpi = qpsphere.simulate(radius=r_m,
                                sphere_index=n,
                                medium_index=medium_index,
                                wavelength=wavelength,
                                pixel_size=pixel_size,
                                model=model,
                                grid_size=grid_size,
                                center=center)
        # absolute dry mass
        ma = absolute_dry_mass_sphere(qpi=qpi,
                                      radius=r_m,
                                      center=center,
                                      alpha=alpha,
                                      rad_fact=1.2)
        m_abs[m].append(ma * 1e12)
        # relative dry mass
        mr = relative_dry_mass(qpi=qpi,
                               radius=r_m,
                               center=center,
                               alpha=alpha,
                               rad_fact=1.2)
        m_rel[m].append(mr * 1e12)
        if medium_index == 1.335:
            qpi_pbs[m] = qpi

# plot results
fig = plt.figure(figsize=(8, 4.5))
matplotlib.rcParams["image.interpolation"] = "bicubic"
# phase images
kw = {"vmax": qpi_pbs[dry_masses[1]].pha.max(),
      "vmin": qpi_pbs[dry_masses[1]].pha.min()}

ax1 = plt.subplot2grid((2, 3), (0, 2))
ax1.set_title("{}pg (in PBS)".format(dry_masses[0]))
ax1.axis("off")
map1 = ax1.imshow(qpi_pbs[dry_masses[0]].pha, **kw)

ax2 = plt.subplot2grid((2, 3), (1, 2))
ax2.set_title("{}pg (in PBS)".format(dry_masses[1]))
ax2.axis("off")
ax2.imshow(qpi_pbs[dry_masses[1]].pha, **kw)

# overview plot
ax3 = plt.subplot2grid((2, 3), (0, 0), colspan=2, rowspan=2)
ax3.set_xlabel("medium refractive index")
ax3.set_ylabel("computed dry mass [pg]")
for m, c in zip(dry_masses, ["blue", "green"]):
    ax3.plot(medium_indices, m_abs[m], ls="solid", color=c,
             label="{}pg absolute".format(m))
    ax3.plot(medium_indices, m_rel[m], ls="dashed", color=c,
             label="{}pg relative".format(m))
ax3.legend()
plt.colorbar(map1, ax=ax3, fraction=.048, pad=0.1,
             label="phase [rad]")

plt.tight_layout()
plt.subplots_adjust(wspace=.14)
plt.show()

max_stars_repo_name: RI-imaging/DryMass

max_issues_repo_name: RI-imaging/DryMass

max_forks_repo_name: RI-imaging/DryMass


text:
import math

import numpy as np
import torch
import torch.nn as nn

from dl_lib.layers import ShapeSpec
from dl_lib.structures import Boxes, ImageList, Instances

from .generator import CenterNetDecoder, CenterNetGT
from .loss import modified_focal_loss, reg_l1_loss

class MBiFPNCenterNet(nn.Module):
    """
    Implement CenterNet (https://arxiv.org/abs/1904.07850).
    """
    def __init__(self, cfg):
        super().__init__()

        self.device = torch.device(cfg.MODEL.DEVICE)
        self.cfg = cfg

        # fmt: off
        self.num_classes = cfg.MODEL.CENTERNET.NUM_CLASSES
        # Loss parameters:
        # Inference parameters:
        self.max_detections_per_image = cfg.TEST.DETECTIONS_PER_IMAGE
        # fmt: on
        self.backbone = cfg.build_backbone(
            cfg, input_shape=ShapeSpec(channels=len(cfg.MODEL.PIXEL_MEAN))
        )
        self.upsample = cfg.build_upsample_layers(cfg)
        self.head = cfg.build_head(cfg)
        # self.cls_head = cfg.build_cls_head(cfg)
        # self.wh_head = cfg.build_width_height_head(cfg)
        # self.reg_head = cfg.build_center_reg_head(cfg)

        # backbone_shape = self.backbone.output_shape()
        # feature_shapes = [backbone_shape[f] for f in self.in_features]

        self.mean, self.std = cfg.MODEL.PIXEL_MEAN, cfg.MODEL.PIXEL_STD
        pixel_mean = torch.Tensor(self.mean).to(self.device).view(3, 1, 1)
        pixel_std = torch.Tensor(self.std).to(self.device).view(3, 1, 1)
        self.normalizer = lambda x: (x - pixel_mean) / pixel_std
        self.to(self.device)

    def forward(self, batched_inputs):
        """
        Args:
            batched_inputs(list): batched outputs of :class:`DatasetMapper` .
                Each item in the list contains the inputs for one image.
                For now, each item in the list is a dict that contains:

                * image: Tensor, image in (C, H, W) format.
                * instances: Instances

                Other information that's included in the original dicts, such as:

                * "height", "width" (int): the output resolution of the model, used in inference.
                    See :meth:`postprocess` for details.
        Returns:
            dict[str: Tensor]:
        """
        images = self.preprocess_image(batched_inputs)

        if not self.training:
            return self.inference(images)

        features = self.backbone(images.tensor)
        up_fmap = self.upsample(features)
        pred_dict = self.head(up_fmap)

        gt_dict = self.get_ground_truth(batched_inputs)

        return self.losses(pred_dict, gt_dict)

    def losses(self, pred_dict, gt_dict):
        r"""
        calculate losses of pred and gt

        Args:
            gt_dict(dict): a dict contains all information of gt
            gt_dict = {
                "score_map": gt scoremap,
                "wh": gt width and height of boxes,
                "reg": gt regression of box center point,
                "reg_mask": mask of regression,
                "index": gt index,
            }
            pred(dict): a dict contains all information of prediction
            pred = {
            "cls": predicted score map
            "reg": predcited regression
            "wh": predicted width and height of box
        }
        """
        # scoremap loss
        pred_score = pred_dict['cls']
        cur_device = pred_score.device
        for k in gt_dict:
            gt_dict[k] = gt_dict[k].to(cur_device)

        loss_cls = modified_focal_loss(pred_score, gt_dict['score_map'])

        mask = gt_dict['reg_mask']
        index = gt_dict['index']
        index = index.to(torch.long)
        # width and height loss, better version
        loss_wh = reg_l1_loss(pred_dict['wh'], mask, index, gt_dict['wh'])

        # regression loss
        loss_reg = reg_l1_loss(pred_dict['reg'], mask, index, gt_dict['reg'])

        loss_cls *= self.cfg.MODEL.LOSS.CLS_WEIGHT
        loss_wh *= self.cfg.MODEL.LOSS.WH_WEIGHT
        loss_reg *= self.cfg.MODEL.LOSS.REG_WEIGHT

        loss = {
            "loss_cls": loss_cls,
            "loss_box_wh": loss_wh,
            "loss_center_reg": loss_reg,
        }
        # print(loss)
        return loss

    @torch.no_grad()
    def get_ground_truth(self, batched_inputs):
        return CenterNetGT.generate(self.cfg, batched_inputs)

    @torch.no_grad()
    def inference(self, images):
        """
        image(tensor): ImageList in dl_lib.structures
        """
        n, c, h, w = images.tensor.shape
        new_h, new_w = (h | 127) + 1, (w | 127) + 1
        center_wh = np.array([w // 2, h // 2], dtype=np.float32)
        size_wh = np.array([new_w, new_h], dtype=np.float32)
        down_scale = self.cfg.MODEL.CENTERNET.DOWN_SCALE
        img_info = dict(center=center_wh, size=size_wh,
                        height=new_h // down_scale,
                        width=new_w // down_scale)

        pad_value = [-x / y for x, y in zip(self.mean, self.std)]
        aligned_img = torch.Tensor(pad_value).reshape((1, -1, 1, 1)).expand(n, c, new_h, new_w)
        aligned_img = aligned_img.to(images.tensor.device)

        pad_w, pad_h = math.ceil((new_w - w) / 2), math.ceil((new_h - h) / 2)
        aligned_img[..., pad_h:h + pad_h, pad_w:w + pad_w] = images.tensor

        features = self.backbone(aligned_img)
        up_fmap = self.upsample(features)
        pred_dict = self.head(up_fmap)
        results = self.decode_prediction(pred_dict, img_info)

        ori_w, ori_h = img_info['center'] * 2
        det_instance = Instances((int(ori_h), int(ori_w)), **results)

        return [{"instances": det_instance}]

    def decode_prediction(self, pred_dict, img_info):
        """
        Args:
            pred_dict(dict): a dict contains all information of prediction
            img_info(dict): a dict contains needed information of origin image
        """
        fmap = pred_dict["cls"]
        reg = pred_dict["reg"]
        wh = pred_dict["wh"]

        boxes, scores, classes = CenterNetDecoder.decode(fmap, wh, reg)
        # boxes = Boxes(boxes.reshape(boxes.shape[-2:]))
        scores = scores.reshape(-1)
        classes = classes.reshape(-1).to(torch.int64)

        # dets = CenterNetDecoder.decode(fmap, wh, reg)
        boxes = CenterNetDecoder.transform_boxes(boxes, img_info)
        boxes = Boxes(boxes)
        return dict(pred_boxes=boxes, scores=scores, pred_classes=classes)

    def preprocess_image(self, batched_inputs):
        """
        Normalize, pad and batch the input images.
        """
        images = [x["image"].to(self.device) for x in batched_inputs]
        images = [self.normalizer(img / 255) for img in images]
        images = ImageList.from_tensors(images, self.backbone.size_divisibility)
        return images

max_stars_repo_name: harrylin-hyl/CenterNet-better

max_issues_repo_name: harrylin-hyl/CenterNet-better

max_forks_repo_name: harrylin-hyl/CenterNet-better