Python wrapper for running instances of trisurf-ng
Samo Penic
2017-11-28 8b8845e452b45b765c0c74a388296d10e91787fc
trisurf/trisurf.py
@@ -186,7 +186,6 @@
      self.path=path
      self.filename=filename
      self.fullname=os.path.join(path,filename)
      self.fileOK=self.read()
      return
   def exists(self):
@@ -196,7 +195,7 @@
      else:
         return False
   def mapcount(self):
   def lineCount(self):
      '''
      Internal method for determining the number of the lines in the most efficient way. Is it really the most efficient?
      '''
@@ -213,19 +212,26 @@
         f.close()
      return lines
   def tail(self,filename,n=2):
      with open(filename,'r') as myfile:
   def tail(self):
      with open(self.fullname,'r') as myfile:
         lines=myfile.readlines()
      return [lines[len(lines)-2].replace('\n',''),lines[len(lines)-1].replace('\n','')]
   def read(self):
   def checkFileValidity(self):
      try:
         lines=self.tail(self.fullname)
         lines=self.tail()
      except:
         return(False)
      if len(lines)<2:
         return(False)
      #print (line)
      return(True)
   def getSimulationDeltaTime(self):
      try:
         lines=self.tail()
      except:
         return 0
      fields=shlex.split(lines[0])
      epoch1=fields[0]
      n1=fields[1]
@@ -234,61 +240,59 @@
      epoch2=fields[0]
      n2=fields[1]
      try:
         self.dT=int(epoch2)-int(epoch1)
         self.last=n2
         #print(epoch1)
         #print(epoch2)
         #print(self.dT)
         #print(self.last)
         self.startDate=os.path.getmtime(os.path.join(self.path,'.lock'))
         dT=int(epoch2)-int(epoch1)
      except:
         return(False)
      return(True)
         return 0
      return dT
   def getLastIterationInStatistics(self):
      try:
         lines=self.tail()
      except:
         return 0
      fields=shlex.split(lines[0])
      epoch1=fields[0]
      n1=fields[1]
      fields=shlex.split(lines[1])
      epoch2=fields[0]
      return (fields[1])
   def getColumn(self,n=0):
      lines=self.readText().splitlines()
      col=[]
      name=lines[0].split()[n]
      for line in lines:
         col.append(line.split()[n])
      return col[2:],name
   def getTable(self):
      lines=self.readText().splitlines()
      keys=lines[0].split()
      table={}
      def num(s):
         try:
            return int(s)
         except ValueError:
            return float(s)
      for key in keys:
         table[key]=[]
      for line in lines:
         fields=line.split()
         for i in range(0,len(keys)):
            try:
               value=num(fields[i])
               table[keys[i]].append(value)
            except:
               pass
      return table
   def readText(self):
      with open(self.fullname, 'r+') as fin:
         cont=fin.read()
      return cont
   def read_old(self):
      '''
      Method read() reads the statistics if it exists. It sets local variable dT storing the time differential between two intervals of simulation (outer loops). It also stores last simulation loop and the start of the run.
      '''
      if(self.exists()):
      #   epoch1=0
      #   epoch2=0
      #   n1=0
      #   n2=0
         nlines=self.mapcount()
         if nlines<2:
            return(False)
         try:
            with open(self.fullname, "r+") as fin:
               i=0;
               for line in fin:
                  if(i==1):
                     #print (line)
                     fields=shlex.split(line)
                     epoch1=fields[0]
                     n1=fields[1]
                  if(i==nlines-1):
                     fields=shlex.split(line)
                     epoch2=fields[0]
                     n2=fields[1]
                  i=i+1
         except:
            #print("Cannot read statistics file in "+self.fullname+"\n")
            return(False)
      else:
         #print("File "+self.fullname+" does not exists.\n")
         return(False)
      try:
         self.dT=(int(epoch2)-int(epoch1))/(int(n2)-int(n1))
      except:
         self.dT=0
      self.last=n2
      self.startDate=epoch1
      return(True)
   def __str__(self):
      '''
@@ -366,6 +370,13 @@
      else:
         return False
   def getStartTime(self):
      try:
         return os.path.getmtime(os.path.join(self.Dir.fullpath(),'.lock'))
      except:
         return -1
   def getStatus(self):
      pid=self.getPID()
      if(self.isCompleted()):
@@ -381,7 +392,7 @@
         else:
            procname=proc.name
            procstat=proc.status
         if procname=="trisurf":
         if procname=="tssystem":
            if procstat=="stopped":
               return TS_STOPPED
            else:
@@ -394,7 +405,7 @@
   def start(self):
      if(self.getStatus()==0 or self.getStatus()==TS_COMPLETED):
         #check if executable exists
         if(shutil.which('trisurf')==None):
         if(shutil.which('tssystem')==None):
            print("Error. Trisurf executable not found in PATH. Please install trisurf prior to running trisurf manager.")
            exit(1)
#Symlinks tape file to the directory or create tape file from snapshot in the direcory...
@@ -434,13 +445,13 @@
            else:
               initSnap=lastVTU
               print("WARNING: Not using initial snapshot as starting point, but selecting "+initSnap+" as a starting vesicle")
            params=["trisurf", "--restore-from-vtk",initSnap]+self.runArgs
            params=["tssystem", "--restore-from-vtk",initSnap]+self.runArgs
            print("InitSnap is: "+initSnap)
         else:
            #veify if dump exists. If not it is a first run and shoud be run with --force-from-tape
            if(os.path.isfile("dump.bin")==False):
               self.runArgs.append("--force-from-tape")
            params=["trisurf"]+self.runArgs
            params=["tssystem"]+self.runArgs
         subprocess.Popen (params, stdout=subprocess.DEVNULL)
         cwd.goto()
      else:
@@ -451,12 +462,12 @@
   def setMaindir(self,prefix,variables):
      maindir=""
      for p,v in zip(prefix,variables):
         if(v=="xk0"):
            tv=str(round(float(self.Tape.config[v])))
            if sys.version_info<(3,0):
               tv=str(int(float(self.Tape.config[v])))
         else:
            tv=self.Tape.config[v]
         #if(v=="xk0"):
         #   tv=str(round(float(self.Tape.config[v])))
         #   if sys.version_info<(3,0):
         #      tv=str(int(float(self.Tape.config[v])))
         #else:
         tv=str(self.Tape.config[v])
         maindir=maindir+p+tv
      self.maindir=maindir
      return
@@ -469,8 +480,8 @@
      self.Comment=FileContent(os.path.join(self.Dir.fullpath(),".comment"))
      pid=self.getPID()
      status=self.getStatus()
      if(self.Statistics.fileOK):
         ETA=str(datetime.timedelta(microseconds=(int(self.Tape.config['iterations'])-int(self.Statistics.last))*self.Statistics.dT)*1000000)
      if(self.Statistics.checkFileValidity()):
         ETA=str(datetime.timedelta(microseconds=(int(self.Tape.config['iterations'])-int(self.Statistics.getLastIterationInStatistics()))*self.Statistics.getSimulationDeltaTime())*1000000)
      if(status==TS_NONEXISTANT or status==TS_NOLOCK):
         statustxt="Not running"
         pid=""
@@ -485,8 +496,8 @@
      else:
         statustxt="Running"
      if(self.Statistics.fileOK):
         report=[time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(self.Statistics.startDate))),ETA, statustxt, pid, str(self.Dir.fullpath()), self.Comment.getText()]
      if(self.Statistics.checkFileValidity()):
         report=[time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(self.getStartTime()))),ETA, statustxt, pid, str(self.Dir.fullpath()), self.Comment.getText()]
      else:
         report=["N/A","N/A",statustxt, pid, str(self.Dir.fullpath()), self.Comment.getText()]
      return report
@@ -505,12 +516,23 @@
      self.Comment.writefile(data,mode=mode)
   def getLastVTU(self):
   def getLastVTUold(self):
      vtuidx=self.getLastIteration()-int(self.Tape.getValue("inititer"))
      if vtuidx<0:
         return None
      else:
         return  'timestep_{:06d}.vtu'.format(vtuidx)
   def getLastVTU(self):
      flist=[]
      for file in os.listdir(self.Dir.fullpath()):
         if file.endswith(".vtu"):
            flist.append(file)
      flist.sort()
      if(len(flist)==0):
         return -1
      else:
         return(flist[-1])
   def __str__(self):
      if(self.getStatus()==0):
@@ -519,4 +541,5 @@
         str=" running."
      return(self.Dir.fullpath()+str)
   def __repr__(self):
      return("Instance of trisurf in "+self.Dir.fullpath())