Exemple #1
0
 def update(self):
     self.previewArea.update()
     return
     mix = Mixture()
     for i in range(self.loadTable.rowCount()):
         #for j in range(3,6):
         ##print "Load update", self.loadTable.item(i,5).text(),self.loadTable.cellWidget(i,1).show
         if self.loadTable.cellWidget(i,1).show:
             mix.add(self.myMixture.getMolecule(str(self.loadTable.item(i,5).text())))
     self.previewArea.setMixture(mix)
Exemple #2
0
    def on_saveButton_pressed3(self, saveFiles=True):
        if not saveFiles: return
        selected = self.editor.selectedMolecules()
        #print "on_saveButton_pressed ", selected
        if selected == []:
            QtGui.QMessageBox.warning(
                self, "Wolffia's warning",
                "Could not determine the molecule to be saved.\nPlease select one.",
                QtGui.QMessageBox.Ok)
            return

        mixtureToSave = Mixture("To save")
        molName = ""
        for mol in selected:
            mixtureToSave.add(mol.copy(), False)
            if molName == "":
                molName = mol.molname()
            else:
                molName += ("-" + mol.molname())

        d = WDirectoryDialog(
            self, 'Specify directory to save ' + molName + ".pdb and " +
            molName + ".psf", self.settings.workingFolder)

        try:
            if d.accepted():
                basename = str(d.path() + "/" + molName)
                #import os
                if not (os.path.exists(basename + ".pdb") or os.path.exists(
                        basename + ".psf")) or QtGui.QMessageBox.question(
                            self, "Wolffia's message", "File exists.",
                            "Overwrite", "Cancel") == 0:
                    #mix = self.history.currentState().getMixture()
                    #print "on_saveButton_pressed ", basename
                    mixtureToSave.writePDB(basename + ".pdb")
                    mixtureToSave.writePSF(basename + ".psf")

                    QtGui.QMessageBox.information(
                        self, "Wolffia's message",
                        molName + ".pdb and " + molName + ".psf saved.",
                        QtGui.QMessageBox.Ok)
        except:
            QtGui.QMessageBox.warning(
                self, "Wolffia's warning",
                molName + ".pdb and " + molName + ".psf could not be saved.",
                QtGui.QMessageBox.Ok)
Exemple #3
0
class PropertyEditor(QtWidgets.QWidget):
    def __init__(self, viewer, history):
        super(PropertyEditor, self).__init__()

        # set class fields
        self.viewer = viewer
        self.history = history

        #widgets import
        self.ui = Ui_propertyEditor()
        self.ui.setupUi(self)
        
        self.tree = self.ui.propertyTree
        self.tree.  setColumnWidth(0, 100)
        self.tree.  setColumnWidth(1, 140)        

        #initializes widgets on tree
        self.xRotate = QtWidgets.QDoubleSpinBox(self.tree)
        self.xRotate.  setSingleStep (10.)
        self.xRotate.  setRange (-360., 360.)
        xRotateAt    = self.tree.topLevelItem(1).child(0)
        
        self.yRotate = QtWidgets.QDoubleSpinBox(self.tree)
        self.yRotate.  setSingleStep (10.)
        self.yRotate.  setRange (-360., 360.)
        yRotateAt    = self.tree.topLevelItem(1).child(1)
        
        self.zRotate = QtWidgets.QDoubleSpinBox(self.tree)
        self.zRotate.  setSingleStep (10.)
        self.zRotate.  setRange (-360., 360.)
        zRotateAt    = self.tree.topLevelItem(1).child(2)

        self.xMoveBy = QtWidgets.QDoubleSpinBox(self.tree)
        self.xMoveBy.  setSingleStep (0.5)
        self.xMoveBy.  setRange (-1000., 1000.)
        xMoveByAt    = self.tree.topLevelItem(2).child(0)
        
        self.yMoveBy = QtWidgets.QDoubleSpinBox(self.tree)
        self.yMoveBy.  setSingleStep (0.5)
        self.yMoveBy.  setRange (-1000., 1000.)
        yMoveByAt    = self.tree.topLevelItem(2).child(1)
        
        self.zMoveBy = QtWidgets.QDoubleSpinBox(self.tree)
        self.zMoveBy.  setSingleStep (0.5)
        self.zMoveBy.  setRange (-1000., 1000.)
        zMoveByAt    = self.tree.topLevelItem(2).child(2)
        
        #adds widgets to tree 
        self.tree.setItemWidget(xRotateAt, 1, self.xRotate)  
        self.tree.setItemWidget(yRotateAt, 1, self.yRotate)                
        self.tree.setItemWidget(zRotateAt, 1, self.zRotate)   

        self.tree.setItemWidget(xMoveByAt, 1, self.xMoveBy)  
        self.tree.setItemWidget(yMoveByAt, 1, self.yMoveBy)                
        self.tree.setItemWidget(zMoveByAt, 1, self.zMoveBy)
         
        #manages widget events
        self.xRotate.valueChanged.connect(self.Rotate)
        self.yRotate.valueChanged.connect(self.Rotate)
        self.zRotate.valueChanged.connect(self.Rotate)

        self.xMoveBy.valueChanged.connect(self.MoveBy)
        self.yMoveBy.valueChanged.connect(self.MoveBy)
        self.zMoveBy.valueChanged.connect(self.MoveBy)

        self.tree.resizeColumnToContents(0)
        self.tree.resizeColumnToContents(1)

        #initialize tree window
        self.reset()

    def reset(self):
        #print "PropertyEditor reset "
        self.mixture  = Mixture(None)
        self.registry = dict()
        #self.ident    = None
        
        self.resetBoxes()
        self.setToolTip("Select molecules to activate.")
        self.setEnabled(False)
        self.update()

    def update(self):
        # update resistry
        presentMolecules = self.history.currentState().getMixture().molecules()
        #print "PropertyEditor update  ",presentMolecules, self.registry
        regKeys = list(self.registry.keys())
        for regKey in regKeys:
            if not regKey in presentMolecules:
                if self.mixture.hasMoleculeID(regKey): self.mixture.remove(regKey)
                self.registry.pop(regKey)

        self.resetBoxes()
        QtWidgets.QWidget.update(self)

    def resetBoxes(self):
        if len(self) == 0:
            self.tree.topLevelItem(0).setText(1, "")
        else:
            self.tree.topLevelItem(0).setText(1, str(self))
        self.dx = 0.
        self.dy = 0.
        self.dz = 0.
        self.anglex = 0.
        self.angley = 0.
        self.anglez = 0.
        
        self.xRotate.setValue(0.)
        self.yRotate.setValue(0.)
        self.zRotate.setValue(0.)

        self.xMoveBy.setValue(0.)
        self.yMoveBy.setValue(0.)
        self.zMoveBy.setValue(0.)

    #show molecule name in the editor
    def setMolecule(self, molecule, ident, removeIfPresent=False):
        '''
        Returns True if the molecule ends up selected, False otherwise..
        '''
        from .BuildTab import ShownSolvent
        #print "PropertyEditor setMolecule new", ident,  self.registry
        if ident not in self.registry:
            if ShownSolvent.isSolvent(ident):
                mixture = self.history.currentState().getMixture()
                mixtureNames = mixture.molecules()
                #print "PropertyEditor setMolecule SOLVENT(",mixtureNames
                pos = ident.find(')')+1
                for mol in mixtureNames:
                    if mol[:pos] == ident[:pos]:
                        self.registry[mol] = self.mixture.add(mixture.getMolecule(mol), False)
                        self.registry[mol] = mixture.getMolecule(mol)
            else:
                #print "PropertyEditor setMolecule adding", ident
                self.registry[ident] = molecule
                #print "PropertyEditor setMolecule adding to mixture", ident, self.mixture.molecules()
                self.mixture.add(molecule, False)
            
            #self.ident = ident
            #self.ident = self.getId()
            self.setToolTip("Manage molecules' positions.")
            self.setEnabled(True)
            return False
            self.resetBoxes()
        else:
            #print "PropertyEditor setMolecule duplicate",ident,  self.registry
            if removeIfPresent:
                if ShownSolvent.isSolvent(ident):
                    mixture = self.history.currentState().getMixture()
                    mixtureNames = mixture.molecules()
                    pos = ident.find(')')+1
                    for mol in mixtureNames:
                        #print "PropertyEditor removing ",ident[:pos], mol[:pos]
                        if mol[:pos] == ident[:pos]:
                            #print "PropertyEditor OK "
                            self.removeSelection(mixture.getMolecule(mol), mol)
                else:
                    self.removeSelection(molecule, ident)
                return True
        #print "PropertyEditor setMolecule reseting"
        #print "PropertyEditor setMolecule finished"


    def removeSelection(self, molecule, ident):
        if ident in self.registry:
            self.mixture.remove(self.mixture.getMoleculeID(molecule))
            self.registry.pop(ident)
            #print "PropertyEditor removeSelection removed:",ident
            if len(self.registry) == 0:
                self.reset()
            #print "PropertyEditor setMolecule reseting"
            self.resetBoxes()
    
    def hasSelections(self): return len(self.registry) > 0

    def selectedMolecules(self):
        #print "selectedMolecules ", self.registry
        return list(self.registry.values())

    def selectedNames(self):
        #print "selectedMolecules ",self.registry
        return list(self.registry.keys())

    def __str__(self):
        return str(list(self.registry.keys()))

    def __len__(self):
        return len(self.registry)
    
    #show rotation values in the editor     
    def Rotate(self):        
        if self.mixture.order() > 0:
            x = self.xRotate.value()
            y = self.yRotate.value()
            z = self.zRotate.value()
            value = str(x) + " x " + str(y) + " x " + str(z)
            self.tree.topLevelItem(1).setText(1, value)
            center = self.mixture.center()
            self.mixture.moveBy([-xx for xx in center])
            #print "Rotate ", x-self.anglex,y-self.angley,z-self.anglez
            self.mixture.rotateDeg(x-self.anglex,y-self.angley,z-self.anglez)
            self.mixture.moveBy(center)
            self.anglex = x
            self.angley = y
            self.anglez = z

            self.history.currentState().getMixture().setChanged()
            self.viewer.update()
        else:
            self.tree.topLevelItem(1).setText(1, "0 x 0 x 0")

    def MoveBy(self):
        x = self.xMoveBy.value()
        y = self.yMoveBy.value()
        z = self.zMoveBy.value()

        value = str(x) + " x " + str(y) + " x " + str(z)
        self.tree.topLevelItem(2).setText(1, value)  
        self.mixture.moveBy([x-self.dx,y-self.dy,z-self.dz])
        self.dx = x
        self.dy = y
        self.dz = z
        self.history.currentState().getMixture().setChanged()
        self.viewer.update()

    def getId(self):
        return str(self.mixture.moleculeNames())
Exemple #4
0
for i in range(len(densities)):

    # Density value
    PABAratio = densities[i]
    FileName = "Cellulose_PABA_Tetradecane_D" + d_names[i] + ".wfm"

    # Define mixture
    mixture = Mixture()

    # Generate crystal minus last layer
    monomer = Cellulose(POLY_LENGTH)
    for j in range(VERTICAL_N - 1):
        for i in range(HORIZONTAL_N):
            newMonomer = monomer.copy()
            newMonomer.moveBy([dx * i + dxz * (j % 2), dy * (i % 2), dz * j])
            mixture.add(newMonomer)
            print "layer " + str(j) + ", row " + str(i)

    # Generate last layer
    for i in range(HORIZONTAL_N):
        newMonomer = monomer.copy()
        newMonomer.moveBy([
            dx * i + dxz * ((VERTICAL_N - 1) % 2), dy * (i % 2),
            dz * (VERTICAL_N - 1)
        ])
        mixture.add(newMonomer)
        #print "last layer, row " + str(i)

    #find OHs at the Cellulose nanocrystal
    OHs = list()
    for m in mixture.moleculeGenerator():
Exemple #5
0
class CelluloseEditor(QtGui.QDialog):
    """
	Wolffia's dialogue to produce homopolymers.
	"""

    # Class Fields:
    # ui: stores reference to user interface
    # files: [string, string], PDB and PSF filenames
    # homopol: Mixture, an Homopolymer
    # homopolPreview: MixtureViewer

    def __init__(self, appState, parent=None, settings=None):
        """
		Constructor for homopolymer editor.
		
		Parameters used:
		parent  :	Window, widget or object that was used to call this dialogue
		settings:	Settings
		"""

        super(CelluloseEditor, self).__init__(parent, modal=1)

        self.settings = settings
        self.state = appState
        self.files = None
        self.isAdded = False
        #esto hay que arreglarlo!
        # Que hay que arreglar de aqui??? ~ Radames
        self.history = History()
        self.homopolPreview = MixtureViewer(self.history, self, None)
        self.ui = Ui_CelluloseEditor()

        self.ui.setupUi(self)
        self.generateCellulose()
        self.ui.viewerLayout.addWidget(self.homopolPreview)
        self.ui.headerLabel.setText("Cellulose Crystal Editor")
        #self.ui.stackedWidget.setCurrentIndex	(self.poly.STACK_INDEX)
        self.ui.lengthDSpinner.setSingleStep(self.poly.DISPL)
        self.ui.lengthDSpinner.setMinimum(self.poly.DISPL)
        self.ui.lengthSlider.setTickInterval(self.poly.DISPL)
        self.ui.lengthSlider.setMinimum(self.poly.DISPL)
        self.ui.nSpinBox.setValue(2)

        image = os.path.dirname(
            os.path.realpath(__file__)) + "/images/" + self.poly.IMAGE
        self.ui.diagram.setPixmap(
            QtGui.QPixmap(QtCore.QString.fromUtf8(image)).scaledToHeight(
                100, 1))

        if self.settings != None:
            self.homopolPreview.setHighResolution(self.settings.highResolution)
            self.homopolPreview.setLabeling(self.settings.showLabels)
            self.homopolPreview.showAxes(self.settings.showAxes)
            self.homopolPreview.showHelp(settings.showHelp)
            self.ui.okButton.setText("OK")

        try:
            self.setStyleSheet(open(WOLFFIA_STYLESHEET, 'r').read())
        except:
            print("WARNING: Could not read style specifications")
        self.homopolPreview.update()

    def generateCellulose(self):
        n = self.ui.nSpinBox.value()
        self.homopol = Mixture()
        from chemicalGraph.molecule.polymer.Cellulose import Cellulose
        if self.ui.buttonA.isChecked():
            self.poly = Cellulose(n, 'a')
        else:
            self.poly = Cellulose(n, 'b')
        self.homopol.add(self.poly)

        self.history.currentState().reset()
        self.history.currentState().addMixture(self.homopol)
        self.homopolPreview.update()

    def getMixture(self):
        return self.history.currentState().getMixture()

    # Signal managers
    def on_nSpinBox_valueChanged(self):
        self.generateCellulose()
        length = self.poly.DISPL * self.ui.nSpinBox.value()
        self.ui.lengthDSpinner.setValue(length)
        self.ui.lengthSlider.setValue(length)

    def on_lengthDSpinner_valueChanged(self):
        n = round(self.ui.lengthDSpinner.value() / self.poly.DISPL)
        self.ui.nSpinBox.setValue(n)
        self.ui.lengthSlider.setValue(n * self.poly.DISPL)

    def on_lengthSlider_sliderReleased(self):
        n = int(self.ui.lengthSlider.value() / self.poly.DISPL)
        self.ui.nSpinBox.setValue(n)

    #---------------------------------------------------------------------
    def on_buttonB_toggled(self, checked):
        self.ui.buttonA.setChecked(not checked)
        self.generateCellulose()

    #---------------------------------------------------------------------
    def on_buttonA_toggled(self, checked):
        self.ui.buttonB.setChecked(not checked)
        self.generateCellulose()

    #---------------------------------------------------------------------
    def on_button110_toggled(self, checked):
        if checked:
            self.ui.button100.setChecked(not checked)
            self.ui.button010.setChecked(not checked)
            self.update()

    #---------------------------------------------------------------------
    def on_button100_toggled(self, checked):
        if checked:
            self.ui.button110.setChecked(not checked)
            self.ui.button010.setChecked(not checked)
            self.update()

    #---------------------------------------------------------------------
    def on_button010_toggled(self, checked):
        if checked:
            self.ui.button100.setChecked(not checked)
            self.ui.button110.setChecked(not checked)
            self.update()

    def on_okButton_pressed(self):
        self.generateCellulose()
        self.isAdded = True
        self.close()

    def on_cancelButton_pressed(self):
        self.history.currentState().reset()
        self.close()

    def closeEvent(self, e):
        if not self.isAdded:
            self.history.currentState().updateMixture(Mixture())

    def wheelEvent(self, e):
        super(HomopolyEditor, self).wheelEvent(e)
Exemple #6
0
class BuildTab(QtWidgets.QFrame):
    def __init__(self, hist, parent=None, previewer=None, settings=None):
        super(BuildTab, self).__init__(parent)

        #print "buildTab init in"
        self.history = hist
        self.mixModification = 0
        self.wolffia = parent
        self.allowUpdate = True
        self.buildPreview = previewer
        self.settings = settings
        self.clipboard = None
        self.prevSelection = None
        self.prevShow = None
        self.prevFixed = None

        #widgets import
        self.ui = Ui_buildTab()
        self.ui.setupUi(self)
        self.ui.structManager.setSortingEnabled(False)

        px = QtGui.QPixmap()
        self._WOLFFIA_OS = platform.system()
        px.load(WOLFFIA_GRAPHICS + "hide.gif", format=None)
        ico = QtGui.QIcon()
        ico.addPixmap(px, state=QtGui.QIcon.On)
        self.ui.structManager.horizontalHeaderItem(0).setIcon(ico)

        px2 = QtGui.QPixmap()
        px2.load(WOLFFIA_GRAPHICS + "pin16.png", format=None)
        fixico = QtGui.QIcon()
        fixico.addPixmap(px2, state=QtGui.QIcon.On)
        self.ui.structManager.horizontalHeaderItem(1).setIcon(fixico)

        #initialize editor
        self.editor = PropertyEditor(self.buildPreview, self.history)
        self.ui.editorLayout.addWidget(self.editor)
        self.buildPreview.setBuildTab(self)

        #initialize tool buttons
        self.ui.removeButton.setIcon(QtGui.QIcon().fromTheme(
            "edit-cut", QtGui.QIcon(str(WOLFFIA_GRAPHICS) + "edit-cut.png")))
        self.ui.updateButton.setIcon(QtGui.QIcon().fromTheme(
            "system-software-update",
            QtGui.QIcon(str(WOLFFIA_GRAPHICS) + "system-software-update.png")))
        self.ui.removeButton.setFlat(True)
        self.ui.duplicateButton.setIcon(QtGui.QIcon().fromTheme(
            "edit-paste",
            QtGui.QIcon(str(WOLFFIA_GRAPHICS) + "edit-paste.png")))
        self.ui.copyButton.setIcon(QtGui.QIcon().fromTheme(
            "edit-copy", QtGui.QIcon(str(WOLFFIA_GRAPHICS) + "edit-copy.png")))
        self.ui.saveWFMbutton.setIcon(QtGui.QIcon().fromTheme(
            "document-save",
            QtGui.QIcon(str(WOLFFIA_GRAPHICS) + "document-save.png")))
        self.ui.addCustomButton.setIcon(QtGui.QIcon().fromTheme(
            "document-open",
            QtGui.QIcon(str(WOLFFIA_GRAPHICS) + "document-open.png")))

        self.showCheckboxes = dict()

        self.firstUpdate = True
        #print "buildTab init out", QtGui.QWidget.keyboardGrabber ()

        self.cMol = C_MOLECULE_CATALOG

    def _checkFixedShiftModifier_(self, basePin, selected):
        for i in range(self.ui.structManager.rowCount()):
            if self.ui.structManager.cellWidget(i, 1) == basePin:
                row = i
                break

        modifiers = QtGui.QApplication.keyboardModifiers()
        if modifiers == QtCore.Qt.ShiftModifier and self.prevFixed != None:
            if self.prevFixed[1] == selected:
                if row < self.prevFixed[0]:
                    ind = list(range(row + 1, self.prevFixed[0] + 1))
                else:
                    ind = list(range(self.prevFixed[0], row))
                for i in ind:
                    pin = self.ui.structManager.cellWidget(i, 1)
                    #if selected: pin.setFixed(update=False)
                    if self.prevFixed[1]: pin.setFixed(update=False)
                    else: pin.setLoose(update=False)
        self.prevFixed = [row, selected]
        #self.buildPreview.update()

    def _checkShowShiftModifier_(self, baseEye, selected):
        #find row
        for i in range(self.ui.structManager.rowCount()):
            if self.ui.structManager.cellWidget(i, 0) == baseEye:
                row = i
                break

        modifiers = QtGui.QApplication.keyboardModifiers()
        if modifiers == QtCore.Qt.ShiftModifier and self.prevShow != None:
            if self.prevShow[1] == selected:
                if row < self.prevShow[0]:
                    ind = list(range(row, self.prevShow[0]))
                else:
                    ind = list(range(self.prevShow[0] + 1, row))
                for i in ind:
                    pin = self.ui.structManager.cellWidget(i, 0)
                    #if selected: pin.setShown(update=False)
                    if self.prevShow[1]: pin.setShown(update=False)
                    else: pin.setHidden(update=False)
        self.prevShow = [row, selected]
        #self.buildPreview.update()

    #---------------------------------------------------------------
    def on_structManager_cellPressed(self, i, j):
        #print "on_structManager_cellPressed ",  i,j
        mouse_state = QtGui.qApp.mouseButtons()
        if QtGui.qApp.mouseButtons() == QtCore.Qt.LeftButton:
            #print "on_structManager_cellPressed ", QtGui.qApp.mouseButtons()==QtCore.Qt.LeftButton, mouse_state==QtCore.Qt.NoButton
            QtGui.qApp.sendEvent(self.ui.structManager,
                                 QtCore.QEvent(QtCore.QEvent.MouseButtonPress))
            #self.ui.structManager.cellPressed.emit(i,j)

    #activates the Structure Catalog
    def on_molCatalog_itemActivated(self, item):
        #print "on_molCatalog_itemActivated in"
        self.key = str(item.text(0))
        self.parent = item.parent().text(0)

        def moleculeDialog(self, dialog):
            dialog.show()
            dialog.exec_()
            self.addMixture(dialog.getMixture())
            self.buildPreview.update()

        # Polymers
        if self.key == "Polyaniline":
            from interface.PANI.paniEditor import PANIBuilder
            pani = PANIBuilder(self.history.currentState(),
                               self,
                               settings=self.settings)
            moleculeDialog(self, pani)
        elif self.key == "PEDOT":
            from interface.PEDOT.pedotEditor import PEDOTBuilder
            pedot = PEDOTBuilder(self.history.currentState(),
                                 self,
                                 settings=self.settings)
            moleculeDialog(self, pedot)
        elif self.key == "PSS":
            from interface.PSS.pssEditor import PSSBuilder
            pss = PSSBuilder(self.history.currentState(),
                             self,
                             settings=self.settings)
            moleculeDialog(self, pss)
        elif self.key == "Cellulose":
            from interface.celluloseEditor.CelluloseEditor import CelluloseEditor
            c = CelluloseEditor(self.history.currentState(),
                                self,
                                settings=self.settings)
            moleculeDialog(self, c)
        elif self.key == "ssDNA":
            print("ssDNA is not yet implemented!")
        elif self.parent == "Homopolymer":
            from interface.homopolyEditor.HomopolyEditor import HomopolyEditor
            homopol = HomopolyEditor(self.key,
                                     self.history.currentState(),
                                     settings=self.settings)
            moleculeDialog(self, homopol)

        # Carbon Allotropes
        elif self.key == "swCNT":
            from interface.nanotubeEditor.nanotubeEditor import NanotubeBuilder
            cnt = NanotubeBuilder(self, self.settings)
            moleculeDialog(self, cnt)
        elif self.key == "Graphene":
            from interface.grapheneEditor.grapheneEditor import GrapheneBuilder
            graph = GrapheneBuilder(self, self.settings)
            moleculeDialog(self, graph)
        elif self.key == "Diamond":
            from interface.diamondEditor.diamondEditor import DiamondBuilder
            diamond = DiamondBuilder(self, self.settings)
            moleculeDialog(self, diamond)

        # Solvents
        elif self.key == "THF":
            from lib.chemicalGraph.molecule.solvent.THF import THF
            self.addMolecule(THF())
        elif self.key == "DMF":
            from lib.chemicalGraph.molecule.solvent.DMF import DMF
            self.addMolecule(DMF())
        elif self.key == "Water":
            from lib.chemicalGraph.molecule.solvent.WATER import WATER
            self.addMolecule(WATER())
        elif self.key == "Chloroform":
            from lib.chemicalGraph.molecule.solvent.CLF import CLF
            self.addMolecule(CLF())
        elif self.key == "Chloroform (4 atoms)":
            from lib.chemicalGraph.molecule.solvent.CLF4 import CLF4
            self.addMolecule(CLF4())
        elif self.key == "Hydrogen Peroxide":
            from lib.chemicalGraph.molecule.solvent.H2O2 import H2O2
            self.addMolecule(H2O2())
        elif self.key == "Xylene":
            from lib.chemicalGraph.molecule.solvent.Xylene import Xylene
            self.addMolecule(Xylene())
        elif self.key == "AcetoneAllH":
            from lib.chemicalGraph.molecule.solvent.AcetoneAllH import AcetoneAllH
            self.addMolecule(AcetoneAllH())
        elif self.key == "AcetoneNoH":
            from lib.chemicalGraph.molecule.solvent.AcetoneNoH import AcetoneNoH
            self.addMolecule(AcetoneNoH())

        # Surfactants
        elif self.key == "SDS":
            from lib.chemicalGraph.molecule.solvent.SDS import SDS
            self.addMixture(SDS())

        elif self.key == "SDBS":
            from lib.chemicalGraph.molecule.solvent.SDBS import SDBS
            self.addMixture(SDBS())

        elif self.key == "PABA-Tetradecane":
            from lib.chemicalGraph.molecule.solvent.PABA import PABA_Tetradecane
            self.addMolecule(PABA_Tetradecane())

        elif self.key == "PABA-Heptane":
            from lib.chemicalGraph.molecule.solvent.PABA import PABA_Heptane
            self.addMolecule(PABA_Heptane())

        elif self.key == "PABA-Pentane":
            from lib.chemicalGraph.molecule.solvent.PABA import PABA_Pentane
            self.addMolecule(PABA_Pentane().changeResidues("PAB"))

        # Ions
        elif self.key == "Na":
            from lib.chemicalGraph.molecule.solvent.Na import Na
            self.addMolecule(Na())

        else:
            self.addMolecule(
                Element(Element.nameToSymbol(self.key.split(' ')[0])))

        self.update()
        self.buildPreview.update()

    def on_addCustomButton_pressed(self):
        from interface.classifier.Load import Load
        self.history.push()
        loader = Load(self)
        loader.show()
        loader.exec_()

        self.addMixture(loader.getMixture())
        self.buildPreview.update()
        self.update()
        self.buildPreview.update()

    def on_copyButton_pressed(self):
        if not self.ui.copyButton.isFlat():
            if (self.wolffia.simRunning):
                message = QtGui.QMessageBox(
                    1, "Warning", "There's a simulation running right now.")
                message.exec_()
            else:
                self.copy()
        if not self.ui.removeButton.isFlat():
            if (self.wolffia.simRunning):
                message = QtGui.QMessageBox(
                    1, "Warning", "There's a simulation running right now.")
                message.exec_()
            else:
                self.copy()

    def on_catalogButton_pressed(self):
        if not self.ui.catalogButton.isFlat():
            selected = self.editor.selectedMolecules()
            #print "SELCTEDDDDDD >>." , selected[0]
            if (self.wolffia.simRunning):
                message = QtGui.QMessageBox(
                    1, "Warning", "There's a simulation running right now.")
                message.exec_()

            elif selected == []:
                QtGui.QMessageBox.warning(self, "Wolffia's warning",
                                          "Please select a molecule.",
                                          QtGui.QMessageBox.Ok)
                return

            else:
                #print "on_catalogButton_pressed",  self.ui.molCatalog.topLevelItemCount()
                customTreeWidget = self.ui.molCatalog.topLevelItem(
                    self.ui.molCatalog.topLevelItemCount() - 1)
                #print "on_catalogButton_pressed childCount", customTreeWidget.childCount ()

                print("SELCTEDDDDDD >>.", selected)
                mixtureToSave = Mixture()
                print("mixtureToSave >>>>", mixtureToSave)
                molName = ""
                print("molName >>>>", molName)
                for mol in selected:
                    print("mol >>>>", mol)
                    mixtureToSave.add(mol.copy(), True)
                    print("mixtureToSave agregados >>>>", mixtureToSave)
                    if molName == "":
                        molName = mol.molname()
                    else:
                        molName += ("-" + mol.molname())

                print("SELECETEDDDD: ", selected, "mixtureToSave Final",
                      mixtureToSave)
                print(
                    "############################################################"
                )
                #Pregunta el nombre de la molecula que quiere guardar en el catalogo
                nameMolGUI = QtGui.QInputDialog(self)
                nameMolGUI.setTextValue(str(selected[0]))

                nameMol, ok = nameMolGUI.getText(self, "Custom Molecule",
                                                 "Set Molecule Name:", 0,
                                                 str(selected[0]))

                print("value ", nameMol, " ok ", ok)
                if ok:
                    #Guarda archivo en .cMolecule dentro de .wolffia
                    cMixFileName = "/" + nameMol + ".wfm"
                    cMixFileDir = WOLFFIA_DIR + C_MOLECULE_CATALOG + cMixFileName
                    if os.path.exists(cMixFileDir):
                        print("archivo existe", cMixFileDir)
                        nameMol = nameMol + "*"
                        cMixFileName = "/" + nameMol + ".wfm"
                        cMixFileDir = WOLFFIA_DIR + C_MOLECULE_CATALOG + cMixFileName

                    print("cMixFileDir>>>>>", cMixFileDir)
                    #Add a child to Custom Molecule in the Molecular Structure Catalog
                    nameQT = QtGui.QTreeWidgetItem()
                    nameQT.setText(0, nameMol)
                    customTreeWidget.addChild(nameQT)
                    #customTreeWidget.addChild(QtGui.QTreeWidgetItem())
                    print("NAMEMOL1", nameMol)
                    self.history.currentState().getMixture().save(cMixFileDir)

                #Guarda archivo en .cMolecule dentro de .wolffia
                #MixtureToSave are selected
                #cMixtureToSave = Mixture("To save")
                #Nombre del Archivo que se va a guardar es cMolName
                #cMolName = str(nombre.textValue()) + ".wfm"
                #for mol in selected:
                #   print "mol:", mol
                #	cMixtureToSave.add(mol.copy(), False)

                #Directorio en donde se va a guardar es dirCmolName
                #dirCmolName = self.settings.workingFolder + self.cMol

                #try:
                #	print "TRYYYYYYYYYYYYyyyyy"
                #	basename = str(dirCmolName.path() +  "/" + cMolName)
                #	print "basename" , basename
                #	mixtureToSave.writePDB(basename)

                #except:
                #	QtGui.QMessageBox.warning(self, "Wolffia's warning", cMolName + " could not be saved.", QtGui.QMessageBox.Ok)

                #print "cmolName >>>>>>>>>",cMolName, "directorio: >>>>>>", dirCmolName
                #selected.writePDB(cMolName)
                #print "SAVEEEEEEEEEEEEEEEEEEEEEEEEEEEEEE "
                #print ""

    def on_catalogButton_pressed(self):
        if not self.ui.removeButton.isFlat():
            if (self.wolffia.simRunning):
                message = QtGui.QMessageBox(
                    1, "Warning", "There's a simulation running right now.")
                message.exec_()
            else:
                print("on_catalogButton_pressed",
                      self.ui.molCatalog.topLevelItemCount())
                customTreeWidget = self.ui.molCatalog.topLevelItem(
                    self.ui.molCatalog.topLevelItemCount() - 1)
                print("on_catalogButton_pressed childCount",
                      customTreeWidget.childCount())
                selected = self.editor.selectedMolecules()
                nombre = QtGui.QInputDialog(self)
                nombre.setTextValue(str(selected[0]))
                nombre.exec_()
                customTreeWidget.addChild(
                    QtGui.QTreeWidgetItem([str(nombre.textValue())]))

    def on_duplicateButton_pressed(self):
        if not self.ui.duplicateButton.isFlat():
            if (self.wolffia.simRunning):
                message = QtGui.QMessageBox(
                    1, "Warning", "There's a simulation running right now.")
                message.exec_()
            else:
                self.history.push()
                self.duplicate()
                self.buildPreview.update()

    def on_removeButton_pressed(self):
        #print "on_removeButton_pressed"
        if not self.ui.removeButton.isFlat():
            if (self.wolffia.simRunning):
                message = QtGui.QMessageBox(
                    1, "Warning", "There's a simulation running right now.")
                message.exec_()
            else:
                progress = QtGui.QProgressDialog(
                    "Removing...", QtCore.QString(), 0, 5, self,
                    QtCore.Qt.Dialog | QtCore.Qt.WindowTitleHint)
                progress.setWindowModality(QtCore.Qt.WindowModal)

                progress.setValue(1)
                self.history.push()
                progress.setValue(2)
                self.remove()
                progress.setValue(3)
                self.editor.reset()
                progress.setValue(4)
                self.buildPreview.update()
                #self.buildPreview.setMixture(self.history.currentState().getMixture())
                progress.setValue(5)
                progress.hide()

    #-------------------------------------------------------------------------------
    def on_saveWFMbutton_pressed(self, saveState=True):
        #print "on_saveWFMbutton_pressed "
        if not saveState: return

        else:
            mixFile = self.settings.currentMixtureLocation(
            ) + self.history.currentState().getMixtureName() + ".wfm"
            d = WFileNameDialog(self, 'Save current Mixture',
                                self.settings.currentMixtureLocation(),
                                "Mixture file (*.wfm)")
            if d.isReady():
                filename = d.fullFilename()
                #print "FILENAME = ", filename
                #print "on_saveWFMbutton_pressed >>>>> ","\'"+filename[-4:]+"\'"
                if filename[-4:] != ".wfm" and QtGui.QMessageBox.question(
                        self, "Wolffia's message",
                        "File does not end with .wfm. Add extension?", "Yes",
                        "No") == 0:
                    filename += ".wfm"
                    if os.path.exists(filename) and QtGui.QMessageBox.question(
                            self, "Wolffia's message", "File exists.",
                            "Overwrite", "Cancel") != 0:
                        return
                self.history.currentState().getMixture().save(filename)

                QtGui.QMessageBox.information(self, "Wolffia's message",
                                              filename + " saved.",
                                              QtGui.QMessageBox.Ok)

    def on_saveButton_pressed2(self, saveFiles=True):
        if not saveFiles: return
        mixName = self.history.currentState().getMixtureName()
        d = WDirectoryDialog(
            self, 'Specify directory to save ' + mixName + ".pdb and " +
            mixName + ".psf", self.settings.workingFolder)

        if d.accepted():
            basename = d.path() + "/" + mixName
            import os
            if not (os.path.exists(basename + ".pdb") or os.path.exists(
                    basename + ".psf")) or QtGui.QMessageBox.question(
                        self, "Wolffia's message", "File exists.", "Overwrite",
                        "Cancel") == 0:
                mix = self.history.currentState().getMixture()
                mix.writePDB(basename + ".pdb")
                mix.writePSF(basename + ".psf")

                QtGui.QMessageBox.information(
                    self, "Wolffia's message",
                    mixName + ".pdb and " + mixName + ".psf saved.",
                    QtGui.QMessageBox.Ok)

    def on_saveButton_pressed3(self, saveFiles=True):
        if not saveFiles: return
        selected = self.editor.selectedMolecules()
        #print "on_saveButton_pressed ", selected
        if selected == []:
            QtGui.QMessageBox.warning(
                self, "Wolffia's warning",
                "Could not determine the molecule to be saved.\nPlease select one.",
                QtGui.QMessageBox.Ok)
            return

        mixtureToSave = Mixture("To save")
        molName = ""
        for mol in selected:
            mixtureToSave.add(mol.copy(), False)
            if molName == "":
                molName = mol.molname()
            else:
                molName += ("-" + mol.molname())

        d = WDirectoryDialog(
            self, 'Specify directory to save ' + molName + ".pdb and " +
            molName + ".psf", self.settings.workingFolder)

        try:
            if d.accepted():
                basename = str(d.path() + "/" + molName)
                #import os
                if not (os.path.exists(basename + ".pdb") or os.path.exists(
                        basename + ".psf")) or QtGui.QMessageBox.question(
                            self, "Wolffia's message", "File exists.",
                            "Overwrite", "Cancel") == 0:
                    #mix = self.history.currentState().getMixture()
                    #print "on_saveButton_pressed ", basename
                    mixtureToSave.writePDB(basename + ".pdb")
                    mixtureToSave.writePSF(basename + ".psf")

                    QtGui.QMessageBox.information(
                        self, "Wolffia's message",
                        molName + ".pdb and " + molName + ".psf saved.",
                        QtGui.QMessageBox.Ok)
        except:
            QtGui.QMessageBox.warning(
                self, "Wolffia's warning",
                molName + ".pdb and " + molName + ".psf could not be saved.",
                QtGui.QMessageBox.Ok)

    #------------------------------------------------------------------------------------------

    def on_updateButton_pressed(self):
        #print "on_updateButton_pressed "

        QtGui.QMessageBox.information(
            self, "Wolffia's message",
            "Updates can only be done from coordinate files\nproduced by simulations prepared with Wolffia.\nOther files will produce unexpected results..",
            QtGui.QMessageBox.Ok)

        d = WFileDialog(self,
                        'Specify coordinate file to load.',
                        self.settings.workingFolder,
                        filter="*.pdb *.coor")

        if d.accepted():
            self.history.push()
            try:
                self.history.currentState().mixture.updateCoordinates(
                    str(d.fullFilename()))

                self.buildPreview.update()
                QtGui.QMessageBox.information(self, "Wolffia's message",
                                              "Coordinates updated.",
                                              QtGui.QMessageBox.Ok)
            except:
                QtGui.QMessageBox.warning(self, "Wolffia's warning",
                                          "Coordinates could not be updated.",
                                          QtGui.QMessageBox.Ok)
                self.history.back()

    def on_structManager_itemChanged(self, wi):
        #if isinstance(wi, myTableWidgetItem) and wi.name != "(no name)" and wi.isSelected():
        if wi.column() == 2:
            row = wi.row()
            mol = str(self.ui.structManager.item(row, 4).text())

            if str(wi.text()) == "":
                wi.setText(
                    self.history.currentState().getMixture().getMolecule(
                        mol).molname())
            elif mol[:8] == "SOLVENT(":
                if wi.text() != self.history.currentState().getMixture(
                ).getMolecule(mol).molname():
                    nameLen = len(mol)
                    sepPos = mol.rfind("_")
                    for molecule in self.history.currentState().getMixture():
                        if mol[:sepPos] == molecule[:sepPos]:
                            with warnings.catch_warnings(record=True) as w:
                                #print "on_structManager_itemChanged",molecule,str(wi.text()),str(wi.text())+molecule[sepPos:]
                                self.history.currentState().getMixture(
                                ).renameMolecule(molecule, str(wi.text()))
                            if len(w) > 0:
                                QtGui.QMessageBox.information(
                                    self, "Error", str(w[-1].message))
                    self.update()

            else:
                #print "on_structManager_itemChanged changing molecule with id ", mol
                #print "on_structManager_itemChanged", self.history.currentState().getMixture().getMolecule(mol).molname(), "->", str(wi.text()), " row=", row
                if wi.text() != self.history.currentState().getMixture(
                ).getMolecule(mol).molname():
                    self.history.push()
                    with warnings.catch_warnings(record=True) as w:
                        self.history.currentState().getMixture(
                        ).renameMolecule(mol, str(wi.text()))
                    if len(w) > 0:
                        QtGui.QMessageBox.information(self, "Error",
                                                      str(w[-1].message))
                    self.update()

                    #self.history.currentState().getMixture().getMolecule(mol).rename(str(wi.text()))
                    #print "on_structManager_itemChanged getMixture:",self.history.currentState().getMixture()

    def on_structManager_cellClicked(self, row, col):
        #update editor with selected molecule
        #print "on_structManager_cellClicked",row,col

        molecules = self.history.currentState().getMixture().moleculeIDs()
        molecules.sort()

        #mol = molecules[row]
        mol = str(self.ui.structManager.item(row, 4).text())
        #print "on_structManager_cellClicked",row,col,mol
        if col == 0:
            item = self.ui.structManager.itemAt(row, col)
            #print "detecto"
        elif col == 2:
            #print "on_structManager_cellClicked B"
            #selected = self.editor.setMolecule(self.history.currentState().getMixture().getMolecule(mol), str(mol), True)
            m = self.history.currentState().getMixture().getMolecule(mol)
            #print "on_structManager_cellClicked B2",m,mol
            selected = self.editor.setMolecule(m, str(mol), True)
            #print "on_structManager_cellClicked C", selected

            # if shift key is pressed perform multiple selects
            modifiers = QtGui.QApplication.keyboardModifiers()
            if modifiers == QtCore.Qt.ShiftModifier and self.prevSelection != None:
                if self.prevSelection[1] == selected:
                    if row < self.prevSelection[0]:
                        ind = list(range(row + 1, self.prevSelection[0]))
                    else:
                        ind = list(range(self.prevSelection[0] + 1, row))
                    for i in ind:
                        mol = str(self.ui.structManager.item(i, 4).text())
                        m = self.history.currentState().getMixture(
                        ).getMolecule(mol)
                        if self.prevSelection[1]:
                            self.editor.removeSelection(m, str(mol))
                        else:
                            self.editor.setMolecule(m,
                                                    str(mol),
                                                    removeIfPresent=False)

            self.prevSelection = [row, selected]
            self.ui.removeButton.setFlat(False)
            self.ui.duplicateButton.setFlat(self.clipboard == None
                                            or len(self.clipboard) == 0)
            self.ui.copyButton.setFlat(False)
            self.ui.catalogButton.setFlat(False)

            self.repaint()
            self.buildPreview.update()
            #print "on_structManager_cellClicked D"

        #self.update()
        #self.buildPreview.update()
        return

    @QtCore.pyqtSlot()
    def on_saveButton_triggered(self, saveFiles=True):
        if not saveFiles: return
        d = WFileNameDialog(self, 'Save Files',
                            self.history.currentState().getBuildDirectory())
        if d.isReady():
            self.history.currentState().setMixtureName(d.mixname())
            self.history.currentState().writeFiles(d.fullFilename())
            mesg = self.history.currentState().getMixtureName(
            ) + '.pdb, ' + self.history.currentState().getMixtureName(
            ) + '.psf and ' + self.history.currentState().getMixtureName(
            ) + '.prm'
            info = QtGui.QErrorMessage(self)
            info.setModal(True)  # blocks Wolffia
            info.showMessage("The files " + mesg +
                             " have been successfully saved in " + d.path())

    def on_showCheckbox(self, on):
        print("on_showCheckbox", end=' ')

    def addMolecule(self, mol, remember=True):
        if mol != None:
            self.editor.reset()
            with warnings.catch_warnings(record=True) as w:
                self.history.currentState().addMolecule(mol)
                self.buildPreview.setMixture(
                    self.history.currentState().getMixture(), True)
                #print "addMolecule len(w)",len(w)
                if len(w) > 0:
                    QtGui.QMessageBox.information(self, "Error",
                                                  str(w[-1].message))
            if remember: self.history.push()

    def addMixture(self, mix, remember=True):
        if mix != None:
            for mol in mix:
                self.addMolecule(mix.getMolecule(mol), False)
                #self.history.currentState().addMixture(mix)
            if remember: self.history.push()

    def chosenMolecules(self):
        count = self.ui.structManager.topLevelItemCount()
        for i in range(count):
            item = self.ui.structManager.itemAt(i, 1)
            #print item.isChecked()

    def copy(self):
        selected = self.editor.selectedMolecules()
        #print "copy ", selected
        if selected == []:
            errorgui = QtGui.QErrorMessage(self)
            errorgui.setModal(True)  # blocks Wolffia
            errorgui.showMessage("Error: no molecule chosen.")
        else:
            self.clipboard = Mixture("Clipboard")
            for mol in selected:
                #print "copy", mol
                #self.clipboard.add(self.history.currentState().getMixture().getMolecule(molname).copy(), False)
                self.clipboard.add(mol.copy(), False)
        #print "copy update<", self.editor.selected()
        self.update()
        #print "copy >", self.editor.selected()

    def duplicate(self):
        from sets import Set
        #print "duplicate ", self.clipboard.molecules()
        currentIDs = Set(self.history.currentState().getMixture().molecules())
        try:
            newMols = self.clipboard.copy()
            newMols.moveBy([
                random.uniform(0., 0.1),
                random.uniform(0., 0.1),
                random.uniform(0., 0.1)
            ])
            self.history.currentState().getMixture().merge(newMols)
        except:
            errorgui = QtGui.QErrorMessage(self)
            errorgui.setModal(True)  # blocks Wolffia
            errorgui.showMessage("Error: could not duplicate molecules.")

        # select pasted molecules
        newMols = Set(
            self.history.currentState().getMixture().molecules()) - currentIDs

        progressMax = len(newMols) - 1
        progressCount = 0
        progress = QtGui.QProgressDialog(
            "Adding...", QtCore.QString(), 0, progressMax, self,
            QtCore.Qt.Dialog | QtCore.Qt.WindowTitleHint)
        progress.setWindowModality(QtCore.Qt.WindowModal)

        #print "duplicate ", self.history.currentState().getMixture().molecules(),newMols
        self.editor.reset()
        for mol in newMols:
            self.editor.setMolecule(
                self.history.currentState().getMixture().getMolecule(mol), mol)
            self.history.currentState().shownMolecules.show(mol)
            progressCount += 1
            progress.setValue(progressCount)
        self.insertAllToManager()
        progress.hide()

        self.update()

    def insertAllToManager(self):
        from lib.chemicalGraph.molecule.solvent.Solvent import Solvent
        start = time.clock()
        #print "insertAllToManager ",self.history.currentState().getMixture().molecules()

        self.mixModification = self.history.currentState().getMixture(
        ).getModificationTime()
        #self.ui.structManager.setRowCount(len(self.history.currentState().mixture))
        self.ui.structManager.setRowCount(0)
        row = 0
        solventShown = ShownSolvent()
        shownMolecules = self.history.currentState().shownMolecules
        molecules = self.history.currentState().getMixture().moleculeIDs()
        #print "insertAllToManager ",molecules

        #progress	  = QtGui.QProgressDialog("Storing...", "Abort", 0, len(molecules), self,QtCore.Qt.Dialog|QtCore.Qt.WindowTitleHint)
        #progress.setWindowModality(QtCore.Qt.WindowModal)
        #progress.setAutoClose(True)
        #progress.setMinimumDuration(0)

        self.ui.structManager.blockSignals(True)
        molecules.sort()
        molNum = 0
        for molName in molecules:
            #molName = self.history.currentState().getMixture().getMolecule(mol).molname()
            #print "insertAllToManager ",ShownSolvent.isSolvent(molName),solventShown.isShown(molName)
            if not ShownSolvent.isSolvent(molName) or not solventShown.isShown(
                    molName):
                self.ui.structManager.setRowCount(row + 1)
                #insert checkbox on column 1

                checkBox = PreviewButton(self.history.currentState(),
                                         self.buildPreview,
                                         molname=str(molName),
                                         parent=self,
                                         initState=shownMolecules.isShown(
                                             str(molName)),
                                         editor=self.editor)
                checkBox.setToolTip("Show or hide.")
                self.ui.structManager.setCellWidget(row, 0, checkBox)

                pin = FixedButton(self.history.currentState(),
                                  self.buildPreview,
                                  molname=str(molName),
                                  parent=self,
                                  initState=self.history.currentState().
                                  fixedMolecules.isFixed(str(molName)))
                pin.setToolTip("Fixes position of the molecule.")
                self.ui.structManager.setCellWidget(row, 1, pin)

                #print "insertAllToManager",str(self.history.currentState().mixture.getMolecule(molName)._name) , molecules

                #insert molname on column 2
                baseMolName = str(
                    self.history.currentState().mixture.getMolecule(
                        molName).molname())
                #print "insertAllToManager  creando item para ", baseMolName

                #if isinstance(self.history.currentState().mixture.getMolecule(molName), Solvent):
                #	baseMolName += "(solvent)"
                newitem = QtGui.QTableWidgetItem(baseMolName)
                newitem.setFlags(QtCore.Qt.ItemIsEditable
                                 | QtCore.Qt.ItemIsEnabled)
                newitem.setToolTip(
                    "Click to select or double click to edit the name.")
                self.ui.structManager.setItem(row, 2, newitem)

                #print "insertAllToManager",self.editor.getId(),molName
                if molName in self.editor.selectedNames():
                    newitem.setBackgroundColor(QtCore.Qt.green)

                #insert atom count on column 3
                newitem = QtGui.QTableWidgetItem(
                    str(self.history.currentState().mixture.getMolecule(
                        molName).order()))
                newitem.setFlags(QtCore.Qt.ItemIsEnabled)
                self.ui.structManager.setItem(row, 3, newitem)

                #insert id on column 4
                newitem = QtGui.QTableWidgetItem(str(molName))
                newitem.setFlags(QtCore.Qt.ItemIsEnabled)
                self.ui.structManager.setItem(row, 4, newitem)

                row += 1
                solventShown.setAsShown(molName)
                #print "insertAllToManager solventShown.setAsShown(molName) ", solventShown.isShown(molName)
            elif not ShownSolvent.isSolvent(molName):
                self.history.currentState().shownMolecules.show(molName)

            molNum += 1
            #progress.setValue(molNum)

        #self.buildPreview.setMixture(self.history.currentState().getMixture())
        #self.chosenMolecules()

        self.ui.structManager.blockSignals(False)
        self.ui.removeButton.setFlat(len(self.editor) == 0)
        #self.ui.duplicateButton.setFlat(self.editor.ident == None)
        self.ui.copyButton.setFlat(len(self.editor) == 0)
        self.ui.catalogButton.setFlat(len(self.editor) == 0)
        self.ui.duplicateButton.setFlat(self.clipboard == None
                                        or len(self.clipboard) == 0)

        #self.ui.removeButton.setFlat(molNum == 0)
        #self.ui.duplicateButton.setFlat(molNum == 0)

        #progress.hide()
        stop = time.clock()
        #print "insertAllToManager time",stop-start

    def showEvent(self, e):
        #print "buildTab showEvent"
        #start = time.clock()
        #if self.firstUpdate:
        #	self.update()
        #	self.firstUpdate = False

        self.update()
        super(BuildTab, self).showEvent(e)
        #print "buildTab showEvent time",time.clock()-start

    def remove(self):
        #print "remove"
        self.copy()
        selected = self.editor.selectedNames()
        #print "BuildTab.remove ", selected

        try:
            self.history.currentState().removeMoleculesFrom(selected)
            '''
			for molname in selected:
				self.history.currentState().removeMolecule(molname)
			'''

            #print "BuildTab.remove ", selected, " removed "
        except:
            #errorgui = QtGui.QErrorMessage(self)
            #errorgui.setModal(True) # blocks Wolffia
            #errorgui.showMessage("Error: could not delete molecule "
            #	+ molname + "." )
            logging.getLogger(self.__class__.__name__).warning(
                "Could not delete molecules " + selected + ".")
        self.editor.reset()
        self.update()

    def repaint(self):
        selected = self.editor.selectedNames()
        for row in range(self.ui.structManager.rowCount()):
            #print "repaint ", self.ui.structManager.item(row,4).text()
            if self.ui.structManager.item(row, 4).text() in selected:
                self.ui.structManager.item(row, 2).setBackgroundColor(
                    QtCore.Qt.green)
            else:
                self.ui.structManager.item(row, 2).setBackgroundColor(
                    QtCore.Qt.white)

    def reset(self):
        #print "buildTab reset in"
        self.buildPreview.reset()
        self.editor.reset()
        self.prevSelection = None
        self.prevShow = None
        self.prevFixed = None
        #print "buildTab reset out"

    def update(self):
        #start = time.clock()

        #print "updating buldTab, mixture=", self.history.currentState().getMixture()
        self.insertAllToManager()
        #print "buildTab update insertAllToManager",time.clock()-start
        #self.buildPreview.setMixture(self.history.currentState().getMixture())
        self.mixModification = time.clock()

        self.ui.structManager.resizeColumnToContents(0)
        self.ui.structManager.resizeColumnToContents(1)
        self.ui.structManager.resizeColumnToContents(2)
        self.ui.structManager.resizeColumnToContents(3)

        self.editor.update()
        #self.buildPreview.update()
        #self.wolffia.update()
        #print "buildTab update time",time.clock()-start
        self.repaint()

    '''
Exemple #7
0
    def on_catalogButton_pressed(self):
        if not self.ui.catalogButton.isFlat():
            selected = self.editor.selectedMolecules()
            #print "SELCTEDDDDDD >>." , selected[0]
            if (self.wolffia.simRunning):
                message = QtGui.QMessageBox(
                    1, "Warning", "There's a simulation running right now.")
                message.exec_()

            elif selected == []:
                QtGui.QMessageBox.warning(self, "Wolffia's warning",
                                          "Please select a molecule.",
                                          QtGui.QMessageBox.Ok)
                return

            else:
                #print "on_catalogButton_pressed",  self.ui.molCatalog.topLevelItemCount()
                customTreeWidget = self.ui.molCatalog.topLevelItem(
                    self.ui.molCatalog.topLevelItemCount() - 1)
                #print "on_catalogButton_pressed childCount", customTreeWidget.childCount ()

                print("SELCTEDDDDDD >>.", selected)
                mixtureToSave = Mixture()
                print("mixtureToSave >>>>", mixtureToSave)
                molName = ""
                print("molName >>>>", molName)
                for mol in selected:
                    print("mol >>>>", mol)
                    mixtureToSave.add(mol.copy(), True)
                    print("mixtureToSave agregados >>>>", mixtureToSave)
                    if molName == "":
                        molName = mol.molname()
                    else:
                        molName += ("-" + mol.molname())

                print("SELECETEDDDD: ", selected, "mixtureToSave Final",
                      mixtureToSave)
                print(
                    "############################################################"
                )
                #Pregunta el nombre de la molecula que quiere guardar en el catalogo
                nameMolGUI = QtGui.QInputDialog(self)
                nameMolGUI.setTextValue(str(selected[0]))

                nameMol, ok = nameMolGUI.getText(self, "Custom Molecule",
                                                 "Set Molecule Name:", 0,
                                                 str(selected[0]))

                print("value ", nameMol, " ok ", ok)
                if ok:
                    #Guarda archivo en .cMolecule dentro de .wolffia
                    cMixFileName = "/" + nameMol + ".wfm"
                    cMixFileDir = WOLFFIA_DIR + C_MOLECULE_CATALOG + cMixFileName
                    if os.path.exists(cMixFileDir):
                        print("archivo existe", cMixFileDir)
                        nameMol = nameMol + "*"
                        cMixFileName = "/" + nameMol + ".wfm"
                        cMixFileDir = WOLFFIA_DIR + C_MOLECULE_CATALOG + cMixFileName

                    print("cMixFileDir>>>>>", cMixFileDir)
                    #Add a child to Custom Molecule in the Molecular Structure Catalog
                    nameQT = QtGui.QTreeWidgetItem()
                    nameQT.setText(0, nameMol)
                    customTreeWidget.addChild(nameQT)
                    #customTreeWidget.addChild(QtGui.QTreeWidgetItem())
                    print("NAMEMOL1", nameMol)
                    self.history.currentState().getMixture().save(cMixFileDir)
Exemple #8
0
class HomopolyEditor(QtGui.QDialog):
    # Class Fields:
    # ui: stores reference tu user interface
    # files: [string, string], PDF and PSF filenames
    # homopol: Mixture, an Homopolymer
    # homopolPreview: MixtureViewer

    DISPL = {"PMMA": [3.7, 0], "PolyCYT": [6.0, 1]}

    def __init__(self, key, appState, parent=None):
        super(HomopolyEditor, self).__init__(parent, modal=1)

        self.ui = Ui_HomopolyEditor()
        self.ui.setupUi(self)

        self.state = appState
        self.type = key
        #self.slideFactor = 50
        #self.files 	= None

        self.homopolPreview = MixtureViewer()
        self.ui.viewerLayout.addWidget(self.homopolPreview)

        self.ui.lengthDSpinner.setValue(self.DISPL[self.type][0])
        self.ui.lengthDSpinner.setSingleStep(self.DISPL[self.type][0])
        self.ui.lengthDSpinner.setMinimum(self.DISPL[self.type][0])
        self.ui.lengthSlider.setValue(self.DISPL[self.type][0])
        self.ui.lengthSlider.setTickInterval(self.DISPL[self.type][0])
        self.ui.lengthSlider.setMinimum(self.DISPL[self.type][0])
        self.ui.stackedWidget.setCurrentIndex(self.DISPL[self.type][1])

        self.generateHomopol()
        self.generateHomopol()

        if __name__ != '__main__':
            self.ui.saveButton.setHidden(True)

    def generateHomopol(self):
        self.ui.headerLabel.setText(str(self.type) + " Editor")
        n = self.ui.nSpinBox.value()
        self.homopol = Mixture()
        exec("from chemicalGraph.molecule.polymer." + str(self.type) +
             " import " + str(self.type))
        self.homopol.add(eval(str(self.type) + "(n)"))
        self.homopolPreview.setMixture(self.homopol)

    # Manages signals
    def on_nSpinBox_valueChanged(self, value):
        self.generateHomopol()
        length = self.DISPL[self.type][0] * value
        self.ui.lengthDSpinner.setValue(length)
        self.ui.lengthSlider.setValue(length)

    def on_lengthDSpinner_valueChanged(self, value):
        n = int(math.floor(value / self.DISPL[self.type][0]))
        self.ui.nSpinBox.setValue(n)
        self.generateHomopol()
        #self.ui.lengthSlider.setValue(value)

    def on_lengthSlider_sliderMoved(self, value):
        n = int(math.floor(value / self.DISPL[self.type][0]))
        self.ui.nSpinBox.setValue(n)
        self.generateHomopol()
        self.ui.lengthDSpinner.setValue(value)

    def on_okButton_pressed(self):
        self.generateHomopol()
        self.state.addMixture(self.homopol)
        self.close()

    '''
	def on_saveButton_pressed(self):
		from NanotubeSaveDialog import NanotubeSaveDialog

		# generate tube
		self.generateTubes()

		ntDialog = NanotubeSaveDialog(self.tubes,files=self.files, parent=self)
		ntDialog.show()
		ntDialog.exec_()
		self.files = ntDialog.getFileNames()
		print self.files 
	'''

    def on_cancelButton_pressed(self):
        self.close()
Exemple #9
0
class CoordinateFile:
	def __init__(self, mixtureFile, fileType=None, psfFile=None, mixtureName=None):
		'''
		Prepares file for reading molecules.
		
		Raises MixtureError or whichever exception that pybel raises.
		'''
		if fileType == None:
			fileType = os.path.splitext(mixtureFile)[1][1:].strip()  # get filename extension
		if mixtureName == None:
			mixtureName = os.path.basename(mixtureFile)
			
		self.fileType = fileType
		self.fileName = mixtureFile
		self.mixtureName = mixtureName
		print("CoordinateFile ", fileType)

		if psfFile == None: self.psf = None
		else: self.psf = PSF(psfFile)
		
		self.__iter__()
		
	def __iter__(self):
		if self.fileType == "cc1":
			from . import cc1
			self.molIterator = cc1.readfile(self.fileName)
		else:
			self.molIterator = pybel.readfile(self.fileType, self.fileName)
		self.currentMolecule = None 
		self.firstMolecule = True
		return self


	def _processFirstFrame(self):
		"""
		Gets the first pybel Molecule and puts its Wolffia equivalent Mixture in self.currentMolecule.
		Returns the first frame.
		Raises whichever exception that pybel throws (probably StopIteration).
		"""
		
		mol = next(self.molIterator)
		chemicalGraphMixed = ChemicalGraph()
		etable			 = openbabel.OBElementTable()

		
		n = 0
		for atom in mol.atoms:
			atomType = atom.OBAtom.GetResidue().GetAtomID(atom.OBAtom)
			symbol = etable.GetSymbol(atom.atomicnum)
			coords = list(atom.coords)
			name	 = etable.GetName(atom.atomicnum) 
			residue = atom.OBAtom.GetResidue().GetName()
			psfType = atom.OBAtom.GetResidue().GetAtomID(atom.OBAtom).strip()
			#print "_processFirstFrame: '" + psfType + "'"
			charge = atom.partialcharge
			mass	 = atom.atomicmass	
			if self.psf != None:
				psfType = self.psf.getType(n)
				charge = self.psf.getCharge(n)
				mass	 = self.psf.getMass(n)
				print("CoordinateFile _processFirstFrame charge  ", charge)
		
		
			ai  = AtomInfo(atomType, symbol, psfType, charge, mass, 1, 1, 1, name, residue)
			atr = AtomAttributes(ai, coords, [])
			chemicalGraphMixed.add_node(n + 1, attrs=[atr])
			n += 1
		
		# add edges
		print('_processFirstFrame add edges')
		if self.psf != None:
			for b in self.psf.bonds:
				try:  # avoids adding an edge twice
					chemicalGraphMixed.add_edge(b)
				except AdditionError:
					pass			
			if len(mol.atoms) != len(self.psf.atoms):
				raise MixtureError("Amount of atoms in " + self.fileName + " and psf File files are different (" + str(len(self.atoms)) + " vs " + str(len(self.psf.atoms)) + ").")
		else:			
			for bond in openbabel.OBMolBondIter(mol.OBMol):   
				chemicalGraphMixed.add_edge([bond.GetBeginAtom().GetIdx(), bond.GetEndAtom().GetIdx()])	   
					
		molecules = list(chemicalGraphMixed.connectedComponents())
		self.currentMolecule = Mixture()
		
		#print '_processFirstFrame Añadir'+  str(list(molecules)) + ' moléculas a mezcla:  ', 
		if len(molecules) == 1:
			self.currentMolecule.add(Molecule(self.mixtureName, molecule=molecules[0]))
		else:
			n = 0
			for m in molecules:
				self.currentMolecule.add(
							Molecule(self.mixtureName + "(" + str(n) + ")", molecule=m),
							checkForInconsistentNames=False)
				n += 1

		return self.currentMolecule
	
	
	def _processNextFrame(self):
		"""
		Gets next pybel Molecule and puts its Wolffia equivalent Mixture in self.currentMolecule.
		Returns the next frame.
		Assumes that _processFirstFrame() has been called earlier.
		Raises whichever exception that pybel throws (probably StopIteration).
		"""
		self.currentMolecule = Mixture(self.currentMolecule)  # copy mixture
		mol = next(self.molIterator)
		print("_processNextFrame", mol)
		coordinates = []
		for atom in mol.atoms:
			coordinates.append(atom.coords)
		self.currentMolecule.updateCoordinatesFromArray(coordinates)
		return self.currentMolecule

		
	def __next__(self):
		"""
		Returns next frame if present.
		Raises whichever exception that pybel throws (probably StopIteration).
		"""
		if self.firstMolecule:
			self.firstMolecule = False
			return self._processFirstFrame()
		else: return self._processNextFrame()
Exemple #10
0
    def __init__(self, m, n, q):

        diamondMix = Mixture()
        diamondMix.loadWFM(WOLFFIA_WFY_DIR + "/diamond.wfm")
        diamondCell = diamondMix.getMolecule('Diamond_1')

        sal = Element("NA")
        sal.moveBy([-1, -1, -1])  # put it out of the way

        #'Crece' el diamante
        tempMixture = Mixture()
        for dm in range(m):
            for dn in range(n):
                for dq in range(q):
                    newCell = diamondCell.copy()
                    newCell.moveby([dm * 5.43, dn * 5.43, dq * 5.43])
                    tempMixture.add(newCell)

        tempMixture.add(sal)

        G = tempMixture.copy()
        H = tempMixture.copy()
        Coord = []
        overlapAtoms = []
        atomNeighbors = []
        toEliminate = []

        #Hace que las moleculas se conecten al atomo de Na y hace de la mezcla una molecula
        for p, mol in enumerate(G):
            molecule = G.getMolecule(mol)
            for idx, atom1 in enumerate(molecule):
                if molecule.getAttributes(
                        atom1).getInfo().getElement() == "NA":
                    molSal = mol
                    numMolecule = p
                    atomSal = molecule.atom(idx)

        for p, mol in enumerate(G):
            molecule = G.getMolecule(mol)
            if p != numMolecule:
                molC = mol
                atomC = molecule.atom(1)
                H.addBond([molSal, atomSal], [molC, atomC])

        #Pone las coordenadas de la mezcla en una lista
        for p, mol in enumerate(H):
            molecule = H.getMolecule(mol)
            for atom in molecule:
                coordinates = molecule.getAttributes(atom).getCoord()
                Coord.append(coordinates)

        #Te da los atomos que estan en la misma posicion
        for a, coord1 in enumerate(Coord):
            #print a,coord1
            for x, coord2 in enumerate(Coord):
                if a < x and math.fabs(
                        coord1[0] - coord2[0]) < TOLERANCE and math.fabs(
                            coord1[1] - coord2[1]) < TOLERANCE and math.fabs(
                                coord1[2] - coord2[2]) < TOLERANCE:
                    overlapAtoms.append(a)
                    overlapAtoms.append(x)
                    toEliminate.append(x)

        #Te dice los vecinos de los atomos
        for mol in H:
            molecule = H.getMolecule(mol)
            for i in range(len(overlapAtoms) / 2):
                vecinos = molecule.neighbors(overlapAtoms[2 * i + 1] + 1)
                #atomNeighbors.append(overlapAtoms[2*i+1]+1)
                atomNeighbors.append(vecinos)

        G = H.copy()

        for p, mol in enumerate(G):
            molecule = G.getMolecule(mol)
            for i, j in enumerate(atomNeighbors):
                #print i, len(j), j[0]

                mol1 = mol
                atom1 = molecule.atom(overlapAtoms[2 * i])
                #print atom1, "atomo 1", i
                if len(j) == 1:
                    atom2 = molecule.atom(j[0] - 1)
                    #print j[0]
                    #print atom2, atom1
                    H.addBond([mol1, atom1], [mol1, atom2])
                elif len(j) == 2:
                    atom2A = molecule.atom(j[0] - 1)
                    atom2B = molecule.atom(j[1] - 1)
                    H.addBond([mol1, atom1], [mol1, atom2A])
                    H.addBond([mol1, atom1], [mol1, atom2B])

        #toEliminate.sort()
        G = H.copy()
        #print "a Eliminarse", toEliminate

        toEliminate = sorted(set(toEliminate))

        #Busca el indice del atomo Na
        for p, mol in enumerate(G):
            molecule = G.getMolecule(mol)
            for idx, atom1 in enumerate(molecule):
                if molecule.getAttributes(
                        atom1).getInfo().getElement() == "NA":
                    idxNa = idx + 1

        #Elimina los atomos 'repetidos' y el atomo de Na
        for p, mol in enumerate(G):
            molecule = G.getMolecule(mol)
            for i in reversed(toEliminate):
                #print i+1
                molecule.removeAtom(i + 1)
            molecule.removeAtom(idxNa)

        Molecule.__init__(self, "Diamond", next(G.moleculeGenerator()))

        # Fix atom types
        for atom in self:
            N = len(self.neighbors(atom))
            if N == 4:
                self.getAtomAttributes(atom).getInfo().setType("C")
            if N == 1:
                self.getAtomAttributes(atom).getInfo().setType("C2")
            if N == 2:
                self.getAtomAttributes(atom).getInfo().setType("C3")

        self.getForceField().setBond(('C', 'C'), 222., NonBond._EPSILON)
        self.getForceField().setBond(('C', 'C'), 1.512, NonBond._SIGMA)
Exemple #11
0
		
	def __init2__(self,n,m,q):
		super(Diamond,self).__init__(ident="Diamond")
		
		allCells = Mixture()
		allCells.loadWFM(WOLFFIA_WFY_DIR + "/diamond.wfm")
		#print allCells.moleculeNames()
		#print allCells.nodes()
		cell = allCells.getMolecule(allCells.nodes()[0])

		for x in range(n):
			for y in range(m):
				line = Molecule()
				for z in range(q):
					newCell = cell.copy()
					newCell.moveBy([x*self._CELL_WIDTH_,y*self._CELL_WIDTH_,z*self._CELL_WIDTH_])
					addAndJoin(line, newCell)
				print "Diamond __init__",x,y
				addAndJoin(self, line)
		#print allCells.enclosingBox()
'''
#==========================================================================
#==========================================================================
if __name__ == '__main__':
    d = Diamond(3, 3, 3)
    print(d.edges())
    d.writePDB("/home/jse/Desktop/Diamantito.pdb")

    m = Mixture()
    m.add(d)
    m.save("/home/jse/Desktop/Diamantito.wfm")
Exemple #12
0
class ShownMoleculesSet(set):
    def __init__(self, mixture):
        print("ShownMoleculesSet,__init__ caller=",
              inspect.stack()[1])  #[3], mixture, type(mixture)
        if isinstance(mixture, list):
            self.mixture = Mixture()
            for m in mixture:
                self.mixture.add(m)
            self.showAll()
        else:
            self.mixture = mixture

    def show(self, mol):
        #print "ShownMolecules show",mol
        self.add(mol)

    def showAll(self, mixture=None):
        if mixture != None: self.addMolecules(mixture)
        for mol in self.mixture:
            self.add(mol)

    def add(self, mol):
        super(ShownMoleculesSet, self).add(self.mixture.getMolecule(mol))

    def hide(self, mol):
        self.discard(mol)

    def remove(self, mol):
        #print "ShownMoleculesSet remove ",mol
        #try:
        if isinstance(mol, Molecule):
            super(ShownMoleculesSet, self).remove(mol)
        else:
            super(ShownMoleculesSet,
                  self).remove(self.mixture.getMolecule(mol))
        #except:
        #pass

    def discard(self, mol):
        super(ShownMoleculesSet, self).discard(self.mixture.getMolecule(mol))

    '''
    def discardFrom(self, molIDSet):
        molset = set([ self.mixture.getMolecule(m) for m in molIDSet])
        super(ShownMoleculesSet, self).difference(set(molSet))
    '''

    def duplicate(self, mol):
        pass

    def __deepcopy__(self, memo):
        '''
        Blocks deepcopy because it takes too long.  Copy done manually in push()
        '''
        pass

    def isShown(self, mol):
        #print "isShown ", mol, mol in self.keys(), self[mol]
        try:
            return self.mixture.getMolecule(mol) in self
        except:
            return False

    def shownList(self, mixture):
        print("WARNING: ShownMoleculesSet deprecated.")
        return list(self)

    def addMolecules(self, mixture):
        for mol in mixture:
            self.add(mol)

    def addDictionary(self, shDict):
        '''
        Adds information from a ShownMolecules object.
        '''
        for mol in shDict:
            if shDict[mol]: self.add(mol)

    def updateMixture(self, mixture):
        self.intersection_update(
            set([self.mixture.getMolecule(mol) for mol in mixture]))
        self.mixture = mixture

    def names(self):
        return [self.mixture.getMoleculeID(molecule) for molecule in self]
Exemple #13
0
class NanoCADState(object):
    def __init__(self, parent=None, filename=None, log=None):
        #import inspect
        #print "NanoCADState.init, caller=",inspect.stack()[1]
        self.parent = parent
        self.log = log
        self.wolffiaVerion = WOLFFIA_VERSION
        self.mixture = Mixture(mixName=WOLFFIA_DEFAULT_MIXTURE_NAME)
        self.workingDir = WOLFFIA_DEFAULT_MIXTURE_LOCATION + "/"
        self.drawer = None
        self.simTabValues = None
        self.minTabValues = None
        self.shownMolecules = None
        self.fixedMolecules = None

        self.reset()
        if not filename == None:
            self.load(filename)
        #print "NanoCADState__init__", self.forceFieldStorage.keys()

    #-------------------------- methods ------------------------------------
    def reset(self):
        #self.forceFieldStorage    =    None
        #self.mixture        =    Mixture(mixName = WOLFFIA_DEFAULT_MIXTURE_NAME)
        self.mixture = Mixture(mixName=self.mixture.getMixtureName())
        self.wolffiaVerion = WOLFFIA_VERSION
        self.simTabValues = None
        self.minTabValues = None

        #self.mixture.setChanged()
        #self.forceFieldStorage = dict()

        #self.buildDir = WOLFFIA_DEFAULT_MIXTURE_LOCATION + "/" + self.mixture.getMixtureName()
        #self.workingDir = os.getcwd()
        self.drawer = Drawer()
        self.shownMolecules = ShownMoleculesSet(self.mixture)
        self.fixedMolecules = FixedMolecules()
        #print "NanoCADState reset"

    #--------------------------------------------------------------------

    def save(self, filename=None, fileObject=None):

        if fileObject != None:
            f = fileObject
            f.seek(0)
            pickle.dump(self.__dict__, f)
        else:
            if filename == None:
                #filename = WOLFFIA_DEFAULT_MIXTURE_LOCATION + "/" + WOLFFIA_DEFAULT_MIXTURE_NAME + ".wfy"
                filename = self.getBuildDirectory(
                ) + "/" + self.getMixtureName() + ".wfy"

            #print "History.save_ importing cPickle"
            #print "History.save_ imported cPickle, starting to save"
            #print "History.save_ self.getBuildDirectory(), self.getMixtureName() ", self.getBuildDirectory(), self.getMixtureName()
            try:
                f = open(filename, "w")
            except IOError:
                print(filename + ": File does not exist.")
            pickle.dump(self.__dict__, f)
            f.close()

        #print "NanoCADState.save, save sucessful", f.name

    #--------------------------------------------------------------------------------
    def writeFiles(self, filename=None):
        from chemicalGraph.io.PRM import PRMError
        if filename == None:
            filename = self.getBuildDirectory() + "/" + self.getMixtureName()
        #print "NanoCADState writeFiles,", filename

        try:
            self.getMixture().writeFiles(filename,
                                         self.fixedMolecules.fixedList())
        except:
            raise

    #--------------------------------------------------------------------------------
    def packFiles(self, mixBaseFilename, filename, progressSignal=None):
        import zipfile

        if progressSignal != None: progressSignal.emit(0)

        self.writeFiles(filename=mixBaseFilename)
        if progressSignal != None: progressSignal.emit(50)

        self.save(
        )  # .wfy  saved because it may have changed w/r to the one when the MixtureBrowser was created

        # .coor, .vel and .conf files preserve configuration of last run

        #print "NanoCADState packFiles ", mixBaseFilename, filename
        file1 = zipfile.ZipFile(filename, "w")
        if progressSignal != None: progressSignal.emit(60)
        #mixBaseFilename = str(self.settings.currentMixtureLocation()) + "/" + self.history.currentState().getMixtureName()
        #mixBaseFilename = str(self.getBuildDirectory()) + "/" + self.getMixtureName()
        #print "packFiles mixname", mixBaseFilename

        #for name in glob.glob(str(self.settings.currentMixtureLocation()) + "/*"):
        #	file1.write(name, os.path.basename(name), zipfile.ZIP_DEFLATED)
        extensionsNotPacked = ""
        extensionsToPack = [
            ".prm", ".pdb", ".psf", ".wfy", ".conf", ".coor", ".vel", ".xsc"
        ]
        progress = 60
        for ext in extensionsToPack:
            #if progress.wasCanceled(): break
            confFilename = mixBaseFilename + ext
            if not os.path.isfile(confFilename):
                #print "packFiles confFilename NotPacked",confFilename
                extensionsNotPacked += " " + ext
            else:
                file1.write(confFilename, os.path.basename(confFilename),
                            zipfile.ZIP_DEFLATED)
            progress += 5
            if progressSignal != None: progressSignal.emit(progress)

        file1.close()
        return extensionsNotPacked

    #--------------------------------------------------------------------
    def load(self, filename=None):
        import pickle as pickle  #Tremenda aportación por carlos cortés
        #import inspect
        #print "NanoCADState.load, caller1=",inspect.stack()[1]
        #print "NanoCADState.load, caller2=",inspect.stack()[2]
        #print "NanoCADState.load, caller3=",inspect.stack()[3]
        if filename == None:
            filename = WOLFFIA_DEFAULT_MIXTURE_LOCATION + "/" + WOLFFIA_DEFAULT_MIXTURE_NAME + ".wfy"

        logger = logging.getLogger(self.__class__.__name__)

        if hasattr(filename, 'read'):  # new in v 1.132
            logger.info("Loading state from " + str(filename.name))
            filename.seek(0)
            self.__dict__ = pickle.load(filename)
            f = filename
        else:
            logger.info("Loading state from " + str(filename))
            if not os.path.exists(filename):
                self.reset()
                self.save(filename)
                return
            #print "History.load_ importing cPickle"
            #print "History.load_ imported cPickle, starting to load"

            try:
                f = open(filename, "r")
                self.__dict__ = pickle.load(f)
                f.close()
            except Exception as e:
                import traceback
                traceback.print_exc()
                #print "NanoCADState.load_ Exeption ", e, " when unpickling file."
                from PyQt5 import QtGui
                gui = QtWidgets.QErrorMessage.qtHandler()
                QtWidgets.QErrorMessage.showMessage(
                    gui, "Error: could not open configuration file " +
                    filename + ".")
                logger.warning("Error: could not open configuration file " +
                               filename + ".")

        if not hasattr(self, "fixedMolecules"):  # introduced in v 0.24
            self.fixedMolecules = FixedMolecules()
        if self.wolffiaVerion < "0.24-4":
            self.simTabValues["pmeGridSp"] = 1.0

        logger.info("Loaded mixture from version " + self.wolffiaVerion +
                    ". Current version is " + WOLFFIA_VERSION)

        if self.wolffiaVerion < "0.24-42":
            #if True:
            #print "YES, mixture=",self.getMixture().molecules()
            for mol in self.getMixture():
                #print "load ", self.getMixture().getMolecule(mol).getForceField()._NONBONDED
                molecule = self.getMixture().getMolecule(mol)
                self.getMixture().getMolecule(mol).copyChargesToForceField()
                self.wolffiaVerion = "0.24-42"
                #print "load ", self.getMixture().getMolecule(mol).getForceField()._NONBONDED
        #else: print "NO"

        if self.wolffiaVerion < "0.24-43":
            temp = ShownMoleculesSet(self.getMixture())
            temp.addDictionary(self.shownMolecules)
            del self.shownMolecules
            self.shownMolecules = temp

        if self.wolffiaVerion < "0.24-44":
            #print "History.load_ fixing self bonds"
            for m in self.mixture:  #remove bonds to self
                molecule = self.mixture.getMolecule(m)
                for atom in molecule:
                    if molecule.has_edge(atom, atom):
                        molecule.remove_edge(atom, atom)

            #print "History.load_  self bonds removed"

        # trick for backward compatibility
        for mol in self.getMixture():
            molecule = self.getMixture().getMolecule(mol)
            #print "load inspecting ",molecule.__class__
            if str(molecule.__class__)[-10:] == "Molecule\'>":
                molecule.__class__ = Molecule
                #print "molecule class changed", molecule.__class__

        if self.wolffiaVerion < "1.13":  # until further versions
            # self.mixture.mixName should be the same as
            # self.parent.settings.currentMixtureName.
            print(
                "History.load_ self.mixture.mixName should be the same as self.parent.settings.currentMixtureName"
            )
            try:
                self.mixture.setMixtureName(
                    self.parent.settings.currentMixtureName)
            except:
                pass

        if self.wolffiaVerion < "1.131":  # fix for 1.13 did not work.
            # self.parent.settings.currentMixtureName is being
            # eliminated in this version.
            print(
                "History.load_ self.mixture.mixName should be the same as self.parent.settings.currentMixtureName"
            )
            try:
                self.parent.settings.setMixtureLocation(
                    self.parent.settings.currentMixtureName)
                del self.parent.settings.currentMixtureName
            except:
                pass

        # other fixes ===========================
        if self.shownMolecules == None:
            self.shownMolecules = ShownMoleculesSet(self.getMixture())
        # end other fixes ===========================

        if self.wolffiaVerion < "1.31":
            self.getMixture().upgrade(self.wolffiaVerion)

        #from PyQt5 import QtGui
        if self.wolffiaVerion < WOLFFIA_VERSION:
            #QtGui.QMessageBox.information(self.parent,"Wolffia", "Simulation version updated from "+str(self.wolffiaVerion)+" to "+str(WOLFFIA_VERSION))
            print("NANOCADState.load: Simulation version updated from " +
                  str(self.wolffiaVerion) + " to " + str(WOLFFIA_VERSION))
        self.wolffiaVerion = WOLFFIA_VERSION
        print("NanoCADState.load_ imported cPickle, load sucessful", f.name)
        #print "History.load self.shownMolecules", self.shownMolecules
        #self.shownMolecules.showAll()

    #--------------------------------------------------------------------
    # If progress != None, it is an object that responds to he folowing methods:
    #   .setLabelText("Removing collisions")
    #   .setRange(0,molNum)
    #   .setValue(0)

    def fillBox(self,
                solv,
                molNum,
                checkCollisions=False,
                replaceCollisions=False,
                applyPCBs=True,
                progress=None):
        import math, random
        import numpy as np
        from lib.chemicalGraph.molecule.solvent.Solvent import Solvent

        solventMolecules = Solvent(solv)  #.__class__)

        remaining = -1  # to track removng collissions

        totalDim = self.getDrawer().getBoxDimension()
        boxmin = self.getDrawer().getCellOrigin()
        boxmax = [
            boxmin[0] + totalDim[0], boxmin[1] + totalDim[1],
            boxmin[2] + totalDim[2]
        ]

        #calculate the volume for a single solvent molecule
        center = [0., 0., 0.]
        pos = solv.massCenter()
        solv.moveBy(
            [center[0] - pos[0], center[1] - pos[1], center[2] - pos[2]])
        #solvDiameter = solv.diameter()+ _SEPARATION_BETWEEN_SOLVENTS_
        solvDiameter = math.pow(self.getDrawer().getBoxVolume() / molNum,
                                1. / 3.)
        if solvDiameter == 0: return

        row = math.floor(totalDim[1] / solvDiameter)
        col = math.floor(totalDim[0] / solvDiameter)
        dep = math.floor(totalDim[2] / solvDiameter)

        progressMax = molNum
        progressCount = 0
        if progress != None:
            progress.setLabelText("Adding solvent")
            progress.setRange(0, molNum - 1)
            progress.setValue(0)

        solvRadius = solvDiameter / 2
        newPos = solv.massCenter()
        refCoor = boxmin

        #boxmax[0] -= solvDiameter/2.
        #boxmax[1] -= solvDiameter/2.
        #boxmax[2] -= solvDiameter/2.

        if progress != None:
            progress.setLabelText("Adding solvent")
            progress.setRange(progressCount, progressMax)
            progress.setValue(progressCount)

        # lopps over a sequence of adding solvent and removing collisions
        originalMolecules = self.getMixture().molecules()
        originalCoords = self.getMixture().getAtomsCoordinatesAsArray()
        solvRadius = solvDiameter / 2.0 + 1.5

        #print "anadiendo... ", progressMax-progressCount
        while progressCount < progressMax:  # adds solvent
            #random rotation for solvent atoms
            rx = random.uniform(0, 360)
            ry = random.uniform(0, 360)
            rz = random.uniform(0, 360)

            #random displacement for solvent atoms
            rdx = random.uniform(boxmin[0], boxmax[0])
            rdy = random.uniform(boxmin[1], boxmax[1])
            rdz = random.uniform(boxmin[2], boxmax[2])

            #generate new molecule and assign next position
            mol = solv.copy()
            mol.rotateDeg(rx, ry, rz)
            newPos = np.array([[rdx, rdy, rdz]])

            if checkCollisions:
                atomDistances = euclidean_distances(originalCoords, newPos)
                if np.min(atomDistances) > solvRadius:
                    #print 'fillBox: añadiendo', progressCount, np.min(atomDistances), newPos
                    mol.moveBy(list(newPos)[0])
                    #nodeName = self.addMolecule(mol, checkForInconsistentNames=False)
                    #self.shownMolecules.show(nodeName)
                    solventMolecules.addCoordinates(mol)
                else:
                    #print 'fillBox: colision'
                    if replaceCollisions: progressCount -= 1

            progressCount += 1
            if progress != None: progress.setValue(progressCount)
            del mol

        # add solvent and rename with the given name
        nodeName = self.addMolecule(solventMolecules,
                                    checkForInconsistentNames=True)
        self.shownMolecules.show(nodeName)
        #print "fillBox ", mol.molname(),progressMax
        solv.rename(solventMolecules.molname())
        progressMax -= 1

        #print "tiempo ", time.clock() - start
        #print "Molecules after cleaning: ",mix.order()

    def fillBoxBAK(self,
                   solv,
                   molNum,
                   checkCollisions=False,
                   replaceCollisions=False,
                   applyPCBs=True,
                   progress=None):
        import math, random
        remaining = -1  # to track removng collissions

        totalDim = self.getDrawer().getBoxDimension()
        boxmin = self.getDrawer().getCellOrigin()
        boxmax = [
            boxmin[0] + totalDim[0], boxmin[1] + totalDim[1],
            boxmin[2] + totalDim[2]
        ]

        #calculate the volume for a single solvent molecule
        center = [0., 0., 0.]
        pos = solv.massCenter()
        solv.moveBy(
            [center[0] - pos[0], center[1] - pos[1], center[2] - pos[2]])
        #solvDiameter = solv.diameter()+ _SEPARATION_BETWEEN_SOLVENTS_
        solvDiameter = math.pow(self.getDrawer().getBoxVolume() / molNum,
                                1. / 3.)
        if solvDiameter == 0: return

        row = math.floor(totalDim[1] / solvDiameter)
        col = math.floor(totalDim[0] / solvDiameter)
        dep = math.floor(totalDim[2] / solvDiameter)

        progressMax = molNum
        progressCount = 0
        if progress != None:
            progress.setLabelText("Adding solvent")
            progress.setRange(0, molNum - 1)
            progress.setValue(0)

        solvRadius = solvDiameter / 2
        newPos = solv.massCenter()
        refCoor = boxmin

        boxmax[0] -= solvDiameter / 2.
        boxmax[1] -= solvDiameter / 2.
        boxmax[2] -= solvDiameter / 2.

        # add first molecule and rename solvent with the given name
        mol = solv.copy()
        mol.moveBy([
            random.uniform(boxmin[0], boxmax[0]),
            random.uniform(boxmin[1], boxmax[1]),
            random.uniform(boxmin[2], boxmax[2])
        ])
        nodeName = self.addMolecule(mol, checkForInconsistentNames=True)
        self.shownMolecules.show(nodeName)
        #print "fillBox ", mol.molname(),progressMax
        solv.rename(mol.molname())
        progressMax -= 1

        if progress != None:
            progress.setLabelText("Adding solvent")
            progress.setRange(progressCount, progressMax)
            progress.setValue(progressCount)

        # lopps over a sequence of adding solvent and removing collisions
        while progressCount < progressMax:

            originalMolecules = self.getMixture().molecules()

            #print "anadiendo... ", progressMax-progressCount
            while progressCount < progressMax:  # adds solvent
                #random rotation for solvent atoms
                rx = random.uniform(0, 360)
                ry = random.uniform(0, 360)
                rz = random.uniform(0, 360)

                #random displacement for solvent atoms
                rdx = random.uniform(boxmin[0], boxmax[0])
                rdy = random.uniform(boxmin[1], boxmax[1])
                rdz = random.uniform(boxmin[2], boxmax[2])

                #generate new molecule and assign next position
                mol = solv.copy()
                mol.rotateDeg(rx, ry, rz)
                newPos = [rdx, rdy, rdz]
                mol.moveBy(newPos)
                #mol.rename("SOLVENT("+mol.molname()+")")
                nodeName = self.addMolecule(mol,
                                            checkForInconsistentNames=False)
                self.shownMolecules.show(nodeName)

                progressCount += 1
                if progress != None: progress.setValue(progressCount)

            # remove collisions
            if checkCollisions:
                if progress != None:
                    progress.setLabelText("Removing collisions")

                mix = self.getMixture()
                collisions = mix.overlapingMolecules(originalMolecules,
                                                     pbc=self.getDrawer(),
                                                     applyPBCs=applyPCBs)

                toRemove = set(collisions).difference(set(originalMolecules))
                if remaining < 0: remaining = len(toRemove)
                #print "remaining", remaining
                #print "removiendo... ", len(toRemove)
                #print "faltan... ", remaining-len(toRemove)
                if progress != None:
                    progress.setRange(0, remaining)
                    progress.setValue(remaining - len(toRemove))
                self.removeMoleculesFrom(toRemove)

                if replaceCollisions: progressCount -= len(toRemove)

        #print "tiempo ", time.clock() - start
        #print "Molecules after cleaning: ",mix.order()

    def getMixture(self):
        return self.mixture

    def getDrawer(self):
        return self.drawer

    def name(self):
        return self.mixture.mixName

    def getMixtureName(self):
        return self.mixture.mixName

    def getBuildDirectory(self):
        #return self.buildDir  # no longer used
        try:
            return self.workingDir
        except:
            self.workingDir = WOLFFIA_DEFAULT_MIXTURE_LOCATION + "/"
            return self.workingDir

    def getCurrentDirectory(self):
        return self.getBuildDirectory()

    def getSimTabValues(self):
        return self.simTabValues

    def updateMixture(self, mix):
        #self.setChanged()
        self.mixture = mix
        self.shownMolecules.updateMixture(self.mixture)
        self.fixedMolecules.updateMixture(self.mixture)
        #for mol in self.mixture:
        #    print "mix @t NanoCADState",self.mixture.getMolecule(mol)._name

    def addMixture(self, mix):
        #print "History addMixture",mix
        #self.mixture.merge(mix)
        for mol in mix:
            self.addMolecule(mix.getMolecule(mol))

    def addMolecule(self, mol, checkForInconsistentNames=True):
        print("NanoCADState addMolecule", mol)
        molname = self.mixture.add(mol, checkForInconsistentNames)
        self.shownMolecules.show(molname)
        return molname

    def removeMolecule(self, mol):
        #import inspect
        #print "NanoCADState.removeMolecule, caller=",inspect.stack()[1]
        #self.forceFieldStorage    =    None

        self.shownMolecules.remove(mol)
        self.getMixture().remove(mol)

    def removeMoleculesFrom(self, mols):
        self.getMixture().removeFrom(mols)
        self.updateMixture(self.getMixture())
        #self.getMixture().removeFrom(mols)

    def duplicateMolecule(self, mol):
        newName = self.getMixture().duplicateMolecule(mol)
        self.shownMolecules.show(newName)

    def setMixtureName(self, n):
        self.mixture.mixName = n

    def setDrawer(self, dr):
        self.drawer = dr

    def setBuildDirectory(self, d):
        #print "buildDirectory changed to, " , d
        #self.buildDir = d  # no longer used
        self.workingDir = d

    def setCurrentDirectory(self, d):
        self.workingDir = d

    def setSimTabValues(self, simVals):
        self.simTabValues = simVals.copy()

    def hasBox(self):
        return self.drawer != None and self.drawer.hasCell()