diff --git a/core/models_survex.py b/core/models_survex.py
index ed21658..efd3022 100644
--- a/core/models_survex.py
+++ b/core/models_survex.py
@@ -52,10 +52,20 @@ class SurvexFile(models.Model):
 class SurvexEquate(models.Model):
     cave        = models.ForeignKey('Cave', blank=True, null=True)
 
+class SurvexStationLookUpManager(models.Manager):
+    def lookup(self, name):
+        blocknames, sep, stationname = name.rpartition(".")
+        return self.get(block = SurvexBlock.objects.lookup(blocknames),
+                        name = stationname)
+
 class SurvexStation(models.Model):
     name        = models.CharField(max_length=20)   
     block       = models.ForeignKey('SurvexBlock')
     equate      = models.ForeignKey('SurvexEquate', blank=True, null=True)
+    objects = SurvexStationLookUpManager()
+    x = models.FloatField(blank=True, null=True)
+    y = models.FloatField(blank=True, null=True)
+    z = models.FloatField(blank=True, null=True)
 
 class SurvexLeg(models.Model):
     block       = models.ForeignKey('SurvexBlock')
@@ -70,7 +80,16 @@ class SurvexLeg(models.Model):
 #
 # Single SurvexBlock 
 # 
+class SurvexBlockLookUpManager(models.Manager):
+    def lookup(self, name):
+        blocknames = name.split(".")
+        block = SurvexBlock.objects.get(parent=None, survexfile__path="all")
+        for blockname in blocknames:
+            block = SurvexBlock.objects.get(parent=block, name=blockname)
+        return block
+
 class SurvexBlock(models.Model):
+    objects = SurvexBlockLookUpManager()
     name       = models.CharField(max_length=100)
     parent     = models.ForeignKey('SurvexBlock', blank=True, null=True)
     text       = models.TextField()
diff --git a/parsers/survex.py b/parsers/survex.py
index f8ec6d4..2e0b8d3 100644
--- a/parsers/survex.py
+++ b/parsers/survex.py
@@ -1,5 +1,8 @@
 import troggle.settings as settings
 import troggle.core.models as models
+import troggle.settings as settings
+
+from subprocess import call, Popen, PIPE
 
 from troggle.parsers.people import GetPersonExpeditionNameLookup
 import re
@@ -14,7 +17,13 @@ def LoadSurvexLineLeg(survexblock, stardata, sline, comment):
     
     survexleg = models.SurvexLeg(block=survexblock, stationfrom=ssfrom, stationto=ssto)
     if stardata["type"] == "normal":
-        survexleg.tape = float(ls[stardata["tape"]])
+        try:
+            survexleg.tape = float(ls[stardata["tape"]])
+        except ValueError: 
+            print "Tape misread in", survexblock.survexfile.path
+            print "Stardata:", stardata
+            print "Line:", ls
+            survexleg.tape = 1000
         lclino = ls[stardata["clino"]]
         lcompass = ls[stardata["compass"]]
         if lclino == "up":
@@ -24,7 +33,13 @@ def LoadSurvexLineLeg(survexblock, stardata, sline, comment):
             survexleg.compass = 0.0
             survexleg.clino = -90.0
         elif lclino == "-" or lclino == "level":
-            survexleg.compass = float(lcompass)
+            try:
+                survexleg.compass = float(lcompass)
+            except ValueError:
+                print "Compass misread in", survexblock.survexfile.path
+                print "Stardata:", stardata
+                print "Line:", ls
+                survexleg.compass = 1000
             survexleg.clino = -90.0
         else:
             assert re.match("[\d\-+.]+$", lcompass), ls
@@ -37,7 +52,10 @@ def LoadSurvexLineLeg(survexblock, stardata, sline, comment):
     
     itape = stardata.get("tape")
     if itape:
-        survexblock.totalleglength += float(ls[itape])
+        try:
+            survexblock.totalleglength += float(ls[itape])
+        except ValueError:
+            print "Length not added"
         survexblock.save()
         
 def LoadSurvexEquate(survexblock, sline):
@@ -86,6 +104,7 @@ def RecursiveLoad(survexblock, survexfile, fin, textlines):
                 LoadSurvexLineLeg(survexblock, stardata, sline, comment)
             elif stardata["type"] == "passage":
                 LoadSurvexLinePassage(survexblock, stardata, sline, comment)
+            #Missing "station" in stardata.
             continue
         
         # detect the star command
@@ -151,8 +170,7 @@ def RecursiveLoad(survexblock, survexfile, fin, textlines):
             for i in range(0, len(ls)):
                 stardata[stardataparamconvert.get(ls[i], ls[i])] = i - 1
             if ls[0] in ["normal", "cartesian", "nosurvey"]:
-                assert "from" in stardata, line
-                assert "to" in stardata, line
+                assert (("from" in stardata and "to" in stardata) or "station" in stardata), line
             elif ls[0] == "default":
                 stardata = stardatadefault
             else:
@@ -162,7 +180,7 @@ def RecursiveLoad(survexblock, survexfile, fin, textlines):
             LoadSurvexEquate(survexblock, sline)
         
         else:
-            assert cmd.lower() in [ "sd", "equate", "include", "units", "entrance", "fix", "data", "flags", "title", "export", "instrument", "calibrate", ], (cmd, line, survexblock)
+            assert cmd.lower() in [ "sd", "equate", "include", "units", "entrance", "fix", "data", "flags", "title", "export", "instrument", "calibrate", "set", "infer"], (cmd, line, survexblock)
         
         
 
@@ -186,6 +204,30 @@ def ReloadSurvexCave(survex_cave):
 
 
 def LoadAllSurvexBlocks():
+    models.SurvexBlock.objects.all().delete()
+    models.SurvexFile.objects.all().delete()
+    models.SurvexDirectory.objects.all().delete()
+    models.SurvexEquate.objects.all().delete()
+    models.SurvexLeg.objects.all().delete()
+    models.SurvexTitle.objects.all().delete()
+    models.SurvexPersonRole.objects.all().delete()
+
+    survexfile = models.SurvexFile(path="all", cave=None)
+    survexfile.save()
+    survexfile.SetDirectory()
+
+    #Load all
+    survexblockroot = models.SurvexBlock(name="root", survexpath="", begin_char=0, cave=None, survexfile=survexfile, totalleglength=0.0)
+    survexblockroot.save()
+    fin = survexfile.OpenFile()
+    textlines = [ ]
+    RecursiveLoad(survexblockroot, survexfile, fin, textlines)
+    survexblockroot.text = "".join(textlines)
+    survexblockroot.save()
+
+
+    #Load each cave, 
+    #FIXME this should be dealt with load all above
     caves = models.Cave.objects.all()
     for cave in caves:
         if cave.kataster_number and os.path.isdir(os.path.join(settings.SURVEX_DATA, "caves", cave.kataster_number)):
@@ -193,4 +235,20 @@ def LoadAllSurvexBlocks():
                 print "loading", cave
                 ReloadSurvexCave(cave.kataster_number)
     
-
+poslineregex = re.compile("^\(\s*([+-]?\d*\.\d*),\s*([+-]?\d*\.\d*),\s*([+-]?\d*\.\d*)\s*\)\s*([^\s]+)$")
+def LoadPos():
+    call([settings.CAVERN, "--output=%s/all.3d" % settings.SURVEX_DATA, "%s/all.svx" % settings.SURVEX_DATA])
+    call([settings.THREEDTOPOS, '%sall.3d' % settings.SURVEX_DATA], cwd = settings.SURVEX_DATA)
+    posfile = open("%sall.pos" % settings.SURVEX_DATA)
+    posfile.readline()#Drop header
+    for line in posfile.readlines():
+        r = poslineregex.match(line)                
+        if r:
+            x, y, z, name = r.groups()
+            try:
+                ss = models.SurvexStation.objects.lookup(name)
+            except:
+                pass
+            ss.x = float(x)
+            ss.y = float(y)
+            ss.z = float(z)