# coding: utf-8
# Copyright (c) 2016, 2018, Oracle and/or its affiliates. All rights reserved.

from ...util import formatted_flat_dict, NONE_SENTINEL, value_allowed_none_or_none_sentinel  # noqa: F401
from ...decorators import init_model_state_from_kwargs

@init_model_state_from_kwargs
class CreateBucketDetails(object):

    def __init__(self, **kwargs):
        """
        Initializes a new CreateBucketDetails object with values from values from keyword arguments.
        The following keyword arguments are supported (corresponding to the getters/setters of this class):

        :param name:
            The value to assign to the name property of this CreateBucketDetails.
        :type name: str

        :param compartment_id:
            The value to assign to the compartment_id property of this CreateBucketDetails.
        :type compartment_id: str

        :param metadata:
            The value to assign to the metadata property of this CreateBucketDetails.
        :type metadata: dict(str, str)

        :param public_access_type:
            The value to assign to the public_access_type property of this CreateBucketDetails.
            Allowed values for this property are: "NoPublicAccess", "ObjectRead", "ObjectReadWithoutList"
        :type public_access_type: str

        :param storage_tier:
            The value to assign to the storage_tier property of this CreateBucketDetails.
            Allowed values for this property are: "Standard", "Archive"
        :type storage_tier: str

        """
        self.swagger_types = {
            'name': 'str',
            'compartment_id': 'str',
            'metadata': 'dict(str, str)',
            'public_access_type': 'str',
            'storage_tier': 'str'
        }

        self.attribute_map = {
            'name': 'name',
            'compartment_id': 'compartmentId',
            'metadata': 'metadata',
            'public_access_type': 'publicAccessType',
            'storage_tier': 'storageTier'
        }

        self._name = None
        self._compartment_id = None
        self._metadata = None
        self._public_access_type = None
        self._storage_tier = None

    @property
    def name(self):
        """
        **[Required]** Gets the name of this CreateBucketDetails.
        The name of the bucket. Valid characters are uppercase or lowercase letters,
        numbers, and dashes. Bucket names must be unique within the namespace. Avoid entering confidential information.
        example: Example: my-new-bucket1

        :return: The name of this CreateBucketDetails.
        :rtype: str
        """
        return self._name

    @name.setter
    def name(self, name):
        """
        Sets the name of this CreateBucketDetails.
        The name of the bucket. Valid characters are uppercase or lowercase letters,
        numbers, and dashes. Bucket names must be unique within the namespace. Avoid entering confidential information.
        example: Example: my-new-bucket1

        :param name: The name of this CreateBucketDetails.
        :type: str
        """
        self._name = name

    @property
    def compartment_id(self):
        """
        **[Required]** Gets the compartment_id of this CreateBucketDetails.
        The ID of the compartment in which to create the bucket.

        :return: The compartment_id of this CreateBucketDetails.
        :rtype: str
        """
        return self._compartment_id

    @compartment_id.setter
    def compartment_id(self, compartment_id):
        """
        Sets the compartment_id of this CreateBucketDetails.
        The ID of the compartment in which to create the bucket.

        :param compartment_id: The compartment_id of this CreateBucketDetails.
        :type: str
        """
        self._compartment_id = compartment_id

    @property
    def metadata(self):
        """
        Gets the metadata of this CreateBucketDetails.
        Arbitrary string, up to 4KB, of keys and values for user-defined metadata.

        :return: The metadata of this CreateBucketDetails.
        :rtype: dict(str, str)
        """
        return self._metadata

    @metadata.setter
    def metadata(self, metadata):
        """
        Sets the metadata of this CreateBucketDetails.
        Arbitrary string, up to 4KB, of keys and values for user-defined metadata.

        :param metadata: The metadata of this CreateBucketDetails.
        :type: dict(str, str)
        """
        self._metadata = metadata

    @property
    def public_access_type(self):
        """
        Gets the public_access_type of this CreateBucketDetails.
        The type of public access enabled on this bucket.
        A bucket is set to `NoPublicAccess` by default, which only allows an authenticated caller to access the
        bucket and its contents. When `ObjectRead` is enabled on the bucket, public access is allowed for the
        `GetObject`, `HeadObject`, and `ListObjects` operations. When `ObjectReadWithoutList` is enabled on the bucket,
        public access is allowed for the `GetObject` and `HeadObject` operations.

        Allowed values for this property are: "NoPublicAccess", "ObjectRead", "ObjectReadWithoutList"

        :return: The public_access_type of this CreateBucketDetails.
        :rtype: str
        """
        return self._public_access_type

    @public_access_type.setter
    def public_access_type(self, public_access_type):
        """
        Sets the public_access_type of this CreateBucketDetails.
        The type of public access enabled on this bucket.
        A bucket is set to `NoPublicAccess` by default, which only allows an authenticated caller to access the
        bucket and its contents. When `ObjectRead` is enabled on the bucket, public access is allowed for the
        `GetObject`, `HeadObject`, and `ListObjects` operations. When `ObjectReadWithoutList` is enabled on the bucket,
        public access is allowed for the `GetObject` and `HeadObject` operations.

        :param public_access_type: The public_access_type of this CreateBucketDetails.
        :type: str
        """
        allowed_values = ["NoPublicAccess", "ObjectRead", "ObjectReadWithoutList"]
        if not value_allowed_none_or_none_sentinel(public_access_type, allowed_values):
            raise ValueError(
                "Invalid value for `public_access_type`, must be None or one of {0}"
                .format(allowed_values)
            )
        self._public_access_type = public_access_type

    @property
    def storage_tier(self):
        """
        Gets the storage_tier of this CreateBucketDetails.
        The type of storage tier of this bucket.
        A bucket is set to 'Standard' tier by default, which means the bucket will be put in the standard storage tier.
        When 'Archive' tier type is set explicitly, the bucket is put in the Archive Storage tier. The 'storageTier'
        property is immutable after bucket is created.

        Allowed values for this property are: "Standard", "Archive"

        :return: The storage_tier of this CreateBucketDetails.
        :rtype: str
        """
        return self._storage_tier

    @storage_tier.setter
    def storage_tier(self, storage_tier):
        """
        Sets the storage_tier of this CreateBucketDetails.
        The type of storage tier of this bucket.
        A bucket is set to 'Standard' tier by default, which means the bucket will be put in the standard storage tier.
        When 'Archive' tier type is set explicitly, the bucket is put in the Archive Storage tier. The 'storageTier'
        property is immutable after bucket is created.

        :param storage_tier: The storage_tier of this CreateBucketDetails.
        :type: str
        """
        allowed_values = ["Standard", "Archive"]
        if not value_allowed_none_or_none_sentinel(storage_tier, allowed_values):
            raise ValueError(
                "Invalid value for `storage_tier`, must be None or one of {0}"
                .format(allowed_values)
            )
        self._storage_tier = storage_tier

    def __repr__(self):
        return formatted_flat_dict(self)

    def __eq__(self, other):
        if other is None:
            return False

        return self.__dict__ == other.__dict__

    def __ne__(self, other):
        return not self == other


# converting the text from uppercase to lowercase and then creating the output file with the lowercase text
import sys

def createLCV(currlist):
	'puts everything to lower case'
	mod_list = []

	for x in currlist:
		mod_list.append(str(x).lower())

	return mod_list


import sqlite3
from sqlite3 import Error

# functions to manage our database:

def create_connection(db_file):
    """ create a database connection to a SQLite database """
    conn = None

    try:
        conn = sqlite3.connect(db_file)
    except Error as e:
        print(e)

    return conn

def create_table(conn, create_table_sql):
    try:
        c = conn.cursor()
        c.execute(create_table_sql)
    except Error as e:
        print(e)

def create_customer(conn, customer):
    sql = ''' INSERT INTO customers(email, password, first_name, last_name, phone_number)
              VALUES(?,?,?,?,?) '''
    cur = conn.cursor()
    cur.execute(sql, customer)
    conn.commit()
    return cur.lastrowid

def create_driver(conn, driver):
    sql = ''' INSERT INTO drivers(first_name, last_name, phone_number, car_model, car_color, company_id)
              VALUES(?,?,?,?,?,?) '''
    cur = conn.cursor()
    cur.execute(sql, driver)
    conn.commit()
    return cur.lastrowid

def create_company(conn, company):
    sql = ''' INSERT INTO companies(name)
              VALUES(?) '''
    cur = conn.cursor()
    cur.execute(sql, company)
    conn.commit()
    return cur.lastrowid

def create_trip(conn, trip):
    sql = ''' INSERT INTO trips(driver_id, customer_id, start_time, start_place, end_time, end_place, payment_method)
              VALUES(?,?,?,?,?,?,?) '''
    cur = conn.cursor()
    cur.execute(sql, trip)
    conn.commit()
    return cur.lastrowid

def create_tables(conn):
    sql_create_companies_table = """ CREATE TABLE IF NOT EXISTS companies (
                                        id integer PRIMARY KEY,
                                        name text NOT NULL
                                ); """

    sql_create_drivers_table = """ CREATE TABLE IF NOT EXISTS drivers (
                                        id integer PRIMARY KEY,
                                        first_name text NOT NULL,
                                        last_name text NOT NULL,
                                        phone_number text UNIQUE,
                                        car_model text NOT NULL,
                                        car_color text,
                                        company_id integer NOT NULL,
                                        FOREIGN KEY (company_id) REFERENCES companies (id)
                                    ); """

    sql_create_customers_table = """ CREATE TABLE IF NOT EXISTS customers (
                                        id integer PRIMARY KEY,
                                        email text UNIQUE NOT NULL,
                                        password text NOT NULL,
                                        first_name text NOT NULL,
                                        last_name text NOT NULL,
                                        phone_number text
                                    ); """

    sql_create_trips_table = """ CREATE TABLE IF NOT EXISTS trips (
                                    id integer PRIMARY KEY,
                                    driver_id integer NOT NULL,
                                    customer_id integer NOT NULL,
                                    start_time text NOT NULL,
                                    start_place text NOT NULL,
                                    end_time text NOT NULL,
                                    end_place text NOT NULL,
                                    payment_method text NOT NULL,
                                    FOREIGN KEY (driver_id) REFERENCES drivers (id),
                                    FOREIGN KEY (customer_id) REFERENCES customers (id)
                                ); """

    # create customers table
    create_table(conn, sql_create_customers_table)
    # create drivers table
    create_table(conn, sql_create_drivers_table)
    # create companies table
    create_table(conn, sql_create_companies_table)
    # # create trips table
    create_table(conn, sql_create_trips_table)

def login_customer(conn, user):
    sql = ''' SELECT * FROM customers WHERE email=? AND password=?'''
    cur = conn.cursor()
    cur.execute(sql, user)
    first = cur.fetchall()[0]
    return first

def get_drivers(conn):
    sql = ''' SELECT * FROM drivers'''
    cur = conn.cursor()
    cur.execute(sql)
    return cur.fetchall()

def get_trips(conn):
    sql = ''' SELECT * FROM trips'''
    cur = conn.cursor()
    cur.execute(sql)
    return cur.fetchall()

def delete_trip(conn, id):
    sql = 'DELETE FROM trips WHERE id=?'
    cur = conn.cursor()
    cur.execute(sql, (id,))
    conn.commit()


import copy
import json
from collections import OrderedDict
from datetime import datetime
from pathlib import Path

import asreview
import numpy as np
from asreview.settings import ASReviewSettings

def query_key(query_i):
    "Get key from iteration number."
    return str(query_i)

def read_log(log_fp):
    """Read log file.

    Arguments
    ---------
    log_fp: str, pathlib.Path
        File path of the log file.

    Returns
    -------
    Logger:
        A Logger object with logs.
    """
    log_fp_path = Path(log_fp)

    try:
        with open(log_fp_path, "r") as f:

            log = Logger()
            log._log_dict = json.load(f)

            return log

    except Exception as err:
        raise err

def read_logs_from_dir(log_dir, prefix=None):
    """Read log files from directory.

    Arguments
    ---------
    log_dir: str, pathlib.Path
        Directory in which to find the log file(s).
    prefix: str
        Prefix for log files. For example 'result_'.

    Returns
    -------
    list:
        A list with Logger objects.
    """

    log_fp_path = Path(log_dir)

    if log_fp_path.is_dir():
        log_list = []

        for x in log_fp_path.iterdir():

            try:
                if prefix and not x.name.startswith(prefix):
                    continue
                log_list.append(read_log(x))
            except ValueError:
                pass

        return log_list
    raise ValueError("log_dir is not a valid directory.")

class Logger(object):
    """Class for logging the Systematic Review"""

    def __init__(self, log_fp=None):
        super(Logger, self).__init__()
        self.settings = None
        if log_fp is not None:
            self.restore(log_fp)
        else:
            # since python 3, this is an ordered dict
            self._log_dict = OrderedDict({
                "time": {"start_time": str(datetime.now())},
                "version": 1,
                "software_version": asreview.__version__
            })

    def __str__(self):
        return self._print_logs()

    def _print_logs(self):
        self._log_dict["time"]["end_time"] = str(datetime.now())
        log_str = "Logs of the Systematic Review process:\n"
        for i, value in self._log_dict.items():
            log_str += f"Query {i} - Reduction {value}"

        return log_str

    def _add_log(self, new_dict, i, append_result=False):
        # Find the first number that is not logged yet.
        if i is None:
            i = 0
            qk = query_key(i)
            while qk in self._log_dict:
                # If the keys of the new dictionary don't exist, this is it.
                if set(new_dict.keys()).isdisjoint(self._log_dict[qk].keys()):
                    break
                i += 1
                qk = query_key(i)

        qk = query_key(i)
        if qk not in self._log_dict:
            self._log_dict[qk] = {}

        for key in new_dict:
            if key in self._log_dict[qk] and append_result:
                self._log_dict[qk][key].extend(new_dict[key])
            else:
                self._log_dict[qk].update(new_dict)

    def add_settings(self, settings):
        self.settings = copy.deepcopy(settings)

    def add_labels(self, y):
        self._log_dict["labels"] = y.tolist()

    def add_classification(self, indices, labels, methods, i=None):
        """Add training indices and their labels.

        Arguments
        ---------
        indices: list, np.array
            A list of indices used for training.
        labels: list
            A list of labels corresponding with the training indices.
        i: int
            The query number.
        """

        # ensure that variables are serializable
        if isinstance(indices, np.ndarray):
            indices = indices.tolist()
        if isinstance(labels, np.ndarray):
            labels = labels.tolist()

        qi = query_key(i)
        if qi not in self._log_dict:
            self._log_dict[qi] = {}
        label_methods = self._log_dict[qi].get("label_methods", [])
        for method in methods:
            if len(label_methods) and label_methods[-1][0] == method[1]:
                label_methods[-1][1] += 1
            else:
                label_methods.append([method[1], 1])

        new_dict = {'label_methods': label_methods}
        self._add_log(new_dict, i, append_result=False)
        new_dict = {'labelled': list(zip(indices, labels))}
        self._add_log(new_dict, i, append_result=True)

    def add_pool_predict(self, indices, pred, i=None):
        """Add inverse pool indices and their labels.

        Arguments
        ---------
        indices: list, np.array
            A list of indices used for unlabeled pool.
        pred: np.array
            A list of predictions for those samples.
        i: int
            The query number.
        """

        if isinstance(indices, np.ndarray):
            indices = indices.tolist()
        pred = np.reshape(pred, -1)
        if isinstance(pred, np.ndarray):
            pred = pred.tolist()
        new_dict = {'predictions': list(zip(indices, pred))}
        self._add_log(new_dict, i, append_result=False)

    def add_proba(self, indices, pred_proba, logname="pool_proba", i=None):
        """Add inverse pool indices and their labels.

        Arguments
        ---------
        indices: list, np.array
            A list of indices used for unlabeled pool.
        pred: np.array
            Array of prediction probabilities for unlabeled pool.
        i: int
            The query number.
        """

        if isinstance(indices, np.ndarray):
            indices = indices.tolist()
        pred_proba = pred_proba[:, 1]
        if isinstance(pred_proba, np.ndarray):
            pred_proba = pred_proba.tolist()
        new_dict = {logname: list(zip(indices, pred_proba))}
        self._add_log(new_dict, i)

    def save(self, fp):
        """Save logs to file.

        Arguments
        ---------
        fp: str
            The file path to export the results to.

        """
        self._log_dict["settings"] = copy.deepcopy(vars(self.settings))
        self._log_dict["settings"]["query_kwargs"].pop("pred_proba", None)
        self._log_dict["settings"]["query_kwargs"].pop("query_src", None)
        self._log_dict["settings"]["query_kwargs"].pop("current_queries", None)
        self._log_dict.move_to_end("settings", last=False)
        self._log_dict["time"]["end_time"] = str(datetime.now())
        fp = Path(fp)

        if fp.is_file:
            fp.parent.mkdir(parents=True, exist_ok=True)

        with fp.open('w') as outfile:
            json.dump(self._log_dict, outfile, indent=2)
        del self._log_dict["settings"]

    def restore(self, fp):
        with open(fp, "r") as f:
            self._log_dict = OrderedDict(json.load(f))
        self.settings = ASReviewSettings(**self._log_dict.pop("settings"))


import decimal, time
precision = 2
elapsed = 1
while elapsed < 60:
    decimal.setcontext(decimal.Context(prec=precision))
    i = 1
    x = decimal.Decimal(3)
    pi = x
    start = time.time()
    while x > 0:  # taylor series expansion
            x = x * i / ((i + 1) * 4)
            i += 2
            pi += x / i
    elapsed = time.time() - start

    print('In {:6.2f} seconds {:5d} digits of pi is'.format(elapsed, len(str(pi)) - 1), pi)
    precision *= 2


def countWord(fname,word):
    count = 0
    with open(fname, 'r') as f:
        for line in f:
            words = line.split()
            for i in words:
                if(i == word):
                    count=count+1
    return count

print(countWord('/home/pramodbhalerao/Workspace/code/fsdse-python-assignment-5/files/testfile.txt','dummy'))


#!/usr/bin/python
##########################################################################
# If not stated otherwise in this file or this component's Licenses.txt
# file the following copyright and licenses apply:
#
# Copyright 2015 RDK Management
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##########################################################################

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

import optparse
import os
import re
import sys
import traceback
import uuid

sys.path.append(os.path.join(os.path.dirname(sys.argv[0]), "lib"))
from hdk.hslparser import HSLParser
from hdk.modutil import HDKModule

#
# Main
#
def main():

    # Command line options
    cmdParser = optparse.OptionParser("usage: %prog [options] hsl...")
    cmdParser.add_option("-o", action = "store", type = "string", dest = "outputDir", default = ".",
                         help = "output directory", metavar = "DIR")
    cmdParser.add_option("-b", action = "store", type = "string", dest = "baseName", default = "hdk",
                         help = "base file name (e.g. 'hdk')", metavar = "NAME")
    cmdParser.add_option("-I", action = "append", dest = "importDirs", default = [],
                         help = "add directory to import path", metavar = "DIR")
    cmdParser.add_option("--action-include", action = "append", dest = "actionsInclusive",
                         help = "include only specified actions", metavar = "ACTION")
    cmdParser.add_option("--action-exclude", action = "append", dest = "actionsExclusive",
                         help = "exclude specified actions", metavar = "ACTION")
    cmdParser.add_option("--event-include", action = "append", dest = "eventsInclusive",
                         help = "include only specified events", metavar = "EVENT")
    cmdParser.add_option("--event-exclude", action = "append", dest = "eventsExclusive",
                         help = "exclude specified events", metavar = "EVENT")
    cmdParser.add_option("--noid", action = "store", dest = "noid", default = None,
                         help = "network object identifier (optional)")
    cmdParser.add_option("--friendly-name", action = "store", dest = "friendly_name", default = None,
                         help = "network object friendly name (optional)", metavar = "NAME")
    cmdParser.add_option("--client", action = "store_true", dest = "client", default = False,
                         help = "generate client module"),
    cmdParser.add_option("--noauth", action = "store_true", dest = "noauth", default = False,
                         help = "set noauth attribute for all module actions"),
    cmdParser.add_option("--action-location", action = "store", type = "string", dest = "actionLocation", default = "/HNAP1",
                         help = "specify the module actions HTTP location", metavar = "PATH")
    cmdParser.add_option("--dom-schema", action = "store_true", dest = "dom_schema", default = False,
                         help = "generate DOM schemas for user-defined structs")
    cmdParser.add_option("--server-methods", action = "store_true", dest = "server_methods", default = False,
                         help = "generate server method implementation file"),
    cmdParser.add_option("--adi-report", action = "store_true", dest = "adi_report", default = False,
                         help = "generate module ADI report"),

    # Parse command line options
    (cmdOptions, cmdArgs) = cmdParser.parse_args()
    if cmdArgs is None or not cmdArgs:
        cmdParser.error("Must specify at least one HSL file")

    # Check we have a valid UUID.
    noid = None
    if cmdOptions.noid is not None:
        noid = uuid.UUID(cmdOptions.noid)

    # Parse HSL files
    parser = HSLParser(importPath = cmdOptions.importDirs,
                       noauth = cmdOptions.noauth)
    for file in cmdArgs:
        parser.parseFile(file)
    parser.parseDone()
    if parser.errors:
        for error in parser.errors:
            print >> sys.stderr, error
        sys.exit(1)

    # Include/exclude actions and events
    if cmdOptions.actionsInclusive is not None:
        parser.filterActions(cmdOptions.actionsInclusive, False)
    if cmdOptions.actionsExclusive is not None:
        parser.filterActions(cmdOptions.actionsExclusive, True)
    if cmdOptions.eventsInclusive is not None:
        parser.filterEvents(cmdOptions.eventsInclusive, False)
    if cmdOptions.eventsExclusive is not None:
        parser.filterEvents(cmdOptions.eventsExclusive, True)
    if parser.errors:
        for error in parser.errors:
            print >> sys.stderr, error
        sys.exit(1)

    # Get the parsed actions, types and services
    model = parser.getmodel()
    if not model.actions and not cmdOptions.dom_schema:
        print >> sys.stderr, "Error: No actions defined"
        sys.exit(1)

    # Ensure the output directory exists
    if not os.path.isdir(cmdOptions.outputDir):
        try:
            os.makedirs(cmdOptions.outputDir)
        except:
            print >> sys.stderr, "Error: Couldn't create directory '%s'" % cmdOptions.outputDir
            sys.exit(1)

    # Generate code
    try:
        gen = ModuleGenerator(model, cmdOptions.baseName, noid, cmdOptions.friendly_name,
                              cmdOptions.actionLocation, cmdOptions.dom_schema,
                              cmdOptions.server_methods, cmdOptions.client, cmdOptions.adi_report)
        gen.generate(cmdOptions.outputDir, sys.stdout)
    except:
        print >> sys.stderr, "Error: An unexpected exception occurred generating code:"
        traceback.print_exc()
        sys.exit(1)

#
# HDK module code generation
#
class ModuleGenerator:

    # Class initializer
    def __init__(self, model, baseName, noid, friendlyName,
                 actionLocation, bGenerateDOMSchemas,
                 bGenerateMethods, bClient, bADIReport):

        self._model = model

        # Options
        self._baseName = baseName
        self._noid = noid
        self._friendlyName = friendlyName
        self._bGenerateMethods = bGenerateMethods
        self._bADIReport = bADIReport

        # Generator state
        self._out = None

        # Module
        self._module = HDKModule(model, baseName, actionLocation, bGenerateDOMSchemas)

        # Generation options
        self._bGenerateActions = not bClient and self._module.actions
        self._bGenerateServices = not bClient and self._module.services
        self._bGenerateModule = self._module.actions or self._module.events
        self._bGenerateModuleDynamic = not bClient and self._bGenerateModule

    #
    # Generate code
    #

    def generate(self, dir, fhReport):

        for file, fn, bGenerate in \
                [(os.path.join(dir, self._module.filename('.h')), self._generate_h, not self._bGenerateMethods),
                 (os.path.join(dir, self._module.filename('.c')), self._generate_c, not self._bGenerateMethods),
                 (os.path.join(dir, self._module.filename('_methods.c')), self._generate_methods_c, self._bGenerateMethods),
                 (os.path.join(dir, self._module.filename('_adi.txt')), self._generate_adi_txt, self._bADIReport)]:

            if bGenerate:

                if fhReport is not None:
                    print >>fhReport, 'Generating "%s" ...' % file

                self._out = open(file, "w")
                try:
                    fn()
                except:
                    raise
                finally:
                    self._out.close()

    #
    # Output helper methods
    #

    # Output
    def _write(self, s):

        self._out.write(s)

    # Write .c file header
    def _write_header_c(self):

        self._write('''\
/*
 * Copyright 2014 Cisco Systems, Inc.
 * Licensed under the Apache License, Version 2.0
 */
''')

    # Write .h file header
    def _write_header_h(self):

        self._write_header_c();
        self._write('''\

#ifndef %s
#define %s
''' % (self._module.header_sentinel('.h'), self._module.header_sentinel('.h')))

    # Write .h file footer
    def _write_footer_h(self):

        self._write('''\

#endif /* %s */
''' % (self._module.header_sentinel('.h')))

    # Write a section comment
    def _write_section(self, comment):

            self._write('''\

/*
 * %s
 */

''' % (comment))

    # Write enumeration definition
    def _write_enumeration(self, name, values, ix_start = 0, ix_delta = 1, value_symbols = {}):

        # Enum header
        self._write('''\
typedef enum _%s
{
''' % (name))

        # Write enum values
        ix_value = ix_start
        ix_value_last = ix_start + ix_delta * (len(values) - 1)
        sep = ","
        for value in values:

            # Does the value have a symbol?
            if value_symbols.has_key(value):
                str_value = value_symbols[value]
            else:
                str_value = str(ix_value)

            # Don't separate the last value
            if ix_value == ix_value_last:
                sep = ""

            # Write the enum value
            self._write('''\
    %s = %s%s
''' % (value, str_value, sep))

            ix_value += ix_delta

        # Enum footer
        self._write('''\
} %s;
''' % (name))

    # Write schema definition
    def _write_schema(self, schema_nodes_static, schema_static, nodes,
                      element_path_static = None, element_path = None):

        # Schema nodes header
        self._write('''\
static const HDK_XML_SchemaNode %s[] =
{
''' % (schema_nodes_static))

        # Write the schema nodes
        ix = 0
        for node in nodes:

            # Compute the parent index
            if node.parent:
                ix_parent = nodes.index(node.parent)
            else:
                ix_parent = 0

            # Compute the options
            options = []
            if node.is_optional:
                options.append("HDK_XML_SchemaNodeProperty_Optional")
            if node.is_unbounded:
                options.append("HDK_XML_SchemaNodeProperty_Unbounded")
            if node.is_any_element:
                options.append("HDK_XML_SchemaNodeProperty_AnyElement")
            if node.is_error:
                options.append("HDK_XML_SchemaNodeProperty_ErrorOutput")
            if node.is_csv:
                options.append("HDK_XML_SchemaNodeProperty_CSV")
            if options:
                options = " | ".join(options)
            else:
                options = "0"

            # Write the schema node
            self._write('''\
    /* %d */ { %d, %s, %s, %s },
''' % (ix, ix_parent,
       self._module.element_value(node.element()),
       self._module.type_value(node.type),
       options))
            ix += 1

        # Schema nodes footer
        self._write('''\
    HDK_XML_Schema_SchemaNodesEnd
};
''')

        # Schema struct element path
        if element_path_static and element_path:

            self._write('''\

static const HDK_XML_Element %s[] =
{
''' % (element_path_static))
            for element in element_path:
                self._write('''\
    %s,
''' % (self._module.element_value(element)))
            self._write('''\
    HDK_MOD_ElementPathEnd
};
''')

        # Schema
        self._write('''\

static const HDK_XML_Schema %s =
{
    s_namespaces,
    s_elements,
    %s,
    %s
};
''' % (schema_static,
       schema_nodes_static,
       "s_enumTypes" if self._module.schema.enums else "0"))

    # Write action definition
    def _write_action(self, action_loc):

        http_method, http_location, action, noauth = \
            (action_loc.http_method, action_loc.http_location, action_loc.action, action_loc.noauth)

        # Compute the SOAP action
        is_get = (http_method.lower() == "get")
        if is_get:
            soap_action = "0"
        else:
            soap_action = '"' + action.uri + '"'

        # Compute the action function name
        if self._bGenerateActions:
            action_fn = self._module.action_fn(action)
        else:
            action_fn = "0"

        # Compute the schema struct element path symbols
        if not is_get and self._module.schema.struct_nodes_envelope(action.inputMember, soap = True):
            input_element_path = self._module.schema_element_path_static(action, "_Input")
        else:
            input_element_path = "0"
        if self._module.schema.struct_nodes_envelope(action.outputMember, soap = True):
            output_element_path = self._module.schema_element_path_static(action, "_Output")
        else:
            output_element_path = "0"

        # Compute the method options
        options = []
        if noauth:
            options.append("HDK_MOD_MethodOption_NoBasicAuth")
        if is_get:
            options.append("HDK_MOD_MethodOption_NoInputStruct")
        if options:
            options = " | ".join(options)
        else:
            options = "0"

        # Compute the OK and REBOOT values
        result_member = action.outputMember.type.members[0]
        if "REBOOT" in action.resultEnum.enumValues:
            result_reboot = "REBOOT"
        else:
            result_reboot = "OK"

        # Write the method struct
        self._write('''\
    {
        "%s",
        "%s",
        %s,
        %s,
        &%s,
        &%s,
        %s,
        %s,
        %s,
        %s,
        %s,
        %s,
        %s
    },
''' % (http_method,
       http_location,
       soap_action,
       action_fn,
       self._module.schema_static(action, suffix = "_Input"),
       self._module.schema_static(action, suffix = "_Output"),
       input_element_path,
       output_element_path,
       options,
       self._module.element_value((result_member.namespace, result_member.name)),
       self._module.type_value(result_member.type),
       self._module.enum_value(result_member.type, "OK"),
       self._module.enum_value(result_member.type, result_reboot)))

    # Write event definition
    def _write_event(self, event):

        # Write the method struct
        self._write('''\
    {
        "%s",
        &%s
    },
''' % (event.uri,
       self._module.schema_static(event)))

    #
    # *.h code generator
    #

    def _generate_h(self):

        # File header
        self._write_header_h()

        # Includes
        self._write('''\

#include "hdk_mod.h"

/*
 * Macro to control public exports
 */

#ifdef __cplusplus
#  define %s_PREFIX extern "C"
#else
#  define %s_PREFIX extern
#endif
#ifdef HDK_MOD_STATIC
#  define %s %s_PREFIX
#else /* ndef HDK_MOD_STATIC */
#  ifdef _MSC_VER
#    ifdef %s
#      define %s %s_PREFIX __declspec(dllexport)
#    else
#      define %s %s_PREFIX __declspec(dllimport)
#    endif
#  else /* ndef _MSC_VER */
#    ifdef %s
#      define %s %s_PREFIX __attribute__ ((visibility("default")))
#    else
#      define %s %s_PREFIX
#    endif
#  endif /*def _MSC_VER */
#endif /* def HDK_MOD_STATIC */
''' % (self._module.export_macro(),
       self._module.export_macro(),
       self._module.export_macro(), self._module.export_macro(),
       self._module.build_macro(),
       self._module.export_macro(), self._module.export_macro(),
       self._module.export_macro(), self._module.export_macro(),
       self._module.build_macro(),
       self._module.export_macro(), self._module.export_macro(),
       self._module.export_macro(), self._module.export_macro()))

        # Element enumeration
        self._write_section("Elements")
        self._write_enumeration(self._module.element_enum(),
                                [ self._module.element_value(element) for element in self._module.schema.elements ])

        # Enumeration type definition
        if self._module.schema.enums:

            self._write_section("Enum types enumeration")
            self._write_enumeration(self._module.enum_type_enum(),
                                    [ self._module.enum_type_value(enum) for enum in self._module.schema.enums ],
                                    ix_start = -1, ix_delta = -1)

        # Enumeration declarations
        for enum in self._module.schema.enums:

            # Enumeration type definition
            self._write_section("Enumeration %s" % (enum.uri))
            value_unknown = self._module.enum_value(enum, None, is_unknown = True)
            values = [ value_unknown ]
            values.extend([ self._module.enum_value(enum, value) for value in enum.enumValues ])
            self._write_enumeration(self._module.enum_enum(enum), values, ix_start = -1,
                                    value_symbols = { value_unknown: "HDK_XML_Enum_Unknown" })

            # Enumeration accessor declarations
            self._write('''\

#define %s(pStruct, element, value) HDK_XML_Set_Enum(pStruct, element, %s, 0 ? %s : (value))
#define %s(pStruct, element, value) HDK_XML_Append_Enum(pStruct, element, %s, 0 ? %s : (value))
#define %s(pStruct, element) (%s*)HDK_XML_Get_Enum(pStruct, element, %s)
#define %s(pStruct, element, value) (%s)HDK_XML_GetEx_Enum(pStruct, element, %s, 0 ? %s : (value))
#define %s(pMember) (%s*)HDK_XML_GetMember_Enum(pMember, %s)
''' % (self._module.enum_accessor(enum, "Set"), self._module.enum_type_value(enum), self._module.enum_value(enum, enum.enumValues[0]),
       self._module.enum_accessor(enum, "Append"), self._module.enum_type_value(enum), self._module.enum_value(enum, enum.enumValues[0]),
       self._module.enum_accessor(enum, "Get"), self._module.enum_enum(enum), self._module.enum_type_value(enum),
       self._module.enum_accessor(enum, "GetEx"), self._module.enum_enum(enum), self._module.enum_type_value(enum), self._module.enum_value(enum, enum.enumValues[0]),
       self._module.enum_accessor(enum, "GetMember"), self._module.enum_enum(enum), self._module.enum_type_value(enum)))

        # Action enumeration
        if self._module.actions:
            self._write_section("Method enumeration")
            self._write_enumeration(self._module.action_enum(),
                                    [ self._module.action_value(action_loc) for action_loc in self._module.action_locations() ])

        # Action sentinels
        if self._bGenerateActions:
            self._write_section("Method sentinels")
            for action in self._module.actions:
                self._write('''\
#define %s
''' % (self._module.action_sentinel(action)))

        # Action declarations
        if self._bGenerateActions:
            self._write_section("Methods")
            for action in self._module.actions:
                self._write('''\
extern void %s(HDK_MOD_MethodContext* pMethodCtx, HDK_XML_Struct* pInput, HDK_XML_Struct* pOutput);
''' % (self._module.action_fn(action)))

        # Event enumeration
        if self._module.events:
            self._write_section("Event enumeration")
            self._write_enumeration(self._module.event_enum(),
                                    [ self._module.event_value(event) for event in self._module.events ])

        # DOM (struct) schema accessor declarations
        if self._module.schema.structs:
            self._write_section("DOM Schemas")
        for struct in self._module.schema.structs:
            self._write('''\
%s const HDK_XML_Schema* %s();
''' % (self._module.export_macro(), self._module.dom_schema_fn(struct)))

        # State declarations
        if self._module.states:

            self._write_section("ADI")
            self._write_enumeration(self._module.state_enum(),
                                    [ self._module.state_value(state) for state in self._module.states ],
                                    ix_start = 1)

            self._write_section("ADI sentinels")
            for state in self._module.states:

                # Determine get/set
                usages = {}
                for actionState in self._model.actionStates:
                    if state.uri in actionState.stateMembers:
                        stateMember = actionState.stateMembers[state.uri]
                        if stateMember.isGet:
                            usages["get"] = None
                        if stateMember.isSet:
                            usages["set"] = None

                for usage in sorted(usages.iterkeys()):
                    self._write('''\
#define %s
''' % (self._module.state_value_sentinel(state, usage)))

        # Module declaration
        if self._bGenerateModule:

            self._write_section("Module")
            self._write('''\
%s const HDK_MOD_Module* %s(void);
''' % (self._module.export_macro(), self._module.module_fn()))

            if self._bGenerateModuleDynamic:
                self._write('''\

/* Dynamic server module export */
%s const HDK_MOD_Module* HDK_SRV_Module(void);
''' % (self._module.export_macro()))

        # File footer
        self._write_footer_h()

    #
    # *.c code generator
    #

    def _generate_c(self):

        # File header
        self._write_header_c()
        self._write('''\

#include "%s"

#include <string.h>
''' % (self._module.filename('.h')))

        # Namespace table
        self._write_section("Namespaces")
        self._write('''\
static const HDK_XML_Namespace s_namespaces[] =
{
''')
        for namespace in self._module.schema.namespaces:
            self._write('''\
    /* %d */ "%s",
''' % (self._module.schema.namespace_index(namespace),
       namespace))
        self._write('''\
    HDK_XML_Schema_NamespacesEnd
};
''')

        # Elements table
        self._write_section("Elements")
        self._write('''\
static const HDK_XML_ElementNode s_elements[] =
{
''')
        for element in self._module.schema.elements:
            self._write('''\
    /* %s = %d */ { %d, "%s" },
''' % (self._module.element_value(element),
       self._module.schema.element_index(element),
       self._module.schema.namespace_index(element[0]),
       element[1]))
        self._write('''\
    HDK_XML_Schema_ElementsEnd
};
''')

        # Enumerations definitions
        for enum in self._module.schema.enums:

            # Enumeration string table
            self._write_section("Enumeration %s" % (enum.uri))
            self._write('''\
static const HDK_XML_EnumValue %s[] =
{
''' % (self._module.enum_type_strings_static(enum)))
            for value in enum.enumValues:
                self._write('''\
    "%s",
''' % (value))
            self._write('''\
    HDK_XML_Schema_EnumTypeValuesEnd
};
''')

        # Enum types array
        if self._module.schema.enums:

            self._write_section("Enumeration types array")
            self._write('''\
static const HDK_XML_EnumType s_enumTypes[] =
{
''')
            sep = ','
            for enum in self._module.schema.enums:
                if enum is self._module.schema.enums[-1]:
                    sep = ""
                self._write('''\
    %s%s
''' % (self._module.enum_type_strings_static(enum), sep))
            self._write('''\
};
''')

        # Action definitions
        for action in self._module.actions:

            self._write_section("Method %s" % (action.uri))

            # Input schema
            self._write_schema(self._module.schema_nodes_static(action, suffix = "_Input"),
                               self._module.schema_static(action, suffix = "_Input"),
                               self._module.schema.struct_nodes(action.inputMember, soap = True),
                               element_path_static = self._module.schema_element_path_static(action, suffix = "_Input"),
                               element_path = self._module.schema.struct_nodes_envelope(action.inputMember, soap = True))

            # Output schema
            self._write('''\

''')
            self._write_schema(self._module.schema_nodes_static(action, suffix = "_Output"),
                               self._module.schema_static(action, suffix = "_Output"),
                               self._module.schema.struct_nodes(action.outputMember, soap = True),
                               element_path_static = self._module.schema_element_path_static(action, suffix = "_Output"),
                               element_path = self._module.schema.struct_nodes_envelope(action.outputMember, soap = True))

        # Actions table
        if self._module.actions:

            self._write_section("Methods")

            # Actions table header
            self._write('''\
static const HDK_MOD_Method s_methods[] =
{
''')

            # Write each action node
            for action_loc in self._module.action_locations():
                self._write_action(action_loc)

            # Actions table footer
            self._write('''\
    HDK_MOD_MethodsEnd
};
''')

        # Event definitions
        for event in self._module.events:

            self._write_section("Event %s" % (event.uri))
            self._write_schema(self._module.schema_nodes_static(event),
                               self._module.schema_static(event),
                               self._module.schema.struct_nodes(event.member))

        # Events table
        if self._module.events:

            self._write_section("Events")

            # Events table header
            self._write('''\
static const HDK_MOD_Event s_events[] =
{
''')

            # Write each event node
            for event in self._module.events:
                self._write_event(event)

            # Events table footer
            self._write('''\
    HDK_MOD_EventsEnd
};
''')

        if self._bGenerateServices:

            # Services action tables
            self._write_section("Service Methods")
            for service in self._module.services:

                # Service actions header
                self._write('''\
static const HDK_MOD_Method* %s[] =
{
''' % (self._module.service_actions_name(service)))

                # Service actions
                for action_uri in service.actions:

                    action_loc = [a for a in self._module.action_locations() if a.action.uri == action_uri][0]
                    self._write('''\
    &s_methods[%s],
''' % (self._module.action_value(action_loc)))

                # Service actions footer
                self._write('''\
    0
};
''')

            # Services event tables
            self._write_section("Service Events")
            for service in self._module.services:

                # Service events header
                self._write('''\
static const HDK_MOD_Event* %s[] =
{
''' % (self._module.service_events_name(service)))

                # Service events
                for eventURI in service.events:

                    event = [e for e in self._module.events if e.uri == eventURI][0]
                    self._write('''\
    &s_events[%s],
''' % (self._module.event_value(event)))

                # Service events footer
                self._write('''\
    0
};
''')

            # Services table
            self._write_section("Services")

            # Services table header
            self._write('''\
static const HDK_MOD_Service s_services[] =
{
''')

            # Write each service node
            for service in self._module.services:
                self._write('''\
    {
        "%s",
        %s,
        %s
    },
''' % (service.uri,
       self._module.service_actions_name(service),
       self._module.service_events_name(service)))

            # Services table footer
            self._write('''\
    HDK_MOD_ServicesEnd
};
''')

        # State definitions
        if self._module.states:

            self._write_section("ADI")
            self._write_schema("s_schemaNodes_ADI", "s_schema_ADI",
                               self._module.schema.state_nodes())

        # Struct schema definitions
        for struct in self._module.schema.structs:
            self._write_section("Struct %s" % (struct.uri))
            self._write_schema(self._module.schema_nodes_static(struct),
                               self._module.schema_static(struct),
                               self._module.schema.struct_nodes(struct))
            self._write('''\

/* extern */ const HDK_XML_Schema* %s()
{
    return &%s;
}
''' % (self._module.dom_schema_fn(struct),
       self._module.schema_static(struct)))

        # Module definition
        if self._bGenerateModule:

            self._write_section("Module");

            # Network Object ID definition
            if self._noid is not None:
                self._write('''\
/* %s */
static const HDK_XML_UUID s_uuid_NOID =
{
    { %s }
};

''' % (self._noid, ", ".join(["0x%02x" % ord(byte) for byte in self._noid.bytes])))

            # Module definition and accessors
            self._write('''\
static const HDK_MOD_Module s_module =
{
    %s,
    %s,
    %s,
    %s,
    %s,
    %s
};

const HDK_MOD_Module* %s(void)
{
    return &s_module;
}
''' % (
    "&s_uuid_NOID" if self._noid else "0",
    '"' + self._friendlyName + '"' if self._friendlyName else "0",
    "s_services" if self._bGenerateServices else "0",
    "s_methods" if self._module.actions else "0",
    "s_events" if self._module.events else "0",
    "&s_schema_ADI" if self._module.states else "0",
    self._module.module_fn()
    ))

            if self._bGenerateModuleDynamic:
                self._write('''\

const HDK_MOD_Module* HDK_SRV_Module(void)
{
    return &s_module;
}
''')

    #
    # *_methods.c code generator
    #

    def _generate_methods_c(self):

        # File header
        self._write_header_c()
        self._write('''\

#include "%s"

#include "hdk_srv.h"

/* Helper method for HNAP results */
#define SetHNAPResult(pStruct, prefix, method, result) \\
    prefix##_Set_##method##Result(pStruct, prefix##_Element_##method##Result, prefix##_Enum_##method##Result_##result)
''' % (self._module.filename('.h')))

        # Action declarations
        for action in self._module.actions:

            self._write_section("Method %s" % (action.uri))
            self._write('''\
#ifdef %s

void %s(HDK_MOD_MethodContext* pMethodCtx, HDK_XML_Struct* pInput, HDK_XML_Struct* pOutput)
{
    /* Unused parameters */
    (void)pMethodCtx;
    (void)pInput;
    (void)pOutput;
}

#endif /* %s */
''' % (self._module.action_sentinel(action),
       self._module.action_fn(action),
       self._module.action_sentinel(action)))

    #
    # *_adi.txt report generator
    #

    def _generate_adi_txt(self):

        # ADI report title
        self._write('''\
======================================================================
ADI Report for the %s Module
======================================================================
''' % (self._baseName.upper()))

        # Output the ADI values used (show get/set)
        self._write('''\

======================================================================
ADI values
======================================================================
''')
        for state in self._model.referenced_states():

            # Determine get/set
            usages = {}
            for actionState in self._model.actionStates:
                if state.uri in actionState.stateMembers:
                    stateMember = actionState.stateMembers[state.uri]
                    if stateMember.isGet:
                        usages["get"] = None
                    if stateMember.isSet:
                        usages["set"] = None
            sUsages = ', '.join(sorted(usages.iterkeys()))

            # Get the base type
            type = state.type
            nArray = 0
            while type.isArray:
                nArray += 1
                type = type.arrayType
            sArray = "[]" * nArray

            # Get the type description
            sDesc = ""
            if type.isEnum:
                sDesc = "enum"
            elif type.isStruct:
                sDesc = "struct"

            # Get the type string
            if sDesc:
                sType = '%s%s (%s, "%s")' % (type.name, sArray, sDesc, type.namespace)
            else:
                sType = '%s%s' % (type.name, sArray)

            self._write('''\

%s

    Namespace: "%s"
         Name: "%s"
         Type: %s
        Usage: %s
''' % (self._module.state_value(state), state.namespace, state.name, sType, sUsages))

        # Output the ADI values used by action
        self._write('''\

======================================================================
ADI values by action
======================================================================
''')
        for actionState in self._model.actionStates:
            self._write('''\

%s

''' % (actionState.uri))
            for stateMember in sorted(actionState.stateMembers.itervalues()):

                # Determine usage
                usages = {}
                if stateMember.isGet:
                    usages["get"] = None
                if stateMember.isSet:
                    usages["set"] = None
                sUsages = ', '.join(sorted(usages.iterkeys()))

                self._write('''\
    [%s] %s
''' % (sUsages, self._module.state_value(stateMember.state)))

######################################################################

if __name__ == "__main__":
    main()


import sys
import getopt
import random
import ctypes
import argparse

# Creates a golden model that decompresses data from a 1D L2 memory
# to an L1 2D memory

def parse_arguments(parser):
    parser.add_argument('--transfer_size', type=int, help="Total items to transfer: value between 1 to 4096")
    parser.add_argument('--use_sign', type=int, help="Use a sign extension: 0 or 1")
    parser.add_argument('--qbit', type=int, help="Number of quantization bits: Value between 1 to 16")
    parser.add_argument('--word_extension', type=int, help="Word extension: 0: 8-bit (byte), 1: 16-bit (half-word), 3: 32-bit (word)")
    parser.add_argument('--item_count', type=int, help="Number of items to decompress/compress (T1) during the linear part of the 2D transfer")
    parser.add_argument('--stride_length', type=int, help="Number of items to JUMP (T1) during the linear part of the 2D transfer to move to the second chunk")
    parser.add_argument('--special_symbol', type=int, help="Symbol used for T3 transfers mostly (used here only for coverage)")
    parser.add_argument('--L2_memory_elements', type=int, help="Number of elements stored in L2 cache memory")
    parser.add_argument('--start_bit', type=int, help="Starting bit")
    parser.add_argument('--start_byte', type=int, help="Starting byte")

    args = parser.parse_args()

    if (args.transfer_size == None or args.transfer_size < 1 or args.transfer_size > 4096):
        raise argparse.ArgumentError(args.transfer_size, "Value must be between 1 and 4096")
    if (args.use_sign < 0 or args.use_sign > 1):
        raise argparse.ArgumentError(args.use_sign, "Can be only 0 (unsigned) or 1 (signed)")
    if (args.qbit < 1 or args.qbit > 16):
        raise argparse.ArgumentError(args.qbit, "qbit must be between 1 and 16")
    if (args.word_extension == '0' or args.word_extension == '1' or args.word_extension == '3'):
        raise argparse.ArgumentError(args.word_extension, "Word extension must be either 0 (8 bits), 1 (16 bits) or 3 (32 bits)")
    if (args.item_count > args.stride_length):
        raise argparse.ArgumentError(args.stride_length, "Stride length must be higher than the item count")
    if (args.L2_memory_elements == None or args.L2_memory_elements < 1 or args.L2_memory_elements > 4096):
        raise argparse.ArgumentError(args.L2_memory_elements, "L2 memory elements must be between 1 and 4096")
    if (args.start_bit < 0 or args.start_bit > 8):
        raise argparse.ArgumentError(args.start_bit, "Start bit should be between 0 and 7")
    if (args.start_byte < 0 or args.start_byte > 3):
        raise argparse.ArgumentError(args.start_byte, "Start byte should be between 0 and 3")

def output_to_file():
    # Output golden model of L2 2D data decompressed into L1 to a file
    file = open("compressed_data.c", "w")

    file.write('/******************\n')
    file.write(' * GENERATED FILE *\n')
    file.write(' * DO NOT COMMIT !*\n')
    file.write('*******************/\n\n')

    file.write('/* -------- */\n')
    file.write('/* includes */\n')
    file.write('/* -------- */\n')
    file.write('#include <stdint.h>\n\n')

    word_size_table = ['int8_t', 'int16_t', 'int32_t']
    word_size = word_size_table[word_length_choice-1]

    if (word_length_choice == 0):
        word_size = 'int8_t'
    elif (word_length_choice == 1):
        word_size = 'int16_t'
    elif (word_length_choice == 3):
        word_size = 'int32_t'
    else:
        raise RuntimeError("invalid word size");

    if (use_sign):
        data_type = ""
    else:
        data_type = "u"

    hex_zero_fill_table = [2, 4, 8]

    hzero_fill = hex_zero_fill_table[word_length_choice-1]

    # Write the golden model decompressed elements
    file.write('/* ------------------------------------------ */\n')
    file.write('/* expected decompressed data in cluster TCDM */\n')
    file.write('/* ------------------------------------------ */\n')
    file.write('static PI_L1 u' + word_size + ' tcdm_expect_data[' + str(list_length) + '] = {\n')

    # Decompress in byte size
    if (word_length_choice == 0):
        for i in range(0, list_length):
            byte = decompressed_list[i]
            byte = byte[6:]

            if (use_sign == 1):
                # Turn hex to binary
                byte = bin(int(byte, 16))[2:].zfill(8)

                # If MSB is '1' then pad the rest of bits with '1's
                if (byte[8-qbit] == '1'):
                    # If qbit > than a byte then just write the byte and discard
                    # the excess qbits
                    if (qbit > 8):
                        byte = ('1' * 24 + byte)
                    else:
                        # Pad with '1's if the number is negative
                        byte = ('1' * (8-qbit)) + byte[8-qbit:]
                # Else just turn back to hex and continue
                byte = '{:02x}'.format(int(byte, 2))

            byte = int(byte, 16)
            byte = hex(byte)[2:].zfill(2)
            file.write("    " + "0x" + byte + ", // " + "@" + str(i) + "\n")

        file.write("")
        file.write("};\n\n\n\n\n")

    # Decompress in half word size
    if (word_length_choice == 1):
        for i in range(0, list_length):
            half_word = decompressed_list[i]
            half_word = half_word[4:]

            if (use_sign == 1):
                # Turn hex to binary
                half_word = bin(int(half_word, 16))[2:].zfill(16)

                # If MSB is '1' then pad the rest of bits with '1's
                if (half_word[16-qbit] == '1'):
                    # Pad with '1's if the number is negative
                    half_word = ('1' * (16-qbit)) + half_word[16-qbit:]
                # Else just turn back to hex and continue
                half_word = '{:04x}'.format(int(half_word, 2))

            half_word = int(half_word, 16)
            half_word = hex(half_word)[2:].zfill(2)
            file.write("    " + "0x" + half_word + ", // " + "@" + str(i) + "\n")

        file.write("")
        file.write("};\n\n\n\n\n")

    # Decompress in word size
    if (word_length_choice == 3):
        for i in range(0, list_length):
            word = decompressed_list[i]

            if (use_sign == 1):
                # Turn hex to binary
                word = bin(int(word, 16))[2:].zfill(32)

                # If MSB is '1' then pad the rest of bits with '1's
                if (word[32-qbit] == '1'):
                    # Pad with '1's if the number is negative
                    word = ('1' * (32-qbit)) + word[32-qbit:]
                # Else just turn back to hex and continue
                word = '{:08x}'.format(int(word, 2))

            word = int(word, 16)
            word = hex(word)[2:].zfill(hzero_fill)
            file.write("    " + "0x" + word + ", // " + "@" + str(i) + "\n")
        file.write("")
        file.write("};\n\n\n\n\n")

    # Write the random data to load to the L2 memory
    file.write('/* ------------------------------------- */\n')
    file.write('/* L2 Data to decompress in cluster TCDM */\n')
    file.write('/* ------------------------------------- */\n')
    file.write('static PI_L2 uint32_t l2_compr_data[' + str(total_L2_memory_elements) + '] = {\n')
    for i, comp_item in enumerate(L2_memory):
        comp_item = hex(comp_item)
        file.write("    " + comp_item + ", // " + "@" + str(i) + "\n")
    file.write("};\n")

    # Writes the configuration for the register
    file.write("/* ------------------------------ */\n")
    file.write("/* decompressor command structure */\n")
    file.write("/* ------------------------------ */\n")

    file.write("pi_cl_dma_decompressor_cmd_t cmd = {\n")
    file.write("    .ext                    = (uint32_t) l2_compr_data,\n"),
    file.write("    .loc                    = (uint32_t) NULL, // should be set before testing\n"),
    file.write("    .conf.items_to_transfer = {},\n".format(transfer_size)),
    file.write("    .conf.decompr_mode      = PI_CL_DMA_DECOMPRESSOR_MODE_T1,\n"),
    file.write("    .conf.decompr_direction = PI_CL_DMA_DECOMPRESSOR_DIR_EXT2LOC,\n"),
    file.write("    .transf_type            = PI_CL_DMA_DECOMPRESSOR_TRANSF_EXT_LIN_LOC_2D,\n"),
    file.write("    .conf.extension_type    = PI_CL_DMA_DECOMPRESSOR_EXT_TYPE_{},\n"
               .format(8 * (word_length_choice+1))),
    file.write("    .conf.sign_extension = PI_CL_DMA_DECOMPRESSOR_EXT_SIGN_{},\n"
               .format("SIGNED" if use_sign else "UNSIGNED")),
    file.write("    .conf.item_bit_width    = {},\n".format(qbit)),
    file.write("    .conf.start_bit         = {},\n".format(start_bit)),
    file.write("    .conf.start_byte        = {},\n".format(start_byte)),
    file.write("    .lut                    = NULL,\n"),
    file.write("    .lut_size               = 0,\n"),
    file.write("    .l2_2d.count            = 0,\n"),
    file.write("    .l2_2d.stride           = 0,\n"),
    file.write("    .tcdm_2d.count          = {},\n".format(item_count - 1)),
    file.write("    .tcdm_2d.stride         = {},\n".format(stride_length - 1)),
    file.write("    .special_symbol         = {},\n".format(special_symbol)),
    file.write("    .done                   = 0,\n"),
    file.write("    .flag.update_lut        = 0,\n"),
    file.write("    .flag.update_2d_ext     = 0,\n"),
    file.write("    .flag.update_2d_loc     = 1,\n"),
    file.write("};\n\n")

    file.close()

# Parse the script arguments
parser = argparse.ArgumentParser()
parse_arguments(parser)
args = parser.parse_args()

# If arguments are ok assign them to the values
use_sign = args.use_sign
transfer_size = args.transfer_size
qbit = args.qbit
item_count = args.item_count
stride_length = args.stride_length
total_L2_memory_elements = args.L2_memory_elements
start_bit = args.start_bit
start_byte = args.start_byte
# 0: 8 bits, 1: 16bits, 3: 32 bits
word_length_choice = args.word_extension
special_symbol = args.special_symbol

word_length = 2**32

hex_zero_fill_table = [2, 4, 8]
bin_zero_fill_table = [8, 16, 32]

hex_zero_fill = 32
bin_zero_fill = 32

# Create a list with N numbers in range (0, 2**N) and put them in L2 memory as compressed data
randomlist = random.sample(range(0, word_length), total_L2_memory_elements)

L2_memory = randomlist[:]

# Fill hex numbers with zeroes if needed
for i in range(0, total_L2_memory_elements):
    randomlist[i] = '{:08x}'.format(randomlist[i]).zfill(hex_zero_fill)

item_index = 0
item_to_decomp = randomlist[item_index]

item_to_decomp = bin(int(item_to_decomp, 16))[2:].zfill(bin_zero_fill)

start_bit_index = (args.start_byte * 8) + args.start_bit
end_bit_index = start_bit_index + qbit

# Items that are decompressed from L2 memory to the L1
decompressed_list = []

# Indexes from where in the array to read 'item_count' elements
stride_index = 0

elements_remaining = transfer_size

# Engine to generate the decompressed 2D data to L1
while (elements_remaining > 0):
    # Start from stride index and read item_count items
    for decomp_item in range(0, item_count):
        # If qbit word spans between 2 L2 elements then we read
        # from N bit up to 31 and
        # from 0 of the next L2 element up to the R bits remaining
        # Crossword schematic example:
        #     L2 element N   [ --------(---- ],
        #     L2 element N+1 [ --)---------- ]
        if (elements_remaining <= 0):
            # no more element to compress
            decompressed_list.append("0x00000000")
            continue
        if (end_bit_index) > 32:
            cross_word_start = item_to_decomp[0:32-start_bit_index]

            item_index += 1
            item_to_decomp = randomlist[item_index]
            item_to_decomp = bin(int(item_to_decomp, 16))[2:].zfill(bin_zero_fill)

            cross_word_end = item_to_decomp[32-(end_bit_index-32):32]

            start_bit_index = end_bit_index - 32
            end_bit_index = start_bit_index + qbit

            cross_word = cross_word_end + cross_word_start
            decompressed_list.append('{:08x}'.format(int(cross_word, 2)).zfill(8))
            elements_remaining -= 1
            continue

        # Use the binary string and select specific bits to decompress. Then turn to hex and add leading zeros
        item_to_decomp = randomlist[item_index]
        item_to_decomp = bin(int(item_to_decomp, 16))[2:].zfill(bin_zero_fill)
        item = item_to_decomp[32-end_bit_index:32-start_bit_index]

        decompressed_list.append('{:08x}'.format(int(item, 2)).zfill(8))
        start_bit_index += qbit
        end_bit_index += qbit
        elements_remaining -= 1

    # After we finish the decompressing of the linear part of a 2D array
    # we jump to the next stride offset and continue for the next items.
    # The items jumped are assumed to be 0 when testing
    for i in range(0, stride_length-item_count):
        decompressed_list.append("0x00000000")

    item_to_decomp = randomlist[item_index]
    item_to_decomp = bin(int(item_to_decomp, 16))[2:].zfill(bin_zero_fill)

list_length = len(decompressed_list)

output_to_file()


# Numstat2 python assignment
# By Dylan Lade

import math
import statistics
from collections import Counter

loop = "y"

while(loop == 'y'):
    filename = input('What file would you like to read? ')

    total = 0

    try:
        file = open(filename, "r")
    except:
        print("File failed to open. Would you like to try another file? (y/n) ")
        loop = input()
        if(loop == 'y'):
            continue
        else:
            break

    lines = file.readlines()

    array = []

    for i in lines:
        temp = i.strip("\n")
        total += int(temp)
        array.append(int(temp))

    if(len(array) == 0):
        print("There are no numbers in " + filename)
        loop = input("Would you like to evaluate another file? (y/n) ")
        if(loop == 'y'):
            continue
        else:
            break

    n = len(array)

    data = Counter(array)
    get_mode = dict(data)
    mode = [k for k, v in get_mode.items() if v == max(list(data.values()))]

    average = (total/len(array))
    arrayRange = (max(array) - min(array))
    median = statistics.median(array)

    print("Grabbing number information from : " + filename)

    print("Sum: " + str(total))
    print("Count: " + str(len(array)))
    print("Average: " + str(average))
    print("Maximum: " + str(max(array)))
    print("Minimum: " + str(min(array)))
    print("Range: " + str(arrayRange))
    print("Median: " + str(median))
    print("Mode: " + str(mode))

    loop = input("Would you like to evaluate another file? (y/n) ")


#!/usr/bin/env python
# -*- coding: utf-8 -*-
from bs4 import BeautifulSoup
import re
import requests
import unicodedata
import time
url_base = 'http://wikimipt.org/index.php?title=%D0%9A%D0%B0%D1%82%D0%B5%D0%B3%D0%BE%D1%80%D0%B8%D1%8F:%D0%9F%D1%80%D0%B5%D0%BF%D0%BE%D0%B4%D0%B0%D0%B2%D0%B0%D1%82%D0%B5%D0%BB%D0%B8_%D0%BF%D0%BE_%D0%B0%D0%BB%D1%84%D0%B0%D0%B2%D0%B8%D1%82%D1%83&from='
IS_TESTING = False
print ('\n -----------')

def test(func):
    """декоратор для анализа времени выполнения разных функций парсера"""
    if(not IS_TESTING):
        def run_test(*args):
            return func(*args)
    else:
        def run_test(*args):
            t0 = time.time()
            x = func(*args)
            t1 = time.time()
            print (func.__name__ + ' - ' + str(t1 - t0))
            return x
    return run_test

def getPrepList(name):
    """получает список препов с викимипта(тех чьи фамилии на нужную букву начинаются)"""
    url = url_base + name[0].upper()
    r = requests.get(url)
    if(r.status_code == 200):
        soup = BeautifulSoup(r.text, 'html.parser')
        rawPrepList = soup.find(
            class_="mw-category-group")
        if not rawPrepList:
            rawPrepList = soup.find(class_="mw-content-ltr")
        rawPrepList = rawPrepList.find('ul').find_all('li')
        result = []
        for rawItem in rawPrepList:
            cleanItem = list(rawItem.children)[0]
            result.append(
                {'name': cleanItem['title'], 'href': cleanItem['href']})
        return result
    else:
        raise ValueError(
            'Невозможно получить список преподавателей ((00((00(((' +
            ' - ' +
            r.status_code)

def findPrepInList(name, array):
    """находит нужного преподавателя в списке"""
    result = []
    pattern = re.compile(name.lower(), flags=re.IGNORECASE)
    for item in array:
        if pattern.match(
                item['name']):
            result.append(
                {'name': item['name'], 'href': 'http://wikimipt.org' + item['href']})
    return result

def getPrepInfo(url):
    '''получаем инфу по конкретному преподавателю'''
    r = requests.get(url)
    if(r.status_code == 200):
        soup = BeautifulSoup(r.text, 'html.parser')
        items = list(soup.find(class_="wikitable card").children)
        resultObj = {}
        resultObj["name"] = items[1].find('b').get_text().strip()
        resultObj["image"] = items[3].find('td').find('img')['src']
        resultObj["href"] = url
        rating = list(
            soup.find(
                class_="wikitable card").find_all(
                class_='starrating-div'))
        resultObj['rate'] = []
        resultObj['href'] = url
        skills = [
            u'Знания',
            u'Умение преподавать',
            u'В общении',
            u'Халявность',
            u'Общая оценка']
        for key in range(0, 5):
            skillRate = rating[key].find('span').get_text()
            resultObj['rate'].append(
                {'skill': skills[key], 'num': key, 'value': skillRate})
        return resultObj
    else:
        raise ValueError(
            'Невозможно получить страницу преподавателя (00((((((' + ' - ' + r.status_code)

def finalSearch(name):
    """получает список преподавателей с wikimipt.org и находит нужного"""
    result = findPrepInList(name, getPrepList(name))
    if(len(result) != 0):
        if(len(result) == 1):
            return getPrepInfo(result[0]['href'])
        else:
            return result


import sys
from collections import OrderedDict
import numpy as np
import matplotlib as mpl
import matplotlib.gridspec as gridspec
from matplotlib.ticker import AutoMinorLocator
import MDSplus as mds
from scipy import io, constants
import pandas as pd
import gpr1dfusion
import seaborn as sns
import bin_by
import bottleneck as bn
from myThbObject import myThbObject

if int(sys.version_info[0]) < 3:
    import eqtools
mpl.rcParams['font.family'] = 'sans-serif'
mpl.rc("font", size=22)
mpl.rc('font', **{'family': 'sans-serif', 'sans-serif': ['Helvetica']})
mpl.rc("lines", linewidth=2)
import cmocean

if int(sys.version_info[0]) >= 3:
    import plasmapy.physics.parameters as plasma
    from astropy import units as u

def print_menu():
    print(30 * "-", "MENU", 30 * "-")
    print("1. Shot 35879  - Plot with Edge density with upstream profiles ")
    print("2. Shot 35879 - Plot the evolution of lower and upper outer divertor")
    print("3. Plot Radial correlation length from THB with probe from LSN and velocity distributions")
    print("4. Compare shot 33339 and 35879 same greenwald fraction")
    print("99. Exit")
    print(67 * "-")

loop = True

while loop:
    print_menu()
    selection = int(input('Enter your choice [1-99] '))
    # noinspection PyUnboundLocalVariable
    if selection == 1:
        shot = 35879
        tRangesL = ((1.95, 2.1), (2.45, 2.6), (3.09, 3.2))
        colorL = ('#00D3E6', '#8ABA07', '#BC2764')
        fig, ax = mpl.pylab.subplots(figsize=(6, 8.5), nrows=2, ncols=1)
        fig.subplots_adjust(hspace=0.22, bottom=0.1, top=0.95, right=0.95, left=0.2)
        for _ax in ax.flatten():
            _ax.xaxis.set_minor_locator(AutoMinorLocator())
        ax[1].yaxis.set_major_locator(
            mpl.ticker.LogLocator(base=10.0, numticks=15,
                                  subs=(1, 2, 3, 4, 5, 6, 7, 8, 9)))

        conn = mds.Connection('localhost:8001')
        # edge Data
        eN = conn.get(
            'augsignal({}, "TOT", "H-5_corr")'.format(shot)).data() / 1e20
        time = conn.get(
            'dim_of(augsignal({}, "TOT", "H-5_corr")'.format(
                shot) + ')').data()
        ax[0].plot(time, eN, '-k', lw=2)
        _s = 'augdiag(' + str(shot) + ',"LIN","ne", "LIBE")'
        _st = 'dim_of(augdiag(' + str(shot) + ',"LIN","ne", "LIBE"), 0)'
        _sr = 'dim_of(augdiag(' + str(shot) + ',"LIN","ne", "LIBE"), 1)'
        LiBes = conn.get(_s).data()
        LiTime = conn.get(_st).data()
        LiRho = conn.get(_sr).data()
        nG = float(0.8) / (np.pi * np.power(0.5, 2))
        for _idxt, (_t, _c) in enumerate(zip(tRangesL, colorL)):
            ax[0].axvline(np.asarray(_t).mean(), ls='--', color=_c)
            _dummyTime = np.where((LiTime >= _t[0]) & (LiTime <= _t[1]))
            _dummyLib = LiBes[:, _dummyTime].ravel() / 1e19
            _dummyRho = LiRho[:, _dummyTime].ravel()
            _idx = np.where((time >= _t[0]) & (time <= _t[1]))[0]
            nGlabel = eN[_idx].mean() / nG
            yOut, bins, bin_means, bin_width, xOut = bin_by.bin_by(
                _dummyRho, _dummyLib, nbins=30)
            xB = np.asarray([np.nanmean(k) for k in xOut])
            xBE = np.asarray([np.nanstd(k) for k in xOut])
            yB = np.asarray([np.nanmean(k) for k in yOut])
            yBE = np.asarray([np.nanstd(k) for k in yOut])
            xN = np.linspace(0.95, 1.08, 200)
            # be sure to include rho = 1
            xN = np.append(xN, 1)
            xN = xN[np.argsort(xN)]
            # perform the fit
            gp = gpr1dfusion.GibbsInverseGaussianFGPR1D(
                xB, yB, yBE,
                xe=xBE, nrestarts=100, length_scale=0.5,
                epsilon=5.e-3, regularization_parameter=1)
            gp.GPRFit(xN)
            yFit, yFitE, dYrho, dYrhoE = gp.get_gp_results()
            enS = yFit[np.argmin(np.abs(xN - 1))]
            ax[1].semilogy(_dummyRho, _dummyLib / enS,
                           '.', color=_c, ms=1, alpha=0.3)
            ax[1].semilogy(xN, yFit / enS, '-', lw=2, color=_c,
                           label=r'n$^e$/n$_G$ = {:.1f}'.format(nGlabel))
            ax[1].fill_between(xN,
                               (yFit - yFitE / 2) / enS,
                               (yFit + yFitE / 2) / enS,
                               facecolor=_c,
                               edgecolor='none',
                               alpha=0.3)
            ax[1].text(0.05, 0.4 - 0.1 * _idxt, r'n$^e$/n$_G$ = {:.2f}'.format(nGlabel),
                       transform=ax[1].transAxes, color=_c)
        ax[1].set_xlabel(r'$\rho$')
        ax[1].set_ylabel(r'n$_e$/n$_e(\rho=1)$')
        ax[0].set_xlabel(r't [s]')
        ax[0].set_ylabel(r'n$^e [10^{19}$m$^{-3}$]')
        ax[1].set_ylim([2e-2, 3])
        ax[1].set_xlim([0.98, 1.1])
        ax[0].set_ylim([0, 2.0])
        ax[0].set_title(r'#{}'.format(shot))
        fig.savefig('../pdfbox/EdgeDensityUpstreamProfileShot{}.pdf'.format(shot),
                    bbox_to_inches='tight')
    elif selection == 2:
        shot = 35879
        OuterLower = OrderedDict([
            ('ua1', {'R': 1.582, 'z': -1.199, 's': 1.045}),
            ('ua2', {'R': 1.588, 'z': -1.175, 's': 1.070}),
            ('ua3', {'R': 1.595, 'z': -1.151, 's': 1.094}),
            ('ua4', {'R': 1.601, 'z': -1.127, 's': 1.126}),
            ('ua5', {'R': 1.608, 'z': -1.103, 's': 1.158}),
            ('ua6', {'R': 1.614, 'z': -1.078, 's': 1.189}),
            ('ua7', {'R': 1.620, 'z': -1.054, 's': 1.213}),
            ('ua8', {'R': 1.627, 'z': -1.030, 's': 1.246}),
            ('ua9', {'R': 1.640, 'z': -0.982, 's': 1.276})])
        InnerLower = OrderedDict([
            ('ui9', {'R': 1.288, 'z': -0.959, 's': 0.339}),
            ('ui8', {'R': 1.281, 'z': -0.993, 's': 0.373}),
            ('ui7', {'R': 1.275, 'z': -1.011, 's': 0.391}),
            ('ui6', {'R': 1.269, 'z': -1.029, 's': 0.411}),
            ('ui5', {'R': 1.262, 'z': -1.047, 's': 0.429}),
            ('ui4', {'R': 1.256, 'z': -1.065, 's': 0.448}),
            ('ui3', {'R': 1.250, 'z': -1.083, 's': 0.468}),
            ('ui2', {'R': 1.244, 'z': -1.101, 's': 0.486}),
            ('ui1', {'R': 1.238, 'z': -1.119, 's': 0.505})])
        OuterUpper = OrderedDict([
            ('oa5', {'R': 1.637, 'z': 1.139}),
            ('oa4', {'R': 1.606, 'z': 1.152}),
            ('oa3', {'R': 1.574, 'z': 1.164}),
            ('oa2', {'R': 1.544, 'z': 1.176}),
            ('oa1', {'R': 1.515, 'z': 1.188})])
        InnerUpper = OrderedDict([
            ('oi1', {'R': 1.477, 'z': 1.172}),
            ('oi2', {'R': 1.460, 'z': 1.162}),
            ('oi3', {'R': 1.443, 'z': 1.153}),
            ('oi4', {'R': 1.427, 'z': 1.144}),
            ('oi5', {'R': 1.410, 'z': 1.135}),
            ('oi6', {'R': 1.377, 'z': 1.116}),
            ('oi7', {'R': 1.360, 'z': 1.107}),
            ('oi8', {'R': 1.344, 'z': 1.098})])

        fig, ax = mpl.pylab.subplots(figsize=(6, 4), nrows=1, ncols=1)
        fig.subplots_adjust(bottom=0.2, top=0.95, right=0.95, left=0.2)
        c = mds.Connection('localhost:8001')
        # computation of outer target integrated ion flux
        outDivSignal = np.asarray([])
        neTime = c.get(
            'dim_of(augsignal({}, "LSD", "ne-{}"))'.format(
                shot, 'ua1')).data()
        for i, s in enumerate(OuterLower.keys()):
            _ne = c.get(
                'augsignal({}, "LSD", "ne-{}")'.format(shot, s)).data()
            _te = c.get(
                'augsignal({}, "LSD", "te-{}")'.format(shot, s)).data()
            _an = c.get(
                'augsignal({}, "LSD", "ang-{}")'.format(shot, s)).data()
            _cs = np.sqrt(constants.e * 4 * _te / (2 * constants.m_p))
            # this is the ion flux
            _s = _ne * _cs * np.abs(np.sin(np.radians(_an)))

            if i == 0:
                outDivSignal = _s
            else:
                outDivSignal = np.vstack((outDivSignal,
                                          _s))
        # now we compute the total integrate ion flux
        outTarget = np.zeros(neTime.size)
        for i in range(neTime.size):
            # _x = np.asarray([OuterLower[k]['s']
            #                  for k in OuterLower.keys()])
            _xr = np.asarray([OuterLower[k]['R']
                              for k in OuterLower.keys()])
            _zr = np.asarray([OuterLower[k]['z']
                              for k in OuterLower.keys()])
            _x = np.sqrt(np.power(_xr, 2) + np.power(_zr, 2))
            _r = np.asarray([OuterLower[k]['R']
                                 for k in OuterLower.keys()])
            _y = outDivSignal[:, i]
            indices = ~(np.isnan(_x) | np.isnan(_y))
            # _dummy = np.vstack((_x, _y)).transpose()
            # _dummy = _dummy[~np.isnan(_dummy).any(1)]
            _x = _x[indices]
            _y = _y[indices]
            # _dummy = np.vstack((_x, _y)).transpose()
            # _dummy = _dummy[~np.isnan(_dummy).any(1)]
            # _x = _dummy[:, 0]
            # _y = _dummy[:, 1][np.argsort(_x)]
            _x = np.sort(_x)
            outTarget[i] = 2 * np.pi * _r.mean() * np.trapz(
                _y, x=_x)
        ax.plot(neTime, bn.move_mean(outTarget,200)/1e22,'-',color='#182E58')
        ax.text(0.1,0.9,'Outer Lower target', color='#182E58', transform=ax.transAxes)
        # now repeat for upper target
        neTimeU = c.get(
            'dim_of(augsignal({}, "LSD", "ne-{}"))'.format(
                shot, 'oa1')).data()
        for i, s in enumerate(OuterUpper.keys()):
            _ne = c.get(
                'augsignal({}, "LSD", "ne-{}")'.format(shot, s)).data()
            _te = c.get(
                'augsignal({}, "LSD", "te-{}")'.format(shot, s)).data()
            _an = c.get(
                'augsignal({}, "LSD", "ang-{}")'.format(shot, s)).data()
            _cs = np.sqrt(constants.e * 4 * _te / (2 * constants.m_p))
            # this is the ion flux
            _s = _ne * _cs * np.abs(np.sin(np.radians(_an)))

            if i == 0:
                outDivSignal = _s
            else:
                outDivSignal = np.vstack((outDivSignal,
                                          _s))
        # now we compute the total integrate ion flux
        upTarget = np.zeros(neTime.size)
        for i in range(neTime.size):
            _xr = np.asarray([OuterUpper[k]['R']
                             for k in OuterUpper.keys()])
            _zr = np.asarray([OuterUpper[k]['z']
                             for k in OuterUpper.keys()])
            _x = np.sqrt(np.power(_xr,2) + np.power(_zr,2))
            _r = np.asarray([OuterUpper[k]['R']
                             for k in OuterUpper.keys()])
            _y = outDivSignal[:, i]
            indices = ~(np.isnan(_x) | np.isnan(_y))
            # _dummy = np.vstack((_x, _y)).transpose()
            # _dummy = _dummy[~np.isnan(_dummy).any(1)]
            _x = _x[indices]
            _y = _y[indices]
            # _dummy = np.vstack((_x, _y)).transpose()
            # _dummy = _dummy[~np.isnan(_dummy).any(1)]
            # _x = _dummy[:, 0]
            # _y = _dummy[:, 1][np.argsort(_x)]
            _x = np.sort(_x)
            upTarget[i] = 2 * np.pi * _r.mean() * np.trapz(
                _y, x=_x)
        ax.plot(neTimeU, bn.move_mean(upTarget,200)/1e22,'-',color='#F27C1B')
        ax.text(0.1,0.8,'Outer Upper target', color='#F27C1B', transform=ax.transAxes)
        ax.set_xlabel(r't[s]')
        ax.set_ylabel(r'[10$^{22}$ ion/s]')
        ax.set_ylim([0,1.2])
        # sign the timing used for the profiles and the THB investigation
        tRangesL = ((1.95, 2.1), (2.45, 2.6), (3.09, 3.2))
        colorL = ('#00D3E6', '#8ABA07', '#BC2764')
        for _t,_c in zip(tRangesL, colorL):
            ax.axvline(np.asarray(_t).mean(),ls='--', color=_c)
        fig.savefig('../pdfbox/UpperLowerIntegratedFluxShot{}.pdf'.format(shot),
                    bbox_to_inches='tight')

    elif selection == 3:
        shot = 35879
        tRangesL = ((1.95, 2.1), (2.45, 2.6), (3.05, 3.2))
        colorL = ('#00D3E6', '#8ABA07', '#BC2764')
        sel_PMT = 'PMT1'
        sel_wavelen = 587
        conn = mds.Connection('localhost:8001')
        # edge Data
        eN = conn.get(
            'augsignal({}, "TOT", "H-5_corr")'.format(shot)).data() / 1e20
        time = conn.get(
            'dim_of(augsignal({}, "TOT", "H-5_corr")'.format(
                shot) + ')').data()
        fig, ax = mpl.pylab.subplots(figsize=(6, 4), nrows=1, ncols=1)
        fig.subplots_adjust(bottom=0.2, top=0.95, right=0.95, left=0.2)
        fig2, ax2 = mpl.pylab.subplots(figsize=(6, 4), nrows=1, ncols=1)
        fig2.subplots_adjust(bottom=0.2, top=0.95, right=0.95, left=0.2)
        fig3, ax3 = mpl.pylab.subplots(figsize=(6,8), nrows=2, ncols=1)
        fig3. subplots_adjust(hspace=0.3, left=0.2, bottom=0.12,top=0.96,right=0.95)
        DataAUG = pd.read_csv('/Users/vianello/Documents/Fisica/Conferences/IAEA/iaea2018//data/aug/LModeBlobDatabase.csv')
        shotListAug = (34102, 34104, 34105, 34106)
        DataAUG = DataAUG[DataAUG['shots'].isin(shotListAug)]
        ax.errorbar(DataAUG['<n_e^e>']/DataAUG['n/nG'],
                    DataAUG['Size [rhos]'] * DataAUG['Rhos'] * 2*np.sqrt(np.log(2)) * 1e3,
                    yerr= DataAUG['Size Err [rhos]']* DataAUG['Rhos'] * 2*np.sqrt(np.log(2)) * 1e3,
                    fmt='o', ms=15, color='#182E58')
        for _t, _c in zip(tRangesL, colorL):
            _idx = np.where((time >= _t[0]) & (time <= _t[1]))[0]
            nG = float(0.8) / (np.pi * np.power(0.5, 2))
            _x = eN[_idx].mean()/nG
            # load the THB object
            myObj = myThbObject('../data/THB/filament_data/%i_t_%0.3f_%0.3f_%s'
                                                % (shot, _t[0], _t[1], sel_PMT))
            ax.plot(_x, myObj.rad_corr_len*1e3,'*', ms=15, color='#F27C1B')
            _y = myObj.velocity_all/1e3
            sns.distplot(_y[~np.isnan(_y)], bins=None,color=_c, kde=True,
                        ax=ax2,label=r'n$^e$/n$_G$ = {:.2f}'.format(_x))
            ax3[0].plot(_x,myObj.rad_corr_len*1e3,'*', ms=18,color=_c)
            sns.distplot(_y[~np.isnan(_y)], bins=None, color=_c, kde=True,
                         ax=ax3[1], label=r'n$^e$/n$_G$ = {:.2f}'.format(_x))
        ax.text(0.6,5,'LSN Probe', color='#182E58')
        ax.text(0.6,3,'DN THB', color='#F27C1B')
        ax.set_ylabel(r'$\delta_b$ [mm]')
        ax.set_xlabel(r'n$_e^e$/n$_G$')
        ax3[0].set_ylim([0,10])
        ax3[0].set_ylabel(r'$\delta_b$ [mm]')
        ax3[0].set_xlabel(r'n$_e^e$/n$_G$')
        ax3[0].set_ylim([3,10])
        fig.savefig('../pdfbox/BlobSizeVsGreenwaldLSN-DN.pdf',bbox_to_inches='tight')
        ax2.set_xlabel(r'v$_r$ [km/s]')
        ax2.legend(loc='best', numpoints=1,frameon=False,fontsize=14)
        ax2.set_xlim([0, 1.2])
        ax3[1].set_xlabel(r'v$_r$ [km/s]')
        ax3[1].legend(loc='best', numpoints=1,frameon=False,fontsize=14)
        ax3[1].set_xlim([0, 1.2])
        fig2.savefig('../pdfbox/VelocityDistributionTHBShot{}.pdf'.format(shot),bbox_to_inches='tight')
        fig3.savefig('../pdfbox/BlobVelocityDistributionTHBShot{}.pdf'.format(shot),bbox_to_inches='tight')
    elif selection == 4:
        shotList = (33339, 35879)
        trangeList = (((2.59, 2.60), (4.93, 4.96)),
                      ((2.45, 2.6), (2.94, 2.98)))
        colorList = ('#AC0D2B', '#0E1259')
        fig, ax = mpl.pylab.subplots(figsize=(6,9), nrows=2,ncols=1)
        fig.subplots_adjust(hspace=0.05,left=0.2,top=0.95,bottom=0.12)
        for i in np.arange(2,dtype='int'):
            ax[i].xaxis.set_minor_locator(AutoMinorLocator())
            ax[i].yaxis.set_major_locator(
                mpl.ticker.LogLocator(base=10.0, numticks=15,
                                      subs=(1, 2, 3, 4, 5, 6, 7, 8, 9)))
            ax[i].set_xlim([0.98, 1.1])
            ax[i].set_ylim([5e-2, 3])
            ax[i].set_ylabel(r'n$_e$/n$_e (\rho=1)$')
        ax[0].tick_params(labelbottom=False)
        ax[1].set_xlabel(r'$\rho$')
        ax[0].text(0.1,0.15, r'#{} LSN'.format(shotList[0]),transform=ax[0].transAxes)
        ax[1].text(0.1,0.15, r'#{} DN'.format(shotList[1]),transform=ax[1].transAxes)
        conn = mds.Connection('localhost:8001')
        for _idxshot,(shot, tList) in enumerate(zip(shotList, trangeList)):
            eN = conn.get('augsignal({}, "TOT", "H-5_corr")'.format(shot)).data() / 1e20
            time = conn.get(
                'dim_of(augsignal({}, "TOT", "H-5_corr")'.format(shot) + ')').data()
            nG = 0.8 / (np.pi * np.power(0.5, 2))
            # read the Li_bea
            if shot == 33339:
                _s = 'augdiag(' + str(shot) + ',"LIN","ne")'
                _st = 'dim_of(augdiag(' + str(shot) + ',"LIN","ne"), 0)'
                _sr = 'dim_of(augdiag(' + str(shot) + ',"LIN","ne"), 1)'
            else:
                _s = 'augdiag(' + str(shot) + ',"LIN","ne", "LIBE")'
                _st = 'dim_of(augdiag(' + str(shot) + ',"LIN","ne", "LIBE"), 0)'
                _sr = 'dim_of(augdiag(' + str(shot) + ',"LIN","ne", "LIBE"), 1)'
            LiBes = conn.get(_s).data()
            LiTime = conn.get(_st).data()
            LiRho = conn.get(_sr).data()
            for _idxtr, (_tr, _col) in enumerate(zip(tList, colorList)):
                _idx = np.where((LiTime >= _tr[0]) & (LiTime <= _tr[1]))[0]
                _dummyTime = LiTime[_idx]
                _dummyLib = LiBes[:, _idx]
                _dummyRho = LiRho[:, _idx]
                xB = np.nanmean(_dummyRho, axis=1)
                xBE = np.nanstd(_dummyRho, axis=1)
                yB = np.nanmean(_dummyLib, axis=1)
                yBE = np.nanstd(_dummyLib, axis=1)
                yBE[~np.isfinite(yBE)] = np.mean(yBE[np.isfinite(yBE)])
                # now the fit
                xN = np.linspace(0.9, 1.1, 200)
                # be sure to include rho = 1
                xN = np.append(xN, 1)
                xN = xN[np.argsort(xN)]
                # perform the fit
                gp = gpr1dfusion.GibbsInverseGaussianFGPR1D(
                    xB, yB, yBE,
                    xe=xBE, nrestarts=100, length_scale=0.5,
                    epsilon=5.e-3, regularization_parameter=1)
                gp.GPRFit(xN)
                yFit, yFitE, dYrho, dYrhoE = gp.get_gp_results()
                enS = yFit[np.argmin(np.abs(xN - 1))]
                # determine the edge greenwald fraction
                _idx = np.where((time >= _tr[0]) & (time <= _tr[1]))[0]
                nLabel = np.nanmean(eN[_idx]) / nG
                ax[_idxshot].plot(_dummyRho, _dummyLib / enS, '.', ms=3, color=_col, alpha=0.3)
                ax[_idxshot].semilogy(xN, yFit / enS, '-', lw=2, color=_col)
                ax[_idxshot].fill_between(xN,
                                   (yFit - yFitE / 2) / enS,
                                   (yFit + yFitE / 2) / enS,
                                   facecolor=_col,
                                   edgecolor='none',
                                   alpha=0.3)
                ax[_idxshot].text(0.5, 0.92 - _idxtr * 0.1, r'n$_e^e$/n$_G$ = {0:.2f}'.format(nLabel),
                           transform=ax[_idxshot].transAxes, color=_col)
        fig.savefig('../pdfbox/CompareUpstreamShot{0}_{1}.pdf'.format(shotList[0], shotList[1]),
                    bbox_to_inches='tight')

    elif selection == 99:
        mpl.pylab.close('all')
        loop = False
    else:
        input("Unknown Option Selected!")