diff --git a/segmentmodel.py b/segmentmodel.py
index 6e9055071b4f1f008982e538283dca92e246fba3..24ba170024846276f29318385904fcbd8a06a323 100644
--- a/segmentmodel.py
+++ b/segmentmodel.py
@@ -33,6 +33,7 @@ TODO:
  - rework Location class 
  - remove recursive calls
  - document
+ - add unit test of helices connected to themselves
 """
 
 class Location():
@@ -1475,11 +1476,7 @@ class SegmentModel(ArbdModel):
             pot = self.get_bond_potential(4,18.5)
             self.add_bond(b1,b2, pot)
 
-            if not local_twist:
-                ## TODOTODO
-                
-                ...
-            else:
+            if local_twist:
                 k = (1.0/2) * 1.5 * kT * (1.0 / (1-np.exp(-float(1)/147))) * 0.00030461742; # kcal_mol/degree^2
                 if 'orientation_bead' in b1.__dict__:
                     # t0 = 90 + 60
@@ -1543,15 +1540,115 @@ class SegmentModel(ArbdModel):
                         k = k_fn( 0.5*(dists[b1][u1]+dists[b2][d2]) )
                         pot = self.get_dihedral_potential(k,t0)
                         self.add_dihedral( u1,b1,b2,d2, pot )
+            
+        ## TODOTODO check that this works
+        for crossovers in self.get_consecutive_crossovers():
+            ## filter crossovers
+            new_cl = []
+            particles = set()
+            for c,A,B in crossovers:
+                if A.particle not in particles:
+                    new_cl.append(c)
+                    particles.add(A.particle)
+            crossovers = new_cl
+            for i in range(len(crossovers)-1):
+                c1,A1,B1,dir1 = crossovers[i]
+                c2,A2,B2,dir2 = crossovers[j]
+                s1,s2 = [l.container for l in (A1,A2)]
+                sep = A1.get_nt_position(s1) - A2.get_nt_position(s2)
+                sep = np.abs(sep)
+
+                n1,n2,n3,n4 = (B1.particle, A1.particle, A2.particle, B2.particle)
+
+                ## <cos(q)> = exp(-s/Lp) = integrate( cos[x] exp(-A x^2), {x, 0, pi} ) / integrate( exp(-A x^2), {x, 0, pi} )
+                ##   Assume A is small
+                ## int[B_] :=  Normal[Integrate[ Series[Cos[x] Exp[-B x^2], {B, 0, 1}], {x, 0, \[Pi]}]/
+                ##             Integrate[Series[Exp[-B x^2], {B, 0, 1}], {x, 0, \[Pi]}]]
+                ## Actually, without assumptions I get fitFun below
+
+                ## From http://www.annualreviews.org/doi/pdf/10.1146/annurev.bb.17.060188.001405
+                ##   units "3e-19 erg cm/ 295 k K" "nm" =~ 73
+                Lp = s1.twistPersistenceLength/0.34  # set semi-arbitrarily as there is a large spread in literature
+
+                fitFun = lambda x: np.real(erf( (4*np.pi*x + 1j)/(2*np.sqrt(x)) )) * np.exp(-1/(4*x)) / erf(2*np.sqrt(x)*np.pi) - exp(-sep/Lp)
+                k = opt.leastsq( fitFun, x0=exp(-sep/Lp) )
+                k = k[0][0] * 2*kT*0.00030461742
+                        
+                t0 = sep*(360.0/s1.twist_per_nt)
+                
+                # pdb.set_trace()
+                if c1.on_fwd_strand: t0 -= 120
+                if dir1 != dir2:
+                    c2_on_fwd = not c2.on_fwd_strand
+                else:
+                    c2_on_fwd = c2.on_fwd_strand
+                if c2_on_fwd: t0 += 120
+   
+                # t0 = (t0 % 360
+
+                # if n2.idx == 0:
+                #     print( n1.idx,n2.idx,n3.idx,n4.idx,k,t0,sep )
+                pot = self.get_dihedral_potential(k,t0)
+                dihedrals.add( n1,n2,n3,n4, pot )
+                
 
-        def get_consecutive_crossovers():
+    def walk_through_helices(segment, direction=1, processed_segments=None):
+        assert( direction in (1,-1) )
+        if processed_segments = None:
             processed_segments = set()
-            for s in self.segments:
-                if s in processed_segments: continue
-            
-        for s in self.segments:
-            for cl in s.get_contour_sorted_connections_and_locations("crossover"):
-                ...
+
+        def segment_is_new_helix(s):
+            return isinstance(s0,DoubleStrandedSegment) and s0 not in processed_segments
+
+        s = s0 = segment
+        direction0 = direction
+        while segment_is_new_helix(s):
+            ## comb through helicalwalk through helix
+            conn_locs = s.get_contour_sorted_connections_and_locations("intrahelical")[::direction]
+
+            new_s = None
+            new_dir = None
+            for i in range(len(conn_locs)):
+                c,A,B = conn_locs[i]
+                ## TODO: handle change of direction
+                address = 1*(direction==-1)
+                if A.address == address and segment_is_new_helix(B.container):
+                    new_s = B.container
+                    assert(B.address in (0,1))
+                    new_dir = 2*(B.address == 0) - 1
+                    break
+
+            processed_segments.add(s)
+            yield s,direction
+            s = new_s   # will break if None
+            direction = new_dir
+        #     if new_s is None:
+        #         break
+        #     else:
+        #         s = new_s
+        # yield s
+        ## return s
+
+
+    def get_consecutive_crossovers(self):
+        crossovers = []
+        processed_segments = set()
+        for s1 in self.segments:
+            if not isinstance(s1,DoubleStrandedSegment):
+                continue
+            if s1 in processed_segments: continue
+
+            s0,d0 = list(SegmentModel.walk_through_helices(s1,direction=-1))[-1]
+
+            # s,direction = get_start_of_helices()
+            tmp = []
+            for s,d in SegmentModel.walk_through_helices(s0,-d0):
+                tmp.extend( s.get_contour_sorted_connections_and_locations("crossover")[::d] )
+                processed_segments.add(s)
+            ## TODOTODO 
+            ## if s and s0 are connected, do something
+            crossovers.append(tmp)
+        return crosovers
 
     def _generate_strands(self):
         self.strands = strands = []