def tstTravelSurfOutside(
    tstFileName, phiFileName=False, tstDataIn=False, phiDataIn=False,
    borderSize=10):
  if tstDataIn:
    #don't want to read in if calling function already did it for us
    tstD = tstDataIn
  else:
    tstD = tstdata.tstData(tstFileName)  # read the file into the data structure
  if phiDataIn:
    phiData = phiDataIn
  else:
    phiData = phi(phiFileName)  # read in the phimap if possible
  #depends on convex hull _only_ to decide how far out to put the border
  if 'CONVEX_HULL_TRI_POINT_LIST' not in tstD.dict.keys():
    print "Run tstConvexHull.py on this tst data file first."
    sys.exit(1)
  #these sets are useful to construct
  convexHullPoints = set()
  for record in tstD.dict['CONVEX_HULL_TRI_POINT_LIST']:
    convexHullPoints.update(record[1:])
  gridD, mins, maxs = grid.makeTrimmedGridFromPhi(
      phiData, tstD.dict['POINT_XYZ'], convexHullPoints, 0.6, -2.0, 0,
      borderSize)
  gridSize = 1.0/phiData.scale
  del phiData  # no longer needed in this function, so delete this reference
  #do the biggest disjoint set of tris/points stuff
  allPoints, allTris, cavPoints, cavTris = cavity.assumeNoCavities(
      tstD.dict['POINT_XYZ'], tstD.dict['TRIANGLE_POINT'],
      tstD.dict['POINT_NEIGHBOR'])
  #here's the (relatively simple) surface travel distance calculation finally
  #  assign following encoding -1 = outside ch, 0 = on border,
  #   pos ints = dist from border, -2 = far inside ms,
  #   other neg ints = -(dist)-3
  extraEdges, surfaceEdgeBoxes = grid.findLongSurfEdges(
      tstD.dict['POINT_XYZ'], tstD.dict['POINT_NEIGHBOR'], gridSize, mins, maxs)
  for surfaceEdgeBox in surfaceEdgeBoxes.keys():
    x, y, z = gridD[surfaceEdgeBox[0]][surfaceEdgeBox[1]][surfaceEdgeBox[2]][1:]
    gridD[surfaceEdgeBox[0]][surfaceEdgeBox[1]][surfaceEdgeBox[2]] = (
        -1., x, y, z)
  pointTravelDist, traceback, volumePointDepths = \
      travelDistNoMesh.calcTravelDist(
          gridD, tstD.dict['POINT_XYZ'], gridSize, mins, maxs, allPoints,
          extraEdges, surfaceEdgeBoxes, tstFileName)
  #transform grid to actual travel distance
  maxTD = grid.finalizeGridTravelDist(gridD, gridSize)
  gridMaximaRanking = grid.getMaximaRanking(gridD)
  #output the grids and the gridmaxima....
  phiDataOut = phi()
  phiDataOut.createFromGrid(
      gridMaximaRanking, gridSize, toplabel="travel depth maxima rank")
  phiDataOut.write(tstFileName+".travel.out.max.rank.phi")
  phiDataOut = phi()
  phiDataOut.createFromGrid(
      gridD, gridSize, toplabel="travel depth surf-out", defaultValue=maxTD+1.0)
  phiDataOut.write(tstFileName+".travel.out.phi")
  return mins, maxs, gridSize, convexHullPoints, allPoints, allTris, \
      extraEdges, surfaceEdgeBoxes, pointTravelDist, traceback, maxTD, gridD, \
      gridMaximaRanking
def tstTravelSurfOutsideMesh(
    tstFileName, phiFileName=None, tstDataIn=False, phiDataIn=None,
    borderSize=10, threshold="auto"):
  if tstDataIn:
    #don't want to read in if calling function already did it for us
    tstD = tstDataIn
  else:
    tstD = tstdata.tstData(
        tstFileName, necessaryKeys=tstdata.tstData.necessaryKeysForMesh)
  if phiDataIn is not None:
    phiData = phiDataIn
  else:
    phiData = phi(phiFileName)  # read in the phimap if possible
  if 'CONVEX_HULL_TRI_POINT_LIST' not in tstD.dict.keys():
    print "Run tstConvexHull.py on this tst data file first."
    sys.exit(1)
  #these sets are useful to construct
  convexHullPoints = set()
  for record in tstD.dict['CONVEX_HULL_TRI_POINT_LIST']:
    convexHullPoints.update(record[1:])
  maxPhi = phiData.getMaxValues()
  if threshold == "auto" and maxPhi == 1.0:
    threshold = 0.6
  if threshold == "auto" and maxPhi == 10.0:
    threshold = 6.0
  gridD, mins, maxs = grid.makeTrimmedGridFromPhi(
      phiData, tstD.dict['POINT_XYZ'],
      convexHullPoints, threshold, -2, 0, borderSize)
  gridSize = 1.0/phiData.scale
  del phiData  # no longer needed in this function, so delete this reference
  #do the biggest disjoint set of tris/points stuff
  allPoints, allTris, cavPoints, cavTris = cavity.assumeNoCavities(
      tstD.dict['POINT_XYZ'], tstD.dict['TRIANGLE_POINT'],
      tstD.dict['POINT_NEIGHBOR'])
  #here is where code is mesh-specific
  meshData = mesh.mesh(
      gridD, tstD.dict['POINT_XYZ'], tstD.dict['POINT_NEIGHBOR'],
      gridSize, 0, -2, "X")  # no between
  meshData.calculateTravelDistance("surfout", [3], [0, 2])
  #transform grid to actual travel distance
  maxTD = grid.finalizeGridTravelDist(gridD, gridSize)
  gridMaximaRanking = grid.getMaximaRanking(gridD)
  #output the grids and the gridmaxima....
  phiDataOut = phi()
  phiDataOut.createFromGrid(
      gridMaximaRanking, gridSize, toplabel="travel depth maxima rank")
  phiDataOut.write(tstFileName + ".mesh.travel.out.max.rank.phi")
  phiDataOut = phi()
  phiDataOut.createFromGrid(
      gridD, gridSize, toplabel="travel depth surf-out",
      defaultValue=maxTD + 1.0)
  phiDataOut.write(tstFileName+".mesh.travel.out.phi")
def tstTravelDepthMesh(
    tstFileName, phiFileName, ligandFileName=None, cavities=False,
    threshold="auto"):
  '''sets up a normal travel depth mesh run, calls tstTravelDepthMeshRun.
  if cavities is set, it means we want the (new) travel depth of those too'''
  distanceName = 'traveldepth'
  tstD = tstdata.tstData(tstFileName)  # read the file into the data structure
  phiData = phi(phiFileName)  # read in the phimap if possible
  phiGridSpacing = 1. / phiData.scale
  phiTravelDepthGrid, phiTravelDepth, meshData = tstTravelDepthMeshRun(
      tstD, phiData, tstFileName, cavities=cavities,
      threshold=threshold)  # modifies tstD in place
  if ligandFileName is not None:
    ligand = pdb.pdbData(ligandFileName)
    ligandXYZR = ligand.getHeavyAtomXYZRadius()
    betweenList = meshData.getBetweenNodes()
    surfaceList = meshData.getSurfaceNodes()
    nodeWithinSet = meshData.getWithinNodesNoInside(ligandXYZR)
    #print len(nodeWithinSet), len(ligandXYZR)
    tracebackSet = meshData.getTracebackSet(nodeWithinSet, distanceName)
    #print len(tracebackSet)
    minW, maxW, meanW = meshData.getMinMaxMeanNodes(nodeWithinSet, distanceName)
    minT, maxT, meanT = meshData.getMinMaxMeanNodes(tracebackSet, distanceName)
    minB, maxB, meanB = meshData.getMinMaxMeanNodes(betweenList, distanceName)
    minS, maxS, meanS = meshData.getMinMaxMeanNodes(surfaceList, distanceName)
    #print all on one line, header printed earlier
    print minW, maxW, meanW,
    print minT, maxT, meanT,
    print minB, maxB, meanB,
    print minS, maxS, meanS,
    volumeWithin = len(nodeWithinSet) * phiGridSpacing**3.
    volumeTrace = len(tracebackSet) * phiGridSpacing**3.
    print volumeWithin, volumeTrace  # newline wanted here so no comma
    #print phiGridSpacing
    listWithin, listTrace = [], []
    for node in nodeWithinSet:
      listWithin.append(node.getXYZ())
    for node in tracebackSet:
      listTrace.append(node.getXYZ())
    tstdebug.pointDebug(listWithin, filename=ligandFileName+".within.py")
    tstdebug.pointDebug(listTrace, filename=ligandFileName+".trace.py")
  #tstdebug.debugGridCountVals(phiTravelDepthGrid)
  #transform grid to actual travel distance
  phiTravelDepth.write(tstFileName+".travel.phi")
  #write data to file
  tstFile = open(tstFileName, 'a')
  tstFile.write("DEPTH_TRAVEL_DIST\n")
  for line in tstD.dict['DEPTH_TRAVEL_DIST']:
    lineOut = "%8d" % line[0]
    for count in xrange(1, len(line)):
      lineOut += "%+9.4f " % line[count]
    noPlusLine = string.replace(lineOut, "+", " ")
    tstFile.write(noPlusLine)
    tstFile.write("\n")
  tstFile.write("END DEPTH_TRAVEL_DIST\n")
  tstFile.close()
def tstTravelDepth(tstFileName, phiFileName):
  tstD = tstdata.tstData(tstFileName)  # read the file into the data structure
  phiData = phi(phiFileName)  # read in the phimap if possible
  phiTravelDepthGrid, phiTravelDepthData, volumePointDepths = \
      tstTravelDepthRun(tstD, phiData, tstFileName)  # modifies tstD in place
  #transform grid to actual travel distance
  phiTravelDepthData.write(tstFileName+".travel.phi")
  #write data to file
  tstFile = open(tstFileName, 'a')
  tstFile.write("DEPTH_TRAVEL_DIST\n")
  for line in tstD.dict['DEPTH_TRAVEL_DIST']:
    lineOut = "%8d" % line[0]
    for count in xrange(1, len(line)):
      lineOut += "%+9.4f " % line[count]
    noPlusLine = string.replace(lineOut, "+", " ")
    tstFile.write(noPlusLine)
    tstFile.write("\n")
  tstFile.write("END DEPTH_TRAVEL_DIST\n")
  tstFile.close()
  if volumePointDepths:
    tstD.dict['POINT_TRAVEL_DEPTH_REPORT'] = volumePointDepths
    tstFile = open(tstFileName, 'a')
    tstFile.write("POINT_TRAVEL_DEPTH_REPORT\n")
    for line in volumePointDepths:
      lineOut = "%8d" % line[0]
      for count in xrange(1, len(line)):
        lineOut += "%+9.4f " % line[count]
      noPlusLine = string.replace(lineOut, "+", " ")
      tstFile.write(noPlusLine)
      tstFile.write("\n")
    tstFile.write("END POINT_TRAVEL_DEPTH_REPORT\n")
    tstFile.close()
  #now write to file
  tstFile = open(tstFileName, 'a')
  tstFile.write("TRACEBACK_LIST\n")
  for line in tstD.dict['TRACEBACK_LIST']:
    lineOut = " "
    for count in xrange(0, len(line)):
      lineOut += "%+9.4f " % line[count]
    noPlusLine = string.replace(lineOut, "+", " ")
    tstFile.write(noPlusLine)
    tstFile.write("\n")
  tstFile.write("END TRACEBACK_LIST\n")
  tstFile.close()
def tstTravelDepthMeshRun(
    tstD, phiData, tstFileName="temp.tst", borderSize=2,
    threshold="auto", cavities=False):
  '''returns a phi and a grid, modifies tstD in place.'''
  meshData, gridData = meshConstruct(
      tstD, phiData, tstFileName, borderSize=borderSize, threshold=threshold,
      cavities=cavities)
  if cavities:
    validList = [2, 3, 5]
  else:
    validList = [2, 3]
  meshData.calculateTravelDistance("traveldepth", [0], validList)
  pointTravelDepth = meshData.getSurfaceTravelDistance("traveldepth")
  gridTravelDepth = meshData.getGridTravelDistance(gridData, "traveldepth")
  tstD.dict['DEPTH_TRAVEL_DIST'] = pointTravelDepth  # save to tstD...
  phiDataOut = phi()
  gridSize = 1.0/phiData.scale
  phiDataOut.createFromGrid(
      gridTravelDepth, gridSize, toplabel="travel depth", defaultValue=-1)
  return gridTravelDepth, phiDataOut, meshData
def tstPocketMap(
    tstFileName, phiFileName, tstD=None, ligandFileName=None,
    nearbyDistance=0., appendTst=True, doPCA=True):
  '''pocket mapping algorithm, finds all pockets on entire surface, puts in
  tree and graph data structure, various outputs'''
  print "read tst file"
  if tstD is None:  # hasn't been read in already
    tstD = tstdata.tstData(
        tstFileName, necessaryKeys=tstdata.tstData.necessaryKeysForPocket)
  print "repairing nearby points if necessary"
  repairPointPdbRecord(tstD, tstFileName)
  print "calculating charges"
  chargeXyz, hydroXyz = calculateCharges(tstD, charge.charge())
  print "calculating curvatures"
  edgeCurv, ptCurv, ptWeighCurv = tstCurvature.tstEdgeCurvature(
      tstD.dict['TRIANGLE_POINT'], tstD.dict['POINT_XYZ'],
      tstD.dict['POINT_TRIANGLE'], tstD.dict['POINT_NEIGHBOR'])
  tstD.dict['POINT_CURVATURE_EDGE'] = ptWeighCurv
  tstD.dict['CHARGE_XYZ'] = chargeXyz
  tstD.dict['HYDROPHOBIC_XYZ'] = hydroXyz
  print "read in phi file"
  phiData = phi(phiFileName)  # read in the phimap
  print "making mesh data structure"
  meshData, gridData = meshConstruct(
      tstD, phiData, tstFileName, threshold="auto", cavities=True)
  meshData.setPtHydro(tstD.dict['HYDROPHOBIC_XYZ'])
  meshData.setPtCurvature(tstD.dict['POINT_CURVATURE_EDGE'])
  gridSize = 1.0/phiData.scale
  tstPdbRecord = tstD.dict['PDB_RECORD']
  meshData.setSurfaceArea(tstD.dict['TRIANGLE_POINT'])
  del tstD, phiData, gridData  # not needed, reclaim memory
  pdbD = pdb.pdbData()
  pdbD.processLines(tstPdbRecord)
  pointAtomList = meshData.calculateNearbyAtoms(pdbD, nearbyDistance)
  meshData.setVolume(gridSize)
  print "calculating travel depth"
  meshData.calculateTravelDistance("traveldepth", [0], [2, 3, 5])
  pointTravelDepth = meshData.getSurfaceTravelDistance("traveldepth")
  if ligandFileName is not None:  # if there is a ligand, read it
    ligand = pdb.pdbData(ligandFileName)
    ligandXYZR = ligand.getHeavyAtomXYZRadius()
    nodeWithinSet = meshData.getWithinNodesNoInside(ligandXYZR)
    bestIU = 0.  # intersection / union, 1 is perfect
    #print nodeWithinSet, len(nodeWithinSet)
  print "pocket mapping starting"
  if ligandFileName is not None and len(nodeWithinSet) > 0:
    outFileName = ligandFileName
    #tstdebug.nodeDebug(nodeWithinSet, \
    #              filename = tstFileName+".within.ligand.py")
    localMaxima, borders, tm3tree, surfNodeToLeaf = meshData.pocketMapping(
        'traveldepth',  [2, 3, 5], pointAtomList, pdbD,
        outName=outFileName + ".", groupName='group',
        ligandNodes=nodeWithinSet, doPCA=doPCA)
  else:
    outFileName = tstFileName
    localMaxima, borders, tm3tree, surfNodeToLeaf = meshData.pocketMapping(
        'traveldepth',  [2, 3, 5], pointAtomList, pdbD,
        outName=outFileName + ".", groupName='group', doPCA=doPCA)
  #print len(localMaxima), len(borders), tm3tree, len(surfNodeToLeaf)
  #tstdebug.nodeDebug(localMaxima, \
  #              filename=tstFileName+".localmaxima.pocketmap.py")
  #tstdebug.nodeDebug(borders, \
  #              filename=tstFileName+".borders.pocketmap.py")
  #tstdebug.nodeDebug(meshData.getSurfaceNodes(), \
  #              filename=tstFileName+".groups.pocketmap.py", name='group')
  tm3tree.write(outFileName + ".tree.tm3")
  #tm3tree.writeTNV(tstFileName + ".tree.tnv")
  #doesn't seem to import into treemap correctly
  if appendTst:  # turn off sometimes since appends to tst file
    print "appending data to tst file"
    surfNodes = meshData.getSurfaceNodes()
    pointLeafList = []
    for aNode in surfNodes:
      if aNode not in surfNodeToLeaf:
        print aNode, aNode.distances
        leafNum = 0  # made up and wrong for testing
      else:
        leafNum = surfNodeToLeaf[aNode]
      pointLeafList.append([aNode, int(leafNum)])
    #print pointLeafList
    leafToGroup = tm3tree.getLeafToGroup()
    leafGroupList = []
    leafKeyMax = max(leafToGroup.keys())
    for leaf in xrange(leafKeyMax):
      tempList = [leaf + 1]
      try:
        tempList.extend(leafToGroup[leaf + 1])
      except KeyError:
        pass  # means leaf doesn't exist
      leafGroupList.append(tempList)
    #print leafGroupList
    tstFile = open(tstFileName, 'a')
    tstdata.writeEntryIntegers(
        pointLeafList, "POINT_LEAF LIST", "END POINT_LEAF", tstFile)
    tstdata.writeEntryIntegers(
        leafGroupList, "LEAF_GROUP LIST", "END LEAF_GROUP", tstFile)
    tstdata.writeEntryIntegers(
        pointAtomList, "POINT_NEARBY_ATOM LIST", "END POINT_NEARBY_ATOM",
        tstFile)
    #also write curvature and charge data here
    tstdata.writeEntrySingleFloat(
        ptWeighCurv, "POINT_CURVATURE_EDGE LIST", "END POINT_CURVATURE_EDGE",
        tstFile)
    tstdata.writeEntrySingleFloat(
        chargeXyz, "CHARGE_XYZ", "END CHARGE_XYZ", tstFile)
    tstdata.writeEntrySingleFloat(
        hydroXyz, "HYDROPHOBIC_XYZ", "END HYDROPHOBIC_XYZ", tstFile)
    #write data to file
    tstFile.write("DEPTH_TRAVEL_DIST\n")
    for line in pointTravelDepth:
      lineOut = "%8d" % line[0]
      for count in xrange(1, len(line)):
        lineOut += "%+9.4f " % line[count]
      noPlusLine = string.replace(lineOut, "+", " ")
      tstFile.write(noPlusLine)
      tstFile.write("\n")
    tstFile.write("END DEPTH_TRAVEL_DIST\n")
    tstFile.close()
  print "pocket mapping complete"
def tstTravelSurfInsideMesh(tstFileName, phiFileName, threshold="auto"):
  '''calculates the burial depth'''
  print "reading in tst and phi files"
  tstD = tstdata.tstData(
      tstFileName,
      necessaryKeys=tstdata.tstData.necessaryKeysForMesh + ['PDB_RECORD'])
  phiData = phi(phiFileName)  # read in the phimap if possible
  if 'CONVEX_HULL_TRI_POINT_LIST' not in tstD.dict.keys():
    print "Run tstConvexHull.py on this tst data file first."
    sys.exit(1)
  #these sets are useful to construct
  convexHullPoints = set()
  for record in tstD.dict['CONVEX_HULL_TRI_POINT_LIST']:
    convexHullPoints.update(record[1:])
  maxPhi = phiData.getMaxValues()
  if threshold == "auto" and maxPhi == 1.0:
    threshold = 0.6
  if threshold == "auto" and maxPhi == 10.0:
    threshold = 6.0
  gridD, mins, maxs = grid.makeTrimmedGridFromPhi(
      phiData, tstD.dict['POINT_XYZ'], convexHullPoints, threshold, 0, -2, 2)
  gridSize = 1.0 / phiData.scale
  del phiData  # no longer needed in this function, so delete this reference
  #do the biggest disjoint set of tris/points stuff
  allPoints, allTris, cavPoints, cavTris = cavity.assumeNoCavities(
      tstD.dict['POINT_XYZ'], tstD.dict['TRIANGLE_POINT'],
      tstD.dict['POINT_NEIGHBOR'])
  #here is where code is mesh-specific
  print "setting up mesh data structure"
  meshData = mesh.mesh(
      gridD, tstD.dict['POINT_XYZ'], tstD.dict['POINT_NEIGHBOR'],
      gridSize, -2, 0, "X")  # no between
  print "calculating burial depth"
  meshData.calculateTravelDistance("travelin", [3], [1])
  gridTravelInDepth = meshData.getGridTravelDistance(gridD, "travelin")
  #tstdebug.debugGridCountVals(gridTravelInDepth)
  print "writing phi file output"
  phiDataOut = phi()
  phiDataOut.createFromGrid(
      gridTravelInDepth, gridSize, toplabel="travel depth surf-in")
  phiDataOut.write(tstFileName+".mesh.travel.in.phi")
  print "writing pdb file output"
  pdbD = pdb.pdbData()
  for line in tstD.dict['PDB_RECORD']:
    pdbD.processLine(line)
  atomTravelInDepths = grid.assignAtomDepths(
      gridTravelInDepth, gridSize, mins, maxs, pdbD)
  #make a pdb file with the bfactor replaced
  for index, atomTID in enumerate(atomTravelInDepths):
    pdbD.updateFactors(index, (pdbD.factors[index][0], atomTID))
  pdbD.write(tstFileName+".mesh.travelin.pdb")
  #also add record to tstD
  atomTIDRecord = []
  for index, atomTID in enumerate(atomTravelInDepths):
    atomTIDRecord.append([index + 1, atomTID])
  print "updating tst file"
  tstD.dict['ATOM_TRAVEL_IN'] = atomTIDRecord
  #write data into tst file
  tstFile = open(tstFileName, 'a')
  tstFile.write("ATOM_TRAVEL_IN\n")
  for line in tstD.dict['ATOM_TRAVEL_IN']:
    lineOut = "%8d" % line[0]
    for count in xrange(1, len(line)):
      lineOut += "%+9.4f " % line[count]
    noPlusLine = string.replace(lineOut, "+", " ")
    tstFile.write(noPlusLine)
    tstFile.write("\n")
  tstFile.write("END ATOM_TRAVEL_IN\n")
  tstFile.close()
  print "burial depth done"
def tstTravelFindHoles(
    tstFileName, phiFileName, debugOut=False, borderSize=2, nearbyDistance=4.):
  '''if debugout is set, additional files are created.
  bordersize can change the amount of extra space around the protein.
  nearbydistance changes the distance that nearby residues are gathered from.'''
  print "reading tst and phi files"
  tstD = tstdata.tstData(
      tstFileName, necessaryKeys=tstdata.tstData.necessaryKeysForHoles)
  phiData = phi(phiFileName)  # read in the phimap if possible
  gridSize = 1.0 / phiData.scale  # needed later
  numberHandles = tstD.countHandles()
  print "there are ", numberHandles, " holes in this structure"
  print "running travel depth now"
  phiTravelDepthGrid, phiTravelDepthData, meshData = tstTravelDepthMeshRun(
      tstD, phiData, tstFileName, borderSize=borderSize, threshold="auto")
  del phiData, phiTravelDepthGrid, phiTravelDepthData
  #not needed, reclaim memory
  print "calculating travel out distance"
  meshData.calculateTravelDistance("surfout", [3], [0, 2])
  print "finding holes"
  loopTrisSave, loopPointsSave, regLoopTris, regLoopPts, pointNeighbors, \
      pointNeighborsNodes, outsidePoints, outsidePointsNodes, possHoleStarts = \
      tstTopology.fillInHolesAndGrow(
          tstD.dict['TRIANGLE_POINT'], tstD.dict['POINT_TRIANGLE'],
          tstD.dict['POINT_XYZ'], tstD.dict['NORM_XYZ'], numberHandles,
          tstFileName, debugOut, meshData, "surfout")
  if debugOut:
    tstdebug.debugTriangleList(
        regLoopTris, tstD.dict['TRIANGLE_POINT'], tstD.dict['POINT_XYZ'],
        tstFileName + ".regular.loops.py")
  tstDPointXYZ = tstD.dict['POINT_XYZ']  # save for later
  tstDPdbRecord = tstD.dict['PDB_RECORD']  # save for later
  del tstD  # rest of tstD isn't needed, so free memory
  #output the possible places where HOLE could start... centers of regular plugs
  print "writing output files"
  paths.outputNodesText(possHoleStarts, tstFileName + ".HOLE.start.txt")
  pathsList = meshData.getPaths(
      "surfout", pointNeighbors, outsidePoints, possHoleStarts)
  del meshData  # deletes everything that has no other refs (from paths)
  #print len(pointNeighbors), len(outsidePoints), len(possHoleStarts),
  #print len(pathsList)
  allPoints, outsidePts = [], []
  for point in pointNeighborsNodes.keys():
    allPoints.append(point.pathXyz)
  for point in outsidePointsNodes:
    outsidePts.append(point.pathXyz)
  tstdebug.pointDebug(allPoints, filename=tstFileName+".tree.py")
  tstdebug.pointDebug(
      outsidePts, filename=tstFileName+".outside.py", mainColor=(.9, .1, .1),
      radius=0.55)
  #tstdebug.debugSetGridSpheres(
  #     pointNeighbors.keys(),, gridSize, tstFileName+".tree.radius.py",
  #     radius=True, mainColor=(0.01, 0.9, 0.05))
  #testing new output of tree with radius
  foundPaths = 0
  pathFile = string.replace(tstFileName, ".nocav.tst", ".py")
  #very very specific... probably bad but nice...
  #can always rerun standalone later.
  knownPathExists = os.path.isfile(pathFile)
  logName = tstFileName + ".findholes.log"
  logFile = open(logName, 'w')
  logFile.write(
      "number endNumOne endNumTwo plugs stepLength pathLength pathMinRadius " +
      "pathMaxInsideRadius endMinOne endMinTwo minimaCount travelDepthMax " +
      "windingMetric avgTheta ")
  if knownPathExists:
    logFile.write("pRMSD coverage span wrmsd less1 lessrad radiicomp")
  logFile.write("\n")
  if knownPathExists:
    bestStats = ["err", "err", "err", "err", "err", "err", "err"]
    bestStatsPaths = [0, 0, 0, 0, 0, 0, 0]
  sortedByMinRadiusPaths = []
  for pathIndex, (outsideOne, outsideTwo, plugs, nodePath) in enumerate(
      pathsList):
    pointPath, spheres = [], []
    for node in nodePath:
      pointPath.append(list(node.pathXyz))
      spheres.append(list(node.pathXyz))
      pointRadius = node.distances["surfout"]  # add 'radius' info
      if not pointRadius or pointRadius == 0.:
        pointRadius = .000000001  # very small number, on surface
      pointPath[-1].insert(0, pointRadius)
      spheres[-1].append(pointRadius)
    minRad = paths.pathMinRadius(pointPath)
    newTuple = (
        minRad, outsideOne, outsideTwo, plugs, nodePath, pointPath, spheres)
    #insertion sort into new list
    position = 0
    while position < len(sortedByMinRadiusPaths) and \
        sortedByMinRadiusPaths[position][0] > minRad:
      #only if list can handle it and already inserted are bigger
      position += 1
    sortedByMinRadiusPaths.insert(position, newTuple)
  print "output files for individual paths"
  for pathIndex, newTuple in enumerate(sortedByMinRadiusPaths):
    (minRad, outsideOne, outsideTwo, plugs, nodePath, pointPath, spheres) = \
        newTuple  # unpack the tuple into the various data
    throughTris, throughPts = paths.checkPath(
        pointPath, loopPointsSave, tstDPointXYZ)
    if throughTris:  # it worked... make some more debugging output
      foundPaths += 1
      outName = tstFileName + "." + str(foundPaths)
      if debugOut and throughTris:
        tstdebug.debugTrianglesNotOrig(
            throughTris, tstDPointXYZ, outName+".through.loop.py",
            ptList=throughPts)
      #always do these 2
      tstdebug.debugSetGridSpheres(
          pointPath, gridSize, outName + ".pore.py", radius=True,
          mainColor=(0.01, 0.9, 0.05))
      tstdebug.debugSetGridSpheres(
          pointPath, gridSize, outName + ".path.py", mainColor=(.01, 0.95, 0.9))
      #mesh.meshFromSpheres(spheres, 0.5, outName + ".points.py")
      paths.outputRadiiTxt(pointPath, outName + ".radii.txt")
      paths.outputNearbyResidues(
          pointPath, outName, tstDPdbRecord, nearbyDistance)
      pathLen = paths.pathLength(pointPath)
      minimaCount = paths.pathMinimaCount(pointPath)
      maxRad, endMinOne, endMinTwo = paths.insideTwoMinimaRadiusMax(pointPath)
      travelDepthMax = paths.pathMaxDistance(nodePath, 'traveldepth')
      windingMetric = paths.computeWindingMetric(pointPath)
      thetas, avgTheta = paths.averageTheta(pointPath)
      #print endMinOne, endMinTwo, minimaCount, travelDepthMax, windingMetric,
      #print avgTheta
      #attempt to do pRMSD if possible...
      prmsd, coverage, span, wrmsd, less1, lessrad, radiicomp = \
          "err", "err", "err", "err", "err", "err", "err"
      if knownPathExists:
        try:
          sourcePath, sourceRadii = [], []
          for pathPt in pointPath:
            sourcePath.append(pathPt[1:4])
            sourceRadii.append(pathPt[0])
          prmsd, coverage, span, wrmsd, less1, lessrad, radiicomp = \
              comparePathsManyMetrics(False, pathFile, sourcePath, sourceRadii)
          if bestStats[0] == 'err' or bestStats[0] > prmsd:
            bestStats[0] = prmsd
            bestStatsPaths[0] = foundPaths
          if bestStats[1] == 'err' or bestStats[1] < coverage:
            bestStats[1] = coverage
            bestStatsPaths[1] = foundPaths
          if bestStats[2] == 'err' or bestStats[2] < span:
            bestStats[2] = span
            bestStatsPaths[2] = foundPaths
          if bestStats[3] == 'err' or bestStats[3] > wrmsd:
            bestStats[3] = wrmsd
            bestStatsPaths[3] = foundPaths
          if bestStats[4] == 'err' or bestStats[4] < less1:
            bestStats[4] = less1
            bestStatsPaths[4] = foundPaths
          if bestStats[5] == 'err' or bestStats[5] < lessrad:
            bestStats[5] = lessrad
            bestStatsPaths[5] = foundPaths
          if bestStats[6] == 'err' or bestStats[6] < radiicomp:
            bestStats[6] = radiicomp
            bestStatsPaths[6] = foundPaths
        except (IOError, TypeError):
          #if there is no known path  file, this should be the error
          pass
      #now output data
      logFile.write(str(foundPaths) + " ")
      logFile.write(str(outsideOne) + " ")
      logFile.write(str(outsideTwo) + " ")
      logFile.write(str(plugs) + " ")
      logFile.write(str(len(pointPath)) + " ")
      logFile.write(str(pathLen) + " ")
      logFile.write(str(minRad) + " ")
      logFile.write(str(maxRad) + " ")
      logFile.write(str(endMinOne) + " ")
      logFile.write(str(endMinTwo) + " ")
      logFile.write(str(minimaCount) + " ")
      logFile.write(str(travelDepthMax) + " ")
      logFile.write(str(windingMetric) + " ")
      logFile.write(str(avgTheta) + " ")
      if knownPathExists:
        logFile.write(str(prmsd) + " ")
        logFile.write(str(coverage) + " ")
        logFile.write(str(span) + " ")
        logFile.write(str(wrmsd) + " ")
        logFile.write(str(less1) + " ")
        logFile.write(str(lessrad) + " ")
        logFile.write(str(radiicomp) + " ")
      logFile.write("\n")  # that's all
  logFile.close()
  if knownPathExists:  # output bestStats and bestStatsPaths
    bestName = tstFileName + ".known.best.txt"
    bestFile = open(bestName, 'w')
    bestFile.write("pRMSD coverage span wrmsd less1 lessrad radiicomp ")
    bestFile.write("pRMSD# coverage# span# wrmsd# less1# lessrad# radiicomp#\n")
    for stat in bestStats:
      bestFile.write(str(stat) + " ")
    for stat in bestStatsPaths:
      bestFile.write(str(stat) + " ")
    bestFile.write("\n")
    bestFile.close()
  print "done with chunnel"
def examinePhiMap(phiFileIn):
  phiData = phi(phiFileIn)  # read in the phimap if possible
  print phiData.getMinMaxValues()
  print phiData.histogramValues()
示例#10
0
def copyPhiMap(phiFileIn, phiFileOut):
  '''simple, just copies the phi map and writes it, to check binary i/o'''
  phiData = phi(phiFileIn)  # read in the phimap if possible
  phiData.write(phiFileOut)  # write out
示例#11
0
def tstTravelSurfInside(tstFileName, phiFileName=False):
  tstD = tstdata.tstData(tstFileName)  # read the file into the data structure
  phiData = phi(phiFileName)   # read in the phimap if possible
  if 'CONVEX_HULL_TRI_POINT_LIST' not in tstD.dict.keys():
    print "Run tstConvexHull.py on this tst data file first."
    sys.exit(1)
  #these sets are useful to construct
  convexHullPoints = set()
  for record in tstD.dict['CONVEX_HULL_TRI_POINT_LIST']:
    convexHullPoints.update(record[1:])
  gridD, mins, maxs = grid.makeTrimmedGridFromPhi(
      phiData, tstD.dict['POINT_XYZ'], convexHullPoints, 0.6, 0, -2.0, 2)
  gridSize = 1.0/phiData.scale
  del phiData  # no longer needed in this function, so delete this reference
  #do the biggest disjoint set of tris/points stuff
  allPoints, allTris, cavPoints, cavTris = cavity.assumeNoCavities(
      tstD.dict['POINT_XYZ'], tstD.dict['TRIANGLE_POINT'],
      tstD.dict['POINT_NEIGHBOR'])
  #here's the (relatively simple) surface travel distance calculation finally
  #  assign following encoding -1 = outside ch, 0 = on border,
  #   pos ints = dist from border, -2 = far inside ms,
  #   other neg ints = -(dist)-3
  #whole algorithm wrapped into big function...
  extraEdges, surfaceEdgeBoxes = grid.findLongSurfEdges(
      tstD.dict['POINT_XYZ'], tstD.dict['POINT_NEIGHBOR'], gridSize, mins, maxs)
  for surfaceEdgeBox in surfaceEdgeBoxes.keys():
    x, y, z = gridD[surfaceEdgeBox[0]][surfaceEdgeBox[1]][surfaceEdgeBox[2]][1:]
    gridD[surfaceEdgeBox[0]][surfaceEdgeBox[1]][surfaceEdgeBox[2]] = (
        -1., x, y, z)
  pointTravelDist, traceback, volumePointDepths = \
      travelDistNoMesh.calcTravelDist(
          gridD, tstD.dict['POINT_XYZ'], gridSize, mins, maxs, allPoints,
          extraEdges, surfaceEdgeBoxes, tstFileName)
  #transform grid to actual travel distance
  maxTD = grid.finalizeGridTravelDist(gridD, gridSize)
  phiDataOut = phi()
  phiDataOut.createFromGrid(gridD, gridSize, toplabel="travel depth surf-in")
  phiDataOut.write(tstFileName+".travel.in.phi")
  pdbD = pdb.pdbData()
  for line in tstD.dict['PDB_RECORD']:
    pdbD.processLine(line)
  atomTravelInDepths = grid.assignAtomDepths(gridD, gridSize, mins, maxs, pdbD)
  #make a pdb file with the bfactor replaced
  for index, atomTID in enumerate(atomTravelInDepths):
    pdbD.updateFactors(index, (pdbD.factors[index][0], atomTID))
  pdbD.write(tstFileName+".travelin.pdb")
  #also add record to tstdata
  atomTIDRecord = []
  for index, atomTID in enumerate(atomTravelInDepths):
    atomTIDRecord.append([index+1, atomTID])
  tstD.dict['ATOM_TRAVEL_IN'] = atomTIDRecord
  #write data into tst file
  tstFile = open(tstFileName, 'a')
  tstFile.write("ATOM_TRAVEL_IN\n")
  for line in tstD.dict['ATOM_TRAVEL_IN']:
    lineOut = "%8d" % line[0]
    for count in xrange(1, len(line)):
      lineOut += "%+9.4f " % line[count]
    noPlusLine = string.replace(lineOut, "+", " ")
    tstFile.write(noPlusLine)
    tstFile.write("\n")
  tstFile.write("END ATOM_TRAVEL_IN\n")
  tstFile.close()
示例#12
0
def tstTravelDepthNoPhi(tstFileName, gridSize=1.0):
  '''does old style (v1.0) travel depth with no phi-map, finds own inside and
  outside data, proceeds as normal'''
  tstD = tstdata.tstData(tstFileName)  # read the file into the data structure
  if 'CONVEX_HULL_TRI_POINT_LIST' not in tstD.dict.keys():
    print "Run tstConvexHull.py on this tst data file first."
    sys.exit(1)
  #these sets are useful to construct
  convexHullPoints = set()
  for record in tstD.dict['CONVEX_HULL_TRI_POINT_LIST']:
    convexHullPoints.update(record[1:])
  #do the biggest disjoint set of tris/points stuff
  allPoints, allTris, cavPoints, cavTris = cavity.assumeNoCavities(
      tstD.dict['POINT_XYZ'], tstD.dict['TRIANGLE_POINT'],
      tstD.dict['POINT_NEIGHBOR'])
  #find the minimum coordinates in each dimension
  mins = tstD.dict['POINT_XYZ'][0][1:]
  maxs = tstD.dict['POINT_XYZ'][0][1:]
  for point in convexHullPoints:
    xyz = tstD.dict['POINT_XYZ'][point-1][1:]
    for coord in range(3):
      mins[coord] = min(mins[coord], xyz[coord])
      maxs[coord] = max(maxs[coord], xyz[coord])
  #floor and ceiling everything to whole numbers
  minsSave = mins[:]
  maxsSave = maxs[:]
  #cache a bunch of computations on each triangle
  #triTuples does not contain the ones that are for cavities
  triTuples = geometry.cacheTriangle(
      tstD.dict['TRIANGLE_POINT'], tstD.dict['POINT_XYZ'], allTris)
  convexTriTuples = geometry.cacheTriangle(
      tstD.dict['CONVEX_HULL_TRI_POINT_LIST'], tstD.dict['POINT_XYZ'])
  #grid encoding -1 = outside ch, 0 = between ch, ms, -2 = inside ms
  mins, maxs = [], []  # so values computed are saved
  mins = [math.floor(x)-gridSize for x in minsSave]
  maxs = [math.ceil(x)+gridSize for x in maxsSave]
  gridD = grid.makeNewEmptyGrid(mins, maxs, gridSize, -1)  # set to outside ch
  #tstdebug.debugGridCountVals(gridD)
  #first step, check and set outside ch
  orstHelper.decideInside(
      gridD, convexTriTuples, convexHullPoints,
      tstD.dict['CONVEX_HULL_POINT_TRI_LIST'], tstD.dict['POINT_XYZ'],
      tstD.dict['CONVEX_HULL_TRI_POINT_LIST'], 0, False, 2)
   #0 inside convex hull, False any value, 2=max tris
  #tstdebug.debugGridCountVals(gridD)
  #now find inside molecular surface
  orstHelper.decideInside(
      gridD, triTuples, allPoints, tstD.dict['POINT_TRIANGLE'],
      tstD.dict['POINT_XYZ'], tstD.dict['TRIANGLE_POINT'], -2)
  #-2 inside everything
  #tstdebug.debugGridCountVals(gridD)
  #following lines make files that allow visual debugging in pymol
  #tstdebug.debugGrid(gridD, "debug.grid." + str(gridSize) + ".py")
  #tstdebug.debugGridNoBlue(gridD, "debug.grid.nb." + str(gridSize) + ".py")
  #tstdebug.debugGridJustGreen(gridD, "debug.grid.jg." + str(gridSize) + ".py")
  #now...
  #here's the (relatively simple) surface travel distance calculation finally
  #  assign following encoding -1 = outside ch, 0 = on border,
  #   pos ints = dist from border, -2 = far inside ms,
  #   other neg ints = -(dist)-3
  #whole algorithm wrapped into big function...
  extraEdges, surfaceEdgeBoxes = grid.findLongSurfEdges(
      tstD.dict['POINT_XYZ'], tstD.dict['POINT_NEIGHBOR'], gridSize, mins, maxs)
  volumePoints = False
  if 'POINT_TRAVEL_DEPTH_CHECK' in tstD.dict.keys():
    volumePoints = tstD.dict['POINT_TRAVEL_DEPTH_CHECK']
  pointTravelDist, traceback, volumePointDepths = \
      travelDistNoMesh.calcTravelDist(
          gridD, tstD.dict['POINT_XYZ'], gridSize, mins, maxs, allPoints,
          extraEdges, surfaceEdgeBoxes, tstFileName, volumePoints)
  #tstdebug.debugGridCountVals(gridD)
  #reassign -1 to max+1 (cavities)
  maximumTD = max([xxx[1] for xxx in pointTravelDist])
  for onePoint in pointTravelDist:
    if onePoint[1] < 0.0:
      onePoint[1] = maximumTD + 1.0
  maxTD = grid.finalizeGridTravelDist(gridD, gridSize)
  phiDataOut = phi()
  phiDataOut.createFromGrid(gridD, gridSize, toplabel="travel depth")
  phiDataOut.write(tstFileName+".travel.oldmethod.phi")
  #more pymol debugging if desired
  #tstdebug.debugTravelGrid(
  #    gridD,"debug.travel.grid." + str(gridSize) + ".py", maximumTD)
  #tstdebug.debugTravelSurfGrid(
  #    gridD, "debug.travel.surf.grid." + str(gridSize) + ".py",
  #    extraEdges, mins, maxs, gridSize, maximumTD)
  #save data into tstData
  tstD.dict['DEPTH_TRAVEL_DIST'] = pointTravelDist
  #write data to file
  tstFile = open(tstFileName, 'a')
  tstFile.write("DEPTH_TRAVEL_DIST\n")
  for line in pointTravelDist:
    lineOut = "%8d" % line[0]
    for count in xrange(1, len(line)):
      lineOut += "%+9.4f " % line[count]
    noPlusLine = string.replace(lineOut, "+", " ")
    tstFile.write(noPlusLine)
    tstFile.write("\n")
  tstFile.write("END DEPTH_TRAVEL_DIST\n")
  tstFile.close()
  if volumePointDepths:
    tstD.dict['POINT_TRAVEL_DEPTH_REPORT'] = volumePointDepths
    tstFile = open(tstFileName, 'a')
    tstFile.write("POINT_TRAVEL_DEPTH_REPORT\n")
    for line in volumePointDepths:
      lineOut = "%8d" % line[0]
      for count in xrange(1, len(line)):
        lineOut += "%+9.4f " % line[count]
      noPlusLine = string.replace(lineOut, "+", " ")
      tstFile.write(noPlusLine)
      tstFile.write("\n")
    tstFile.write("END POINT_TRAVEL_DEPTH_REPORT\n")
    tstFile.close()
  #save tracebacks into tstData
  tracebackArray = []  # format is end, dist, list of starts
  tracebackKeys = traceback.keys()
  tracebackKeys.sort()
  for endkey in tracebackKeys:
    startList, end, dist = traceback[endkey]
    tbLine = [end[0], end[1], end[2], dist]
    for start in startList:
      tbLine.append(start[0])
      tbLine.append(start[1])
      tbLine.append(start[2])
    tracebackArray.append(tbLine)
  tstD.dict['TRACEBACK_LIST'] = tracebackArray
  #now write to file
  tstFile = open(tstFileName, 'a')
  tstFile.write("TRACEBACK_LIST\n")
  for line in tracebackArray:
    lineOut = " "
    for count in xrange(0, len(line)):
      lineOut += "%+9.4f " % line[count]
    noPlusLine = string.replace(lineOut, "+", " ")
    tstFile.write(noPlusLine)
    tstFile.write("\n")
  tstFile.write("END TRACEBACK_LIST\n")
  tstFile.close()
示例#13
0
def tstTravelDepthRun(tstD, phiData, tstFileName="temp.tst"):
  if 'CONVEX_HULL_TRI_POINT_LIST' not in tstD.dict.keys():
    print "Run tstConvexHull.py on this tst data file first."
    sys.exit(1)
  #these sets are useful to construct
  convexHullPoints = set()
  for record in tstD.dict['CONVEX_HULL_TRI_POINT_LIST']:
    convexHullPoints.update(record[1:])
  gridD, mins, maxs = grid.makeTrimmedGridFromPhi(
      phiData, tstD.dict['POINT_XYZ'], convexHullPoints, 0.6, -2.0, -1.0)
  gridSize = 1.0/phiData.scale
  del phiData  # no longer needed in this function, so delete this reference
  #tstdebug.debugGridCountVals(gridD)
  #do the biggest disjoint set of tris/points stuff
  allPoints, allTris, cavPoints, cavTris = cavity.assumeNoCavities(
      tstD.dict['POINT_XYZ'], tstD.dict['TRIANGLE_POINT'],
      tstD.dict['POINT_NEIGHBOR'])
  convexTriTuples = geometry.cacheTriangle(
      tstD.dict['CONVEX_HULL_TRI_POINT_LIST'], tstD.dict['POINT_XYZ'])
  #grid encoding -1 = outside ch, 0 = between ch, ms, -2 = inside ms
  #this function marks cavities as interior
  #cavities now removed already
  #cavTriTuples = geometry.cacheTriangle( \
  #                tstD.dict['TRIANGLE_POINT'], tstD.dict['POINT_XYZ'], cavTris)
  #orstHelper.decideInside(gridD, cavTriTuples, cavPoints, \
  #               tstD.dict['POINT_TRIANGLE'], tstD.dict['POINT_XYZ'], \
  #               tstD.dict['TRIANGLE_POINT'], -2, -1)
  #-2 inside everything, -1 only valid to change
  #tstdebug.debugGridCountVals(gridD)
  #this marks the editable volume between the two surfaces
  orstHelper.decideInside(
      gridD, convexTriTuples, convexHullPoints,
      tstD.dict['CONVEX_HULL_POINT_TRI_LIST'], tstD.dict['POINT_XYZ'],
      tstD.dict['CONVEX_HULL_TRI_POINT_LIST'], 0, -1, 2)
  #0 inside convex hull, -1 outside (only valid to change), 2 = max tris
  #tstdebug.debugGridCountVals(gridD)
  #following lines make files that allow visual debugging in pymol
  #tstdebug.debugGrid(gridD, "debug.grid." + str(gridSize) + ".py")
  #tstdebug.debugGridNoBlue(gridD, "debug.grid.nb." + str(gridSize) + ".py")
  #tstdebug.debugGridJustGreen(gridD, "debug.grid.jg." + str(gridSize) + ".py")
  #now...
  #here's the (relatively simple) surface travel distance calculation finally
  #  assign following encoding -1 = outside ch, 0 = on border,
  #   pos ints = dist from border, -2 = far inside ms,
  #   other neg ints = -(dist)-3
  #whole algorithm wrapped into big function...
  extraEdges, surfaceEdgeBoxes = grid.findLongSurfEdges(
      tstD.dict['POINT_XYZ'], tstD.dict['POINT_NEIGHBOR'], gridSize, mins, maxs)
  volumePoints = False
  if 'POINT_TRAVEL_DEPTH_CHECK' in tstD.dict.keys():
    volumePoints = tstD.dict['POINT_TRAVEL_DEPTH_CHECK']
  pointTravelDist, traceback, volumePointDepths = \
      travelDistNoMesh.calcTravelDist(
          gridD, tstD.dict['POINT_XYZ'], gridSize, mins, maxs, allPoints,
          extraEdges, surfaceEdgeBoxes, tstFileName, volumePoints)
  #tstdebug.debugGridCountVals(gridD)
  #transform grid to actual travel distance
  maxTD = grid.finalizeGridTravelDist(gridD, gridSize)
  #more pymol debugging if desired
  #tstdebug.debugTravelGrid(
  #    gridD, "debug.travel.grid." + str(gridSize) + ".py", maximumTD)
  #tstdebug.debugTravelSurfGrid(
  #    gridD, "debug.travel.surf.grid." + str(gridSize) + ".py",
  #    extraEdges, mins, maxs, gridSize, maximumTD)
  #save data into tstD
  tstD.dict['DEPTH_TRAVEL_DIST'] = pointTravelDist
  #save tracebacks into tstD
  tracebackArray = []  # format is end, dist, list of starts
  tracebackKeys = traceback.keys()
  tracebackKeys.sort()
  for endkey in tracebackKeys:
    startList, end, dist = traceback[endkey]
    tbLine = [end[0], end[1], end[2], dist]
    for start in startList:
      tbLine.append(start[0])
      tbLine.append(start[1])
      tbLine.append(start[2])
    tracebackArray.append(tbLine)
  tstD.dict['TRACEBACK_LIST'] = tracebackArray
  phiDataOut = phi()
  phiDataOut.createFromGrid(
      gridD, gridSize, toplabel="travel depth", defaultValue=maxTD)
  return gridD, phiDataOut, volumePointDepths
示例#14
0
def tstCavityRemoval(
    tstFileName, tstFileNameOut, phiFileName=False, phiFileNameOut=False):
  oldTst = tstdata.tstDataWritable(tstFileName)  # read the file into the struct
  allPoints, allTris, cavPoints, cavTris = findBiggestDisjointSets(
      oldTst.dict['POINT_XYZ'], oldTst.dict['TRIANGLE_POINT'],
      oldTst.dict['POINT_NEIGHBOR'])
  #print len(allPoints), len(allTris), len(cavPoints), len(cavTris) #debug
  #now remove everything that isn't allPoints and allTris
  #first generate maps from old numbering to new numbering
  mapPoints = makeMapLists(oldTst.dict['POINT_XYZ'], allPoints)
  mapTris = makeMapLists(oldTst.dict['TRIANGLE_POINT'], allTris)
  #ugh. phi map.
  phiData = sharp_phi.phi(phiFileName)   # read in the phimap if possible
  gridD = grid.makeGridFromPhi(phiData, False)
  #the False just makes it copy values
  mins, maxs = phiData.getMinsMaxs()
  maxVal = phiData.getMaxValues()
  gridSize = 1.0/phiData.scale
  #this function marks cavities as interior
  cavTriTuples = geometry.cacheTriangle(
      oldTst.dict['TRIANGLE_POINT'], oldTst.dict['POINT_XYZ'], cavTris)
  #have to do this now before oldTst gets modified
  orstHelper.decideInside(
      gridD, cavTriTuples, cavPoints,
      oldTst.dict['POINT_TRIANGLE'], oldTst.dict['POINT_XYZ'],
      oldTst.dict['TRIANGLE_POINT'], maxVal)
  #change anything inside cavities to max..
  #now piece-by-piece fix each entry
  newTN = replaceEntry(
      oldTst.dict['TRIANGLE_NEIGHBOR'], mapTris, [mapTris, mapTris, mapTris])
  oldTst.dict['TRIANGLE_NEIGHBOR'] = newTN
  newPX = replaceEntry(
      oldTst.dict['POINT_XYZ'], mapPoints, [False, False, False])
  oldTst.dict['POINT_XYZ'] = newPX
  newTP = replaceEntry(
      oldTst.dict['TRIANGLE_POINT'], mapTris, [mapPoints, mapPoints, mapPoints])
  oldTst.dict['TRIANGLE_POINT'] = newTP
  newPT = replaceEntry(
      oldTst.dict['POINT_TRIANGLE'], mapPoints, [False, mapTris],
      extendToEnd=True)
  oldTst.dict['POINT_TRIANGLE'] = newPT
  newPN = replaceEntry(
      oldTst.dict['POINT_NEIGHBOR'], mapPoints, [False, mapPoints],
      extendToEnd=True)
  oldTst.dict['POINT_NEIGHBOR'] = newPN
  newNX = replaceEntry(
      oldTst.dict['NORM_XYZ'], mapPoints, [False, False, False])
  oldTst.dict['NORM_XYZ'] = newNX
  newPPR = replaceEntry(oldTst.dict['POINT_PDB_RECORD'], mapPoints, [False])
  oldTst.dict['POINT_PDB_RECORD'] = newPPR
  newTPR = replaceEntry(oldTst.dict['TRIANGLE_PDB_RECORD'], mapTris, [False])
  oldTst.dict['TRIANGLE_PDB_RECORD'] = newTPR
  #don't touch PDB_RECORD...
  newCX = replaceEntry(oldTst.dict['CURVATURE_XYZ'], mapPoints, [False])
  oldTst.dict['CURVATURE_XYZ'] = newCX
  newPX = replaceEntry(oldTst.dict['PROPERTY_XYZ'], mapPoints, [False])
  oldTst.dict['PROPERTY_XYZ'] = newPX
  #now write it back out...should probably tag it somehow....hmmm
  oldTst.write(tstFileNameOut)
  #write phi map
  phiDataOut = sharp_phi.phi()
  phiDataOut.createFromGrid(
      gridD, gridSize, toplabel=phiData.toplabel,
      head=phiData.head, title=phiData.title, botlabel=phiData.botlabel)
  phiDataOut.write(phiFileNameOut)