~ubuntu-branches/ubuntu/precise/code-saturne/precise

« back to all changes in this revision

Viewing changes to gui/Pages/BatchRunningView.py

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2011-11-01 17:43:32 UTC
  • mto: (6.1.7 sid)
  • mto: This revision was merged to the branch mainline in revision 11.
  • Revision ID: package-import@ubuntu.com-20111101174332-tl4vk45no0x3emc3
Tags: upstream-2.1.0
ImportĀ upstreamĀ versionĀ 2.1.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# -*- coding: iso-8859-1 -*-
2
 
#
 
1
# -*- coding: utf-8 -*-
 
2
 
3
3
#-------------------------------------------------------------------------------
4
 
#
5
 
#     This file is part of the Code_Saturne User Interface, element of the
6
 
#     Code_Saturne CFD tool.
7
 
#
8
 
#     Copyright (C) 1998-2009 EDF S.A., France
9
 
#
10
 
#     contact: saturne-support@edf.fr
11
 
#
12
 
#     The Code_Saturne User Interface is free software; you can redistribute it
13
 
#     and/or modify it under the terms of the GNU General Public License
14
 
#     as published by the Free Software Foundation; either version 2 of
15
 
#     the License, or (at your option) any later version.
16
 
#
17
 
#     The Code_Saturne User Interface is distributed in the hope that it will be
18
 
#     useful, but WITHOUT ANY WARRANTY; without even the implied warranty
19
 
#     of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20
 
#     GNU General Public License for more details.
21
 
#
22
 
#     You should have received a copy of the GNU General Public License
23
 
#     along with the Code_Saturne Kernel; if not, write to the
24
 
#     Free Software Foundation, Inc.,
25
 
#     51 Franklin St, Fifth Floor,
26
 
#     Boston, MA  02110-1301  USA
27
 
#
 
4
 
 
5
# This file is part of Code_Saturne, a general-purpose CFD tool.
 
6
#
 
7
# Copyright (C) 1998-2011 EDF S.A.
 
8
#
 
9
# This program is free software; you can redistribute it and/or modify it under
 
10
# the terms of the GNU General Public License as published by the Free Software
 
11
# Foundation; either version 2 of the License, or (at your option) any later
 
12
# version.
 
13
#
 
14
# This program is distributed in the hope that it will be useful, but WITHOUT
 
15
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
 
16
# FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
 
17
# details.
 
18
#
 
19
# You should have received a copy of the GNU General Public License along with
 
20
# this program; if not, write to the Free Software Foundation, Inc., 51 Franklin
 
21
# Street, Fifth Floor, Boston, MA 02110-1301, USA.
 
22
 
28
23
#-------------------------------------------------------------------------------
29
24
 
30
25
"""
31
26
This module contains the following classes and function:
32
27
- BatchRunningUserFilesDialogView
33
 
- BatchRunningPBSJobManagementDialogView
34
28
- BatchRunningAdvancedOptionsDialogView
35
29
- BatchRunningView
36
30
"""
42
36
import os, sys
43
37
import string, types
44
38
import logging
 
39
import subprocess
45
40
 
46
41
#-------------------------------------------------------------------------------
47
42
# Third-party modules
54
49
# Application modules import
55
50
#-------------------------------------------------------------------------------
56
51
 
57
 
from BatchRunningForm import Ui_BatchRunningForm
58
 
from BatchRunningUserFilesDialogForm import Ui_BatchRunningUserFilesDialogForm
59
 
from BatchRunningPBSJobManagementDialogForm import Ui_BatchRunningPBSJobManagementDialogForm
60
 
from BatchRunningAdvancedOptionsDialogForm import Ui_BatchRunningAdvancedOptionsDialogForm
 
52
from Pages.BatchRunningForm import Ui_BatchRunningForm
 
53
from Pages.BatchRunningUserFilesDialogForm import Ui_BatchRunningUserFilesDialogForm
 
54
from Pages.BatchRunningAdvancedOptionsDialogForm import Ui_BatchRunningAdvancedOptionsDialogForm
61
55
 
 
56
from Base.Common import cs_batch_type
62
57
from Base.Toolbox import GuiParam
63
58
from Base.QtPage import ComboModel, IntValidator, RegExpValidator, setGreenColor
64
 
from BatchRunningModel import RuncaseModel, BatchRunningModel
 
59
from Pages.BatchRunningModel import BatchRunningModel
 
60
from Pages.ScriptRunningModel import ScriptRunningModel
65
61
from Pages.LocalizationModel import LocalizationModel, Zone
66
62
 
67
63
#-------------------------------------------------------------------------------
73
69
log.setLevel(GuiParam.DEBUG)
74
70
 
75
71
#-------------------------------------------------------------------------------
76
 
# Popup window class: Data and results user files
 
72
# Popup window class: Data user files
77
73
#-------------------------------------------------------------------------------
78
74
 
79
75
 
80
76
class BatchRunningUserFilesDialogView(QDialog, Ui_BatchRunningUserFilesDialogForm):
81
77
    """
82
 
    Class for data and results user files
 
78
    Class for data user files
83
79
    """
84
 
    def __init__(self, parent, default):
 
80
    def __init__(self, parent, data_path, default):
85
81
        """
86
82
        Constructor
87
83
        """
92
88
 
93
89
        self.setWindowTitle(self.tr("User files"))
94
90
 
 
91
        self.data_path = data_path
95
92
        self.default = default
96
 
        self.result  = {}
97
 
        for key in self.default.keys():
98
 
            self.result[key] = []
 
93
        self.result  = []
99
94
 
100
95
        # Models
101
96
        rows = 0
102
97
        columns = 1
103
98
        self.modelData = QListModel(rows, columns)
104
 
        self.modelResu = QListModel(rows, columns)
105
99
 
106
100
        # associated with views.
107
101
        self.viewData.setModel(self.modelData)
108
 
        self.viewResu.setModel(self.modelResu)
109
 
 
110
 
        self.viewData.setItemDelegate(DataDelegate(self, self.default['data_path']))
111
 
        self.viewResu.setItemDelegate(ResuDelegate(self))
 
102
        self.viewData.setItemDelegate(DataDelegate(self, self.data_path))
112
103
 
113
104
        # Connections
114
105
        self.connect(self.buttonNewData, SIGNAL("clicked()"), self.slotAddData)
115
106
        self.connect(self.buttonAddData, SIGNAL("clicked()"), self.slotNewData)
116
 
        self.connect(self.buttonAddResu, SIGNAL("clicked()"), self.slotNewResu)
117
107
        self.connect(self.buttonDeleteData, SIGNAL("clicked()"), self.slotDeleteData)
118
 
        self.connect(self.buttonDeleteResu, SIGNAL("clicked()"), self.slotDeleteResu)
119
108
 
120
109
        # Previous values
121
 
        for item in self.default['data']:
122
 
            self.setFileData(item)
123
 
        for item in self.default['results']:
124
 
            self.setFileResu(item)
 
110
        if self.default != None:
 
111
            for item in self.default:
 
112
                self.setFileData(item)
125
113
 
126
114
 
127
115
    def setFileData(self, item):
137
125
            self.modelData.appendRow(std_item)
138
126
 
139
127
 
140
 
    def setFileResu(self, item):
141
 
        # Verify that the input is not already in the QListView
142
 
        indexList = self.modelResu.search(QString(item))
143
 
 
144
 
        if indexList:
145
 
            title = self.tr("Warning")
146
 
            msg   = self.tr("%s is already in the list." % str(item))
147
 
            QMessageBox.warning(self, title, msg)
148
 
        else:
149
 
            std_item = QStandardItem(QString(item))
150
 
            self.modelResu.appendRow(std_item)
151
 
 
152
 
 
153
128
    @pyqtSignature("")
154
129
    def slotAddData(self):
155
130
        """
156
131
        Add data users files input in entries in the good list.
157
132
        """
158
 
        title = self.tr("Search user data files.")
 
133
        title = self.tr("Select user data files.")
159
134
        filetypes = self.tr("User data files (*);;""All Files (*)")
160
135
        list = QFileDialog.getOpenFileNames(self,
161
136
                                            title,
162
 
                                            self.default['data_path'],
 
137
                                            self.data_path,
163
138
                                            filetypes)
164
139
        for item in list:
165
140
            self.setFileData(os.path.basename(str(item)))
174
149
 
175
150
 
176
151
    @pyqtSignature("")
177
 
    def slotNewResu(self):
178
 
        std_item = QStandardItem(QString(""))
179
 
        self.modelResu.appendRow(std_item)
180
 
        index = self.modelResu.indexFromItem(std_item)
181
 
        self.viewResu.edit(index)
182
 
 
183
 
 
184
 
    @pyqtSignature("")
185
152
    def slotDeleteData(self):
186
153
        """
187
154
        Delete the selection from the listbox (one by one).
191
158
            self.modelData.removeRow(index.row())
192
159
 
193
160
 
194
 
    @pyqtSignature("")
195
 
    def slotDeleteResu(self):
196
 
        """
197
 
        Delete the selection from the listbox (one by one).
198
 
        """
199
 
        index = self.viewResu.currentIndex()
200
 
        if index.isValid():
201
 
            self.modelResu.removeRow(index.row())
202
 
 
203
 
 
204
161
    def get_result(self):
205
162
        """
206
163
        Method to get the result
217
174
        for row in range(self.modelData.rowCount()):
218
175
            index = self.modelData.index(row, column, QModelIndex())
219
176
            qstring = index.data(Qt.DisplayRole).toString()
220
 
            self.result['data'].append(str(qstring))
221
 
 
222
 
        for row in range(self.modelResu.rowCount()):
223
 
            index = self.modelResu.index(row, column, QModelIndex())
224
 
            qstring = index.data(Qt.DisplayRole).toString()
225
 
            self.result['results'].append(str(qstring))
 
177
            self.result.append(str(qstring))
226
178
 
227
179
        QDialog.accept(self)
228
180
 
231
183
        """
232
184
        Method called when user clicks 'Cancel'
233
185
        """
234
 
        self.result  = self.default.copy()
 
186
        self.result  = self.default
235
187
        QDialog.reject(self)
236
188
 
237
189
 
312
264
        model.setData(index, QVariant(item), Qt.DisplayRole)
313
265
 
314
266
 
315
 
class ResuDelegate(QItemDelegate):
316
 
    def __init__(self, parent=None):
317
 
        super(ResuDelegate, self).__init__(parent)
318
 
        self.parent = parent
319
 
 
320
 
 
321
 
    def createEditor(self, parent, option, index):
322
 
        editor = QLineEdit(parent)
323
 
        vd = RegExpValidator(editor, QRegExp("[_A-Za-z0-9\-\*\!\?\.]*"))
324
 
        editor.setValidator(vd)
325
 
        editor.setFrame(False)
326
 
        self.connect(editor, SIGNAL("returnPressed()"), self.commitAndCloseEditor)
327
 
        editor.setCursorPosition(0)
328
 
        return editor
329
 
 
330
 
 
331
 
    def commitAndCloseEditor(self):
332
 
        editor = self.sender()
333
 
        if isinstance(editor, QLineEdit):
334
 
            self.emit(SIGNAL("commitData(QWidget*)"), editor)
335
 
            self.emit(SIGNAL("closeEditor(QWidget*)"), editor)
336
 
 
337
 
 
338
 
    def setEditorData(self, editor, index):
339
 
        text = index.model().data(index, Qt.DisplayRole).toString()
340
 
        editor.setText(text)
341
 
 
342
 
 
343
 
    def setModelData(self, editor, model, index):
344
 
        if not editor.isModified():
345
 
            return
346
 
 
347
 
        item = editor.text()
348
 
 
349
 
        if model.search(item):
350
 
            model.removeRow(index.row())
351
 
            title = self.tr("Warning")
352
 
            msg   = self.tr("%s is already in the list." % str(item))
353
 
            QMessageBox.warning(self.parent, title, msg)
354
 
        else:
355
 
            model.setData(index, QVariant(item), Qt.DisplayRole)
356
 
 
357
 
 
358
 
#-------------------------------------------------------------------------------
359
 
# Popup window class: Cluster job management
360
 
#-------------------------------------------------------------------------------
361
 
 
362
 
 
363
 
class BatchRunningPBSJobManagementDialogView(QDialog, Ui_BatchRunningPBSJobManagementDialogForm):
364
 
    """
365
 
    Advanced dialog
366
 
    """
367
 
    def __init__(self, parent, default):
368
 
        """
369
 
        Constructor
370
 
        """
371
 
        QDialog.__init__(self, parent)
372
 
 
373
 
        Ui_BatchRunningPBSJobManagementDialogForm.__init__(self)
374
 
        self.setupUi(self)
375
 
 
376
 
        self.setWindowTitle(self.tr("PBS job management"))
377
 
 
378
 
        self.default = default
379
 
        self.result  = self.default.copy()
380
 
 
381
 
        # Validators
382
 
        validatorJobName  = RegExpValidator(self.lineEditJobName, QRegExp("[_A-Za-z0-9]*"))
383
 
        validatorNodes    = IntValidator(self.lineEditNodes, min=1)
384
 
        validatorCPUNodes = IntValidator(self.lineEditCPUNodes, min=1, max=32)
385
 
        validatorHours    = IntValidator(self.lineEditHours, min=0, max=999)
386
 
        validatorMinutes  = IntValidator(self.lineEditMinutes, min=0, max=59)
387
 
        validatorSeconds  = IntValidator(self.lineEditSeconds, min=0, max=59)
388
 
 
389
 
        self.lineEditJobName.setValidator(validatorJobName)
390
 
        self.lineEditNodes.setValidator(validatorNodes)
391
 
        self.lineEditCPUNodes.setValidator(validatorCPUNodes)
392
 
 
393
 
        self.lineEditHours.setValidator(validatorHours)
394
 
        self.lineEditMinutes.setValidator(validatorMinutes)
395
 
        self.lineEditSeconds.setValidator(validatorSeconds)
396
 
 
397
 
        # Previous values
398
 
        self.job_name     = self.default['PBS_JOB_NAME']
399
 
        self.cluster_node = self.default['PBS_nodes']
400
 
        self.cluster_ppn  = self.default['PBS_ppn']
401
 
        L = string.split(self.default['PBS_walltime'], ":")
402
 
        self.h_cput = L[0]
403
 
        self.m_cput = L[1]
404
 
        self.s_cput = L[2]
405
 
 
406
 
        self.lineEditJobName.setText(QString(self.job_name))
407
 
        self.lineEditNodes.setText(QString(str(self.cluster_node)))
408
 
 
409
 
        self.lineEditCPUNodes.setText(QString(str(self.cluster_ppn)))
410
 
        self.lineEditHours.setText(QString(str(self.h_cput)))
411
 
        self.lineEditMinutes.setText(QString(str(self.m_cput)))
412
 
        self.lineEditSeconds.setText(QString(str(self.s_cput)))
413
 
 
414
 
 
415
 
    def get_result(self):
416
 
        """
417
 
        Method to get the result
418
 
        """
419
 
        return self.result
420
 
 
421
 
 
422
 
    def accept(self):
423
 
        """
424
 
        Method called when user clicks 'OK'
425
 
        """
426
 
        self.result['PBS_JOB_NAME'] = str(self.lineEditJobName.text())
427
 
        if self.lineEditNodes.validator().state == QValidator.Acceptable:
428
 
            self.result['PBS_nodes'] = str(self.lineEditNodes.text())
429
 
        if self.lineEditCPUNodes.validator().state == QValidator.Acceptable:
430
 
            self.result['PBS_ppn']  = str(self.lineEditCPUNodes.text())
431
 
        if self.lineEditCPUNodes.validator().state == QValidator.Acceptable and \
432
 
            self.lineEditMinutes.validator().state == QValidator.Acceptable and \
433
 
            self.lineEditSeconds.validator().state == QValidator.Acceptable:
434
 
            h_cput = str(self.lineEditHours.text())
435
 
            m_cput = str(self.lineEditMinutes.text())
436
 
            s_cput = str(self.lineEditSeconds.text())
437
 
            self.result['PBS_walltime'] = h_cput + ":" + m_cput + ":" + s_cput
438
 
 
439
 
        QDialog.accept(self)
440
 
 
441
 
 
442
 
    def reject(self):
443
 
        """
444
 
        Method called when user clicks 'Cancel'
445
 
        """
446
 
        QDialog.reject(self)
447
 
 
448
 
 
449
 
    def tr(self, text):
450
 
        """
451
 
        Translation
452
 
        """
453
 
        return text
454
 
 
455
 
 
456
267
#-------------------------------------------------------------------------------
457
268
# Popup advanced options
458
269
#-------------------------------------------------------------------------------
462
273
    """
463
274
    Advanced dialog
464
275
    """
465
 
    def __init__(self, parent, default):
 
276
    def __init__(self, parent):
466
277
        """
467
278
        Constructor
468
279
        """
472
283
        self.setupUi(self)
473
284
 
474
285
        self.setWindowTitle(self.tr("Advanced options"))
475
 
        self.default = default
476
 
        self.result  = self.default.copy()
 
286
        self.parent = parent
477
287
 
478
288
        self.lineEdit.setReadOnly(True)
479
289
 
480
290
        # Combo models
481
 
        self.modelCSTMPPREFIX  = ComboModel(self.comboBoxCSTMPPREFIX, 2, 1)
482
 
        self.modelExecPrepro   = ComboModel(self.comboBox, 2, 1)
483
 
        self.modelExecPartit   = ComboModel(self.comboBox_2, 2, 1)
484
 
        self.modelExecKernel   = ComboModel(self.comboBox_3, 2, 1)
485
 
        self.modelArg_cs_verif = ComboModel(self.comboBox_5, 2, 1)
 
291
        self.modelSCRATCHDIR   = ComboModel(self.comboBoxSCRATCHDIR, 2, 1)
 
292
        self.modelPartitType   = ComboModel(self.comboBox_2, 4, 1)
486
293
        self.modelCSOUT1       = ComboModel(self.comboBox_6, 2, 1)
487
294
        self.modelCSOUT2       = ComboModel(self.comboBox_7, 3, 1)
488
295
 
489
296
        # Combo items
490
 
        self.modelCSTMPPREFIX.addItem(self.tr("automatic"), 'automatic')
491
 
        self.modelCSTMPPREFIX.addItem(self.tr("prescribed"), 'prescribed')
492
 
 
493
 
        self.modelExecPrepro.addItem(self.tr("Run the preprocessor"), 'yes')
494
 
        self.modelExecPrepro.addItem(self.tr("Use existing DATA/preprocessor_output"), 'no')
495
 
 
496
 
        self.modelExecPartit.addItem(self.tr("Run the partioner"), 'yes')
497
 
        self.modelExecPartit.addItem(self.tr("Use existing domain_number_<p> file in DATA/PARTITION_OUTPUT/\n"\
498
 
                                             "if present, unoptimized partition otherwise"), 'no')
499
 
 
500
 
        self.modelExecKernel.addItem(self.tr("Setup data and run the calculation"), 'yes')
501
 
        self.modelExecKernel.addItem(self.tr("Do not setup data and run the calculation"), 'no')
502
 
 
503
 
        self.modelArg_cs_verif.addItem(self.tr("Off"), 'standard')
504
 
        self.modelArg_cs_verif.addItem(self.tr("Mesh quality criteria"), 'mesh_quality')
505
 
 
506
 
        self.modelCSOUT1.addItem(self.tr("to standard output"), 'standard')
 
297
        self.modelSCRATCHDIR.addItem(self.tr("automatic"), 'automatic')
 
298
        self.modelSCRATCHDIR.addItem(self.tr("prescribed"), 'prescribed')
 
299
 
 
300
        self.modelPartitType.addItem(self.tr("Default"), 'default')
 
301
        self.modelPartitType.addItem(self.tr("Scotch"), 'scotch')
 
302
        self.modelPartitType.addItem(self.tr("Metis"), 'metis')
 
303
        self.modelPartitType.addItem(self.tr("Morton curve (bounding box)"), 'morton sfc')
 
304
        self.modelPartitType.addItem(self.tr("Morton curve (bounding cube)"), 'morton sfc cube')
 
305
        self.modelPartitType.addItem(self.tr("Hilbert curve (bounding box)"), 'hilbert sfc')
 
306
        self.modelPartitType.addItem(self.tr("Hilbert curve (bounding cube)"), 'hilbert sfc cube')
 
307
 
 
308
        self.modelCSOUT1.addItem(self.tr("to standard output"), 'stdout')
507
309
        self.modelCSOUT1.addItem(self.tr("to listing"), 'listing')
508
310
 
509
 
        self.modelCSOUT2.addItem(self.tr("no output"), 'shunte')
510
 
        self.modelCSOUT2.addItem(self.tr("to standard output"), 'standard')
511
 
        self.modelCSOUT2.addItem(self.tr("to listing_n<N>"), 'listing')
512
 
 
513
 
        # connections
514
 
        self.connect(self.comboBoxCSTMPPREFIX, SIGNAL("activated(const QString&)"), self.slotCSTMPPREFIX)
 
311
        self.modelCSOUT2.addItem(self.tr("no output"), 'null')
 
312
        self.modelCSOUT2.addItem(self.tr("to standard output"), 'stdout')
 
313
        self.modelCSOUT2.addItem(self.tr("to listing_n<p>"), 'listing')
 
314
 
 
315
        # Validators
 
316
        partListVd = RegExpValidator(self.lineEdit_2, QRegExp("[0-9- ]*"))
 
317
        self.lineEdit_2.setValidator(partListVd)
 
318
 
 
319
        # Connections
 
320
        self.connect(self.comboBoxSCRATCHDIR, SIGNAL("activated(const QString&)"), self.slotSCRATCHDIR)
515
321
        self.connect(self.toolButton, SIGNAL("clicked()"), self.slotSearchDirectory)
516
 
        self.connect(self.comboBox, SIGNAL("activated(const QString&)"), self.slotExePrepro)
517
322
        self.connect(self.comboBox_2, SIGNAL("activated(const QString&)"), self.slotExePartit)
518
 
        self.connect(self.comboBox_3, SIGNAL("activated(const QString&)"), self.slotExeKernel)
519
323
        self.connect(self.toolButton_2, SIGNAL("clicked()"), self.slotSearchFile)
520
324
        self.connect(self.lineEdit_2, SIGNAL("textChanged(const QString &)"), self.slotPartitionList)
521
325
        self.connect(self.lineEdit_3, SIGNAL("textChanged(const QString &)"), self.slotValgrind)
522
 
        self.connect(self.lineEdit_4, SIGNAL("textChanged(const QString &)"), self.slotCs_lib_add)
523
 
        self.connect(self.comboBox_5, SIGNAL("activated(const QString&)"), self.slotArgCsVerif)
524
 
        self.connect(self.comboBox_6, SIGNAL("activated(const QString&)"), self.slotArgCsOutput)
525
 
        self.connect(self.comboBox_7, SIGNAL("activated(const QString&)"), self.slotArgCsOutput)
 
326
        self.connect(self.comboBox_6, SIGNAL("activated(const QString&)"), self.slotLogType)
 
327
        self.connect(self.comboBox_7, SIGNAL("activated(const QString&)"), self.slotLogType)
526
328
 
527
329
        # Previous values
528
 
        self.dir_name = self.default['CS_TMP_PREFIX']
529
 
        self.lineEdit.setText(QString(self.dir_name))
530
 
        if self.dir_name == "":
 
330
        self.scratchdir = self.parent.mdl.getString('scratchdir')
 
331
        self.scratchdir_default = self.scratchdir
 
332
        self.lineEdit.setText(QString(self.scratchdir))
 
333
        if self.scratchdir == "":
531
334
            self.lineEdit.setEnabled(False)
532
335
            self.toolButton.setEnabled(False)
533
 
            self.modelCSTMPPREFIX.setItem(str_model='automatic')
 
336
            self.modelSCRATCHDIR.setItem(str_model='automatic')
534
337
        else:
535
338
            self.lineEdit.setEnabled(True)
536
339
            self.toolButton.setEnabled(True)
537
 
            self.modelCSTMPPREFIX.setItem(str_model='prescribed')
538
 
 
539
 
        self.exe_prepro = self.default['EXEC_PREPROCESS']
540
 
        self.modelExecPrepro.setItem(str_model=self.exe_prepro)
541
 
 
542
 
        self.exe_partit = self.default['EXEC_PARTITION']
543
 
        self.modelExecPartit.setItem(str_model=self.exe_partit)
544
 
 
545
 
        self.exe_kernel = self.default['EXEC_KERNEL']
546
 
        self.modelExecKernel.setItem(str_model=self.exe_kernel)
547
 
 
548
 
        self.partition_list = self.default['PARTITION_LIST']
 
340
            self.modelSCRATCHDIR.setItem(str_model='prescribed')
 
341
 
 
342
        self.partition_type = str(self.parent.mdl.getPartitionType())
 
343
        self.modelPartitType.setItem(str_model=self.partition_type)
 
344
 
 
345
        self.partition_list = self.parent.mdl.getString('partition_list')
549
346
        self.lineEdit_2.setText(QString(self.partition_list))
550
347
 
551
 
        self.valgrind = self.default['VALGRIND']
552
 
        self.lineEdit_3.setText(QString(self.valgrind))
553
 
 
554
 
        self.cs_lib_add = self.default['CS_LIB_ADD']
555
 
        self.lineEdit_4.setText(QString(self.cs_lib_add))
556
 
 
557
 
        self.setArgCsVerif()
558
 
        self.setArgCsOutput()
 
348
        self.valgrind = self.parent.mdl.getString('valgrind')
 
349
        if self.valgrind != None:
 
350
            self.lineEdit_3.setText(QString(self.valgrind))
 
351
 
 
352
        self.setLogType()
559
353
 
560
354
 
561
355
    @pyqtSignature("const QString &")
562
 
    def slotCSTMPPREFIX(self, text):
563
 
        """
564
 
        Select mode for CS_TMP_PREFIX.
565
 
        """
566
 
        if self.modelCSTMPPREFIX.dicoV2M[str(text)] == 'prescribed':
567
 
            self.dir_name = self.default['CS_TMP_PREFIX']
 
356
    def slotSCRATCHDIR(self, text):
 
357
        """
 
358
        Select mode for SCRATCHDIR.
 
359
        """
 
360
        if self.modelSCRATCHDIR.dicoV2M[str(text)] == 'prescribed':
 
361
            self.scratchdir = self.scratchdir_default
568
362
            self.lineEdit.setEnabled(True)
569
363
            self.toolButton.setEnabled(True)
570
364
            setGreenColor(self.toolButton, True)
571
365
        else:
572
 
            self.dir_name = ""
 
366
            self.scratchdir = ""
573
367
            self.lineEdit.setEnabled(False)
574
368
            self.toolButton.setEnabled(False)
575
369
            setGreenColor(self.toolButton, False)
576
 
        self.lineEdit.setText(QString(self.dir_name))
 
370
        self.lineEdit.setText(QString(self.scratchdir))
577
371
 
578
372
 
579
373
    @pyqtSignature("const QString &")
593
387
 
594
388
 
595
389
    @pyqtSignature("const QString &")
596
 
    def slotCs_lib_add(self, text):
597
 
        """
598
 
        Input for external libraries.
599
 
        """
600
 
        self.cs_lib_add = str(text)
601
 
 
602
 
 
603
 
    @pyqtSignature("const QString &")
604
 
    def slotExePrepro(self, text):
605
 
        """
606
 
        Preprocessor execution mode option.
607
 
        """
608
 
        self.exe_prepro = self.modelExecPrepro.dicoV2M[str(text)]
609
 
 
610
 
 
611
 
    @pyqtSignature("const QString &")
612
390
    def slotExePartit(self, text):
613
391
        """
614
392
        Partitioner execution mode option.
615
393
        """
616
 
        self.exe_partit = self.modelExecPartit.dicoV2M[str(text)]
617
 
 
618
 
 
619
 
    @pyqtSignature("const QString &")
620
 
    def slotExeKernel(self, text):
621
 
        """
622
 
        Kernel execution mode option.
623
 
        """
624
 
        self.exe_kernel = self.modelExecKernel.dicoV2M[str(text)]
625
 
 
626
 
 
627
 
    def setArgCsVerif(self):
628
 
        """
629
 
        Put ARG_CS_VERIF option from "lance" file.
630
 
        """
631
 
        if self.default['ARG_CS_VERIF'] == '':
632
 
            self.arg_cs_verif = 'standard'
633
 
            self.val_verif = ""
634
 
        if self.default['ARG_CS_VERIF'] == '--quality' or self.default['ARG_CS_VERIF'] == '-q':
635
 
            self.arg_cs_verif = 'mesh_quality'
636
 
            self.val_verif = '--quality'
637
 
        self.modelArg_cs_verif.setItem(str_model=self.arg_cs_verif)
638
 
 
639
 
 
640
 
    @pyqtSignature("const QString &")
641
 
    def slotArgCsVerif(self, text):
642
 
        """
643
 
        Input ARG_CS_VERIF option.
644
 
        """
645
 
        self.val_verif = ''
646
 
        self.arg_cs_verif = self.modelArg_cs_verif.dicoV2M[str(text)]
647
 
        arg_verif = self.arg_cs_verif
648
 
 
649
 
        if arg_verif == 'standard'     : self.val_verif = ''
650
 
        if arg_verif == 'mesh_quality' : self.val_verif = '--quality'
651
 
 
652
 
 
653
 
    def setArgCsOutput(self):
654
 
        """
655
 
        Put ARG_CS_OUTPUT options from 'lancer' file.
656
 
        """
657
 
        self.val_output = self.default['ARG_CS_OUTPUT']
658
 
        if self.default['ARG_CS_OUTPUT'] == '':
659
 
            self.modelCSOUT1.setItem(str_model='listing')
660
 
            self.modelCSOUT2.setItem(str_model='shunte')
661
 
        else:
662
 
            list = self.default['ARG_CS_OUTPUT'].split()
663
 
            l1 = 0
664
 
            l2 = 0
665
 
            for n in range(len(list)):
666
 
                if list[n] == '--log':
667
 
                    l1 = 1
668
 
                    if list[n+1] == '0': self.modelCSOUT1.setItem(str_model='standard')
669
 
                    if list[n+1] == '1': self.modelCSOUT1.setItem(str_model='listing')
670
 
                if list[n] == '--logp':
671
 
                    l2 = 1
672
 
                    if list[n+1] == '0': self.modelCSOUT2.setItem(str_model='standard')
673
 
                    if list[n+1] == '1': self.modelCSOUT2.setItem(str_model='listing')
674
 
                    if list[n+1] == '-1': self.modelCSOUT2.setItem(str_model='shunte')
675
 
            if l1 == 0: self.modelCSOUT1.setItem(str_model='listing')
676
 
            if l2 == 0: self.modelCSOUT2.setItem(str_model='shunte')
677
 
 
678
 
 
679
 
    @pyqtSignature("const QString &")
680
 
    def slotArgCsOutput(self, text):
681
 
        """
682
 
        Input ARG_CS_OUTPUT options.
683
 
        """
684
 
        self.val_output =''
685
 
        out1 = ''
686
 
        out2 = ''
687
 
        arg_out1 = self.modelCSOUT1.dicoV2M[str(self.comboBox_6.currentText())]
688
 
        arg_out2 = self.modelCSOUT2.dicoV2M[str(self.comboBox_7.currentText())]
689
 
        if arg_out1 == 'listing': out1 = ''
690
 
        if arg_out1 == 'standard': out1 = '--log 0'
691
 
        if arg_out2 == 'shunte': out2 = ''
692
 
        if arg_out2 == 'standard': out2 = '--logp 0'
693
 
        if arg_out2 == 'listing': out2 = '--logp 1'
694
 
        self.val_output = out1 + ' ' + out2
 
394
        self.partition_type = self.modelPartitType.dicoV2M[str(text)]
 
395
 
 
396
 
 
397
    def setLogType(self):
 
398
        """
 
399
        Set logging arguments.
 
400
        """
 
401
        self.log_type = self.parent.mdl.getLogType()
 
402
        self.modelCSOUT1.setItem(str_model=self.log_type[0])
 
403
        self.modelCSOUT2.setItem(str_model=self.log_type[1])
 
404
 
 
405
 
 
406
    @pyqtSignature("const QString &")
 
407
    def slotLogType(self, text):
 
408
        """
 
409
        Input logging options.
 
410
        """
 
411
        self.log_type = [self.modelCSOUT1.dicoV2M[str(self.comboBox_6.currentText())],
 
412
                         self.modelCSOUT2.dicoV2M[str(self.comboBox_7.currentText())]]
695
413
 
696
414
 
697
415
    @pyqtSignature("")
702
420
        title    = self.tr("Select directory")
703
421
        default  = os.getcwd()
704
422
        options  = QFileDialog.ShowDirsOnly # | QFileDialog.DontResolveSymlinks
705
 
        dir_name = QFileDialog.getExistingDirectory(self, title, default, options)
 
423
        scratchdir = QFileDialog.getExistingDirectory(self, title, default, options)
706
424
 
707
 
        dir = str(dir_name)
 
425
        dir = str(scratchdir)
708
426
        if dir:
709
 
            self.dir_name = dir
 
427
            self.scratchdir = dir
710
428
            setGreenColor(self.toolButton, False)
711
 
        self.lineEdit.setText(QString(self.dir_name))
 
429
        self.lineEdit.setText(QString(self.scratchdir))
712
430
 
713
 
        return self.dir_name
 
431
        return self.scratchdir
714
432
 
715
433
 
716
434
    @pyqtSignature("")
752
470
        """
753
471
        Method called when user clicks 'OK'
754
472
        """
755
 
        self.result['CS_TMP_PREFIX']   = self.dir_name
756
 
        self.result['EXEC_PREPROCESS'] = self.exe_prepro
757
 
        self.result['EXEC_PARTITION']  = self.exe_partit
758
 
        self.result['EXEC_KERNEL']     = self.exe_kernel
759
 
        self.result['PARTITION_LIST']  = self.partition_list
760
 
        self.result['VALGRIND']        = self.valgrind
761
 
        self.result['CS_LIB_ADD']      = self.cs_lib_add
762
 
        self.result['ARG_CS_VERIF']    = self.val_verif
763
 
        self.result['ARG_CS_OUTPUT']   = self.val_output
 
473
 
 
474
        self.parent.mdl.setPartitionType(self.partition_type)
 
475
        self.parent.mdl.setString('partition_list', self.partition_list.strip())
 
476
 
 
477
        self.parent.mdl.setString('valgrind', self.valgrind.strip())
 
478
        self.parent.mdl.setString('scratchdir', self.scratchdir)
 
479
 
 
480
        self.parent.mdl.setLogType(self.log_type)
764
481
 
765
482
        QDialog.accept(self)
766
483
 
802
519
        self.setupUi(self)
803
520
 
804
521
        self.case = case
805
 
        RuncaseModel(self.case)
806
 
 
807
 
        # Combo model
808
 
 
809
 
        self.modelArchi = ComboModel(self.comboBoxArchi, 3, 1)
810
 
        self.modelArchi.addItem(self.tr("Workstation"),                   'station')
811
 
        self.modelArchi.addItem(self.tr("Cluster with PBS queue system"), 'pbs')
812
 
        self.modelArchi.addItem(self.tr("Cluster with LSF queue system"), 'lsf')
813
 
        self.modelArchi.addItem(self.tr("Cluster with SGE queue system"), 'sge')
814
 
        self.modelArchi.disableItem(str_model='lsf')
815
 
        self.modelArchi.disableItem(str_model='sge')
 
522
 
 
523
        self.mdl = ScriptRunningModel(self.case)
 
524
 
 
525
        # Check if the script file name is already defined
 
526
 
 
527
        if self.case['scripts_path']:
 
528
            if not self.case['batch']:
 
529
                if 'runcase' in os.listdir(self.case['scripts_path']):
 
530
                    self.case['batch'] = 'runcase'
 
531
 
 
532
        self.case['batch_type'] = cs_batch_type
 
533
 
 
534
        self.jmdl = BatchRunningModel(parent, self.case)
 
535
 
 
536
        # Batch info
 
537
 
 
538
        self.hideBatchInfo()
 
539
 
 
540
        self.labelNProcs.hide()
 
541
        self.spinBoxNProcs.hide()
 
542
 
 
543
        self.class_list = None
 
544
 
 
545
        self.n_procs = None
 
546
 
 
547
        if self.case['batch_type'] != None:
 
548
 
 
549
            self.groupBoxArchi.setTitle("Job and script files")
 
550
            self.labelBatch.show()
 
551
            self.toolButtonSearchBatch.show()
 
552
 
 
553
            validatorSimpleName = RegExpValidator(self.lineEditJobName,
 
554
                                                  QRegExp("[_A-Za-z0-9]*"))
 
555
            self.lineEditJobName.setValidator(validatorSimpleName)
 
556
            self.lineEditJobGroup.setValidator(validatorSimpleName)
 
557
            self.pushButtonRunSubmit.setText("Submit job")
 
558
 
 
559
        else:
 
560
 
 
561
            try:
 
562
                self.n_procs = int(self.mdl.getString('n_procs'))
 
563
            except Exception:
 
564
                self.n_procs = 1
 
565
 
816
566
 
817
567
        # Connections
818
568
 
819
 
        self.connect(self.comboBoxArchi, SIGNAL("activated(const QString &)"), self.slotBatchCalculation)
820
 
        self.connect(self.toolButtonSearch, SIGNAL("clicked()"), self.slotSearchBatchScriptFile)
821
 
        self.connect(self.spinBoxProcs, SIGNAL("valueChanged(int)"), self.slotParallelComputing)
 
569
        if self.case['batch_type'] != None:
 
570
            self.connect(self.lineEditJobName, SIGNAL("textChanged(const QString &)"),
 
571
                         self.slotJobName)
 
572
            self.connect(self.spinBoxNodes, SIGNAL("valueChanged(int)"),
 
573
                         self.slotJobNodes)
 
574
            self.connect(self.spinBoxPpn, SIGNAL("valueChanged(int)"),
 
575
                         self.slotJobPpn)
 
576
            self.connect(self.spinBoxProcs, SIGNAL("valueChanged(int)"),
 
577
                         self.slotJobProcs)
 
578
            self.connect(self.spinBoxDays, SIGNAL("valueChanged(int)"),
 
579
                         self.slotJobWallTime)
 
580
            self.connect(self.spinBoxHours, SIGNAL("valueChanged(int)"),
 
581
                         self.slotJobWallTime)
 
582
            self.connect(self.spinBoxMinutes, SIGNAL("valueChanged(int)"),
 
583
                         self.slotJobWallTime)
 
584
            self.connect(self.spinBoxSeconds, SIGNAL("valueChanged(int)"),
 
585
                         self.slotJobWallTime)
 
586
            self.connect(self.comboBoxClass, SIGNAL("activated(const QString&)"),
 
587
                         self.slotClass)
 
588
            self.connect(self.lineEditJobGroup, SIGNAL("textChanged(const QString &)"),
 
589
                         self.slotJobGroup)
 
590
 
 
591
        else:
 
592
            self.connect(self.spinBoxNProcs, SIGNAL("valueChanged(int)"), self.slotParallelComputing)
 
593
 
 
594
        self.connect(self.toolButtonSearchBatch, SIGNAL("clicked()"), self.slotSearchBatchFile)
 
595
        self.connect(self.comboBoxRunType, SIGNAL("activated(const QString&)"), self.slotArgRunType)
822
596
        self.connect(self.toolButtonFiles, SIGNAL("clicked()"), self.slotUserFiles)
823
597
        self.connect(self.toolButtonAdvanced, SIGNAL("clicked()"), self.slotAdvancedOptions)
824
 
        self.connect(self.pushButtonRun, SIGNAL("clicked()"), self.slotBatchRunning)
 
598
        self.connect(self.pushButtonRunSubmit, SIGNAL("clicked()"), self.slotBatchRunning)
 
599
 
 
600
        # Combomodels
 
601
 
 
602
        self.modelArg_cs_verif = ComboModel(self.comboBoxRunType, 2, 1)
 
603
 
 
604
        self.modelArg_cs_verif.addItem(self.tr("Import mesh / partition only"), 'none')
 
605
        self.modelArg_cs_verif.addItem(self.tr("Mesh preprocessing"), 'mesh preprocess')
 
606
        self.modelArg_cs_verif.addItem(self.tr("Mesh quality criteria"), 'mesh quality')
 
607
        self.modelArg_cs_verif.addItem(self.tr("Standard"), 'standard')
 
608
        self.modelArg_cs_verif.setItem(str_model=self.mdl.getRunType())
 
609
 
825
610
 
826
611
        # initialize Widgets
827
612
 
828
 
        if self.case['computer'] == "":
829
 
            key = 'station'
830
 
            self.case['computer'] = key
831
 
            self.modelArchi.setItem(str_model=key)
832
 
            self.slotBatchCalculation(self.tr('Workstation'))
833
 
            if self.case['scripts_path']:
834
 
                if "runcase" in os.listdir(self.case['scripts_path']):
835
 
                    if key in self.case['batchScript']:
836
 
                        self.case['batchScript'][key] = "runcase"
837
 
                        self.displayBatchScriptInfo()
838
 
                        setGreenColor(self.toolButtonSearch, False)
 
613
        # Check if the script file name is already defined
 
614
 
 
615
        name = self.case['batch']
 
616
        if name:
 
617
            self.labelBatchName.setText(QString(name))
 
618
            setGreenColor(self.toolButtonSearchBatch, False)
839
619
        else:
840
 
            self.modelArchi.setItem(str_model=self.case['computer'])
841
 
            self.slotBatchCalculation(self.modelArchi.dicoM2V[self.case['computer']])
 
620
            setGreenColor(self.toolButtonSearchBatch, True)
 
621
 
 
622
        if self.case['batch_type'] != None and self.case['batch']:
 
623
            self.displayBatchInfo()
 
624
 
 
625
        # Script info is based on the XML model
 
626
 
 
627
        self.displayScriptInfo()
 
628
 
 
629
 
 
630
    @pyqtSignature("const QString &")
 
631
    def slotJobName(self, v):
 
632
        """
 
633
        Increment, decrement and colorize the input argument entry
 
634
        """
 
635
        if self.lineEditJobName.validator().state == QValidator.Acceptable:
 
636
            self.jmdl.dictValues['job_name'] = str(v)
 
637
            self.jmdl.updateBatchFile('job_name')
 
638
 
 
639
 
 
640
    @pyqtSignature("int")
 
641
    def slotJobNodes(self, v):
 
642
        """
 
643
        Increment, decrement and colorize the input argument entry
 
644
        """
 
645
        self.jmdl.dictValues['job_nodes'] = str(self.spinBoxNodes.text())
 
646
        self.jmdl.updateBatchFile('job_nodes')
 
647
 
 
648
 
 
649
    @pyqtSignature("int")
 
650
    def slotJobPpn(self, v):
 
651
        """
 
652
        Increment, decrement and colorize the input argument entry
 
653
        """
 
654
        self.jmdl.dictValues['job_ppn']  = str(self.spinBoxPpn.text())
 
655
        self.jmdl.updateBatchFile('job_ppn')
 
656
 
 
657
 
 
658
    @pyqtSignature("int")
 
659
    def slotJobProcs(self, v):
 
660
        """
 
661
        Increment, decrement and colorize the input argument entry
 
662
        """
 
663
        self.jmdl.dictValues['job_procs']  = str(self.spinBoxProcs.text())
 
664
        self.jmdl.updateBatchFile('job_procs')
 
665
 
 
666
 
 
667
    @pyqtSignature("")
 
668
    def slotJobWallTime(self):
 
669
 
 
670
        h_cput = self.spinBoxDays.value()*24 + self.spinBoxHours.value()
 
671
        m_cput = self.spinBoxMinutes.value()
 
672
        s_cput = self.spinBoxSeconds.value()
 
673
        self.jmdl.dictValues['job_walltime'] = h_cput*3600 + m_cput*60 + s_cput
 
674
        self.jmdl.updateBatchFile('job_walltime')
 
675
 
 
676
 
 
677
    @pyqtSignature("")
 
678
    def slotClass(self):
 
679
 
 
680
        self.jmdl.dictValues['job_class'] = str(self.comboBoxClass.currentText())
 
681
        if len(self.jmdl.dictValues['job_class']) > 0:
 
682
            self.jmdl.updateBatchFile('job_class')
 
683
 
 
684
 
 
685
    @pyqtSignature("const QString &")
 
686
    def slotJobGroup(self, v):
 
687
        """
 
688
        Increment, decrement and colorize the input argument entry
 
689
        """
 
690
        if self.lineEditJobName.validator().state == QValidator.Acceptable:
 
691
            self.jmdl.dictValues['job_group'] = str(v)
 
692
            self.jmdl.updateBatchFile('job_group')
 
693
 
 
694
 
 
695
    @pyqtSignature("const QString &")
 
696
    def slotArgRunType(self, text):
 
697
        """
 
698
        Input run type option.
 
699
        """
 
700
        self.run_type = self.modelArg_cs_verif.dicoV2M[str(text)]
 
701
        self.mdl.setRunType(self.run_type)
842
702
 
843
703
 
844
704
    @pyqtSignature("int")
846
706
        """
847
707
        Increment, decrement and colorize the input argument entry
848
708
        """
849
 
        self.mdl.dicoValues['NUMBER_OF_PROCESSORS'] = v
850
 
        self.mdl.updateBatchScriptFile('NUMBER_OF_PROCESSORS')
851
 
 
852
 
 
853
 
    @pyqtSignature("")
854
 
    def pbsJobManagement(self):
855
 
        """
856
 
        Get PBS card informations.
857
 
        """
858
 
        default = {}
859
 
        list = ['PBS_JOB_NAME', 'PBS_nodes', 'PBS_ppn', 'PBS_walltime']
860
 
        for opt in list:
861
 
            default[opt] = self.mdl.dicoValues[opt]
862
 
        log.debug("pbsJobManagement -> %s" % str(default))
863
 
 
864
 
        dialog = BatchRunningPBSJobManagementDialogView(self, default)
865
 
 
866
 
        if dialog.exec_():
867
 
            result = dialog.get_result()
868
 
            log.debug("pbsJobManagement -> %s" % str(result))
869
 
            for option in list:
870
 
                self.mdl.dicoValues[option] = result[option]
871
 
 
872
 
        self.mdl.updateBatchScriptFile()
873
 
 
874
 
    @pyqtSignature("")
875
 
    def lsfJobManagement(self):
876
 
        """
877
 
        Get LSF card informations
878
 
        """
879
 
        pass
880
 
##        default = {}
881
 
##        default['job_name'] = self.mdl.dicoValues['PBS_JOB_NAME']
882
 
##        default['NQS_cput'] =
883
 
##        default['NQS_cpuT'] =
884
 
##        windowTitle = self.tr("CaThy")
885
 
##        dialog = LSFJobManagementDialog(self.myPage, title=t.CATHY, default=default)
886
 
##
887
 
##        self.job_name = dialog.result['job_name']
888
 
##        self.NQS_cpult = dialog.result['NQS_cput']
889
 
##        self.NQS_cpulT = dialog.result['NQS_cpuT'] + dialog.result['NQS_cput']
890
 
##
891
 
##        self.mdl.updateBatchScriptFile()
 
709
        self.n_procs = int(v)
 
710
        self.mdl.setString('n_procs', str(v))
892
711
 
893
712
 
894
713
    @pyqtSignature("")
895
714
    def slotUserFiles(self):
896
715
        """
897
 
        Input 'USER_INPUT_FILES' and 'USER_OUTPUT_FILES'
 
716
        Input user data files
898
717
        """
899
 
        default = {}
900
 
        default['data_path'] = self.case['data_path']
901
 
        default['data']      = string.split(self.mdl.dicoValues['USER_INPUT_FILES'])
902
 
        default['results']   = string.split(self.mdl.dicoValues['USER_OUTPUT_FILES'])
 
718
        default = self.mdl.getUserInputFiles()
903
719
        log.debug("slotUserFiles -> %s" % str(default))
904
720
 
905
 
        dialog = BatchRunningUserFilesDialogView(self, default)
 
721
        dialog = BatchRunningUserFilesDialogView(self,
 
722
                                                 self.case['data_path'],
 
723
                                                 default)
906
724
 
907
725
        if dialog.exec_():
908
726
            result = dialog.get_result()
909
727
            log.debug("slotUserFiles -> %s" % str(result))
910
 
            self.mdl.dicoValues['USER_INPUT_FILES']   = string.join(result['data'])
911
 
            self.mdl.dicoValues['USER_OUTPUT_FILES'] = string.join(result['results'])
912
 
            self.mdl.updateBatchScriptFile('USER_INPUT_FILES')
913
 
            self.mdl.updateBatchScriptFile('USER_OUTPUT_FILES')
 
728
            self.mdl.setUserInputFiles(result)
914
729
 
915
730
 
916
731
    @pyqtSignature("")
918
733
        """
919
734
        Ask one popup for advanced specifications
920
735
        """
921
 
        default = {}
922
 
        list = ['CS_TMP_PREFIX', 'EXEC_PREPROCESS', 'EXEC_PARTITION', 'EXEC_KERNEL',
923
 
                'PARTITION_LIST', 'VALGRIND', 'CS_LIB_ADD',
924
 
                'ARG_CS_VERIF', 'ARG_CS_OUTPUT', ]
925
 
        for option in list:
926
 
            default[option] = self.mdl.dicoValues[option]
927
 
        log.debug("slotAdvancedOptions result = %s "%str(default))
 
736
        log.debug("slotAdvancedOptions")
928
737
 
929
 
        dialog = BatchRunningAdvancedOptionsDialogView(self, default)
 
738
        dialog = BatchRunningAdvancedOptionsDialogView(self)
930
739
 
931
740
        if dialog.exec_():
932
 
            result = dialog.get_result()
933
 
            log.debug("slotAdvancedOptions result = %s "%str(result))
934
 
            for option in list:
935
 
                self.mdl.dicoValues[option] = result[option]
936
 
                self.mdl.updateBatchScriptFile(option)
 
741
            log.debug("slotAdvancedOptions validated")
937
742
 
938
743
 
939
744
    @pyqtSignature("")
941
746
        """
942
747
        Launch Code_Saturne batch running.
943
748
        """
944
 
        # Test 1: is the file saved?
 
749
        # Is the file saved?
945
750
 
946
751
        if self.case['new'] == "yes" or self.case.isModified():
947
752
 
948
753
            title = self.tr("Warning")
949
754
            msg   = self.tr("The current case must be saved before "\
950
 
                            "running a Code_Saturne batch job.")
951
 
            QMessageBox.information(self, title, msg)
952
 
            return
953
 
#        if self.case.saved() == "no":
954
 
#            self.case.xmlSaveDocument()
955
 
#            self.mdl.dicoValues['PARAM'] = os.path.basename(self.case['xmlfile'])
956
 
#            self.mdl.updateBatchScriptFile('PARAM')
957
 
 
958
 
        # Test 2: have we a mesh?
959
 
 
960
 
        if not GuiParam.matisse :
961
 
            node_ecs = self.case.xmlGetNode('solution_domain')
962
 
            if not node_ecs.xmlGetNode('meshes_list'):
963
 
                if not node_ecs.xmlGetNode('meshes_list').xmlGetNodeList('mesh'):
964
 
                    title = self.tr("Warning")
965
 
                    msg   = self.tr("You have to select a mesh.\n\n")
966
 
                    QMessageBox.information(self, title, msg)
967
 
                    return
968
 
 
969
 
        # Test 3: have we a trouble with the mesh generation?
970
 
 
971
 
        if GuiParam.matisse :
972
 
            import Pages.Matisse as Matisse
973
 
            if not Matisse.MatisseMeshRunning(self.case).ok :
 
755
                            "running the ") + self.tr(self.case['package']).code_name + self.tr(" script.")
 
756
            QMessageBox.information(self, title, msg)
 
757
            return
 
758
 
 
759
        # Do we have a mesh ?
 
760
 
 
761
        have_mesh = False
 
762
        node_ecs = self.case.xmlGetNode('solution_domain')
 
763
        if node_ecs.xmlGetNode('meshes_list'):
 
764
            if node_ecs.xmlGetNode('meshes_list').xmlGetNodeList('mesh'):
 
765
                have_mesh = True
 
766
        if node_ecs.xmlGetNode('mesh_input', 'path'):
 
767
            have_mesh = True
 
768
        if not have_mesh:
 
769
            title = self.tr("Warning")
 
770
            msg   = self.tr("You have to select a mesh.\n\n")
 
771
            QMessageBox.information(self, title, msg)
 
772
            return
 
773
 
 
774
        # Verify if boundary condition definitions exist
 
775
 
 
776
        bd = LocalizationModel('BoundaryZone', self.case)
 
777
        if not bd.getZones():
 
778
            if self.case['no_boundary_conditions'] == False:
974
779
                title = self.tr("Warning")
975
 
                msg   = self.tr("Mesh generation error.\nSee the file 'listsim'")
976
 
                QMessageBox.information(self, title, msg)
977
 
                return
978
 
 
979
 
        # Test 4: verify if boundary definition exists
980
 
 
981
 
##        if not GuiParam.matisse:
982
 
##            from DefineBoundaryRegionsModel import DefBCModel
983
 
##            groupList = DefBCModel(self.case).getListLabel()
984
 
##            if not groupList:
985
 
##                if self.case['no_boundary_conditions'] == False:
986
 
##                    title = self.tr("Warning")
987
 
##                    msg   = self.tr("No boundary definition declared.\n\n")
988
 
##                    QMessageBox.warning(self, title, msg)
989
 
##                    self.case['no_boundary_conditions'] = True
990
 
 
991
 
        if not GuiParam.matisse:
992
 
            bd = LocalizationModel('BoundaryZone', self.case)
993
 
            if not bd.getZones():
994
 
                if self.case['no_boundary_conditions'] == False:
995
 
                    title = self.tr("Warning")
996
 
                    msg   = self.tr("No boundary definition declared.\n\n")
997
 
                    QMessageBox.warning(self, title, msg)
998
 
                    self.case['no_boundary_conditions'] = True
999
 
 
1000
 
        # Command line building
1001
 
 
1002
 
        key = self.case['computer']
1003
 
 
1004
 
        script = os.path.join(self.case['scripts_path'], self.case['batchScript'][key])
1005
 
        batch1 = os.path.join(self.case['scripts_path'], "batch")
1006
 
        batch2 = batch1 + '~'
1007
 
 
1008
 
        if key == 'station':
1009
 
            try:
1010
 
                os.rename(batch1, batch2)
1011
 
            except:
1012
 
                pass
1013
 
            cmd = 'nice nohup ' + script + ' | tee ' + batch1 + ' &'
1014
 
# FIXME: Work in progress
1015
 
##            dialog = CalculationDialog(self.master, title=t.BATCH, stbar=self.stbar,
1016
 
##                                       script, batch1)
1017
 
##            cmd = 'nice nohup ' + script + 'dialog' + ' &'
1018
 
        elif key == 'pbs':
1019
 
            #cmd = 'qsub ' + script + ' ' + self.case['batchScript'][key] + ' &'
1020
 
            cmd = 'qsub ' + script
1021
 
        elif key == 'lsf':
1022
 
            cmd = 'bsub ' + script + ' ' + self.case['batchScript'][key] + ' &'
1023
 
        elif key == 'sge':
 
780
                msg   = self.tr("No boundary definition declared.\n\n")
 
781
                QMessageBox.warning(self, title, msg)
 
782
                self.case['no_boundary_conditions'] = True
 
783
 
 
784
        # Build command line
 
785
 
 
786
        key = self.case['batch_type']
 
787
 
 
788
        batch = os.path.join(self.case['scripts_path'], self.case['batch'])
 
789
 
 
790
        if key == None:
 
791
            cmd = 'nice nohup ' + batch + ' | tee ' + batch + '.log &'
 
792
        elif key[0:3] == 'CCC':
 
793
            cmd = 'qsub ' + batch
 
794
        elif key[0:5] == 'LOADL':
 
795
            cmd = 'llsubmit ' + batch
 
796
        elif key[0:3] == 'LSF':
 
797
            cmd = 'bsub < ' + batch + ' ' + self.case['batch'] + ' &'
 
798
        elif key[0:3] == 'PBS' or key[0:3] == 'SGE':
 
799
            cmd = 'qsub ' + batch
 
800
        elif key[0:5] == 'SLURM':
 
801
            cmd = 'sbatch ' + batch
 
802
        else:
1024
803
            pass
1025
804
 
1026
805
        if self.case['salome']:
1027
 
            import  SalomeHandler
1028
 
            SalomeHandler.runSolver(self.case, script)
 
806
            from Pages import  SalomeHandler
 
807
            SalomeHandler.runSolver(self.case, batch)
1029
808
        else:
1030
809
            os.system(cmd)
1031
810
 
1032
811
 
1033
 
    def displayBatchScriptInfo(self):
1034
 
        """
1035
 
        Layout of the second part of this page.
1036
 
        """
1037
 
        self.groupBoxBatch.show()
1038
 
 
1039
 
        self.labelJob.hide()
1040
 
        self.toolButtonJob.hide()
1041
 
 
1042
 
        if hasattr(self, 'mdl'):
1043
 
            del self.mdl
1044
 
        self.mdl = BatchRunningModel(self.case)
1045
 
        self.mdl.readBatchScriptFile()
1046
 
 
1047
 
        self.labelFilename.show()
1048
 
        self.computer = self.modelArchi.dicoV2M[str(self.comboBoxArchi.currentText())]
1049
 
        name = self.case['batchScript'][self.computer]
1050
 
        self.labelFilename.setText(QString(name))
1051
 
 
1052
 
        if self.case['computer'] == 'station':
1053
 
            if GuiParam.matisse :
1054
 
                self.labelFiles.show()
1055
 
                self.toolButtonFiles.show()
1056
 
                self.labelProcs.hide()
1057
 
                self.spinBoxProcs.hide()
1058
 
            else:
1059
 
                self.labelFiles.show()
1060
 
                self.toolButtonFiles.show()
1061
 
                self.labelProcs.show()
1062
 
                self.spinBoxProcs.show()
1063
 
        else:
1064
 
            self.labelProcs.hide()
1065
 
            self.spinBoxProcs.hide()
1066
 
            self.labelJob.show()
1067
 
            self.toolButtonJob.show()
1068
 
            if self.case['computer'] == "pbs":
1069
 
                self.connect(self.toolButtonJob, SIGNAL("clicked()"), self.pbsJobManagement)
1070
 
            if self.case['computer'] == "lsf":
1071
 
                self.connect(self.toolButtonJob, SIGNAL("clicked()"), self.lsfJobManagement)
1072
 
            if self.case['computer'] == "sge":
1073
 
                pass
1074
 
 
1075
 
#            self.lineBatch1.show()
1076
 
#            self.labelAdvanced.show()
1077
 
#            self.toolButtonAdvanced.show()
1078
 
 
1079
 
        dico = self.mdl.dicoValues
1080
 
 
1081
 
        if dico['NUMBER_OF_PROCESSORS'] == "":
1082
 
            dico['NUMBER_OF_PROCESSORS'] = "1"
1083
 
        if self.case['computer'] == 'station':
1084
 
            self.spinBoxProcs.setValue(int(dico['NUMBER_OF_PROCESSORS']))
1085
 
 
1086
 
        self.mdl.updateBatchScriptFile()
1087
 
 
1088
 
 
1089
 
    @pyqtSignature("const QString &")
1090
 
    def slotBatchCalculation(self, text):
1091
 
        """
1092
 
        1) Look if the batch script file name is allready known
1093
 
        for the current computer
1094
 
        2) Display the apropriate frame for the selected computer
1095
 
        """
1096
 
        log.debug("slotBatchCalculation -> %s" % str(text))
1097
 
        self.groupBoxBatch.hide()
1098
 
 
1099
 
        key = self.modelArchi.dicoV2M[str(text)]
1100
 
        self.case['computer'] = key
1101
 
        log.debug("slotBatchCalculation -> %s" % key)
1102
 
 
1103
 
        self.labelLauncher.setEnabled(True)
1104
 
 
1105
 
        if key in self.case['batchScript'] and self.case['batchScript'][key]:
1106
 
            self.displayBatchScriptInfo()
1107
 
            setGreenColor(self.toolButtonSearch, False)
1108
 
        else:
1109
 
            self.labelFilename.hide()
1110
 
            setGreenColor(self.toolButtonSearch, True)
 
812
    def getCommandOutput(self, cmd):
 
813
        """
 
814
        Run a command and return it's standard output.
 
815
        """
 
816
        p = subprocess.Popen(cmd,
 
817
                             shell=True,
 
818
                             stdout=subprocess.PIPE,
 
819
                             stderr=subprocess.PIPE)
 
820
        lines = []
 
821
        while True:
 
822
            l = p.stdout.readline()
 
823
            lines.append(l.strip())
 
824
            if len(l) == 0 and p.poll() != None:
 
825
                break
 
826
        output = p.communicate()
 
827
 
 
828
        if p.returncode == 0:
 
829
            return lines
 
830
 
 
831
 
 
832
    def getClassList(self):
 
833
        """
 
834
        Layout of the second part of this page.
 
835
        """
 
836
 
 
837
        self.class_list = []
 
838
 
 
839
        try:
 
840
 
 
841
            if self.case['batch_type'][0:3] == 'CCC':
 
842
                output = self.getCommandOutput('class')
 
843
                for l in output[1:]:
 
844
                    if len(l) == 0:
 
845
                        break
 
846
                    else:
 
847
                        self.class_list.append(l.split(' ')[0])
 
848
 
 
849
            elif self.case['batch_type'][0:5] == 'LOADL':
 
850
                output = self.getCommandOutput('llclass')
 
851
                ignore = True
 
852
                for l in output:
 
853
                    if l[0:3] == '---':
 
854
                        ignore = not ignore
 
855
                    elif ignore == False:
 
856
                        self.class_list.append(l.split(' ')[0])
 
857
 
 
858
            elif self.case['batch_type'][0:3] == 'LSF':
 
859
                output = self.getCommandOutput('bqueues')
 
860
                ignore = True
 
861
                for l in output[1:]:
 
862
                    if len(l) == 0:
 
863
                        break
 
864
                    else:
 
865
                        self.class_list.append(l.split(' ')[0])
 
866
 
 
867
            elif self.case['batch_type'][0:3] == 'PBS':
 
868
                output = self.getCommandOutput('qstat -q')
 
869
                ignore = True
 
870
                for l in output:
 
871
                    if l[0:3] == '---':
 
872
                        ignore = not ignore
 
873
                    elif ignore == False:
 
874
                        self.class_list.append(l.split(' ')[0])
 
875
 
 
876
            elif self.case['batch_type'][0:3] == 'SGE':
 
877
                output = self.getCommandOutput('qconf -sc')
 
878
                for l in output:
 
879
                    if l[0:1] != '#':
 
880
                        self.class_list.append(l.split(' ')[0])
 
881
 
 
882
            elif self.case['batch_type'][0:5] == 'SLURM':
 
883
                output = self.getCommandOutput('sinfo -s')
 
884
                for l in output[1:]:
 
885
                    if len(l) == 0:
 
886
                        break
 
887
                    else:
 
888
                        name = l.split(' ')[0]
 
889
                        if name[-1:] == '*':
 
890
                            name = name[:-1]
 
891
                        self.class_list.append(name)
 
892
 
 
893
        except Exception:
 
894
            pass
 
895
 
 
896
 
 
897
    def hideBatchInfo(self):
 
898
        """
 
899
        hide all batch info before displaying a selected subset
 
900
        """
 
901
 
 
902
        self.groupBoxJob.hide()
 
903
 
 
904
        self.labelJobName.hide()
 
905
        self.lineEditJobName.hide()
 
906
        self.labelNodes.hide()
 
907
        self.spinBoxNodes.hide()
 
908
        self.labelPpn.hide()
 
909
        self.spinBoxPpn.hide()
 
910
        self.labelProcs.hide()
 
911
        self.spinBoxProcs.hide()
 
912
        self.labelClass.hide()
 
913
        self.labelWTime.hide()
 
914
        self.spinBoxDays.hide()
 
915
        self.labelDays.hide()
 
916
        self.spinBoxHours.hide()
 
917
        self.labelHours.hide()
 
918
        self.spinBoxMinutes.hide()
 
919
        self.labelMinutes.hide()
 
920
        self.spinBoxSeconds.hide()
 
921
        self.labelSeconds.hide()
 
922
        self.comboBoxClass.hide()
 
923
        self.labelJobGroup.hide()
 
924
        self.lineEditJobGroup.hide()
 
925
 
 
926
 
 
927
    def displayBatchInfo(self):
 
928
        """
 
929
        Layout of the second part of this page.
 
930
        """
 
931
 
 
932
        self.job_name     = self.jmdl.dictValues['job_name']
 
933
        self.job_nodes = self.jmdl.dictValues['job_nodes']
 
934
        self.job_ppn  = self.jmdl.dictValues['job_ppn']
 
935
        self.job_procs = self.jmdl.dictValues['job_procs']
 
936
        self.job_walltime = self.jmdl.dictValues['job_walltime']
 
937
        self.job_class  = self.jmdl.dictValues['job_class']
 
938
        self.job_group  = self.jmdl.dictValues['job_group']
 
939
 
 
940
        if self.job_name != None:
 
941
            self.labelJobName.show()
 
942
            self.lineEditJobName.setText(QString(self.job_name))
 
943
            self.lineEditJobName.show()
 
944
 
 
945
        if self.job_nodes != None:
 
946
            self.labelNodes.show()
 
947
            self.spinBoxNodes.setValue(int(self.job_nodes))
 
948
            self.spinBoxNodes.show()
 
949
 
 
950
        if self.job_ppn != None:
 
951
            self.labelPpn.show()
 
952
            self.spinBoxPpn.setValue(int(self.job_ppn))
 
953
            self.spinBoxPpn.show()
 
954
 
 
955
        if self.job_procs != None:
 
956
            self.labelProcs.show()
 
957
            self.spinBoxProcs.setValue(int(self.job_procs))
 
958
            self.spinBoxProcs.show()
 
959
 
 
960
        if self.job_walltime != None:
 
961
            seconds = self.job_walltime
 
962
            minutes = seconds / 60
 
963
            hours = minutes / 60
 
964
            days = hours / 24
 
965
            seconds = seconds % 60
 
966
            minutes = minutes % 60
 
967
            hours = hours % 24
 
968
            self.spinBoxDays.setValue(days)
 
969
            self.spinBoxHours.setValue(hours)
 
970
            self.spinBoxMinutes.setValue(minutes)
 
971
            self.spinBoxSeconds.setValue(seconds)
 
972
            self.labelWTime.show()
 
973
            self.spinBoxDays.show()
 
974
            self.labelDays.show()
 
975
            self.spinBoxHours.show()
 
976
            self.labelHours.show()
 
977
            self.spinBoxMinutes.show()
 
978
            self.labelMinutes.show()
 
979
            self.spinBoxSeconds.show()
 
980
            self.labelSeconds.show()
 
981
 
 
982
        if self.job_class != None:
 
983
 
 
984
            # Only one pass here
 
985
            if self.class_list == None:
 
986
                self.getClassList()
 
987
                if len(self.class_list) > 0:
 
988
                    for c in self.class_list:
 
989
                        self.comboBoxClass.addItem(self.tr(c), QVariant(c))
 
990
                else:
 
991
                    c = self.job_class
 
992
                    self.comboBoxClass.addItem(self.tr(c), QVariant(c))
 
993
 
 
994
            # All passes
 
995
            try:
 
996
                index = self.class_list.index(self.job_class)
 
997
                self.comboBoxClass.setCurrentIndex(index)
 
998
            except Exception:
 
999
                if len(self.class_list) > 0:
 
1000
                    self.job_class = self.class_list[0]
 
1001
            self.labelClass.show()
 
1002
            self.comboBoxClass.show()
 
1003
 
 
1004
        if self.job_group != None:
 
1005
            self.labelJobGroup.show()
 
1006
            self.lineEditJobGroup.setText(QString(self.job_group))
 
1007
            self.lineEditJobGroup.show()
 
1008
 
 
1009
        # Show Job management box
 
1010
 
 
1011
        if self.case['batch_type'][0:5] == 'LOADL':
 
1012
            self.groupBoxJob.setTitle("Load Leveler job parameters")
 
1013
        elif self.case['batch_type'][0:3] == 'LSF':
 
1014
            self.groupBoxJob.setTitle("LSF job parameters")
 
1015
        elif self.case['batch_type'][0:3] == 'PBS':
 
1016
            self.groupBoxJob.setTitle("PBS job parameters")
 
1017
        elif self.case['batch_type'][0:3] == 'SGE':
 
1018
            self.groupBoxJob.setTitle("Sun Grid Engine job parameters")
 
1019
        if self.case['batch_type'][0:5] == 'SLURM':
 
1020
            self.groupBoxJob.setTitle("SLURM job parameters")
 
1021
        else:
 
1022
            self.groupBoxJob.setTitle("Batch job parameters")
 
1023
 
 
1024
        self.groupBoxJob.show()
 
1025
 
 
1026
        # Update file
 
1027
 
 
1028
        self.jmdl.updateBatchFile()
 
1029
 
 
1030
 
 
1031
    def displayScriptInfo(self):
 
1032
        """
 
1033
        Layout of the second part of this page.
 
1034
        """
 
1035
 
 
1036
        self.labelFiles.show()
 
1037
        self.toolButtonFiles.show()
 
1038
 
 
1039
        if self.case['batch_type'] == None:
 
1040
            self.labelNProcs.show()
 
1041
            self.spinBoxNProcs.show()
 
1042
        else:
 
1043
            self.labelNProcs.hide()
 
1044
            self.spinBoxNProcs.hide()
 
1045
 
 
1046
        if self.case['batch_type'] == None:
 
1047
            self.spinBoxNProcs.setValue(self.n_procs)
 
1048
        else:
 
1049
            pass
1111
1050
 
1112
1051
 
1113
1052
    @pyqtSignature("")
1114
 
    def slotSearchBatchScriptFile(self):
 
1053
    def slotSearchBatchFile(self):
1115
1054
        """
1116
 
        Open a FileDialog in order to search the batch script file
 
1055
        Open a FileDialog in order to search the batch command file
1117
1056
        in the system file.
1118
1057
        """
1119
1058
        file_name = ""
1121
1060
            path = self.case['scripts_path']
1122
1061
        else:
1123
1062
            path = os.getcwd()
1124
 
        title = self.tr("Search the batch script")
 
1063
        title = self.tr("Select the batch script")
1125
1064
        filetypes = self.tr("All Files (*)")
1126
1065
        file_name = QFileDialog.getOpenFileName(self, title, path, filetypes)
1127
1066
        file_name = str(file_name)
1128
1067
 
1129
1068
        if file_name:
 
1069
 
1130
1070
            launcher = os.path.basename(file_name)
1131
 
            setGreenColor(self.toolButtonSearch, False)
 
1071
            setGreenColor(self.toolButtonSearchBatch, False)
1132
1072
 
1133
1073
            if self.case['scripts_path'] == os.path.dirname(file_name):
1134
 
 
1135
 
                self.computer = self.modelArchi.dicoV2M[str(self.comboBoxArchi.currentText())]
1136
 
                key = self.computer
1137
 
                if key in self.case['batchScript']:
1138
 
                    self.case['batchScript'][key] = launcher
1139
 
                else:
1140
 
                    print "Warning: slotSearchBatchScriptFile\n Error with key:", key
1141
 
                self.displayBatchScriptInfo()
 
1074
                self.case['batch'] = launcher
 
1075
                self.labelBatchName.setText(QString(launcher))
 
1076
                self.jmdl.readBatchFile()
 
1077
                self.hideBatchInfo()
 
1078
                if self.case['batch_type'] != None:
 
1079
                    self.displayBatchInfo()
1142
1080
            else:
1143
1081
                title = self.tr("Warning")
1144
 
                msg   = self.tr("The new batch script file is not in scripts "\
 
1082
                msg   = self.tr("The new batch file is not in scripts "\
1145
1083
                                "directory given in the 'Identity and paths' "\
1146
1084
                                "section.\n\n" + \
1147
1085
                                "Verify the existence and location of these files, "\