示例#1
0
class Controls(object):
    """Main class Neuronvisio"""
    def __init__(self):
        app = QtGui.QApplication.instance()
        self.ui_dir = 'ui'
        # Loading the UI
        self.ui = uic.loadUi(os.path.join(os.path.dirname(__file__), 
                                          self.ui_dir,
                                          "neuronvisio.ui"))
        
        # Connecting
        self.ui.Plot3D.connect(self.ui.Plot3D, 
                                     QtCore.SIGNAL('clicked()'), self.launch_visio)
        self.ui.plot_vector_btn.connect(self.ui.plot_vector_btn,
                                         QtCore.SIGNAL('clicked()'), self.plot_vector)
        self.ui.init_btn.connect(self.ui.init_btn,
                                 QtCore.SIGNAL('clicked()'), self.init)
        self.ui.run_btn.connect(self.ui.run_btn,
                                QtCore.SIGNAL('clicked()'), self.run)
        self.ui.dtSpinBox.connect(self.ui.dtSpinBox, 
                                  QtCore.SIGNAL('valueChanged(double)'), 
                                  self.dt_changed)
        self.ui.tstopSpinBox.connect(self.ui.tstopSpinBox, 
                                     QtCore.SIGNAL('valueChanged(double)'), 
                                     self.tstop_changed)
        self.ui.vSpinBox.connect(self.ui.vSpinBox, 
                                 QtCore.SIGNAL('valueChanged(double)'), 
                                     self.v_changed)
        self.ui.create_vector.connect(self.ui.create_vector,
                                      QtCore.SIGNAL('clicked()'), 
                                      self.create_vector)
        self.ui.actionAbout.connect(self.ui.actionAbout,
                                      QtCore.SIGNAL('triggered()'), 
                                      self.about)
        self.ui.timelineSlider.connect(self.ui.timelineSlider,
                                         QtCore.SIGNAL("valueChanged(int)"),
                                         self.on_timeline_value_changed)
        self.ui.animationTime.connect(self.ui.animationTime,
                                      QtCore.SIGNAL('returnPressed()'),
                                      self.on_animation_time_return_pressed)
        self.ui.actionLoad.connect(self.ui.actionLoad, 
                                   QtCore.SIGNAL("triggered()"),
                                   self.load)
        self.ui.actionSave.connect(self.ui.actionSave,
                                   QtCore.SIGNAL("triggered()"),
                                   self.save_hdf)
        self.ui.tabWidget.connect(self.ui.tabWidget, 
                                  QtCore.SIGNAL('currentChanged(int)'),
                                  self.populate_treeview_model)
        self.ui.tree_models.connect(self.ui.tree_models, 
                                    QtCore.SIGNAL('itemSelectionChanged ()'),
                                    self.select_model_treeview)
        self.ui.load_model_btn.connect(self.ui.load_model_btn, 
                                    QtCore.SIGNAL('clicked()'),
                                    self.load_selected_model)
        self.ui.load_model_btn.connect(self.ui.filter_list_btn, 
                                    QtCore.SIGNAL('clicked()'),
                                    self.filter_list)
        self.ui.filter_input.connect(self.ui.filter_input,
                                     QtCore.SIGNAL('returnPressed()'),
                                     self.filter_list)
        
        
        ### Connection with the console
        widgetDic = {'dt' : self.ui.dtSpinBox, 
                     'tstop' : self.ui.tstopSpinBox,
                     'v_init' : self.ui.vSpinBox, 
                     'time_label' : self.ui.time_label
                    }
        self.timeLoop = Timeloop(widgetDic)
        app.connect( self.timeLoop, QtCore.SIGNAL("updateDt(double)"), self.update_dt )
        app.connect( self.timeLoop, QtCore.SIGNAL("updateTstop(double)"), self.update_tstop )
        app.connect( self.timeLoop, QtCore.SIGNAL("updateVInit(double)"), self.update_v_init )
        self.timeLoop.start()
        
        
        ### Manager class 
        self.manager = manager.Manager()
        self.path_to_hdf = None
        self.visio = None
        self.tab_model_already_populated = False  
        self.ui.show()
        # Start the main event loop.
        #app.exec_()
        
        self.AUTHORS = 1
        self.YEAR = 0
        self.TITLE = 2
        self.ID = 3
        # Dictionary to hold the models class for the ModelDb integration
        self.models = Models()
        
    def populate_treeview_model(self, index, filter=""):
        """populate the tree view and the scroll_area when the tab is 
        activated"""
        if index == 3 and (filter or not self.tab_model_already_populated):
            self.ui.tree_models.clear()
            
            # Populating the treeview with the dictionary
            for model_name in self.models.get_model_names(filter):
                model = self.models.get_model(model_name)
                model_item = QtGui.QTreeWidgetItem(self.ui.tree_models, 'Models')
                model_item.setText(self.YEAR, model.get_year())
                model_item.setText(self.AUTHORS, model.get_authors())
                model_item.setText(self.TITLE, model.get_title())
                model_item.setData(self.ID, 0, model.get_id())
                self._set_tooltip(model, model_item)
            
                
            #Resizing the column.
            #self.ui.tree_models.resizeColumnToContents(0)
            self.ui.tree_models.resizeColumnToContents(self.YEAR)
            self.ui.tree_models.resizeColumnToContents(self.TITLE)
            self.ui.tree_models.resizeColumnToContents(self.ID)
            self.ui.textBrowser_readme.clear()
            self.ui.textBrowser_readme.insertPlainText("No model selected.")
            self.tab_model_already_populated = True #we populated only once.

    def _set_tooltip(self, model, model_item):
        # tooltip
        cols = self.ui.tree_models.columnCount()
        for i in range (cols):
            tooltip = model.get_tooltip()
            model_item.setToolTip(i, tooltip)

       
    def _retrieve_selected_model(self):
        "Return the model selected in the "
        items = self.ui.tree_models.selectedItems()
    
        if items:
            selected_item = items[0] #first element
            model_id = int(selected_item.text(self.ID))
            models_name = self.models.get_model_names()
            for name in models_name:
                mod = self.models.get_model(name)
                if model_id == mod.get_id():
                    return mod
        else:
            logging.info('No model selected!')
            return None
       
    def filter_list(self):
        "Filter the models list using the given text."
        filter = self.ui.filter_input.text()
        logger.debug("Filtering list using keyword '%s'" %(filter))
        self.populate_treeview_model(3, filter)

    def about(self):
        self.aboutUi = uic.loadUi(os.path.join(os.path.dirname(__file__),
                                               self.ui_dir,
                                               "qtAbout.ui"))
        import neuronvisio
        name = '<font size=24><b>Neuronvisio %s<b><font>' %neuronvisio.__version__
        authors = '%s' %neuronvisio.__authors__
        
        self.aboutUi.name.setText(name)
        self.aboutUi.authors.setText(authors)    
        self.aboutUi.show()
     
    def animation(self):
        self.ui.timelineSlider.setRange(0, len (self.manager.groups['t']))
        self.ui.timelineSlider.setEnabled(True)
        self.ui.show()
    
    def create_vector(self):
        var = self.ui.var.text()
        if not var:
            msgBox = QtGui.QMessageBox()
            msgBox.setText("No var specified.")
            msgBox.setIcon(QtGui.QMessageBox.Warning)
            msgBox.exec_()
 
        else: 
            if self.ui.all_sections.isChecked():
                allCreated = self.manager.add_all_vecRef(str(var))
            elif self.ui.selected_section.isChecked():
                if self.visio.selected_cyl is not None:
                    sec = self.visio.cyl2sec[self.visio.selected_cyl]
                    self.manager.add_vecRef(str(var), sec)
                else:
                    msgBox = QtGui.QMessageBox()
                    msgBox.setText("<b>No vector has been created.</b>")
                    msg = "You need to select the section where you want to create the vector"
                    msgBox.setInformativeText(msg)
                    msgBox.setIcon(QtGui.QMessageBox.Warning)
                    msgBox.exec_()
        self.update_tree_view()
    
    def dt_changed(self):
    
        h.dt = self.ui.dtSpinBox.value()
        

    def init(self):
        """Set the vm_init from the spin button and prepare the simulator"""
        
        if not self.manager.refs.has_key('VecRef') :
            message = "No vector Created. Create at least one vector to run the simulation"
            logger.info(message)
            self.ui.statusbar.showMessage(message, 3500)
            return False
        else:
            v_init = self.ui.vSpinBox.value()
            # Set the v_init
            h.v_init = v_init
            h.finitialize(v_init)
            h.fcurrent()
        
            # Reset the time in the GUI
            self.ui.time_label.setNum(h.t)
            return True
            
    def insert_item_treeview(self, groupName, section_name, vecs, 
                             details = None):
        """Insert a new item in the treewidget. 
        Items are grouped by types. If a new type is provided a new group is added.
        Items are then grouped by section.
        In one section more than one variable is allowed.
        Each variable can have a detail associated in a dictionary form """
        group_root = self.get_unique_parent(groupName)
        sec_root = self.get_unique_parent(section_name, 
                                          parentItem = group_root)
        for var,vec in vecs.iteritems():
            item = ItemRef(sec_root, vec)
            item.setText(0, var)
            item.setText(1, details)    
            sec_root.addChild(item)
            
        
    def insert_refs_in_treeview(self):
        for group, ref_list in self.manager.refs.iteritems():
            for ref in ref_list:
                self.insert_item_treeview(group, 
                                          ref.sec_name, 
                                          ref.vecs, 
                                          ref.detail)
        
    def launch_visio(self):
        msg = "Plotting..."
        self.ui.statusbar.showMessage(msg, 3500)
        if self.visio == None:
            
            # Checking there are sections in the model.
            i = 0
            for sec in h.allsec():
                i += 1
            
            if i > 0:
                self.visio = Visio(self.ui.sec_info_label, self.manager)
                self.visio.draw_model()
                self.ui.selected_section.setEnabled(True)
            else:
                msg = """No model found, no section created. You need 
                to have at least one."""
                logger.warning(msg)
        else:
            #Raise the visio window
            self.visio.container.show()
        # Enabling the animation
        try:
            self.animation()
        except KeyError:
            # No simulation run an nothing loaded.
            # just pass
            pass

    def load(self, path_to_file=None):
        """General loading method. It loads either an hoc file or 
        a hdf5 file. The file type is recognised on the extension"""
        if path_to_file == None:
            filename = QtGui.QFileDialog.getOpenFileName()
            if filename:
                path_to_file = str(filename)
        
        base_name, file_extension = os.path.splitext(path_to_file)
        if (file_extension == '.hoc'):
            file_path, hoc_file = os.path.split(path_to_file)
            self.load_hoc_model(file_path, hoc_file)
        else:
            self.load_hdf(path_to_file)

    def load_hdf(self, path_to_hdf):
    
        if path_to_hdf != None:
            self.path_to_hdf=os.path.abspath(path_to_hdf)
            
            self.manager.load_from_hdf(self.path_to_hdf)
            self.update_tree_view()
            msg = "Loaded db: %s" % self.path_to_hdf
            self.ui.statusbar.showMessage(msg, 3500)
            # Enablig the Animation button
            self.animation()
            # Disabling all the rest
            self.ui.init_btn.setEnabled(False)
            self.ui.run_btn.setEnabled(False)
            self.ui.create_vector.setEnabled(False)

    def load_hoc_model(self, model_dir, hoc_file):
        """Load an hoc files. It compiles the mod 
        before loading the hoc."""
        try:
            os.path.isfile(os.path.join (model_dir, hoc_file))
        except IOError:
            logger.error("Not existing file: %s" %e.value)
            
        old_dir = os.path.abspath(os.getcwd())
        logger.info("Path changed to %s" %(os.path.abspath(model_dir)))
        if model_dir != '' :
            os.chdir(model_dir)
        try:
            # Add all mod files into current directory
            self.find_mod_files()
        
            # If windows
            if os.name == 'nt':                
                self.windows_compile_mod_files('.')
                from neuron import h
                h.nrn_load_dll('./nrnmech.dll')
            else: # Anything else.
                call(['nrnivmodl'])
                import neuron            
                neuron.load_mechanisms('.') # Auto loading. Not needed anymore.
            from neuron import gui # to not freeze neuron gui
            from neuron import h
            logger.info("Loading model in %s from %s"%(model_dir, hoc_file))
            h.load_file(hoc_file)
        except Exception as e:
            logger.warning("Error running model: " + e.message)
        logger.info("Path changed back to %s" %old_dir)
        os.chdir(old_dir)
        return True
                        
    def load_selected_model(self):
        "Load the model selected in the treeview."
                    
        mod = self._retrieve_selected_model()
        if mod:
            model_path = mod.download_model()
            # tooltip
            cols = self.ui.tree_models.columnCount()
            items = self.ui.tree_models.selectedItems()
            model_item = items[0]
            for i in range (cols):
                tooltip = mod.get_tooltip()
                model_item.setToolTip(i, tooltip)
            
            if os.path.exists(os.path.join(mod.get_dir(), 'mosinit.hoc')):
                self.load_hoc_model(mod.get_dir(), 'mosinit.hoc')
            else:
                path_info = "Could not locate a predefined mosinit.hoc. Can't automatically load the model. \
                Check the README for hints on which hoc to use and copy it to %s/mosinit.hoc" %model_path
                logging.warning(path_info)
                self.ui.statusbar.showMessage(path_info, 10000)
                mod.browse()
        
    def on_animation_time_return_pressed(self):
        "Getting the value from the text"
        time = self.ui.animationTime.text()
        try:
            time = int (time)
            time_list = self.manager.groups['t']
            time_point_indx = 0
            # If it's a vector on the just ran sim.
            if hasattr(time_list, 'to_python'):
                time_list = time_list.to_python()
                time_list = np.around(time_list, 3)
        
                time_point_indx = np.where(time_list==time)[0]
            # If it's a numpy array saved on the disk
            else:
                rounded = time_list.read().round(3)
                time_point_indx = np.where(rounded==time)[0]
        
            self.sync_visio_3d(time_point_indx)
            self.ui.timelineSlider.setValue(time_point_indx)
        except:
            logger.warning("Value not present in the array.")
        
    def on_timeline_value_changed(self):
        """Draw the animation according to the value of the timeline"""
    
        time_point_indx = self.ui.timelineSlider.value()
        self.sync_visio_3d(time_point_indx)    
        
    def plot_vector(self):
        
        items = self.ui.treeWidget.selectedItems()
        
        x = None
        
        # Plot legend if required
        legend_status = self.ui.legend.isChecked() #return True if toggled.
        
        points_status = self.ui.points.isChecked()
        # Retrieve the fig num
        fig_num = self.ui.fig_num_spinBox.value()
        
        for item in items:
            if item.childCount() == 0: # Leaf, so it is the variable to plot
                
                sectionItem = item.parent()
                sectionName = str(sectionItem.text(0)) #Column used
                var = str(item.text(0))
                detail = str(item.text(1))
                
                groupName = str(sectionItem.parent().text(0))
                x = self.manager.groups[groupName]
                key = sectionName + "_" + var
                vecs_to_plot = { key : item.vec}
                self.manager.plot_vecs(vecs_to_plot, x=x, legend=legend_status, 
                              figure_num=fig_num, points=points_status)
    
    def get_unique_parent(self, name, parentItem = None):
        """Search the name in the treeview and return the qtElement.
        Raise an exception if not unique"""
        search = self.ui.treeWidget.findItems(name , 
                                                Qt.MatchFixedString)
        root_item = None
        if len(search) == 0: # We create the group
            root_item = None
            if parentItem is None:
                root_item = QtGui.QTreeWidgetItem(self.ui.treeWidget)
            else:
                root_item = QtGui.QTreeWidgetItem(parentItem)
            root_item.setText(0, name)
            
        elif len(search) == 1:
            root_item = search[0]
            
        else:
            error = "ERROR - too many match: %d. Group Name not \
            unique." %len(search)
            raise NameError(error)
        
        return root_item
                
    def run(self):
        """Run the simulator till tstop"""
            
        #Initializing
        if self.init():
            # Run
            msg = "Running simulation. It will take a while maybe..."
            self.ui.statusbar.showMessage(msg, 5000)
            while h.t < h.tstop:
                h.fadvance()
    
                self.ui.time_label.setText("<b>" + str(h.t) + "</b>")
        self.animation()
            
    def save_hdf(self):
        if not self.path_to_hdf:
            filename = QtGui.QFileDialog.getSaveFileName()
            self.path_to_hdf = str(filename) # It will go with python 3
            if self.path_to_hdf != None:
                self.manager.save_to_hdf(self.path_to_hdf)
                msg = "Saved hdf file: %s" % self.path_to_hdf
                self.ui.statusbar.showMessage(msg, 3500)    
        
    def select_model_treeview(self):
        """Synch the README and the modelOverview with the selected model."""
        mod = self._retrieve_selected_model()
        if mod:
            readme = mod.get_readme_html()
            overview = mod.get_overview()
            self.ui.textBrowser_readme.clear()
            self.ui.textBrowser_readme.insertHtml(readme)            
            self.ui.textBrowser_model_overview.clear()
            self.ui.textBrowser_model_overview.insertHtml(overview)

    
    def select_sections(self, list_of_sections):
        """Select an arbitrary number of sections from the 
        command line.
        
        
        :param: list_of_section - the list of sections to select. Each section should
                          be given by the name (sec.name() from Neuron point 
                          of view. 
        """
        if self.visio is not None:
            selection_scalar = self.visio.get_selection_scalar(list_of_sections)
            self.visio.redraw_color(selection_scalar, 'v')
            self.visio.update_sections_info(list_of_sections)
        else:
            logger.warning("You have to launch the 3D Visio window first!")
    
                
    def sync_visio_3d(self, time_point_indx):
        
        var = self.ui.varToShow.text()
        var = str(var) # This will go with Py3
#        
#        #Update the label on the scale
        
        if len (self.manager.groups['t']) == time_point_indx:
            time_point_indx = time_point_indx - 1 # Avoid to go out of scale
        time = self.manager.groups['t'][time_point_indx]
        self.ui.animationTime.setText(str(time))
        
        
        start_value = float(self.ui.startValue.text())
        end_value = float(self.ui.endValue.text())

        self.visio.show_variable_timecourse(var, time_point_indx, 
                                            start_value, end_value)
    
    def tstop_changed(self):
        h.tstop = self.ui.tstopSpinBox.value()
        
    def update_dt(self, new_dt):
        self.ui.dtSpinBox.setValue(new_dt)
        
    def update_tree_view(self):
        # Fill the treeview wit all the vectors created
        #Clear all the row
        self.ui.treeWidget.clear()
        self.insert_refs_in_treeview()
            
    def update_tstop(self, new_tstop):
        self.ui.tstopSpinBox.setValue(new_tstop)
    
    def update_v_init(self, new_v_init):
        self.ui.vSpinBox.setValue(new_v_init)
        
    def v_changed(self):
        h.v_init = self.ui.vSpinBox.value()
    
    # create the command line to compile mod files into nrnmech.dll and launch it. command line is
    # <cygwin-dir>\bin\bash.exe -c "cd <model-dir>; /usr/bin/sh -c '<nrnhome>/lib/mknrndll.sh <nrnhome>'"
    def windows_compile_mod_files(self, model_dir):
        # Get the required pathes
        if os.environ.has_key('NEURONHOME'):
            s1=os.environ['NEURONHOME']
            s2=os.environ['NEURONHOME']
        else:
            import _winreg
            k1=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Cygwin\\setup")
            s1=_winreg.QueryValueEx(k1, 'rootdir')[0]
            _winreg.CloseKey(k1)

            k2=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\NEURON\\nrn72") 
            s2=_winreg.QueryValueEx(k2, 'Install_Dir')[0]
            _winreg.CloseKey(k2)

        s1u=s1.replace('\\', '/')
        s2u=s2.replace('\\', '/')
        cmd=s1+"\\bin\\bash.exe"
        arg="cd "+model_dir+";"+s1u+"/bin/sh -c '" + s2u + "/lib/mknrndll.sh " + s2u + "'"
        import subprocess
        subprocess.Popen([cmd, '-c', arg], stdin=subprocess.PIPE).communicate(input="\r\n")

    # Copy all mod files under model directory into the root directory
    def find_mod_files(self):
        import shutil
        mod_files = []
        for root, dirnames, filenames in os.walk('.'):
            if (root == '.'): continue
            for filename in filenames:
                base_name, file_extension = os.path.splitext(filename)
                if file_extension == '.mod':
                    logger.info('Copy %s into model directory'%os.path.join(root, filename))
                    # Double checking we are not copying over the same file.
                    logger.debug("%s %s" %(root, filename))
                    filename_src = os.path.join(root, filename)
                    filename_dest = os.path.join('.', filename)
                    if not os.path.isfile(filename_dest):
                        shutil.copy(filename_src, filename_dest)
示例#2
0
文件: controls.py 项目: Rauell/neuron
class Controls():
    """Main class Neuronvisio"""
    def __init__(self):
        app = QtGui.QApplication.instance()
        self.ui_dir = 'ui'
        # Loading the UI
        self.ui = uic.loadUi(os.path.join(os.path.dirname(__file__), 
                                          self.ui_dir,
                                          "neuronvisio.ui"))
        
        # Connecting
        self.ui.Plot3D.connect(self.ui.Plot3D, 
                                     QtCore.SIGNAL('clicked()'), self.launch_visio)
        self.ui.plot_vector_btn.connect(self.ui.plot_vector_btn,
                                         QtCore.SIGNAL('clicked()'), self.plot_vector)
        self.ui.init_btn.connect(self.ui.init_btn,
                                 QtCore.SIGNAL('clicked()'), self.init)
        self.ui.run_btn.connect(self.ui.run_btn,
                                QtCore.SIGNAL('clicked()'), self.run)
        self.ui.dtSpinBox.connect(self.ui.dtSpinBox, 
                                  QtCore.SIGNAL('valueChanged(double)'), 
                                  self.dt_changed)
        self.ui.tstopSpinBox.connect(self.ui.tstopSpinBox, 
                                     QtCore.SIGNAL('valueChanged(double)'), 
                                     self.tstop_changed)
        self.ui.vSpinBox.connect(self.ui.vSpinBox, 
                                 QtCore.SIGNAL('valueChanged(double)'), 
                                     self.v_changed)
        self.ui.create_vector.connect(self.ui.create_vector,
                                      QtCore.SIGNAL('clicked()'), 
                                      self.create_vector)
        self.ui.actionAbout.connect(self.ui.actionAbout,
                                      QtCore.SIGNAL('triggered()'), 
                                      self.about)
        self.ui.timelineSlider.connect(self.ui.timelineSlider,
                                         QtCore.SIGNAL("valueChanged(int)"),
                                         self.on_timeline_value_changed)
        self.ui.animationTime.connect(self.ui.animationTime,
                                      QtCore.SIGNAL('returnPressed()'),
                                      self.on_animation_time_return_pressed)
        self.ui.actionLoad.connect(self.ui.actionLoad, 
                                   QtCore.SIGNAL("triggered()"),
                                   self.load_hdf)
        self.ui.actionSave.connect(self.ui.actionSave,
                                   QtCore.SIGNAL("triggered()"),
                                   self.save_hdf)
        self.ui.tabWidget.connect(self.ui.tabWidget, 
                                  QtCore.SIGNAL('currentChanged(int)'),
                                  self.populate_treeview_model)
        self.ui.tree_models.connect(self.ui.tree_models, 
                                    QtCore.SIGNAL('itemSelectionChanged ()'),
                                    self.select_model_treeview)
        self.ui.load_model_btn.connect(self.ui.load_model_btn, 
                                    QtCore.SIGNAL('clicked()'),
                                    self.load_selected_model)
        
        
        ### Connection with the console
        widgetDic = {'dt' : self.ui.dtSpinBox, 
                     'tstop' : self.ui.tstopSpinBox,
                     'v_init' : self.ui.vSpinBox, 
                     'time_label' : self.ui.time_label
                    }
        self.timeLoop = Timeloop(widgetDic)
        self.timeLoop.start()
        
        
        ### Manager class 
        self.manager = manager.Manager()
        self.path_to_hdf = None
        self.visio = None
        self.tab_model_already_populated = False  
        self.ui.show()
        # Start the main event loop.
        #app.exec_()
        
        self.AUTHORS = 1
        self.YEAR = 0
        self.TITLE = 2
        self.ID = 3
        # Dictionary to old the models class for the ModelDb integration
        self.models = None
        
    def populate_treeview_model(self, index):
        """populate the tree view and the scroll_area when the tab is 
        activated"""
        if not self.tab_model_already_populated and index == 3 :
            
            self.models =  Models()
            # Populating the treeview with the dictionary
            for model_name in self.models.get_model_names():
                model = self.models.get_model(model_name)
                model_item = QtGui.QTreeWidgetItem(self.ui.tree_models, 'Models')
                model_item.setText(self.YEAR, model.get_year())
                model_item.setText(self.AUTHORS, model.get_authors())
                model_item.setText(self.TITLE, model.get_title())
                model_item.setData(self.ID, 0, model.get_id())
                
                # tooltip
                cols = self.ui.tree_models.columnCount()
                for i in range (cols):
                    tooltip = model.get_tooltip()
                    model_item.setToolTip(i, tooltip)
            
                
            #Resizing the column.
            #self.ui.tree_models.resizeColumnToContents(0)
            self.ui.tree_models.resizeColumnToContents(self.YEAR)
            self.ui.tree_models.resizeColumnToContents(self.TITLE)
            self.ui.tree_models.resizeColumnToContents(self.ID)
            self.ui.textBrowser_readme.clear()
            self.ui.textBrowser_readme.insertPlainText("No model selected.")
            self.tab_model_already_populated = True #we populated only once.
        
    def select_model_treeview(self):
        """Synch the README and the modelOverview with the selected model."""
        mod = self._retrieve_selected_model()
        if mod:
            readme = mod.get_readme_html()
            overview = mod.get_overview()
            self.ui.textBrowser_readme.clear()
            self.ui.textBrowser_readme.insertHtml(readme)            
            self.ui.textBrowser_model_overview.clear()
            self.ui.textBrowser_model_overview.insertHtml(overview)
       
    def _retrieve_selected_model(self):
        "Return the model selected in the "
        items = self.ui.tree_models.selectedItems()
    
        if items:
            selected_item = items[0] #first element
            model_id = int(selected_item.text(self.ID))
            models_name = self.models.get_model_names()
            for name in models_name:
                mod = self.models.get_model(name)
                if model_id == mod.get_id():
                    return mod
        else:
            logging.info('No model selected!')
            return None
       
    def load_selected_model(self):
        "Load the model selected in the treeview."
        
        mod = self._retrieve_selected_model()
        if mod:
            model_path = mod.download_model()
            # tooltip
            cols = self.ui.tree_models.columnCount()
            items = self.ui.tree_models.selectedItems()
            model_item = items[0]
            for i in range (cols):
                tooltip = mod.get_tooltip()
                model_item.setToolTip(i, tooltip)
            self.run_extracted_model(mod)

    # create the command line to compile mod files into nrnmech.dll and launch it. command line is
    # <cygwin-dir>\bin\bash.exe -c "cd <model-dir>; /usr/bin/sh -c '<nrnhome>/lib/mknrndll.sh <nrnhome>'"
    def windows_compile_mod_files(self, model_dir):
        import _winreg
        k1=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Cygwin\\setup")
        s1=_winreg.QueryValueEx(k1, 'rootdir')[0]
        _winreg.CloseKey(k1)

        k2=_winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\NEURON\\nrn72") 
        s2=_winreg.QueryValueEx(k2, 'Install_Dir')[0]
        s2=s2.replace('\\', '/')
        _winreg.CloseKey(k2)

        cmd=s1+"\\bin\\bash.exe"
        arg="cd "+model_dir+";/usr/bin/sh -c '" + s2 + "/lib/mknrndll.sh " + s2 + "'"
        import subprocess
        subprocess.Popen([cmd, '-c', arg], stdin=subprocess.PIPE).communicate(input="\r\n")

    def run_extracted_model(self, mod):
        model_dir = mod.get_dir()
        if os.path.exists(os.path.join (model_dir, 'mosinit.hoc')):
            old_dir = os.path.abspath(os.getcwd())
            logger.info("Path changed to %s" %(os.path.abspath(model_dir)))
            os.chdir(model_dir)
            try:
                # If windows
                if os.name == 'nt':                
                    self.windows_compile_mod_files('.')
                    from neuron import h
                    h.nrn_load_dll('./nrnmech.dll')
                else: # Anything else.
                    call(['nrnivmodl'])
                    import neuron            
                    neuron.load_mechanisms('./')
                from neuron import gui # to not freeze neuron gui
                from neuron import h
                logger.info("Loading model in %s" %model_dir)
                h.load_file('mosinit.hoc')
            except Exception as e:
                logger.warning("Error running model: "+e.message)
            logger.info("Path changed back to %s" %old_dir)
            os.chdir(old_dir)
        else: 
            response = """We didn't find any mosinit.hoc . Unfortunately we can't 
            automatically run the model. Check the README, maybe there is an 
            hint."""
            logging.warning(response)
            path_info = "You can find the extracted model in %s" %model_dir
            mod.browse()
            logging.info(path_info)
    
    def load_hdf(self, path_to_hdf=None):
    
        if path_to_hdf != None:
            self.path_to_hdf=os.path.abspath(path_to_hdf)
        
        else:
            filename = QtGui.QFileDialog.getOpenFileName()
            if filename:
                self.path_to_hdf = str(filename)
        
        if self.path_to_hdf != None:
            
            self.manager.load_from_hdf(self.path_to_hdf)
            self.update_tree_view()
            msg = "Loaded db: %s" % self.path_to_hdf
            self.ui.statusbar.showMessage(msg, 3500)
            # Enablig the Animation button
            self.animation()
            # Disabling all the rest
            self.ui.init_btn.setEnabled(False)
            self.ui.run_btn.setEnabled(False)
            self.ui.create_vector.setEnabled(False)
            
        
    def save_hdf(self):
        if not self.path_to_hdf:
            filename = QtGui.QFileDialog.getSaveFileName()
            self.path_to_hdf = str(filename) # It will go with python 3
            if self.path_to_hdf != None:
                self.manager.save_to_hdf(self.path_to_hdf)
                msg = "Saved hdf file: %s" % self.path_to_hdf
                self.ui.statusbar.showMessage(msg, 3500)
        
    def launch_visio(self):
        msg = "Plotting..."
        self.ui.statusbar.showMessage(msg, 3500)
        if self.visio == None:
            
            # Checking there are sections in the model.
            i = 0
            for sec in h.allsec():
                i += 1
            
            if i > 0:
                self.visio = Visio(self.ui.sec_info_label, self.manager)
                self.visio.draw_model()
                self.ui.selected_section.setEnabled(True)
            else:
                msg = """No model found, no section created. You need 
                to have at least one."""
                logger.warning(msg)
        else:
            #Raise the visio window
            self.visio.container.show()
        # Enabling the animation
        try:
            self.animation()
        except KeyError:
            # No simulation run an nothing loaded.
            # just pass
            pass
        
    
    def init(self):
        """Set the vm_init from the spin button and prepare the simulator"""
        
        if not self.manager.refs.has_key('VecRef') :
            logger.info("No vector Created. Create at least one vector to run the simulation")
            return False
        else:
            v_init = self.ui.vSpinBox.value()
            # Set the v_init
            h.v_init = v_init
            h.finitialize(v_init)
            h.fcurrent()
        
            # Reset the time in the GUI
            self.ui.time_label.setNum(h.t)
            return True
            
    
    def run(self):
        """Run the simulator till tstop"""
        
        #Initializing
        if self.init():
            # Run
            msg = "Running simulation. It will take a while maybe..."
            self.ui.statusbar.showMessage(msg, 5000)
            while h.t < h.tstop:
                h.fadvance()
                
                self.ui.time_label.setText("<b>" + str(h.t) + "</b>")

                    
    def tstop_changed(self):
        
        h.tstop = self.ui.tstopSpinBox.value()
        
        
    def dt_changed(self):
        
        h.dt = self.ui.dtSpinBox.value()
    
    def v_changed(self):
        
        h.v_init = self.ui.vSpinBox.value()
        
    def plot_vector(self):
        
        items = self.ui.treeWidget.selectedItems()
        
        x = None
        
        # Plot legend if required
        legend_status = self.ui.legend.isChecked() #return True if toggled.
        
        points_status = self.ui.points.isChecked()
        # Retrieve the fig num
        fig_num = self.ui.fig_num_spinBox.value()
        
        for item in items:
            if item.childCount() == 0: # Leaf, so it is the variable to plot
                
                sectionItem = item.parent()
                sectionName = str(sectionItem.text(0)) #Column used
                var = str(item.text(0))
                detail = str(item.text(1))
                
                groupName = str(sectionItem.parent().text(0))
                x = self.manager.groups[groupName]
                key = sectionName + "_" + var
                vecs_to_plot = { key : item.vec}
                self.manager.plot_vecs(vecs_to_plot, x=x, legend=legend_status, 
                              figure_num=fig_num, points=points_status)
    
    def create_vector(self):
        
        var = self.ui.var.text()
        if var.isEmpty():

            msgBox = QtGui.QMessageBox()
            msgBox.setText("No var specified.")
            msgBox.setIcon(QtGui.QMessageBox.Warning)
            msgBox.exec_()
 
        else:
            if self.ui.all_sections.isChecked():
                allCreated = self.manager.add_all_vecRef(str(var))
            elif self.ui.selected_section.isChecked():
                if self.visio.selected_cyl is not None:
                    sec = self.visio.cyl2sec[self.visio.selected_cyl]
                    self.manager.add_vecRef(str(var), sec)
                else:
                    msgBox = QtGui.QMessageBox()
                    msgBox.setText("<b>No vector has been created.</b>")
                    msg = "You need to select the section where you want to create the vector"
                    msgBox.setInformativeText(msg)
                    msgBox.setIcon(QtGui.QMessageBox.Warning)
                    msgBox.exec_()
        self.update_tree_view()

    def get_unique_parent(self, name, parentItem = None):
        """Search the name in the treeview and return the qtElement.
        Raise an exception if not unique"""
        search = self.ui.treeWidget.findItems(name , 
                                                Qt.MatchFixedString)
        root_item = None
        if len(search) == 0: # We create the group
            root_item = None
            if parentItem is None:
                root_item = QtGui.QTreeWidgetItem(self.ui.treeWidget)
            else:
                root_item = QtGui.QTreeWidgetItem(parentItem)
            root_item.setText(0, name)
            
        elif len(search) == 1:
            root_item = search[0]
            
        else:
            error = "ERROR - too many match: %d. Group Name not \
            unique." %len(search)
            raise NameError(error)
        
        return root_item
                
    def insert_item_treeview(self, groupName, section_name, vecs, 
                             details = None):
        """Insert a new item in the treewidget. 
        Items are grouped by types. If a new type is provided a new group is added.
        Items are then grouped by section.
        In one section more than one variable is allowed.
        Each variable can have a detail associated in a dictionary form """
        group_root = self.get_unique_parent(groupName)
        sec_root = self.get_unique_parent(section_name, 
                                          parentItem = group_root)
        for var,vec in vecs.iteritems():
            item = ItemRef(sec_root, vec)
            item.setText(0, var)
            item.setText(1, details)    
            sec_root.addChild(item)
            
    
    def insert_refs_in_treeview(self):
        for group, ref_list in self.manager.refs.iteritems():
            for ref in ref_list:
                self.insert_item_treeview(group, 
                                          ref.sec_name, 
                                          ref.vecs, 
                                          ref.detail)
            
                        
    def update_tree_view(self):
        # Fill the treeview wit all the vectors created
        #Clear all the row
        self.ui.treeWidget.clear()
        
        self.insert_refs_in_treeview()

    
    def animation(self):
        
        self.ui.timelineSlider.setRange(0, 
                                          len (self.manager.groups['t']))
        self.ui.timelineSlider.setEnabled(True)
        self.ui.show()
    
    
    
    def select_sections(self, list_of_sections):
        """Select an arbitrary number of sections from the 
        command line.
        
        
        :param: list_of_section - the list of sections to select. Each section should
                          be given by the name (sec.name() from Neuron point 
                          of view. 
        """
        if self.visio is not None:
            selection_scalar = self.visio.get_selection_scalar(list_of_sections)
            self.visio.redraw_color(selection_scalar, 'v')
            self.visio.update_sections_info(list_of_sections)
        else:
            logger.warning("You have to launch the 3D Visio window first!")
    
    def on_animation_time_return_pressed(self):
        "Getting the value from the text"
        time = self.ui.animationTime.text()
        try:
            time = int (time)
            time_list = self.manager.groups['t']
            time_point_indx = 0
            # If it's a vector on the just ran sim.
            if hasattr(time_list, 'to_python'):
                time_list = time_list.to_python()
                time_list = np.around(time_list, 3)
                
                time_point_indx = np.where(time_list==time)[0]
            # If it's a numpy array saved on the disk
            else:
                rounded = time_list.read().round(3)
                time_point_indx = np.where(rounded==time)[0]
                        
            self.sync_visio_3d(time_point_indx)
            self.ui.timelineSlider.setValue(time_point_indx)
        except:
            logger.warning("Value not present in the array.")
    
    def on_timeline_value_changed(self):
        """Draw the animation according to the value of the timeline"""
        
        time_point_indx = self.ui.timelineSlider.value()
        self.sync_visio_3d(time_point_indx)    
    
    def sync_visio_3d(self, time_point_indx):
        
        var = self.ui.varToShow.text()
        var = str(var) # This will go with Py3
#        
#        #Update the label on the scale
        
        if len (self.manager.groups['t']) == time_point_indx:
            time_point_indx = time_point_indx - 1 # Avoid to go out of scale
        time = self.manager.groups['t'][time_point_indx]
        self.ui.animationTime.setText(str(time))
        
        
        start_value = float(self.ui.startValue.text())
        end_value = float(self.ui.endValue.text())

        self.visio.show_variable_timecourse(var, time_point_indx, 
                                            start_value, end_value)
    
    def about(self):
        
        self.aboutUi = uic.loadUi(os.path.join(os.path.dirname(__file__),
                                               self.ui_dir,
                                               "qtAbout.ui"))
        import neuronvisio
        name = '<font size=24><b>Neuronvisio %s<b><font>' %neuronvisio.__version__
        authors = '%s' %neuronvisio.__authors__
        
        self.aboutUi.name.setText(name)
        self.aboutUi.authors.setText(authors)    
        self.aboutUi.show()
示例#3
0
class Controls(object):
    """Main class Neuronvisio"""

    def __init__(self):
        dynamic_neuron_home()
        app = QtGui.QApplication.instance()
        self.ui_dir = "ui"
        # Loading the UI
        self.ui = uic.loadUi(os.path.join(os.path.dirname(__file__), self.ui_dir, "neuronvisio.ui"))

        # Connecting
        self.ui.Plot3D.connect(self.ui.Plot3D, QtCore.SIGNAL("clicked()"), self.launch_visio)
        self.ui.plot_vector_btn.connect(self.ui.plot_vector_btn, QtCore.SIGNAL("clicked()"), self.plot_vector)
        self.ui.init_btn.connect(self.ui.init_btn, QtCore.SIGNAL("clicked()"), self.init)
        self.ui.run_btn.connect(self.ui.run_btn, QtCore.SIGNAL("clicked()"), self.run)
        self.ui.dtSpinBox.connect(self.ui.dtSpinBox, QtCore.SIGNAL("valueChanged(double)"), self.dt_changed)
        self.ui.tstopSpinBox.connect(self.ui.tstopSpinBox, QtCore.SIGNAL("valueChanged(double)"), self.tstop_changed)
        self.ui.vSpinBox.connect(self.ui.vSpinBox, QtCore.SIGNAL("valueChanged(double)"), self.v_changed)
        self.ui.create_vector.connect(self.ui.create_vector, QtCore.SIGNAL("clicked()"), self.create_vector)
        self.ui.actionAbout.connect(self.ui.actionAbout, QtCore.SIGNAL("triggered()"), self.about)
        self.ui.timelineSlider.connect(
            self.ui.timelineSlider, QtCore.SIGNAL("valueChanged(int)"), self.on_timeline_value_changed
        )
        self.ui.animationTime.connect(
            self.ui.animationTime, QtCore.SIGNAL("returnPressed()"), self.on_animation_time_return_pressed
        )
        self.ui.actionLoad.connect(self.ui.actionLoad, QtCore.SIGNAL("triggered()"), self.load)
        self.ui.actionSave.connect(self.ui.actionSave, QtCore.SIGNAL("triggered()"), self.save_hdf)
        self.ui.tabWidget.connect(self.ui.tabWidget, QtCore.SIGNAL("currentChanged(int)"), self.populate_treeview_model)
        self.ui.tree_models.connect(
            self.ui.tree_models, QtCore.SIGNAL("itemSelectionChanged ()"), self.select_model_treeview
        )
        self.ui.load_model_btn.connect(self.ui.load_model_btn, QtCore.SIGNAL("clicked()"), self.load_selected_model)
        self.ui.load_model_btn.connect(self.ui.filter_list_btn, QtCore.SIGNAL("clicked()"), self.filter_list)
        self.ui.filter_input.connect(self.ui.filter_input, QtCore.SIGNAL("returnPressed()"), self.filter_list)

        ### Connection with the console
        widgetDic = {
            "dt": self.ui.dtSpinBox,
            "tstop": self.ui.tstopSpinBox,
            "v_init": self.ui.vSpinBox,
            "time_label": self.ui.time_label,
        }
        self.timeLoop = Timeloop(widgetDic)
        app.connect(self.timeLoop, QtCore.SIGNAL("updateDt(double)"), self.update_dt)
        app.connect(self.timeLoop, QtCore.SIGNAL("updateTstop(double)"), self.update_tstop)
        app.connect(self.timeLoop, QtCore.SIGNAL("updateVInit(double)"), self.update_v_init)
        self.timeLoop.start()

        ### Manager class
        self.manager = manager.Manager()
        self.path_to_hdf = None
        self.visio = None
        self.tab_model_already_populated = False
        self.ui.show()
        # Start the main event loop.
        # app.exec_()

        self.AUTHORS = 1
        self.YEAR = 0
        self.TITLE = 2
        self.ID = 3
        # Dictionary to hold the models class for the ModelDb integration
        self.models = Models()

    def populate_treeview_model(self, index, filter=""):
        """Populate the tree view on the gui and the scroll_area when the tab is 
        activated. 
        
        Args:
            index (int): the index of the activated tab
            
            filter (string): the string used to filter the search on the treeview
            """
        if index == 3 and (filter or not self.tab_model_already_populated):
            self.ui.tree_models.clear()

            # Populating the treeview with the dictionary
            for model_name in self.models.get_model_names(filter):
                model = self.models.get_model(model_name)
                model_item = QtGui.QTreeWidgetItem(self.ui.tree_models, "Models")
                model_item.setText(self.YEAR, model.get_year())
                model_item.setText(self.AUTHORS, model.get_authors())
                model_item.setText(self.TITLE, model.get_title())
                model_item.setData(self.ID, 0, model.get_id())
                self._set_tooltip(model, model_item)

            # Resizing the column.
            # self.ui.tree_models.resizeColumnToContents(0)
            self.ui.tree_models.resizeColumnToContents(self.YEAR)
            self.ui.tree_models.resizeColumnToContents(self.TITLE)
            self.ui.tree_models.resizeColumnToContents(self.ID)
            self.ui.textBrowser_readme.clear()
            self.ui.textBrowser_readme.insertPlainText("No model selected.")
            self.tab_model_already_populated = True  # we populated only once.

    def _set_tooltip(self, model, model_item):
        # tooltip
        cols = self.ui.tree_models.columnCount()
        for i in range(cols):
            tooltip = model.get_tooltip()
            model_item.setToolTip(i, tooltip)

    def _retrieve_selected_model(self):
        "Return the model selected in the treeview"
        items = self.ui.tree_models.selectedItems()

        if items:
            selected_item = items[0]  # first element
            model_id = int(selected_item.text(self.ID))
            models_name = self.models.get_model_names()
            for name in models_name:
                mod = self.models.get_model(name)
                if model_id == mod.get_id():
                    return mod
        else:
            logger.info("No model selected!")
            return None

    def filter_list(self):
        "Filter the models list using the given text in the filter box"
        filter = self.ui.filter_input.text()
        logger.debug("Filtering list using keyword '%s'" % (filter))
        self.populate_treeview_model(3, filter)

    def about(self):
        self.aboutUi = uic.loadUi(os.path.join(os.path.dirname(__file__), self.ui_dir, "qtAbout.ui"))
        import neuronvisio

        name = "<font size=24><b>Neuronvisio %s<b><font>" % neuronvisio.__version__
        authors = "%s" % neuronvisio.__authors__

        self.aboutUi.name.setText(name)
        self.aboutUi.authors.setText(authors)
        self.aboutUi.show()

    def animation(self):
        self.ui.timelineSlider.setRange(0, len(self.manager.groups["t"]))
        self.ui.timelineSlider.setEnabled(True)
        self.ui.show()

    def create_vector(self):
        var = self.ui.var.text()
        if not var:
            msgBox = QtGui.QMessageBox()
            msgBox.setText("No var specified.")
            msgBox.setIcon(QtGui.QMessageBox.Warning)
            msgBox.exec_()

        else:
            if self.ui.all_sections.isChecked():
                allCreated = self.manager.add_all_vecRef(str(var))
            elif self.ui.selected_section.isChecked():
                if self.visio.selected_cyl is not None:
                    sec = self.visio.cyl2sec[self.visio.selected_cyl]
                    self.manager.add_vecRef(str(var), sec)
                else:
                    msgBox = QtGui.QMessageBox()
                    msgBox.setText("<b>No vector has been created.</b>")
                    msg = "You need to select the section where you want to create the vector"
                    msgBox.setInformativeText(msg)
                    msgBox.setIcon(QtGui.QMessageBox.Warning)
                    msgBox.exec_()
        self.update_tree_view()

    def dt_changed(self):

        h.dt = self.ui.dtSpinBox.value()

    def init(self):
        """Set the vm_init from the spin button and prepare the simulator"""

        if not self.manager.refs.has_key("VecRef"):
            message = "No vector Created. Create at least one vector to run the simulation"
            logger.info(message)
            self.ui.statusbar.showMessage(message, 3500)
            return False
        else:
            v_init = self.ui.vSpinBox.value()
            # Set the v_init
            h.v_init = v_init
            h.finitialize(v_init)
            h.fcurrent()

            # Reset the time in the GUI
            self.ui.time_label.setNum(h.t)
            return True

    def insert_item_treeview(self, groupName, section_name, vecs, details=None):
        """Insert a new item in the treewidget. 
        Items are grouped by types. If a new type is provided a new group is added.
        Items are then grouped by section.
        In one section more than one variable is allowed.
        Each variable can have a detail associated in a dictionary form """
        group_root = self.get_unique_parent(groupName)
        sec_root = self.get_unique_parent(section_name, parentItem=group_root)
        for var, vec in vecs.iteritems():
            item = ItemRef(sec_root, vec)
            item.setText(0, var)
            item.setText(1, details)
            sec_root.addChild(item)

    def insert_refs_in_treeview(self):
        for group, ref_list in self.manager.refs.iteritems():
            for ref in ref_list:
                self.insert_item_treeview(group, ref.sec_name, ref.vecs, ref.detail)

    def launch_visio(self):
        msg = "Plotting..."
        self.ui.statusbar.showMessage(msg, 3500)
        if self.visio == None:

            # Checking there are sections in the model.
            i = 0
            for sec in h.allsec():
                i += 1

            if i > 0:
                self.visio = Visio(self.ui.sec_info_label, self.manager)
                self.visio.draw_model()
                self.ui.selected_section.setEnabled(True)
            else:
                msg = """No model found, no section created. You need 
                to have at least one."""
                logger.warning(msg)
        else:
            # Raise the visio window
            self.visio.container.show()
        # Enabling the animation
        try:
            self.animation()
        except KeyError:
            # No simulation run an nothing loaded.
            # just pass
            pass

    def load(self, path_to_file=None):
        """
        General loading method for any kind of format.
        Extensions recognised:
        .xml - NeuroML
        .hoc - NEURON hoc file
        .h5 - HDF file formatted according to Neuronvisio format.
        The file type is recognised using the extension.
        """
        if path_to_file == None:
            filename = QtGui.QFileDialog.getOpenFileName()
            if filename:
                path_to_file = str(filename)

        base_name, file_extension = os.path.splitext(path_to_file)
        try:
            if file_extension == ".hoc":
                file_path, hoc_file = os.path.split(path_to_file)
                self.load_hoc_model(file_path, hoc_file)
            elif file_extension == ".xml":
                self.manager.load_neuroml(path_to_file)
            elif file_extension == ".h5":
                self.load_hdf(path_to_file)
            else:
                raise ExtensionNotRecognised
        except ExtensionNotRecognised:

            msg = """
            File extension not recognised!! 
            Neuronvisio was not able to recognise the file extension. 
            Extensions recognised:
                    .xml - NeuroML
                    .hoc - NEURON hoc file
                    .h5 - HDF file formatted according to Neuronvisio format.
                    """
            logger.error(msg)

    def load_hdf(self, path_to_hdf):

        if path_to_hdf != None:
            self.path_to_hdf = os.path.abspath(path_to_hdf)

            self.manager.load_from_hdf(self.path_to_hdf)
            self.update_tree_view()
            msg = "Loaded db: %s" % self.path_to_hdf
            self.ui.statusbar.showMessage(msg, 3500)
            # Enablig the Animation button
            self.animation()
            # Disabling all the rest
            self.ui.init_btn.setEnabled(False)
            self.ui.run_btn.setEnabled(False)
            self.ui.create_vector.setEnabled(False)

    def load_hoc_model(self, model_dir, hoc_file):
        """Load an hoc files. It compiles the mod 
        before loading the hoc."""
        try:
            os.path.isfile(os.path.join(model_dir, hoc_file))
        except IOError:
            logger.error("Not existing file: %s" % e.value)

        old_dir = os.path.abspath(os.getcwd())
        logger.info("Path changed to %s" % (os.path.abspath(model_dir)))
        if model_dir != "":
            os.chdir(model_dir)
        try:
            # Add all mod files into current directory
            self.find_mod_files()

            # If windows
            if os.name == "nt":
                self.windows_compile_mod_files(".")
                from neuron import h

                h.nrn_load_dll("./nrnmech.dll")
            else:  # Anything else.
                call(["nrnivmodl"])
                import neuron

                neuron.load_mechanisms(".")  # Auto loading. Not needed anymore.
            from neuron import gui  # to not freeze neuron gui
            from neuron import h

            logger.info("Loading model in %s from %s" % (model_dir, hoc_file))
            h.load_file(hoc_file)
        except Exception as e:
            logger.warning("Error running model: " + e.message)
        logger.info("Path changed back to %s" % old_dir)
        os.chdir(old_dir)
        return True

    def load_selected_model(self):
        "Load the model selected in the treeview."

        mod = self._retrieve_selected_model()
        if mod:
            model_path = mod.download_model()
            # tooltip
            cols = self.ui.tree_models.columnCount()
            items = self.ui.tree_models.selectedItems()
            model_item = items[0]
            for i in range(cols):
                tooltip = mod.get_tooltip()
                model_item.setToolTip(i, tooltip)

            if os.path.exists(os.path.join(mod.get_dir(), "mosinit.hoc")):
                self.load_hoc_model(mod.get_dir(), "mosinit.hoc")
            else:
                log_warning = """No mosinit.hoc present. I can't locate the `mosinit.hoc` therefore I can't load automatically the model."""
                logger.warning(log_warning)
                self.ui.statusbar.showMessage("WARNING: Can't load the model automatically.", 10000)
                info_warning = """<h3>No <code>mosinit.hoc</code> present!</h3>
                
                <p>I couldn't find any <code>mosinit.hoc</code>, therefore I have no idea how to
                load this model.</p>
                
                <p>What I can do is to open the folder where the model has been downloaded.
                Then, you need to read the docs of the model to know which file you need to load
                to get the model up.</p> 
            
                <p>How to load an arbitrary hoc file with Neuronvisio is written on the docs:
                <a href='http://neuronvisio.org/gettingstarted.html#loading-a-file'>Loading a file</a></p>
                """

                warning_box = QtGui.QMessageBox()
                warning_box.setTextFormat(QtCore.Qt.RichText)
                warning_box.setText(info_warning)
                warning_box.exec_()
                mod.browse()

    def make_animation_screenshots(self, time_start, time_stop=None, saving_dir="anim"):
        """Creates a series of screenshots which can be put together using memcoder 
        to make a movie
        
        Args:
            time_start (float): time from where to start to take the screenshots
            
            time_stop (float): time where to stop. If None will continue till the end
            
            saving_dir (string): directory where to save the screenshots. Default is anim
        
        """
        from mayavi import mlab

        t = self.manager.get_time()
        indx_start = t.indwhere("==", time_start)
        indx_stop = None
        if time_stop:
            indx_stop = t.indwhere("==", time_stop)
        else:
            indx_stop = len(t)

        if not os.path.exists(saving_dir):
            os.mkdir(saving_dir)

        png_format = "%09d.png"
        for i in range(int(indx_start), int(indx_stop)):

            figure_filename_animation = png_format % (i - indx_start)
            logger.debug(figure_filename_animation)
            self.sync_visio_3d(i)
            mlab.savefig(os.path.join(saving_dir, figure_filename_animation))

        logger.info("files created in %s" % saving_dir)
        logger.info("To create a video run:")
        logger.info("ffmpeg -f image2 -r 10 -i %s -sameq anim.mov -pass 2" % png_format)

    def on_animation_time_return_pressed(self):
        "Getting the value from the text"
        time = self.ui.animationTime.text()
        try:
            time = int(time)
            time_list = self.manager.groups["t"]
            time_point_indx = 0
            # If it's a vector on the just ran sim.
            if hasattr(time_list, "to_python"):
                time_list = time_list.to_python()
                time_list = np.around(time_list, 3)

                time_point_indx = np.where(time_list == time)[0]
            # If it's a numpy array saved on the disk
            else:
                rounded = time_list.read().round(3)
                time_point_indx = np.where(rounded == time)[0]

            self.sync_visio_3d(time_point_indx)
            self.ui.timelineSlider.setValue(time_point_indx)
        except:
            logger.warning("Value not present in the array.")

    def on_timeline_value_changed(self):
        """Draw the animation according to the value of the timeline"""

        time_point_indx = self.ui.timelineSlider.value()
        self.sync_visio_3d(time_point_indx)

    def plot_vector(self):

        items = self.ui.treeWidget.selectedItems()

        x = None

        # Plot legend if required
        legend_status = self.ui.legend.isChecked()  # return True if toggled.

        points_status = self.ui.points.isChecked()
        # Retrieve the fig num
        fig_num = self.ui.fig_num_spinBox.value()

        for item in items:
            if item.childCount() == 0:  # Leaf, so it is the variable to plot

                sectionItem = item.parent()
                sectionName = str(sectionItem.text(0))  # Column used
                var = str(item.text(0))
                detail = str(item.text(1))

                groupName = str(sectionItem.parent().text(0))
                x = self.manager.groups[groupName]
                key = sectionName + "_" + var
                vecs_to_plot = {key: item.vec}
                self.manager.plot_vecs(
                    vecs_to_plot, x=x, legend=legend_status, figure_num=fig_num, points=points_status
                )

    def get_unique_parent(self, name, parentItem=None):
        """Search the name in the treeview and return the qtElement.
        Raise an exception if not unique"""
        search = self.ui.treeWidget.findItems(name, Qt.MatchFixedString)
        root_item = None
        if len(search) == 0:  # We create the group
            root_item = None
            if parentItem is None:
                root_item = QtGui.QTreeWidgetItem(self.ui.treeWidget)
            else:
                root_item = QtGui.QTreeWidgetItem(parentItem)
            root_item.setText(0, name)

        elif len(search) == 1:
            root_item = search[0]

        else:
            error = (
                "ERROR - too many match: %d. Group Name not \
            unique."
                % len(search)
            )
            raise NameError(error)

        return root_item

    def run(self):
        """Run the simulator till tstop"""

        # Initializing
        if self.init():
            # Run
            msg = "Running simulation. It will take a while maybe..."
            self.ui.statusbar.showMessage(msg, 5000)
            while h.t < h.tstop:
                h.fadvance()

                self.ui.time_label.setText("<b>" + str(h.t) + "</b>")
            self.animation()

    def save_hdf(self):
        if not self.path_to_hdf:
            filename = QtGui.QFileDialog.getSaveFileName()
            self.path_to_hdf = str(filename)  # It will go with python 3
            if self.path_to_hdf != None:
                self.manager.save_to_hdf(self.path_to_hdf)
                msg = "Saved hdf file: %s" % self.path_to_hdf
                self.ui.statusbar.showMessage(msg, 3500)

    def select_model_treeview(self):
        """Synch the README and the modelOverview with the selected model."""
        mod = self._retrieve_selected_model()
        if mod:
            readme = mod.get_readme_html()
            overview = mod.get_overview()
            self.ui.textBrowser_readme.clear()
            self.ui.textBrowser_readme.insertHtml(readme)
            self.ui.textBrowser_model_overview.clear()
            self.ui.textBrowser_model_overview.insertHtml(overview)

    def sync_visio_3d(self, time_point_indx):

        var = self.ui.varToShow.text()
        var = str(var)  # This will go with Py3
        #
        #        #Update the label on the scale

        if len(self.manager.groups["t"]) == time_point_indx:
            time_point_indx = time_point_indx - 1  # Avoid to go out of scale
        time = self.manager.groups["t"][time_point_indx]
        time_point_string = "%.3f" % round(time, 3)
        self.ui.animationTime.setText(time_point_string)

        start_value = float(self.ui.startValue.text())
        end_value = float(self.ui.endValue.text())

        self.visio.show_variable_timecourse(var, time_point_indx, start_value, end_value)

    def tstop_changed(self):
        h.tstop = self.ui.tstopSpinBox.value()

    def update_dt(self, new_dt):
        self.ui.dtSpinBox.setValue(new_dt)

    def update_tree_view(self):
        # Fill the treeview wit all the vectors created
        # Clear all the row
        self.ui.treeWidget.clear()
        self.insert_refs_in_treeview()

    def update_tstop(self, new_tstop):
        self.ui.tstopSpinBox.setValue(new_tstop)

    def update_v_init(self, new_v_init):
        self.ui.vSpinBox.setValue(new_v_init)

    def v_changed(self):
        h.v_init = self.ui.vSpinBox.value()

    # create the command line to compile mod files into nrnmech.dll and launch it. command line is
    # <cygwin-dir>\bin\bash.exe -c "cd <model-dir>; /usr/bin/sh -c '<nrnhome>/lib/mknrndll.sh <nrnhome>'"
    def windows_compile_mod_files(self, model_dir):
        # Get the required pathes
        if os.environ.has_key("NEURONHOME"):
            s1 = os.environ["NEURONHOME"]
            s2 = os.environ["NEURONHOME"]
        else:
            import _winreg

            k1 = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\Cygwin\\setup")
            s1 = _winreg.QueryValueEx(k1, "rootdir")[0]
            _winreg.CloseKey(k1)

            k2 = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE, "SOFTWARE\\NEURON\\nrn72")
            s2 = _winreg.QueryValueEx(k2, "Install_Dir")[0]
            _winreg.CloseKey(k2)

        s1u = s1.replace("\\", "/")
        s2u = s2.replace("\\", "/")
        cmd = s1 + "\\bin\\bash.exe"
        arg = "cd " + model_dir + ";" + s1u + "/bin/sh -c '" + s2u + "/lib/mknrndll.sh " + s2u + "'"
        import subprocess

        subprocess.Popen([cmd, "-c", arg], stdin=subprocess.PIPE).communicate(input="\r\n")

    # Copy all mod files under model directory into the root directory
    def find_mod_files(self):
        import shutil

        mod_files = []
        for root, dirnames, filenames in os.walk("."):
            if root == ".":
                continue
            for filename in filenames:
                base_name, file_extension = os.path.splitext(filename)
                if file_extension == ".mod":
                    logger.info("Copy %s into model directory" % os.path.join(root, filename))
                    # Double checking we are not copying over the same file.
                    logger.debug("%s %s" % (root, filename))
                    filename_src = os.path.join(root, filename)
                    filename_dest = os.path.join(".", filename)
                    if not os.path.isfile(filename_dest):
                        shutil.copy(filename_src, filename_dest)
示例#4
0
class Controls(object):
    """Main class Neuronvisio"""
    def __init__(self):
        dynamic_neuron_home()
        app = QtGui.QApplication.instance()
        self.ui_dir = 'ui'
        # Loading the UI
        self.ui = uic.loadUi(
            os.path.join(os.path.dirname(__file__), self.ui_dir,
                         "neuronvisio.ui"))

        # Connecting
        self.ui.Plot3D.connect(self.ui.Plot3D, QtCore.SIGNAL('clicked()'),
                               self.launch_visio)
        self.ui.plot_vector_btn.connect(self.ui.plot_vector_btn,
                                        QtCore.SIGNAL('clicked()'),
                                        self.plot_vector)
        self.ui.init_btn.connect(self.ui.init_btn, QtCore.SIGNAL('clicked()'),
                                 self.init)
        self.ui.run_btn.connect(self.ui.run_btn, QtCore.SIGNAL('clicked()'),
                                self.run)
        self.ui.dtSpinBox.connect(self.ui.dtSpinBox,
                                  QtCore.SIGNAL('valueChanged(double)'),
                                  self.dt_changed)
        self.ui.tstopSpinBox.connect(self.ui.tstopSpinBox,
                                     QtCore.SIGNAL('valueChanged(double)'),
                                     self.tstop_changed)
        self.ui.vSpinBox.connect(self.ui.vSpinBox,
                                 QtCore.SIGNAL('valueChanged(double)'),
                                 self.v_changed)
        self.ui.create_vector.connect(self.ui.create_vector,
                                      QtCore.SIGNAL('clicked()'),
                                      self.create_vector)
        self.ui.actionAbout.connect(self.ui.actionAbout,
                                    QtCore.SIGNAL('triggered()'), self.about)
        self.ui.timelineSlider.connect(self.ui.timelineSlider,
                                       QtCore.SIGNAL("valueChanged(int)"),
                                       self.on_timeline_value_changed)
        self.ui.animationTime.connect(self.ui.animationTime,
                                      QtCore.SIGNAL('returnPressed()'),
                                      self.on_animation_time_return_pressed)
        self.ui.actionLoad.connect(self.ui.actionLoad,
                                   QtCore.SIGNAL("triggered()"), self.load)
        self.ui.actionSave.connect(self.ui.actionSave,
                                   QtCore.SIGNAL("triggered()"), self.save_hdf)
        self.ui.tabWidget.connect(self.ui.tabWidget,
                                  QtCore.SIGNAL('currentChanged(int)'),
                                  self.populate_treeview_model)
        self.ui.tree_models.connect(self.ui.tree_models,
                                    QtCore.SIGNAL('itemSelectionChanged ()'),
                                    self.select_model_treeview)
        self.ui.load_model_btn.connect(self.ui.load_model_btn,
                                       QtCore.SIGNAL('clicked()'),
                                       self.load_selected_model)
        self.ui.load_model_btn.connect(self.ui.filter_list_btn,
                                       QtCore.SIGNAL('clicked()'),
                                       self.filter_list)
        self.ui.filter_input.connect(self.ui.filter_input,
                                     QtCore.SIGNAL('returnPressed()'),
                                     self.filter_list)

        ### Connection with the console
        widgetDic = {
            'dt': self.ui.dtSpinBox,
            'tstop': self.ui.tstopSpinBox,
            'v_init': self.ui.vSpinBox,
            'time_label': self.ui.time_label
        }
        self.timeLoop = Timeloop(widgetDic)
        app.connect(self.timeLoop, QtCore.SIGNAL("updateDt(double)"),
                    self.update_dt)
        app.connect(self.timeLoop, QtCore.SIGNAL("updateTstop(double)"),
                    self.update_tstop)
        app.connect(self.timeLoop, QtCore.SIGNAL("updateVInit(double)"),
                    self.update_v_init)
        self.timeLoop.start()

        ### Manager class
        self.manager = manager.Manager()
        self.path_to_hdf = None
        self.visio = None
        self.tab_model_already_populated = False
        self.ui.show()
        # Start the main event loop.
        #app.exec_()

        self.AUTHORS = 1
        self.YEAR = 0
        self.TITLE = 2
        self.ID = 3
        # Dictionary to hold the models class for the ModelDb integration
        self.models = Models()

    def populate_treeview_model(self, index, filter=""):
        """Populate the tree view on the gui and the scroll_area when the tab is 
        activated. 
        
        Args:
            index (int): the index of the activated tab
            
            filter (string): the string used to filter the search on the treeview
            """
        if index == 3 and (filter or not self.tab_model_already_populated):
            self.ui.tree_models.clear()

            # Populating the treeview with the dictionary
            for model_name in self.models.get_model_names(filter):
                model = self.models.get_model(model_name)
                model_item = QtGui.QTreeWidgetItem(self.ui.tree_models,
                                                   'Models')
                model_item.setText(self.YEAR, model.get_year())
                model_item.setText(self.AUTHORS, model.get_authors())
                model_item.setText(self.TITLE, model.get_title())
                model_item.setData(self.ID, 0, model.get_id())
                self._set_tooltip(model, model_item)

            #Resizing the column.
            #self.ui.tree_models.resizeColumnToContents(0)
            self.ui.tree_models.resizeColumnToContents(self.YEAR)
            self.ui.tree_models.resizeColumnToContents(self.TITLE)
            self.ui.tree_models.resizeColumnToContents(self.ID)
            self.ui.textBrowser_readme.clear()
            self.ui.textBrowser_readme.insertPlainText("No model selected.")
            self.tab_model_already_populated = True  #we populated only once.

    def _set_tooltip(self, model, model_item):
        # tooltip
        cols = self.ui.tree_models.columnCount()
        for i in range(cols):
            tooltip = model.get_tooltip()
            model_item.setToolTip(i, tooltip)

    def _retrieve_selected_model(self):
        "Return the model selected in the treeview"
        items = self.ui.tree_models.selectedItems()

        if items:
            selected_item = items[0]  #first element
            model_id = int(selected_item.text(self.ID))
            models_name = self.models.get_model_names()
            for name in models_name:
                mod = self.models.get_model(name)
                if model_id == mod.get_id():
                    return mod
        else:
            logger.info('No model selected!')
            return None

    def filter_list(self):
        "Filter the models list using the given text in the filter box"
        filter = self.ui.filter_input.text()
        logger.debug("Filtering list using keyword '%s'" % (filter))
        self.populate_treeview_model(3, filter)

    def about(self):
        self.aboutUi = uic.loadUi(
            os.path.join(os.path.dirname(__file__), self.ui_dir, "qtAbout.ui"))
        import neuronvisio
        name = '<font size=24><b>Neuronvisio %s<b><font>' % neuronvisio.__version__
        authors = '%s' % neuronvisio.__authors__

        self.aboutUi.name.setText(name)
        self.aboutUi.authors.setText(authors)
        self.aboutUi.show()

    def animation(self):
        self.ui.timelineSlider.setRange(0, len(self.manager.groups['t']))
        self.ui.timelineSlider.setEnabled(True)
        self.ui.show()

    def create_vector(self):
        var = self.ui.var.text()
        if not var:
            msgBox = QtGui.QMessageBox()
            msgBox.setText("No var specified.")
            msgBox.setIcon(QtGui.QMessageBox.Warning)
            msgBox.exec_()

        else:
            if self.ui.all_sections.isChecked():
                allCreated = self.manager.add_all_vecRef(str(var))
            elif self.ui.selected_section.isChecked():
                if self.visio.selected_cyl is not None:
                    sec = self.visio.cyl2sec[self.visio.selected_cyl]
                    self.manager.add_vecRef(str(var), sec)
                else:
                    msgBox = QtGui.QMessageBox()
                    msgBox.setText("<b>No vector has been created.</b>")
                    msg = "You need to select the section where you want to create the vector"
                    msgBox.setInformativeText(msg)
                    msgBox.setIcon(QtGui.QMessageBox.Warning)
                    msgBox.exec_()
        self.update_tree_view()

    def dt_changed(self):

        h.dt = self.ui.dtSpinBox.value()

    def init(self):
        """Set the vm_init from the spin button and prepare the simulator"""

        if not self.manager.refs.has_key('VecRef'):
            message = "No vector Created. Create at least one vector to run the simulation"
            logger.info(message)
            self.ui.statusbar.showMessage(message, 3500)
            return False
        else:
            v_init = self.ui.vSpinBox.value()
            # Set the v_init
            h.v_init = v_init
            h.finitialize(v_init)
            h.fcurrent()

            # Reset the time in the GUI
            self.ui.time_label.setNum(h.t)
            return True

    def insert_item_treeview(self,
                             groupName,
                             section_name,
                             vecs,
                             details=None):
        """Insert a new item in the treewidget. 
        Items are grouped by types. If a new type is provided a new group is added.
        Items are then grouped by section.
        In one section more than one variable is allowed.
        Each variable can have a detail associated in a dictionary form """
        group_root = self.get_unique_parent(groupName)
        sec_root = self.get_unique_parent(section_name, parentItem=group_root)
        for var, vec in vecs.iteritems():
            item = ItemRef(sec_root, vec)
            item.setText(0, var)
            item.setText(1, details)
            sec_root.addChild(item)

    def insert_refs_in_treeview(self):
        for group, ref_list in self.manager.refs.iteritems():
            for ref in ref_list:
                self.insert_item_treeview(group, ref.sec_name, ref.vecs,
                                          ref.detail)

    def launch_visio(self):
        msg = "Plotting..."
        self.ui.statusbar.showMessage(msg, 3500)
        if self.visio == None:

            # Checking there are sections in the model.
            i = 0
            for sec in h.allsec():
                i += 1

            if i > 0:
                self.visio = Visio(self.ui.sec_info_label, self.manager)
                self.visio.draw_model()
                self.ui.selected_section.setEnabled(True)
            else:
                msg = """No model found, no section created. You need 
                to have at least one."""
                logger.warning(msg)
        else:
            #Raise the visio window
            self.visio.container.show()
        # Enabling the animation
        try:
            self.animation()
        except KeyError:
            # No simulation run an nothing loaded.
            # just pass
            pass

    def load(self, path_to_file=None):
        """
        General loading method for any kind of format.
        Extensions recognised:
        .xml - NeuroML
        .hoc - NEURON hoc file
        .h5 - HDF file formatted according to Neuronvisio format.
        The file type is recognised using the extension.
        """
        if path_to_file == None:
            filename = QtGui.QFileDialog.getOpenFileName()
            if filename:
                path_to_file = str(filename)

        base_name, file_extension = os.path.splitext(path_to_file)
        try:
            if (file_extension == '.hoc'):
                file_path, hoc_file = os.path.split(path_to_file)
                self.load_hoc_model(file_path, hoc_file)
            elif (file_extension == ".xml"):
                self.manager.load_neuroml(path_to_file)
            elif (file_extension == ".h5"):
                self.load_hdf(path_to_file)
            else:
                raise ExtensionNotRecognised
        except ExtensionNotRecognised:

            msg = """
            File extension not recognised!! 
            Neuronvisio was not able to recognise the file extension. 
            Extensions recognised:
                    .xml - NeuroML
                    .hoc - NEURON hoc file
                    .h5 - HDF file formatted according to Neuronvisio format.
                    """
            logger.error(msg)

    def load_hdf(self, path_to_hdf):

        if path_to_hdf != None:
            self.path_to_hdf = os.path.abspath(path_to_hdf)

            self.manager.load_from_hdf(self.path_to_hdf)
            self.update_tree_view()
            msg = "Loaded db: %s" % self.path_to_hdf
            self.ui.statusbar.showMessage(msg, 3500)
            # Enablig the Animation button
            self.animation()
            # Disabling all the rest
            self.ui.init_btn.setEnabled(False)
            self.ui.run_btn.setEnabled(False)
            self.ui.create_vector.setEnabled(False)

    def load_hoc_model(self, model_dir, hoc_file):
        """Load an hoc files. It compiles the mod 
        before loading the hoc."""
        try:
            os.path.isfile(os.path.join(model_dir, hoc_file))
        except IOError:
            logger.error("Not existing file: %s" % e.value)

        old_dir = os.path.abspath(os.getcwd())
        logger.info("Path changed to %s" % (os.path.abspath(model_dir)))
        if model_dir != '':
            os.chdir(model_dir)
        try:
            # Add all mod files into current directory
            self.find_mod_files()

            # If windows
            if os.name == 'nt':
                self.windows_compile_mod_files('.')
                from neuron import h
                h.nrn_load_dll('./nrnmech.dll')
            else:  # Anything else.
                call(['nrnivmodl'])
                import neuron
                neuron.load_mechanisms(
                    '.')  # Auto loading. Not needed anymore.
            from neuron import gui  # to not freeze neuron gui
            from neuron import h
            logger.info("Loading model in %s from %s" % (model_dir, hoc_file))
            h.load_file(hoc_file)
        except Exception as e:
            logger.warning("Error running model: " + e.message)
        logger.info("Path changed back to %s" % old_dir)
        os.chdir(old_dir)
        return True

    def load_selected_model(self):
        "Load the model selected in the treeview."

        mod = self._retrieve_selected_model()
        if mod:
            model_path = mod.download_model()
            # tooltip
            cols = self.ui.tree_models.columnCount()
            items = self.ui.tree_models.selectedItems()
            model_item = items[0]
            for i in range(cols):
                tooltip = mod.get_tooltip()
                model_item.setToolTip(i, tooltip)

            if os.path.exists(os.path.join(mod.get_dir(), 'mosinit.hoc')):
                self.load_hoc_model(mod.get_dir(), 'mosinit.hoc')
            else:
                log_warning = """No mosinit.hoc present. I can't locate the `mosinit.hoc` therefore I can't load automatically the model."""
                logger.warning(log_warning)
                self.ui.statusbar.showMessage(
                    "WARNING: Can't load the model automatically.", 10000)
                info_warning = """<h3>No <code>mosinit.hoc</code> present!</h3>
                
                <p>I couldn't find any <code>mosinit.hoc</code>, therefore I have no idea how to
                load this model.</p>
                
                <p>What I can do is to open the folder where the model has been downloaded.
                Then, you need to read the docs of the model to know which file you need to load
                to get the model up.</p> 
            
                <p>How to load an arbitrary hoc file with Neuronvisio is written on the docs:
                <a href='http://neuronvisio.org/gettingstarted.html#loading-a-file'>Loading a file</a></p>
                """

                warning_box = QtGui.QMessageBox()
                warning_box.setTextFormat(QtCore.Qt.RichText)
                warning_box.setText(info_warning)
                warning_box.exec_()
                mod.browse()

    def make_animation_screenshots(self,
                                   time_start,
                                   time_stop=None,
                                   saving_dir='anim'):
        """Creates a series of screenshots which can be put together using memcoder 
        to make a movie
        
        Args:
            time_start (float): time from where to start to take the screenshots
            
            time_stop (float): time where to stop. If None will continue till the end
            
            saving_dir (string): directory where to save the screenshots. Default is anim
        
        """
        from mayavi import mlab
        t = self.manager.get_time()
        indx_start = t.indwhere("==", time_start)
        indx_stop = None
        if time_stop:
            indx_stop = t.indwhere("==", time_stop)
        else:
            indx_stop = len(t)

        if not os.path.exists(saving_dir):
            os.mkdir(saving_dir)

        png_format = "%09d.png"
        for i in range(int(indx_start), int(indx_stop)):

            figure_filename_animation = png_format % (i - indx_start)
            logger.debug(figure_filename_animation)
            self.sync_visio_3d(i)
            mlab.savefig(os.path.join(saving_dir, figure_filename_animation))

        logger.info("files created in %s" % saving_dir)
        logger.info("To create a video run:")
        logger.info("ffmpeg -f image2 -r 10 -i %s -sameq anim.mov -pass 2" %
                    png_format)

    def on_animation_time_return_pressed(self):
        "Getting the value from the text"
        time = self.ui.animationTime.text()
        try:
            time = int(time)
            time_list = self.manager.groups['t']
            time_point_indx = 0
            # If it's a vector on the just ran sim.
            if hasattr(time_list, 'to_python'):
                time_list = time_list.to_python()
                time_list = np.around(time_list, 3)

                time_point_indx = np.where(time_list == time)[0]
            # If it's a numpy array saved on the disk
            else:
                rounded = time_list.read().round(3)
                time_point_indx = np.where(rounded == time)[0]

            self.sync_visio_3d(time_point_indx)
            self.ui.timelineSlider.setValue(time_point_indx)
        except:
            logger.warning("Value not present in the array.")

    def on_timeline_value_changed(self):
        """Draw the animation according to the value of the timeline"""

        time_point_indx = self.ui.timelineSlider.value()
        self.sync_visio_3d(time_point_indx)

    def plot_vector(self):

        items = self.ui.treeWidget.selectedItems()

        x = None

        # Plot legend if required
        legend_status = self.ui.legend.isChecked()  #return True if toggled.

        points_status = self.ui.points.isChecked()
        # Retrieve the fig num
        fig_num = self.ui.fig_num_spinBox.value()

        for item in items:
            if item.childCount() == 0:  # Leaf, so it is the variable to plot

                sectionItem = item.parent()
                sectionName = str(sectionItem.text(0))  #Column used
                var = str(item.text(0))
                detail = str(item.text(1))

                groupName = str(sectionItem.parent().text(0))
                x = self.manager.groups[groupName]
                key = sectionName + "_" + var
                vecs_to_plot = {key: item.vec}
                self.manager.plot_vecs(vecs_to_plot,
                                       x=x,
                                       legend=legend_status,
                                       figure_num=fig_num,
                                       points=points_status)

    def get_unique_parent(self, name, parentItem=None):
        """Search the name in the treeview and return the qtElement.
        Raise an exception if not unique"""
        search = self.ui.treeWidget.findItems(name, Qt.MatchFixedString)
        root_item = None
        if len(search) == 0:  # We create the group
            root_item = None
            if parentItem is None:
                root_item = QtGui.QTreeWidgetItem(self.ui.treeWidget)
            else:
                root_item = QtGui.QTreeWidgetItem(parentItem)
            root_item.setText(0, name)

        elif len(search) == 1:
            root_item = search[0]

        else:
            error = "ERROR - too many match: %d. Group Name not \
            unique." % len(search)
            raise NameError(error)

        return root_item

    def run(self):
        """Run the simulator till tstop"""

        #Initializing
        if self.init():
            # Run
            msg = "Running simulation. It will take a while maybe..."
            self.ui.statusbar.showMessage(msg, 5000)
            while h.t < h.tstop:
                h.fadvance()

                self.ui.time_label.setText("<b>" + str(h.t) + "</b>")
            self.animation()

    def save_hdf(self):
        if not self.path_to_hdf:
            filename = QtGui.QFileDialog.getSaveFileName()
            self.path_to_hdf = str(filename)  # It will go with python 3
            if self.path_to_hdf != None:
                self.manager.save_to_hdf(self.path_to_hdf)
                msg = "Saved hdf file: %s" % self.path_to_hdf
                self.ui.statusbar.showMessage(msg, 3500)

    def select_model_treeview(self):
        """Synch the README and the modelOverview with the selected model."""
        mod = self._retrieve_selected_model()
        if mod:
            readme = mod.get_readme_html()
            overview = mod.get_overview()
            self.ui.textBrowser_readme.clear()
            self.ui.textBrowser_readme.insertHtml(readme)
            self.ui.textBrowser_model_overview.clear()
            self.ui.textBrowser_model_overview.insertHtml(overview)

    def sync_visio_3d(self, time_point_indx):

        var = self.ui.varToShow.text()
        var = str(var)  # This will go with Py3
        #
        #        #Update the label on the scale

        if len(self.manager.groups['t']) == time_point_indx:
            time_point_indx = time_point_indx - 1  # Avoid to go out of scale
        time = self.manager.groups['t'][time_point_indx]
        time_point_string = "%.3f" % round(time, 3)
        self.ui.animationTime.setText(time_point_string)

        start_value = float(self.ui.startValue.text())
        end_value = float(self.ui.endValue.text())

        self.visio.show_variable_timecourse(var, time_point_indx, start_value,
                                            end_value)

    def tstop_changed(self):
        h.tstop = self.ui.tstopSpinBox.value()

    def update_dt(self, new_dt):
        self.ui.dtSpinBox.setValue(new_dt)

    def update_tree_view(self):
        # Fill the treeview wit all the vectors created
        #Clear all the row
        self.ui.treeWidget.clear()
        self.insert_refs_in_treeview()

    def update_tstop(self, new_tstop):
        self.ui.tstopSpinBox.setValue(new_tstop)

    def update_v_init(self, new_v_init):
        self.ui.vSpinBox.setValue(new_v_init)

    def v_changed(self):
        h.v_init = self.ui.vSpinBox.value()

    # create the command line to compile mod files into nrnmech.dll and launch it. command line is
    # <cygwin-dir>\bin\bash.exe -c "cd <model-dir>; /usr/bin/sh -c '<nrnhome>/lib/mknrndll.sh <nrnhome>'"
    def windows_compile_mod_files(self, model_dir):
        # Get the required pathes
        if os.environ.has_key('NEURONHOME'):
            s1 = os.environ['NEURONHOME']
            s2 = os.environ['NEURONHOME']
        else:
            import _winreg
            k1 = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
                                 "SOFTWARE\\Cygwin\\setup")
            s1 = _winreg.QueryValueEx(k1, 'rootdir')[0]
            _winreg.CloseKey(k1)

            k2 = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
                                 "SOFTWARE\\NEURON\\nrn72")
            s2 = _winreg.QueryValueEx(k2, 'Install_Dir')[0]
            _winreg.CloseKey(k2)

        s1u = s1.replace('\\', '/')
        s2u = s2.replace('\\', '/')
        cmd = s1 + "\\bin\\bash.exe"
        arg = "cd " + model_dir + ";" + s1u + "/bin/sh -c '" + s2u + "/lib/mknrndll.sh " + s2u + "'"
        import subprocess
        subprocess.Popen([cmd, '-c', arg],
                         stdin=subprocess.PIPE).communicate(input="\r\n")

    # Copy all mod files under model directory into the root directory
    def find_mod_files(self):
        import shutil
        mod_files = []
        for root, dirnames, filenames in os.walk('.'):
            if (root == '.'): continue
            for filename in filenames:
                base_name, file_extension = os.path.splitext(filename)
                if file_extension == '.mod':
                    logger.info('Copy %s into model directory' %
                                os.path.join(root, filename))
                    # Double checking we are not copying over the same file.
                    logger.debug("%s %s" % (root, filename))
                    filename_src = os.path.join(root, filename)
                    filename_dest = os.path.join('.', filename)
                    if not os.path.isfile(filename_dest):
                        shutil.copy(filename_src, filename_dest)