diff --git a/mrdna/segmentmodel.py b/mrdna/segmentmodel.py
index b6d4a6c2e56f3a7fd4ca80f5d7a06fd24573644e..28b96ddad7ce06f995921f8c30d09d0fd76325dc 100644
--- a/mrdna/segmentmodel.py
+++ b/mrdna/segmentmodel.py
@@ -1052,97 +1052,110 @@ class Segment(ConnectableElement, Group):
         assert(len(old_beads) == len(self.beads))
 
 
-    def _generate_beads(self, bead_model, max_basepairs_per_bead, max_nucleotides_per_bead):
+    def _generate_beads(self, bead_model, max_basepairs_per_bead, max_nucleotides_per_bead, one_bead_per_monomer=False):
         """ Generate beads (positions, types, etc) and bonds, angles, dihedrals, exclusions """
         ## TODO: decide whether to remove bead_model argument
         ##       (currently unused)
 
-        ## First find points between-which beads must be generated
-        # conn_locs = self.get_contour_sorted_connections_and_locations()
-        # locs = [A for c,A,B in conn_locs]
-        # existing_beads = [l.particle for l in locs if l.particle is not None]
-        # if self.name == "S001":
-        #     pdb.set_trace()
+        tmp_children = []
 
-        # pdb.set_trace()
-        existing_beads0 = { (l.particle, l.particle.get_contour_position(self,l.address))
-                            for l in self.locations if l.particle is not None }
-        existing_beads = sorted( list(existing_beads0), key=lambda bc: bc[1] )
+        if one_bead_per_monomer:
+            last = None
+            for i in range(self.num_nt):
+                s = self.nt_pos_to_contour(i)
+                b = self._generate_one_bead(s,1)
 
-        # if self.num_nt == 1 and all([l.particle is not None for l in self.locations]):
-        #     pdb.set_trace()
-        #     return
-
-        for b,c in existing_beads:
-            assert(b.parent is not None)
-
-        ## Add ends if they don't exist yet
-        ## TODOTODO: test 1 nt segments?
-        if len(existing_beads) == 0 or (existing_beads[0][0].get_nt_position(self,0) >= 0.5 and 'is_circular_bead' not in existing_beads[0][0].__dict__):
-            # if len(existing_beads) > 0:            
-            #     assert(existing_beads[0].get_nt_position(self) >= 0.5)
-            c = self.nt_pos_to_contour(0)
-            if self.num_nt == 1: c -= 0.4
-            b = self._generate_one_bead(c, 0)
-            existing_beads = [(b,0)] + existing_beads
-
-        if (existing_beads[-1][0].get_nt_position(self,1)-(self.num_nt-1) < -0.5 and 'is_circular_bead' not in existing_beads[0][0].__dict__) or len(existing_beads)==1:
-            c = self.nt_pos_to_contour(self.num_nt-1)
-            if self.num_nt == 1: c += 0.4
-            b = self._generate_one_bead(c, 0)
-            existing_beads.append( (b,1) )
-        assert(len(existing_beads) > 1)
-
-        ## Walk through existing_beads, add beads between
-        tmp_children = []       # build list of children in nice order
-        last = None
+                if last is not None:
+                    last.make_intrahelical_neighbor(b)
+                last = b
+                tmp_children.append(b)
+        else:
+            ## First find points between-which beads must be generated
+            # conn_locs = self.get_contour_sorted_connections_and_locations()
+            # locs = [A for c,A,B in conn_locs]
+            # existing_beads = [l.particle for l in locs if l.particle is not None]
+            # if self.name == "S001":
+            #     pdb.set_trace()
 
-        for I in range(len(existing_beads)-1):
-            eb1,eb2 = [existing_beads[i][0] for i in (I,I+1)]
-            ec1,ec2 = [existing_beads[i][1] for i in (I,I+1)]
-            assert( (eb1,ec1) is not (eb2,ec2) )
+            # pdb.set_trace()
+            existing_beads0 = { (l.particle, l.particle.get_contour_position(self,l.address))
+                                for l in self.locations if l.particle is not None }
+            existing_beads = sorted( list(existing_beads0), key=lambda bc: bc[1] )
 
-            # if np.isclose(eb1.position[2], eb2.position[2]):
-            #     import pdb
+            # if self.num_nt == 1 and all([l.particle is not None for l in self.locations]):
             #     pdb.set_trace()
+            #     return
+
+            for b,c in existing_beads:
+                assert(b.parent is not None)
+
+            ## Add ends if they don't exist yet
+            ## TODOTODO: test 1 nt segments?
+            if len(existing_beads) == 0 or (existing_beads[0][0].get_nt_position(self,0) >= 0.5 and 'is_circular_bead' not in existing_beads[0][0].__dict__):
+                # if len(existing_beads) > 0:            
+                #     assert(existing_beads[0].get_nt_position(self) >= 0.5)
+                c = self.nt_pos_to_contour(0)
+                if self.num_nt == 1: c -= 0.4
+                b = self._generate_one_bead(c, 0)
+                existing_beads = [(b,0)] + existing_beads
+
+            if (existing_beads[-1][0].get_nt_position(self,1)-(self.num_nt-1) < -0.5 and 'is_circular_bead' not in existing_beads[0][0].__dict__) or len(existing_beads)==1:
+                c = self.nt_pos_to_contour(self.num_nt-1)
+                if self.num_nt == 1: c += 0.4
+                b = self._generate_one_bead(c, 0)
+                existing_beads.append( (b,1) )
+            assert(len(existing_beads) > 1)
+
+            ## Walk through existing_beads, add beads between
+            last = None
+
+            for I in range(len(existing_beads)-1):
+                eb1,eb2 = [existing_beads[i][0] for i in (I,I+1)]
+                ec1,ec2 = [existing_beads[i][1] for i in (I,I+1)]
+                assert( (eb1,ec1) is not (eb2,ec2) )
+
+                # if np.isclose(eb1.position[2], eb2.position[2]):
+                #     import pdb
+                #     pdb.set_trace()
 
-            # print(" %s working on %d to %d" % (self.name, eb1.position[2], eb2.position[2]))
-            e_ds = ec2-ec1
-            num_beads = self._get_num_beads( e_ds, max_basepairs_per_bead, max_nucleotides_per_bead )
-
-            ## Ensure there is a ssDNA bead between dsDNA beads
-            if num_beads == 0 and isinstance(self,SingleStrandedSegment) and isinstance(eb1.parent,DoubleStrandedSegment) and isinstance(eb2.parent,DoubleStrandedSegment):
-                num_beads = 1
-            ## TODO similarly ensure there is a dsDNA bead between ssDNA beads
-
-            ds = e_ds / (num_beads+1)
-            nts = ds*self.num_nt
-            eb1.num_nt += 0.5*nts
-            eb2.num_nt += 0.5*nts
-
-            ## Add beads
-            if eb1.parent == self:
-                tmp_children.append(eb1)
-
-            s0 = ec1
-            if last is not None:
-                last.make_intrahelical_neighbor(eb1)
-            last = eb1
-            for j in range(num_beads):
-                s = ds*(j+1) + s0
-                # if self.name in ("51-2","51-3"):
-                # if self.name in ("31-2",):
-                #     print(" adding bead at {}".format(s))
-                b = self._generate_one_bead(s,nts)
-
-                last.make_intrahelical_neighbor(b)
-                last = b
-                tmp_children.append(b)
+                # print(" %s working on %d to %d" % (self.name, eb1.position[2], eb2.position[2]))
+                e_ds = ec2-ec1
+                num_beads = self._get_num_beads( e_ds, max_basepairs_per_bead, max_nucleotides_per_bead )
+
+                ## Ensure there is a ssDNA bead between dsDNA beads
+                if num_beads == 0 and isinstance(self,SingleStrandedSegment) and isinstance(eb1.parent,DoubleStrandedSegment) and isinstance(eb2.parent,DoubleStrandedSegment):
+                    num_beads = 1
+                ## TODO similarly ensure there is a dsDNA bead between ssDNA beads
+
+                ds = e_ds / (num_beads+1)
+                nts = ds*self.num_nt
+                eb1.num_nt += 0.5*nts
+                eb2.num_nt += 0.5*nts
+
+                ## Add beads
+                if eb1.parent == self:
+                    tmp_children.append(eb1)
 
-        last.make_intrahelical_neighbor(eb2)
+                s0 = ec1
+                if last is not None:
+                    last.make_intrahelical_neighbor(eb1)
+                last = eb1
+                for j in range(num_beads):
+                    s = ds*(j+1) + s0
+                    # if self.name in ("51-2","51-3"):
+                    # if self.name in ("31-2",):
+                    #     print(" adding bead at {}".format(s))
+                    b = self._generate_one_bead(s,nts)
+
+                    last.make_intrahelical_neighbor(b)
+                    last = b
+                    tmp_children.append(b)
+
+            last.make_intrahelical_neighbor(eb2)
+
+            if eb2.parent == self:
+                tmp_children.append(eb2)
 
-        if eb2.parent == self:
-            tmp_children.append(eb2)
         # if self.name in ("31-2",):
         #     pdb.set_trace()
         self._rebuild_children(tmp_children)
@@ -2249,10 +2262,17 @@ class SegmentModel(ArbdModel):
                                   escapable_twist=escapable_twist)
 
     def generate_bead_model(self,
-                             max_basepairs_per_bead = 7,
-                             max_nucleotides_per_bead = 4,
-                             local_twist=False,
-                             escapable_twist=True):
+                            max_basepairs_per_bead = 7,
+                            max_nucleotides_per_bead = 4,
+                            local_twist=False,
+                            escapable_twist=True,
+                            sequence_dependent = False,
+                            one_bead_per_monomer = False
+                        ):
+        if sequence_dependent and not local_twist:
+            raise ValueError("Incompatible options: if sequence_dependent==True, then local_twist must be True")
+        if sequence_dependent and not one_bead_per_monomer:
+            raise ValueError("Incompatible options: if sequence_dependent==True, then one_bead_per_monomer must be True")
 
         self.children = self.segments # is this okay?
         self.clear_beads()
@@ -2291,97 +2311,120 @@ class SegmentModel(ArbdModel):
         """ Generate beads at intrahelical junctions """
         if self.DEBUG: print( "Adding intrahelical beads at junctions" )
 
+        if not one_bead_per_monomer:
+            ## Loop through all connections, generating beads at appropriate locations
+            for c,A,B in self.get_connections("intrahelical"):
+                s1,s2 = [l.container for l in (A,B)]
 
-        ## Loop through all connections, generating beads at appropriate locations
-        for c,A,B in self.get_connections("intrahelical"):
-            s1,s2 = [l.container for l in (A,B)]
+                assert( A.particle is None )
+                assert( B.particle is None )
 
-            assert( A.particle is None )
-            assert( B.particle is None )
+                ## TODO: offload the work here to s1
+                # TODOTODO
+                a1,a2 = [l.address   for l in (A,B)]            
+                for a in (a1,a2):
+                    assert( np.isclose(a,0) or np.isclose(a,1) )
 
-            ## TODO: offload the work here to s1
-            # TODOTODO
-            a1,a2 = [l.address   for l in (A,B)]            
-            for a in (a1,a2):
-                assert( np.isclose(a,0) or np.isclose(a,1) )
-            
-            ## TODO improve this for combinations of ssDNA and dsDNA (maybe a1/a2 should be calculated differently)
-
-            def _get_nearest(seg,address):
-                b = seg.get_nearest_bead(address)
-                if b is not None:
-                    assert( b.parent is seg )
-                    """ if above assertion is true, no problem here """
-                    if np.abs(b.get_nt_position(seg) - seg.contour_to_nt_pos(address)) > 0.5:
-                        b = None
-                return b
-
-            """ Search to see whether bead at location is already found """
-            b = None
-            if isinstance(s1,DoubleStrandedSegment):
-                b = _get_nearest(s1,a1)
-            if b is None and isinstance(s2,DoubleStrandedSegment):
-                b = _get_nearest(s2,a2)
-
-            if b is not None and b.parent not in (s1,s2):
-                b = None
+                ## TODO improve this for combinations of ssDNA and dsDNA (maybe a1/a2 should be calculated differently)
 
-            if b is None:
-                ## need to generate a bead
-                if isinstance(s2,DoubleStrandedSegment):
-                    b = s2._generate_one_bead(a2,0)
-                else:
-                    b = s1._generate_one_bead(a1,0)
-            A.particle = B.particle = b
-            b.is_intrahelical = True
-            b.locations.extend([A,B])
-            if s1 is s2:
-                b.is_circular_bead = True
+                def _get_nearest(seg,address):
+                    b = seg.get_nearest_bead(address)
+                    if b is not None:
+                        assert( b.parent is seg )
+                        """ if above assertion is true, no problem here """
+                        if np.abs(b.get_nt_position(seg) - seg.contour_to_nt_pos(address)) > 0.5:
+                            b = None
+                    return b
 
-        # pdb.set_trace()
+                """ Search to see whether bead at location is already found """
+                b = None
+                if isinstance(s1,DoubleStrandedSegment):
+                    b = _get_nearest(s1,a1)
+                if b is None and isinstance(s2,DoubleStrandedSegment):
+                    b = _get_nearest(s2,a2)
+
+                if b is not None and b.parent not in (s1,s2):
+                    b = None
+
+                if b is None:
+                    ## need to generate a bead
+                    if isinstance(s2,DoubleStrandedSegment):
+                        b = s2._generate_one_bead(a2,0)
+                    else:
+                        b = s1._generate_one_bead(a1,0)
+                A.particle = B.particle = b
+                b.is_intrahelical = True
+                b.locations.extend([A,B])
+                if s1 is s2:
+                    b.is_circular_bead = True
 
-        """ Generate beads at other junctions """
-        for c,A,B in self.get_connections(exclude="intrahelical"):
-            s1,s2 = [l.container for l in (A,B)]
-            if A.particle is not None and B.particle is not None:
-                continue
-            # assert( A.particle is None )
-            # assert( B.particle is None )
+            # pdb.set_trace()
 
-            ## TODO: offload the work here to s1/s2 (?)
-            a1,a2 = [l.address   for l in (A,B)]
+            """ Generate beads at other junctions """
+            for c,A,B in self.get_connections(exclude="intrahelical"):
+                s1,s2 = [l.container for l in (A,B)]
+                if A.particle is not None and B.particle is not None:
+                    continue
+                # assert( A.particle is None )
+                # assert( B.particle is None )
+
+                ## TODO: offload the work here to s1/s2 (?)
+                a1,a2 = [l.address   for l in (A,B)]
+
+                def maybe_add_bead(location, seg, address, ):
+                    if location.particle is None:
+                        b = seg.get_nearest_bead(address)
+                        try:
+                            distance = seg.contour_to_nt_pos(np.abs(b.contour_position-address))
+                            max_distance =  min(max_basepairs_per_bead, max_nucleotides_per_bead)*0.5
+                            if "is_intrahelical" in b.__dict__:
+                                max_distance = 0.5
+                            if distance >= max_distance:
+                                raise Exception("except")
+
+                            ## combine beads
+                            b.update_position( 0.5*(b.contour_position + address) ) # avg position
+                        except:
+                            b = seg._generate_one_bead(address,0)
+                        location.particle = b
+                        b.locations.append(location)
+
+                maybe_add_bead(A,s1,a1)
+                maybe_add_bead(B,s2,a2)
+
+            """ Some tests """
+            for c,A,B in self.get_connections("intrahelical"):
+                for l in (A,B):
+                    if l.particle is None: continue
+                    assert( l.particle.parent is not None )
 
-            def maybe_add_bead(location, seg, address, ):
-                if location.particle is None:
-                    b = seg.get_nearest_bead(address)
-                    try:
-                        distance = seg.contour_to_nt_pos(np.abs(b.contour_position-address))
-                        max_distance =  min(max_basepairs_per_bead, max_nucleotides_per_bead)*0.5
-                        if "is_intrahelical" in b.__dict__:
-                            max_distance = 0.5
-                        if distance >= max_distance:
-                            raise Exception("except")
-
-                        ## combine beads
-                        b.update_position( 0.5*(b.contour_position + address) ) # avg position
-                    except:
-                        b = seg._generate_one_bead(address,0)
-                    location.particle = b
-                    b.locations.append(location)
-
-            maybe_add_bead(A,s1,a1)
-            maybe_add_bead(B,s2,a2)
-
-        """ Some tests """
-        for c,A,B in self.get_connections("intrahelical"):
-            for l in (A,B):
-                if l.particle is None: continue
-                assert( l.particle.parent is not None )
+            """ Generate beads in between """
+            if self.DEBUG: print("Generating beads")
+            for s in segments:
+                s._generate_beads( self, max_basepairs_per_bead, max_nucleotides_per_bead )
 
-        """ Generate beads in between """
-        if self.DEBUG: print("Generating beads")
-        for s in segments:
-            s._generate_beads( self, max_basepairs_per_bead, max_nucleotides_per_bead )
+        else:
+            """ Generate beads in each segment """
+            if self.DEBUG: print("Generating beads")
+            for s in segments:
+                s._generate_beads( self, max_basepairs_per_bead, max_nucleotides_per_bead, one_bead_per_monomer )
+
+            """ Associate beads with junctions """
+            # for c,A,B in self.get_connections("intrahelical"):
+            for c,A,B in self.get_connections():
+                for l in (A,B):
+                    seg = l.container
+                    a = l.address
+                    b = seg.get_nearest_bead(a)
+
+                    l.particle = b
+                    b.locations.append(l)
+                """
+                b.is_intrahelical = True
+                b.locations.extend([A,B])
+                if s1 is s2:
+                    b.is_circular_bead = True
+                """
 
         # """ Combine beads at junctions as needed """
         # for c,A,B in self.get_connections():