summaryrefslogtreecommitdiff
path: root/cad/src/outtakes/BuildProtein/BuildProtein_PropertyManager.py
blob: 1dc6151e0650a23c27520a9ed58b40ef0c0a25bf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
# Copyright 2007-2008 Nanorex, Inc.  See LICENSE file for details.
"""
BuildProtein_PropertyManager.py

@author: Urmi
@version: $Id$
@copyright: 2008 Nanorex, Inc.  See LICENSE file for details.
History: Urmi initially copied from BuildDna_PropertyManager.py but this version
         used for proteins is much more simple.

"""
import foundation.env as env
from PyQt4.Qt import SIGNAL
from PM.PM_ComboBox      import PM_ComboBox
from PM.PM_GroupBox      import PM_GroupBox
from PM.PM_SpinBox import PM_SpinBox
from PM.PM_PushButton import PM_PushButton
from command_support.EditCommand_PM import EditCommand_PM
from PM.PM_Constants     import PM_DONE_BUTTON
from PM.PM_Constants     import PM_WHATS_THIS_BUTTON
from PM.PM_Constants     import PM_CANCEL_BUTTON
from simulation.ROSETTA.rosetta_commandruns import checkIfProteinChunkInPart

_superclass = EditCommand_PM
class BuildProtein_PropertyManager(EditCommand_PM):
    """
    The BuildDna_PropertyManager class provides a Property Manager
    for the B{Build > Protein } command.

    @ivar title: The title that appears in the property manager header.
    @type title: str

    @ivar pmName: The name of this property manager. This is used to set
                  the name of the PM_Dialog object via setObjectName().
    @type name: str

    @ivar iconPath: The relative path to the PNG file that contains a
                    22 x 22 icon image that appears in the PM header.
    @type iconPath: str
    """

    title         =  "Build Protein"
    pmName        =  title
    #change this icon path later
    iconPath      =  "ui/actions/Tools/Build Structures/Protein.png"

    def __init__( self, command ):
        """
        Constructor for the Build DNA property manager.
        """

        self.current_protein = ""
        self.sequenceEditor = command.win.createProteinSequenceEditorIfNeeded()

        #see self.connect_or_disconnect_signals for comment about this flag
        self.isAlreadyConnected = False
        self.isAlreadyDisconnected = False

        EditCommand_PM.__init__( self, command)

        self.showTopRowButtons( PM_DONE_BUTTON | \
                                PM_CANCEL_BUTTON | \
                                PM_WHATS_THIS_BUTTON)

    def _updateProteinListForShow(self):
        """
        Update the list of proteins in the combo box in the PM.
        """
        #first remove from combo box all the proteins that do not exist in NE-1
        #part anymore
        currentProteinNameList = []
        for mol in self.win.assy.molecules:
            currentProteinNameList.append(mol.name)

        for name in self.protein_name_list:
            try:
                index = currentProteinNameList.index(name)
            except ValueError:
                #protein does not exist any more, need to remove it
                i = self.protein_name_list.index(name)
                self.protein_chunk_list.pop(i)
                self.protein_name_list.pop(i)
                j = self.structureComboBox.findText(name)
                self.structureComboBox.removeItem(j)

        for mol in self.win.assy.molecules:
            #if molecules does not already exist in combo box list, need to add
            #them
            if mol.isProteinChunk():
                try:
                    self.protein_name_list.index(mol.name)
                except ValueError:
                    self.protein_chunk_list.append(mol)
                    self.protein_name_list.append(mol.name)
                    self.structureComboBox.addItem(mol.name)
        return

    def show(self):
        """
        Overrides superclass show method
        """
        env.history.statusbar_msg("")
        self._updateProteinListForShow()
        self._showProteinParametersAndSequenceEditor()
        EditCommand_PM.show(self)
        self.updateMessage()
        return

    def close(self):
        """
        Overrides superclass close method
        """
        self.sequenceEditor.hide()
        env.history.statusbar_msg("")
        EditCommand_PM.close(self)
        return

    def _updateProteinList(self):
        """
        Update the list of proteins so that the protein name combo box in this
        PM can be populated.
        """
        self.protein_chunk_list = []
        self.protein_name_list = []
        for mol in self.win.assy.molecules:
            if mol.isProteinChunk():
                self.protein_chunk_list.append(mol)
                self.protein_name_list.append(mol.name)
        return


    def _showProteinParametersAndSequenceEditor(self):
        """
        Show/ Hide protein parameters and sequence editor based on if there's
        any protein in NE-1 part.
        """
        part = self.win.assy.part
        proteinExists, proteinChunk = checkIfProteinChunkInPart(part)
        if proteinExists:
            #check to see if current_protein is still in part, otherwise set
            # this to first available protein
            try:
                index = self.structureComboBox.findText(self.current_protein)
                index1 = self.protein_name_list.index(self.current_protein)
            except ValueError:
                index = 0
                index1 = 0
                self.set_current_protein_chunk_name(self.protein_name_list[index1])

            self.structureComboBox.setCurrentIndex(index)
            proteinChunk = self.protein_chunk_list[index1]
            self._numberOfAA = len(proteinChunk.protein.get_sequence_string())
        else:
            #remove all items from the combo box
            count = self.structureComboBox.count()
            for i in range(count):
                self.structureComboBox.removeItem(0)
            self._numberOfAA = 0
            self.set_current_protein_chunk_name("")
        self.numberOfAASpinBox.setValue(self._numberOfAA)


        #get the sequence for this protein chunk
        if proteinExists:
            sequence = proteinChunk.protein.get_sequence_string()
            self.sequenceEditor.setSequence(sequence)
            secStructure = proteinChunk.protein.get_secondary_structure_string()
            self.sequenceEditor.setSecondaryStructure(secStructure)
            self.sequenceEditor.setRuler(len(secStructure))
            self.editPropertiesPushButton.setEnabled(True)
        else:
            self.editPropertiesPushButton.setEnabled(False)
        self.sequenceEditor.hide()
        return

    def connect_or_disconnect_signals(self, isConnect):
        """
        Connect or disconnect widget signals sent to their slot methods.
        This can be overridden in subclasses. By default it does nothing.
        @param isConnect: If True the widget will send the signals to the slot
                          method.
        @type  isConnect: boolean
        """

        if isConnect and self.isAlreadyConnected:
            return

        if not isConnect and self.isAlreadyDisconnected:
            return

        self.isAlreadyConnected = isConnect
        self.isAlreadyDisconnected = not isConnect

        if isConnect:
            change_connect = self.win.connect
        else:
            change_connect = self.win.disconnect
        change_connect(self.structureComboBox,
                      SIGNAL("currentIndexChanged(int)"),
                       self._updateProteinParameters)
        change_connect(self.editPropertiesPushButton,
                       SIGNAL("clicked()"),
                       self._showSeqEditor)

    def _showSeqEditor(self):
        """
        Show sequence editor
        """
        if self.editPropertiesPushButton.isEnabled():
            self.sequenceEditor.show()
        return

    def _updateProteinParameters(self, index):
        """
        Update number of amino acids and sequence editor, as well as set the
        current protein pdb id which will be used in the child commands and for
        rosetta simulation from inside the build protein mode.
        @param index: index of the protein combo box
        @type index: int
        """
        for mol in self.protein_chunk_list:
            if  mol.name == self.structureComboBox.currentText():
                self._numberOfAA = len(mol.protein.get_sequence_string())
                self.numberOfAASpinBox.setValue(self._numberOfAA)
                sequence = mol.protein.get_sequence_string()
                self.sequenceEditor.setSequence(sequence)
                secStructure = mol.protein.get_secondary_structure_string()
                self.sequenceEditor.setSecondaryStructure(secStructure)
                self.sequenceEditor.setRuler(len(secStructure))
                break
        self.set_current_protein_chunk_name(mol.name)
        env.history.statusbar_msg("")
        return

    def set_current_protein_chunk_name(self, name):
        """
        Sets the current protein name
        @param name: pdb id of the protein currently selected in the combo box
        @type name: str
        """
        self.current_protein = name
        return


    def get_current_protein_chunk_name(self):
        """
        gets the current protein name
        @return: pdb id of the protein currently selected in the combo box
        """
        return self.current_protein


    def enable_or_disable_gui_actions(self, bool_enable = False):
        """
        Enable or disable some gui actions when this property manager is
        opened or closed, depending on the bool_enable.
        @param bool_enable: enables/disables some gui action
        @type bool_enable: bool

        """
        if hasattr(self.command, 'flyoutToolbar') and \
           self.command.flyoutToolbar:
            self.command.flyoutToolbar.exitProteinAction.setEnabled(not bool_enable)


    def _addWhatsThisText( self ):
        """
        What's This text for widgets in the DNA Property Manager.
        """
        pass

    def _addToolTipText(self):
        """
        Tool Tip text for widgets in the DNA Property Manager.
        """
        pass

    def _addGroupBoxes(self):
        """
        Add the DNA Property Manager group boxes.
        """
        self._pmGroupBox1 = PM_GroupBox(self, title = "Parameters")
        self._loadGroupBox1(self._pmGroupBox1)
        return

    def _loadGroupBox1(self, pmGroupBox):
        """
        Load widgets in group box 1.
        @param pmGroupBox: group box that contains protein name combo box and
                        number of amino acids spin box
        @see: L{PM_GroupBox}
        """
        self._updateProteinList()
        if len(self.protein_name_list) >= 1:
            self.set_current_protein_chunk_name(self.protein_name_list[0])
        self.structureComboBox = PM_ComboBox( pmGroupBox,
                                 label         =  "Name:",
                                 choices       =  self.protein_name_list,
                                 setAsDefault  =  False)

        #Urmi 20080713: May be useful to set the minimum value to not zero
        #Now it does not matter, since its disabled. But zero as the minimum
        #value in a spinbox does not work otherwise.
        self.numberOfAASpinBox = \
            PM_SpinBox( pmGroupBox,
                        label         =  "Amino Acids:",
                        value         =  0,
                        setAsDefault  =  False,
                        minimum       =  0,
                        maximum       =  10000 )
        #for now we do not allow changing number of residues
        self.numberOfAASpinBox.setEnabled(False)
        self.editPropertiesPushButton = PM_PushButton( pmGroupBox,
            text       =  "Edit Sequence",
            setAsDefault  =  True
            )