Trisurf Monte Carlo simulator
Samo Penic
2016-03-16 9154b3cc571c2461010573f84b91fcf84830cf5a
python/trisurf/trisurf.py
@@ -5,7 +5,13 @@
import base64
import zlib
import io
import os
from itertools import islice
import mmap
import shlex
import psutil
import time
import datetime
'''
This is a trisurf instance manager written in python
@@ -18,7 +24,29 @@
'''
class FileContent:
   def __init__(self,filename):
      self.filename=filename
      self.data=""
      self.readfile()
   def readfile(self):
      try:
         with open (self.filename, "r") as myfile:
            self.data=myfile.read().replace('\n', '')
      except:
         pass
   def writefile(self, data, mode='w'):
      with open (self.filename, mode) as myfile:
         myfile.write(data)
   def getText(self):
      return self.data
   def __str__(self):
      return self.getText()
class Tape:
   '''Has all the info on the tape'''
@@ -32,7 +60,6 @@
      except:
         print("Error reading or parsing tape file!\n")
         exit(1)
   def setTape(self, string):
      self.config=configobj.ConfigObj(io.StringIO(string))
@@ -41,12 +68,130 @@
   def getValue(self,key):
      return self.config[key]
   def __str__(self):
      retval=""
      for key,val in self.config.iteritems():
         retval=retval+str(key)+" = "+str(val)+"\n"
      return retval
class Directory:
   def __init__(self, maindir=".", simdir=""):
      self.maindir=maindir
      self.simdir=simdir
      return
   def fullpath(self):
      return os.path.join(self.maindir,self.simdir)
   def exists(self):
      path=self.fullpath()
      if(os.path.exists(path)):
         return 1
      else:
         return 0
   def make(self):
      try:
         os.makedirs(self.fullpath())
      except:
         print("Cannot make directory "+self.fullpath()+"\n")
         exit(1)
      return
   def makeifnotexist(self):
      if(self.exists()==0):
         self.make()
      return
   def remove(self):
      if(self.exists()):
         try:
            os.rmdir(self.fullpath())
         except:
            print("Cannot remove directory "+self.fullpath()+ "\n")
            exit(1)
      return
   def goto(self):
      try:
         os.chdir(self.fullpath())
      except:
         print("Cannot go to directory "+self.fullpath()+"\n")
      return
class Statistics:
   def __init__(self,path,filename="statistics.csv"):
      self.path=path
      self.filename=filename
      self.fullname=os.path.join(path,filename)
      self.fileOK=self.read()
      return
   def exists(self):
      if(os.path.isfile(self.fullname)):
         return True
      else:
         return False
   def mapcount(self):
      f = open(self.fullname, "r+")
      buf = mmap.mmap(f.fileno(), 0)
      lines = 0
      readline = buf.readline
      while readline():
         lines += 1
      return lines
   def read(self):
      if(self.exists()):
         nlines=self.mapcount()
         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)
      self.dT=(int(epoch2)-int(epoch1))/(int(n2)-int(n1))
      self.last=n2
      self.startDate=epoch1
      return(True)
   def __str__(self):
      return(str(self.fullname))
class Runner:
   '''
   Class Runner consists of a single running or terminated instance of the trisurf
   '''
   def __init__(self, subdir='run0', tape='', snapshot=''):
      self.subdir=subdir
      if(tape!=''):
         self.initFromTape(tape)
      if(snapshot!=''):
         self.initFromSnapshot(snapshot)
      return
   def initFromTape(self, tape):
      self.tape=Tape()
      self.tape.readTape(tape)
@@ -61,29 +206,88 @@
      root = tree.getroot()
      tapetxt=root.find('tape')
      version=root.find('trisurfversion')
      #print("Reading snapshot made from: "+version.text)
      self.tape=Tape()
      #print(tapetxt.text)
      self.tape.setTape(tapetxt.text)
   def __init__(self, subdir='run0', tape='', snapshot=''):
      self.subdir=subdir
      if(tape!=''):
         self.initFromTape(tape)
      if(snapshot!=''):
         self.initFromSnapshot(snapshot)
      return
   def getPID(self):
      self.Dir=Directory(maindir=self.maindir,simdir=self.subdir)
      self.Dir.makeifnotexist()
      try:
         fp = open(os.path.join(self.Dir.fullpath(),'.lock'))
      except IOError as e:
         return 0 #file probably does not exist. e==2??
      pid=fp.readline()
      fp.close()
      return pid
   def getStatus(self):
      pass
      pid=self.getPID()
      if(pid==0):
         return 0
      if(psutil.pid_exists(int(pid))):
         if psutil.Process(int(pid)).name=="trisurf":
            return 1
         else:
            return 0
      else:
         return 0
   def start(self):
      pass
      if(self.getStatus()==0):
         self.Dir=Directory(maindir=self.maindir,simdir=self.subdir)
         self.Dir.makeifnotexist()
#         self.Dir.goto()
         print("Starting trisurf-ng executable at "+self.Dir.fullpath()+"\n")
      else:
         print("Process already running. Not starting\n")
      return
   def stop(self):
      pass
   def setMaindir(self,prefix,variables):
      maindir="./"
      for p,v in zip(prefix,variables):
         if(v=="xk0"):
            tv=str(round(float(self.tape.config[v])))
         else:
            tv=self.tape.config[v]
         maindir=maindir+p+tv
      self.maindir=maindir
      return
   def setSubdir(self, subdir="run0"):
      self.subdir=subdir
      return
   def getStatistics(self, statfile="statistics.csv"):
      self.Dir=Directory(maindir=self.maindir,simdir=self.subdir)
      self.statistics=Statistics(self.Dir.fullpath(), statfile)
      self.Comment=FileContent(os.path.join(self.Dir.fullpath(),".comment"))
      pid=self.getPID();
      if(self.getStatus()):
         statustxt="Running"
      else:
         statustxt="Stopped"
         pid=""
      if(self.statistics.fileOK):
#         report=time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(self.statistics.startDate)))+"\t"+str(datetime.timedelta(microseconds=(int(self.tape.config['iterations'])-int(self.statistics.last))*self.statistics.dT)*1000)+" ETA\t"+"STATUS"
         report=[time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(int(self.statistics.startDate))),str(datetime.timedelta(microseconds=(int(self.tape.config['iterations'])-int(self.statistics.last))*self.statistics.dT)*1000), statustxt, pid, str(self.Dir.fullpath()), self.Comment.getText()]
      else:
         report=["N/A","N/A\t",statustxt, pid, str(self.Dir.fullpath()), self.Comment.getText()]
      return report
   def writeComment(self, data):
      self.Dir=Directory(maindir=self.maindir,simdir=self.subdir)
      self.Comment=FileContent(os.path.join(self.Dir.fullpath(),".comment"))
      self.Comment.writefile(data,mode='w')
   def __str__(self):
      return("Running instance")
      if(self.getStatus()==0):
         str=" not running."
      else:
         str=" running."
      return(self.Dir.fullpath()+str)