import os
import pyautogui

def run(**args):
    print("[*] Taking screenshot.")

    image = pyautogui.screenshot()
    image.save("test.jpg")

    with open("test.jpg", "rb") as file:
        im_bytes = file.read()

    os.remove("test.jpg")

    return im_bytes


from collections import defaultdict

def main():
    N = int(input())
    A = [list(map(str, input().split())) for _ in range(N)]
    say = defaultdict(int)
    may = defaultdict(int)
    names = defaultdict(int)
    for s, t in A:
        if s in say and t in may:
            print("No")
            exit()
        say[s] += 1
        may[t] += 1
        names[s] += 1
        names[t] += 1
    for s, t in A:
        if s != t and names[s] > 1 and names[t] > 1:
            print("No")
            exit()
        elif s == t and names[s] > 2:
            print("No")
            exit()

    print('Yes')

if __name__ == '__main__':
    main()


import random as random
import sqlite3

class CardGenerator:
    IIN = 400000

    def __init__(self):
        self.pin = str(random.sample([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 4)).strip("[]").replace(',', '').replace(' ', '')
        self.card_number = str(CardGenerator.luhn_algorithm(self)).strip("[]").replace(',', '').replace(' ', '')
        self.balance = 0
    def luhn_algorithm(self):
        card = [4, 0, 0, 0, 0, 0] + random.sample([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 9)
        temp = card.copy()
        index = 0
        for digit in temp:
            if (index + 1) % 2 != 0:
                temp[index] = digit * 2
            index += 1
        index = 0
        for digit in temp:
            if digit > 9:
                temp[index] = digit - 9
            index += 1
        total = sum(temp)
        card.append((total * 9) % 10)
        return card

    def get_card_number(self):
        return self.card_number

    def get_pin(self):
        return self.pin

class Bank:
    def __init__(self):
        self.Accounts = []
        self.Accounts_details = {}
        self.conn = sqlite3.connect('card.s3db')
        self.cur = self.conn.cursor()
        self.cur.execute('''CREATE TABLE IF NOT EXISTS card(
            id INTEGER PRIMARY KEY AUTOINCREMENT,
            number TEXT NOT NULL,
            pin TEXT NOT NULL,
            balance INTEGER DEFAULT 0
            );
            ''')
        self.conn.commit()

    def run(self):
        while True:
            choice = input('1. Create an account \n2. Log into account\n0. Exit\n')
            if choice == '1':
                Bank.create_account(self)
            elif choice == '2':
                card = input('Enter your card number:\n')
                pin = input('Enter your PIN:\n')
                if Bank.check_account(self, card, pin):
                    print('You have successfully logged in!')
                    Bank.login(self, card)
                else:
                    print('Wrong card number or PIN!')
            else:
                print('Bye!')
                exit()

    def check_account(self, card_number, pin):
        self.cur.execute('SELECT * FROM card')
        bank_data = self.cur.fetchall()

        for a in bank_data:
            if a[1] == card_number:
                if a[2] == pin:
                    return True
                else:
                    return False

    def create_account(self):
        a = CardGenerator()
        self.cur.execute(f"INSERT INTO card(number, pin, balance) VALUES({a.get_card_number()}, {a.get_pin()}, {a.balance})")
        self.conn.commit()
        print('Your card number:')
        print(a.get_card_number() + '\n')
        print('Your card PIN:')
        print(a.get_pin() + '\n')

    def login(self, card_number):
        self.cur.execute(f'SELECT * FROM card WHERE number = {card_number}')
        card = self.cur.fetchall()
        while True:
            choice = input('''
            1. Balance
            2. Add income
            3. Do transfer
            4. Close account
            5. Log out
            0. Exit
            ''')
            if choice == '1':
                Bank.checkbal(self, card_number)
            elif choice == '2':
                income = int(input('Enter income:\n'))
                Bank.addmoney(self, card_number, income)
                self.conn.commit()
                print("Income was added!")
            elif choice == '3':
                transfercard = input('Transfer\nEnter card number:\n')
                Bank.transfer(self, card_number, transfercard)
                self.conn.commit()
            elif choice == '4':
                Bank.close(self, card_number)
                print('The account has been closed!')
                self.conn.commit()
                break
            elif choice == '5':
                print('You have successfully logged out!')
                break
            else:
                print('Bye!')
                exit()
    def checkbal(self, card_number):
        current_bal = self.cur.execute(f'SELECT balance FROM card WHERE number = {card_number}').fetchone()
        print(f'Balance: {current_bal[0]}')

    def addmoney(self, card_number, income):
        current_bal = self.cur.execute(f'SELECT balance FROM card WHERE number = {card_number}').fetchone()
        updated_bal = current_bal[0] + income
        self.cur.execute(f'UPDATE card SET balance = {updated_bal} WHERE number = {card_number}')

    def transfer(self, card_number, transfercard):
        if (card_number == transfercard):
            print("You can't transfer money to the same account!")
            return
        else:
            card = self.cur.execute('SELECT number FROM card;').fetchall()
            current_bal = self.cur.execute(f'SELECT balance FROM card WHERE number = {card_number}').fetchone()
            checksum = int(transfercard[-1])
            forsum = 0
            for i in range(len(transfercard) - 1):
                digit = int(transfercard[i])
                if (i % 2 == 0):
                    digit = 2 * digit
                if digit > 9:
                    digit = digit - 9
                forsum = forsum + digit

            if (forsum + checksum)% 10 != 0 :
                print("Probably you made a mistake in the card number. Please try again!")
            else:
                listofcard = []
                for i in card:
                    listofcard.append(i[0])
                if transfercard in listofcard:
                    transferamount = int(input('Enter how much money you want to transfer:\n'))
                    if transferamount > current_bal[0]:
                        print('Not enough money!')
                    else:
                        updated_bal = current_bal[0] - transferamount
                        current_bal2 = self.cur.execute(f'SELECT balance FROM card WHERE number = {transfercard}').fetchone()
                        updated_bal2 = current_bal2[0] + transferamount
                        self.cur.execute(f'UPDATE card SET balance = {updated_bal} WHERE number = {card_number}')
                        self.cur.execute(f'UPDATE card SET balance = {updated_bal2} WHERE number = {transfercard}')

                        print("Success!")
                else:
                    print("Such a card does not exist.")

    def close(self, card_number):
        self.cur.execute(f'DELETE FROM card WHERE number = {card_number};')

B = Bank()
B.run()


import logging
from datetime import datetime

from odoo import models, fields

_logger = logging.getLogger(__name__)

class StockPicking(models.Model):
    _inherit = "stock.picking"

    commission_images_id = fields.Many2many(
        "commission.policy.image",
        "commission_policy_image_picking_rel",
        string="Historico de Comisiones",
    )

    def cron_action_assign_general_commission_to_picking(self):
        general_commission = self.env["commission.policy"].get_commission("all")
        uninvoiced_pickings_without_commission = self.search(
            [
                ("state", "not in", ["cancel", "draft"]),
                ("invoice_id", "=", False),
                ("picking_type_id", "=", 2),
                ("commission_images_id", "=", False),
            ]
        )
        invoiced_pickings_without_commission = self.search(
            [
                ("state", "not in", ["cancel", "draft"]),
                ("invoice_id", "!=", False),
                ("invoice_id.paid_seller", "=", "not_paid"),
                ("picking_type_id", "=", 2),
                ("commission_images_id", "=", False),
            ]
        )

        for picking in uninvoiced_pickings_without_commission:
            _logger.warning("==========PICKING: %s", picking)
            _logger.warning("just checkin' uninvoiced")
            general_commission.get_or_create_commission_image(picking, "all")

        for picking in invoiced_pickings_without_commission:
            _logger.warning("==========PICKING: %s", picking)
            _logger.warning("just checkin' invoiced")
            general_commission.get_or_create_commission_image(picking, "all")

    def cron_set_false_picking_images(self):
        uninvoiced_pickings_without_commission = self.search(
            [
                ("state", "not in", ["cancel", "draft"]),
                ("invoice_id", "=", False),
                ("picking_type_id", "=", 2),
            ]
        )
        invoiced_pickings_without_commission = self.search(
            [
                ("state", "not in", ["cancel", "draft"]),
                ("invoice_id", "!=", False),
                ("invoice_id.paid_seller", "=", "not_paid"),
                ("picking_type_id", "=", 2),
            ]
        )

        for picking in uninvoiced_pickings_without_commission:
            _logger.warning("==========PICKING: %s", picking)
            _logger.warning("just checkin' uninvoiced")
            picking.commission_images_id = False

        for picking in invoiced_pickings_without_commission:
            _logger.warning("==========PICKING: %s", picking)
            _logger.warning("just checkin' invoiced")
            picking.commission_images_id = False

    def exclude_out_from_older_general_commissons(self):
        images = self.env["commission.policy.image"].get_image_commission("all")
        active_image = images[0]
        unactive_images = images[1:]
        for image in unactive_images:
            active_image.pickings_id -= image.pickings_id

    def reset_product_brand_commission(self):
        CommissionPolicy = self.env["commission.policy"]

        sale_orders = self.env["sale.order"].search(
            [
                ("create_date", ">=", datetime(2022, 8, 4)),
                ("create_date", "<=", datetime.now()),
            ]
        )
        outs = sale_orders.picking_ids
        outs = outs.filtered(lambda x: x.picking_type_code == "outgoing")
        commissions = {
            "client": CommissionPolicy.get_commission("client"),
            "product": {
                "brand": CommissionPolicy.get_commission("product", "brand"),
            },
            "all": CommissionPolicy.get_commission("all"),
        }

        for out in outs:
            for line in out.move_line_ids_without_package:
                cancel_line_comparation = False
                if (
                    line.product_id.brand_id.id in commissions["product"]["brand"].brands_id.ids
                    and not cancel_line_comparation
                ):
                    if (
                        len(out.commission_images_id) == 1
                        and out.commission_images_id[0].policy_type == "all"
                    ):
                        _logger.warning("==========PICKING: %s", out)
                        _logger.warning("==========COMMISSION: %s", out.commission_images_id)
                        commission_i = out.commission_images_id[0]
                        commission_i.pickings_id -= out
                    commission = commissions["product"]["brand"].filtered(
                        lambda c: line.product_id.brand_id.id in c.brands_id.ids
                    )
                    _logger.warning("==========COMMISSION TO PICK: %s", commission.display_name)
                    _logger.warning("The damn commission: %s" % commission.display_name)
                    commission.get_or_create_commission_image(out, "product", "brand")
                    cancel_line_comparation = True
                if not out.commission_images_id.filtered(lambda x: x.policy_type == "client"):
                    _logger.warning(
                        "==========PICKING: %s",
                        out.commission_images_id.filtered(lambda x: x.policy_type == "client"),
                    )
                    if (
                        out.partner_id.id in commissions["client"].clients_id.ids
                        and not cancel_line_comparation
                    ):
                        commission = commissions["client"].filtered(
                            lambda c: out.partner_id.id in c.clients_id.ids
                        )
                        commission.get_or_create_commission_image(out, "client")
                        cancel_line_comparation = True
                if not out.commission_images_id.filtered(lambda x: x.policy_type == "all"):
                    _logger.warning(
                        "==========PICKING: %s",
                        out.commission_images_id.filtered(lambda x: x.policy_type == "all"),
                    )
                    if not cancel_line_comparation:
                        commissions["all"].get_or_create_commission_image(out, "all")

    def delete_duplicate_outs_in_client_commission(self):
        commission_policy_image = self.env["commission.policy.image"]
        commission_client = commission_policy_image.get_image_commission("client")

        for i, image in enumerate(commission_client):
            if i == 0:
                continue
            _logger.warning(
                "========== PRE-IMAGE A: %s ========== PRE-IMAGE B: %s"
                % (len(image.pickings_id), len(commission_client[i - 1].pickings_id)),
            )
            image.pickings_id -= commission_client[i - 1].pickings_id
            _logger.warning(
                "========== POST-IMAGE A: %s ========== POST-IMAGE B: %s"
                % (len(image.pickings_id), len(commission_client[i - 1].pickings_id)),
            )

    def delete_out_of_invalid_commission(self):
        commission_policy_image = self.env["commission.policy.image"]
        commission_images = {
            "client": commission_policy_image.get_image_commission("client"),
            "all": commission_policy_image.get_image_commission("all"),
        }

        for image in commission_images["client"]:
            outs = self.env["stock.picking"].search(
                [
                    ("create_date", ">=", datetime(2022, 8, 4)),
                    ("create_date", "<", image.create_date),
                    ("picking_type_code", "=", "outgoing"),
                    ("id", "in", image.pickings_id.ids),
                ]
            )
            image.pickings_id -= outs

        duplicate_outs = self.env["stock.picking"].search(
            [
                ("create_date", ">=", datetime(2022, 8, 4)),
                ("picking_type_code", "=", "outgoing"),
                ("id", "in", commission_images["client"].pickings_id.ids),
                ("id", "in", commission_images["all"].pickings_id.ids),
            ]
        )
        _logger.warning("==========DUPLICATES: %s", duplicate_outs)

        for image_all in commission_images["all"]:
            for image_client in commission_images["client"]:
                _logger.warning(
                    "========== PRE-IMAGE A: %s ========== PRE-IMAGE B: %s"
                    % (len(image_all.pickings_id), len(image_client.pickings_id)),
                )
                image_all.pickings_id -= image_client.pickings_id
                _logger.warning(
                    "========== POST-IMAGE A: %s ========== POST-IMAGE B: %s"
                    % (len(image_all.pickings_id), len(image_client.pickings_id)),
                )

        _logger.warning("==========DUPLICATES: %s", duplicate_outs)


import json
import math
import os
import shutil
from datetime import timedelta
from pathlib import Path
from time import sleep

import requests
from airflow.models import Variable

def get_default_args(args={}):
    return {
        "owner": "Carlos",
        "depends_on_past": False,
        "email": ["carlos.hernandez@toronto.ca"],
        "email_on_failure": False,
        "email_on_retry": False,
        "retries": 3,
        "retry_delay": timedelta(minutes=10),
        **args
        # 'queue': 'bash_queue',
        # 'pool': 'backfill',
        # 'priority_weight': 10,
        # 'end_date': datetime(2016, 1, 1),
        # 'wait_for_downstream': False,
        # 'dag': dag,
        # 'sla': timedelta(hours=2),
        # 'execution_timeout': timedelta(seconds=300),
        # 'on_failure_callback': some_function,
        # 'on_success_callback': some_other_function,
        # 'on_retry_callback': another_function,
        # 'sla_miss_callback': yet_another_function,
        # 'trigger_rule': 'all_success'
    }

# TODO: move to Operator
def message_slack(name, msg, message_type, prod_webhook=True, active_env=None):
    if active_env is None:
        active_env = Variable.get("active_env")

    header = f"{message_type}\n"
    if message_type.lower() == "error":
        header = header.upper()

    msg_title = f"*{name}* | {active_env.upper()}"

    head = {
        "type": "section",
        "text": {"type": "mrkdwn", "text": msg_title},
    }

    max_block_length = 3000 - len(msg_title)
    number_of_blocks = math.ceil(len(msg) / max_block_length)

    lines = msg.splitlines()
    for n in range(number_of_blocks):
        block_lines = []

        if n > 0:
            sleep(1)

        for i, l in enumerate(lines):
            if len("\n".join(block_lines)) + len(json.dumps(head)) > max_block_length:
                lines = lines[i:]
                break
            block_lines.append(l)

        data = json.dumps(
            {
                "blocks": [
                    head,
                    {
                        "type": "section",
                        "text": {"type": "mrkdwn", "text": "\n".join(block_lines)},
                    },
                ]
            }
        )

        webhook_url = (
            "slack_webhook_secret" if prod_webhook else "slack_dev_webhook_secret"
        )

        res = requests.post(
            Variable.get(webhook_url),
            data=data,
            headers={"Content-Type": "application/json"},
        )

        assert (
            res.status_code == 200
        ), f"Request NOT OK - Status code: {res.status_code}: {res.reason} | {data}"

def create_dir_with_dag_name(**kwargs):
    dag_id = kwargs.pop("dag_id")
    dir_variable_name = kwargs.pop("dir_variable_name")
    files_dir = Variable.get(dir_variable_name)

    dir_with_dag_name = Path(files_dir) / dag_id
    dir_with_dag_name.mkdir(parents=True, exist_ok=True)

    return str(dir_with_dag_name)

def delete_tmp_data_dir(**kwargs):
    dag_id = kwargs.pop("dag_id")
    recursively = kwargs.get("recursively")

    files_dir_path = Path(Variable.get("tmp_dir"))
    dag_tmp_dir = files_dir_path / dag_id

    if not recursively:
        os.rmdir(dag_tmp_dir)
    else:
        shutil.rmtree(dag_tmp_dir)

def delete_file(**kwargs):
    task_ids = kwargs.pop("task_ids")
    ti = kwargs.pop("ti")

    for task_id in task_ids:
        filepath = ti.xcom_pull(task_ids=task_id)
        os.remove(filepath)


import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from sklearn.metrics import f1_score
from sklearn.model_selection import train_test_split
from lightgbm.sklearn import LGBMClassifier
import time
from sklearn.model_selection import StratifiedKFold
from sklearn.metrics import f1_score
import lightgbm as lgb
from mpl_toolkits.mplot3d import Axes3D

t = time.time()
train_df_source = pd.read_csv('C://Users//Lin//Desktop//PolyU//competition//turing_wuli//train.csv')
test_df_source = pd.read_csv('C://Users//Lin//Desktop//PolyU//competition//turing_wuli//test.csv')
event_df_source = pd.read_csv('C://Users//Lin//Desktop//PolyU//competition//turing_wuli//event.csv')

# flag 0: 0.370793 1: 0.629207
# test = df.groupby('flag').count()
# test = test['x'].apply(lambda x: x/test['x'].sum())

# 噪声数量比较稳定，真实信号数量随event_id变化较大
# test = df.groupby(['flag','event_id']).count()['x']
# test = df[df['flag']==0].groupby('event_id').count()['x']
# plt.plot(test)
# plt.show()

# # 把t加上合成三维坐标图，点的大小用q表示
# df_event = train_df_source[train_df_source['event_id']==18]
# fig = plt.figure()
# ax = Axes3D(fig)
# ax.scatter(df_event[df_event['flag']==1]['x'], df_event[df_event['flag']==1]['y'], df_event[df_event['flag']==1]['t'], c='r', s= df_event[df_event['flag']==1]['q'], label='signal')
# ax.scatter(df_event[df_event['flag']==0]['x'], df_event[df_event['flag']==0]['y'], df_event[df_event['flag']==0]['t'], c='g',s= df_event[df_event['flag']==0]['q'], label='noise')
# ax.legend(loc='best')
# ax.set_zlabel('Z', fontdict={'size': 15, 'color': 'red'})
# ax.set_ylabel('Y', fontdict={'size': 15, 'color': 'red'})
# ax.set_xlabel('X', fontdict={'size': 15, 'color': 'red'})
# plt.show()

print(
    '============================================== feature engineering ==============================================')

def f_eng(df, event_df, is_train=True):
    df = pd.merge(df, event_df.loc[:, ['event_id', 'energymc', 'thetamc', 'phimc', 'xcmc', 'ycmc']], how='left',
                  on='event_id')
    # df['dis'] = np.sqrt(df['x']**2+df['y']**2+df['t']**2)
    # 时间差
    df['t_o'] = df['t'] - df['terror']
    df['q_mean'] = df['q'] - df['q'].groupby(df['event_id']).transform(np.mean)
    df['t_mean'] = df['t'] - df['t'].groupby(df['event_id']).transform(np.mean)
    if is_train:
        df = df.drop('flag', axis=1)
    df = df.drop(['hit_id', 'z', 'event_id'], axis=1)
    return df

labels = train_df_source['flag']
train_df = f_eng(train_df_source, event_df_source)
test_df = f_eng(test_df_source, event_df_source, False)
print(train_df.columns.values.tolist())
# 小样本训练
train_df = train_df.iloc[:100000, :]
labels = labels[:100000]

threshold = 0.5

# 自定义Metric函数
def score(labels, pred):
    # labels = train_data.get_label()
    labels = labels.astype(int)

    pred = np.array([1 if x >= threshold else 0 for x in pred])
    # Nhitrealrange：真实为信号，预测也为信号的数量
    nhitrealrange = sum(labels & pred)

    # nhitrange：训练后被认定为信号的数量
    nhitrange = sum(pred)

    # Nhitreal：事例中的信号hit数量
    nhitreal = sum(labels)

    # Nhit: 事例中的hit数量
    nhit = len(labels)

    # 保留比例
    remaining = nhitrealrange / nhitreal

    # 噪声排除比
    exemption = 1 - (nhitrange - nhitrealrange) / (nhit - nhitreal)

    # accuracy
    # check = [1 if x==y else 0 for x, y in zip(pred, labels)]
    # print("accuracy: {}".format(sum(check)/len(check)))

    w1 = 99
    w2 = 1
    metric = w1 * remaining + w2 * exemption
    return metric

n_fold = 5
skf = StratifiedKFold(n_splits=n_fold, shuffle=True)
eval_fun = f1_score

params = {
    'learning_rate': 0.01,
    'min_child_samples': 5,
    'num_leaves': 15,
    'max_depth': 8,
    'lambda_l1': 2,
    'boosting': 'gbdt',
    'objective': 'binary',
    'n_estimators': 5000,
    'metric': 'auc',
    'feature_fraction': .75,
    'bagging_fraction': .85,
    'seed': 99,
    'num_threads': 20,
    'verbose': -1
}

def run_oof(clf, X_train, y_train, X_test, kf):
    print(clf)
    preds_train = np.zeros((len(X_train), 2), dtype=np.float)
    preds_test = np.zeros((len(X_test), 2), dtype=np.float)
    train_loss = []
    eval_loss = []

    i = 1
    for train_index, eval_index in kf.split(X_train, y_train):
        x_tr = X_train.loc[train_index]
        x_eval = X_train.loc[eval_index]
        y_tr = y_train.loc[train_index]
        y_eval = y_train.loc[eval_index]
        clf.fit(x_tr, y_tr, eval_set=[(x_eval, y_eval)], early_stopping_rounds=200, verbose=True)

        train_loss.append(eval_fun(y_tr, np.argmax(clf.predict_proba(x_tr)[:], 1), average='macro'))
        eval_loss.append(eval_fun(y_eval, np.argmax(clf.predict_proba(x_eval)[:], 1), average='macro'))

        preds_train[eval_index] = clf.predict_proba(x_eval)[:]
        preds_test += clf.predict_proba(X_test)[:]

        print('{0}: Train {1:0.7f} Val {2:0.7f}/{3:0.7f}'.format(i, train_loss[-1], eval_loss[-1], np.mean(eval_loss)))
        print('-' * 50)
        i += 1
    print('Train: ', train_loss)
    print('Val: ', eval_loss)
    print('-' * 50)
    print('Train{0:0.5f}_Test{1:0.5f}\n\n'.format(np.mean(train_loss), np.mean(eval_loss)))
    preds_test /= n_fold
    return preds_train, preds_test, np.mean(eval_loss)

train_pred, test_pred, eval_loss = run_oof(lgb.LGBMClassifier(**params), train_df, labels, test_df, skf)
test_df_source['flag_pred'] = np.argmax(test_pred, 1)
len(test_pred)
len(test_df_source)
sub = pd.concat([test_df_source['hit_id'], test_df_source['flag_pred'], test_df_source['event_id']], axis=1)
sub.to_csv('C://Users//Lin//Desktop//PolyU//competition//turing_wuli//output//sub_{}.csv'.format(eval_loss),
           index=False)
print('runtime:', time.time() - t)
print('finish.')
print('========================================================================================================')


import os
from setuptools import setup
from setuptools import find_packages

def package_file(fname):
    return os.path.relpath(os.path.join(os.path.dirname(__file__), fname))

with open("README.md", encoding="utf-8") as fh:
    long_description = fh.read()

setup(
    name="desed",
    version="1.3.7",
    description="DESED dataset utils",
    long_description=long_description,
    long_description_content_type="text/markdown",
    author="Nicolas Turpault",
    author_email="turpaultn@gmail.com",
    url="https://github.com/turpaultn/DESED",
    license="MIT",
    package_dir={"": package_file("desed")},
    packages=find_packages(package_file("desed")),
    install_requires=[
        "scaper >= 1.6.5rc0",
        "numpy >= 1.15.4",
        "pandas >= 0.24.0",
        "dcase-util >= 0.2.11",
        "yt-dlp >= 2022.3.8.2",  # Better with conda install and conda-forge channel
        "soundfile >= 0.10.1",
        "jams >= 0.3.4",
        "tqdm >= 4.29.1",
        "requests >= 2.21.0",
    ],
)


import os
import time
import datetime

# Función para limpiar la pantalla
def limpiar_pantalla():
    if os.name == 'nt':  # Para sistemas Windows
        os.system('cls')  # Comando para borrar pantalla

# Función de mostrar mensaje con animación
def mostrar_mensaje(texto):
    for letra in texto:
        print(letra, end='', flush=True)
        time.sleep(0.01)
    print()

# Función para preguntar la materia a estudiar
def materia_preguntar():
    while True:
        materia = input("¿Qué materia tienes que estudiar? ")
        if not materia.isnumeric(): #Comprobrar que este escrito en letra
            return materia
        else:
            mostrar_mensaje("¡ERROR!")
            mostrar_mensaje("¡DEBES ESCRIBIR EL TEXTO EN LETRAS!")

# Función para preguntar en qué día hay que estudiar la materia
def dias_estudio(materia):
    while True:
        estudiar_materia = input("¿En qué día tienes que estudiar para " + str(materia) + "? (YYYY-MM-DD) ")
        try:
            fecha_estudio = datetime.datetime.strptime(estudiar_materia, "%Y-%m-%d") #Para que escriba el año, mes y dia (Podes cambiarlo si quieres)
            return fecha_estudio
        except ValueError: #Para que cuando te tire error si digitaste mal no aparezca cualquier error y aparezca lo que vos queres
            print("Error: Formato de fecha incorrecto. Introduce la fecha en el formato solicitado (YYYY-MM-DD).".upper())

# Función para saber en qué día quieres estudiar
def dias_querer_estudiar(materia):
    while True:
        querer_estudiar = input("¿En qué día quieres estudiar para " + str(materia) + "? (YYYY-MM-DD) ")
        try:
            fecha_estudio = datetime.datetime.strptime(querer_estudiar, "%Y-%m-%d")
            return fecha_estudio
        except ValueError:  #Para que cuando te tire error si digitaste mal no aparezca cualquier error y aparezca lo que vos queres
            print("Error: Formato de fecha incorrecto. Introduce la fecha en el formato solicitado (YYYY-MM-DD).".upper())

#Función para restar días
def dias_restantes(estudiar_materia,querer_estudiar):
    dias_restar=(estudiar_materia-querer_estudiar).days #Para que no aparezca hora ni nada
    if dias_restar>=0:
        mostrar_mensaje("Faltan " + str(dias_restar) + " dias para el examen.")
        return dias_restar
    else:
        mostrar_mensaje("¡ERROR DE PROGRAMA")
        mostrar_mensaje("IMPOSIBLE CALCULAR DIAS NEGATIVOS. ¡INTENTE NUEVAMENTE!")
        exit()#cerrar programa
#Funcion para calcular un porcentaje de aprobacion o no
def calcular_porcentaje_estudio(dias_restar):
    if dias_restar < 1: #porcentaje si te queda menos de un dia de estudio
        porcentaje = 2.5
        mostrar_mensaje("¡Reza para que te vaya bien!")
        mostrar_mensaje("Recomendación: Tuviste que haberte puesto a estudiar unos dias antes.")
    elif dias_restar < 2:
        porcentaje = 14.7
        mostrar_mensaje("Tienes pocas posibilidad de aprobar :(")
        mostrar_mensaje("Recomendación: Dos dias no es suficiente para estudiar, así que estudia las proximas 24/7.")

    elif dias_restar < 3:
        porcentaje = 35.9
        mostrar_mensaje("Puede que te vaya bien")
        mostrar_mensaje("Recomendación: Repasa antes de arrancar la prueba.")

    elif dias_restar < 4:
        porcentaje = 67.3
        mostrar_mensaje("Sin dudas fuiste listo")
        mostrar_mensaje("Recomendación: Repasa todos los dias un rato y ya lo tendras.")
    elif dias_restar < 5:
        porcentaje = 75.9
        mostrar_mensaje("Tienes altas posibilidades de aprobar para el examen!")
        mostrar_mensaje("Recomendación: Tomatelo con calma, tienes 5 dias.")
    elif dias_restar < 6:
        porcentaje = 89.3
        mostrar_mensaje("Vas a aprobar, quedate tranqui")
        mostrar_mensaje("Recomendación: Tomate unos matesitos, ya la tenes.")
    elif dias_restar < 7:
        porcentaje = 95.4
        mostrar_mensaje("Minimo un 8 tenes que sacarle loquita")
        mostrar_mensaje("Recomendación: Ya la tene mi loco.")
    else:
        porcentaje = 100  # Porcentaje de estudio si quedan más de 7 dias para estudiar
        mostrar_mensaje("Si no aprobas, es porque sos tremendo salame")
        mostrar_mensaje("Recomendación: No te puedo recomendar nada, hace MUCHISIMOS dias que estas estudiando.")
    return porcentaje

# Función para preguntar si desea obtener información sobre otra materia
def preguntar_otra_materia():
    while True:
        opcion = input("¿Deseas obtener información sobre otra materia? (S/N): ")
        if opcion.upper() == 'S':
            return True
        elif opcion.upper() == 'N':
            mostrar_mensaje("¡Gracias por haber usado el programa!")
            mostrar_mensaje("¡Hasta luego!")
            return False
        else:
            mostrar_mensaje("Opción inválida. Por favor, ingresa 'S' para sí o 'N' para no.")

# Estructura del programa
def ejecutar_programa():
    while True:
        limpiar_pantalla()
        materia = materia_preguntar()
        fecha_estudio = dias_estudio(materia)
        fecha_querer_estudiar = dias_querer_estudiar(materia)
        dias_restantes_valor = dias_restantes(fecha_estudio, fecha_querer_estudiar)
        porcentaje_estudio = calcular_porcentaje_estudio(dias_restantes_valor)
        mostrar_mensaje("Posibilidad de aprobar el examen: " + str(porcentaje_estudio) + "%") #Muestra la posibilidad que tienes de aprobar el examen

        if not preguntar_otra_materia():
            break
# Ejecución del programa
ejecutar_programa()


import os
import csv
import requests
import json
from datetime import datetime

"""
Sample script to create ARKs from the output of the larkm_integration
Drupal module (https://github.com/mjordan/larkm_integration). See that
module's README for more information.

By default, this output is a JSON list containing objects with the keys
'title', 'uuid', and 'nid'. If you add data to the View for 'who', 'when',
and 'policy' ARK metadata, you will need to modify the code below that
populates those ARK fields.
"""

# You will need to set these variables.
drupal_host = 'https://mydrupalhost.org'
larkm_host = 'http://mylarkmhost.org'
shoulder = 'x1'
delete_todays_data = False

# You shouldn't need to modify anything below this line.
dt = datetime.now()
today = dt.strftime('%Y%m%d')
today_json_file_path = f'nodes_{today}.json'

drupal_endpoint = drupal_host.rstrip('/') +  '/larkm_daily_nodes?_format=json&created_date=' + today
r = requests.get(drupal_endpoint)
with open(today_json_file_path, 'w') as output_file:
    output_file.write(r.text)

with open(today_json_file_path, 'r') as input_file:
  records = json.load(input_file)

for record in records:
    larkm_host = larkm_host.rstrip('/')
    endpoint = f'{larkm_host}/larkm'
    headers = {'Content-Type': 'application/json'}
    target = f"{drupal_host.rstrip('/')}/node/{record['nid']}"
    data = {"target": target, "what": record['title']}
    if 'uuid' in record and len(record['uuid']) > 0:
        data['identifier'] = record['uuid']
    # Data for these ARK fields are not included in the Drupal View
    # by default. If you want to populate them, you will need to modify
    # the View to include the source Drupal fields, and modify the code
    # here to map those values to 'who', 'when', and 'policy' ARK fields.
    # If left unused, larkm will provide default values (see larkm's
    # README for more information).
    if 'who' in record and len(record['who']) > 0:
        data['who'] = record['who']
    if 'when' in record and len(record['when']) > 0:
        data['when'] = record['when']
    if 'policy' in record:
        data['policy'] = record['policy']

    r = requests.post(endpoint, json=data, headers=headers)
    # For POST (create ARK) requests, if the provided UUID is already
    # in use, larkm returns a response code of 409.
    if r.status_code != 201:
        print(f"Could not mint ARK for node {record['nid']}. Response code is {r.status_code}.")

if delete_todays_data:
    os.remove(today_json_file_path)


#!/usr/bin/env python3

import os
import sys
import json
from subprocess import getstatusoutput as unix

PAGE=""

def get_sway_config():
    """"""
    st, content = unix("swaymsg -t get_config")
    if st == 0:
        return json.loads(content)["config"].split("\n")
    else:
        return []

def pretty_keys(keys):
    """"""
    return keys.replace('Shift', '[Shift]').replace('Ctrl', '[Ctrl]')\
               .replace('$mod', '[Super]').replace('$alt', '[Alt]')

def printTo(str):
    """"""
    global PAGE
    PAGE += str+'\n'

def parse(config):
    """"""
    padding = 2
    inBlock = False
    ignore = False
    for ln in config:
        cfg = ln.split()
        if len(cfg) == 0 or cfg[0] == '#':
            continue
        if ' '.join(cfg).find("nag start") > -1:
            ignore = True
        elif ' '.join(cfg).find("nag end") > -1:
            ignore = False
        if ignore:
            continue
        #print(cfg)
        if cfg[0] == "bindsym":
            #print(cfg)
            if "--release" in cfg:
                cfg.remove("--release")
            if "--no-repeat" in cfg:
                cfg.remove("--no-repeat")
            pad = " " * padding
            if ' '.join(cfg).find(" workspace number ") > -1 or \
               ' '.join(cfg).find(" /tmp/sovpipe") > -1 :
                continue

            printTo(f"{pad}{pretty_keys(cfg[1]):<23} => {' '.join(cfg[2:])}")
        elif cfg[0] == "mode":
            padding = 4
            inBlock = True
            printTo(f"  mode {cfg[1]}")
            #print("  }")
        elif cfg[0] == "}":
            padding = 2
            if inBlock:
                inBlock = False
                printTo(f"  {cfg[0]}")
        elif cfg[0] == "#=":
            if len(cfg) > 1:
                if ' '.join(cfg[1:]) == "Switch Workspace":
                    printTo("  -- Switch to or Move Container to Workspace --")
                    printTo("  [Super]+0..9            => switch to workspace 0..9")
                elif ' '.join(cfg[1:]) == "Move Focused Container to Workspace":
                    printTo("  [Super]+[Shift]+0..9    => move container to workspace 0..9")
                else:
                    printTo(f"  -- {' '.join(cfg[1:])} --")
            else:
                printTo(f"")
        elif cfg[0] == '':
            printTo("")

def main():
    printTo("\n  SwayWM Key Bindings")
    printTo("  ===================\n")
    config = get_sway_config()
    parse(config)
    _st, _out = unix(f"echo '{PAGE}' | yad --text-info --geometry=1000x600 ")

if __name__ == '__main__':
    #PAGE = ""
    main()


import os
import os.path
import os
from itertools import product
import rasterio as rio
import cv2
import numpy as np
import fiona
import rasterio
import matplotlib.pyplot as plt

from rasterio import windows
from tensorflow.keras.models import load_model
from glob import glob
from osgeo import gdal, osr, ogr
from rasterio.warp import calculate_default_transform, reproject, Resampling
from skimage.segmentation import felzenszwalb
from skimage.segmentation import mark_boundaries
from skimage.measure import regionprops
from copy import deepcopy
from shapely.geometry import (
    shape, mapping, Point, Polygon, MultiPolygon, MultiPoint
)
from models import (
    dice_p_bce,
    dice_coef,
    true_positive_rate,
    IoU,
    make_model
)
from config import (
    WATERBODY_JSON,
    IMG_DIM,
    THRESHOLD
)

def predict(tif_path, model):

    predict_json = {
        "TYPE": "MultiPoint",
        "coordinates": [],
    }
    ds = gdal.Open(tif_path)
    img = ds.ReadAsArray()
    xoff, a, b, yoff, d, e = ds.GetGeoTransform()
    ds_proj = ds.GetProjectionRef()
    ds_srs = osr.SpatialReference(ds_proj)
    geogcs = ds_srs.CloneGeogCS()
    transform = osr.CoordinateTransformation(ds_srs, geogcs)
    reshaped_img = np.moveaxis(img[:-1, :, :], 0, -1)
    if reshaped_img.shape == (IMG_DIM, IMG_DIM, 3):
        segments = model.predict(
            np.expand_dims(reshaped_img, 0)
        )[0, :, :, 0]
        # plt.imshow(segments)
        # plt.savefig(tif_path[:-4] + '.png')
        segments = (segments > THRESHOLD).astype('uint8')

        for idx, ship in enumerate(regionprops(segments)):

            #if (ship.area >= SHIP_AREA_MIN and ship.area <= SHIP_AREA_MAX):
            x, y = (int(np.average([ship.bbox[0], ship.bbox[2]])),
                    int(np.average([ship.bbox[1], ship.bbox[3]])))

            # Get global coordinates from pixel x, y coords
            projected_x = a * y + b * x + xoff
            projected_y = d * y + e * x + yoff

            # Transform from projected x, y to geographic lat, lng
            (lat, lng, elev) = transform.TransformPoint(
                projected_x, projected_y
            )

            # Add ship to results cluster
            predict_json['coordinates'].append([lng, lat])

    return filter_predictions(predict_json)

def filter_predictions(predict_json):
    predictions = MultiPoint(predict_json['coordinates'])
    new_predictions = deepcopy(predict_json)
    new_predictions['coordinates'] = []
    with fiona.open(WATERBODY_JSON) as water_geoms:
        for pol in water_geoms:
            water_features = shape(pol['geometry'])
            for point in predictions:
                if point.within(water_features):
                    new_predictions['coordinates'].append([point.x, point.y])
    return new_predictions

def get_predictions(tif_path, seg_model):
    predict_json_list = []
    tile_path = create_tiles(tif_path)
    for tile in glob(tile_path + '/*.tif'):
        print(tile)
        predict_json_list.append(predict(tile, seg_model))
    return predict_json_list

def create_tiles(tif_image):

    out_path = f'../data/temp/{os.path.basename(tif_image)}_tile/'
    if not os.path.exists(out_path):
        os.makedirs(out_path)
    output_filename = 'tile_{}-{}.tif'
    with rio.open(tif_image) as src:
        tile_width, tile_height = IMG_DIM, IMG_DIM

        meta = src.meta.copy()

        for window, transform in get_tiles(src, tile_width, tile_height):
            meta['transform'] = transform
            meta['width'], meta['height'] = window.width, window.height
            outpath = os.path.join(out_path, output_filename.format(
                int(window.col_off), int(window.row_off)))
            with rio.open(outpath, 'w', **meta) as outds:
                outds.write(src.read(window=window))
    return out_path

def get_tiles(ds, width, height):
    ncols, nrows = ds.meta['width'], ds.meta['height']
    offsets = product(range(0, ncols, width), range(0, nrows, height))
    big_window = windows.Window(
        col_off=0, row_off=0, width=ncols, height=nrows)
    for col_off, row_off in offsets:
        window = windows.Window(
            col_off=col_off,
            row_off=row_off,
            width=width,
            height=height).intersection(big_window)
        transform = windows.transform(window, ds.transform)
        yield window, transform

def join_geojsons(json_list):
    predict_json = {
        "TYPE": "MultiPoint",
        "coordinates": [],
    }
    for item in json_list:
        if item['coordinates'] is not []:
            for points in item['coordinates']:
                predict_json['coordinates'].append(points)
    return predict_json

def scrape_planet_folder(data_path, weight_path):
    seg_model = make_model((1, IMG_DIM, IMG_DIM, 3))
    seg_model.load_weights(weight_path)
    predict_folder_name = data_path + '_predictions'
    if not os.path.exists(predict_folder_name):
        os.makedirs(predict_folder_name)
    for dirpath, dirnames, filenames in os.walk(data_path):
        for filename in [f for f in filenames if f.endswith("Visual.tif")]:
            jsons = get_predictions(
                os.path.join(dirpath, filename), seg_model,
            )
            combined_jsons = join_geojsons(jsons)
            visualize_prediction(
                os.path.join(dirpath, filename),
                combined_jsons,
                os.path.join(predict_folder_name, filename)
            )

def crs_to_4326(tif_image, dest_image):
    dst_crs = 'EPSG:4326'

    with rasterio.open(tif_image) as src:
        transform, width, height = calculate_default_transform(
            src.crs, dst_crs, src.width, src.height, *src.bounds)
        kwargs = src.meta.copy()
        kwargs.update({
            'crs': dst_crs,
            'transform': transform,
            'width': width,
            'height': height
        })

        with rasterio.open(dest_image, 'w', **kwargs) as dst:
            for i in range(1, src.count + 1):
                reproject(
                    source=rasterio.band(src, i),
                    destination=rasterio.band(dst, i),
                    src_transform=src.transform,
                    src_crs=src.crs,
                    dst_transform=transform,
                    dst_crs=dst_crs,
                    resampling=Resampling.nearest)

def visualize_prediction(tif_image, predict_json, save_path):
    latlon = predict_json['coordinates']
    rc = []
    temp_file = '../data/RGB.byte.wgs84.tif'
    crs_to_4326(tif_image, temp_file)
    src = rasterio.open(temp_file)
    bounds = src.bounds
    plt.imshow(np.moveaxis(src.read(), 0, -1))
    for x, y in latlon:

        if (x >= bounds[0] and x <= bounds[2]) and\
           y >= bounds[1] and y <= bounds[3]:
            rc = rasterio.transform.rowcol(src.transform, x, y)
            plt.scatter(rc[1], rc[0], marker='o', alpha=.3, c='blue', linewidth=1)
    plt.savefig(save_path, dpi=1000)

if __name__ == '__main__':
    seg_model = make_model((1, IMG_DIM, IMG_DIM, 3))
    seg_model.load_weights('../models/seg_model_weights.best.hdf5')
    jsons = get_predictions('../data/sf_2.tif', seg_model)
    jsons = join_geojsons(jsons)
    visualize_prediction('../data/sf_2.tif', jsons, 'test2.png')
    # print(jsons)


from collections import Counter
import os
import numpy as np
from tqdm import tqdm
from medvqa.datasets.chest_imagenome.chest_imagenome_dataset_management import (
    load_gold_standard_dicom_ids,
    load_chest_imagenome_label_names_and_templates,
    load_chest_imagenome_dicom_ids_and_labels_as_numpy_matrix,
    load_chest_imagenome_silver_bboxes_as_numpy_array,
)
from medvqa.datasets.utils import deduplicate_indices
from medvqa.datasets.vqa import VQA_Evaluator, VQA_Trainer
from medvqa.datasets.mimiccxr import (
    MIMICCXR_CACHE_DIR,
    MIMICCXR_IMAGE_ORIENTATIONS,
    MIMICCXR_STUDY_REGEX,
    MIMICCXR_EvalViewModes,
    MIMICCXR_ViewModes,
    get_dicom_id_and_orientation_list,
    get_broken_images,
    get_image_views_dict,
    get_mimiccxr_small_image_path,
    get_split_dict,
)
from medvqa.datasets.image_processing import (
    classify_and_rank_questions,
    get_nearest_neighbors,
)
from medvqa.metrics.classification.multilabel_prf1 import MultiLabelPRF1
from medvqa.utils.files import (
    get_cached_json_file,
    get_file_path_with_hashing_if_too_long,
    load_pickle,
    save_to_pickle,
)
from medvqa.utils.constants import CHEXPERT_LABELS, VINBIG_DISEASES, ReportEvalMode
from medvqa.datasets.preprocessing import (
    get_average_question_positions,
    get_question_frequencies,
)
from medvqa.utils.logging import print_red

def _get_train_preprocessing_save_path(qa_adapted_reports_filename, tokenizer, use_chest_imagenome_compatible_data):
    tokenizer_string = f'{tokenizer.vocab_size},{tokenizer.hash[0]},{tokenizer.hash[1]}'
    if tokenizer.medical_tokenization:
        tokenizer_string += f',{tokenizer.medical_terms_frequency_filename}'
    strings = [
        f'dataset={qa_adapted_reports_filename}',
        f'tokenizer={tokenizer_string}',
        f'use_chest_imagenome_compatible_data={use_chest_imagenome_compatible_data}',
    ]
    return get_file_path_with_hashing_if_too_long(MIMICCXR_CACHE_DIR, 'mimiccxr_preprocessed_train_data__', strings, 'pkl')

def get_test_preprocessing_save_path(qa_adapted_reports_filename, tokenizer, report_eval_mode=None,
                                    pretrained_checkpoint_path=None, precomputed_question_probs_path=None,
                                    precomputed_question_thresholds_path=None,
                                    n_questions_per_report=None, qclass_threshold=None, use_random_image=False,
                                    eval_view_mode=None):
    assert eval_view_mode is not None
    strings = [
        f'dataset={qa_adapted_reports_filename}',
        f'tokenizer={tokenizer.vocab_size},{tokenizer.hash[0]},{tokenizer.hash[1]}',
        f'eval_view_mode={eval_view_mode}',
    ]
    if report_eval_mode is not None:
        strings.append(f'report_eval_mode={report_eval_mode}')

        if report_eval_mode == ReportEvalMode.QUESTION_CLASSIFICATION or\
           report_eval_mode == ReportEvalMode.CHEXPERT_AND_QUESTION_CLASSIFICATION:
            assert pretrained_checkpoint_path is not None or\
                   precomputed_question_probs_path is not None
            if precomputed_question_probs_path is not None:
                strings.append(f'precomputed_question_probs_path={precomputed_question_probs_path}')
                strings.append(f'timestamp={os.path.getmtime(precomputed_question_probs_path)}')
            else:
                strings.append(f'pretrained_checkpoint_path={pretrained_checkpoint_path}')

        if report_eval_mode == ReportEvalMode.NEAREST_NEIGHBOR:
            assert pretrained_checkpoint_path is not None
            strings.append(f'pretrained_checkpoint_path={pretrained_checkpoint_path}')

        if report_eval_mode == ReportEvalMode.QUESTION_CLASSIFICATION or\
           report_eval_mode == ReportEvalMode.CHEXPERT_AND_QUESTION_CLASSIFICATION or\
           report_eval_mode == ReportEvalMode.MOST_POPULAR:
            assert n_questions_per_report is not None
            strings.append(f'n_questions_per_report={n_questions_per_report}')

        if report_eval_mode == ReportEvalMode.QUESTION_CLASSIFICATION or\
           report_eval_mode == ReportEvalMode.CHEXPERT_AND_QUESTION_CLASSIFICATION:
            assert (qclass_threshold is not None) != (precomputed_question_thresholds_path is not None)
            if qclass_threshold:
                strings.append(f'qclass_threshold={qclass_threshold}')
            else:
                strings.append(f'precomputed_question_thresholds_path={precomputed_question_thresholds_path}')

        if use_random_image: strings.append('rand_img')

    file_path = get_file_path_with_hashing_if_too_long(MIMICCXR_CACHE_DIR, 'mimiccxr_preprocessed_test_data__', strings)
    return file_path

def _get_orientation_id(orientation):
    try:
        return MIMICCXR_IMAGE_ORIENTATIONS.index(orientation)
    except ValueError:
        return 0

def _rank_questions(report_ids, precomputed_question_probs_path, n_questions, top_k,
        min_num_q_per_report=5, threshold=None, precomputed_question_thresholds_path=None):
    assert (threshold is None) != (precomputed_question_thresholds_path is None)
    print_red('_rank_questions(): loading question probabilities from', precomputed_question_probs_path)
    question_probs = load_pickle(precomputed_question_probs_path)
    if precomputed_question_thresholds_path is not None:
        print_red('_rank_questions(): loading question thresholds from', precomputed_question_thresholds_path)
        thresholds = load_pickle(precomputed_question_thresholds_path)
    question_ids = list(range(n_questions))
    questions = [None] * len(report_ids)
    K = min(min_num_q_per_report, top_k)
    for i, rid in enumerate(report_ids):
        probs = question_probs[rid]
        if threshold:
            probs -= threshold
        else:
            probs -= thresholds
        question_ids.sort(key=lambda k:probs[k], reverse=True)
        questions[i] = [qid for k, qid in enumerate(question_ids) if k < top_k and probs[qid] >= 0]
        if len(questions[i]) < K:
            questions[i] = question_ids[:K]
            assert 0 < len(questions[i]) <= top_k
    print_red('_rank_questions(): average num of questions per report:', sum(len(q) for q in questions) / len(questions))
    return questions

def _sanity_check_questions(questions, report_ids, mimiccxr_qa_reports):
    n_q = len(mimiccxr_qa_reports['questions'])
    gt = np.zeros((len(report_ids), n_q))
    pred = np.zeros((len(report_ids), n_q))
    for i, ri in enumerate(report_ids):
        for j in mimiccxr_qa_reports['reports'][ri]['question_ids']:
            gt[i][j] = 1
        for j in questions[i]:
            pred[i][j] = 1
    met = MultiLabelPRF1(device='cpu')
    met.update((pred, gt))
    res = met.compute()
    print_red(f'_sanity_check_questions(): f1(macro)={res["f1_macro_avg"]}, f1(micro)={res["f1_micro_avg"]}')

def _precompute_questions_per_report(basic_data, report_eval_mode,
        n_questions_per_report=None, qclass_threshold=None,
        qa_adapted_reports_filename=None, image_transform=None,
        image_local_feat_size=None, n_questions_aux_task=None, pretrained_weights=None,
        pretrained_checkpoint_path=None, precomputed_question_probs_path=None,
        precomputed_question_thresholds_path=None, batch_size=None):

    print('_precompute_questions_per_report():')

    # Filepath
    strings = [
        f'report_eval_mode={report_eval_mode}',
        f'dataset={qa_adapted_reports_filename}',
    ]
    if n_questions_per_report is not None:
        strings.append(f'n_questions_per_report={n_questions_per_report}')
    if report_eval_mode == ReportEvalMode.QUESTION_CLASSIFICATION or\
            report_eval_mode == ReportEvalMode.CHEXPERT_AND_QUESTION_CLASSIFICATION:
        assert pretrained_checkpoint_path is not None or precomputed_question_probs_path is not None
        assert qclass_threshold is not None or precomputed_question_thresholds_path is not None
        if precomputed_question_probs_path is not None:
            strings.append(f'precomputed_question_probs_path={precomputed_question_probs_path}')
            strings.append(f'timestamp={os.path.getmtime(precomputed_question_probs_path)}')
        else:
            strings.append(f'pretrained_checkpoint_path={pretrained_checkpoint_path}')
        if qclass_threshold:
            strings.append(f'qclass_threshold={qclass_threshold}')
        else:
            strings.append(f'precomputed_question_thresholds_path={precomputed_question_thresholds_path}')
    file_path = get_file_path_with_hashing_if_too_long(MIMICCXR_CACHE_DIR, 'questions_per_report', strings)

    data = load_pickle(file_path)
    if data is not None:
        print('   questions per report data loaded from', file_path)
        print('   len(data) =', len(data))
        return data

    mimiccxr_qa_reports = get_cached_json_file(os.path.join(MIMICCXR_CACHE_DIR, qa_adapted_reports_filename))

    test_report_ids = [rid for rid, split in zip(basic_data['report_ids'], basic_data['splits']) if split == 'test']
    assert len(test_report_ids) > 0

    data = {}

    if report_eval_mode == ReportEvalMode.GROUND_TRUTH:
        for ri in test_report_ids:
            data[ri] = mimiccxr_qa_reports['reports'][ri]['question_ids']

    elif report_eval_mode == ReportEvalMode.QUESTION_CLASSIFICATION or\
         report_eval_mode == ReportEvalMode.CHEXPERT_AND_QUESTION_CLASSIFICATION:
        assert n_questions_per_report is not None
        assert qclass_threshold is not None or precomputed_question_thresholds_path is not None
        train_report_ids = [rid for rid, split in zip(basic_data['report_ids'], basic_data['splits']) if split == 'train']
        assert len(train_report_ids) > 0
        question_scores = get_average_question_positions(MIMICCXR_CACHE_DIR, qa_adapted_reports_filename, train_report_ids)
        if precomputed_question_probs_path is not None:
            questions = _rank_questions(test_report_ids,
                                        precomputed_question_probs_path,
                                        n_questions_aux_task,
                                        n_questions_per_report,
                                        threshold=qclass_threshold,
                                        precomputed_question_thresholds_path=precomputed_question_thresholds_path)
        elif pretrained_weights is not None:
            test_image_paths = [image_path for image_path, split in zip(basic_data['image_paths'], basic_data['splits']) if split == 'test']
            questions = classify_and_rank_questions(test_image_paths,
                                        image_transform,
                                        image_local_feat_size,
                                        n_questions_aux_task,
                                        pretrained_weights,
                                        batch_size,
                                        n_questions_per_report,
                                        qclass_threshold)
        else: assert False
        assert len(questions) == len(test_report_ids)
        _sanity_check_questions(questions, test_report_ids, mimiccxr_qa_reports)
        question_scorer = lambda j : question_scores[j]

        if report_eval_mode == ReportEvalMode.QUESTION_CLASSIFICATION:
            for i, ri in enumerate(test_report_ids):
                classified_question_ids = sorted(questions[i], key=question_scorer)
                data[ri] = classified_question_ids
        else: # hybrid method
            chexpert_question_ids = [x for x in range(len(CHEXPERT_LABELS))]
            for i, ri in enumerate(test_report_ids):
                classified_question_ids = sorted(questions[i], key=question_scorer)
                assert all(x not in chexpert_question_ids for x in classified_question_ids)
                data[ri] = chexpert_question_ids + classified_question_ids

    elif report_eval_mode == ReportEvalMode.MOST_POPULAR:
        assert n_questions_per_report != None
        test_report_ids = set(test_report_ids)
        train_report_ids = [i for i in range(len(mimiccxr_qa_reports['reports'])) if i not in test_report_ids]
        question_scores = get_question_frequencies(MIMICCXR_CACHE_DIR, qa_adapted_reports_filename, train_report_ids)
        question_ids = list(range(len(mimiccxr_qa_reports['questions'])))
        assert len(question_scores) == len(question_ids)
        question_ids.sort(key=lambda i : question_scores[i], reverse=True)
        question_ids = question_ids[:n_questions_per_report]
        for ri in test_report_ids:
            data[ri] = question_ids

    elif report_eval_mode == ReportEvalMode.NEAREST_NEIGHBOR:
        assert pretrained_weights is not None
        assert pretrained_checkpoint_path is not None
        test_image_paths = [image_path for image_path, split in zip(basic_data['image_paths'], basic_data['splits']) if split == 'test']
        train_image_paths = [image_path for image_path, split in zip(basic_data['image_paths'], basic_data['splits']) if split == 'train']
        nearest_neighbors = get_nearest_neighbors(target_images = test_image_paths,
                                                  reference_images = train_image_paths,
                                                  transform = image_transform,
                                                  pretrained_weights = pretrained_weights,
                                                  batch_size = batch_size,
                                                  cache_dir = MIMICCXR_CACHE_DIR,
                                                  pretrained_checkpoint_path = pretrained_checkpoint_path,
                                                  suffix = 'split=test')
        for i, ri in enumerate(test_report_ids):
            nearest_ri = train_report_ids[nearest_neighbors[i]]
            assert ri != nearest_ri
            data[ri] = mimiccxr_qa_reports['reports'][nearest_ri]['question_ids']

    elif report_eval_mode == ReportEvalMode.CHEXPERT_LABELS:
        question_ids = list(range(len(CHEXPERT_LABELS)))
        for ri in test_report_ids:
            data[ri] = question_ids
    elif report_eval_mode == ReportEvalMode.VINBIG_DISEASES:
        question_ids = list(range(len(VINBIG_DISEASES)))
        for ri in test_report_ids:
            data[ri] = question_ids
    else:
        assert False, f'Unknown report_eval_mode = {report_eval_mode}'

    save_to_pickle(data, file_path)
    print('   len(data) =', len(data))
    print('   questions per report data saved to', file_path)

    return data

def _get_basic_data(qa_adapted_reports_filename, image_views_dict, split_dict,
                    view_mode=MIMICCXR_ViewModes.ANY_SINGLE,
                    use_chest_imagenome_compatible_data=False, chest_imagenome_dicom_ids=None):

    if use_chest_imagenome_compatible_data:
        assert chest_imagenome_dicom_ids is not None
        assert type(chest_imagenome_dicom_ids) == set
        assert view_mode == MIMICCXR_ViewModes.CHEST_IMAGENOME

    print(f'Obtaining basic data ...')

    file_path = os.path.join(MIMICCXR_CACHE_DIR,
        f'mimiccxr_basic_data(dataset={qa_adapted_reports_filename},view_mode={view_mode}).pkl')
    data = load_pickle(file_path)
    if data is not None:
        print(f'   basic data loaded from {file_path}')
        return data

    broken_images = get_broken_images()

    mimiccxr_qa_reports = get_cached_json_file(os.path.join(MIMICCXR_CACHE_DIR, qa_adapted_reports_filename))

    data = dict(
        report_ids = [],
        dicom_ids = [],
        image_paths = [],
        orientation_ids = [],
        splits = [],
    )

    for ri, report in tqdm(enumerate(mimiccxr_qa_reports['reports'])):

        part_id, subject_id, study_id = map(int, MIMICCXR_STUDY_REGEX.findall(report['filepath'])[0])
        views = image_views_dict[(subject_id, study_id)]
        # images = glob.glob(f'/mnt/workspace/mimic-cxr-jpg/images-small/p{part_id}/p{subject_id}/s{study_id}/*.jpg')
        # assert len(views) == len(images)

        dicom_id_orientation_pairs = get_dicom_id_and_orientation_list(views, view_mode, chest_imagenome_dicom_ids)

        for dicom_id, orientation in dicom_id_orientation_pairs:
            assert dicom_id is not None

            if (subject_id, study_id, dicom_id) not in broken_images:
                image_path = get_mimiccxr_small_image_path(part_id, subject_id, study_id, dicom_id)
                orientation_id = _get_orientation_id(orientation)
                data['report_ids'].append(ri)
                data['dicom_ids'].append(dicom_id)
                data['image_paths'].append(image_path)
                data['orientation_ids'].append(orientation_id)
                data['splits'].append(split_dict[(subject_id, study_id, dicom_id)])

    save_to_pickle(data, file_path)
    print(f'   len(report_ids) =', len(data['report_ids']))
    print(f'   len(set(report_ids)) =', len(set(data['report_ids'])))
    # Print the distribution of orientations
    counter = Counter(data["orientation_ids"])
    for oid, c in counter.items():
        print(f'   {MIMICCXR_IMAGE_ORIENTATIONS[oid]}, count = {c}')
    print(f'   basic data saved to {file_path}')

    return data

def _filter_report_orientation_pairs_for_test(report_ids, orientation_ids, view_mode):

    print(f'Filtering report orientation pairs for test ...')

    if view_mode == MIMICCXR_EvalViewModes.ALL:
        output = list(range(len(report_ids)))
    elif view_mode == MIMICCXR_EvalViewModes.FRONT_ALL:
        idxs = []
        PA_ID = MIMICCXR_IMAGE_ORIENTATIONS.index('PA')
        AP_ID = MIMICCXR_IMAGE_ORIENTATIONS.index('AP')
        valid_oids = [PA_ID, AP_ID]
        for i, (ri, oid) in enumerate(zip(report_ids, orientation_ids)):
            if oid in valid_oids:
                idxs.append(i)
        output = idxs
    elif view_mode == MIMICCXR_EvalViewModes.FRONT_SINGLE:
        rid2idx = {}
        PA_ID = MIMICCXR_IMAGE_ORIENTATIONS.index('PA')
        AP_ID = MIMICCXR_IMAGE_ORIENTATIONS.index('AP')
        valid_oids = [PA_ID, AP_ID]
        for i, (ri, oid) in enumerate(zip(report_ids, orientation_ids)):
            if oid in valid_oids:
                if ri not in rid2idx:
                    rid2idx[ri] = i
                else:
                    if oid == PA_ID:
                        rid2idx[ri] = i
        output = list(rid2idx.values())
    elif view_mode == MIMICCXR_EvalViewModes.ANY_SINGLE:
        rid2idx = {}
        PA_ID = MIMICCXR_IMAGE_ORIENTATIONS.index('PA')
        AP_ID = MIMICCXR_IMAGE_ORIENTATIONS.index('AP')
        for i, (ri, oid) in enumerate(zip(report_ids, orientation_ids)):
            if ri not in rid2idx:
                rid2idx[ri] = i
            else:
                if oid == PA_ID:
                    rid2idx[ri] = i
                elif oid == AP_ID:
                    if rid2idx[ri] != PA_ID:
                        rid2idx[ri] = i
        output = list(rid2idx.values())
    else:
        raise ValueError(f'Unknown view_mode = {view_mode}')

    print(f'   len(report_ids) = {len(report_ids)}')
    print(f'   len(output) = {len(output)}')
    return output

def _preprocess_data(self, split_name):

    assert split_name in ('train_val', 'test'), f'Unknown split_name = {split_name}'

    is_train_val = split_name == 'train_val'

    tokenizer = self.tokenizer
    mimiccxr_qa_reports = self.mimiccxr_qa_reports

    if tokenizer.medical_tokenization and split_name != 'test':
        answer_string2ids_func = tokenizer.string2medical_tag_ids
    else:
        answer_string2ids_func = tokenizer.string2ids

    if mimiccxr_qa_reports is None:
        file_path = os.path.join(MIMICCXR_CACHE_DIR, self.qa_adapted_reports_filename)
        print(f'Loading {file_path}')
        mimiccxr_qa_reports = get_cached_json_file(file_path)

    split_dict = get_split_dict()
    image_views_dict = get_image_views_dict()
    basic_data = _get_basic_data(self.qa_adapted_reports_filename, image_views_dict, split_dict,
                                 view_mode=self.view_mode, use_chest_imagenome_compatible_data=self.use_chest_imagenome_compatible_data,
                                 chest_imagenome_dicom_ids=self.chest_imagenome_dicom_ids)

    if split_name == 'test' and self.report_eval_mode is not None:
        questions_per_report = _precompute_questions_per_report(basic_data, self.report_eval_mode,
                        qa_adapted_reports_filename=self.qa_adapted_reports_filename,
                        image_transform=self.transform,
                        image_local_feat_size=self.image_local_feat_size,
                        n_questions_aux_task=self.n_questions_aux_task,
                        pretrained_weights=self.pretrained_weights,
                        batch_size=self.batch_size,
                        n_questions_per_report=self.n_questions_per_report,
                        qclass_threshold=self.qclass_threshold,
                        pretrained_checkpoint_path=self.pretrained_checkpoint_path,
                        precomputed_question_probs_path=self.precomputed_question_probs_path,
                        precomputed_question_thresholds_path=self.precomputed_question_thresholds_path)
    else:
        questions_per_report = None

    print('Preprocessing MIMIC-CXR vqa dataset ...')

    # Define question_list to use
    question_list = mimiccxr_qa_reports['questions'] # default
    if split_name == 'test':
        if self.report_eval_mode == ReportEvalMode.CHEXPERT_LABELS:
            question_list = CHEXPERT_LABELS
        elif self.report_eval_mode == ReportEvalMode.CHEXPERT_AND_QUESTION_CLASSIFICATION:
            question_list = CHEXPERT_LABELS + mimiccxr_qa_reports['questions']

    # Collect multiple fields considerng the split and mode
    if is_train_val:
        if self.use_chest_imagenome_compatible_data:
            # Use only instances whose dicom_id is not in Chest-Imagenome gold standard
            gold_dicom_ids = self.chest_imagenome_gold_dicom_ids
            assert type(gold_dicom_ids) is set
            report_ids = [rid for rid, s, did in zip(basic_data['report_ids'], basic_data['splits'], basic_data['dicom_ids'])\
                 if s != 'test' and did not in gold_dicom_ids]
            image_paths = [ip for ip, s, did in zip(basic_data['image_paths'], basic_data['splits'], basic_data['dicom_ids'])\
                    if s != 'test' and did not in gold_dicom_ids]
            orientation_ids = [oid for oid, s, did in zip(basic_data['orientation_ids'], basic_data['splits'], basic_data['dicom_ids'])\
                    if s != 'test' and did not in gold_dicom_ids]
            dicom_ids = [did for s, did in zip(basic_data['splits'], basic_data['dicom_ids']) if s != 'test' and did not in gold_dicom_ids]
            splits = [s for s, did in zip(basic_data['splits'], basic_data['dicom_ids']) if s != 'test' and did not in gold_dicom_ids]
        else:
            report_ids = [rid for rid, s in zip(basic_data['report_ids'], basic_data['splits']) if s != 'test']
            image_paths = [ip for ip, s in zip(basic_data['image_paths'], basic_data['splits']) if s != 'test']
            orientation_ids = [oid for oid, s in zip(basic_data['orientation_ids'], basic_data['splits']) if s != 'test']
            dicom_ids = [did for s, did in zip(basic_data['splits'], basic_data['dicom_ids']) if s != 'test']
            splits = [s for s in basic_data['splits'] if s != 'test']
    else:
        report_ids = [rid for rid, s in zip(basic_data['report_ids'], basic_data['splits']) if s == 'test']
        image_paths = [ip for ip, s in zip(basic_data['image_paths'], basic_data['splits']) if s == 'test']
        orientation_ids = [oid for oid, s in zip(basic_data['orientation_ids'], basic_data['splits']) if s == 'test']
        dicom_ids = [did for s, did in zip(basic_data['splits'], basic_data['dicom_ids']) if s == 'test']
    assert len(report_ids) == len(image_paths) == len(orientation_ids) == len(dicom_ids)
    assert len(report_ids) > 0

    # Collect data in VQA format (multiple questions per report)
    self.report_ids = []
    self.question_ids = []
    self.dicom_ids = []
    self.images = []
    self.questions = []
    self.orientations = []
    if is_train_val:
        self.train_indices = []
        self.val_indices = []

    if questions_per_report is None: # Normal method
        self.answers = []
        idx = 0

        for i in tqdm(range(len(report_ids))):

            ri = report_ids[i]
            report = mimiccxr_qa_reports['reports'][ri]
            sentences = report['sentences']
            image_path = image_paths[i]
            orientation_id = orientation_ids[i]
            dicom_id = dicom_ids[i]
            split = splits[i]

            for qid, a_ids in report['qa'].items():
                qid = int(qid)
                question = question_list[qid]
                answer = '. '.join(sentences[i] for i in a_ids)
                self.report_ids.append(ri)
                self.question_ids.append(qid)
                self.dicom_ids.append(dicom_id)
                self.images.append(image_path)
                self.questions.append(tokenizer.string2ids(question.lower()))
                self.answers.append(answer_string2ids_func(answer.lower()))
                self.orientations.append(orientation_id)
                if is_train_val:
                    if split == 'train':
                        self.train_indices.append(idx)
                    elif split == 'validate':
                        self.val_indices.append(idx)
                    else:
                        raise ValueError(f'Unknown split: {split}')
                    idx += 1

    else: # Report evaluation method -> we ignore the answers

        filtered_idxs = _filter_report_orientation_pairs_for_test(report_ids, orientation_ids, self.eval_view_mode)

        for i in tqdm(filtered_idxs):
            ri = report_ids[i]
            image_path = image_paths[i]
            orientation_id = orientation_ids[i]
            dicom_id = dicom_ids[i]
            question_ids = questions_per_report[ri]

            # assert len(question_ids) > 0, mimiccxr_qa_reports['reports'][ri]

            for qid in question_ids:
                question = question_list[qid]
                self.report_ids.append(ri)
                self.question_ids.append(qid)
                self.dicom_ids.append(dicom_id)
                self.images.append(image_path)
                self.questions.append(tokenizer.string2ids(question.lower()))
                self.orientations.append(orientation_id)

    self.report_ids = np.array(self.report_ids, dtype=int)
    self.question_ids = np.array(self.question_ids, dtype=int)
    self.dicom_ids = np.array(self.dicom_ids, dtype=str)
    self.images = np.array(self.images, dtype=str)
    self.questions = np.array(self.questions, dtype=object)
    self.orientations = np.array(self.orientations, dtype=int)
    if is_train_val:
        self.train_indices = np.array(self.train_indices, dtype=int)
        self.val_indices = np.array(self.val_indices, dtype=int)
    if questions_per_report is None:
        self.answers = np.array(self.answers, dtype=object)

class MIMICCXR_VQA_Trainer(VQA_Trainer):

    def __init__(self, train_image_transform, val_image_transform,
                batch_size, collate_batch_fn,
                num_workers,
                qa_adapted_reports_filename,
                tokenizer,
                view_mode = MIMICCXR_ViewModes.ANY_SINGLE,
                collate_batch_fn_chexpert_mode = None,
                verbose_question = True,
                classify_tags = False,
                medical_tags_per_report_filename = None,
                classify_orientation = False,
                classify_chexpert = False,
                chexpert_labels_filename = None,
                classify_questions = False,
                classify_chest_imagenome = False,
                predict_bboxes_chest_imagenome = False,
                clamp_bboxes_chest_imagenome = False,
                question_labels_filename = None,
                mimiccxr_qa_reports = None,
                balanced_dataloading = False,
                balanced_metadata_filename = None,
                imbalance_reduction_coef = 1,
                allowed_questions = None,
                one_question_per_batch = False,
                include_mined_questions_mode = False,
                include_chexpert_mode = False,
                include_image = True,
                use_precomputed_visual_features = False,
                precomputed_visual_features_path = None,
                use_merged_findings = False,
                findings_remapper = None,
                n_findings = None,
                include_chest_imagenome_mode = False,
                chest_imagenome_labels_filename = None,
                chest_imagenome_label_names_filename = None,
                collate_batch_fn_chest_imagenome_mode = None,
                debug = False):

        self.tokenizer = tokenizer
        self.mimiccxr_qa_reports = mimiccxr_qa_reports
        self.qa_adapted_reports_filename = qa_adapted_reports_filename
        self.view_mode = view_mode
        self.include_chest_imagenome_mode = include_chest_imagenome_mode
        self.batch_size = batch_size
        self.num_workers = num_workers
        self.classify_chest_imagenome = classify_chest_imagenome
        self.predict_bboxes_chest_imagenome = predict_bboxes_chest_imagenome
        self.chest_imagenome_label_names_filename = chest_imagenome_label_names_filename
        self.chest_imagenome_labels_filename = chest_imagenome_labels_filename
        self.use_chest_imagenome_compatible_data = (
            include_chest_imagenome_mode or classify_chest_imagenome or predict_bboxes_chest_imagenome
        )

        other_tasks = [] # Hack so that parent class can handle other tasks

        preprocessing_save_path = _get_train_preprocessing_save_path(qa_adapted_reports_filename, tokenizer, self.use_chest_imagenome_compatible_data)

        print(f'MIMICCXR_VQA_Trainer: balanced_dataloading = {balanced_dataloading}')

        super().__init__(train_image_transform, val_image_transform,
                        batch_size, collate_batch_fn,
                        preprocessing_save_path,
                        MIMICCXR_CACHE_DIR,
                        num_workers,
                        collate_batch_fn_chexpert_mode = collate_batch_fn_chexpert_mode,
                        verbose_question = verbose_question,
                        classify_tags = classify_tags,
                        rid2tags_filename = medical_tags_per_report_filename,
                        classify_orientation = classify_orientation,
                        classify_chexpert = classify_chexpert,
                        chexpert_labels_filename = chexpert_labels_filename,
                        classify_questions = classify_questions,
                        question_labels_filename = question_labels_filename,
                        balanced_dataloading = balanced_dataloading,
                        balanced_metadata_filename = balanced_metadata_filename,
                        imbalance_reduction_coef = imbalance_reduction_coef,
                        allowed_questions = allowed_questions,
                        qa_adapted_reports_filename = qa_adapted_reports_filename,
                        one_question_per_batch = one_question_per_batch,
                        include_mined_questions_mode = include_mined_questions_mode,
                        include_chexpert_mode = include_chexpert_mode,
                        include_image = include_image,
                        use_precomputed_visual_features = use_precomputed_visual_features,
                        precomputed_visual_features_path = precomputed_visual_features_path,
                        use_merged_findings = use_merged_findings,
                        findings_remapper = findings_remapper,
                        n_findings = n_findings,
                        other_tasks=other_tasks,
                        debug = debug)

        # --------- Chest-Imagenome specific logic ---------
        if include_chest_imagenome_mode:
            assert collate_batch_fn_chest_imagenome_mode is not None
            self.collate_batch_fn_chest_imagenome_mode = collate_batch_fn_chest_imagenome_mode
            # Load Chest-Imagenome label names and templates
            assert chest_imagenome_label_names_filename is not None
            self.chest_imagenome_label_names, self.chest_imagenome_templates = \
                load_chest_imagenome_label_names_and_templates(chest_imagenome_label_names_filename)

        if include_chest_imagenome_mode or classify_chest_imagenome:
            assert chest_imagenome_labels_filename is not None
            # Load Chest-Imagenome dicom_ids and labels
            self.chest_imagenome_dicom_ids, self.chest_imagenome_labels = \
                load_chest_imagenome_dicom_ids_and_labels_as_numpy_matrix(chest_imagenome_labels_filename, qa_adapted_reports_filename)
            # Load Chest-Imagenome gold standard dicom_ids (they must be removed from training and validation sets)
            self.chest_imagenome_gold_dicom_ids = set(load_gold_standard_dicom_ids())

        if classify_chest_imagenome:
            other_tasks.append(('chest_imagenome', lambda _, rid: self.chest_imagenome_labels[rid]))

        if predict_bboxes_chest_imagenome:
            self.dicom_idxs, self.bbox_coords, self.bbox_presence =\
                load_chest_imagenome_silver_bboxes_as_numpy_array(
                    self.dicom_ids, clamp_bboxes_chest_imagenome)
            other_tasks.append(('chest_imagenome_bbox_coords', lambda i, _: self.bbox_coords[self.dicom_idxs[i]]))
            other_tasks.append(('chest_imagenome_bbox_presence', lambda i, _: self.bbox_presence[self.dicom_idxs[i]]))

    def _preprocess_data(self):
        _preprocess_data(self, 'train_val')

    def _generate_dataset_and_dataloader__chest_imagenome_mode(
            self, indices, batch_size, collate_batch_fn, num_workers,
            infinite=True, n_pos_samples=None, n_neg_samples=None, min_pos_to_include=0):

        return self._create_label_based_dataset_and_dataloader(
            indices=indices,
            labels=self.chest_imagenome_labels,
            label_names=self.chest_imagenome_label_names,
            templates=self.chest_imagenome_templates,
            tokenizer=self.tokenizer,
            batch_size=batch_size,
            num_workers=num_workers,
            collate_batch_fn=collate_batch_fn,
            infinite=infinite,
            n_pos_samples=n_pos_samples,
            n_neg_samples=n_neg_samples,
            min_pos_to_include=min_pos_to_include,
            report_ids=self.report_ids,
            print_every=30,
            # break_loop_at_i=40, # for debugging
            create_dataset_kwargs=dict(
                fixed_qa_pair=True,
            ))

    def _generate_train_dataset_and_dataloader__chest_imagenome_mode(self, batch_size, collate_batch_fn, num_workers):
        print('Generating balanced train dataset in chest imagenome mode ...')
        flattened_indices = []
        for _indices in self.train_indices.values():
            flattened_indices.extend(_indices)
        dedup_indices = deduplicate_indices(flattened_indices, self.report_ids)
        dataset, dataloader = self._generate_dataset_and_dataloader__chest_imagenome_mode(
            dedup_indices, batch_size, collate_batch_fn, num_workers, min_pos_to_include=20)
        self.train_dataset__chest_imagenome_mode = dataset
        self.train_dataloader__chest_imagenome_mode = dataloader
        print('len(self.train_dataset__chest_imagenome_mode) =', len(self.train_dataset__chest_imagenome_mode))

    def _generate_val_dataset_and_dataloader__chest_imagenome_mode(self, batch_size, collate_batch_fn, num_workers):
        print('Generating balanced validation dataset in chest imagenome mode ...')
        dedup_indices = deduplicate_indices(self.val_indices, self.report_ids)
        dataset, dataloader = self._generate_dataset_and_dataloader__chest_imagenome_mode(
            dedup_indices, batch_size, collate_batch_fn, num_workers, infinite=False,
            n_pos_samples=5, n_neg_samples=5)
        self.val_dataset__chest_imagenome_mode = dataset
        self.val_dataloader__chest_imagenome_mode = dataloader
        print('len(self.val_dataset__chest_imagenome_mode) =', len(self.val_dataset__chest_imagenome_mode))

    def _load_optional_datasets_and_dataloaders(self):
        if self.include_chest_imagenome_mode:
            if not self.validation_only:
                self._generate_train_dataset_and_dataloader__chest_imagenome_mode(
                    self.batch_size, self.collate_batch_fn_chest_imagenome_mode, self.num_workers)
            if not self.train_with_all:
                self._generate_val_dataset_and_dataloader__chest_imagenome_mode(
                    self.batch_size, self.collate_batch_fn_chest_imagenome_mode, self.num_workers)

class MIMICCXR_VQA_Evaluator(VQA_Evaluator):

    def __init__(self, transform, batch_size, collate_batch_fn,
                qa_adapted_reports_filename,
                num_workers,
                verbose_question = True,
                classify_tags = False,
                medical_tags_per_report_filename = None,
                classify_orientation = False,
                classify_chexpert = False,
                chexpert_labels_filename = None,
                classify_questions = False,
                question_labels_filename = None,
                tokenizer = None,
                mimiccxr_qa_reports = None,
                report_eval_mode = None,
                image_local_feat_size = None,
                pretrained_checkpoint_path = None,
                pretrained_weights = None,
                precomputed_question_probs_path = None,
                precomputed_question_thresholds_path = None,
                n_questions_aux_task = None,
                n_questions_per_report = None,
                qclass_threshold = None,
                include_image = True,
                use_random_image = False,
                use_precomputed_visual_features = False,
                precomputed_visual_features_path = None,
                view_mode = None,
                eval_view_mode = None,
                include_chest_imagenome_mode = False,
                classify_chest_imagenome = False,
                chest_imagenome_labels_filename = None,
                **unused_kwargs):

        print('report_eval_mode =', report_eval_mode)

        self.tokenizer = tokenizer
        self.mimiccxr_qa_reports = mimiccxr_qa_reports
        self.qa_adapted_reports_filename = qa_adapted_reports_filename
        self.view_mode = view_mode
        self.include_chest_imagenome_mode = include_chest_imagenome_mode

        # Args used in report_eval_mode
        self.report_eval_mode = report_eval_mode
        self.transform = transform
        self.image_local_feat_size = image_local_feat_size
        self.n_questions_aux_task = n_questions_aux_task
        self.pretrained_weights = pretrained_weights
        self.batch_size = batch_size
        self.n_questions_per_report = n_questions_per_report
        self.qclass_threshold = qclass_threshold
        self.pretrained_checkpoint_path = pretrained_checkpoint_path
        self.precomputed_question_probs_path = precomputed_question_probs_path
        self.precomputed_question_thresholds_path = precomputed_question_thresholds_path
        self.eval_view_mode = eval_view_mode

        if pretrained_weights is not None:
            assert pretrained_checkpoint_path is not None

        if classify_chest_imagenome: # Chest-Imagenome specific logic
            assert chest_imagenome_labels_filename is not None
            # Load Chest-Imagenome dicom_ids and labels
            self.chest_imagenome_dicom_ids, self.chest_imagenome_labels = \
                load_chest_imagenome_dicom_ids_and_labels_as_numpy_matrix(chest_imagenome_labels_filename, qa_adapted_reports_filename)
            # Necessary hack so that parent classes can access chest_imagenome_labels
            other_tasks = [('chest_imagenome', lambda _, rid: self.chest_imagenome_labels[rid])]
        else:
            other_tasks = None

        preprocessing_save_path = get_test_preprocessing_save_path(
                        qa_adapted_reports_filename, tokenizer, report_eval_mode,
                        pretrained_checkpoint_path, precomputed_question_probs_path,
                        precomputed_question_thresholds_path,
                        n_questions_per_report, qclass_threshold, use_random_image,
                        eval_view_mode)

        super().__init__(transform, batch_size, collate_batch_fn,
                        preprocessing_save_path,
                        MIMICCXR_CACHE_DIR,
                        num_workers,
                        verbose_question = verbose_question,
                        include_answer = report_eval_mode == None,
                        classify_tags = classify_tags,
                        rid2tags_filename = medical_tags_per_report_filename,
                        classify_orientation = classify_orientation,
                        classify_chexpert = classify_chexpert,
                        chexpert_labels_filename = chexpert_labels_filename,
                        classify_questions = classify_questions,
                        question_labels_filename = question_labels_filename,
                        include_image = include_image,
                        use_random_image = use_random_image,
                        use_precomputed_visual_features = use_precomputed_visual_features,
                        precomputed_visual_features_path = precomputed_visual_features_path,
                        other_tasks = other_tasks)

    def _preprocess_data(self):
        _preprocess_data(self, 'test')


from django import forms
from .models import Cadastro, Ligacao, get_actual_content

class ParametrosForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(ParametrosForm, self).__init__(*args, **kwargs)
        self.instance = getattr(self, 'instance', None)

        cadastro = Cadastro
        for key, value in self.fields.items():
            value.initial = get_actual_content(cadastro, key)

    class Meta:
        model = Cadastro
        fields = ["broker", "conta_sid", "token_sid", "servicos", "ligacao_de"]

class LigacaoForm(forms.ModelForm):
    def __init__(self, *args, **kwargs):
        super(LigacaoForm, self).__init__(*args, **kwargs)
        self.instance.cadastro = Cadastro.objects.all()[0]

    class Meta:
        model = Ligacao
        fields = ["ligacao_para", "mensagem"]


from flair.data import Sentence

def pridect(Model,Data):
    dict={"label":"Prediction"}

    import time
    start=time.time()
    for i in range(len(Data)-1):
     if(len(Data[i])!=0):

        sentence = Sentence(Data[i])
        Model.predict(sentence)
        list=sentence.to_dict(tag_type='ner')
        if(len(list['entities'])>0):
            for j in range(len(list['entities'])):

                dict[list['entities'][j]['text']]=str(list['entities'][j]['labels'])

    print("le Temps d'execution est :"+str(time.time()-start))
    return (dict)


from django.conf import settings

from lava_common.version import __version__

def lava(request):
    return {
        "lava": {
            "instance_name": settings.INSTANCE_NAME,
            "instance_version": __version__,
            "branding_url": settings.BRANDING_URL,
            "branding_icon": settings.BRANDING_ICON,
            "branding_alt": settings.BRANDING_ALT,
            "branding_height": settings.BRANDING_HEIGHT,
            "branding_width": settings.BRANDING_WIDTH,
            "branding_bug_url": settings.BRANDING_BUG_URL,
            "branding_source_url": settings.BRANDING_SOURCE_URL,
            "branding_message": settings.BRANDING_MESSAGE,
            "branding_css": settings.BRANDING_CSS,
        }
    }

def ldap_available(request):
    ldap_enabled = (
        "django_auth_ldap.backend.LDAPBackend" in settings.AUTHENTICATION_BACKENDS
    )
    login_message_ldap = getattr(settings, "LOGIN_MESSAGE_LDAP", "")
    return {"ldap_available": ldap_enabled, "login_message_ldap": login_message_ldap}

def oidc_context(request):
    return {
        "oidc_enabled": settings.OIDC_ENABLED,
        "oidc_account_name": settings.LAVA_OIDC_ACCOUNT_NAME,
    }

def socialaccount(request):
    return {
        "socialaccount_enabled": settings.AUTH_SOCIALACCOUNT
        or settings.AUTH_GITLAB_URL,
    }


import pytesseract
import cv2
from time import sleep
from selenium import webdriver
from selenium.webdriver.common.keys import Keys

# set browser to Firefox (requires geckodriver.exe in main Python executable folder
browser = webdriver.Firefox()
# set config for OCR
custom_config = r'-l eng --oem 3 --psm 6'

# resize all input images to factor for different screen resolutions
width = 1024
height = 576
dim = (width, height)

# cropping values
h = 110
w = 95
# column 1 (2 tags)
y1 = 275
x1 = 345
# column 2 (2 tags)
y2 = 275
x2 = 450
# column 3 (1 tag)
h3 = 55
w3 = 98
y3 = 275
x3 = 560

# function to read image, pre-process it for OCR, then use OCR to get the recruitment tags from the screenshot
def gettags(file_name):
	# read image
	img = cv2.imread(file_name)

	# resize image to factor for different resolutions
	resized = cv2.resize(img, dim, interpolation=cv2.INTER_AREA)
	resized1 = resized[y1:y1 + h, x1:x1 + w]
	resized2 = resized[y2:y2 + h, x2:x2 + w]
	resized3 = resized[y3:y3 + h3, x3:x3 + w3]

	# pre-process images for better results
	resized1 = cv2.bitwise_not(resized1)
	resized2 = cv2.bitwise_not(resized2)
	resized3 = cv2.bitwise_not(resized3)

	# find tags by column and split them into lists of strings
	col1 = pytesseract.image_to_string(resized1, config=custom_config)
	col1 = col1.splitlines()
	col2 = pytesseract.image_to_string(resized2, config=custom_config)
	col2 = col2.splitlines()
	col3 = pytesseract.image_to_string(resized3, config=custom_config)
	col3 = col3.splitlines()

	# concatenate column into main tag list
	tag_list = col1 + col2 + col3
	# replace in-game 'Crowd-Control' tag to aceship 'Crowd Control' tag
	tag_list = [sub.replace('Crowd-Control', 'Crowd Control') for sub in tag_list]
	print("Tag List:", tag_list)
	return tag_list

if __name__ == "__main__":
	try:
		# ask for user-input image file
		image_file = input("Enter screenshot filename: ")
		# get tags from screenshot
		tags = gettags(image_file)
		# browse to aceship recruitment calculator, switch server to EN
		browser.get('https://aceship.github.io/AN-EN-Tags/akhr.html')
		sleep(1)
		server = browser.find_element_by_id('navitemRegion')
		sleep(0.25)
		server.click()
		server_en = browser.find_element_by_link_text('English')
		sleep(0.25)
		server_en.click()

		# iterate over tag list and input tags
		tag_input = browser.find_element_by_id('fastInput')
		for i in range(len(tags)):
			sleep(0.25)
			tag_input.send_keys(tags[i])
			sleep(0.25)
			tag_input.send_keys(Keys.ENTER)
	except IOError:
		pass


import argparse
import numpy as np
import pandas as pd
import matplotlib as mpl
import matplotlib.pyplot as plt
import ufedmm

from scipy import stats
from simtk import unit

parser = argparse.ArgumentParser()
parser.add_argument('--platform', dest='platform', help='the computation platform', default='Reference')
args = parser.parse_args()

nbins = 20
factor = 8

ufed = ufedmm.deserialize('ufed_object.yml')
df = pd.read_csv('output.csv')

print(df[['T[atoms] (K)'] + [f'T[{v.id}] (K)' for v in ufed.variables]].mean())

analyzer = ufedmm.FreeEnergyAnalyzer(ufed, df)

centers, mean_forces = analyzer.centers_and_mean_forces(nbins)

delta = 2*np.pi/nbins
properties = {'Precision': 'mixed'} if args.platform == 'CUDA' else {}
potential, mean_force = analyzer.mean_force_free_energy(
    centers, mean_forces, sigma=factor*delta, platform_name=args.platform, properties=properties,
)

ranges = [(cv.min_value, cv.max_value) for cv in ufed.variables]
x = [np.linspace(*range, num=101) for range in ranges]
X = np.meshgrid(*x)
Z = potential(*X)
fe = Z-Z.min()

def in_degrees(angles):
    return [180*angle/np.pi for angle in angles]

fig, ax = plt.subplots()
cmap = plt.get_cmap('jet')
extent = in_degrees([item for sublist in ranges for item in sublist])
ax.imshow(fe, extent=extent, cmap=cmap, interpolation='spline36', origin='lower', zorder=0)
ax.contour(*in_degrees(x), fe, 20, cmap=cmap, linewidths=0.5, zorder=10)
ax.quiver(*in_degrees(centers), *mean_forces, zorder=20)
plt.savefig('figure.png')
plt.show()


import json
from datetime import datetime, timedelta

from aiess.web.ratelimiter import request_with_rate_limit
from aiess.settings import API_RATE_LIMIT, APIV2_CLIENT_ID, APIV2_CLIENT_SECRET

cached_token = None

class Token():
    def __init__(self, bearer: str, expires_in: int, access_token: str):
        self.bearer       = bearer
        self.expires_at   = datetime.utcnow() + timedelta(seconds=expires_in)
        self.access_token = access_token

    def alive(self):
        return datetime.utcnow() < self.expires_at

def _request_token():
    response = request_with_rate_limit(
        request_url   = "https://osu.ppy.sh/oauth/token",
        rate_limit    = API_RATE_LIMIT,
        rate_limit_id = "api",
        timeout       = 10,
        method        = "POST",
        data          = {
            "client_id":     APIV2_CLIENT_ID,
            "client_secret": APIV2_CLIENT_SECRET,
            "grant_type":    "client_credentials",
            "scope":         "public"
        }
    )

    json_obj = json.loads(response.text)

    bearer       = json_obj["token_type"]
    expires_in   = json_obj["expires_in"]
    access_token = json_obj["access_token"]

    token = Token(bearer, expires_in, access_token)
    global cached_token
    cached_token = token

    return token

def get_or_request_token():
    if cached_token and cached_token.alive():
        return cached_token
    else:
        return _request_token()

def request_api(route: str, query: str=None) -> object:
    """Requests a json object from the v1 osu!api, where the api key is supplied."""
    route = route.strip("/")
    token = get_or_request_token()
    response = request_with_rate_limit(
        request_url   = f"https://osu.ppy.sh/api/v2/{route}" + (f"?{query}" if query else ""),
        rate_limit    = API_RATE_LIMIT,
        rate_limit_id = "api",
        timeout       = 10,
        headers       = { "Authorization": f"Bearer {token.access_token}" }
    )

    return json.loads(response.text)

def request_discussions(page: int=1, message_types: str=None, limit: int=None) -> object:
    """Requests a json object representing discussions on the given page, by default page 1."""
    # Response is of from:
    # {"beatmaps":[],"cursor":null,"discussions":[],"included_discussions":[],"reviews_config":{"max_blocks":100},"users":[]}
    return request_api(
        route = "/beatmapsets/discussions",
        query = f"page={page}" + (f"&message_types[]={message_types}" if message_types else "") + (f"&limit={limit}" if limit else "")
    )

def request_discussion_posts(page: int=1, limit: int=None) -> object:
    """Requests a json object representing discussion replies on the given page, by default page 1."""
    # Response is of form:
    # {"beatmaps":[],"discussions":[],"cursor":null,"posts":[],"users":[]}
    return request_api(
        route = "/beatmapsets/discussions/posts",
        query = f"page={page}" + (f"&limit={limit}" if limit else "")
    )

def request_news(cursor_id: int, cursor_published_at: str, limit: int=None) -> object:
    return request_api(
        route = "/news",
        query = f"cursor[id]={cursor_id}&cursor[published_at]={cursor_published_at}" + (f"&limit={limit}" if limit else "")
    )