# Import packages
import cv2
import numpy as np
from PIL import Image
from pytesseract import pytesseract
from pytesseract import Output

if __name__ == "__main__":

    img = cv2.imread('shelf_for_rectangles.jpg')
    print(img.shape) # Print image shape
    cv2.imshow("original", img)

    # Cropping an image

    # cropped_image = img[35:75, 65:275] #1
    # cropped_image = img[35:75, 285:495] #2
    # cropped_image = img[35:75, 495:705] #3
    # cropped_image = img[35:75, 715:925] #4
    # cropped_image = img[175:215, 65:275] #LCD 5
    # cropped_image = img[175:215, 285:495]  # 6
    # cropped_image = img[175:215, 495:705] #7
    # cropped_image = img[175:215, 715:925] #8
    # cropped_image = img[310:345, 65:275] #9 battery
    # cropped_image = img[310:345, 285:495] #10
    # cropped_image = img[310:345, 495:705] #11
    # cropped_image = img[310:345, 715:925] #12
    # cropped_image = img[450:485, 153:300] #13 joystick
    # cropped_image = img[450:485, 395:620] #14
    # cropped_image = img[450:495, 670:910] #15
    # cropped_image = img[630:675, 420:590] #16 arduino

    #list with positions : pos (upper left corner) for all signs
    signs = [[35,65],]

    w = 210 #width sign
    h = 40 #hight sign

    # A text file is created and flushed
    file = open("signs_position_name.txt", "w+")
    file.write("")
    file.close()

    # Creating a copy of image
    im2 = img.copy()

    for pos in signs:
        y = pos[0]
        x = pos[1]
        mid_x = x + w/2
        mid_x = str(int(mid_x))
        mid_y = y + h/2
        mid_y = str(int(mid_y))

        cropped = im2[y:y + h, x:x + w]
        text = pytesseract.image_to_string(cropped)
        file = open("signs_position_name.txt", "a")
        if text == '':
            continue
        # Appending the text into file
        file.write(text + ' - ' + mid_x + ',' + mid_y + ',90')
        file.close()

    # Display cropped image
    cv2.imshow("cropped", cropped_image)

    # Save the cropped image
    cv2.imwrite("Cropped Image.jpg", cropped_image)

    cv2.waitKey(0)
    #cv2.destroyAllWindows()

    imgGray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    def tesseract():
        path_to_tesseract = r"C:\Program Files\Tesseract-OCR\tesseract.exe"
        image_path = 'Cropped Image.jpg'
        pytesseract.tesseract_cmd = path_to_tesseract
        text = pytesseract.image_to_string(Image.open(image_path))
        print(text[:-1])

    tesseract()


from django.contrib import admin
from .models import Review

# Register your models here.

class ReviewAdmin(admin.ModelAdmin):
    list_display = (
        'product',
        'user',
        'rating',
        'title',
        'description',
        'review_date',
    )
    ordering = ('product',)

admin.site.register(Review, ReviewAdmin)


# Author: Joshua Jackson
# Date: 06/20/2020

# This file will contain the class which create Word2Vec file using gensim

from gensim.models import Word2Vec
from gensim.models.phrases import Phrases, Phraser
from datetime import datetime

# script to create word embeddings for Neural Network weight

class word2vec:
    def __init__(self, debug=False):
        try:
            #initiliaze init variable
            self.debug = debug

        except Exception as e:
            print(f"Something went wrong in __init__: {e}")

    #using a pre tokenized list create the word2vec traing data
    def create_bigram_embedding(self, tokens, emb_size=250, minCount=1, threshold_amount=1, workers=3, algo=0, window=5):
        try:

            #generate tri-gram using gensim
            phrases = Phrases(tokens, min_count=minCount, threshold=threshold_amount)
            #create bi-gram
            bigram = Phraser(phrases)

            #build model
            model = Word2Vec(bigram[tokens],\
                            size=emb_size,\
                            window=window,\
                            min_count=minCount,\
                            workers=workers,\
                            sg=algo)

            dateTimeObj = datetime.now()
            timestampStr = dateTimeObj.strftime("%d-%b-%Y")
            #save model to local directory as bin file

            #save both binary and non binary file
            model.save(f'bigram-model-{timestampStr}.bin', binary=True)
            model.save(f'bigram-model-{timestampStr}.txt', binary=False)

            return model
        except Exception as e:
            print(f"Something went wrong in create_training_data: {e}")


#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Thu Feb  9 14:49:52 2023

@author: intern
"""

import cv2

kernel = np.ones((3, 3), dtype=np.uint8)
erosion = cv2.erode(im0, kernel, iterations=1)
plt.imshow( erosion[:,:,0:3])
#%%
erosion = cv2.morphologyEx(im0, cv2.MORPH_OPEN, kernel, 1)
plt.imshow( erosion[:,:,0:3])
hsvim = rgb_to_hsv(erosion[:,:,0:3])
#%%
float("0.5555554573")
a = format(float("0.5555554573"), '.6f')


pkgname = "libsbsms"
pkgver = "2.3.0"
pkgrel = 0
build_style = "cmake"
hostmakedepends = [
    "cmake",
    "ninja",
    "pkgconf",
]
pkgdesc = "Library for high quality time and pitch scale modification"
maintainer = "psykose <alice@ayaya.dev>"
license = "GPL-2.0-or-later"
url = "https://github.com/claytonotey/libsbsms"
source = (
    f"https://github.com/claytonotey/libsbsms/archive/refs/tags/{pkgver}.tar.gz"
)
sha256 = "4f88d152bc06fedbda9d5d65517d40254a7310c9050601a93122309d45afd2c9"
# vis breaks symbols
hardening = []
# no tests
options = ["!check"]

@subpackage("libsbsms-devel")
def _devel(self):
    return self.default_devel()


from PyQt5.QtWidgets import  QDialog, QComboBox, QPushButton, QRadioButton
from pulse.utils import error
from os.path import basename
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import Qt
from PyQt5 import uic
import configparser

class ElementTypeInput(QDialog):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        uic.loadUi('pulse/uix/user_input/ui/elementTypeInput.ui', self)

        icons_path = 'pulse\\data\\icons\\'
        self.icon = QIcon(icons_path + 'pulse.png')
        self.setWindowIcon(self.icon)

        self.index = 0
        self.element_type = 'pipe_1'

        self.comboBox = self.findChild(QComboBox, 'comboBox')
        self.comboBox.currentIndexChanged.connect(self.selectionChange)
        self.index = self.comboBox.currentIndex()

        self.radioButton_all = self.findChild(QRadioButton, 'radioButton_all')
        self.radioButton_entity = self.findChild(QRadioButton, 'radioButton_entity')
        self.radioButton_all.toggled.connect(self.radioButtonEvent)
        self.radioButton_entity.toggled.connect(self.radioButtonEvent)
        self.flagAll = self.radioButton_all.isChecked()
        self.flagEntity = self.radioButton_entity.isChecked()

        self.pushButton_2 = self.findChild(QPushButton, 'pushButton_confirm')
        self.pushButton_2.clicked.connect(self.button_clicked)

        self.exec_()

    def radioButtonEvent(self):
        self.flagAll = self.radioButton_all.isChecked()
        self.flagEntity = self.radioButton_entity.isChecked()

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Enter or event.key() == Qt.Key_Return:
            self.check()
        elif event.key() == Qt.Key_Escape:
            # self.index = -1
            self.close()

    def selectionChange(self, index):
        self.index = self.comboBox.currentIndex()
        if self.index == 0:
            self.element_type = 'pipe_1'
        elif self.index == 1:
            self.element_type = 'pipe_2'
        elif self.index == 2:
            self.element_type = 'shell'

    def check(self):
        self.close()

    def button_clicked(self):
        self.check()


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

import matplotlib.pyplot as plt
import numpy as np

def approach_angle_reward(roll,pitch):
    if np.abs(roll) + np.abs(pitch) < 0.174:
        return 100*np.exp((7.0*(0.174-np.abs(roll) - np.abs(pitch)))**1)
    if (np.abs(roll) + np.abs(pitch)<=1.55)and(np.abs(roll) + np.abs(pitch) >=0.174):
        return -6.0*(np.exp((3.2*(np.abs(roll) + np.abs(pitch)-0.174))**1))
    if (np.abs(roll) + np.abs(pitch)>1.55):
        return -500.0

def flip_reward(angle,prev_angle):
    if np.abs(angle) < 0.26:
        return 0.05*np.exp(20*(0.26-np.abs(angle)))
    if (np.abs(angle)>=0.26):
        return -7.0*np.exp((2.1*(np.abs(angle)-0.26))**1)

def approach_velocity_reward(velocity):
    if velocity>1.6:
        return -20.0*np.exp((0.45*(np.abs(velocity)))**1)
    if (velocity<=1.6) and (velocity >=0.1):
        return - 12.5 * np.exp(2.1*(velocity-0.1))
    if velocity < 0.1:
        return +55.0 * np.exp(20*(0.1-velocity))

# approach angle
#roll_space = np.linspace(-1.57,1.57,300)
#pitch_space = np.linspace(-1.57,1.57,300)

#X,Y = np.meshgrid(roll_space,pitch_space)
#
#Z = np.zeros(shape = (len(roll_space),len(pitch_space)))

#for it_r,r in enumerate(roll_space):
#    for it_p,p in enumerate(pitch_space):
#        Z[it_r,it_p] = approach_angle_reward(r,p)

# calculate angle_space for flipping
#angle_space = np.linspace(-3.14,3.14,500)
#dummy_space = np.linspace(-3.14,3.14,500)
#
#
#X,Y = np.meshgrid(angle_space,dummy_space)
#Z = np.zeros(shape = (len(angle_space),len(dummy_space)))
#
#for it_a1,a1 in enumerate(angle_space):
#    for it_a2,a2 in enumerate(dummy_space):
#        Z[it_a1,it_a2] = flip_reward(a1,a2)

# approach velocity

vel_space = np.linspace(0.0,10,500)
dummy_space = np.linspace(0.0,10,500)

X,Y = np.meshgrid(vel_space,dummy_space)
Z = np.zeros(shape = (len(vel_space),len(dummy_space)))

for it_a1,a1 in enumerate(vel_space):
    for it_a2,a2 in enumerate(dummy_space):
        Z[it_a1,it_a2] = approach_velocity_reward(a1)

fig, ax = plt.subplots(figsize=(7, 7), dpi=100)

# for positive values
p = ax.pcolor(X, Y, Z, cmap=plt.cm.RdBu, vmin=(Z).min(), vmax=(Z).max())

#p = ax.pcolor(X, Y, Z, cmap=plt.cm.RdBu, vmin=Z.min(), vmax=Z.max())

cb = fig.colorbar(p)

#cnt = plt.contour(Z, cmap=plt.cm.RdBu, vmin=abs(Z).min(), vmax=abs(Z).max(), extent=[0, 1, 0, 1])


"""
A Gopher Server written in Python

author:  Julia Connelly, Adante Ratzlaff, Jack Wines
CS 331, Spring 2018
date:  12 April 2018
"""
import sys
import socket
import os

class GopherServer:
    def __init__(self, port=50000):
        self.port = port
        self.host = ""
        self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        self.sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        self.sock.bind((self.host, self.port))
        self.links = GopherServer.readLinks("root/")

    @staticmethod
    def cleanLinksFile(s):
        cleanLinks = ""
        splitLines = s.split("\n")
        splitLines.sort()
        for line in splitLines:
            splitLine = line.split("\t")
            properLengths = [70 - 1, 225 - 1]
            for name, length, i in zip(splitLine[:2], properLengths, range(2)):
                splitLine[i] = name[:length]
            cleanLinks += "\t".join(splitLine) + "\r\n"
        return cleanLinks

    @staticmethod
    def readLinks(linksPath):
        try:
            with open(linksPath + ".links", "r") as linksFile:
                return GopherServer.cleanLinksFile(linksFile.read())
        except OSError:
            return None

    @staticmethod
    def readFile(filePath):
        try:
            with open(filePath, "r", encoding = "ascii", errors = "ignore") as file:
                return file.read()
        except OSError:
            return None

    @staticmethod
    def getResponse(filePath):
        filePath = "root/" + filePath.replace("\r", "").replace("\n", "")
        if os.path.isdir(filePath):
            return GopherServer.readLinks(filePath)
        else:
            return GopherServer.readFile(filePath)

    @staticmethod
    def addPeriodOnNewLine(resp):
        return resp + "\r\n."

    # returns False and prints if fails
    @staticmethod
    def safeDecode(data, clientSock):
        try:
            return data.decode(encoding = "ascii", errors = "ignore")
        except UnicodeDecodeError:
            errStr = "Error decoding from utf-8\r\n"
            print(errStr, file=sys.stderr)
            clientSock.sendall(errStr.encode('ascii'))
            return None

    # returns an error string and prints if fails
    @staticmethod
    def safeEncode(s):
        try:
            return s.encode('ascii', errors = "ignore")
        except UnicodeEncodeError:
            errStr = "Error encoding to utf-8. str: "
            print(errStr, s, "\r\n", file=sys.stderr)
            return errStr.encode('ascii', errors = "ignore")

    def listen(self):
        self.sock.listen(5)

        while True:
            clientSock, clientAddr = self.sock.accept()
            print("Connection received from ", clientSock.getpeername())

            data = clientSock.recv(1024)

            # try to decode data. utf-8 is the default
            decodedData = GopherServer.safeDecode(data, clientSock)
            if not decodedData:
                continue
            # an empty string means we should send the .links file.
            if decodedData.strip() == "":
                toSend = GopherServer.safeEncode(GopherServer.addPeriodOnNewLine(self.links))
                clientSock.sendall(toSend)
            else:
                info = GopherServer.getResponse(decodedData)
                if info:
                    clientSock.sendall(GopherServer.safeEncode(GopherServer.addPeriodOnNewLine(info)))
                else:
                    clientSock.sendall(
                        GopherServer.addPeriodOnNewLine("Received file path does not exist.\r\n").encode('ascii'))
            clientSock.close()

def main():
    # Create a server
    if len(sys.argv) > 1:
        try:
            server = GopherServer(int(sys.argv[1]))
        except ValueError:
            print("Error in specifying port. Creating server on default port.")
            server = GopherServer()
    else:
        server = GopherServer()

    # Listen forever
    print("Listening on port " + str(server.port))
    server.listen()

main()


#!/usr/bin/env python3.11

"""
Video Command Invoker (Command Design Pattern)

This Python script defines the `VideoInvoker` class, a central component in the Command
design pattern for executing video-related commands. It manages the video generation
process and serves as the invoker in the pattern.

The `VideoInvoker` class provides methods for executing video commands, including
starting subshells, running code animations, and interacting with a web browser to
create instructional videos. It collaborates with classes like `CodeAnimationGenerator`,
`BrowserInteraction`, and `ProcessManagement` to record video segments and assemble
them into a final video.

Usage:
    To create and execute a sequence of video commands, initialize an instance of
    the `VideoInvoker` class and use its methods. This class works with command objects
    that encapsulate specific actions and parameters.

Example:
    ```python
    invoker = VideoInvoker()

    # Create command objects
    animation_generator = CodeAnimationGenerator(text_mapping, INTRO_CODE, OUTRO_CODE)
    start_subshell = StartSubshell("server_subshell")
    run_server = ExecuteSubshellCommand("server_subshell", "python3.11 test_server.py &")
    browser_interaction = BrowserInteraction("http://localhost:5000/", "Webpage narration")
    kill_subshell = TerminateSubshell("server_subshell")

    # Execute command objects
    invoker.execute_command(animation_generator)
    invoker.execute_command(start_subshell)
    invoker.execute_command(run_server)
    invoker.execute_command(browser_interaction)
    invoker.execute_command(kill_subshell)

    FINAL_VIDEO_NAME = "final_video.mp4"
    invoker.dump_file(FINAL_VIDEO_NAME)
    ```

Author:
    Roman Parise
"""

# Project imports
from .video_receiver import VideoReceiver
from .command import Command, CreateClipCommand
from .code_animation_generator import CodeAnimationGenerator
from .browser_interaction import BrowserInteraction
from .process_management import StartSubshell, ExecuteSubshellCommand, TerminateSubshell

class VideoInvoker:
    """
    A class that invokes video-related commands.
    """

    def __init__(self):
        """
        Initializes a VideoInvoker with a VideoReceiver.
        """
        self.video_receiver = VideoReceiver()

    def execute_command(self, command: Command):
        """
        Executes a given command.

        Args:
            command (Command): The command to execute.
        """
        if isinstance(command, CreateClipCommand):
            command.set_receiver(self.video_receiver)
            command.execute()
        else:
            command.execute()

    def dump_file(self, output_filename: str = "output.mp4"):
        """
        Saves the full movie to an mp4 file using write_videofile.

        Args:
            output_filename (str): The name of the output video file.
        """
        self.video_receiver.dump_file(output_filename)

if __name__ == "__main__":
    invoker = VideoInvoker()

    # Write Flask server
    text_mapping = [
        {
            "narration_text": "First, we're going to make the necessary imports.",
            "code_text": """
vim test_server.py
ifrom flask import Flask

""",
        },
        {
            "narration_text": "Then, we're going to instantiate our webapp and create a route.",
            "code_text": """
app = Flask(__name__)

@app.route("/")
def hello():
    return "Hello World!"

""",
        },
        {
            "narration_text": "Finally, we'll run the app.",
            "code_text": """
if __name__ == '__main__':
    app.run()

""",
        },
        {
            "narration_text": "We're now going to run the server.",
            "code_text": """
<Escape>
:x

""",
        },
    ]
    INTRO_CODE = "rm -rf test_server.py; clear"
    OUTRO_CODE = "rm -rf test_server.py; clear"

    # Initialize the CodeAnimationGenerator
    animation_generator = CodeAnimationGenerator(text_mapping, INTRO_CODE, OUTRO_CODE)
    invoker.execute_command(animation_generator)

    # Start subshell for server
    start_subshell = StartSubshell("server_subshell")
    invoker.execute_command(start_subshell)

    # Run server in subshell
    run_server = ExecuteSubshellCommand(
        "server_subshell", "python3.11 test_server.py &"
    )
    invoker.execute_command(run_server)

    # Test the BrowserInteraction class
    browser_interaction = BrowserInteraction(
        "http://localhost:5000/",
        "As you can see, the webpage is rendered as expected.",
    )
    invoker.execute_command(browser_interaction)

    # Kill subshell
    kill_subshell = TerminateSubshell("server_subshell")
    invoker.execute_command(kill_subshell)

    FINAL_VIDEO_NAME = "final_video.mp4"
    invoker.dump_file(FINAL_VIDEO_NAME)
    print(f"Animation video saved to {FINAL_VIDEO_NAME}")


import marqo
import pprint
import requests
import random
import math

# Test bug in pagination feature of OpenSearch
# Create marqo index
mq = marqo.Client(url='http://localhost:8882')

try:
    mq.index("my-first-index").delete()
except:
    pass

# Index set number of documents
# 100 random words
mq.create_index("my-first-index")
vocab_source = "https://www.mit.edu/~ecprice/wordlist.10000"
vocab = requests.get(vocab_source).text.splitlines()
num_docs = 100
random.seed(2020)
docs = [{"Title": "a " + (" ".join(random.choices(population=vocab, k=25))),
                    "_id": str(i)
                    }
                  for i in range(num_docs)]

mq.index("my-first-index").add_documents(
            docs, auto_refresh=False
        )
mq.index("my-first-index").refresh()
search_method = "TENSOR"

# Search for all 100 documents at the same time
# DEBUG FULL RESULTS
debug_res = mq.index("my-first-index").search(
                search_method=search_method,
                q='a',
                limit=num_docs)
debug_res_id_only = [hit["_id"] for hit in debug_res["hits"]]

# Search for pages of 1 document at a time
for page_size in [1]:
    print("========================================================")
    print(f"{search_method}: Results for page_size = {page_size}")

    paginated_search_results = {"hits": []}
    for page_num in range(math.ceil(num_docs / page_size)):
        lim = page_size
        off = page_num * page_size
        # print(f"Now testing: limit={lim}, offset={off}")
        page_res = mq.index("my-first-index").search(
                        search_method=search_method,
                        q='a',
                        limit=lim, offset=off)
        single_page_id_only = [hit["_id"] for hit in page_res["hits"]]

        paginated_search_results["hits"].extend(page_res["hits"])
        print("========================================================")
        print(f"Query for page num {page_num}")
        print(f"size: {page_res['limit']}, from: {page_res['offset']}")

        expected_res = debug_res_id_only[off:off+lim]
        print(f"Paginated result for page num  {page_num}: {single_page_id_only}")
        print(f"Expected result for page num  {page_num}: {expected_res}")

        if expected_res != single_page_id_only:
            print("DISCREPANCY FOUND.")

    page_id_only = [hit["_id"] for hit in paginated_search_results["hits"]]

    print("========================================================")
    print(f"FULL RESULTS: (length = {len(debug_res['hits'])})")
    print(debug_res_id_only)

    print(f"PAGINATED: (length = {len(paginated_search_results['hits'])})")
    print(page_id_only)

    print("Paginated results same as expected full results?")
    print(debug_res["hits"] == paginated_search_results["hits"])


__all__ = (
    'Persistor',
    'SQLPersistor',
    'SQLitePersistor',
)

try:
    import sqlite3
except Exception:
    sqlite3 = None

class Persistor(object):
    """
    Class providing methods for persisting input (persistence occurs when the
    `persist` method is called on a `Model` instance)
    """
    def persist(self, attributes):
        """
        Persist the specified `attributes`

        Args:
            attributes (dict): the attributes

        Returns:
            bool: the result

        Raises:
            NotImplementedError: if this method is not overridden by an
                inheriting class
        """
        raise NotImplementedError

class SQLPersistor(Persistor):
    """
    Class providing methods for persisting input to a SQL DB (persistence occurs
    when the `persist` method is called on a `Model` instance)

    Instance Attributes:
        table_name (str): the table name
        key_attribute_names (set of str): the key-attribute names (in the future
            complex keys will likely be supported, for now only simple/singular
            keys are supported)
    """
    def __init__(
        self,
        table_name,
        key_attribute_name=None,
    ):
        self.table_name = table_name
        self.key_attribute_names = frozenset([key_attribute_name]) if \
            key_attribute_name else frozenset()

    @property
    def connection(self):
        """
        Lazy-load and return the "Connection" instance

        Returns:
            mixed: the instantiated/connected "Connection" instance

        Raises:
            NotImplementedError: if the `_connect` method is not overridden by
                an inheriting class
        """
        if not hasattr(self, '_connection'):
            self._connection = self._connect()
        return self._connection

    def persist(self, attributes):
        """
        Persist the specified `attributes`

        Args:
            attributes (dict): the attributes

        Returns:
            mixed: the mapped INSERT/UPDATE result

        Raises:
            RuntimeError: if a dependency could not be loaded or a connection to
                DB could not be established
        """
        key_attributes, non_key_attributes = \
            self._partition_attributes(attributes)
        if key_attributes and all(key_attributes.values()):
            return self._update(key_attributes, non_key_attributes)
        return self._insert(non_key_attributes)

    def _column_name(self, attribute_name):
        """
        Convert an attribute-name to a column-name

        Args:
            attribute_name (str): the attribute-name

        Returns:
            str: the column-name
        """
        return ''.join(
            str.capitalize(attribute_name_part)
            for attribute_name_part in attribute_name.split('_')
        )

    def _column_value(self, attribute_value):
        """
        Sanitize and quote an attribute-value

        Args:
            attribute_value (mixed): the attribute-value

        Returns:
            str: the sanitized and quoted attribute-value
        """
        return "'%s'" % attribute_value if attribute_value is not None else \
            'NULL'

    def _connect(self):
        """
        Establish a new connection to a DB

        Returns:
            mixed: the new connection instance

        Raises:
            NotImplementedError: if this method is not overridden by an
                inheriting class
        """
        raise NotImplementedError

    def _insert(self, non_key_attributes):
        """
        Perform an INSERT operation based on the specified `non_key_attributes`

        Args:
            non_key_attributes (dict): the non-key-attributes

        Returns:
            mixed: the mapped INSERT result
        """
        return self._map_insert_result(self.connection.execute(self._insert_sql(
            non_key_attributes)))

    def _insert_sql(self, non_key_attributes):
        """
        Generate the SQL required for an INSERT operation based on the specified
        `non_key_attributes`

        Args:
            non_key_attributes (dict): the non-key-attributes

        Returns:
            str: the SQL string
        """
        return 'INSERT INTO %s (%s) VALUES (%s)' % (
            self.table_name,
            ', '.join(
                self._column_name(attribute_name)
                for attribute_name in non_key_attributes.keys()
            ),
            ', '.join(
                self._column_value(attribute_value)
                for attribute_value in non_key_attributes.values()
            ),
        )

    def _map_insert_result(self, result):
        """
        Map the result from an INSERT operation

        Args:
            result (mixed): the unmapped INSERT result

        Returns:
            mixed: the mapped INSERT result
        """
        return result

    def _map_update_result(self, result):
        """
        Map the result from an UPDATE operation

        Args:
            result (mixed): the unmapped UPDATE result

        Returns:
            mixed: the mapped UPDATE result
        """
        return result

    def _partition_attributes(self, attributes):
        """
        Partition the specified `attributes` into two `dict(s)`, one of the
        `key_attributes` and another of the `non_key_attributes`

        Args:
            attributes (dict): the attributes

        Returns:
            tuple (of dicts): a `tuple` of the `key_attributes` and
                `non_key_attributes`
        """
        key_attributes, non_key_attributes = {}, {}
        key_attribute_names = self.key_attribute_names
        for attribute_name, attribute_value in attributes.items():
            if attribute_name in key_attribute_names:
                key_attributes[attribute_name] = attribute_value
            else:
                non_key_attributes[attribute_name] = attribute_value
        return (key_attributes, non_key_attributes)

    def _update(
        self,
        key_attributes,
        non_key_attributes
    ):
        """
        Perform an UPDATE operation based on the specified `key_attributes` and
        `non_key_attributes`

        Args:
            key_attributes (dict): the key-attributes
            non_key_attributes (dict): the non-key-attributes

        Returns:
            mixed: the mapped UPDATE result
        """
        return self._map_update_result(self.connection.execute(self._update_sql(
            key_attributes, non_key_attributes)))

    def _update_sql(
        self,
        key_attributes,
        non_key_attributes
    ):
        """
        Generate the SQL required for an UPDATE operation based on the specified
        `key_attributes` and `non_key_attributes`

        Args:
            key_attributes (dict): the key-attributes
            non_key_attributes (dict): the non-key-attributes

        Returns:
            str: the SQL string
        """
        return 'UPDATE %s SET %s WHERE %s' % (
            self.table_name,
            ', '.join(
                '%s = %s' % (self._column_name(attribute_name),
                    self._column_value(attribute_value))
                for attribute_name, attribute_value in
                    non_key_attributes.items()
            ),
            ' AND '.join(
                '%s = %s' % (self._column_name(attribute_name),
                    self._column_value(attribute_value))
                for attribute_name, attribute_value in
                    key_attributes.items()
            )
        )

class SQLitePersistor(SQLPersistor):
    """
    Class providing methods for persisting input to a SQLite DB (persistence
    occurs when the `persist` method is called on a `Model` instance)

    Instance Attributes:
        database_file_path (str): the database file-path
        table_name (str): the table name
        key_attribute_names (set of str): the key-attribute names (in the future
            complex keys will likely be supported, for now only simple/singular
            keys are supported)
    """
    def __init__(
        self,
        database_file_path,
        table_name,
        key_attribute_name=None
    ):
        super(SQLitePersistor, self).__init__(table_name, key_attribute_name)
        self.database_file_path = database_file_path

    def _connect(self):
        """
        Establish a new connection to a SQLite DB

        Returns:
            sqlite3.Connection: the new connection instance

        Raises:
            RuntimeError: if the `sqlite3` library was not successfully loaded
        """
        if sqlite3 is None:
            raise RuntimeError
        return sqlite3.connect(self.database_file_path)

    def _map_insert_result(self, result):
        """
        Map the result from an INSERT operation

        Args:
            result (mixed): the unmapped INSERT result

        Returns:
            mixed: the mapped INSERT result
        """
        return {next(iter(self.key_attribute_names)): result.lastrowid}

    def _map_update_result(self, result):
        """
        Map the result from an UPDATE operation

        Args:
            result (mixed): the unmapped UPDATE result

        Returns:
            mixed: the mapped UPDATE result
        """
        return {next(iter(self.key_attribute_names)): result.lastrowid}


import csv
import json
from collections import OrderedDict

def import_jsonfile_as_OrderedDict(json_filepath):
    f = open(json_filepath, "r")
    return json.loads(f.read(), object_pairs_hook = OrderedDict)

def export_dict_to_jsonfile(dic, json_filepath, indent = 2, separators=(',', ': ')):
    outstr = json.dumps(dic, indent = indent, separators = separators)
    with open(json_filepath, "w") as outfile:
        outfile.write(outstr)

def get_entries_in_csv_col(csv_filepath, col_name, delimiter = ','):
    with open(csv_filepath) as csv_file:
        csv_reader = csv.reader(csv_file, delimiter = delimiter)
        i_col_requested = 0
        res = []
        for i_row, row in enumerate(csv_reader):
            if i_row == 0:
                for i_col, col in enumerate(row):
                    if col == col_name: i_col_requested = i_col
            else:
                res.append(row[i_col_requested])
        return res


#! /usr/bin/env python3

import os
import re
from azure.identity import DefaultAzureCredential
from azure.mgmt.compute import ComputeManagementClient

# Variables
subscription_id = os.environ.get("AZURE_SUBSCRIPTION_ID")
location = "eastus"
publisher_name = "PaloAltoNetworks"

# Acquire a credential object
token_credential = DefaultAzureCredential()

# Acquire a compute client
compute_client = ComputeManagementClient(token_credential, subscription_id)

# Gather version numbers per offer and per sku
fixed_bnd1 = []
offer = "vmseries1" # Fixed CPU
sku = "bundle1"
images = compute_client.virtual_machine_images.list(location, publisher_name, offer, sku)
for image in images:
    fixed_bnd1.append(image.name)

fixed_bnd2 = []
offer = "vmseries1" # Fixed CPU
sku = "bundle2"
images = compute_client.virtual_machine_images.list(location, publisher_name, offer, sku)
for image in images:
    fixed_bnd2.append(image.name)

fixed_byol = []
offer = "vmseries1" # Fixed CPU
sku = "byol"
images = compute_client.virtual_machine_images.list(location, publisher_name, offer, sku)
for image in images:
    fixed_byol.append(image.name)

flex_bnd1_v9 = []
flex_bnd2_v9 = []
flex_bnd3_v9 = []
flex_byol_v9 = []
panorama_v9 = []

flex_bnd1 = []
offer = "vmseries-flex" # Flex
sku = "bundle1"
images = compute_client.virtual_machine_images.list(location, publisher_name, offer, sku)
for image in images:
    if image.name[0]=="9":
        flex_bnd1_v9.append(image.name)
    else:
        flex_bnd1.append(image.name)

flex_bnd2 = []
offer = "vmseries-flex" # Flex
sku = "bundle2"
images = compute_client.virtual_machine_images.list(location, publisher_name, offer, sku)
for image in images:
    if image.name[0]=="9":
        flex_bnd2_v9.append(image.name)
    else:
        flex_bnd2.append(image.name)

flex_bnd3 = []
offer = "vmseries-flex" # Flex
sku = "bundle3"
images = compute_client.virtual_machine_images.list(location, publisher_name, offer, sku)
for image in images:
    if image.name[0]=="9":
        flex_bnd3_v9.append(image.name)
    else:
        flex_bnd3.append(image.name)

flex_byol = []
offer = "vmseries-flex" # Flex
sku = "byol"
images = compute_client.virtual_machine_images.list(location, publisher_name, offer, sku)
for image in images:
    if image.name[0]=="9":
        flex_byol_v9.append(image.name)
    else:
        flex_byol.append(image.name)

panorama = []
offer = "panorama" # Panorama
sku = "byol"
images = compute_client.virtual_machine_images.list(location, publisher_name, offer, sku)
for image in images:
    if image.name[0]=="9":
        panorama_v9.append(image.name)
    else:
        panorama.append(image.name)

# Output in markdown format
result = "\n# Azure\n"
result += "\n## Flexible CPU (Offer: `vmseries-flex`)\n"
result += "\n### BYOL (SKU: `byol`)\n"
for sku in flex_byol_v9:
    result += "`" + sku + "` "
for sku in flex_byol:
    result += "`" + sku + "` "
result += "\n### PAYG Bundle 1 (SKU: `bundle1`)\n"
for sku in flex_bnd1_v9:
    result += "`" + sku + "` "
for sku in flex_bnd1:
    result += "`" + sku + "` "
result += "\n### PAYG Bundle 2 (SKU: `bundle2`)\n"
for sku in flex_bnd2_v9:
    result += "`" + sku + "` "
for sku in flex_bnd2:
    result += "`" + sku + "` "
result += "\n### PAYG Bundle 3 (SKU: `bundle3`)\n"
for sku in flex_bnd3_v9:
    result += "`" + sku + "` "
for sku in flex_bnd3:
    result += "`" + sku + "` "
result += "\n## Fixed CPU (Offer: `vmseries1`)\n"
result += "\n### BYOL (SKU: `byol`)\n"
for sku in fixed_byol:
    result += "`" + sku + "` "
result += "\n### PAYG Bundle 1 (SKU: `bundle1`)\n"
for sku in fixed_bnd1:
    result += "`" + sku + "` "
result += "\n### PAYG Bundle 2 (SKU: `bundle2`)\n"
for sku in fixed_bnd2:
    result += "`" + sku + "` "
result += "\n"
result += "\n## Panorama (Offer: `panorama`, SKU: `byol`)\n"
for sku in panorama_v9:
    result += "`" + sku + "` "
for sku in panorama:
    result += "`" + sku + "` "

print(result)


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

# file docbook2epub.py
# This file is part of LyX, the document processor.
# Licence details can be found in the file COPYING.
#
# \author Thibaut Cuvelier
#
# Full author contact details are available in file CREDITS

# Usage:
#   python docbook2epub.py java_binary saxon_path xsltproc_path xslt_path in.docbook in.orig.path out.epub

from __future__ import print_function

import glob
import os
import shutil
import sys
import tempfile
import zipfile
from io import open  # Required for Python 2.

def _parse_nullable_argument(arg):
    return arg if arg != '' and arg != 'none' else None

class ImageRename:
    def __init__(self, opf_path, local_path, epub_path):
        self.opf_path = opf_path
        self.local_path = local_path
        self.epub_path = epub_path

class DocBookToEpub:
    def __init__(self, args=None):
        if args is None:
            args = sys.argv

        if len(args) != 8:
            print('Exactly eight arguments are expected, only %s found: %s.' % (len(args), args))
            sys.exit(1)

        self.own_path = sys.argv[0]
        self.java_path = _parse_nullable_argument(sys.argv[1])
        self.saxon_path = _parse_nullable_argument(sys.argv[2])
        self.xsltproc_path = _parse_nullable_argument(sys.argv[3])
        self.xslt_path = _parse_nullable_argument(sys.argv[4])
        self.input = sys.argv[5]
        self.input_path = sys.argv[6]
        self.output = sys.argv[7]
        self.script_folder = os.path.dirname(self.own_path) + '/../'

        print('Generating ePub with the following parameters:')
        print(self.own_path)
        print(self.java_path)
        print(self.saxon_path)
        print(self.xsltproc_path)
        print(self.xslt_path)
        print(self.input)
        print(self.input_path)
        print(self.output)

        # Precompute paths that will be used later.
        self.output_dir = tempfile.mkdtemp().replace('\\', '/')
        self.package_opf = self.output_dir + '/OEBPS/package.opf'  # Does not exist yet,
        print('Temporary output directory: %s' % self.output_dir)

        if self.xslt_path is None:
            self.xslt = self.script_folder + 'docbook/epub3/chunk.xsl'
        else:
            self.xslt = self.xslt_path + '/epub3/chunk.xsl'
        print('XSLT style sheet to use:')
        print(self.xslt)

        if self.saxon_path is None:
            self.saxon_path = self.script_folder + 'scripts/saxon6.5.5.jar'

        # These will be filled during the execution of the script.
        self.renamed = None

    def gracefully_fail(self, reason):
        print('docbook2epub fails: %s' % reason)
        shutil.rmtree(self.output_dir, ignore_errors=True)
        sys.exit(1)

    def start_xslt_transformation(self):
        command = None
        if self.xsltproc_path is not None:
            command = self.start_xslt_transformation_xsltproc()
        elif self.java_path is not None:
            command = self.start_xslt_transformation_saxon6()

        if command is None:
            self.gracefully_fail('no XSLT processor available')

        print('Command to execute:')
        print(command)

        quoted_command = command
        if os.name == 'nt':
            # On Windows, it is typical to have spaces in folder names, and that requires to wrap the whole command
            # in quotes. On Linux, this might create errors when starting the command.
            quoted_command = '"' + command + '"'
        # This could be simplified by using subprocess.run, but this requires Python 3.5.

        if os.system(quoted_command) != 0:
            self.gracefully_fail('error from the XSLT processor')

        print('Generated ePub contents.')

    def start_xslt_transformation_xsltproc(self):
        params = '-stringparam base.dir "' + self.output_dir + '"'
        return '"' + self.xsltproc_path + '" ' + params + ' "' + self.xslt + '" "' + self.input + '"'

    def start_xslt_transformation_saxon6(self):
        params = 'base.dir=%s' % self.output_dir
        executable = '"' + self.java_path + '" -jar "' + self.saxon_path + '"'
        return executable + ' "' + self.input + '" "' + self.xslt + '" "' + params + '"'

    def get_images_from_package_opf(self):
        images = []

        # Example in the OPF file:
        #     <item id="d436e1" href="D:/LyX/lib/images/buffer-view.svgz" media-type="image/SVGZ"/>
        # The XHTML files are also <item> tags:
        #     <item id="id-d0e2" href="index.xhtml" media-type="application/xhtml+xml"/>
        try:
            with open(self.package_opf, 'r') as f:
                for line in f.readlines():
                    if '<item' in line and 'media-type="image' in line:
                        images.append(line.split('href="')[1].split('"')[0])
        except FileNotFoundError:
            print('The package.opf file was not found, probably due to a DocBook error. The ePub file will be corrupt.')

        return images

    def get_image_changes(self):
        epub_folder = 'images/'

        changes = []
        for image in self.get_images_from_package_opf():
            if os.path.exists(image):
                file_system_path = image
            elif os.path.exists(self.input_path + image):
                file_system_path = self.input_path + image
            else:
                file_system_path = ''

            changes.append(ImageRename(image, file_system_path, epub_folder + os.path.basename(image)))
        return changes

    def change_image_paths(self, file):
        # This could be optimised, as the same operation is performed a zillion times on many files:
        # https://www.oreilly.com/library/view/python-cookbook/0596001673/ch03s15.html
        with open(file, 'r', encoding='utf8') as f:
            contents = list(f)

        with open(file, 'w', encoding='utf8') as f:
            for line in contents:
                for change in self.renamed:
                    line = line.replace(change.opf_path, change.epub_path)
                f.write(line)

    def copy_images(self):
        # Copy the assets to the OEBPS/images/. All paths are available in OEBPS/package.opf, but they must also be
        # changed in the XHTML files. Typically, the current paths are absolute.

        # First, get the mapping old file => file in the ePub archive.
        self.renamed = self.get_image_changes()

        # Then, transform all paths (both OPF and XHTML files).
        self.change_image_paths(self.output_dir + '/OEBPS/package.opf')
        for file in glob.glob(self.output_dir + '/OEBPS/*.xhtml'):
            self.change_image_paths(file)

        # Ensure that the destination path exists. OEBPS exists due to the DocBook-to-ePub transformation.
        if not os.path.exists(self.output_dir + '/OEBPS/images/'):
            os.mkdir(self.output_dir + '/OEBPS/images/')

        # Finally, actually copy the image files.
        for change in self.renamed:
            shutil.copyfile(change.local_path, self.output_dir + '/OEBPS/' + change.epub_path)

    def create_zip_archive(self):
        with zipfile.ZipFile(self.output, 'w', zipfile.ZIP_DEFLATED) as zip:
            # Python 3.5 brings the `recursive` argument. For older versions, this trick is required...
            # for file in glob.glob(output_dir + '/**/*', recursive=True):
            for file in [os.path.join(dp, f) for dp, dn, filenames in os.walk(self.output_dir) for f in filenames]:
                zip.write(file, os.path.relpath(file, self.output_dir), compress_type=zipfile.ZIP_STORED)

        shutil.rmtree(self.output_dir)
        print('Generated ePub.')

    def transform(self):
        self.start_xslt_transformation()
        self.copy_images()
        self.create_zip_archive()

if __name__ == '__main__':
    DocBookToEpub(sys.argv).transform()


#!/bin/python3

import sys

def icecreamParlor(m, arr):
    res = []
    for first in range(len(arr) - 1):
        for second in range(first + 1, len(arr)):
            if (arr[first] + arr[second]) == m:
                res.append(first + 1)
                res.append(second + 1)
                return res

if __name__ == "__main__":
    t = int(input().strip())
    for a0 in range(t):
        m = int(input().strip())
        n = int(input().strip())
        arr = list(map(int, input().strip().split(' ')))
        result = icecreamParlor(m, arr)
        print (" ".join(map(str, result)))


import ROOT
from xAH_config import xAH_config
import sys, os

sys.path.insert(0, os.environ['ROOTCOREBIN']+"/user_scripts/HTopMultilepAnalysis/")

c = xAH_config()

event_branches = ["EventNumber","RunNumber","mc_channel_number","isSS01","dilep_type","trilep_type",
                  "is_T_T","is_T_AntiT","is_AntiT_T","is_AntiT_AntiT",
                  "is_TMVA_TMVA","is_TMVA_AntiTMVA","is_AntiTMVA_TMVA","is_AntiTMVA_AntiTMVA",
                  "nJets_OR_T","nJets_OR_T_MV2c10_70",
                  ]

lep_branches   = ["lep_ID_0","lep_Pt_0","lep_Eta_0","lep_Phi_0","lep_EtaBE2_0","lep_deltaRClosestJet_0","lep_isTightSelected_0","lep_isTightSelectedMVA_0","lep_isTrigMatch_0",
                  "lep_ID_1","lep_Pt_1","lep_Eta_1","lep_Phi_1","lep_EtaBE2_1","lep_deltaRClosestJet_1","lep_isTightSelected_1","lep_isTightSelectedMVA_1","lep_isTrigMatch_1"]

branches_to_activate = event_branches + lep_branches

# Trick to pass the list as a comma-separated string to the C++ algorithm

branches_to_activate_str = ",".join(branches_to_activate)

# Instantiate the main algorithm

base_dir = "/imports/home/mmilesi/PhD/ttH_MultiLeptons/RUN2/HTopMultilepAnalysisCode/trunk/"
#base_dir = "/afs/cern.ch/user/m/mmilesi/ttH/RUN2/HTopMultilepAnalysisCode/trunk"

HTopMultilepNTupReprocesserDict = { "m_name"                       : "HTopMultilepNTupReprocesser",
                                    "m_debug"                      : False,
                                    "m_verbose"                    : False,
				    "m_outputNTupStreamName"       : "output",
                                    "m_inputBranches"              : branches_to_activate_str,
                                    # "m_weightToCalc"               : "QMisID,MM",
                                    "m_weightToCalc"               : "MM",
                                    # "m_weightToCalc"               : "QMisID",
                                    "m_QMisIDRates_dir"            : "$ROOTCOREBIN/data/HTopMultilepAnalysis/External/",
                                    "m_QMisIDRates_Filename_T"     : "Rates_v29_Tight.root",
                                    "m_QMisIDRates_Filename_AntiT" : "Rates_v29_AntiTight.root",
                                    # "m_QMisIDRates_Filename_T"     : "Rates_v27_For3l.root",
                                    # "m_QMisIDRates_Filename_AntiT" : "Rates_v27_For3l_AntiT.root",
                                    # "m_QMisIDRates_Filename_T"     : "Rates_Data_3l_2D_tight.root",
                                    # "m_QMisIDRates_Filename_AntiT" : "Rates_Data_3l_2D_Loose.root",
                                    "m_QMisIDRates_Histname_T"     : "LikelihoodEtaPtTight",
                                    "m_QMisIDRates_Histname_AntiT" : "LikelihoodEtaPtLoose",
                                    # "m_QMisIDRates_Histname_T"     : "LikelihoodEtaPt",
                                    # "m_QMisIDRates_Histname_AntiT" : "LikelihoodEtaPt",
                                    "m_useTAntiTRates"             : False, # --> set this option to True if QMisID rates have NOT been measured independently for T and AntiT electrons - Set True for v19
                                    #
                                    # ------------------------------------------------------------
                                    #
                                    # v26
                                    #
                                    #"m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v26/CombinedEfficiencies_LeptonMVA_410501",
                                    #"m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v26/CombinedEfficiencies_LeptonMVA_410000",
                                    #
                                    #"m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v26/CombinedEfficiencies_LeptonCutBased_410501",
                                    #"m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v26/CombinedEfficiencies_LeptonCutBased_410000",
                                    #"m_useCutBasedLep"             : True,
                                    #
                                    #"m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v26/MMRates_DATA/OutputPlots_MMRates_25ns_v26_LeptonMVA_DDQMisID",
                                    #"m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/OutputPlots_MMClosureRates_25ns_v26_LeptonMVA", # Closure
                                    #
                                    # ------------------------------------------------------------
                                    #
                                    # v27
                                    #
                                    # "m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v27/OutputPlots_MMRates_25ns_v27",
                                    # "m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v27/OutputPlots_MMRates_TTWx2_25ns_v27",
                                    # "m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v27_v2/OutputPlots_MMClosureRates_25ns_v27", # Closure
                                    #
                                    # ------------------------------------------------------------
                                    #
                                    # v28
                                    #
                                    # "m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v28/OutputPlots_MMRates_25ns_v28",
                                    # "m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v28/OutputPlots_MMRates_25ns_v28_NewBinning",
                                    #
                                    # "m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v28/OutputPlots_MMRates_25ns_v28_FINAL_BINNING_2",
                                    # "m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v28/OutputPlots_MMClosureRates_25ns_v28_FINAL_BINNING_2", # Closure
                                    #
                                    # ------------------------------------------------------------
                                    #
                                    # v29
                                    #
                                    "m_REFF_dir" 		   : base_dir + "HTopMultilepAnalysis/PlotUtils/PLOTS_25ns_v29/OutputPlots_MMRates_25ns_v29",
                                    #
                                    # ------------------------------------------------------------
                                    #
                                    # "m_parametrisation_list"       : "Real_El:Pt,Real_Mu:Pt,Fake_El:Pt,Fake_Mu:Pt",
                                    # "m_parametrisation_list"       : "Real_El:Pt,Real_Mu:Pt,Fake_El:PtxEta,Fake_Mu:Pt",
                                    # "m_parametrisation_list"       : "Real_El:Pt,Real_Mu:Pt,Fake_El:NBJets_VS_Pt,Fake_Mu:Pt",
                                    # "m_parametrisation_list"       : "Real_El:Pt,Real_Mu:DistanceClosestJet_VS_Pt,Fake_El:NBJets_VS_Pt,Fake_Mu:Pt",
                                    "m_parametrisation_list"       : "Real_El:Pt,Real_Mu:Pt,Fake_El:NBJets_VS_Pt,Fake_Mu:DistanceClosestJet_VS_Pt",
                                    "m_useScaledFakeElEfficiency_ElEl" : True,
                                    #
                                    # "m_systematics_list"           : "Nominal:",
				    # "m_systematics_list"           : "Nominal:,Stat:UncorrBins",
				    "m_systematics_list"           : "Nominal:,Stat:UncorrBins,ND_TTV:CorrBins,ND_VV:CorrBins,ND_OtherPromptSS:CorrBins,ND_FakesOS:CorrBins,N_QMisID:UncorrBins,D_QMisID:UncorrBins",
                                    "m_correlatedMMWeights"        : False,
                                    #
				    "m_useTrigMatchingInfo"        : False,
				    #
				    # "m_Efficiency_Filename"        : "LeptonEfficiencies.root",
				    # "m_Efficiency_Filename"        : "LeptonEfficiencies_physics_Main_FixedRescaling_25_07_17.root",
				    "m_Efficiency_Filename"        : "LeptonEfficiencies_physics_Main_FixedRescaling_26_07_17.root",
				    # "m_Efficiency_Filename"        : "LeptonEfficiencies_physics_Main_FixedRescaling_29_07_17.root",
				    # "m_Efficiency_Filename"        : "LeptonEfficiencies_FakeElPtRescaledPhConv.root",
				    # "m_Efficiency_Filename"        : "LeptonEfficiencies_RealMuDistanceClosestJetVSPt.root",
				    #
                                    "m_doMMClosure"                : False,
				    "m_useTEfficiency"             : False,
                                  }

# Instantiate the NTupleSvc algorithm

ntuplesvc = ROOT.EL.NTupleSvc(HTopMultilepNTupReprocesserDict["m_outputNTupStreamName"])

# Copy ALL branches over from the input TTree

print("Copying all branches from input TTree to output...")
ntuplesvc.copyBranch(".*")

# Add the algorithms to the job.
#
# Here order matters!

c._algorithms.append(ntuplesvc)
c.setalg("HTopMultilepNTupReprocesser", HTopMultilepNTupReprocesserDict)


import torch
import torch.nn as nn
from attention import NewAttention
from language_model import (
    WordEmbedding,
    QuestionEmbedding,
    TemporalConvNet,
    BertEmbedding,
)
from classifier import SimpleClassifier
from fc import FCNet

class BaseModel(nn.Module):
    def __init__(self, w_emb, q_emb, v_att, q_net, v_net, classifier):
        super(BaseModel, self).__init__()
        self.w_emb = w_emb
        self.q_emb = q_emb
        self.v_att = v_att
        self.q_net = q_net
        self.v_net = v_net
        self.classifier = classifier

    def forward(self, v, q,  attention_output=False):
        """Forward

        v: [batch, num_objs, obj_dim], visual features
        b: [batch, num_objs, b_dim], spatial features
        q: [batch_size, seq_length], tokenized question

        return: logits, not probs
        """
        w_emb = self.w_emb(q)
        q_emb = self.q_emb(w_emb)  # [batch, q_dim]
        att = self.v_att(v, q_emb)
        # use att weights to compute attention output
        v_emb = (att * v).sum(1)  # [batch, v_dim], values are img features

        q_repr = self.q_net(q_emb)
        v_repr = self.v_net(v_emb)
        joint_repr = q_repr * v_repr
        logits = self.classifier(joint_repr)

        if attention_output:
            return logits, att
        return logits

def build_baseline0_newatt(
    dataset,
    num_hid,
    bidirectional=False,
    emb_dim=300,
    w_emb_type="baseline",
    rnn_type="GRU",
    activation=nn.ReLU,
    rnn_init=False,
    relu_init=False,
    var_analysis=False,
):

    if w_emb_type == "BERT":
        w_emb = BertEmbedding(0.0)
    else:
        w_emb = WordEmbedding(dataset.dictionary.ntoken, emb_dim, 0.0)

    if rnn_type == "TCN":
        q_emb = TemporalConvNet(14, [14] * 2, num_hid, kernel_size=(3, 300))
    else:
        q_emb = QuestionEmbedding(
            emb_dim,
            num_hid,
            1,
            bidirectional,
            0.0,
            rnn_type=rnn_type,
            personalized_init=rnn_init,
        )

    num_hid = num_hid * 2 if bidirectional else num_hid  # to double number of params
    v_att = NewAttention(dataset.v_dim, q_emb.out_size, num_hid, activation=activation)
    q_net = FCNet(
        [q_emb.out_size, num_hid],
        activation,
        relu_init=relu_init,
        var_analysis=var_analysis,
        name="q_net",
    )
    v_net = FCNet(
        [dataset.v_dim, num_hid],
        activation,
        relu_init=relu_init,
        var_analysis=var_analysis,
        name="v_net",
    )
    classifier = SimpleClassifier(
        num_hid, num_hid * 2, dataset.num_ans_candidates, 0.5, activation
    )
    return BaseModel(w_emb, q_emb, v_att, q_net, v_net, classifier)


"""Score network module."""
import torch
import copy
import math
from torch import nn
from torch.nn import functional as F
from openfold.utils.rigid_utils import Rigid, Rotation
from data import utils as du
from data import all_atom
from model import ipa_pytorch
from motif_scaffolding import twisting
import functools as fn

Tensor = torch.Tensor

def get_index_embedding(indices, embed_size, max_len=2056):
    """Creates sine / cosine positional embeddings from a pruespecified indices.

    Args:
        indices: offsets of size [..., N_edges] of type integer
        max_len: maximum length.
        embed_size: dimension of the embeddings to create

    Returns:
        positional embedding of shape [N, embed_size]
    """
    K = torch.arange(embed_size//2).to(indices.device)
    pos_embedding_sin = torch.sin(
        indices[..., None] * math.pi / (max_len**(2*K[None]/embed_size))).to(indices.device)
    pos_embedding_cos = torch.cos(
        indices[..., None] * math.pi / (max_len**(2*K[None]/embed_size))).to(indices.device)
    pos_embedding = torch.cat([
        pos_embedding_sin, pos_embedding_cos], axis=-1)
    return pos_embedding

def get_timestep_embedding(timesteps, embedding_dim, max_positions=10000):
    # Code from https://github.com/hojonathanho/diffusion/blob/master/diffusion_tf/nn.py
    assert len(timesteps.shape) == 1
    timesteps = timesteps * max_positions
    half_dim = embedding_dim // 2
    emb = math.log(max_positions) / (half_dim - 1)
    emb = torch.exp(torch.arange(half_dim, dtype=torch.float32, device=timesteps.device) * -emb)
    emb = timesteps.float()[:, None] * emb[None, :]
    emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=1)
    if embedding_dim % 2 == 1:  # zero pad
        emb = F.pad(emb, (0, 1), mode='constant')
    assert emb.shape == (timesteps.shape[0], embedding_dim)
    return emb

class Embedder(nn.Module):

    def __init__(self, model_conf):
        super(Embedder, self).__init__()
        self._model_conf = model_conf
        self._embed_conf = model_conf.embed

        # Time step embedding
        index_embed_size = self._embed_conf.index_embed_size
        t_embed_size = index_embed_size
        node_embed_dims = t_embed_size + 1
        edge_in = (t_embed_size + 1) * 2

        # Sequence index embedding
        node_embed_dims += index_embed_size
        edge_in += index_embed_size

        node_embed_size = self._model_conf.node_embed_size
        self.node_embedder = nn.Sequential(
            nn.Linear(node_embed_dims, node_embed_size),
            nn.ReLU(),
            nn.Linear(node_embed_size, node_embed_size),
            nn.ReLU(),
            nn.Linear(node_embed_size, node_embed_size),
            nn.LayerNorm(node_embed_size),
        )

        if self._embed_conf.embed_self_conditioning:
            edge_in += self._embed_conf.num_bins
        edge_embed_size = self._model_conf.edge_embed_size
        self.edge_embedder = nn.Sequential(
            nn.Linear(edge_in, edge_embed_size),
            nn.ReLU(),
            nn.Linear(edge_embed_size, edge_embed_size),
            nn.ReLU(),
            nn.Linear(edge_embed_size, edge_embed_size),
            nn.LayerNorm(edge_embed_size),
        )

        self.timestep_embedder = fn.partial(
            get_timestep_embedding,
            embedding_dim=self._embed_conf.index_embed_size
        )
        self.index_embedder = fn.partial(
            get_index_embedding,
            embed_size=self._embed_conf.index_embed_size
        )

    def _cross_concat(self, feats_1d, num_batch, num_res):
        return torch.cat([
            torch.tile(feats_1d[:, :, None, :], (1, 1, num_res, 1)),
            torch.tile(feats_1d[:, None, :, :], (1, num_res, 1, 1)),
        ], dim=-1).float().reshape([num_batch, num_res**2, -1])

    def forward(
            self,
            *,
            seq_idx,
            t,
            fixed_mask,
            self_conditioning_ca,
        ):
        """Embeds a set of inputs

        Args:
            seq_idx: [..., N] Positional sequence index for each residue.
            t: Sampled t in [0, 1].
            fixed_mask: mask of fixed (motif) residues.
            self_conditioning_ca: [..., N, 3] Ca positions of self-conditioning
                input.

        Returns:
            node_embed: [B, N, D_node]
            edge_embed: [B, N, N, D_edge]
        """
        num_batch, num_res = seq_idx.shape
        node_feats = []

        # Set time step to epsilon=1e-5 for fixed residues.
        fixed_mask = fixed_mask[..., None]
        prot_t_embed = torch.tile(
            self.timestep_embedder(t)[:, None, :], (1, num_res, 1))
        prot_t_embed = torch.cat([prot_t_embed, fixed_mask], dim=-1)
        node_feats = [prot_t_embed]
        pair_feats = [self._cross_concat(prot_t_embed, num_batch, num_res)]

        # Positional index features.
        node_feats.append(self.index_embedder(seq_idx))
        rel_seq_offset = seq_idx[:, :, None] - seq_idx[:, None, :]
        rel_seq_offset = rel_seq_offset.reshape([num_batch, num_res**2])
        pair_feats.append(self.index_embedder(rel_seq_offset))

        # Self-conditioning distogram.
        if self._embed_conf.embed_self_conditioning:
            sc_dgram = du.calc_distogram(
                self_conditioning_ca,
                self._embed_conf.min_bin,
                self._embed_conf.max_bin,
                self._embed_conf.num_bins,
            )
            pair_feats.append(sc_dgram.reshape([num_batch, num_res**2, -1]))

        node_embed = self.node_embedder(torch.cat(node_feats, dim=-1).float())
        edge_embed = self.edge_embedder(torch.cat(pair_feats, dim=-1).float())
        edge_embed = edge_embed.reshape([num_batch, num_res, num_res, -1])
        if torch.any(node_embed.isnan()):
            print("node_embed is somewhere nan in Embedder")
            import ipdb; ipdb.set_trace()

        return node_embed, edge_embed

class ScoreNetwork(nn.Module):

    def __init__(self, model_conf, diffuser):
        super(ScoreNetwork, self).__init__()
        self._model_conf = model_conf

        self.embedding_layer = Embedder(model_conf)
        self.diffuser = diffuser
        self.score_model = ipa_pytorch.IpaScore(model_conf, diffuser)

    def _apply_mask(self, aatype_diff, aatype_0, diff_mask):
        return diff_mask * aatype_diff + (1 - diff_mask) * aatype_0

    def forward(self, input_feats, F=None,
        use_twisting=False, twist_scale=1.,
        twist_potential_rot=True,
        twist_potential_trans=True,
        twist_update_rot=True,
        twist_update_trans=True,
    ):
        """Forward computes the reverse diffusion conditionals p(X^t|X^{t+1})
        for each item in the batch

        Args:
            X: the noised samples from the noising process, of shape [Batch, N, D].
                Where the T time steps are t=1,...,T (i.e. not including the un-noised X^0)

        Returns:
            model_out: dictionary of model outputs.
        """
        # Frames as [batch, res, 7] tensors.
        bb_mask = input_feats['res_mask'].type(torch.float32)  # [B, N]
        fixed_mask = input_feats['fixed_mask'].type(torch.float32)
        edge_mask = bb_mask[..., None] * bb_mask[..., None, :]

        # Initial embeddings of positonal and relative indices.
        init_node_embed, init_edge_embed = self.embedding_layer(
            seq_idx=input_feats['seq_idx'],
            t=input_feats['t'],
            fixed_mask=fixed_mask,
            self_conditioning_ca=input_feats['sc_ca_t'],
        )
        edge_embed = init_edge_embed * edge_mask[..., None]
        node_embed = init_node_embed * bb_mask[..., None]
        if torch.any(node_embed.isnan()):
            print("node_embed is somewhere nan")
            import ipdb; ipdb.set_trace()

        # If input_feats has conditioning information, update input rigids to track gradients
        if use_twisting and "rigids_motif" in input_feats:
            # Log that we are using conditioning
            Log_delta_R, delta_x = twisting.perturbations_for_grad(input_feats, self.diffuser)

        # Run main network
        model_out = self.score_model(node_embed, edge_embed, input_feats)

        # Psi angle prediction
        gt_psi = input_feats['torsion_angles_sin_cos'][..., 2, :]
        psi_pred = self._apply_mask(
            model_out['psi'], gt_psi, 1 - fixed_mask[..., None])
        pred_out = {'psi_pred': psi_pred}
        pred_out['rot_score'] = model_out['rot_score']
        pred_out['trans_score'] = model_out['trans_score']
        final_rigids = Rigid(Rotation(model_out['R_final']), model_out['trans_final'])
        model_out['final_rigids'] = final_rigids

        rigids_pred = model_out['final_rigids']
        pred_out['rigids'] = rigids_pred.to_tensor_7()

        # If input_feats has conditioning information, compute conditional score
        if use_twisting:
            grad_R_log_p_motif, grad_x_log_p_motif, max_log_p_idx, twist_log_p = twisting.grad_log_lik_approx(
                R_t=input_feats['R_t'],
                R_pred=model_out['R_final'],
                trans_pred=model_out['trans_final'],
                motif_tensor_7=input_feats['rigids_motif'],
                Log_delta_R=Log_delta_R, delta_x=delta_x,
                se3_diffuser=self.diffuser,
                t=input_feats['t'],
                F=F,
                twist_scale=twist_scale,
                twist_potential_rot=twist_potential_rot,
                twist_potential_trans=twist_potential_trans,
                )
            pred_out['max_log_p_idx'] = max_log_p_idx
            pred_out['twist_log_p'] = twist_log_p

            verbose = False
            if verbose:
                # Log the mean norms of the two gradients
                grad_R_log_p_motif_norm = torch.norm(grad_R_log_p_motif, dim=[-2, -1]).mean()
                grad_x_log_p_motif_norm = torch.norm(grad_x_log_p_motif, dim=[-1]).mean()
                print("input_feats[t]: ", input_feats['t'])
                print("grad_R_log_p_motif_norm: ", grad_R_log_p_motif_norm)
                print("grad_x_log_p_motif_norm: ", grad_x_log_p_motif_norm)

                # Log the means of the unconditioanal gradients
                grad_R_uncond = pred_out['rot_score']
                grad_x_uncond = pred_out['trans_score']
                grad_R_uncond_norm = torch.norm(grad_R_uncond, dim=[-2, -1]).mean()
                grad_x_uncond_norm = torch.norm(grad_x_uncond, dim=[-1]).mean()
                print("grad_R_uncond_norm: ", grad_R_uncond_norm)
                print("grad_x_uncond_norm: ", grad_x_uncond_norm)

            # scale grad_R_log_p_motif such that each 3x3 matrix can have Frobenius norm at most 1000
            if sum(torch.isnan(grad_R_log_p_motif).flatten()) > 0:
                num_nans = sum(torch.isnan(grad_R_log_p_motif).flatten())
                print("grad_R_log_p_motif has ", num_nans, " nans")

                # set the nans to 0
                # first find indices corresponding to nans
                nan_indices = torch.where(torch.isnan(grad_R_log_p_motif[0]).sum(dim=[-2,-1]))[0]
                # set  rotation matrices to zero if they have nans
                grad_R_log_p_motif[0, nan_indices] = 0.

            # Consider doing something similar for translations? (i.e. for scaling)
            # TODO: Do ablation to check if this matters! (i.e. if we don't scale the gradients)
            max_norm = 1e3
            norms = torch.norm(grad_R_log_p_motif, dim=[-2, -1], keepdim=True) # keep the last dimensions
            if sum(norms.flatten() > max_norm) > 0:
                print("norms of grad_R_log_p_motif are ", norms.shape, norms.flatten())
            grad_R_scaling = max_norm / (max_norm + norms)
            grad_R_log_p_motif = grad_R_scaling*grad_R_log_p_motif

            if sum(norms.flatten() > max_norm) > 0:
                print("norms of grad_trans_log_p_motif are ", norms.shape, norms.flatten())
            #norms = torch.norm(grad_x_log_p_motif, dim=[-1], keepdim=True) # keep the last dimensions
            #if sum(norms.flatten() > max_norm) > 0:
            #    print("norms of grad_trans_log_p_motif are ", norms.shape, norms.flatten())
            #grad_x_scaling = max_norm / (max_norm + norms)
            #grad_x_log_p_motif = grad_x_scaling*grad_x_log_p_motif

            if twist_update_rot:
                pred_out['rot_score_uncond'] = pred_out['rot_score'].detach().clone()
                pred_out['rot_score'] = pred_out['rot_score'] + grad_R_log_p_motif
            if twist_update_trans:
                pred_out['trans_score_uncond'] = pred_out['trans_score'].detach().clone()
                pred_out['trans_score'] = pred_out['trans_score'] + grad_x_log_p_motif

            bar_a_t = torch.exp(-self.diffuser._r3_diffuser.marginal_b_t(input_feats['t']))
            factor_on_score_x = (1-bar_a_t)/torch.sqrt(bar_a_t)

            rigids_pred = Rigid.from_tensor_7(pred_out['rigids'])
            pred_out['rigids_uncond'] = pred_out['rigids'].detach().clone()
            x_pred = rigids_pred.get_trans()
            x_pred = x_pred + factor_on_score_x[:, None, None] * self.diffuser._r3_diffuser._unscale(grad_x_log_p_motif)
            rigids_pred._trans = x_pred
            pred_out['rigids'] = rigids_pred.to_tensor_7()

        for k, v in input_feats.items():
            # check if a the value is a tensor, and detach if so.
            if isinstance(v, torch.Tensor):
                input_feats[k] = v.detach()

        return pred_out