class PM_ToolButtonGrid(PM_WidgetGrid):
    """
    The PM_ToolButtonGrid widget provides a grid of tool buttons that function
    as an I{exclusive button group}.
    
    @see: B{PM_ElementChooser} for an example of how this is used.
    
    @todo: Fix button size issue (e.g. all buttons are sized 32 x 32).
    """

    buttonList = []
    defaultCheckedId = -1  # -1 means no checked Id
    setAsDefault = True

    def __init__(self,
                 parentWidget,
                 title='',
                 buttonList=[],
                 alignment=None,
                 label='',
                 labelColumn=0,
                 spanWidth=True,
                 checkedId=-1,
                 setAsDefault=False,
                 isAutoRaise=False,
                 isCheckable=True):
        """
        Appends a PM_ToolButtonGrid widget to the bottom of I{parentWidget}, 
        the Property Manager Group box.
        
        @param parentWidget: The parent group box containing this widget.
        @type  parentWidget: PM_GroupBox
        
        @param title: The group box title.
        @type  title: str
        
        @param buttonList: A list of I{button info lists}. There is one button
                           info list for each button in the grid. The button
                           info list contains the following items:
                           1. Button Type - in this case its 'ToolButton'(str),
                           2. Button Id (int), 
                           3. Button text (str),
                           4. Button icon path (str),
                           5. Button tool tip (str),
                           6. Column (int), 
                           7. Row (int).
        @type  buttonList: list
        
        @param alignment:  The alignment of the toolbutton row in the parent 
                           groupbox. Based on its value,spacer items is added 
                           to the grid layout of the parent groupbox. 
        @type  alignment:  str
        
        @param label:      The label for the toolbutton row. If present, it is 
                           added to the same grid layout as the rest of the 
                           toolbuttons, in column number E{0}.
        @type  label:      str
        
        @param labelColumn: The column in the parentWidget's grid layout to which
                            this widget's label will be added. The labelColum
                            can only be E{0} or E{1}
        @type  labelColumn: int
        
        @param spanWidth: If True, the widget and its label will span the width
                      of the group box. Its label will appear directly above
                      the widget (unless the label is empty) and is left justified.
        @type  spanWidth: bool (default False)
                
        @param checkedId:  Checked button id in the button group. Default value
                           is -1 that implies no button is checked. 
        @type  checkedId:  int
        
        @param setAsDefault: If True, sets the I{checkedId} specified by the
                            user as the  default checked
        @type  setAsDefault: boolean
        """

        self.buttonGroup = QButtonGroup()
        self.buttonGroup.setExclusive(True)

        self.isAutoRaise = isAutoRaise
        self.isCheckable = isCheckable
        self.buttonsById = {}
        self.buttonsByText = {}

        if setAsDefault:
            self.setDefaultCheckedId(checkedId)

        PM_WidgetGrid.__init__(self, parentWidget, title, buttonList,
                               alignment, label, labelColumn, spanWidth)

    def _createWidgetUsingParameters(self, widgetParams):
        """
        Returns a tool button created using the parameters specified by the user
        
        @param widgetParams: A list of label parameters. This is a modified
                             using the original list returned 
                             by L{self.getWidgetInfoList}. The modified list
                             doesn't contain the row and column information.
        @type  widgetParams: list
        @see:  L{PM_WidgetGrid._createWidgetUsingParameters} (overrided in this
               method)
        @see:  L{PM_WidgetGrid.loadWidgets} which calls this method. 
        
        """
        buttonFont = self.getButtonFont()
        buttonParams = list(widgetParams)

        button = self._createToolButton(buttonParams)

        buttonId = buttonParams[1]

        if self.defaultCheckedId == buttonId:
            button.setChecked(True)
        button.setFont(buttonFont)
        button.setAutoRaise(self.isAutoRaise)
        button.setCheckable(self.isCheckable)
        self.buttonGroup.addButton(button, buttonId)

        self.buttonsById[buttonId] = button
        self.buttonsByText[str(button.text())] = button

        return button

    def getButtonFont(self):
        """
        Returns the font for the tool buttons in the grid.
        
        @return: Button font.
        @rtype:  U{B{QFont}<http://doc.trolltech.com/4/qfont.html>}
        """
        # Font for tool buttons.
        buttonFont = QFont(self.font())
        buttonFont.setFamily(BUTTON_FONT)
        buttonFont.setPointSize(BUTTON_FONT_POINT_SIZE)
        buttonFont.setBold(BUTTON_FONT_BOLD)
        return buttonFont

    def restoreDefault(self):
        """
        Restores the default checkedId.
        """
        if self.setAsDefault:
            for buttonInfo in self.buttonList:
                buttonId = buttonInfo[0]
                if buttonId == self.defaultCheckedId:
                    button = self.getButtonById(buttonId)
                    button.setChecked(True)
        return

    def setDefaultCheckedId(self, checkedId):
        """
        Sets the default checked id (button) to I{checkedId}. The current checked
        button is unchanged.
                      
        @param checkedId: The new default id for the tool button group.
        @type  checkedId: int
        """
        self.setAsDefault = True
        self.defaultCheckedId = checkedId

    def checkedButton(self):
        """
        Returns the tool button group's checked button, or E{0} if no button is
        checked.
        @return: Checked tool button or E{0}
        @rtype:  instance of QToolButton  or int
        """
        return self.buttonGroup.checkedButton()

    def checkedId(self):
        """
        Returns the id of the checkedButton(), or -1 if no button is checked.
        
        @return: The checked button Id
        @rtype:  int
        """
        return self.buttonGroup.checkedId()

    def getButtonByText(self, text):
        """
        Returns the button with its current text set to I{text}.
        
        @return: The button, or B{None} if no button was found.
        @rtype:  U{B{QToolButton}<http://doc.trolltech.com/4/qtoolbutton.html>}
        
        @note: If multiple buttons have the same text, only the last one is returned.
        """
        if self.buttonsByText.has_key(text):
            return self.buttonsByText[text]
        else:
            return None

    def getButtonById(self, buttonId):
        """
        Returns the button with the button id of I{buttonId}.
        
        return: The button, or B{None} if no button was found.
        rtype:  U{B{QToolButton}<http://doc.trolltech.com/4/qtoolbutton.html>}
        """
        if self.buttonsById.has_key(buttonId):
            return self.buttonsById[buttonId]
        else:
            return None

    def setButtonSize(self, width=32, height=32):
        """
        """
        for btn in self.buttonGroup.buttons():
            btn.setFixedSize(QSize(width, height))
Ejemplo n.º 2
0
class PM_ToolButtonGrid( PM_WidgetGrid ):
    """
    The PM_ToolButtonGrid widget provides a grid of tool buttons that function
    as an I{exclusive button group}.
    
    @see: B{PM_ElementChooser} for an example of how this is used.
    
    @todo: Fix button size issue (e.g. all buttons are sized 32 x 32).
    """
    
    buttonList       = []
    defaultCheckedId = -1    # -1 means no checked Id
    setAsDefault     = True
    
    
    def __init__(self, 
                 parentWidget, 
                 title        = '', 
                 buttonList   = [],
                 alignment    = None, 
                 label        = '',
                 labelColumn = 0,
                 spanWidth   = True,
                 checkedId    = -1, 
                 setAsDefault = False,   
                 isAutoRaise  = False,
                 isCheckable  = True
                 ):
        """
        Appends a PM_ToolButtonGrid widget to the bottom of I{parentWidget}, 
        the Property Manager Group box.
        
        @param parentWidget: The parent group box containing this widget.
        @type  parentWidget: PM_GroupBox
        
        @param title: The group box title.
        @type  title: str
        
        @param buttonList: A list of I{button info lists}. There is one button
                           info list for each button in the grid. The button
                           info list contains the following items:
                           1. Button Type - in this case its 'ToolButton'(str),
                           2. Button Id (int), 
                           3. Button text (str),
                           4. Button icon path (str),
                           5. Button tool tip (str),
                           6. Column (int), 
                           7. Row (int).
        @type  buttonList: list
        
        @param alignment:  The alignment of the toolbutton row in the parent 
                           groupbox. Based on its value,spacer items is added 
                           to the grid layout of the parent groupbox. 
        @type  alignment:  str
        
        @param label:      The label for the toolbutton row. If present, it is 
                           added to the same grid layout as the rest of the 
                           toolbuttons, in column number E{0}.
        @type  label:      str
        
        @param labelColumn: The column in the parentWidget's grid layout to which
                            this widget's label will be added. The labelColum
                            can only be E{0} or E{1}
        @type  labelColumn: int
        
        @param spanWidth: If True, the widget and its label will span the width
                      of the group box. Its label will appear directly above
                      the widget (unless the label is empty) and is left justified.
        @type  spanWidth: bool (default False)
                
        @param checkedId:  Checked button id in the button group. Default value
                           is -1 that implies no button is checked. 
        @type  checkedId:  int
        
        @param setAsDefault: If True, sets the I{checkedId} specified by the
                            user as the  default checked
        @type  setAsDefault: boolean
        """
                
        self.buttonGroup = QButtonGroup()
        self.buttonGroup.setExclusive(True)
        
        self.isAutoRaise = isAutoRaise    
        self.isCheckable = isCheckable
        self.buttonsById   = {}
        self.buttonsByText = {}
        
        if setAsDefault:
            self.setDefaultCheckedId(checkedId)
        
                    
        PM_WidgetGrid.__init__(self, 
                               parentWidget , 
                               title, 
                               buttonList, 
                               alignment,
                               label,
                               labelColumn,
                               spanWidth
                              ) 
        
            
    def _createWidgetUsingParameters(self, widgetParams):
        """
        Returns a tool button created using the parameters specified by the user
        
        @param widgetParams: A list of label parameters. This is a modified
                             using the original list returned 
                             by L{self.getWidgetInfoList}. The modified list
                             doesn't contain the row and column information.
        @type  widgetParams: list
        @see:  L{PM_WidgetGrid._createWidgetUsingParameters} (overrided in this
               method)
        @see:  L{PM_WidgetGrid.loadWidgets} which calls this method. 
        
        """               
        buttonFont = self.getButtonFont() 
        buttonParams = list(widgetParams) 
        
        button = self._createToolButton(buttonParams)
        
        buttonId = buttonParams[1]     
        
        if self.defaultCheckedId == buttonId:
            button.setChecked(True)
        button.setFont(buttonFont)
        button.setAutoRaise(self.isAutoRaise)
        button.setCheckable(self.isCheckable)
        self.buttonGroup.addButton(button, buttonId)
        
        self.buttonsById[buttonId]    = button
        self.buttonsByText[str(button.text())] = button     
        
        return button
                   
        
    def getButtonFont(self):
        """
        Returns the font for the tool buttons in the grid.
        
        @return: Button font.
        @rtype:  U{B{QFont}<http://doc.trolltech.com/4/qfont.html>}
        """
        # Font for tool buttons.
        buttonFont = QFont(self.font())
        buttonFont.setFamily(BUTTON_FONT)
        buttonFont.setPointSize(BUTTON_FONT_POINT_SIZE)
        buttonFont.setBold(BUTTON_FONT_BOLD)
        return buttonFont              

    def restoreDefault(self):
        """
        Restores the default checkedId.
        """
        if self.setAsDefault:
            for buttonInfo in self.buttonList:
                buttonId = buttonInfo[0]
                if buttonId == self.defaultCheckedId:
                    button = self.getButtonById(buttonId)
                    button.setChecked(True)
        return
    
    def setDefaultCheckedId(self, checkedId):
        """
        Sets the default checked id (button) to I{checkedId}. The current checked
        button is unchanged.
                      
        @param checkedId: The new default id for the tool button group.
        @type  checkedId: int
        """
        self.setAsDefault = True
        self.defaultCheckedId = checkedId
        
    def checkedButton(self):
        """
        Returns the tool button group's checked button, or E{0} if no button is
        checked.
        @return: Checked tool button or E{0}
        @rtype:  instance of QToolButton  or int
        """
        return self.buttonGroup.checkedButton()
        
    def checkedId(self):
        """
        Returns the id of the checkedButton(), or -1 if no button is checked.
        
        @return: The checked button Id
        @rtype:  int
        """
        return self.buttonGroup.checkedId()
    
    def getButtonByText(self, text):
        """
        Returns the button with its current text set to I{text}.
        
        @return: The button, or B{None} if no button was found.
        @rtype:  U{B{QToolButton}<http://doc.trolltech.com/4/qtoolbutton.html>}
        
        @note: If multiple buttons have the same text, only the last one is returned.
        """
        if self.buttonsByText.has_key(text):
            return self.buttonsByText[text]
        else:
            return None
        
    def getButtonById(self, buttonId):
        """
        Returns the button with the button id of I{buttonId}.
        
        return: The button, or B{None} if no button was found.
        rtype:  U{B{QToolButton}<http://doc.trolltech.com/4/qtoolbutton.html>}
        """
        if self.buttonsById.has_key(buttonId):
            return self.buttonsById[buttonId]
        else:
            return None
    
    def setButtonSize(self, width = 32, height = 32):
        """
        """
        for btn in self.buttonGroup.buttons():
            btn.setFixedSize(QSize(width, height))
class PM_RadioButtonList(PM_GroupBox):
    """
    The PM_RadioButtonList widget provides a list of radio buttons that function
    as an I{exclusive button group}.
    """

    buttonList = []
    defaultCheckedId = -1  # -1 means no checked Id
    setAsDefault = True
    labelWidget = None

    def __init__(self,
                 parentWidget,
                 title='',
                 label='',
                 labelColumn=0,
                 buttonList=[],
                 checkedId=-1,
                 setAsDefault=False,
                 spanWidth=True,
                 borders=True):
        """
        Appends a PM_RadioButtonList widget to the bottom of I{parentWidget}, 
        the Property Manager dialog or group box.
        
        @param parentWidget: The parent group box containing this widget.
        @type  parentWidget: PM_GroupBox or PM_Dialog
        
        @param title: The group box title.
        @type  title: str
        
        @param label:      The label for the coordinate spinbox.
        @type  label:      str
        
        @param labelColumn: The column in the parentWidget's grid layout to 
                            which this widget's label will be added. 
                            The labelColum can only be E{0} or E{1}
        @type  labelColumn: int
                
        
        @param buttonList: A list of I{button info lists}. There is one button
                           info list for each radio button in the list. The 
                           button info list contains the following three items:
                           1). Button Id (int), 
                           2). Button text (str),
                           3). Button tool tip (str).
        @type  buttonList: list
        
        @param spanWidth: If True, the widget and its label will span the width
                         of the group box. Its label will appear directly above
                         the widget (unless the label is empty) and is left 
                         justified.
        @type  spanWidth: bool (default False)
        
        
        @param borders: If true (default), this widget will have borders displayed. 
                        otherwise the won't be any outside borders around the 
                        set of radio buttons this class provides
        @type borders: boolean
        """

        # Intializing label, labelColumn etc is needed before doing
        # PM_GroupBox.__init__. This is done so that
        # self.parentWidget.addPmWidget(self) done at the end of __init__
        # works properly.
        # 'self.parentWidget.addPmWidget(self)' is done to avoid a bug where a
        # groupbox is always appended as the 'last widget' when its
        # parentWidget is also a groupbox. This is due to other PM widgets
        #(e.g. PM_PushButton)add themselves to their parent widget in their
        #__init__ using self.parentWidget.addPmWidget(self). So doing the
        #same thing here. More general fix is needed in PM_GroupBox code
        # --Ninad 2007-11-14 (comment copied from PM_coordinateSpinBoxes)
        self.label = label
        self.labelColumn = labelColumn
        self.spanWidth = spanWidth

        if label:  # Create this widget's QLabel.
            self.labelWidget = QLabel()
            self.labelWidget.setText(label)

        PM_GroupBox.__init__(self, parentWidget, title)

        # These are needed to properly maintain the height of the grid if
        # all buttons in a row are hidden via hide().
        self.vBoxLayout.setMargin(0)
        self.vBoxLayout.setSpacing(0)

        self.buttonGroup = QButtonGroup()
        self.buttonGroup.setExclusive(True)

        self.parentWidget = parentWidget
        self.buttonList = buttonList

        if setAsDefault:
            self.setDefaultCheckedId(checkedId)

        self.buttonsById = {}
        self.buttonsByText = {}

        # Create radio button list from button info.
        for buttonInfo in buttonList:
            buttonId = buttonInfo[0]
            buttonText = buttonInfo[1]
            buttonToolTip = buttonInfo[2]

            button = QRadioButton(self)

            button.setText(buttonText)
            button.setToolTip(buttonToolTip)  # Not working.
            button.setCheckable(True)
            if checkedId == buttonId:
                button.setChecked(True)
            self.buttonGroup.addButton(button, buttonId)
            self.vBoxLayout.addWidget(button)

            self.buttonsById[buttonId] = button
            self.buttonsByText[buttonText] = button

        if isinstance(self.parentWidget, PM_GroupBox):
            self.parentWidget.addPmWidget(self)
        else:
            #@@ Should self be added to self.parentWidget's widgetList?
            #don't know. Retaining old code -- Ninad 2008-06-23
            self._widgetList.append(self)
            self._rowCount += 1

        if not borders:
            #reset the style sheet so that there are no borders around the
            #radio button set this class provides.
            self.setStyleSheet(self._getAlternateStyleSheet())

    def restoreDefault(self):
        """
        Restores the default checkedId.
        """
        if self.setAsDefault:
            for buttonInfo in self.buttonList:
                buttonId = buttonInfo[0]
                if buttonId == self.defaultCheckedId:
                    button = self.getButtonById(buttonId)
                    button.setChecked(True)
        return

    def setDefaultCheckedId(self, checkedId):
        """
        Sets the default checked id (button) to I{checkedId}. The current checked
        button is unchanged.
                      
        @param checkedId: The new default id for the tool button group.
        @type  checkedId: int
        """
        self.setAsDefault = True
        self.defaultCheckedId = checkedId

    def checkedButton(self):
        """
        Returns the tool button group's checked button, or 0 if no buttons are
        checked.
        """
        return self.buttonGroup.checkedButton()

    def checkedId(self):
        """
        Returns the id of the checkedButton(), or -1 if no button is checked.
        """
        return self.buttonGroup.checkedId()

    def getButtonByText(self, text):
        """
        Returns the button with its current text set to I{text}.
        """
        if self.buttonsByText.has_key(text):
            return self.buttonsByText[text]
        else:
            return None

    def getButtonById(self, buttonId):
        """
        Returns the button with the button id of I{buttonId}.
        """
        if self.buttonsById.has_key(buttonId):
            return self.buttonsById[buttonId]
        else:
            return None

    def _getAlternateStyleSheet(self):
        """
        Return the style sheet for the groupbox. This sets the following 
        properties only:
         - border style
         - border width
         - border color
         - border radius (on corners)
        @see: L{PM_GroupBox._getStyleSheet} (overrided here)
        """

        styleSheet = "QGroupBox {border-style:hidden;\
        border-width: 0px;\
        border-color: " ";\
        border-radius: 0px;\
        min-width: 10em; }"

        return styleSheet


# End of PM_RadioButtonList ############################
Ejemplo n.º 4
0
class GamessProp(QDialog, Ui_GamessPropDialog):
    """
    The Gamess Jig Properties dialog used for:
    - running a GAMESS energy calculation on a structure (group of atoms).
    - running a GAMESS optimization on a structure.
    - setting and saving the GAMESS parameters used for an energy calculation or optimization.
    """
    def __init__(self):
        QDialog.__init__(self)
        self.setModal(True)
        self.setupUi(self)

        self.ecm_btngrp = QButtonGroup()
        self.ecm_btngrp.setExclusive(True)
        objId = 0
        for obj in self.ecm_grpbox.children():
            if isinstance(obj, QAbstractButton):
                self.ecm_btngrp.addButton(obj)
                self.ecm_btngrp.setId(obj, objId)
                objId +=1

        self.scftyp_btngrp = QButtonGroup()
        self.scftyp_btngrp.setExclusive(True)
        objId = 0
        for obj in self.scftyp_grpbox.children():
            if isinstance(obj, QAbstractButton):
                self.scftyp_btngrp.addButton(obj)
                self.scftyp_btngrp.setId(obj, objId)
                objId +=1

        self.connect(self.cancel_btn,SIGNAL("clicked()"),self.reject)
        self.connect(self.ecm_btngrp,SIGNAL("buttonPressed(int)"),self.set_ecmethod)
        self.connect(self.multi_combox,SIGNAL("activated(int)"),self.set_multiplicity)
        self.connect(self.run_job_btn,SIGNAL("clicked()"),self.run_job)
        self.connect(self.save_btn,SIGNAL("clicked()"),self.accept)
        self.connect(self.runtyp_combox,SIGNAL("activated(int)"),self.calculate_changed)
        self.connect(self.choose_color_btn,SIGNAL("clicked()"),self.change_jig_color)
        self.connect(self.whats_this_btn,SIGNAL("clicked()"),self.whats_this)
        ##self.connect(self.new_btn,SIGNAL("clicked()"),self.addServer)
        ##self.connect(self.exit_btn,SIGNAL("clicked()"),self.close)
        ##self.connect(self.server_listview,SIGNAL("currentChanged(QListViewItem*)"),self.changeServer)
        ##self.connect(self.engine_combox,SIGNAL("activated(const QString&)"),self.engineChanged)
        ##self.connect(self.del_btn,SIGNAL("clicked()"),self.deleteServer)
        self.sManager = ServerManager()
        self.servers = self.sManager.getServers()
        self.server = self.servers[0]

        self.name_linedit.setWhatsThis("""Name of the GAMESS jig.""")
        self.runtyp_combox.setWhatsThis("""Type of calculation, where "Energy" calculates the Energy Minima,and "Optimization" calculates the "Equilibrium Geometry".""")
        self.comment_linedit.setWhatsThis("""Description, also placed in the comment line of the $DATA section of the INP file.""")
        self.choose_color_btn.setWhatsThis("""Change the GAMESS jig color.""")
        self.rhf_radiobtn.setWhatsThis("""Restricted Hartree-Fock.  All electrons are paired and each spatial orbital is doubly occupied.  Cannot be used with multiplicities greater than 1.""")
        self.uhf_radiobtn.setWhatsThis("""Unrestricted Hartree-Fock.  All electrons are unpaired and spatial (spin) orbitals are uniquely defined for each electron.  More time consuming, but more accurate, than ROHF.  """)
        self.rohf_radiobtn.setWhatsThis("""Restricted Open-shell Hartree-Fock.  Spin-paired electrons are assigned to doubly-occupied spatial orbitals, while electrons with unpaired spins are provided unique spatial orbitals.""")
        self.icharg_spinbox.setWhatsThis("""The total charge of the structure to be treated quantum mechanically (ICHARG).""")
        self.multi_combox.setWhatsThis("""N + 1, where N is the number of unpaired electrons (MULT).""")
        self.memory_spinbox.setWhatsThis("""System memory reserved for calculation""")
        self.dirscf_checkbox.setWhatsThis("""Check this box to run the calculation in RAM and avoid hard disk usage for integral storage.""")
        self.gbasis_combox.setWhatsThis("""Select from among the standard Gaussian-type basis sets and semi-empirical parameters in GAMESS.""")
        self.checkBox10_3_2.setWhatsThis("""Reads the $HESS group from the output file of a previous GAMESS calculation.  Only valid for identical molecules.""")
        self.checkBox10_2_2_2.setWhatsThis("""Reads the $VEC group from the output of a previous GAMESS calculation. Requires that both the molecule and basis set be identical.  Useful for restarted calculations and starting orbitals for electron correlation methods.""")
        self.none_radiobtn.setWhatsThis("""Select this button to neglect electron correlation in the calculation.""")
        self.dft_radiobtn.setWhatsThis("""Select this button to perform a density functional theory calculation.""")
        self.mp2_radiobtn.setWhatsThis("""Select this button to perform a Second-Order Moeller Plesset calculation.""")
        self.dfttyp_combox.setWhatsThis("""Select an available density functional in GAMESS.""")
        self.gridsize_combox.setWhatsThis("""Select the grid spacing for the DFT calculation.""")
        self.core_electrons_checkbox.setWhatsThis("""Check this box to include both the valence and core electrons in the MP2 calculation.""")
        self.density_conv_combox.setWhatsThis("""Selects the accuracy of the electron density convergence for the calculation (CONV).""")
        self.rmsd_combox.setWhatsThis("""Gradient convergence tolerance (OPTTOL), in Hartree/Bohr. Convergence of a geometry search requires the largest component of the gradient to be less than this value, and the root mean square gradient less than 1/3 of OPTTOL.  (default=0.0001)""")
        self.iterations_spinbox.setWhatsThis("""Maximum number of SCF iteration cycles (MAXIT).""")
        self.edit_input_file_cbox.setWhatsThis("""Opens the INP file generated by NanoEngineer-1 in a text editor.""")
        self.whats_this_btn.setWhatsThis("""What's This Help Utility""")
        self.run_job_btn.setWhatsThis("""Save GAMESS parameters, generates the INP file and launches the GAMESS job.""")
        self.save_btn.setWhatsThis("""Save GAMESS parameters and generates the INP file.  It does not launch the GAMESS job.""")
        self.cancel_btn.setWhatsThis("""Cancels changes and closes dialog.""")

    def showDialog(self, job):
        """
        Display the GAMESS Jig Properties dialog
        """
        self.gamessJig =  job.gamessJig
        self.job = job
        self.pset = self.gamessJig.pset
        self.win = self.gamessJig.assy.w
        self.glpane = self.gamessJig.assy.o

        if self._setup(): return
        self.exec_()


    ######Private or helper methods###############################
    def _setup(self):
        """
        Setup widgets to initial (default or defined) values. Return True on error.
        """
        #To fix bug 684
        #if gamess.is_disabled():
        #    self.run_job_btn.setEnabled(False)
        #else:
        #    self.run_job_btn.setEnabled(True)

        self.jig_attrs = self.gamessJig.copyable_attrs_dict() # Save the jig's attributes in case of Cancel.

        # Jig color
        self.original_normcolor = self.gamessJig.normcolor
        self.jig_QColor = RGBf_to_QColor(self.gamessJig.normcolor) # Used as default color by Color Chooser
        self.jig_color_pixmap = get_widget_with_color_palette(
                self.jig_color_pixmap, self.jig_QColor)

        # Init the top widgets (name, runtyp drop box, comment)
        self.name_linedit.setText(self.gamessJig.name)
        self.runtyp_combox.setCurrentIndex(self.pset.ui.runtyp) # RUNTYP
        self.calculate_changed(self.pset.ui.runtyp)
        self.comment_linedit.setText(self.pset.ui.comment)

        # Electronic Structure Properties section.
        btn = self.scftyp_btngrp.button(self.pset.ui.scftyp)# RHF, UHF, or ROHF
        btn.setChecked(True)
        self.icharg_spinbox.setValue(self.pset.ui.icharg) # Charge
        self.multi_combox.setCurrentIndex(self.pset.ui.mult) # Multiplicity
        # Disable RHF if multiplicity is not the first item.
        if self.pset.ui.mult == 0:
            self.rhf_radiobtn.setEnabled(1) # Enable RHF
        else:
            self.rhf_radiobtn.setEnabled(0) # Disable RHF

        # System Memory and Usage
        self.dirscf_checkbox.setChecked(self.pset.ui.dirscf) # DIRSCF
        self.memory_spinbox.setValue(self.pset.ui.memory) # Memory

        # Electron Correlation Method and Basis Set
        ecm = self.pset.ui.ecm
        btn = self.ecm_btngrp.button(self.pset.ui.ecm)# None, DFT or MP2
        btn.setChecked(True)
        self.set_ecmethod(self.pset.ui.ecm) # None, DFT or MP2
        self.gbasis_combox.setCurrentIndex(self.pset.ui.gbasis) # Basis set

        # Load the combo box with all the valid DFT functions.
        self._load_dfttyp_combox()
        self.dfttyp_combox.setCurrentIndex(self.pset.ui.dfttyp) # DFT Functional
        self.gridsize_combox.setCurrentIndex(self.pset.ui.gridsize) # Grid Size
        self.core_electrons_checkbox.setChecked(self.pset.ui.ncore) # Include core electrons

        # Convergence Criteria
        self.density_conv_combox.setCurrentIndex(self.pset.ui.conv) # Density Convergence
        self.rmsd_combox.setCurrentIndex(self.pset.ui.rmsdconv) # RMSD Convergence
        self.iterations_spinbox.setValue(self.pset.ui.iterations) # Iterations

# These have been removed per discussions with Damian.
# Mark 050628
#        self.extrap_checkbox.setChecked(self.pset.ui.extrap) # EXTRAP
#        self.damp_checkbox.setChecked(self.pset.ui.damp) # DAMP
#        self.diis_checkbox.setChecked(self.pset.ui.diis) # DIIS
#        self.shift_checkbox.setChecked(self.pset.ui.shift) # SHIFT
#        self.soscf_checkbox.setChecked(self.pset.ui.soscf) # SOSCF
#        self.rstrct_checkbox.setChecked(self.pset.ui.rstrct) # RSTRCT

        # Load the server combo box
        #self._reloadServerList() # Not used in A6.  Mark.

        # If there is an error, return 1. NIY.
        return 0

    def _reloadServerList(self):
        """
        Load the server combo box
        """
        self.server_combox.clear()
        for s in self.servers:
            self.server_combox.insertItem(100, s.hostname + "-" + s.engine)
            # 100 makes sure item is appended to list. [mark 2007-05-04]
        if self.server not in self.servers:
            self.server = self.servers[0]
        indx = self.servers.index(self.server)
        self.server_combox.setCurrentIndex(indx)

    def _load_dfttyp_combox(self):
        """
        Load list of DFT function in a combobox widget
        """
        self.dfttyp_combox.clear() # Clear all combo box items
        if self.server.engine == 'GAMESS':
            for f in gms_dfttyp_items:
                self.dfttyp_combox.insertItem(100, f)
                # 100 makes sure item is appended to list. [mark 2007-05-04]
        elif self.server.engine == 'PC GAMESS':
            for f in pcgms_dfttyp_items:
                self.dfttyp_combox.insertItem(100, f)
                # 100 makes sure item is appended to list. [mark 2007-05-04]
        else:
            print "load_dfttyp_combox: Unknown GAMESS Version.  Loading GAMES DFT functionals."
            for f in gms_dfttyp_items:
                self.dfttyp_combox.insertItem(100, f)
                # 100 makes sure item is appended to list. [mark 2007-05-04]

    def _update_gbasis_list(self, val):
        """
        Add/remove AM1 and PM3 to/from the gbasis list.
        """
        citem = self.gbasis_combox.currentIndex()
        if val == DFT or val == MP2:
            if self.gbasis_combox.count() == 18:
                self.gbasis_combox.removeItem(0)
                self.gbasis_combox.removeItem(0)
                self.gbasis_combox.setCurrentIndex(max(0, citem-2))
        else:
            if self.gbasis_combox.count() != 18:
                self.gbasis_combox.insertItem(0,"PM3") # 0 prepends item to list.
                self.gbasis_combox.insertItem(0,"AM1")
                self.gbasis_combox.setCurrentIndex(citem+2)

    def _save_ui_settings(self):
        """
        Save the UI settings in the Gamess jig pset.
        There is one setting for each pset.
        """
        self.pset.ui.comment = str(self.comment_linedit.text()) # Description
        self.pset.ui.runtyp = self.runtyp_combox.currentIndex() # RUNTYP = Energy or Optimize

        # Electronic Structure Props and Basis Set section.
        self.pset.ui.scftyp = self.scftyp_btngrp.checkedId() # SCFTYP = RHF, UHF, or ROHF
        self.pset.ui.icharg = self.icharg_spinbox.value() # Charge
        self.pset.ui.mult = self.multi_combox.currentIndex() # Multiplicity

        # System Memory and Usage
        self.pset.ui.memory = self.memory_spinbox.value() # Memory
        self.pset.ui.dirscf = self.dirscf_checkbox.isChecked() # DIRSCF

        # Electron Correlation Method
        self.pset.ui.ecm = self.ecm_btngrp.checkedId() # None, DFT or MP2
        #self.pset.ui.inttyp = self.ecm_btngrp.selectedId() # INTTYP
        self.pset.ui.gbasis = self.gbasis_combox.currentIndex() # Basis Set
        self.pset.ui.gbasisname = str(self.gbasis_combox.currentText())
        self.pset.ui.dfttyp = self.dfttyp_combox.currentIndex() # DFT Functional Type
        self.pset.ui.gridsize = self.gridsize_combox.currentIndex() # Grid Size
        self.pset.ui.ncore = self.core_electrons_checkbox.isChecked() # Include core electrons

        # Convergence Criteria
        self.pset.ui.conv = self.density_conv_combox.currentIndex() # Density Convergence
        self.pset.ui.rmsdconv = self.rmsd_combox.currentIndex() # RMSD Convergence
        self.pset.ui.iterations = self.iterations_spinbox.value() # Iterations

#        self.pset.ui.extrap = self.extrap_checkbox.isChecked() # EXTRAP
#        self.pset.ui.damp = self.damp_checkbox.isChecked() # DAMP
#        self.pset.ui.diis = self.diis_checkbox.isChecked() # DIIS
#        self.pset.ui.shift = self.shift_checkbox.isChecked() # SHIFT
#        self.pset.ui.soscf = self.soscf_checkbox.isChecked() # SOSCF
#        self.pset.ui.rstrct = self.rstrct_checkbox.isChecked() # RSTRCT

    def _save_job_parms(self):
        calculate = ['Energy', 'Optimization']
        self.job.Calculation = calculate[self.pset.ui.runtyp]
        self.job.Description = self.pset.ui.comment
        self.job.server =  self.server
        ##Copy some  attributes from the server object to job description
        self.job.Server_id = self.server.server_id
        self.job.Engine = self.server.engine

    ######End of private or helper methods.########################

    ###### Unused methods ###############

    def openServerManager(self):
        """
        Pop up ServerManagerDialog to edit the properties of the servers.
        """
        self.sManager.showDialog(self.server)
        self.servers = self.sManager.getServers()
        self._reloadServerList()

    def serverChanged(self, si):
        """
        User has changed server, so update the DFT comboBox. Currently not used.
        """
        self.server = self.servers[si]
        self._load_dfttyp_combox()

    ###### End of unused methods ###############

    ##########Slot methods for some GUI controls################

    def calculate_changed(self, val):
        """
        """
        if val == 0: # Energy
            self.rmsd_lbl.setEnabled(0)
            self.rmsd_combox.setEnabled(0)
            self.iterations_lbl.setEnabled(0)
            self.iterations_spinbox.setEnabled(0)
#            self.extrap_checkbox.setEnabled(0)
#            self.rstrct_checkbox.setEnabled(0)
#            self.damp_checkbox.setEnabled(0)
#            self.diis_checkbox.setEnabled(0)
#            self.shift_checkbox.setEnabled(0)
#            self.soscf_checkbox.setEnabled(0)
        else: # Optimization
            self.rmsd_lbl.setEnabled(1)
            self.rmsd_combox.setEnabled(1)
            self.iterations_lbl.setEnabled(1)
            self.iterations_spinbox.setEnabled(1)
#            self.extrap_checkbox.setEnabled(1)
#            self.rstrct_checkbox.setEnabled(1)
#            self.damp_checkbox.setEnabled(1)
#            self.diis_checkbox.setEnabled(1)
#            self.shift_checkbox.setEnabled(1)
#            self.soscf_checkbox.setEnabled(1)

    def set_multiplicity(self, val):
        """
        Enable/disable widgets when user changes Multiplicity.
        """
        if val != 0:
            qt4todo("if scftyp[self.scftyp_btngrp.selectedId()] != 'RHF':")
            #if scftyp[self.scftyp_btngrp.selectedId()] != 'RHF':
            #    self.rhf_radiobtn.setEnabled(0)
            #    return

            ret = QMessageBox.warning( self, "Multiplicity Conflict",
                "If Multiplicity is greater than 1, then <b>UHF</b> or <b>ROHF</b> must be selected.\n"
                "Select Cancel to keep <b>RHF</b>.",
                "&UHF", "&ROHF", "Cancel",
                0, 2 )

            if ret == 0: # UHF
                self.uhf_radiobtn.toggle()
                self.rhf_radiobtn.setEnabled(0)

            elif ret == 1: # ROHF
                self.rohf_radiobtn.toggle()
                self.rhf_radiobtn.setEnabled(0)

            elif ret == 2: # Cancel
                self.multi_combox.setCurrentIndex(0)

        elif val == 0:
            self.rhf_radiobtn.setEnabled(1)

    def set_ecmethod(self, val):
        """
        Enable/disable widgets when user changes Electron Correlation Method.
        """
        #print "set_ecmethod = ", val
        if val == DFT:
            self.dfttyp_label.setEnabled(1)
            self.dfttyp_combox.setEnabled(1)
            self.gridsize_label.setEnabled(1)
            self.gridsize_combox.setEnabled(1)
            self.core_electrons_checkbox.setChecked(0)
            self.core_electrons_checkbox.setEnabled(0)

        elif val == MP2:
            self.core_electrons_checkbox.setEnabled(1)
            self.dfttyp_label.setEnabled(0)
            self.dfttyp_combox.setEnabled(0)
            self.gridsize_label.setEnabled(0)
            self.gridsize_combox.setEnabled(0)

        else: # None = Hartree-Fock
            self.dfttyp_label.setEnabled(0)
            self.dfttyp_combox.setEnabled(0)
            self.gridsize_label.setEnabled(0)
            self.gridsize_combox.setEnabled(0)
            self.core_electrons_checkbox.setChecked(0)
            self.core_electrons_checkbox.setEnabled(0)

        # AM1 and PM3 are not options for DFT or MP2.
        # We have to remove or add them from the combo box.
        self._update_gbasis_list(val)

    def open_tmp_inputfile(self):
        """
        Writes a temporary GAMESS inputfile of the current Gamess jig and opens the
        file in an editor.
        """
        # Make tmp_inputfile filename (i.e. ~/Nanorex/temp/jigname_parms_info.inp)
        from platform_dependent.PlatformDependent import find_or_make_Nanorex_subdir
        tmpdir = find_or_make_Nanorex_subdir('temp')
        basename = self.gamessJig.name + "-" + self.gamessJig.gms_parms_info('_')
        tmp_inputfile = os.path.join(tmpdir, "%s.inp" % basename)

        # Write INP file (in ~/Nanorex/temp subdirectory)
        from analysis.GAMESS.files_gms import writegms_inpfile
        writegms_inpfile(tmp_inputfile, self.gamessJig)

        from platform_dependent.PlatformDependent import open_file_in_editor
        open_file_in_editor(tmp_inputfile)

    def run_job(self):
        """
        Slot method for the 'Save and Run' button
        """
        self.accept()

        # Run GAMESS job.  Return value r:
        # 0 = success
        # 1 = job cancelled
        # 2 = job failed.
        r = self.job.launch()

        if r == 1: # Job was cancelled
            env.history.message( redmsg( "GAMESS job cancelled."))
            return

        if r == 2: # Job failed.
            env.history.message( redmsg( "GAMESS job failed. Maybe you didn't set the right Gamess executable file. Make sure you can run the same job manually."))
            return

        # Job success.
        fn = self.gamessJig.outputfile

        # Print energy or move atoms
        if self.pset.ui.runtyp == 0: #Energy
            self.gamessJig.print_energy()
        else:  # Optimize
            try:
                r = self.gamessJig.move_optimized_atoms()
                # r = insertgms(self.gamessJig.assy, fn)
            except:
                print_compact_traceback( "GamessProp.run_job(): error reading GAMESS OUT file [%s]: " % fn )
                env.history.message( redmsg( "Internal error while inserting GAMESS geometry: " + fn) )
            else:
                if r:
                    env.history.message(redmsg( "Atoms not adjusted."))
                else:
                    self.gamessJig.assy.changed() # The file and the part are not the same.
                    self.gamessJig.print_energy() # Print the final energy from the optimize OUT file, too.
                    env.history.message( "Atoms adjusted.")

    def change_jig_color(self):
        """
        Slot method to change the jig's color.
        """
        color = QColorDialog.getColor(self.jig_QColor, self)

        if color.isValid():
            self.jig_QColor = color
            self.jig_color_pixmap = get_widget_with_color_palette(
                self.jig_color_pixmap, self.jig_QColor)

            self.gamessJig.color = self.gamessJig.normcolor = QColor_to_RGBf(color)
            self.glpane.gl_update()

    def accept(self):
        """
        The slot method for the 'Save' button.
        """
        QDialog.accept(self)
        self.gamessJig.try_rename(self.name_linedit.text())
        self._save_ui_settings()
        self.gamessJig.update_gamess_parms() # Update all the GAMESS parameters.
        self._save_job_parms()
        if self.edit_input_file_cbox.isChecked():
            self.open_tmp_inputfile()

    def reject(self):
        """
        The slot method for the 'Cancel' button.
        """
        QDialog.reject(self)
        self.gamessJig.attr_update(self.jig_attrs) # Restore attributes of the jig.
        # self.gamessJig.color = self.gamessJig.normcolor = self.original_normcolor
        self.gamessJig.cancelled = True
        self.glpane.gl_update()

    def whats_this(self):
        from PyQt4.Qt import QWhatsThis, QDialog
        QWhatsThis.enterWhatsThisMode()
Ejemplo n.º 5
0
class GamessProp(QDialog, Ui_GamessPropDialog):
    """
    The Gamess Jig Properties dialog used for:
    - running a GAMESS energy calculation on a structure (group of atoms).
    - running a GAMESS optimization on a structure.
    - setting and saving the GAMESS parameters used for an energy calculation or optimization.
    """
    def __init__(self):
        QDialog.__init__(self)
        self.setModal(True)
        self.setupUi(self)

        self.ecm_btngrp = QButtonGroup()
        self.ecm_btngrp.setExclusive(True)
        objId = 0
        for obj in self.ecm_grpbox.children():
            if isinstance(obj, QAbstractButton):
                self.ecm_btngrp.addButton(obj)
                self.ecm_btngrp.setId(obj, objId)
                objId += 1

        self.scftyp_btngrp = QButtonGroup()
        self.scftyp_btngrp.setExclusive(True)
        objId = 0
        for obj in self.scftyp_grpbox.children():
            if isinstance(obj, QAbstractButton):
                self.scftyp_btngrp.addButton(obj)
                self.scftyp_btngrp.setId(obj, objId)
                objId += 1

        self.connect(self.cancel_btn, SIGNAL("clicked()"), self.reject)
        self.connect(self.ecm_btngrp, SIGNAL("buttonPressed(int)"),
                     self.set_ecmethod)
        self.connect(self.multi_combox, SIGNAL("activated(int)"),
                     self.set_multiplicity)
        self.connect(self.run_job_btn, SIGNAL("clicked()"), self.run_job)
        self.connect(self.save_btn, SIGNAL("clicked()"), self.accept)
        self.connect(self.runtyp_combox, SIGNAL("activated(int)"),
                     self.calculate_changed)
        self.connect(self.choose_color_btn, SIGNAL("clicked()"),
                     self.change_jig_color)
        self.connect(self.whats_this_btn, SIGNAL("clicked()"), self.whats_this)
        ##self.connect(self.new_btn,SIGNAL("clicked()"),self.addServer)
        ##self.connect(self.exit_btn,SIGNAL("clicked()"),self.close)
        ##self.connect(self.server_listview,SIGNAL("currentChanged(QListViewItem*)"),self.changeServer)
        ##self.connect(self.engine_combox,SIGNAL("activated(const QString&)"),self.engineChanged)
        ##self.connect(self.del_btn,SIGNAL("clicked()"),self.deleteServer)
        self.sManager = ServerManager()
        self.servers = self.sManager.getServers()
        self.server = self.servers[0]

        self.name_linedit.setWhatsThis("""Name of the GAMESS jig.""")
        self.runtyp_combox.setWhatsThis(
            """Type of calculation, where "Energy" calculates the Energy Minima,and "Optimization" calculates the "Equilibrium Geometry"."""
        )
        self.comment_linedit.setWhatsThis(
            """Description, also placed in the comment line of the $DATA section of the INP file."""
        )
        self.choose_color_btn.setWhatsThis("""Change the GAMESS jig color.""")
        self.rhf_radiobtn.setWhatsThis(
            """Restricted Hartree-Fock.  All electrons are paired and each spatial orbital is doubly occupied.  Cannot be used with multiplicities greater than 1."""
        )
        self.uhf_radiobtn.setWhatsThis(
            """Unrestricted Hartree-Fock.  All electrons are unpaired and spatial (spin) orbitals are uniquely defined for each electron.  More time consuming, but more accurate, than ROHF.  """
        )
        self.rohf_radiobtn.setWhatsThis(
            """Restricted Open-shell Hartree-Fock.  Spin-paired electrons are assigned to doubly-occupied spatial orbitals, while electrons with unpaired spins are provided unique spatial orbitals."""
        )
        self.icharg_spinbox.setWhatsThis(
            """The total charge of the structure to be treated quantum mechanically (ICHARG)."""
        )
        self.multi_combox.setWhatsThis(
            """N + 1, where N is the number of unpaired electrons (MULT).""")
        self.memory_spinbox.setWhatsThis(
            """System memory reserved for calculation""")
        self.dirscf_checkbox.setWhatsThis(
            """Check this box to run the calculation in RAM and avoid hard disk usage for integral storage."""
        )
        self.gbasis_combox.setWhatsThis(
            """Select from among the standard Gaussian-type basis sets and semi-empirical parameters in GAMESS."""
        )
        self.checkBox10_3_2.setWhatsThis(
            """Reads the $HESS group from the output file of a previous GAMESS calculation.  Only valid for identical molecules."""
        )
        self.checkBox10_2_2_2.setWhatsThis(
            """Reads the $VEC group from the output of a previous GAMESS calculation. Requires that both the molecule and basis set be identical.  Useful for restarted calculations and starting orbitals for electron correlation methods."""
        )
        self.none_radiobtn.setWhatsThis(
            """Select this button to neglect electron correlation in the calculation."""
        )
        self.dft_radiobtn.setWhatsThis(
            """Select this button to perform a density functional theory calculation."""
        )
        self.mp2_radiobtn.setWhatsThis(
            """Select this button to perform a Second-Order Moeller Plesset calculation."""
        )
        self.dfttyp_combox.setWhatsThis(
            """Select an available density functional in GAMESS.""")
        self.gridsize_combox.setWhatsThis(
            """Select the grid spacing for the DFT calculation.""")
        self.core_electrons_checkbox.setWhatsThis(
            """Check this box to include both the valence and core electrons in the MP2 calculation."""
        )
        self.density_conv_combox.setWhatsThis(
            """Selects the accuracy of the electron density convergence for the calculation (CONV)."""
        )
        self.rmsd_combox.setWhatsThis(
            """Gradient convergence tolerance (OPTTOL), in Hartree/Bohr. Convergence of a geometry search requires the largest component of the gradient to be less than this value, and the root mean square gradient less than 1/3 of OPTTOL.  (default=0.0001)"""
        )
        self.iterations_spinbox.setWhatsThis(
            """Maximum number of SCF iteration cycles (MAXIT).""")
        self.edit_input_file_cbox.setWhatsThis(
            """Opens the INP file generated by NanoEngineer-1 in a text editor."""
        )
        self.whats_this_btn.setWhatsThis("""What's This Help Utility""")
        self.run_job_btn.setWhatsThis(
            """Save GAMESS parameters, generates the INP file and launches the GAMESS job."""
        )
        self.save_btn.setWhatsThis(
            """Save GAMESS parameters and generates the INP file.  It does not launch the GAMESS job."""
        )
        self.cancel_btn.setWhatsThis("""Cancels changes and closes dialog.""")

    def showDialog(self, job):
        """
        Display the GAMESS Jig Properties dialog
        """
        self.gamessJig = job.gamessJig
        self.job = job
        self.pset = self.gamessJig.pset
        self.win = self.gamessJig.assy.w
        self.glpane = self.gamessJig.assy.o

        if self._setup(): return
        self.exec_()

    ######Private or helper methods###############################
    def _setup(self):
        """ 
        Setup widgets to initial (default or defined) values. Return True on error.
        """
        #To fix bug 684
        #if gamess.is_disabled():
        #    self.run_job_btn.setEnabled(False)
        #else:
        #    self.run_job_btn.setEnabled(True)

        self.jig_attrs = self.gamessJig.copyable_attrs_dict(
        )  # Save the jig's attributes in case of Cancel.

        # Jig color
        self.original_normcolor = self.gamessJig.normcolor
        self.jig_QColor = RGBf_to_QColor(
            self.gamessJig.normcolor)  # Used as default color by Color Chooser
        self.jig_color_pixmap = get_widget_with_color_palette(
            self.jig_color_pixmap, self.jig_QColor)

        # Init the top widgets (name, runtyp drop box, comment)
        self.name_linedit.setText(self.gamessJig.name)
        self.runtyp_combox.setCurrentIndex(self.pset.ui.runtyp)  # RUNTYP
        self.calculate_changed(self.pset.ui.runtyp)
        self.comment_linedit.setText(self.pset.ui.comment)

        # Electronic Structure Properties section.
        btn = self.scftyp_btngrp.button(
            self.pset.ui.scftyp)  # RHF, UHF, or ROHF
        btn.setChecked(True)
        self.icharg_spinbox.setValue(self.pset.ui.icharg)  # Charge
        self.multi_combox.setCurrentIndex(self.pset.ui.mult)  # Multiplicity
        # Disable RHF if multiplicity is not the first item.
        if self.pset.ui.mult == 0:
            self.rhf_radiobtn.setEnabled(1)  # Enable RHF
        else:
            self.rhf_radiobtn.setEnabled(0)  # Disable RHF

        # System Memory and Usage
        self.dirscf_checkbox.setChecked(self.pset.ui.dirscf)  # DIRSCF
        self.memory_spinbox.setValue(self.pset.ui.memory)  # Memory

        # Electron Correlation Method and Basis Set
        ecm = self.pset.ui.ecm
        btn = self.ecm_btngrp.button(self.pset.ui.ecm)  # None, DFT or MP2
        btn.setChecked(True)
        self.set_ecmethod(self.pset.ui.ecm)  # None, DFT or MP2
        self.gbasis_combox.setCurrentIndex(self.pset.ui.gbasis)  # Basis set

        # Load the combo box with all the valid DFT functions.
        self._load_dfttyp_combox()
        self.dfttyp_combox.setCurrentIndex(
            self.pset.ui.dfttyp)  # DFT Functional
        self.gridsize_combox.setCurrentIndex(
            self.pset.ui.gridsize)  # Grid Size
        self.core_electrons_checkbox.setChecked(
            self.pset.ui.ncore)  # Include core electrons

        # Convergence Criteria
        self.density_conv_combox.setCurrentIndex(
            self.pset.ui.conv)  # Density Convergence
        self.rmsd_combox.setCurrentIndex(
            self.pset.ui.rmsdconv)  # RMSD Convergence
        self.iterations_spinbox.setValue(self.pset.ui.iterations)  # Iterations

        # These have been removed per discussions with Damian.
        # Mark 050628
        #        self.extrap_checkbox.setChecked(self.pset.ui.extrap) # EXTRAP
        #        self.damp_checkbox.setChecked(self.pset.ui.damp) # DAMP
        #        self.diis_checkbox.setChecked(self.pset.ui.diis) # DIIS
        #        self.shift_checkbox.setChecked(self.pset.ui.shift) # SHIFT
        #        self.soscf_checkbox.setChecked(self.pset.ui.soscf) # SOSCF
        #        self.rstrct_checkbox.setChecked(self.pset.ui.rstrct) # RSTRCT

        # Load the server combo box
        #self._reloadServerList() # Not used in A6.  Mark.

        # If there is an error, return 1. NIY.
        return 0

    def _reloadServerList(self):
        """ 
        Load the server combo box
        """
        self.server_combox.clear()
        for s in self.servers:
            self.server_combox.insertItem(100, s.hostname + "-" + s.engine)
            # 100 makes sure item is appended to list. [mark 2007-05-04]
        if self.server not in self.servers:
            self.server = self.servers[0]
        indx = self.servers.index(self.server)
        self.server_combox.setCurrentIndex(indx)

    def _load_dfttyp_combox(self):
        """
        Load list of DFT function in a combobox widget
        """
        self.dfttyp_combox.clear()  # Clear all combo box items
        if self.server.engine == 'GAMESS':
            for f in gms_dfttyp_items:
                self.dfttyp_combox.insertItem(100, f)
                # 100 makes sure item is appended to list. [mark 2007-05-04]
        elif self.server.engine == 'PC GAMESS':
            for f in pcgms_dfttyp_items:
                self.dfttyp_combox.insertItem(100, f)
                # 100 makes sure item is appended to list. [mark 2007-05-04]
        else:
            print "load_dfttyp_combox: Unknown GAMESS Version.  Loading GAMES DFT functionals."
            for f in gms_dfttyp_items:
                self.dfttyp_combox.insertItem(100, f)
                # 100 makes sure item is appended to list. [mark 2007-05-04]

    def _update_gbasis_list(self, val):
        """
        Add/remove AM1 and PM3 to/from the gbasis list. 
        """
        citem = self.gbasis_combox.currentIndex()
        if val == DFT or val == MP2:
            if self.gbasis_combox.count() == 18:
                self.gbasis_combox.removeItem(0)
                self.gbasis_combox.removeItem(0)
                self.gbasis_combox.setCurrentIndex(max(0, citem - 2))
        else:
            if self.gbasis_combox.count() != 18:
                self.gbasis_combox.insertItem(
                    0, "PM3")  # 0 prepends item to list.
                self.gbasis_combox.insertItem(0, "AM1")
                self.gbasis_combox.setCurrentIndex(citem + 2)

    def _save_ui_settings(self):
        """
        Save the UI settings in the Gamess jig pset.  
        There is one setting for each pset.
        """
        self.pset.ui.comment = str(self.comment_linedit.text())  # Description
        self.pset.ui.runtyp = self.runtyp_combox.currentIndex(
        )  # RUNTYP = Energy or Optimize

        # Electronic Structure Props and Basis Set section.
        self.pset.ui.scftyp = self.scftyp_btngrp.checkedId(
        )  # SCFTYP = RHF, UHF, or ROHF
        self.pset.ui.icharg = self.icharg_spinbox.value()  # Charge
        self.pset.ui.mult = self.multi_combox.currentIndex()  # Multiplicity

        # System Memory and Usage
        self.pset.ui.memory = self.memory_spinbox.value()  # Memory
        self.pset.ui.dirscf = self.dirscf_checkbox.isChecked()  # DIRSCF

        # Electron Correlation Method
        self.pset.ui.ecm = self.ecm_btngrp.checkedId()  # None, DFT or MP2
        #self.pset.ui.inttyp = self.ecm_btngrp.selectedId() # INTTYP
        self.pset.ui.gbasis = self.gbasis_combox.currentIndex()  # Basis Set
        self.pset.ui.gbasisname = str(self.gbasis_combox.currentText())
        self.pset.ui.dfttyp = self.dfttyp_combox.currentIndex(
        )  # DFT Functional Type
        self.pset.ui.gridsize = self.gridsize_combox.currentIndex(
        )  # Grid Size
        self.pset.ui.ncore = self.core_electrons_checkbox.isChecked(
        )  # Include core electrons

        # Convergence Criteria
        self.pset.ui.conv = self.density_conv_combox.currentIndex(
        )  # Density Convergence
        self.pset.ui.rmsdconv = self.rmsd_combox.currentIndex(
        )  # RMSD Convergence
        self.pset.ui.iterations = self.iterations_spinbox.value()  # Iterations

#        self.pset.ui.extrap = self.extrap_checkbox.isChecked() # EXTRAP
#        self.pset.ui.damp = self.damp_checkbox.isChecked() # DAMP
#        self.pset.ui.diis = self.diis_checkbox.isChecked() # DIIS
#        self.pset.ui.shift = self.shift_checkbox.isChecked() # SHIFT
#        self.pset.ui.soscf = self.soscf_checkbox.isChecked() # SOSCF
#        self.pset.ui.rstrct = self.rstrct_checkbox.isChecked() # RSTRCT

    def _save_job_parms(self):
        calculate = ['Energy', 'Optimization']
        self.job.Calculation = calculate[self.pset.ui.runtyp]
        self.job.Description = self.pset.ui.comment
        self.job.server = self.server
        ##Copy some  attributes from the server object to job description
        self.job.Server_id = self.server.server_id
        self.job.Engine = self.server.engine

    ######End of private or helper methods.########################

    ###### Unused methods ###############

    def openServerManager(self):
        """
        Pop up ServerManagerDialog to edit the properties of the servers.
        """
        self.sManager.showDialog(self.server)
        self.servers = self.sManager.getServers()
        self._reloadServerList()

    def serverChanged(self, si):
        """
        User has changed server, so update the DFT comboBox. Currently not used.
        """
        self.server = self.servers[si]
        self._load_dfttyp_combox()

    ###### End of unused methods ###############

    ##########Slot methods for some GUI controls################

    def calculate_changed(self, val):
        """
        """
        if val == 0:  # Energy
            self.rmsd_lbl.setEnabled(0)
            self.rmsd_combox.setEnabled(0)
            self.iterations_lbl.setEnabled(0)
            self.iterations_spinbox.setEnabled(0)
#            self.extrap_checkbox.setEnabled(0)
#            self.rstrct_checkbox.setEnabled(0)
#            self.damp_checkbox.setEnabled(0)
#            self.diis_checkbox.setEnabled(0)
#            self.shift_checkbox.setEnabled(0)
#            self.soscf_checkbox.setEnabled(0)
        else:  # Optimization
            self.rmsd_lbl.setEnabled(1)
            self.rmsd_combox.setEnabled(1)
            self.iterations_lbl.setEnabled(1)
            self.iterations_spinbox.setEnabled(1)
#            self.extrap_checkbox.setEnabled(1)
#            self.rstrct_checkbox.setEnabled(1)
#            self.damp_checkbox.setEnabled(1)
#            self.diis_checkbox.setEnabled(1)
#            self.shift_checkbox.setEnabled(1)
#            self.soscf_checkbox.setEnabled(1)

    def set_multiplicity(self, val):
        """
        Enable/disable widgets when user changes Multiplicity.
        """
        if val != 0:
            qt4todo("if scftyp[self.scftyp_btngrp.selectedId()] != 'RHF':")
            #if scftyp[self.scftyp_btngrp.selectedId()] != 'RHF':
            #    self.rhf_radiobtn.setEnabled(0)
            #    return

            ret = QMessageBox.warning(
                self, "Multiplicity Conflict",
                "If Multiplicity is greater than 1, then <b>UHF</b> or <b>ROHF</b> must be selected.\n"
                "Select Cancel to keep <b>RHF</b>.", "&UHF", "&ROHF", "Cancel",
                0, 2)

            if ret == 0:  # UHF
                self.uhf_radiobtn.toggle()
                self.rhf_radiobtn.setEnabled(0)

            elif ret == 1:  # ROHF
                self.rohf_radiobtn.toggle()
                self.rhf_radiobtn.setEnabled(0)

            elif ret == 2:  # Cancel
                self.multi_combox.setCurrentIndex(0)

        elif val == 0:
            self.rhf_radiobtn.setEnabled(1)

    def set_ecmethod(self, val):
        """
        Enable/disable widgets when user changes Electron Correlation Method.
        """
        #print "set_ecmethod = ", val
        if val == DFT:
            self.dfttyp_label.setEnabled(1)
            self.dfttyp_combox.setEnabled(1)
            self.gridsize_label.setEnabled(1)
            self.gridsize_combox.setEnabled(1)
            self.core_electrons_checkbox.setChecked(0)
            self.core_electrons_checkbox.setEnabled(0)

        elif val == MP2:
            self.core_electrons_checkbox.setEnabled(1)
            self.dfttyp_label.setEnabled(0)
            self.dfttyp_combox.setEnabled(0)
            self.gridsize_label.setEnabled(0)
            self.gridsize_combox.setEnabled(0)

        else:  # None = Hartree-Fock
            self.dfttyp_label.setEnabled(0)
            self.dfttyp_combox.setEnabled(0)
            self.gridsize_label.setEnabled(0)
            self.gridsize_combox.setEnabled(0)
            self.core_electrons_checkbox.setChecked(0)
            self.core_electrons_checkbox.setEnabled(0)

        # AM1 and PM3 are not options for DFT or MP2.
        # We have to remove or add them from the combo box.
        self._update_gbasis_list(val)

    def open_tmp_inputfile(self):
        """
        Writes a temporary GAMESS inputfile of the current Gamess jig and opens the
        file in an editor.
        """
        # Make tmp_inputfile filename (i.e. ~/Nanorex/temp/jigname_parms_info.inp)
        from platform_dependent.PlatformDependent import find_or_make_Nanorex_subdir
        tmpdir = find_or_make_Nanorex_subdir('temp')
        basename = self.gamessJig.name + "-" + self.gamessJig.gms_parms_info(
            '_')
        tmp_inputfile = os.path.join(tmpdir, "%s.inp" % basename)

        # Write INP file (in ~/Nanorex/temp subdirectory)
        from analysis.GAMESS.files_gms import writegms_inpfile
        writegms_inpfile(tmp_inputfile, self.gamessJig)

        from platform_dependent.PlatformDependent import open_file_in_editor
        open_file_in_editor(tmp_inputfile)

    def run_job(self):
        """
        Slot method for the 'Save and Run' button 
        """
        self.accept()

        # Run GAMESS job.  Return value r:
        # 0 = success
        # 1 = job cancelled
        # 2 = job failed.
        r = self.job.launch()

        if r == 1:  # Job was cancelled
            env.history.message(redmsg("GAMESS job cancelled."))
            return

        if r == 2:  # Job failed.
            env.history.message(
                redmsg(
                    "GAMESS job failed. Maybe you didn't set the right Gamess executable file. Make sure you can run the same job manually."
                ))
            return

        # Job success.
        fn = self.gamessJig.outputfile

        # Print energy or move atoms
        if self.pset.ui.runtyp == 0:  #Energy
            self.gamessJig.print_energy()
        else:  # Optimize
            try:
                r = self.gamessJig.move_optimized_atoms()
                # r = insertgms(self.gamessJig.assy, fn)
            except:
                print_compact_traceback(
                    "GamessProp.run_job(): error reading GAMESS OUT file [%s]: "
                    % fn)
                env.history.message(
                    redmsg("Internal error while inserting GAMESS geometry: " +
                           fn))
            else:
                if r:
                    env.history.message(redmsg("Atoms not adjusted."))
                else:
                    self.gamessJig.assy.changed(
                    )  # The file and the part are not the same.
                    self.gamessJig.print_energy(
                    )  # Print the final energy from the optimize OUT file, too.
                    env.history.message("Atoms adjusted.")

    def change_jig_color(self):
        """
        Slot method to change the jig's color.
        """
        color = QColorDialog.getColor(self.jig_QColor, self)

        if color.isValid():
            self.jig_QColor = color
            self.jig_color_pixmap = get_widget_with_color_palette(
                self.jig_color_pixmap, self.jig_QColor)

            self.gamessJig.color = self.gamessJig.normcolor = QColor_to_RGBf(
                color)
            self.glpane.gl_update()

    def accept(self):
        """
        The slot method for the 'Save' button.
        """
        QDialog.accept(self)
        self.gamessJig.try_rename(self.name_linedit.text())
        self._save_ui_settings()
        self.gamessJig.update_gamess_parms(
        )  # Update all the GAMESS parameters.
        self._save_job_parms()
        if self.edit_input_file_cbox.isChecked():
            self.open_tmp_inputfile()

    def reject(self):
        """
        The slot method for the 'Cancel' button.
        """
        QDialog.reject(self)
        self.gamessJig.attr_update(
            self.jig_attrs)  # Restore attributes of the jig.
        # self.gamessJig.color = self.gamessJig.normcolor = self.original_normcolor
        self.gamessJig.cancelled = True
        self.glpane.gl_update()

    def whats_this(self):
        from PyQt4.Qt import QWhatsThis, QDialog
        QWhatsThis.enterWhatsThisMode()
Ejemplo n.º 6
0
class PM_RadioButtonList( PM_GroupBox ):
    """
    The PM_RadioButtonList widget provides a list of radio buttons that function
    as an I{exclusive button group}.
    """
    
    buttonList       = []
    defaultCheckedId = -1    # -1 means no checked Id
    setAsDefault     = True
    labelWidget      = None
    
    def __init__(self, 
                 parentWidget, 
                 title        = '', 
                 label = '',
                 labelColumn = 0,
                 buttonList   = [],
                 checkedId    = -1,
                 setAsDefault = False, 
                 spanWidth   = True, 
                 borders = True
                 ):
        """
        Appends a PM_RadioButtonList widget to the bottom of I{parentWidget}, 
        the Property Manager dialog or group box.
        
        @param parentWidget: The parent group box containing this widget.
        @type  parentWidget: PM_GroupBox or PM_Dialog
        
        @param title: The group box title.
        @type  title: str
        
        @param label:      The label for the coordinate spinbox.
        @type  label:      str
        
        @param labelColumn: The column in the parentWidget's grid layout to 
                            which this widget's label will be added. 
                            The labelColum can only be E{0} or E{1}
        @type  labelColumn: int
                
        
        @param buttonList: A list of I{button info lists}. There is one button
                           info list for each radio button in the list. The 
                           button info list contains the following three items:
                           1). Button Id (int), 
                           2). Button text (str),
                           3). Button tool tip (str).
        @type  buttonList: list
        
        @param spanWidth: If True, the widget and its label will span the width
                         of the group box. Its label will appear directly above
                         the widget (unless the label is empty) and is left 
                         justified.
        @type  spanWidth: bool (default False)
        
        
        @param borders: If true (default), this widget will have borders displayed. 
                        otherwise the won't be any outside borders around the 
                        set of radio buttons this class provides
        @type borders: boolean
        """
        
        # Intializing label, labelColumn etc is needed before doing 
        # PM_GroupBox.__init__. This is done so that 
        # self.parentWidget.addPmWidget(self) done at the end of __init__
        # works properly. 
        # 'self.parentWidget.addPmWidget(self)' is done to avoid a bug where a 
        # groupbox is always appended as the 'last widget' when its 
        # parentWidget is also a groupbox. This is due to other PM widgets 
        #(e.g. PM_PushButton)add themselves to their parent widget in their 
        #__init__ using self.parentWidget.addPmWidget(self). So doing the
        #same thing here. More general fix is needed in PM_GroupBox code
        # --Ninad 2007-11-14 (comment copied from PM_coordinateSpinBoxes)
        self.label = label
        self.labelColumn = labelColumn
        self.spanWidth = spanWidth
        
        if label: # Create this widget's QLabel.
            self.labelWidget = QLabel()
            self.labelWidget.setText(label)
            
        
        PM_GroupBox.__init__(self, parentWidget, title)
        
        # These are needed to properly maintain the height of the grid if 
        # all buttons in a row are hidden via hide().
        self.vBoxLayout.setMargin(0)
        self.vBoxLayout.setSpacing(0)
        
        self.buttonGroup = QButtonGroup()
        self.buttonGroup.setExclusive(True)
        
        self.parentWidget = parentWidget
        self.buttonList   = buttonList
        
        if setAsDefault:
            self.setDefaultCheckedId(checkedId)
        
        self.buttonsById   = {}
        self.buttonsByText = {}
            
        # Create radio button list from button info.
        for buttonInfo in buttonList:
            buttonId       = buttonInfo[0]
            buttonText     = buttonInfo[1]
            buttonToolTip  = buttonInfo[2]
            
            button = QRadioButton(self)
            
            button.setText(buttonText)
            button.setToolTip(buttonToolTip) # Not working.
            button.setCheckable(True)
            if checkedId == buttonId:
                button.setChecked(True)
            self.buttonGroup.addButton(button, buttonId)
            self.vBoxLayout.addWidget(button)
            
            self.buttonsById[buttonId]    = button
            self.buttonsByText[buttonText] = button
            
        if isinstance(self.parentWidget, PM_GroupBox):
            self.parentWidget.addPmWidget(self)
        else:   
            #@@ Should self be added to self.parentWidget's widgetList?
            #don't know. Retaining old code -- Ninad 2008-06-23
            self._widgetList.append(self)            
            self._rowCount += 1
        
        if not borders:
            #reset the style sheet so that there are no borders around the 
            #radio button set this class provides. 
            self.setStyleSheet(self._getAlternateStyleSheet())
        
    def restoreDefault(self):
        """
        Restores the default checkedId.
        """
        if self.setAsDefault:
            for buttonInfo in self.buttonList:
                buttonId = buttonInfo[0]
                if buttonId == self.defaultCheckedId:
                    button = self.getButtonById(buttonId)
                    button.setChecked(True)
        return
    
    def setDefaultCheckedId(self, checkedId):
        """
        Sets the default checked id (button) to I{checkedId}. The current checked
        button is unchanged.
                      
        @param checkedId: The new default id for the tool button group.
        @type  checkedId: int
        """
        self.setAsDefault = True
        self.defaultCheckedId = checkedId
        
    def checkedButton(self):
        """
        Returns the tool button group's checked button, or 0 if no buttons are
        checked.
        """
        return self.buttonGroup.checkedButton()
        
    def checkedId(self):
        """
        Returns the id of the checkedButton(), or -1 if no button is checked.
        """
        return self.buttonGroup.checkedId()
    
    def getButtonByText(self, text):
        """
        Returns the button with its current text set to I{text}.
        """
        if self.buttonsByText.has_key(text):
            return self.buttonsByText[text]
        else:
            return None
        
    def getButtonById(self, buttonId):
        """
        Returns the button with the button id of I{buttonId}.
        """
        if self.buttonsById.has_key(buttonId):
            return self.buttonsById[buttonId]
        else:
            return None
              
        
    def _getAlternateStyleSheet(self):
        """
        Return the style sheet for the groupbox. This sets the following 
        properties only:
         - border style
         - border width
         - border color
         - border radius (on corners)
        @see: L{PM_GroupBox._getStyleSheet} (overrided here)
        """
        
        styleSheet = "QGroupBox {border-style:hidden;\
        border-width: 0px;\
        border-color: "";\
        border-radius: 0px;\
        min-width: 10em; }" 
   
        return styleSheet
            
# End of PM_RadioButtonList ############################