Esempio n. 1
0
        def insertBaseFromMmp(filename, subgroup, tfm, position=position):
            """
            Insert the atoms for a nucleic acid base from an MMP file into
            a single chunk.
             - If atomistic, the atoms for each base are in a separate chunk.
             - If PAM5, the pseudo atoms for each base-pair are together in a
               chunk.

            @param filename: The mmp filename containing the base
                             (or base-pair).
            @type  filename: str

            @param subgroup: The part group to add the atoms to.
            @type  subgroup: L{Group}

            @param tfm: Transform applied to all new base atoms.
            @type  tfm: V

            @param position: The origin in space of the DNA duplex, where the
                             3' end of strand A is 0, 0, 0.
            @type  position: L{V}
            """
            try:
                ok, grouplist = readmmp(assy, filename, isInsert=True)
            except IOError:
                raise PluginBug("Cannot read file: " + filename)
            if not grouplist:
                raise PluginBug("No atoms in DNA base? " + filename)

            viewdata, mainpart, shelf = grouplist

            for member in mainpart.members:
                # 'member' is a chunk containing a set of base-pair atoms.
                for atm in member.atoms.values():
                    atm._posn = tfm(atm._posn) + position
                    if atm.element.symbol in ('Se3', 'Ss3', 'Ss5'):
                        if atm.getDnaBaseName() == "a":
                            baseLetter = currentBaseLetter
                        else:
                            try:
                                baseLetter = \
                                    basesDict[currentBaseLetter]['Complement']
                            except:
                                # If complement not found, just assign same
                                # letter.
                                baseLetter = currentBaseLetter
                        if 0:
                            print "Ss(%r) being set to %r." \
                                  % (atm.getDnaBaseName(), baseLetter)
                        atm.setDnaBaseName(baseLetter)

                member.name = currentBaseLetter
                subgroup.addchild(member)
                baseList.append(member)

            # Clean up.
            del viewdata
            shelf.kill()
Esempio n. 2
0
    def build_struct(self, name, params, position):
        """
        Build the DNA helix based on parameters in the UI.
        
        @param name: The name to assign the node in the model tree.
        @type  name: str
        
        @param params: The list of parameters gathered from the PM.
        @type  params: tuple
        
        @param position: The position in 3d model space at which to
                         create the DNA strand. This is always 0, 0, 0.
        @type position:  position
        """
        # No error checking in build_struct, do all your error
        # checking in gather_parameters
        numberOfBases, \
        dnaForm, \
        basesPerTurn, \
        endPoint1, \
        endPoint2 = params

        if Veq(endPoint1, endPoint2):
            raise CadBug("DNA endpoints cannot be the same point.")

        if numberOfBases < 1:
            msg = redmsg("Cannot to preview/insert a DNA duplex with 0 bases.")
            self.MessageGroupBox.insertHtmlMessage(msg, setAsDefault=False)
            self.dna = None  # Fixes bug 2530. Mark 2007-09-02
            return None

        if dnaForm == 'B-DNA':
            dna = B_Dna_PAM3()
        else:
            raise PluginBug("Unsupported DNA Form: " + dnaForm)

        self.dna = dna  # needed for done msg

        # Create the model tree group node.
        dnaGroup = Group(self.name, self.win.assy, self.win.assy.part.topnode)
        try:
            # Make the DNA duplex. <dnaGroup> will contain three chunks:
            #  - Strand1
            #  - Strand2
            #  - Axis
            dna.make(dnaGroup, numberOfBases, basesPerTurn, endPoint1,
                     endPoint2)

            return dnaGroup

        except (PluginBug, UserError):
            # Why do we need UserError here? Mark 2007-08-28
            rawDnaGroup.kill()
            raise PluginBug(
                "Internal error while trying to create DNA duplex.")

        pass
Esempio n. 3
0
    def _create_atomLists_for_regrouping(self, dnaGroup):
        """
        Creates and returns the atom lists that will be used to regroup the
        chunks  within the DnaGroup.

        @param dnaGroup: The DnaGroup whose atoms will be filtered and put into
                         individual strand A or strandB or axis atom lists.
        @return: Returns a tuple containing three atom lists
                 -- two atom lists for strand chunks and one for axis chunk.
        @see: self._regroup()
        """
        _strandA_list  =  []
        _strandB_list  =  []
        _axis_list     =  []
        # Build strand and chunk atom lists.
        for m in dnaGroup.members:
            for atom in m.atoms.values():
                if atom.element.symbol in ('Pl5', 'Pe5'):
                    if atom.getDnaStrandId_for_generators() == 'Strand1':
                        _strandA_list.append(atom)
                        # Following makes sure that the info record
                        #'dnaStrandId_for_generators' won't be written for
                        #this atom that the dna generator outputs. i.e.
                        #the info record 'dnaStrandId_for_generators' is only
                        #required while generating the dna from scratch
                        #(by reading in the strand base files in 'cad/plugins'
                        #see more comments in Atom.getDnaStrandId_for_generators
                        atom.setDnaStrandId_for_generators('')
                    elif atom.getDnaStrandId_for_generators() == 'Strand2':
                        atom.setDnaStrandId_for_generators('')
                        _strandB_list.append(atom)
                if atom.element.symbol in ('Ss5', 'Sh5'):
                    if atom.getDnaBaseName() == 'a':
                        _strandA_list.append(atom)
                        #Now reset the DnaBaseName for the added atom
                        # to 'unassigned' base i.e. 'X'
                        atom.setDnaBaseName('X')
                    elif atom.getDnaBaseName() == 'b':
                        _strandB_list.append(atom)
                        #Now reset the DnaBaseName for the added atom
                        # to 'unassigned' base i.e. 'X'
                        atom.setDnaBaseName('X')
                    else:
                        msg = "Ss5 or Sh5 atom not assigned to strand 'a' or 'b'."
                        raise PluginBug(msg)
                elif atom.element.symbol in ('Ax5', 'Ae5', 'Gv5', 'Gr5'):
                    _axis_list.append(atom)

        return (_strandA_list, _strandB_list, _axis_list)
Esempio n. 4
0
    def gather_parameters(self):
        """
        Return the parameters from the property manager UI.
        
        @return: All the parameters:
                 - dnaSequence
                 - dnaType
                 - basesPerTurn
                 - chunkOption
        @rtype:  tuple
        """
        if not basepath_ok:
            raise PluginBug("The cad/plugins/DNA directory is missing.")

        dnaModel = str(self.modelComboBox.currentText())
        dnaType = str(self.conformationComboBox.currentText())

        assert dnaType in ('B-DNA')

        # Get bases per turn.
        basesPerTurnString = str(self.basesPerTurnComboBox.currentText())
        basesPerTurn = float(basesPerTurnString)

        chunkOption = str(self.createComboBox.currentText())
        resolve_random = False
        # Later this flag may depend on a new checkbox in that case;
        # for now it doesn't matter, since sequence info is
        # discarded for reduced bases anyway.


        (dnaSequence, allKnown) = \
            self._getSequence( resolve_random = resolve_random)

        x1 = self.x1SpinBox.value()
        y1 = self.y1SpinBox.value()
        z1 = self.z1SpinBox.value()

        x2 = self.x2SpinBox.value()
        y2 = self.y2SpinBox.value()
        z2 = self.z2SpinBox.value()

        endpoint1 = V(x1, y1, z1)
        endpoint2 = V(x2, y2, z2)

        return (dnaSequence, dnaModel, dnaType, basesPerTurn, chunkOption,
                endpoint1, endpoint2)
Esempio n. 5
0
    def _createStructure(self):
        """
        creates and returns the structure (in this case a L{Group} object that
        contains the DNA strand and axis chunks.
        @return : group containing that contains the DNA strand and axis chunks.
        @rtype: L{Group}
        @note: This needs to return a DNA object once that model is implemented
        """

        # self.name needed for done message
        if self.create_name_from_prefix:
            # create a new name
            name = self.name = gensym(self.prefix,
                                      self.win.assy)  # (in _build_struct)
            self._gensym_data_for_reusing_name = (self.prefix, name)
        else:
            # use externally created name
            self._gensym_data_for_reusing_name = None
            # (can't reuse name in this case -- not sure what prefix it was
            #  made with)
            name = self.name

        # Create the model tree group node.
        # Make sure that the 'topnode'  of this part is a Group (under which the
        # DNa group will be placed), if the topnode is not a group, make it a
        # a 'Group' (applicable to Clipboard parts).See part.py
        # --Part.ensure_toplevel_group method. This is an important line
        # and it fixes bug 2585
        self.win.assy.part.ensure_toplevel_group()

        dnaGroup = DnaGroup(self.name,
                            self.win.assy,
                            self.win.assy.part.topnode,
                            editCommand=self)
        try:

            self.win.assy.place_new_geometry(dnaGroup)

            return dnaGroup

        except (PluginBug, UserError):
            # Why do we need UserError here? Mark 2007-08-28
            dnaGroup.kill()
            raise PluginBug(
                "Internal error while trying to create DNA duplex.")
Esempio n. 6
0
 def build_struct(self, name, params, position):
     """
     Same API as in GeneratorBaseClass (though we are not its subclass).
     On error, raise an exception.
     """
     # get executable, append exe, ensure it exists
     program = self.executable_path
     # make command line args from params
     args, outfiles = self.command_line_args_and_outfiles(params, name)
     # makes param args and outputfile args;
     # args is a list of strings (including outfile names);
     # outfiles is a list of full pathnames of files this command might create
     # run executable using the way we run the sim
     exitcode = self.run_command(program, args)
     #e look at exitcode?
     if exitcode and debug_run():
         print "generator exitcode: %r" % (exitcode, )
     if exitcode:
         # treat this as a fatal error for this run [to test, use an invalid chirality with m > n]
         msg = "Plugin %r exitcode: %r" % (self.plugin_name, exitcode)
         ## not needed, GBC UserError will do it, more or less: env.history.message(redmsg(msg))
         ###e should: self.remove_outfiles(outfiles, complain_if_missing = False)
         raise UserError(
             msg
         )  # this prints a redmsg; maybe we'd rather do that ourselves, and raise SilentUserError (nim)??
     # look for outfiles
     # (if there are more than one specified, for now just assume all of them need to be there)
     for outfile in outfiles:
         if not os.path.exists(outfile):
             ###e should: self.remove_outfiles(outfiles, complain_if_missing = False)
             raise PluginBug(
                 "generator output file should exist but doesn't: [%s]" %
                 (outfile, ))
     # insert file contents, rename the object in it, return that (see dna generator)
     thing = self.insert_output(outfiles, params, name)
     # we pass params, since some params might affect insertion (or postprocessing)
     # other than by affecting the command output
     ###@@@ WARNING: the following repositioning code is not correct for all kinds of "things",
     # only for single-chunk things like for CoNTub
     # (and also it probably belongs inside insert_output, not here):
     for atom in thing.atoms.values():
         atom.setposn(atom.posn() + position)
     self.remove_outfiles(outfiles)
     return thing
    def _createStructure(self):
        """
        Returns the current NanotubeSegment being edited with a new nanotube 
        chunk.
        @return : Nanotube segment that include the new nanotube chunk.
        @rtype: L{NanotubeSegment}        
        """
        
        try:
            # Create a new nanotube chunk using new params.
            n, m, type, endings, endPoint1, endPoint2 = self._gatherParameters()
            from cnt.model.NanotubeParameters import NanotubeParameters
            self.nanotube = NanotubeParameters()
            nanotube  =  self.nanotube
            nanotube.setChirality(n, m)
            nanotube.setType(type)
            nanotube.setEndings(endings)
            nanotube.setEndPoints(endPoint1, endPoint2)
            position = V(0.0, 0.0, 0.0)
            ntChunk = nanotube.build(self.struct.name, self.win.assy, position)
            nanotube.computeEndPointsFromChunk(ntChunk) # Needed.
            self.struct.addchild(ntChunk)
            
            #WARNING 2008-03-05:
            #When we actually permit modifying a nanotube without recreating it,
            #then the following properties must be set in self._modifyStructure 
            #as well. Needs more thought.
            props =(nanotube.getChirality(),
                    nanotube.getType(),
                    nanotube.getEndings(),
                    nanotube.getEndPoints())

            self.struct.setProps(props)

            return self.struct

        except (PluginBug, UserError):
            self.struct.kill()
            raise PluginBug("Internal error while trying to recreate a NanotubeSegment.")
        return None
    def _create_atomLists_for_regrouping(self, dnaGroup):
        """
        Creates and returns the atom lists that will be used to regroup the 
        chunks  within the DnaGroup. 

        @param dnaGroup: The DnaGroup whose atoms will be filtered and put into 
                         individual strand A or strandB or axis atom lists.
        @return: Returns a tuple containing three atom lists 
                 -- two atom lists for strand chunks and one for axis chunk. 
        @see: self._regroup()
        """
        _strandA_list = []
        _strandB_list = []
        _axis_list = []

        # Build strand and chunk atom lists.
        for m in dnaGroup.members:
            for atom in m.atoms.values():
                if atom.element.symbol in ('Ss3'):
                    if atom.getDnaBaseName() == 'a':
                        _strandA_list.append(atom)
                        #Now reset the DnaBaseName for the added atom
                        # to 'unassigned' base i.e. 'X'
                        atom.setDnaBaseName('X')
                    elif atom.getDnaBaseName() == 'b':
                        _strandB_list.append(atom)
                        #Now reset the DnaBaseName for the added atom
                        # to 'unassigned' base i.e. 'X'
                        atom.setDnaBaseName('X')
                    else:
                        msg = "Ss3 atom not assigned to strand 'a' or 'b'."
                        raise PluginBug(msg)
                elif atom.element.symbol in ('Ax3', 'Ae3'):
                    _axis_list.append(atom)

        return (_strandA_list, _strandB_list, _axis_list)
Esempio n. 9
0
    def build_struct(self, name, params, position):
        """
        Build the DNA helix based on parameters in the UI.
        
        @param name: The name to assign the node in the model tree.
        @type  name: str
        
        @param params: The list of parameters gathered from the PM.
        @type  params: tuple
        
        @param position: The position in 3d model space at which to
                         create the DNA strand. This is always 0, 0, 0.
        @type position:  position
        """
        # No error checking in build_struct, do all your error
        # checking in gather_parameters
        theSequence, \
        dnaModel, \
        dnaType, \
        basesPerTurn, \
        chunkOption, \
        endpoint1, \
        endpoint2 = params

        if Veq(endpoint1, endpoint2):
            raise CadBug("Dna endpoints cannot be the same point.")
            return

        if len(theSequence) < 1:
            msg = redmsg("Enter a strand sequence to preview/insert DNA")
            self.MessageGroupBox.insertHtmlMessage(msg, setAsDefault=False)
            self.dna = None  # Fixes bug 2530. Mark 2007-09-02
            return None

        if dnaModel == 'PAM3':
            dna = B_Dna_PAM3()
        else:
            dna = B_Dna_PAM5()

        self.dna = dna  # needed for done msg

        # Create the model tree group node.
        rawDnaGroup = Group(self.name, self.win.assy,
                            self.win.assy.part.topnode)
        try:
            # Make the DNA duplex. <rawDnaGroup> returns a different
            # grouping arrangement for atomistic vs. PAM5. This 'issue'
            # is resolved when we regroup the atoms into strand chunks
            # below.
            dna.make(rawDnaGroup, theSequence, basesPerTurn)

            self._orientRawDnaGroup(rawDnaGroup, endpoint1, endpoint2)

            # Now group the DNA atoms based on the grouping option selected
            # (i.e. "Strand chunks" or "Single Chunk").
            dnaGroup = self._makePAMStrandAndAxisChunks(rawDnaGroup)

            if chunkOption == 'Single chunk':
                return self._makeDuplexChunk(dnaGroup)

            return dnaGroup

        except (PluginBug, UserError):
            # Why do we need UserError here? Mark 2007-08-28
            rawDnaGroup.kill()
            raise PluginBug(
                "Internal error while trying to create DNA duplex.")
            return None
Esempio n. 10
0
    def _createStructure(self):
        """
        Creates and returns the structure (in this case a L{Group} object that
        contains the DNA strand and axis chunks.
        @return : group containing that contains the DNA strand and axis chunks.
        @rtype: L{Group}
        @note: This needs to return a DNA object once that model is implemented
        """

        params = self._gatherParameters()

        # No error checking in build_struct, do all your error
        # checking in gather_parameters
        number_of_basePairs_from_struct,\
                                       numberOfBases, \
                                       dnaForm, \
                                       dnaModel, \
                                       basesPerTurn, \
                                       duplexRise, \
                                       endPoint1, \
                                       endPoint2, \
                                       color_junk = params
        #Note: color_junk is not used. Ideally it should do struct.setColor(color)
        #but the color combobox in the PM directly sets the color of the
        #structure to the specified one when the current index in the combobx
        #changes

        #If user enters the number of basepairs and hits preview i.e. endPoint1
        #and endPoint2 are not entered by the user and thus have default value
        #of V(0, 0, 0), then enter the endPoint1 as V(0, 0, 0) and compute
        #endPoint2 using the duplex length.
        #Do not use '==' equality check on vectors! its a bug. Use same_vals
        # or Veq instead.
        if Veq(endPoint1, endPoint2) and Veq(endPoint1, V(0, 0, 0)):
            endPoint2 = endPoint1 + \
                      self.win.glpane.right*getDuplexLength('B-DNA',
                                                            numberOfBases)

        if numberOfBases < 1:
            msg = redmsg("Cannot preview/insert a DNA duplex with 0 bases.")
            self.propMgr.updateMessage(msg)
            self.dna = None  # Fixes bug 2530. Mark 2007-09-02
            return None

        if dnaForm == 'B-DNA':
            if dnaModel == 'PAM3':
                dna = B_Dna_PAM3_Generator()
            elif dnaModel == 'PAM5':
                dna = B_Dna_PAM5_Generator()
            else:
                print "bug: unknown dnaModel type: ", dnaModel
        else:
            raise PluginBug("Unsupported DNA Form: " + dnaForm)

        self.dna = dna  # needed for done msg

        # self.name needed for done message
        if self.create_name_from_prefix:
            # create a new name
            name = self.name = gensym(self.prefix,
                                      self.win.assy)  # (in _build_struct)
            self._gensym_data_for_reusing_name = (self.prefix, name)
        else:
            # use externally created name
            self._gensym_data_for_reusing_name = None
            # (can't reuse name in this case -- not sure what prefix it was
            #  made with)
            name = self.name

        # Create the model tree group node.
        # Make sure that the 'topnode'  of this part is a Group (under which the
        # DNa group will be placed), if the topnode is not a group, make it a
        # a 'Group' (applicable to Clipboard parts).See part.py
        # --Part.ensure_toplevel_group method. This is an important line
        # and it fixes bug 2585
        self.win.assy.part.ensure_toplevel_group()
        dnaSegment = DnaSegment(self.name,
                                self.win.assy,
                                self.win.assy.part.topnode,
                                editCommand=self)
        try:
            # Make the DNA duplex. <dnaGroup> will contain three chunks:
            #  - Strand1
            #  - Strand2
            #  - Axis

            dna.make(dnaSegment, numberOfBases, basesPerTurn, duplexRise,
                     endPoint1, endPoint2)

            #set some properties such as duplexRise and number of bases per turn
            #This information will be stored on the DnaSegment object so that
            #it can be retrieved while editing this object.
            #This works with or without dna_updater. Now the question is
            #should these props be assigned to the DnaSegment in
            #dnaDuplex.make() itself ? This needs to be answered while modifying
            #make() method to fit in the dna data model. --Ninad 2008-03-05

            #WARNING 2008-03-05: Since self._modifyStructure calls
            #self._createStructure()
            #If in the near future, we actually permit modifying a
            #structure (such as dna) without actually recreating the whole
            #structre, then the following properties must be set in
            #self._modifyStructure as well. Needs more thought.
            props = (duplexRise, basesPerTurn)
            dnaSegment.setProps(props)

            return dnaSegment

        except (PluginBug, UserError):
            # Why do we need UserError here? Mark 2007-08-28
            dnaSegment.kill()
            raise PluginBug(
                "Internal error while trying to create DNA duplex.")
    def _createStructure(self):
        """
        Creates and returns the structure (in this case a L{Group} object that
        contains the nanotube chunk.
        @return : group containing the nanotube chunk.
        @rtype: L{Group}
        @note: This needs to return a CNT object once that model is implemented
        """

        # self.name needed for done message
        if self.create_name_from_prefix:
            # create a new name
            name = self.name = gensym(self.prefix,
                                      self.win.assy)  # (in _build_struct)
            self._gensym_data_for_reusing_name = (self.prefix, name)
        else:
            # use externally created name
            self._gensym_data_for_reusing_name = None
            # (can't reuse name in this case -- not sure what prefix it was
            #  made with)
            name = self.name

        # Create the model tree group node.
        # Make sure that the 'topnode'  of this part is a Group (under which the
        # Nanotube group will be placed), if the topnode is not a group, make it
        # a 'Group' (applicable to Clipboard parts). See part.py
        # --Part.ensure_toplevel_group method. This is an important line
        # and it fixes bug 2585
        self.win.assy.part.ensure_toplevel_group()

        ntSegment = NanotubeSegment(self.name,
                                    self.win.assy,
                                    self.win.assy.part.topnode,
                                    editCommand=self)
        try:
            # Make the nanotube. <ntGroup> will contain one chunk:
            #  - Axis (Segment)
            # No error checking here; do all error checking in _gatherParameters().
            nanotube = self._gatherParameters()
            position = V(0.0, 0.0, 0.0)
            self.nanotube = nanotube  # needed for done msg #@
            ntChunk = nanotube.build(self.name, self.win.assy, position)

            ntSegment.addchild(ntChunk)

            #set some properties such as ntRise and its two endpoints.
            #This information will be stored on the NanotubeSegment object so that
            #it can be retrieved while editing this object.

            #WARNING 2008-03-05: Since self._modifyStructure calls
            #self._createStructure() If in the near future, we actually permit
            #modifying a
            #structure (such as a nanotube) without actually recreating the
            #entire structure, then the following properties must be set in
            #self._modifyStructure as well. Needs more thought.
            #props =(nanotube.getChirality(),
            #        nanotube.getType(),
            #        nanotube.getEndings(),
            #        nanotube.getEndPoints())

            ntSegment.setProps(nanotube.getParameters())

            return ntSegment

        except (PluginBug, UserError):
            # Why do we need UserError here? Mark 2007-08-28
            self._segmentList.remove(ntSegment)
            ntSegment.kill_with_contents()
            raise PluginBug("Internal error while trying to create Nanotube.")
Esempio n. 12
0
 def _strandBinfo(self, sequence, index):
     """
     Raise exception since A-DNA is not support.
     """
     raise PluginBug("A-DNA is not yet implemented.")
Esempio n. 13
0
 def _strandAinfo(self, baseLetter, index):
     """
     Raise exception since A-DNA is not support.
     """
     raise PluginBug("A-DNA is not yet implemented.")