# -*- coding: utf-8 -*-
from __future__ import division, unicode_literals, print_function

# Qt
try:
    from PySide import QtCore, QtGui
    fmode = 1
except ImportError:
    try:
        from PyQt4 import QtCore, QtGui
        fmode = 2
    except ImportError:
        msg = 'Failed to import PySide or PyQt4'
        raise ImportError(msg)
assert fmode in [1, 2]

# standard library
import sys
import os.path
import cgi #  html lib
import datetime
import traceback
#import webbrowser
#webbrowser.open("http://xkcd.com/353/")

# 3rd party
from numpy import ndarray, amax, amin
import vtk
from vtk.qt4.QVTKRenderWindowInteractor import QVTKRenderWindowInteractor

# pyNastran
import pyNastran
from pyNastran.utils import print_bad_path
from pyNastran.utils.log import SimpleLogger
from pyNastran.gui.formats import (NastranIO, Cart3dIO, PanairIO, LaWGS_IO, STL_IO, TetgenIO, Usm3dIO, Plot3d_io,
    is_nastran, is_cart3d, is_panair, is_lawgs, is_stl, is_tetgen, is_usm3d, is_plot3d)
from pyNastran.gui.arg_handling import get_inputs

pkg_path = pyNastran.__path__[0]
script_path = os.path.join(pkg_path, 'gui', 'scripts')
icon_path = os.path.join(pkg_path, 'gui', 'icons')

# tcolorpick.png and tabout.png trefresh.png icons on LGPL license, see
# http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/color-picker-grey.png
# http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/help-hint.png
# http://openiconlibrary.sourceforge.net/gallery2/?./Icons/actions/view-refresh-8.png

# kills the program when you hit Cntl+C from the command line
import signal
signal.signal(signal.SIGINT, signal.SIG_DFL)

class MainWindow(QtGui.QMainWindow, NastranIO, Cart3dIO, PanairIO, LaWGS_IO, STL_IO, TetgenIO, Usm3dIO, Plot3d_io):
    def __init__(self, inputs):
        QtGui.QMainWindow.__init__(self)

        NastranIO.__init__(self)
        Cart3dIO.__init__(self)
        PanairIO.__init__(self)
        LaWGS_IO.__init__(self)
        STL_IO.__init__(self)
        TetgenIO.__init__(self)
        Usm3dIO.__init__(self)
        Plot3d_io.__init__(self)

        settings = QtCore.QSettings()

        self.Title = None
        self.Title_overwrite = None
        self.min_value = None
        self.max_value = None
        self.blue_to_red = False
        self.nvalues = 9

        #-------------
        # inputs dict
        self.is_edges = inputs['is_edges']
        self.is_nodal = inputs['is_nodal']
        self.is_centroidal = inputs['is_centroidal']
        self.magnify = inputs['magnify']
        assert self.is_centroidal != self.is_nodal, "is_centroidal and is_nodal can't be the same and are set to \"%s\"" % self.is_nodal
        format = inputs['format']  # the active format loaded into the gui
        input = inputs['input']
        output = inputs['output']
        script = inputs['script']

        #self.format = ''
        debug = inputs['debug']
        self.debug = debug
        assert debug in [True, False], 'debug=%s' % debug
        shots = inputs['shots']
        if shots is None:
            shots = []

        #-------------
        # file
        self.format = None
        self.infile_name = None
        self.out_filename = None
        self.dirname = ''
        self.last_dir = '' # last visited directory while opening file

        #-------------
        # internal params
        self.show_info = True
        self.show_debug = True
        self.show_gui = True
        self.show_command = True

        self.nCases = 0
        self.iCase = 0
        self.nNodes = 0
        self.nElements = 0

        #-------
        # vtk actors

        self.grid = vtk.vtkUnstructuredGrid()
        #gridResult = vtk.vtkFloatArray()

        self.grid2 = vtk.vtkUnstructuredGrid()
        #self.emptyResult = vtk.vtkFloatArray()
        #self.vectorResult = vtk.vtkFloatArray()

        # edges
        self.edgeActor = vtk.vtkActor()
        self.edgeMapper = vtk.vtkPolyDataMapper()

        # cell picker
        self.cell_picker = vtk.vtkCellPicker()
        self.cell_picker.SetTolerance(0.0005)

        # scalar bar
        self.scalarBar = vtk.vtkScalarBarActor()

        #-------------
        # logging

        self.log = SimpleLogger('debug', lambda x, y: self.logg_msg(x, y))
        # logging needs synchronizing, so the messages from different threads
        # would not be interleave
        self.log_mutex = QtCore.QReadWriteLock()

        #-------------
        # build GUI and restore saved application state
        self.restoreGeometry(settings.value("mainWindowGeometry").toByteArray())
        self.background_col = settings.value("backgroundColor", (0.1, 0.2, 0.4)).toPyObject()

        self.init_ui()
        self.vtk_interactor.SetPicker(self.cell_picker)

        self.restoreState(settings.value("mainWindowState").toByteArray())

        #-------------
        # loading
        self.show()

        #inputs['format'] = 'nastran'
        #inputs['input'] = 'solid_bending.bdf'
        self.load_batch_inputs(inputs)
        #self.on_load_geometry('solid_bending.bdf', 'nastran')
        #self.on_load_results('solid_bending.op2')
        #self.vtk_interactor.Modified()

        if shots:
        #for shot in shots:
            self.on_take_screenshot(shots)
            sys.exit('took screenshot %r' % shots)

        if script:
            self.on_run_script(script)

    def on_cell_picker(self):
        worldPosition = self.cell_picker.GetPickPosition()
        cell_id = self.cell_picker.GetCellId()
        ds = self.cell_picker.GetDataSet()
        self.log_command("on_cell_picker()")
        self.log_info("worldPosition = %s" % str(worldPosition))
        self.log_info("cell_id = %s" % cell_id)
        self.log_info("data_set = %s" % ds)

    def load_batch_inputs(self, inputs):
        if not inputs['format']:
            return
        form = inputs['format'].lower()
        input = inputs['input']
        output = inputs['output']
        is_failed = self.on_load_geometry(input, form)
        if is_failed:
            return
        if output:
            print("format=%r" % format)
            print("output=%r" % output)
            self.on_load_results(output)
        self._simulate_key_press('r')
        self.vtk_interactor.Modified()

    def logg_msg(self, typ, msg):
        """
        Add message to log widget trying to choose right color for it.
        @param msg message to be displayed
        """
        _fr =  sys._getframe(4)  # jump to get out of the logger code
        n = _fr.f_lineno
        fn = os.path.basename(_fr.f_globals['__file__'])

        if typ == 'DEBUG' and not self.show_debug:
            return
        elif typ == 'INFO' and not self.show_info:
            return
        elif typ == 'GUI' and not self.show_gui:
            return
        elif typ == 'COMMAND' and not self.show_command:
            return

        msg = '   fname=%-25s lineNo=%-4s   %s\n' % (fn, n, msg)

        tim = datetime.datetime.now().strftime('[%d-%m-%Y %H:%M:%S]')
        msg = cgi.escape(msg)
        #message colors
        dark_orange = '#EB9100'
        cols = {"GUI": "blue", "COMMAND":"green", "GUI ERROR":"Crimson", "DEBUG" : dark_orange}
        msg = msg.rstrip().replace('\n', '
')
        msg = tim + ' ' + (typ + ': ' + msg) if typ else msg
        if typ in cols:
            msg = ' %s ' % (cols[typ], msg)

        self.log_mutex.lockForWrite()
        text_cursor = self.log_widget.textCursor()
        end = text_cursor.End
        #print("end", end)
        text_cursor.movePosition(end)
        #print dir(text_cursor)
        text_cursor.insertHtml(msg + r"
")
        self.log_widget.ensureCursorVisible() # new message will be visible
        self.log_mutex.unlock()

    def log_info(self, msg):
        """ Helper funtion: log a messaage msg with a 'GUI:' prefix """
        self.log.simple_msg(msg, 'GUI')

    def log_command(self, msg):
        """ Helper funtion: log a messaage msg with a 'GUI:' prefix """
        self.log.simple_msg(msg, 'COMMAND')

    def log_error(self, msg):
        """ Helper funtion: log a messaage msg with a 'GUI:' prefix """
        self.log.simple_msg(msg, 'GUI ERROR')

    def change_background_col(self):
        """ Choose a background color """
        c =  [int(255 * i) for i in self.background_col]
        col = QtGui.QColorDialog.getColor(QtGui.QColor(*c), self, "Choose a background color")
        if col.isValid():
            self.background_col = col.getRgbF()[:3]
            self.rend.SetBackground(*self.background_col)

    def about_dialog(self):
        """ Display about dialog """
        about = [
            'pyNastran QT GUI',
            '',
            'pyNastran v%s' % pyNastran.__version__,
            pyNastran.__copyright__,
            pyNastran.__author__,
            '',
            '%s' % pyNastran.__website__,
            '',
            'Mouse',
            'Left Click - Rotate',
            'Middle Click - Pan/Recenter Rotation Point',
            'Shift + Left Click - Pan/Recenter Rotation Point',
            'Right Mouse - Zoom',
            '',
            'Keyboard Controls',
            'r   - reset camera view',
            'X/x - snap to x axis',
            'Y/y - snap to y axis',
            'Z/z - snap to z axis',
            '',
            #'h   - show/hide legend & info',
            'CTRL+I - take a screenshot (image)',
            #'L     - cycle op2 results',
            'm/M    - scale up/scale down by 1.1 times',
            'o/O    - rotate counter-clockwise/clockwise 5 degrees',
            's      - view model as a surface',
            'w      - view model as a wireframe',
        ]
        QtGui.QMessageBox.about(self, "About pyNastran GUI", "\n".join(about))

    def set_window_title(self, msg):
        msg2 = "pyNastran v%s - "  % pyNastran.__version__
        msg2 += msg
        self.setWindowTitle(msg)

    def init_ui(self):
        """ Initialize user iterface"""
        self.resize(800, 600)
        self.statusBar().showMessage('Ready')

        # windows title and aplication icon
        self.setWindowTitle('Statusbar')
        self.setWindowIcon(QtGui.QIcon(os.path.join(icon_path, 'logo.png')))
        self.set_window_title('')

        #=========== Results widget ===================
        self.res_dock = QtGui.QDockWidget("Results", self)
        self.res_dock.setObjectName("results_obj")
        self.res_widget = QtGui.QTextEdit()
        self.res_widget.setReadOnly(True)
        self.res_dock.setWidget(self.res_widget)
        self.addDockWidget(QtCore.Qt.RightDockWidgetArea, self.res_dock)
        #=========== Logging widget ===================
        self.log_dock = QtGui.QDockWidget("Application log", self)
        self.log_dock.setObjectName("application_log")
        self.log_widget = QtGui.QTextEdit()
        self.log_widget.setReadOnly(True)
        self.log_dock.setWidget(self.log_widget)
        self.addDockWidget(QtCore.Qt.BottomDockWidgetArea, self.log_dock)
        #===============================================

        # right sidebar

        ## menubar
        self.menubar = self.menuBar()
        self.menu_file = self.menubar.addMenu('&File')
        self.menu_view = self.menubar.addMenu('&View')
        self.menu_window = self.menubar.addMenu('&Window')
        self.menu_help = self.menubar.addMenu('&Help')
        self.menu_scripts = self.menubar.addMenu('&Scripts')

        ## toolbar
        self.toolbar = self.addToolBar('Show toolbar')
        self.toolbar.setObjectName('main_toolbar')

        # prepare actions that will  be used in application
        actions = {}
        #pth = os.path.join(icon_path, 'tbdf.png')
        pth = os.path.join(icon_path, 'tbdf.png')
        #print print_bad_path(pth)

        # http://docs.python.org/2/library/sys.html#sys.platform
        #System  platform value
        #Linux (2.x and 3.x) 'linux2'
        #Windows 'win32'
        #Windows/Cygwin  'cygwin'
        #Mac OS X    'darwin'
        #print sys.platform
        #quit_key = 'Alt+F4' if sys.platform in ['win32', 'cygwin'] else 'Ctrl+Q'

        checkables = ['show_info', 'show_debug', 'show_gui', 'show_command']
        scripts = [script for script in os.listdir(script_path) if '.py' in script ]
        scripts = tuple(scripts)
        print('script_path =', script_path)
        print('scripts =', scripts)

        tools = [
          ('exit', '&Exit', os.path.join(icon_path, 'texit.png'), 'Ctrl+Q', 'Exit application', QtGui.qApp.quit),
          ('load_geometry', 'Load &Geometry', os.path.join(icon_path, 'load_geometry.png'), 'Ctrl+O', 'Loads a geometry input file', self.on_load_geometry),  ## @todo no picture...
          ('load_results', 'Load &Results',   os.path.join(icon_path, 'load_results.png'), 'Ctrl+R', 'Loads a results file', self.on_load_results),  ## @todo no picture...
          ('back_col', 'Change background color', os.path.join(icon_path, 'tcolorpick.png'), None, 'Choose a background color', self.change_background_col),

          ('wireframe', 'Wireframe Model', os.path.join(icon_path, 'twireframe.png'), 'w', 'Show Model as a Wireframe Model', self.on_wireframe),
          ('surface', 'Surface Model', os.path.join(icon_path, 'tsolid.png'), 's', 'Show Model as a Surface Model', self.on_surface),
          ('edges', 'Show/Hide Edges', os.path.join(icon_path, 'tedges.png'), 'e', 'Show/Hide Model Edges', self.onFlipEdges),

          ('show_info', 'Show INFO', os.path.join(icon_path, 'show_info.png'), None, 'Show "INFO" messages', self.on_show_info),
          ('show_debug', 'Show DEBUG', os.path.join(icon_path, 'show_debug.png'), None, 'Show "DEBUG" messages', self.on_show_debug),
          ('show_gui', 'Show GUI', os.path.join(icon_path, 'show_gui.png'), None, 'Show "GUI" messages', self.on_show_gui),
          ('show_command', 'Show COMMAND', os.path.join(icon_path, 'show_command.png'), None, 'Show "COMMAND" messages', self.on_show_command),

          ('magnify', 'Magnify', os.path.join(icon_path, 'plus_zoom.png'), 'M', 'Increase Magnfication', self.on_increase_magnification),
          ('shrink', 'Shrink', os.path.join(icon_path, 'minus_zoom.png'), 'm', 'Decrease Magnfication', self.on_decrease_magnification),

          ('cell_pick', 'Cell Pick', '', 'CTRL+K', 'PickTip', self.on_cell_picker),

          ('rotate_clockwise', 'Rotate Clockwise', os.path.join(icon_path, 'tclock.png'), 'o', 'Rotate Clockwise', self.on_rotate_clockwise),
          ('rotate_cclockwise', 'Rotate Counter-Clockwise', os.path.join(icon_path, 'tcclock.png'), 'O', 'Rotate Counter-Clockwise', self.on_rotate_cclockwise),

          ('scshot', 'Take a Screenshot', os.path.join(icon_path, 'tcamera.png'), 'CTRL+I', 'Take a Screenshot of current view', self.take_screenshot),
          ('about', 'About pyNastran GUI', os.path.join(icon_path, 'tabout.png'), 'CTRL+H', 'About pyNastran GUI and help on shortcuts', self.about_dialog),
          ('creset', 'Reset camera view', os.path.join(icon_path, 'trefresh.png'), 'r', 'Reset the camera view to default', self.on_reset_camera),
          ('reload', 'Reload model', os.path.join(icon_path, 'treload.png'), 'r', 'Reload the model', self.on_reload),

          ('cycle_res', 'Cycle Results', os.path.join(icon_path, 'cycle_results.png'), 'CTRL+L', 'Changes the result case', self.cycleResults),

          ('x', 'Flips to +X Axis', os.path.join(icon_path, 'plus_x.png'), 'x', 'Flips to +X Axis', lambda: self.update_camera('+x')),
          ('y', 'Flips to +Y Axis', os.path.join(icon_path, 'plus_y.png'), 'y', 'Flips to +Y Axis', lambda: self.update_camera('+y')),
          ('z', 'Flips to +Z Axis', os.path.join(icon_path, 'plus_z.png'), 'z', 'Flips to +Z Axis', lambda: self.update_camera('+z')),

          ('X', 'Flips to -X Axis', os.path.join(icon_path, 'minus_x.png'), 'X', 'Flips to -X Axis', lambda: self.update_camera('-x')),
          ('Y', 'Flips to -Y Axis', os.path.join(icon_path, 'minus_y.png'), 'Y', 'Flips to -Y Axis', lambda: self.update_camera('-y')),
          ('Z', 'Flips to -Z Axis', os.path.join(icon_path, 'minus_z.png'), 'Z', 'Flips to -Z Axis', lambda: self.update_camera('-z')),
          ('script', 'Run Python script', os.path.join(icon_path, 'python.png'), None, 'Runs pyNastranGUI in batch mode', self.on_run_script),
        ]
        for script in scripts:
            fname = os.path.join(script_path, script)
            tool = (script, script, os.path.join(icon_path, 'python.png'), None, '', self.on_run_script )
            tools.append(tool)

        for (nam, txt, icon, shortcut, tip, func) in tools:
            #print "name=%s txt=%s icon=%s short=%s tip=%s func=%s" % (nam, txt, icon, short, tip, func)
            #if icon is None:
                #print "missing_icon = %r!!!" % nam
                #icon = os.path.join(icon_path, 'no.png')

            if icon is None:
                print("missing_icon = %r!!!" % nam)
                #print print_bad_path(icon)
            #elif not "/" in icon:
                #ico = QtGui.QIcon.fromTheme(icon)
            else:
                ico = QtGui.QIcon()
                ico.addPixmap(QtGui.QPixmap(icon), QtGui.QIcon.Normal, QtGui.QIcon.Off)

            if nam in checkables:
                actions[nam] = QtGui.QAction(ico, txt, self, checkable=True)
                actions[nam].setChecked(True)
            else:
                actions[nam] = QtGui.QAction(ico, txt, self)

            if shortcut:
                actions[nam].setShortcut(shortcut)
            if tip:
                actions[nam].setStatusTip(tip)
            if func:
                actions[nam].triggered.connect(func)

        actions['toolbar'] = self.toolbar.toggleViewAction()
        actions['toolbar'].setStatusTip("Show/Hide application toolbar")

        actions['reswidget'] = self.res_dock.toggleViewAction()
        actions['reswidget'].setStatusTip("Show/Hide results selection")

        actions['logwidget'] = self.log_dock.toggleViewAction()
        actions['logwidget'].setStatusTip("Show/Hide application log")

        menu_items = [(self.menu_file, ('load_geometry', 'load_results', 'script', '', 'exit')),
                      (self.menu_view,  ('scshot', '', 'wireframe', 'surface', 'creset', '', 'back_col', '', 'show_info', 'show_debug', 'show_gui', 'show_command')),
                      (self.menu_window,('toolbar', 'reswidget', 'logwidget' )),
                      (self.menu_help,  ('about',)),
                      (self.menu_scripts, scripts),
                      (self.toolbar, ('cell_pick', 'reload', 'load_geometry', 'load_results', 'cycle_res',
                                      'x', 'y', 'z', 'X', 'Y', 'Z',
                                      'magnify', 'shrink', 'rotate_clockwise', 'rotate_cclockwise',
                                      'wireframe', 'surface', 'edges', 'creset', 'scshot', '', 'exit'))]
        # populate menus and toolbar
        for menu, items in menu_items:
            for i in items:
                if not i:
                    menu.addSeparator()
                else:
                    menu.addAction(actions[i] if isinstance(i, basestring) else i())
        self.res_dock.hide()

        #Frame that VTK will render on
        vtk_frame = QtGui.QFrame()
        vtk_hbox  = QtGui.QHBoxLayout()
        vtk_hbox.setContentsMargins(2, 2, 2, 2)

        #Qt VTK RenderWindowInteractor
        self.vtk_interactor = QVTKRenderWindowInteractor(parent = vtk_frame)
        vtk_hbox.addWidget(self.vtk_interactor)
        vtk_frame.setLayout(vtk_hbox)
        vtk_frame.setFrameStyle(QtGui.QFrame.NoFrame | QtGui.QFrame.Plain)
        # this is our main, 'central' widget
        self.setCentralWidget(vtk_frame)

        #=============================================================
        self.rend = vtk.vtkRenderer()
        self.vtk_interactor.GetRenderWindow().AddRenderer(self.rend)
        self.vtk_interactor.GetRenderWindow().Render()
        #self.load_nastran_geometry(None, None)
        self.textActors = {}

        self.addGeometry()
        self.addAltGeometry()
        self.rend.GetActiveCamera().ParallelProjectionOn()
        self.rend.SetBackground(*self.background_col)
        self.rend.ResetCamera()
        self._simulate_key_press('t') # change mouse style to trackball
        self.build_lookup_table()

        self.magnify = 1
        self.iText = 0
        textSize = 14 * self.magnify
        self.createText([5, 50], 'Max  ', textSize)  # text actor 0
        self.createText([5, 35], 'Min  ', textSize)  # text actor 1
        self.createText([5, 20], 'Word1', textSize)  # text actor 2
        self.createText([5, 5], 'Word2', textSize)  # text actor 3

        self.get_edges()
        if self.is_edges:
            prop = self.edgeActor.GetProperty()
            prop.EdgeVisibilityOn()
        else:
            prop = self.edgeActor.GetProperty()
            prop.EdgeVisibilityOff()

    #def _script_helper(self, python_file=False):
        #if python_file in [None, False]:
            #self.on_run_script(python_file)

    def on_run_script(self, python_file=False):
        if python_file in [None, False]:
            Title = 'Choose a Python Script to Run'
            wildcard = "Python (*.py)"
            wildcard_index, infile_name = self._create_load_file_dialog(wildcard, Title)
            if not infile_name:
                is_failed = True
                return is_failed # user clicked cancel

            python_file = os.path.join(script_path, infile_name)
        execfile(python_file)
        self.log_command('self.on_run_script(%r)' % python_file)

    def on_show_info(self):
        self.show_info = not(self.show_info)

    def on_show_debug(self):
        self.show_debug = not(self.show_debug)

    def on_show_gui(self):
        self.show_gui = not(self.show_gui)

    def on_show_command(self):
        self.show_command = not(self.show_command)

    def on_reset_camera(self):
        self.log_command('on_reset_camera()')
        self._simulate_key_press('r')

    def on_surface(self):
        self.log_command('on_surface()')
        self._simulate_key_press('s')

    def on_wireframe(self):
        self.log_command('on_wireframe()')
        self._simulate_key_press('w')

    def _update_camera(self, camera=None):
        if camera is None:
            camera = self.GetCamera()
        camera.Modified()
        self.vtk_interactor.Render()

    def zoom(self, value):
        camera = self.GetCamera()
        camera.Zoom(value)
        camera.Modified()
        self.vtk_interactor.Render()
        self.log_command('zoom(%s)' % value)
        #except Exception as e:
            #self.log_error(str(e))

    def rotate(self, rotate_deg):
        camera = self.GetCamera()
        camera.Roll(-rotate_deg)
        camera.Modified()
        self.vtk_interactor.Render()
        self.log_command('rotate(%s)' % rotate_deg)

    def on_rotate_clockwise(self):
        self.rotate(15.0)

    def on_rotate_cclockwise(self):
        self.rotate(-15.0)

    def on_increase_magnification(self):
        self.zoom(1.1)

    def on_decrease_magnification(self):
        self.zoom(1.0/1.1)

    def onFlipEdges(self):
        self.is_edges = not(self.is_edges)
        self.edgeActor.SetVisibility(self.is_edges)
        #self.edgeActor.GetProperty().SetColor(0, 0, 0)  # cart3d edge color isn't black...
        self.edgeActor.Modified()
        #self.widget.Update()
        self._update_camera()
        #self.refresh()
        self.log_command('onFlipEdges()')

    def get_edges(self):
        """
        ..todo:: For some reason, the edge color is set to the parent
        surface's color instead of black
        """
        edges = vtk.vtkExtractEdges()
        edges.SetInput(self.grid)
        self.edgeMapper.SetInput(edges.GetOutput())

        self.edgeActor.SetMapper(self.edgeMapper)
        self.edgeActor.GetProperty().SetColor(0, 0, 0)

        prop = self.edgeActor.GetProperty()
        prop.SetColor(0, 0, 0)
        self.edgeActor.SetVisibility(self.is_edges)
        self.rend.AddActor(self.edgeActor)

    def createText(self, position, label, textSize=18, movable=False):
        txt = vtk.vtkTextActor()
        txt.SetInput(label)
        txtprop = txt.GetTextProperty()
        #txtprop.SetFontFamilyToArial()
        txtprop.SetFontSize(textSize)
        txtprop.SetColor(1, 1, 1)
        txt.SetDisplayPosition(*position)

        #print "dir(text) = ",dir(txt)
        txt.VisibilityOff()

        #txt.SetDisplayPosition(5,5) # bottom left
        #txt.SetDisplayPosition(5,95)
        #txt.SetPosition(0.1,0.5)

        # assign actor to the renderer
        self.rend.AddActor(txt)
        self.textActors[self.iText] = txt
        self.iText += 1

    def TurnTextOff(self):
        for (i, text) in self.textActors.iteritems():
            text.VisibilityOff()

    def TurnTextOn(self):
        for (i, text) in self.textActors.iteritems():
            text.VisibilityOn()

    def build_lookup_table(self):
        self.colorFunction = vtk.vtkColorTransferFunction()
        self.colorFunction.SetColorSpaceToHSV()
        self.colorFunction.HSVWrapOff()

        drange = [10., 20.]
        # blue - low
        # red - high
        self.colorFunction.AddRGBPoint(drange[0], 0.0, 0.0, 1.0)
        self.colorFunction.AddRGBPoint(drange[1], 1.0, 0.0, 0.0)

        self.scalarBar.SetTitle("Title1")
        self.scalarBar.SetLookupTable(self.colorFunction)
        self.scalarBar.SetOrientationToVertical()

        self.scalarBar.SetHeight(0.9)
        self.scalarBar.SetWidth(0.20)  # the width is set first
        # after the width is set, this is adjusted
        self.scalarBar.SetPosition(0.77, 0.1)

        propTitle = vtk.vtkTextProperty()
        propTitle.SetFontFamilyToArial()
        #propTitle.ItalicOff()
        propTitle.BoldOn()
        propTitle.ShadowOn()

        propLabel = vtk.vtkTextProperty()
        propLabel.BoldOff()
        propLabel.ShadowOn()

        scalar_range = self.grid.GetScalarRange()
        self.aQuadMapper.SetScalarRange(scalar_range)
        self.aQuadMapper.SetLookupTable(self.colorFunction)

        #self.scalarBar.SetTitleTextProperty(propTitle)
        #self.scalarBar.SetLabelTextProperty(propLabel)
        self.scalarBar.SetLabelFormat("%i")

        # allows 0-1 to be nice number when ranging values (gotta pick something)
        self.scalarBar.SetNumberOfLabels(11)
        self.scalarBar.SetMaximumNumberOfColors(11)

        #self.scalarBar.VisibilityOff()  # first load -> scalar bar off
        #self.scalarBar.ShadowOn()
        #self.scalarBar.RepositionableOn()
        self.rend.AddActor(self.scalarBar)
        self.scalarBar.VisibilityOff()
        #return scalarBar

    def on_reload(self):
        Title = self.Title
        if self.format == 'usm3d':
            self.step_results_usm3d()
        else:
            self.on_load_geometry(self.infile_name, self.format)

        msg = '%s - %s - %s' % (self.format, self.infile_name, self.out_filename)
        self.set_window_title(msg)
        #self.cycleResults(Title)
        for i in xrange(10):  #  limit on number of cycles
            if self.Title != Title:
                self.cycleResults(Title)
            else:
                break

    def on_load_geometry(self, infile_name=None, geometry_format=None):
        wildcard = ''
        is_failed = False
        if infile_name:
            geometry_format = geometry_format.lower()
            print("geometry_format = %r" % geometry_format)
            if geometry_format == 'nastran':
                has_results = True
                load_function = self.load_nastran_geometry
            elif geometry_format == 'cart3d':
                has_results = True
                load_function = self.load_cart3d_geometry
            elif geometry_format == 'panair':
                has_results = False
                load_function = self.load_panair_geometry
            elif geometry_format == 'lawgs':
                has_results = False
                load_function = None
            elif geometry_format == 'stl':
                has_results = False
                load_function = self.load_stl_geometry
            elif geometry_format == 'tetgen':
                has_results = False
                load_function = self.load_tetgen_geometry
            elif geometry_format == 'usm3d':
                has_results = False
                load_function = self.load_usm3d_geometry
            elif geometry_format == 'plot3d':
                has_results = False
                load_function = self.load_plot3d_geometry
            else:
                self.log_error('---invalid format=%r' % geometry_format)
                is_failed = True
                return is_failed
                raise NotImplementedError('on_load_geometry; infile_name=%r format=%r' % (infile_name, geometry_format))
            formats = [geometry_format]
            filter_index = 0
        else:
            formats = []
            load_functions = []
            has_results_list = []
            wildcard_list = []
            if is_nastran:
                wildcard_list.append("Nastran BDF (*.bdf; *.dat; *.nas)")
                formats.append('Nastran')
                has_results_list.append(True)
                load_functions.append(self.load_nastran_geometry)
                #load_functions.append(None)
            if is_cart3d:
                wildcard_list.append("Cart3d (*.tri; *.triq)")
                formats.append('Cart3d')
                has_results_list.append(True)
                load_functions.append(self.load_cart3d_geometry)
            if is_panair:
                wildcard_list.append("Panair (*.inp)")
                formats.append('Panair')
                has_results_list.append(True)
                load_functions.append(self.load_panair_geometry)
            if is_lawgs:
                wildcard_list.append("LaWGS (*.inp)")
                formats.append('LaWGS')
                has_results_list.append(False)
                load_functions.append(None)
            if is_stl:
                wildcard_list.append("STereoLithography (*.STL)")
                formats.append('STL')
                has_results_list.append(False)
                load_functions.append(None)
            if is_tetgen:
                wildcard_list.append("Tetgen (*.smesh)")
                formats.append('STL')
                has_results_list.append(False)
                load_functions.append(self.load_tetgen_geometry)
            if is_usm3d:
                wildcard_list.append("USM3D (*.cogsg; *.front)")
                formats.append('USM3D')
                has_results_list.append(True)
                load_functions.append(self.load_usm3d_geometry)
            if is_plot3d:
                wildcard_list.append("Plot3D (*.p3d; *.p3da)")
                formats.append('Plot3D')
                has_results_list.append(False)
                load_functions.append(self.load_plot3d_geometry)
            wildcard = ';;'.join(wildcard_list)

            # get the filter index and filename
            if infile_name is not None and geometry_format is not None:
                filter_index = formats.index(geometry_format)
            else:
                Title = 'Choose a Geometry File to Load'
                wildcard_index, infile_name = self._create_load_file_dialog(wildcard, Title)
                #print("infile_name = %r" % infile_name)
                #print("wildcard_index = %r" % wildcard_index)
                if not infile_name:
                    is_failed = True
                    return is_failed # user clicked cancel
                filter_index = wildcard_list.index(wildcard_index)

            geometry_format = formats[filter_index]
            load_function = load_functions[filter_index]
            has_results = has_results_list[filter_index]
            #return is_failed

        if load_function is not None:
            self.last_dir = os.path.split(infile_name)[0]

            self.grid.Reset()
            self.grid.Modified()
            self.grid2.Reset()
            self.grid2.Modified()
            #gridResult.Reset()
            #gridResult.Modified()

            if not os.path.exists(infile_name) and geometry_format:
                msg = 'input file=%r does not exist' % infile_name
                self.log_error(msg)
                return

            self.log_info("reading %s file %r" % (geometry_format, infile_name))
            try:
                has_results = load_function(infile_name, self.last_dir)
            except Exception as e:
                msg = traceback.format_exc()
                self.log_error(msg)
                raise
                #return
            #self.vtk_panel.Update()
            self.rend.ResetCamera()

        # the model has been loaded, so we enable load_results
        if filter_index >= 0:
            self.format = formats[filter_index].lower()
            if has_results:
                enable = True
            else:
                enable = False
            #self.load_results.Enable(enable)
        else: # no file specified
            return
        print("on_load_geometry(%r)" % infile_name)
        self.infile_name = infile_name

        if self.out_filename is not None:
            msg = '%s - %s - %s' % (self.format, self.infile_name, self.out_filename)
        else:
            msg = '%s - %s - %s' % (self.format, self.infile_name)
        self.set_window_title(msg)

        self.log_command("on_load_geometry(%r, %r)" % (infile_name, self.format))

    def _create_load_file_dialog(self, qt_wildcard, Title):
        # getOpenFileName return QString and we want Python string
        fname, wildcard_level = QtGui.QFileDialog.getOpenFileNameAndFilter(self, Title, self.last_dir, qt_wildcard)
        #print "d =", d # fname, wildcard_level
        #fname = str(QtGui.QFileDialog.getOpenFileName(self, Title, self.last_dir, wildcard))
        return str(wildcard_level), str(fname)

    def import_nastran_geometry(self, infile_name, geometry_format):
        """
        Load BDF file.
        """
        # getOpenFileName return QString and we want Python string
        fname = str(QtGui.QFileDialog.getOpenFileName(self, 'Open BDF file', self.last_dir,
        'Nastran BDF (*.bdf *.dat *.nas)'))

        if fname:
            self.last_dir = os.path.split(fname)[0]
            self.load_nastran_geometry(fname, self.last_dir)
            self.rend.ResetCamera()
            #self.set_window_title_msg(fname)

    def on_load_results(self, out_filename=None):
            geometry_format = self.format
            if self.format is None:
                msg ='on_load_results failed:  You need to load a file first...'
                self.log_error(msg)
                raise RuntimeError(msg)

            if out_filename in [None, False]:
                Title = 'Select a Results File for %s' % self.format
                if geometry_format == 'nastran':
                    has_results = True
                    #wildcard = "Nastran OP2 (*.op2);;Nastran PCH (*.pch);;Nastran F06 (*.f06)"
                    wildcard = "Nastran OP2 (*.op2)"
                    load_functions = [self.load_nastran_results]
                elif geometry_format == 'cart3d':
                    has_results = True
                    wildcard = "Cart3d (*.triq)"
                    load_functions = [self.load_cart3d_results]
                elif geometry_format == 'panair':
                    has_results = False
                    wildcard = "Panair (*.agps);;Panair (*.out)"
                    load_functions = [self.load_panair_results]
                elif geometry_format == 'lawgs':
                    has_results = False
                    load_functions = [None]
                elif geometry_format == 'stl':
                    has_results = False
                    load_functions = [None]
                elif geometry_format == 'tetgen':
                    has_results = False
                    load_functions = [None]
                elif geometry_format == 'usm3d':
                    wildcard = "Usm3d (*.flo)"
                    has_results = True
                    load_functions = [self.load_usm3d_results]
                elif geometry_format == 'plot3d':
                    has_results = False
                    load_functions = [None]
                else:
                    msg = 'format=%r is not supported' % geometry_format
                    self.log_error(msg)
                    raise RuntimeError(msg)
                #scard = wildcard.split(';;')
                #n = len(load_functions)
                #wildcard = ';;'.join(scard[:n])
                load_function = load_functions[0]

                wildcard_index, out_filename = self._create_load_file_dialog(wildcard, Title)
            else:
                if geometry_format == 'nastran':
                    load_function = self.load_nastran_results
                elif geometry_format == 'cart3d':
                    load_function = self.load_cart3d_results
                #elif geometry_format == 'panair':
                    #load_function = self.load_panair_results
                #elif geometry_format == 'lawgs':
                    #load_function = None
                #elif geometry_format == 'stl':
                    #load_function = None
                #elif geometry_format == 'tetgen':
                    #load_function = None
                elif geometry_format == 'usm3d':
                    load_function = self.load_usm3d_results
                #elif geometry_format == 'plot3d':
                    #load_function = None
                else:
                    msg = 'format=%r is not supported.  Did you load a geometry model?' % geometry_format
                    self.log_error(msg)
                    raise RuntimeError(msg)

            if out_filename == '':
                return
            if not os.path.exists(out_filename):
                msg = 'result file=%r does not exist' % out_filename
                self.log_error(msg)
                return
                #raise IOError(msg)
            self.last_dir = os.path.split(out_filename)[0]
            load_function(out_filename, self.last_dir)

            self.out_filename = out_filename
            msg = '%s - %s - %s' % (self.format, self.infile_name, out_filename)
            self.set_window_title(msg)
            print("on_load_results(%r)" % out_filename)
            self.out_filename = out_filename
            self.log_command("on_load_results(%r)" % out_filename)

    def load_op2(self):
        """
        Load OP2 file.
        @todo not done...
        """
        return self.on_load_results()

        # getOpenFileName return QString and we want Python string
        fname = str(QtGui.QFileDialog.getOpenFileName(self, 'Open OP2 file', self.last_dir, 'Nastran OP2 (*.op2)'))

        if fname:
            self.last_dir = os.path.split(fname)[0]
            self.load_nastran_results(fname, self.last_dir)
            self.rend.ResetCamera()

    def load_f06(self):
        """
        Load F06 file.
        @todo not done...
        """
        # getOpenFileName return QString and we want Python string
        fname = str(QtGui.QFileDialog.getOpenFileName(self, 'Open F06 file', self.last_dir, 'Nastran F06 (*.f06)'))

        if fname:
            self.last_dir = os.path.split(fname)[0]
            self.load_nastran_results(fname, self.last_dir)
            self.rend.ResetCamera()

    def take_screenshot(self):
        """ Take a screenshot of a current view and save as a file"""
        self.on_take_screenshot(None)

    def on_take_screenshot(self, fname):
        """ Take a screenshot of a current view and save as a file"""
        if fname is None:
            filt = QtCore.QString()
            default_filename = ''

            Title = ''
            if self.Title is not None:
                Title = self.Title

            if self.out_filename is None:
                base, ext = os.path.splitext(os.path.basename(self.infile_name))
                #default_filename = base
                default_filename = self.infile_name
            else:
                base, ext = os.path.splitext(os.path.basename(self.out_filename))
                default_filename = Title + '_' + base

            fname = str(QtGui.QFileDialog.getSaveFileName(self, ('Choose a file name'
                        'and type'), default_filename, ('PNG Image *.png (*.png);; JPEG Image '
                        '*.jpg *.jpeg (*.jpg, *.jpeg);; TIFF Image *.tif *.tiff '
                        '(*.tif, *.tiff);; BMP Image *.bmp (*.bmp);; PostScript '
                        'Document *.ps (*.ps)'), filt))
            #print("fname=%r" % fname)
            if fname is None or fname == '':  # 2nd option
                return
            flt = str(filt).split()[0]
        else:
            flt = 'png'

        if fname:
            renderLarge = vtk.vtkRenderLargeImage()
            renderLarge.SetInput(self.rend)
            renderLarge.SetMagnification(self.magnify)

            nam, ext = os.path.splitext(fname)
            ext = ext.lower()
            for nam, exts, ob in (('PostScript', ['.ps'], vtk.vtkPostScriptWriter),
                                  ("BMP", ['.bmp'], vtk.vtkBMPWriter),
                                  ('JPG', ['.jpg', '.jpeg'], vtk.vtkJPEGWriter),
                                  ("TIFF", ['.tif', '.tiff'], vtk.vtkTIFFWriter)):
                if flt == nam:
                    fname = fname if ext in exts else fname + exts[0]
                    writer = ob()
                    break
            else:
                fname = fname if ext == '.png' else fname + '.png'
                writer = vtk.vtkPNGWriter()

            writer.SetInputConnection(renderLarge.GetOutputPort())
            writer.SetFileName(fname)
            writer.Write()
            self.log_info("Saved screenshot: " + fname)

    def closeEvent(self, event):
        """
        Handling saving state before application when application is being closed.
        """
        settings = QtCore.QSettings()
        settings.setValue("main_WindowGeometry", self.saveGeometry())
        settings.setValue("mainWindowState", self.saveState())
        settings.setValue("backgroundColor", self.background_col)

    def _simulate_key_press(self, key):
        """
        A little hack method that simulates pressing the key for the VTK
        interactor. There is no easy way to instruct VTK to e.g. change mouse
        style to 'trackball' (as by pressing 't' key),
        (see http://public.kitware.com/pipermail/vtkusers/2011-November/119996.html)
        therefore we trick VTK to think that a key has been pressed.

        :param key: a key that VTK should be informed about, e.g. 't'
        """
        print("key = ", key)
        self.vtk_interactor._Iren.SetEventInformation(0, 0, 0, 0, key, 0, None)
        self.vtk_interactor._Iren.KeyPressEvent()
        self.vtk_interactor._Iren.CharEvent()

        #if key in ['y', 'z', 'X', 'Y', 'Z']:
            #self.update_camera(key)

    def addGeometry(self):
        self.aQuadMapper = vtk.vtkDataSetMapper()
        self.aQuadMapper.SetInput(self.grid)
        #aQuadMapper.SetInput(Filter.GetOutput())
        geometryActor = vtk.vtkActor()
        geometryActor.SetMapper(self.aQuadMapper)
        #geometryActor.AddPosition(2, 0, 2)
        #geometryActor.GetProperty().SetDiffuseColor(0, 0, 1) # blue
        geometryActor.GetProperty().SetDiffuseColor(1, 0, 0)  # red
        self.rend.AddActor(geometryActor)

    def addAltGeometry(self):
        self.aQuadMapper = vtk.vtkDataSetMapper()
        self.aQuadMapper.SetInput(self.grid2)
        #aQuadMapper.SetInput(Filter.GetOutput())
        geometryActor = vtk.vtkActor()
        geometryActor.SetMapper(self.aQuadMapper)
        #geometryActor.AddPosition(2, 0, 2)
        #geometryActor.GetProperty().SetDiffuseColor(0, 0, 1) # blue
        geometryActor.GetProperty().SetDiffuseColor(1, 1, 0)  # green
        self.rend.AddActor(geometryActor)
        vtk.vtkPolyDataMapper().SetResolveCoincidentTopologyToPolygonOffset()

    def cycleResults(self, result_name=None):
        self.log_command('cycleResults(result_name=%r)' % result_name)
        #print("nCases = %i" %(self.nCases+1))
        if self.nCases == 0:
            self.log.warning('nCases=0')
            self.scalarBar.SetVisibility(False)
            return

        print('cycling...')
        print("is_nodal=%s is_centroidal=%s" % (self.is_nodal,self.is_centroidal))

        foundCases = self.incrementCycle(result_name)
        if foundCases:
            print("incremented case")
            #gridResult.Reset()
            gridResult = vtk.vtkFloatArray()
            #gridResult.Reset()
            #gridResult.Modified()
            self.rend.Modified()
            #emptyResult = vtk.vtkFloatArray()

            key = self.caseKeys[self.iCase]
            case = self.resultCases[key]
            print("len(case) = %i" % len(case))
            (subcaseID, resultType, vectorSize, location, data_format) = key

            gridResult.SetNumberOfComponents(vectorSize)
            if location == 'centroid':
            #if location == 'centroid' and self.is_centroidal:
                #allocationSize = vectorSize*location (where location='centroid'-> self.nElements)
                gridResult.Allocate(self.nElements, 1000)
            #elif location == 'nodal' and self.is_nodal:
            elif location == 'nodal':
                #allocationSize = vectorSize*self.nNodes # (where location='node'-> self.nNodes)
                gridResult.Allocate(self.nNodes * vectorSize, 1000)
                #gridResult.SetNumberOfComponents(vectorSize)
            else:
                print("***%s skipping" % location)

            #self.iSubcaseNameMap[self.isubcase] = [Subtitle,Label]
            try:
                caseName = self.iSubcaseNameMap[subcaseID]
            except KeyError:
                caseName = ('case=NA', 'label=NA')
            (subtitle, label) = caseName

            #name_map = {
                #'rhoU' : 'ρU',
                #'rhoV' : 'ρV',
                #'rhoW' : 'ρW',
            #}
            #try:
                #resultType = name_map[resultType]
            #except KeyError:
                #pass

            print("subcaseID=%s resultType=%r subtitle=%r label=%r" % (subcaseID, resultType, subtitle, label))

            if isinstance(case, ndarray):
                max_value = amax(case)
                min_value = amin(case)
            else:
                min_value = case[0]
                max_value = case[0]
                for value in case:
                    max_value = max(value, max_value)
                    min_value = min(value, min_value)

            # flips sign to make colors go from blue -> red
            norm_value = max_value - min_value
            print('max_value=%s min_value=%r norm_value=%r' % (max_value, min_value, norm_value))
            #print "case = ",case
            #if norm_value==0.: # avoids division by 0.
            #    norm_value = 1.

            if 1:
                valueSet = set()
                if vectorSize == 1:
                    #print "min_value = ",min(case)
                    for i, value in enumerate(case):
                        #gridResult.InsertValue(i, value)
                        gridResult.InsertNextValue(1.0-(value - min_value)/norm_value)
                        #if len(valueSet) < 20:
                            #valueSet.add(value)
                else:  # vectorSize=3
                    pass
                    #for value in case:
                    #    .gridResult.InsertNextTuple3(value)  # x,y,z
                print("value_range", gridResult.GetValueRange())

            print("max=%g min=%g norm=%g\n" % (max_value, min_value, norm_value))

            nValueSet = len(valueSet)
            if 1:
                self.textActors[0].SetInput('Max:  %g' % max_value)  # max
                self.textActors[1].SetInput('Min:  %g' % min_value)  # min
                self.textActors[2].SetInput('Subcase=%s Subtitle: %s' % (subcaseID, subtitle))  # info

                if label:
                    self.textActors[3].SetInput('Label: %s' % label)  # info
                    self.textActors[3].VisibilityOn()
                else:
                    self.textActors[3].VisibilityOff()

            self.UpdateScalarBar(resultType, min_value, max_value, norm_value, data_format)
            #self.scalarBar.SetNumberOfLabels(nValueSet)
            #self.scalarBar.SetMaximumNumberOfColors(nValueSet)
            #prop = self.scalarBar.GetLabelTextProperty()
            #fontSize = prop.GetFontSize()
            #print "fontSize = ",fontSize
            #prop.SetFontSize(40)

            # TODO results can only go from centroid->node and not back to
            ## centroid
            #print dir(self.grid)
            #self.grid.Reset()
            #print('gridResult', dir(gridResult))
            #print('gridResult', gridResult)
            print("location =", location)

            npoints = self.nPoints()
            ncells = self.nCells()

            if location == 'centroid':
            #if location == 'centroid' and self.is_centroidal:
                if npoints:
                    point_data = self.grid.GetPointData()
                    point_data.Reset()
                self.grid.GetCellData().SetScalars(gridResult)
                self.log_info("***centroidal plotting vector=%s - subcaseID=%s resultType=%s subtitle=%s label=%s" % (vectorSize, subcaseID, resultType, subtitle, label))
            elif location == 'nodal':
            #elif location == 'nodal' and self.is_nodal:
                if ncells:
                    cell_data = self.grid.GetCellData()
                    print(dir(cell_data))
                    cell_data.Reset()
                if vectorSize == 1:
                    self.log_info("***nodal plotting vector=%s - subcaseID=%s resultType=%s subtitle=%s label=%s" % (vectorSize, subcaseID, resultType, subtitle, label))
                    self.grid.GetPointData().SetScalars(gridResult)
                else:
                    self.log_info("***nodal plotting vector=%s - subcaseID=%s resultType=%s subtitle=%s label=%s" % (vectorSize, subcaseID, resultType, subtitle, label))
                    self.grid.GetPointData().SetScalars(gridResult)
                #print("***nodal skipping - subcaseID=%s resultType=%s subtitle=%s label=%s" %(subcaseID,resultType,subtitle,label))
            else:
                self.log_info("***D%s skipping - subcaseID=%s resultType=%s subtitle=%s label=%s" % (location, subcaseID, resultType, subtitle, label))
                self.scalarBar.SetVisibility(False)
            self.grid.Modified()
            self.vtk_interactor.Render()

    def nCells(self):
        try:
            cell_data = self.grid.GetCellData()
            return cell_data.GetNumberOfCells()
        except AttributeError:
            return 0

    def nPoints(self):
        try:
            point_data = self.grid.GetPointData()
            return point_data.GetNumberOfPoints()
        except AttributeError:
            return 0

    def incrementCycle(self, result_name=False):
        found_case = False
        if result_name is not False and result_name is not None:
            for icase, cases in sorted(self.resultCases.iteritems()):
                #cases[(ID, 'Region', 1, 'centroid', '%.0f')] = bcs
                if result_name == cases[1]:
                    found_case = True
                    self.iCase = icase

        if not found_case:
            if self.iCase is not self.nCases:
                self.iCase += 1
            else:
                self.iCase = 0

        if len(self.caseKeys) > 0:
            #print('caseKeys =', self.caseKeys)
            try:
                key = self.caseKeys[self.iCase]
            except IndexError:
                foundCases = False
                return foundCases

            print("key = %s" % str(key))
            if key[2] == 3:  # vector size=3 -> vector, skipping ???
                self.incrementCycle()
            foundCases = True
        else:
            self.log_error("No Results found.  Many results are not supported in the GUI.\n")
            foundCases = False
        #print "next key = ",key
        return foundCases

    def on_update_scalar_bar(Title, min_value, max_value, data_format):
        self.Title = str(Title)
        self.min_value = float(min_value)
        self.max_value = float(max_value)
        try:
            data_format % 1
        except:
            self.log_error("failed applying the data formatter format=%r and should be of the form: '%i', '%8f', '%.2f', '%e', etc.")
            return
        self.data_format = data_format
        self.log_command('on_update_scalar_bar(%r, %r, %r')

    def _is_int_result(self, data_format):
        if 'i' in data_format:
            return True
        return False

    def UpdateScalarBar(self, Title, min_value, max_value, norm_value, data_format):
        """
        :param Title the:   scalar bar title
        :param min_value:   the blue value
        :param max_value:   the red value
        :param data_format: '%g','%f','%i', etc.
        """
        print("UpdateScalarBar min=%s max=%s norm=%s" % (min_value, max_value, norm_value))
        self.colorFunction.RemoveAllPoints()

        if self.Title_overwrite is not None:
            Title = self.Title
        self.Title = Title
        #if self.min_value is not None:
            #min_value = self.min_value
        #if self.max_value is not None:
            #max_value = self.max_value
        #if not self.blue_to_red:
            #min_value, max_value = max_value, min_value

        self.colorFunction.AddRGBPoint(min_value, 0.0, 0.0, 1.0)  # blue
        self.colorFunction.AddRGBPoint(max_value, 1.0, 0.0, 0.0)  # red
        #self.scalarBar.SetLookupTable(self.colorFunction)

        self.scalarBar.SetTitle(Title)
        self.scalarBar.SetLabelFormat(data_format)

        nvalues = 11
        if (Title in ['Element_ID', 'Eids', 'Region'] and norm_value < 11):
            nvalues = int(max_value - min_value) + 1
            #print "need to adjust axes...max_value=%s" % max_value

        if self.nvalues is not None:
            if not self._is_int_result(data_format):  # don't change nvalues for int results
                nvalues = self.nvalues

        #if data_format=='%.0f' and maxValue>

        self.scalarBar.SetNumberOfLabels(nvalues)
        self.scalarBar.SetMaximumNumberOfColors(nvalues)
        self.scalarBar.Modified()

    def ResetCamera(self):
        self.GetCamera().ResetCamera()

    def GetCamera(self):
        #print "getting camera..."
        return self.rend.GetActiveCamera()

    def update_camera(self, code):
        camera = self.GetCamera()
        print("code =", code)
        if code == '+x':  # set x-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., 0., 1.)
            camera.SetPosition(1., 0., 0.)
        elif code == '-x':  # set x-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., 0., -1.)
            camera.SetPosition(-1., 0., 0.)

        elif code == '+y':  # set y-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., 0., 1.)
            camera.SetPosition(0., 1., 0.)
        elif code == '-y':  # set y-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., 0., -1.)
            camera.SetPosition(0., -1., 0.)

        elif code == '+z':  # set z-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., 1., 0.)
            camera.SetPosition(0., 0., 1.)
        elif code == '-z':  # set z-axis
            camera.SetFocalPoint(0., 0., 0.)
            camera.SetViewUp(0., -1., 0.)
            camera.SetPosition(0., 0., -1.)
        else:
            self.log_error('invalid camera code...%r' % code)
            return
        self._update_camera(camera)
        #print dir(camera)
        #print dir(self.vtk_interactor)
        #print dir(self.rend)
        self.rend.ResetCamera()
        #self.vtk_interactor.ResetCamera()
        self.log_command('update_camera(%r)' % code)

def main():
    app = QtGui.QApplication(sys.argv)
    QtGui.QApplication.setOrganizationName("pyNastran")
    QtGui.QApplication.setOrganizationDomain(pyNastran.__website__)
    QtGui.QApplication.setApplicationName("pyNastran")
    QtGui.QApplication.setApplicationVersion(pyNastran.__version__)

    inputs = get_inputs('qt')
    window = MainWindow(inputs)
    sys.exit(app.exec_())

if __name__ == "__main__":
    main()


from __future__ import nested_scopes
from numpy.core.fromnumeric import sort
import pandas as pd
import json
import numpy as np
from pandas._libs.algos import unique_deltas
from pandas.core import series

def get_data_from_csv():
    df = pd.read_csv('../Data/korea_geo_name.csv', encoding="utf-8")
    df = df[df["시도"].notna()]
    return df

def handle_dup_siGunGu(geo_lv2):
    sigungu = geo_lv2[geo_lv2["소분류"].isna()]  # 시군구명 + 시도명
    sido = geo_lv2[geo_lv2.T.count() == 2]  # 시도
    sido_for_dict = sido.copy()  # 영어 시도명 딕셔너리
    # 인덱스 스왑
    sido_for_dict["orgidx"] = sido_for_dict.index
    sido_for_dict.index = sido_for_dict["시도"]
    sido_in_eng_dict = sido_for_dict.to_dict('index')
    sigungu_name_count = sigungu["시군구"].value_counts()  # 모든 시군구이름 중복갯수
    dup_sigungu_name = sigungu_name_count.\
        loc[sigungu_name_count != 1].index  # 중복 시군구 ['중구','동구',...]
    dup_sigungu_json = sigungu_name_count.to_json()
    with open("../Data/lv2_dup_name.json", "w") as f:
        f.write(
            json.dumps(
                json.loads(dup_sigungu_json),
                indent=2,
                sort_keys=False,
                ensure_ascii=False)
        )

    def dup_engname_to_nest(
            x, dup_sigungu_name, sido, sigungu, sido_in_eng_dict
    ):
        """
        Jung-gu -> Jung-gu in Seoul

        """
        if (x.name == "시군구"):
            dup_idx = x[x.isin(dup_sigungu_name)].index
            sido_eng_for_dup_sigungu = \
                sigungu.loc[dup_idx, "시도"].apply(
                    lambda x: sido_in_eng_dict[x]["영문 표기"]
                )
            sigungu.loc[dup_idx, "영문 표기"] = sigungu.loc[dup_idx, "영문 표기"]\
                + " in "\
                + sido_eng_for_dup_sigungu
            sigungu["지명 갯수"] = 1
            sigungu.loc[dup_idx, "지명 갯수"] = 2
            return sigungu

    sigungu[["시도", "시군구"]].apply(
        lambda x: dup_engname_to_nest(
            x,
            dup_sigungu_name,
            sido,
            sigungu,
            sido_in_eng_dict
        )
    )
    geo_lv2["지명 갯수"] = 1
    geo_lv2[geo_lv2["소분류"].isna()] = sigungu
    return sigungu

def write_geo_lv2(kor_geo_data):
    nested_sigungu_df = handle_dup_siGunGu(kor_geo_data)
    geo_lv2 = nested_sigungu_df.copy()
    geo_lv2 = geo_lv2[geo_lv2.T.count() == 5]
    geo_lv2.drop(columns=["읍면동", "소분류", "중분류"], inplace=True)
    j_lv2 = geo_lv2.groupby(["시도"])\
        .apply(lambda x: x[["시군구", "영문 표기", "지명 갯수"]].to_dict('records'))\
        .reset_index()\
        .rename(columns={0: "시군구_영어"})\
        .to_json(orient="records")
    with open("../Data/lv2_korea_geo.json", "w") as outfile:
        outfile.write(
            json.dumps(json.loads(j_lv2),
                       indent=2,
                       sort_keys=False,
                       ensure_ascii=False)
        )
    return nested_sigungu_df

def write_geo_lv1(kor_geo_data):
    geo_lv1 = kor_geo_data.copy()
    geo_lv1 = geo_lv1[geo_lv1.T.count() == 2]
    geo_lv1.drop(columns=["읍면동", "시군구"], inplace=True)
    geo_lv1_json = geo_lv1.to_json(orient="records")

    with open("../Data/lv1_korea_geo.json", "w") as outfile:
        outfile.write(
            json.dumps(
                json.loads(geo_lv1_json),
                indent=2,
                sort_keys=False,
                ensure_ascii=False
            )
            )

def gen_nest_emd_english(kor_geo_data, u_myeon_dong, u_m_d_dup_df, write=False):
    si_gun_gu = kor_geo_data[(kor_geo_data["소분류"].isna())
                             &
                             (kor_geo_data.T.count() == 5)
                             ]
    u_m_d_dup_df_left = u_m_d_dup_df.copy()
    u_m_d_dup_df_left = u_m_d_dup_df_left.merge(
        si_gun_gu,
        how="left",
        on="중분류"
    )
    u_m_d_dup_df_left.index = u_m_d_dup_df.index
    u_m_d_dup_df.loc[u_m_d_dup_df.index, "영문 표기"] = \
        u_m_d_dup_df_left.loc[u_m_d_dup_df.index, "영문 표기_x"]\
        + " in "\
        + u_m_d_dup_df_left.loc[u_m_d_dup_df.index, "영문 표기_y"]
    u_m_d_dup_df.loc[u_m_d_dup_df.index, "지명 갯수"] = \
        u_m_d_dup_df.loc[u_m_d_dup_df.index, "영문 표기"].copy().apply(
        lambda x: len(x.split("in"))
    )
    if write:
        u_m_d_dup_df.copy().\
            sort_values(by=["읍면동"]).to_csv("../Data/lv3_dup_handled_name.csv")
    kor_geo_data.loc[u_m_d_dup_df.index] = u_m_d_dup_df.loc[u_m_d_dup_df.index]
    return kor_geo_data

def write_geo_lv3(kor_geo_data, write=False):
    u_myeon_dong = kor_geo_data[kor_geo_data["소분류"].notna()]
    u_m_d_column = u_myeon_dong["읍면동"]
    u_m_d_count = u_m_d_column.value_counts()
    u_m_d_dup_name = u_m_d_count[u_m_d_count != 1].index
    u_m_d_dup_df = u_myeon_dong[u_myeon_dong["읍면동"].isin(u_m_d_dup_name)]
    if write:
        u_m_d_dup_df.copy().\
            sort_values(by=["읍면동"]).to_csv("../Data/lv3_dup_name.csv")
    gen_nest_emd_english(kor_geo_data, u_myeon_dong, u_m_d_dup_df)

    u_myeon_dong_json = kor_geo_data.copy()[kor_geo_data["소분류"].notna()]
    u_myeon_dong_json.drop(columns=["소분류", "중분류"], inplace=True)
    u_myeon_dong_json_test = u_myeon_dong_json.copy().groupby(["시군구"])

    print(u_myeon_dong_json_test)
    j_lv3 = u_myeon_dong_json.groupby(["시도", "시군구"])\
        .apply(lambda x: x[["읍면동", "영문 표기", "지명 갯수"]].to_dict('records'))\
        .reset_index()\
        .rename(columns={0: "읍면동_영어"})\
        .to_json(orient="records")
    with open("../Data/lv3_korea_geo.json", "w") as outfile:
        outfile.write(
            json.dumps(json.loads(j_lv3),
                       indent=2,
                       sort_keys=False,
                       ensure_ascii=False)
        )

if __name__ == "__main__":
    kor_geo_data = get_data_from_csv()
    nested_sigungu_df = write_geo_lv2(kor_geo_data)
    write_geo_lv3(kor_geo_data)


import pandas as pd
from sklearn.metrics import pairwise as similarity_measures

from pipeline import CosinePipeline
from similarity_interface import Similarity

class TracksCosineSimilarity(Similarity):
    """The class implements a Cosine similarity between a playlist vector and the tracks dataset to determine
        similar tracks to the playlist.

        This class inherits the Similarity interface.

        Attributes:
            additional_weighting (int): The weighting factor applied to weighted columns.
            playlist (DataFrame): The tracks dataset dataframe (before pipeline transformation)
            tracks (DataFrame): The playlist tracks dataframe (before pipeline transformation)
            playlist_features (DataFrame): The tracks dataset features (after transformation pipeline)
            track_features (DataFrame): The playlist tracks features (after transformation pipeline)
            similarity (Series): The ordered ranking of track similarity to the playlist vector (The index is uris)
        """
    def __init__(self, playlist: pd.DataFrame, tracks: pd.DataFrame, weighted_features: list):
        """The initialization of the Cosine Similarity class

        Args:
            playlist (DataFrame): The tracks dataset dataframe (before pipeline transformation)
            tracks (DataFrame): The playlist tracks dataframe (before pipeline transformation)
            weighted_features (list): A list of features to be weighted in order to prioritize feature importance in similarity calculation.

        """
        self.additional_weighting = 2  # Feature weighting value
        features = CosinePipeline.data_pipeline(tracks)  # Pass data through pipeline to extract features

        self.playlist = playlist
        self.tracks = tracks

        self.playlist_features, self.track_features = self.separate_playlist_from_tracks(features)
        self.weight_features(weighted_features)
        self.similarity = None

    def calculate_similarity(self):
        """Method calculates the similarity between a playlist vector and the tracks feature matrix using cosine similarity

        This calculation populates the `self.similarity` field.

        The playlist feature dataframe is mean of each feature, creating a playlist vector.
        """
        playlist_vector = self.vectorize_playlist()
        track_matrix = self.track_features.to_numpy()

        similarity_score = similarity_measures.cosine_similarity(track_matrix, playlist_vector)
        uris = self.track_features.index.tolist()

        self.similarity = pd.Series(similarity_score.T.tolist()[0], index=uris, name='sim_score')

    def access_similarity_scores(self):
        """Getter method to access the `similarity` class field.

        Returns:
            (Series): The track similarity to the playlist vector. Similarity is a Series using uris as the index.
        """
        return self.similarity

    def get_top_n(self, n: int):
        """This method should return the top-n most similar tracks as a Dataframe with essential features included.

        Note, due to the cosine similarity. A similarity value of 1 indicates a high similarity, while a value near 0 indicates a low similarity.

        Args:
            n (int): The top-n most similar tracks to the playlist vector

        Returns:
            (DataFrame): A dataframe containing the top-n tracks.
        """
        sim_df = pd.DataFrame(self.similarity, columns=['sim_score'])
        sorted_sim = sim_df.sort_values(by='sim_score', ascending=False)
        sorted_top = sorted_sim.head(n)
        return sorted_top.merge(self.tracks, left_index=True, right_on='uris')

    def separate_playlist_from_tracks(self, features: pd.DataFrame):
        """Method separates the feature dataframe (from pipeline) into tracks and playlist feature dataframes

        Args:
            features (DataFrame): The track dataset features dataframe (This contains the playlist tracks too)

        Returns:
            playlist_features (Dataframe): The playlist track features dataframe
            tracks_features (DataFrame): The track dataset features dataframe
        """
        playlist_uris = self.playlist['uris'].tolist()
        return features[features.index.isin(playlist_uris)], features[~features.index.isin(playlist_uris)]

    def vectorize_playlist(self):
        """Method vectorizes the playlist track features by determining the mean value of each track feature

        Returns:
            (Numpy vector): The playlist feature vector
        """
        playlist_vector = self.playlist_features.mean(axis=0)
        return playlist_vector.to_numpy().reshape(1, -1)

    def weight_features(self, weighted_columns: list):
        """Method weights the track dataset features (all features are normalized [0, 1]) by a scaler value
        to increase the effect of that feature in the similarity calculation.

        Wighting in cosine similarity increases the impact of the feature in the similarity calculation

        Note, this method directly alters the `self.track_features` field.

        Args:
            weighted_columns: The columns to be weighted by the additional weighting factor.

        """
        all_features = pd.Series(self.track_features.columns)
        feature_filter = all_features.isin(weighted_columns).tolist()   # Boolean filter based on if feature is in weighted columns
        binary_filter = [int(feature) for feature in feature_filter]  # Modify boolean filter into a binary filter
        filler = [1] * len(binary_filter)  # Create a filler of 1's to not effect features that have no weighting
        weights = [(self.additional_weighting * weight) + fill for weight, fill in zip(binary_filter, filler)]  # Calculate feature scaler weights

        self.track_features = self.track_features.mul(weights, axis=1)  # Weight features


from django.contrib import admin
from .models import * # para cargar en el panel de adm.

# Register your models here.

class ArticleAdmin(admin.ModelAdmin):
    readonly_fields = ('created_at', 'updated_at')

admin.site.register(Article, ArticleAdmin)
admin.site.register(Category)

#Configurar el titulo del panel adm

admin.site.site_header="Master en Python" #Cambiar nombre del panelAdm
admin.site.site_title="Master en Python Sub"
admin.site.index_title="Panel de Gestion"


#!/usr/bin/env python3
import math
import os

from common.connect_to_rabbitmq import connect_to_rabbitmq
from common.send_end import send_end

with connect_to_rabbitmq() as channel:
    node_id = os.getenv('NODE_ID')
    question_user_with_total_score_queue_name = f'question_user_with_total_score_{node_id}'
    channel.queue_declare(queue=question_user_with_total_score_queue_name)

    answer_user_with_total_score_queue_name = f'answer_user_with_total_score_{node_id}'
    channel.queue_declare(queue=answer_user_with_total_score_queue_name)

    channel.queue_declare(queue='user_with_joined_score')

    scores_by_user_id = {}
    has_all_question_users = False
    has_all_answer_users = False

    def enqueue_remaining_users():
        for user_id, scores in scores_by_user_id.items():
            channel.basic_publish(
                exchange='',
                routing_key='user_with_joined_score',
                body=' '.join((user_id, str(scores.get('answer', 0) + scores.get('question', 0))))
            )
        send_end(channel, exchange='', routing_key='user_with_joined_score')
        exit(0)

    def handle_user(method, body, is_answer):
        global has_all_answer_users
        global has_all_question_users
        global answer_user_with_total_score_queue_name
        global question_user_with_total_score_queue_name
        body = body.decode("ISO-8859-1")
        if body == '__end__':
            if is_answer:
                has_all_answer_users = True
            else:
                has_all_question_users = True
            if has_all_answer_users and has_all_question_users:
                enqueue_remaining_users()
        else:
            user_id, score = body.split(' ')
            if user_id not in scores_by_user_id:
                scores_by_user_id[user_id] = {}
            score = float(score)
            score = 0 if math.isnan(score) else score
            key = 'answer' if is_answer else 'question'
            scores_by_user_id[user_id][key] = score
            if 'answer' in scores_by_user_id[user_id] and 'question' in scores_by_user_id[user_id]:
                scores = scores_by_user_id.pop(user_id)
                channel.basic_publish(exchange='', routing_key='user_with_joined_score', body=' '.join((user_id, str(scores['answer'] + scores['question']))))
        channel.basic_ack(delivery_tag=method.delivery_tag)

    def handle_question_user(_ch, method, _properties, body):
        handle_user(method, body, is_answer=False)

    channel.basic_consume(queue=question_user_with_total_score_queue_name, on_message_callback=handle_question_user)

    def handle_answer_user(_ch, method, _properties, body):
        handle_user(method, body, is_answer=True)

    channel.basic_consume(queue=answer_user_with_total_score_queue_name, on_message_callback=handle_answer_user)

    channel.start_consuming()


# -*- coding: utf-8 -*-
"""
Created on Wed Sep 14 20:51:34 2022

@author: ilhan
"""

#os

#operating system kütüphanesi, klasörlerde dolaşmayı sağlayıp, resimleri içeriye yükler ya da kaydeder.

import os

print(os.name)
#bilgisayarın işletim sisteminin ne olduğuna bakılır.
#nt -> windows

current_directory = os.getcwd()
print(current_directory)

#getcwd methodu ile hangi klasörde bulunduğunun bilgisi alınır.
#C:\Users\ilhan

#new folder
folder_name = "new folder"
os.mkdir(folder_name)
#new folder adında bir klasör oluşturuldu.

new_folder_name = "new_folder_2"
os.rename(folder_name, new_folder_name)
#new folder klasör adı new_folder_2 olarak değiştirildi.

#change directory
os.chdir(current_directory+"\\"+new_folder_name)
print(os.getcwd()) #C:\Users\ilhan\new_folder_2
#new_folder_2 klasörünün içerisine girileceği için '\\' kullanılır.

os.chdir(current_directory)
print(os.getcwd())

files = os.listdir()
#listdir methodu ile bulunan konumdaki klasörler listelenir.

for f in files:
    if f.endswith(".ipynb"):
        print(f) #data.ipynb
#tüm dosyalar değil de sonu ipynb ile biten dosyalar yazdırılır.

#remove directory
os.rmdir(new_folder_name)

for i in os.walk(current_directory):
    print(i)

#current directoryde bulunan klasörlerde dolaşarak yazdırılır.

os.path.exists("Desktop")
#böyle bir klasör bulunduğu için True sonucu yazdırılır.


import requests
import constants
from urllib.request import urlopen, URLError

def login_attempt(key):
    print('login_attempt')
    status = check_server()
    print(status)
    if status == requests.codes.not_found:
        pack = constants.ServerAnswer(requests.codes.not_found)
        return pack
    ans = requests.get(constants.LOGIN_URL + key)
    if ans.status_code == requests.codes.ok:
        pack = constants.ServerAnswer(requests.codes.ok, ans.text)
        return pack
    else:
        pack = constants.ServerAnswer(requests.codes.unauthorized)
        return pack

def check_server():
    a = ping(constants.HTTP_START + constants.SERVER_IP)
    if (a):
        print("Server is reachable")
        return requests.codes.ok
    else:
        return requests.codes.not_found

def ping(host):
    try:
        urlopen(host, timeout=3)
        return True
    except URLError as a:
        print(a.strerror)
        return False


# from django.shortcuts import get_object_or_404, render
from sigi_op.views import CustomViewSet
# from rest_framework.response import Response
from .serializers import GODSerializer, GODPortSerializer, JumperSerializer
from .serializers import GODPortConnectionTypeSerializer, AccessCableSerializer
from .serializers import GODFabricantSerializer, GODFabricantModelSerializer
from .models import GOD, GODPort, GODPortConnectionType, Jumper, AccessCable
from .models import GODFabricant, GODFabricantModel

# Create your views here.

class GODFabricantListViewSet(CustomViewSet):
    class_name = GODFabricant
    order_param_name = 'pk'
    queryset = GODFabricant.objects.all().order_by('pk')
    serializer_class = GODFabricantSerializer

class GODFabricantModelListViewSet(CustomViewSet):
    class_name = GODFabricantModel
    order_param_name = 'pk'
    queryset = GODFabricantModel.objects.all().order_by('pk')
    serializer_class = GODFabricantModelSerializer

class GODListViewSet(CustomViewSet):
    class_name = GOD
    order_param_name = 'site_id'
    queryset = GOD.objects.all().order_by('site_id')
    serializer_class = GODSerializer

class GODPortListViewSet(CustomViewSet):
    class_name = GODPort
    order_param_name = 'god_id'
    queryset = GODPort.objects.all().order_by('god_id')
    serializer_class = GODPortSerializer

class GODPortConnectionTypeListViewSet(CustomViewSet):
    class_name = GODPortConnectionType
    order_param_name = 'code'
    queryset = GODPortConnectionType.objects.all().order_by('code')
    serializer_class = GODPortConnectionTypeSerializer

class JumperViewSet(CustomViewSet):
    class_name = Jumper
    order_param_name = 'god_port1'
    queryset = Jumper.objects.all().order_by('god_port1')
    serializer_class = JumperSerializer

class AccessCableListViewSet(CustomViewSet):
    class_name = AccessCable
    order_param_name = 'site_id'
    queryset = AccessCable.objects.all().order_by('site_id')
    serializer_class = AccessCableSerializer


#!/usr/bin/env python3
import os
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import datetime
from scipy.io import netcdf
from time import strptime  # it's needed to get month number for a given month name
import csv
import model2

# THE SIZE OF THE TIME WINDOW IS DETERMINED HERE, in the text of program, DIRECTLY!!!

# this is just like "ml_set_creator_local_0.py" and "read_and_find_the_event" together and in a form of functions:
# the present functions enable to get the big table with all the information needed for ml-analysis
# swrf-data is obtained with use of function from "model2.py"
# the eventual result - the "big table" with the information about all the events fron some set could be made by multiple use of functions from this file
# multiple use of this file is organised by "run_parameters.py", which gets datetimes and thresholds of chosen events from text-file.

# everything above the threshold we consider being "the flux", everything under it - isn't "the flux"
# "start" and "end" are strings, "threshold" is an integer

def find_the_event(start, end, threshold, short_name_of_detector):
    print("The event under consideration starts at " + start)
    print("The event under consideration ends at " + end)
    print("The threshold value is " + str(threshold))

    start_finish_date_str = start + '_' + end;
#    name_of_detector = 'Stand_1_upper_1cm'
    #name_of_detector = 'NaI_2'

    name_of_detector = 'aaa';

    if (short_name_of_detector ==  'NaI_2'):
        name_of_detector = 'NaI_2';

    if (short_name_of_detector == 'Stand'):
         name_of_detector = 'Stand_1_upper_1cm'

    initial_data = pd.read_csv('/home/kate-svch/wrfmain/kate/reanalysis/csv_all/' + start_finish_date_str + '_' + name_of_detector + '.csv')
    output_file = '/home/kate-svch/wrfmain/kate/reanalysis/datetime_and_01/test_tables/' + start_finish_date_str + '_' + str(threshold) + '_dt_and_01.csv'
    # the following means that for "initial_time_unit = 1 min" - new time uniti turns out to be "resulting_time_unit = 10 min"
    size_of_time_window = 10;

    # those two are different units of time - "initial_time_unit" and "resulting_time_unit"
    initial_moments_of_event = 0;
    resulting_moments_of_event = 0;

    new_length_of_data = len(initial_data) // size_of_time_window;

    averaged_data = [0] * (new_length_of_data)
    averaged_whether_there_is_a_flux = [0] * (new_length_of_data)

    # the following "averaging" is "nre value is maximum value from the corresponding time interval"
    # =============================================================================
    # let's make an averaged data (from initial_data - for count rate):
    for new_time_j in range(0, new_length_of_data):
#        current_averaged_value = 0;
        for little_j in range(0, size_of_time_window ):
            time_j = new_time_j*size_of_time_window + little_j
            if (initial_data.iloc[time_j,1] > averaged_data[new_time_j] ):
                averaged_data[new_time_j] = initial_data.iloc[time_j,1]

    # the following makes "averaged_whether_there_is_a_flux" from "averaged_data" - just the result we need
    for new_time_j in range(0, new_length_of_data ):
        if (averaged_data[new_time_j]  > threshold):
            averaged_whether_there_is_a_flux[new_time_j] = 1;
            #print (whether_there_is_a_flux[time_j])
            resulting_moments_of_event = resulting_moments_of_event + 1;
    # =============================================================================

    # here we make an array of datetime-objects for corresponding to "averaged_data" and "averaged_whether_there_is_a_flux" moments

    array_of_datetimes = [0] * (new_length_of_data)

    for new_time_j in range(0, new_length_of_data ):
        time_j = new_time_j*size_of_time_window + size_of_time_window//2;
        time_init_format = initial_data.iloc[time_j,0]
        year = 2000 + int(time_init_format[7])*10 + int(time_init_format[8])  # we could use int(time_init_format[7:9]) instead, if we wanted to
        day =  int(time_init_format[0])*10 + int(time_init_format[1])
        month = strptime(time_init_format[3:6],'%b').tm_mon
        hour = int(time_init_format[10])*10 + int(time_init_format[11])
        minute = int(time_init_format[13])*10 + int(time_init_format[14])
        array_of_datetimes[new_time_j] = datetime.datetime(year, month, day, hour, minute)

    with open(output_file, "w") as output:
        for new_time_j in range(0, new_length_of_data ):
            output.write(str(array_of_datetimes[new_time_j]) + '      ' + str(averaged_whether_there_is_a_flux[new_time_j]) + '\n')

    print('we have ' + str(initial_moments_of_event) + ' initial_moments of event')
    print('we have ' + str(resulting_moments_of_event) + ' resulting_moments of event')
    print('we have ' + str(resulting_moments_of_event*size_of_time_window) + ' "initial_moments" of event - AFTER THE AVERAGING')

    plt.figure(figsize=(14,8))
    plt.plot(initial_data.iloc[:, 1])
    plt.title('Particle flux ', fontsize=22)
    plt.xlabel('time', fontsize=20, horizontalalignment='right' )
    plt.ylabel('Count rate', rotation='horizontal', fontsize=20, horizontalalignment='right', verticalalignment='top')
    plt.show()

    # Additional output: averaged flux and 0-1-results
    plt.figure(figsize=(14,8))
    plt.plot(averaged_data)
    plt.title('Averaged particle flux, time_window = '+ str(size_of_time_window) + ' min', fontsize=22)
    plt.xlabel('time', fontsize=20, horizontalalignment='right' )
    plt.ylabel('Count rate', rotation='horizontal', fontsize=20, horizontalalignment='right', verticalalignment='top')
    plt.show()

    plt.figure(figsize=(14,8))
    plt.plot( averaged_whether_there_is_a_flux)
    plt.title('averaged_whether_there_is_a_flux, threshold =  '+ str(threshold), fontsize=22)
    plt.xlabel('time', fontsize=20, horizontalalignment='right' )
    plt.ylabel('0_or_1', rotation='horizontal', fontsize=20, horizontalalignment='right', verticalalignment='top')
    plt.show()

def add_the_event_to_the_big_table(start, end, threshold, name_of_file):
# this file is used as "events" in what follows
#input_event_01_data = '/home/kate-svch/wrfmain/kate/reanalysis/datetime_and_01/current_set/' + start_finish_date_str + '_' + str(threshold) + '_dt_and_01.csv'

    print("The event under consideration starts at " + start)
    print("The event under consideration ends at " + end)

    x_lon = 45                                                                  # Index to d02 Aragats point
    y_lat = 45

    year = int(start[0:4])
    month = int(start[5:7])
    day =  int(start[8:10])
    hour = int(start[11:13])
    dt_start = datetime.datetime(year, month, day, hour)
    start_finish_date_str = start + '_' + end;

    model_datetime = dt_start;
#    model2.set_model_datetime(model_datetime)
    wrf_step_minutes = 5;
    model_period = datetime.timedelta(minutes = wrf_step_minutes)

    file = model2.get_wrf_file(model_datetime)
    variable = file.variables['T2'].data[:]
    model_length = len(variable[:, y_lat, x_lon])

    # this is a file made by the previous function (find_the_event(start, end, threshold)) from this file:- times and 0-1-s
    events = pd.read_csv('/home/kate-svch/wrfmain/kate/reanalysis/datetime_and_01/test_tables/' + start_finish_date_str + '_' + str(threshold) + '_dt_and_01.csv', delimiter='     ', names=['date', 'TGE'])
    #events = pd.read_csv('/home/kate-svch/wrfmain/kate/reanalysis/datetime_and_01/current_set/' + start_finish_date_str + '_' + str(threshold) + '_dt_and_01.csv', delimiter='     ')
    events['fulltime'] = pd.to_datetime(events.date, format='%Y-%m-%d %H:%M:%S')

    events['t2'] = np.nan
    events['s_wind'] = np.nan

    q_vapor = model2.get_q(model_datetime, model_period, model_length, model_datetime, name='QVAPOR')
    for i in range(len(q_vapor[0])):
        events['qvapor_'+str(i).zfill(2) ] = np.nan
        events['qsnow_'+str(i).zfill(2) ] = np.nan
        events['qice_'+str(i).zfill(2) ] = np.nan
        events['qrain_'+str(i).zfill(2) ] = np.nan
        events['qgraup_'+str(i).zfill(2) ] = np.nan
        events['qcloud_'+str(i).zfill(2) ] = np.nan

    for ii, d in events.iterrows():
        print (ii)
        date = d.fulltime

        events['t2'].iloc[ii] = model2.get_t2(model_datetime, model_period, model_length, date)[0]
        events['s_wind'].iloc[ii] = model2.get_s_wind(model_datetime, model_period, model_length, date)[0]
        for i in range(len(q_vapor[0])):
            events['qvapor_'+str(i).zfill(2)].iloc[ii] = model2.get_q(model_datetime, model_period, model_length,date, name='QVAPOR')[0][i]
            events['qsnow_'+str(i).zfill(2)].iloc[ii] = model2.get_q(model_datetime, model_period, model_length,date, name='QSNOW')[0][i]
            events['qice_'+str(i).zfill(2)].iloc[ii] = model2.get_q(model_datetime, model_period, model_length,date, name='QICE')[0][i]
            events['qrain_'+str(i).zfill(2)].iloc[ii] = model2.get_q(model_datetime, model_period, model_length,date, name='QRAIN')[0][i]
            events['qgraup_'+str(i).zfill(2)].iloc[ii] = model2.get_q(model_datetime, model_period, model_length,date, name='QGRAUP')[0][i]
            events['qcloud_'+str(i).zfill(2)].iloc[ii] = model2.get_q(model_datetime, model_period, model_length,date, name='QCLOUD')[0][i]
            print (i)

        print(events.head())

    events.to_csv('/home/kate-svch/wrfmain/kate/reanalysis/datetime_and_01/big_tables_for_separate_events/' + name_of_file  + '_big_table.csv', mode='a')

# this test functioni just takes one file as "events" and rewrites it to the other file
def test_add_the_event(start, end, threshold, name_of_file):
# this file is used as "events" in what follows
#input_event_01_data = '/home/kate-svch/wrfmain/kate/reanalysis/datetime_and_01/current_set/' + start_finish_date_str + '_' + str(threshold) + '_dt_and_01.csv'

    print("The event under consideration starts at " + start)
    print("The event under consideration ends at " + end)

    year = int(start[0:4])
    month = int(start[5:7])
    day =  int(start[8:10])
    hour = int(start[11:13])
    dt_start = datetime.datetime(year, month, day, hour)
    start_finish_date_str = start + '_' + end;

    model_datetime = dt_start;
#    model2.set_model_datetime(model_datetime)
    wrf_step_minutes = 5;
    model_period = datetime.timedelta(minutes = wrf_step_minutes)

    file = model2.get_wrf_file(model_datetime)
    variable = file.variables['T2'].data[:]
    model_length = len(variable[:, y_lat, x_lon])

    # this is a file made by the previous function (find_the_event(start, end, threshold)) from this file:- times and 0-1-s
    events = pd.read_csv('/home/kate-svch/wrfmain/kate/reanalysis/datetime_and_01/current_set/' + start_finish_date_str + '_' + str(threshold) + '_dt_and_01.csv', delimiter='     ', names=['date', 'TGE'])
#    events = pd.read_csv('/home/kate-svch/wrfmain/kate/reanalysis/datetime_and_01/current_set/' + start_finish_date_str + '_' + str(threshold) + '_dt_and_01.csv', delimiter='     ')

    events.to_csv('/home/kate-svch/wrfmain/kate/reanalysis/datetime_and_01/big_tables_for_sets_of_events/' + name_of_file + '_big_table.csv', mode='a')


class Solution:
    def pivotIndex(self, nums: List[int]) -> int:
        right_sum = sum(nums)
        left_sum = 0
        for i in range(len(nums)):
            right_sum -= nums[i]
            if right_sum == left_sum:
                return i
            left_sum += nums[i]
        return -1