Trisurf Monte Carlo simulator
Miha
2016-07-11 e818ba5bcc461af545665c78157be4e52252aa1c
Merge branch 'master' of https://bitbucket.org/samop/trisurf-ng

Conflicts:
src/io.c
src/timestep.c
7 files modified
6 files added
781 ■■■■ changed files
python/networkedExample.py 27 ●●●●● patch | view | raw | blame | history
python/pythonvtk.py 42 ●●●●● patch | view | raw | blame | history
python/tape 12 ●●●● patch | view | raw | blame | history
python/trisurf/Remote.py 73 ●●●●● patch | view | raw | blame | history
python/trisurf/VTKRendering.py 155 ●●●●● patch | view | raw | blame | history
python/trisurf/WebTrisurf.py 59 ●●●●● patch | view | raw | blame | history
python/trisurf/__init__.py patch | view | raw | blame | history
python/trisurf/trisurf.py 8 ●●●●● patch | view | raw | blame | history
python/trisurf/tsmgr.py 306 ●●●● patch | view | raw | blame | history
src/io.c 72 ●●●● patch | view | raw | blame | history
src/main.c 4 ●●●● patch | view | raw | blame | history
src/tape 18 ●●●● patch | view | raw | blame | history
src/timestep.c 5 ●●●●● patch | view | raw | blame | history
python/networkedExample.py
New file
@@ -0,0 +1,27 @@
from trisurf import trisurf
from trisurf import tsmgr
#Ok... Configure your keys:
#ssh-keygen
#and copy them to all the remote hosts
#ssh-copy-id -i ./ssh/id_rsa.pub username@remotehost
run2=trisurf.Runner(tape='tape')
run2.setMaindir(("N","k","V","Np","Nm"),("nshell","xk0","constvolswitch","npoly","nmono"))
run2.setSubdir("run1")
run3=trisurf.Runner(tape='tape')
run3.setMaindir(("N","k","V","Np","Nm"),("nshell","xk0","constvolswitch","npoly","nmono"))
run3.setSubdir("run2")
Runs=[run2, run3]
hosts=({'name':'natalie','address':'kabinet.penic.eu', 'runs':Runs, 'username':'samo'},
    {'name':'Hestia','address':'127.0.0.1', 'runs':Runs, 'username':'samo'})
tsmgr.start(hosts)
python/pythonvtk.py
New file
@@ -0,0 +1,42 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# by Panos Mavrogiorgos, email: pmav99 <> gmail
from vtk import *
# The source file
#file_name = "uGridEx.vtk"
file_name="timestep.vtu"
# Read the source file.
#reader = vtkUnstructuredGridReader()
reader=vtkXMLUnstructuredGridReader()
reader.SetFileName(file_name)
reader.Update() # Needed because of GetScalarRange
output = reader.GetOutput()
scalar_range = output.GetScalarRange()
# Create the mapper that corresponds the objects of the vtk file
# into graphics elements
mapper = vtkDataSetMapper()
mapper.SetInput(output)
mapper.SetScalarRange(scalar_range)
# Create the Actor
actor = vtkActor()
actor.SetMapper(mapper)
# Create the Renderer
renderer = vtkRenderer()
renderer.AddActor(actor)
renderer.SetBackground(0, 0, 0) # Set background to white
# Create the RendererWindow
renderer_window = vtkRenderWindow()
renderer_window.AddRenderer(renderer)
# Create the RendererWindowInteractor and display the vtk_file
interactor = vtkRenderWindowInteractor()
interactor.SetRenderWindow(renderer_window)
interactor.Initialize()
interactor.Start()
python/tape
@@ -1,6 +1,6 @@
####### Vesicle definitions ###########
# nshell is a number of divisions of dipyramid
nshell=5
nshell=10
# dmax is the max. bond length (in units l_min)
dmax=1.7
# dmin_interspecies in the min. dist. between different vertex species (in units l_min)
@@ -17,15 +17,15 @@
pressure=0.0
#Constant volume constraint (0 disable constant volume, 1 enable wiht additional vertex move, 2 enable with epsvol)
constvolswitch=2
constvolswitch=0
constvolprecision=1e-14
#Constant area constraint (0 disable constant area, 2 enable constant area with epsarea)
constareaswitch=2
constareaswitch=0
####### Polymer (brush) definitions ###########
# npoly is a number of polymers attached to npoly distinct vertices on vesicle
npoly=2
npoly=60
# nmono is a number of monomers in each polymer
nmono=10
# Spring constant between monomers of the polymer
@@ -55,7 +55,7 @@
mcsweeps=200
#how many initial mcsweeps*inititer MC sweeps before recording to disk?
#2
inititer=0
inititer=10
#how many records do you want on the disk iteration are there in a run?
#10000
iterations=100
@@ -63,7 +63,7 @@
###### Spherical harmonics ###########
# If 0 then spherical harmonics are not calculated at all.
spherical_harmonics_coefficients=21
spherical_harmonics_coefficients=0
#shut up if we are using cluster!!!
quiet=false
python/trisurf/Remote.py
New file
@@ -0,0 +1,73 @@
import paramiko
class Connection:
    def __init__(self, hostname, port=22, username=None, password=None):
        self.hostname=hostname
        self.port=port
        if(username!=None):
            self.username=username
        else:
            self.username=''
        if(password!=None):
            self.password=password
        else:
            self.password=''
        self.ssh=paramiko.SSHClient()
        self.ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
        self.connected=False
        return
    def connect(self, Timeout=5):
        if(not self.connected):
            try:
                print("Trying to connect to: "+self.username+"@"+self.hostname+":"+str(self.port)+".")
                self.ssh.connect(self.hostname, username=self.username, password=self.password, port=self.port, timeout=Timeout)
                self.connected=True
            except:
                print("Error establishing connection with "+self.username+"@"+self.hostname+":"+str(self.port)+".")
                exit(1)
        else:
            print("Already connected!")
        return
    def disconnect(self):
        if(self.connected):
            try:
                self.ssh.close()
            except:
                print("Cannot disconect. Unknown error.")
        else:
            print("Cannot disconect. Already disconnected.")
        self.connected=False
    def execute(self,command):
        if(self.connected):
            try:
                stdin,stdout,stderr=self.ssh.exec_command(command)
                output=stdout.readlines()
                errors=stderr.readlines()
            #    print(errors)
                return(output)
            except:
                print("Cannot execute remote commands")
        else:
            print("Cannot execute remote commands. Connect first.")
    def send_file(self, local, remote):
        sftp=self.ssh.open_sftp()
        sftp.put(local,remote)
        sftp.close()
    def receive_file(self,remote,local):
        sftp=self.ssh.open_sftp()
        sftp.get(remote,local)
        sftp.close()
    def mkdir_remote(self,directory):
        sftp=self.ssh.open_sftp()
        sftp.mkdir(directory)
        sftp.close()
python/trisurf/VTKRendering.py
New file
@@ -0,0 +1,155 @@
import os,sys
from . import trisurf
if sys.version_info<(3,0):
    from vtk import *
class MultiRender:
    def __init__(self,args,host):
        target_runs=getRargetRunIdxList(args)
        if target_runs==None:
            target_runs=list(range(1,len(host['runs'])+1))
        nruns=len(target_runs)
        #prepare rendering window
        self.renderer_window = vtkRenderWindow()
        self.renderer_window.AddRenderer(self.renderer)
        self.renderer_window.SetSize(1200,600)
        interactor = vtkRenderWindowInteractor()
        interactor.SetRenderWindow(self.renderer_window)
        interactor.Initialize()
         interactor.AddObserver("TimerEvent", self.RenderUpdate)
        timerIDR = interactor.CreateRepeatingTimer(1000)
        self.filename=[]
        self.renderer=[]
        i=0
        for run in target_runs:
            #for each target run calculate renderer location
            r.vtkRenderer()
            r.SetBackground(0,0,0)
            p=1.0/float(nruns)
            x1=i*p
            x2=(i+1)*p
            r.SetViewport(x1,0.0,x2,1.0)
            self.renderer.Append(r)
            self.renderer_window.AddRenderer(r)
            i=i+1
        #call Renderer object with Run, renderer
        #start endless loop of interactor
        interactor.Start()
    def lastVTU(self,run):
        Dir=trisurf.Directory(maindir=run.maindir,simdir=run.subdir)
        filename=os.path.join("./",Dir.fullpath(),run.getLastVTU())
        return filename
    def lastActorForRun(self,run):
        filename=self.lastVTU(run)
        reader=vtkXMLUnstructuredGridReader()
        reader.SetFileName(self.filename)
        reader.Update() # Needed because of GetScalarRange
        output = reader.GetOutput()
        scalar_range = output.GetScalarRange()
        mapper = vtkDataSetMapper()
        mapper.SetInput(output)
        mapper.SetScalarRange(scalar_range)
        # Create the Actor
        actor = vtkActor()
        actor.SetMapper(mapper)
        return actor
    def RenderUpdate(self, obj, event):
        i=0
        for run in runs:
            if(self.lastVTU(run)!=self.filename[i]):
                #print("updejt")
                self.renderer.RemoveActor(self.actor)
                self.renderer.RemoveActor(self.textactor)
                self.actor=self.lastActor()
                self.textactor=self.textActor()
                self.renderer.AddActor(self.actor)
                self.renderer.AddActor(self.textactor)
                self.renderer_window.Render()
            #self.render.RemoveActor(self.actor)
            i=i+1
        return
class Renderer:
    def __init__(self,args,host):
        self.host=host
        self.args=args
        self.renderer = vtkRenderer()
        self.actor=self.lastActor()
        self.textactor=self.textActor()
        self.renderer.AddActor(self.actor)
        self.renderer.AddActor(self.textactor)
        self.renderer.SetBackground(0, 0, 0) # Set background to white
        # Create the RendererWindow
        self.renderer_window = vtkRenderWindow()
        self.renderer_window.AddRenderer(self.renderer)
        self.renderer_window.SetSize(1200,600)
        self.renderer.SetViewport(0.0,0.0,0.5,1.0)
        rend=vtk.vtkRenderer()
        rend.AddActor(self.actor)
        rend.SetViewport(0.5,0.0,1.0,1.0)
        self.renderer_window.AddRenderer(rend)
# Set up a check for aborting rendering.
        # Create the RendererWindowInteractor and display the vtk_file
        interactor = vtkRenderWindowInteractor()
        interactor.SetRenderWindow(self.renderer_window)
        interactor.Initialize()
         interactor.AddObserver("TimerEvent", self.RenderUpdate)
        timerIDR = interactor.CreateRepeatingTimer(1000)
        interactor.Start()
        return
    def lastVTU(self):
        Dir=trisurf.Directory(maindir=self.host['runs'][0].maindir,simdir=self.host['runs'][0].subdir)
        filename=os.path.join("./",Dir.fullpath(),self.host['runs'][0].getLastVTU())
        return filename
    def textActor(self):
        textactor=vtkTextActor()
        textactor.SetInput(self.filename)
        tp=textactor.GetTextProperty()
        tp.SetColor(1,1,1)
        tp.SetFontSize(11)
        textactor.SetDisplayPosition(20,30)
        return textactor
    def lastActor(self):
        self.filename=self.lastVTU()
        reader=vtkXMLUnstructuredGridReader()
        reader.SetFileName(self.filename)
        reader.Update() # Needed because of GetScalarRange
        output = reader.GetOutput()
        scalar_range = output.GetScalarRange()
        mapper = vtkDataSetMapper()
        mapper.SetInput(output)
        mapper.SetScalarRange(scalar_range)
        # Create the Actor
        actor = vtkActor()
        actor.SetMapper(mapper)
        return actor
    def RenderUpdate(self, obj, event):
        if(self.lastVTU()!=self.filename):
            #print("updejt")
            self.renderer.RemoveActor(self.actor)
            self.renderer.RemoveActor(self.textactor)
            self.actor=self.lastActor()
            self.textactor=self.textActor()
            self.renderer.AddActor(self.actor)
            self.renderer.AddActor(self.textactor)
            self.renderer_window.Render()
        #self.render.RemoveActor(self.actor)
        return
python/trisurf/WebTrisurf.py
New file
@@ -0,0 +1,59 @@
import subprocess
import sys, os
if sys.version_info>=(3,0):
    from urllib.parse import urlparse
else:
    from urlparse import urlparse
import http.server
import socketserver
#Web server
class TsWEB(http.server.BaseHTTPRequestHandler):
    def do_GET(self):
        parsed_path=urlparse(self.path)
        """    message_parts = [
                'CLIENT VALUES:',
                'client_address=%s (%s)' % (self.client_address, self.address_string()),
                'command=%s' % self.command,
                'path=%s' % self.path,
                'real path=%s' % parsed_path.path,
                'query=%s' % parsed_path.query,
                'request_version=%s' % self.request_version,
                '',
                'SERVER VALUES:',
                'server_version=%s' % self.server_version,
                'sys_version=%s' % self.sys_version,
                'protocol_version=%s' % self.protocol_version,
                '',
                'HEADERS RECEIVED:',
                ]
        for name, value in sorted(self.headers.items()):
            message_parts.append('%s=%s' % (name, value.rstrip()))
        message_parts.append('')
        message = '<br>'.join(message_parts) """
        self.send_response(200)
        self.end_headers()
        self.wfile.write(b"<h1>Trisurf-ng manager web interface</h1><hr>")
        oldstdout=sys.stdout
        process=subprocess.Popen (['/usr/bin/python3', sys.argv[0], '-s', '--html'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        stdout, stderr= process.communicate()
        output=stdout.decode('ascii')
        output=output.replace('\n','<BR>')
        output=bytearray(output,'ascii')
        self.wfile.write(output)
class WebServer():
    def __init__(self, port=8000):
        http_server = socketserver.TCPServer(('', port), TsWEB)
        try:
            http_server.serve_forever()
        except KeyboardInterrupt:
            print('^C received, shutting down the web server')
            http_server.socket.close()
python/trisurf/__init__.py
python/trisurf/trisurf.py
@@ -2,7 +2,7 @@
import xml.etree.ElementTree as ET
import base64
import zlib
import io
import sys,io
import os
from itertools import islice
import mmap
@@ -350,7 +350,7 @@
        return int(status)
    def isCompleted(self):
        if (int(self.tape.getValue("iterations"))==self.getLastIteration()+1):
        if int(self.tape.getValue("iterations"))+int(self.tape.getValue("inititer"))==self.getLastIteration()+1:
            return True
        else:
            return False
@@ -443,6 +443,8 @@
        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]
            maindir=maindir+p+tv
@@ -493,7 +495,7 @@
    def getLastVTU(self):
        vtuidx=self.getLastIteration()
        vtuidx=self.getLastIteration() -int(self.tape.getValue("inititer"))
        if vtuidx<0:
            return None
        else:
python/trisurf/tsmgr.py
@@ -1,21 +1,61 @@
import sys, getopt
import argparse
import paramiko
from . import Remote
from . import trisurf
import socket
import os,sys
import tabulate
import subprocess,re
import psutil
def printHelp():
    print('Python module tsmgr accept following switches:\n')
    print('tsmgr [-n process number] [-R] [-h] [-r] [-s] [-c comment text] [-a comment text]\n')
    print('[-n process number]: number of process for which -s -r -c or -a switch apply. Should be placed before any other switch');
    print('[-R]               : raw output for -s switch');
    print('[-r]               : run process');
    print('[-s]               : process status');
    print('[-k]               : kill process');
    print('[-c comment text]  : write new comment for process');
    print('[-a comment text]  : append additional comment for process');
    print('[-h]               : print help');
#import http.server
#import socketserver
if sys.version_info>=(3,0):
    from urllib.parse import urlparse
    from . import WebTrisurf
else:
    from urlparse import urlparse
    from vtk import *
    from . import VTKRendering
#import io
#Color definitions for terminal
class bcolors:
    HEADER = '\033[95m'
    OKBLUE = '\033[94m'
    OKGREEN = '\033[92m'
    WARNING = '\033[93m'
    FAIL = '\033[91m'
    ENDC = '\033[0m'
    BOLD = '\033[1m'
    UNDERLINE = '\033[4m'
#parses Command Line Arguments and returns the list of parsed values
def ParseCLIArguments(arguments):
    parser = argparse.ArgumentParser(description='Manages (start, stop, status) multiple simulation processes of trisurf according to the configuration file.')
    parser.add_argument('proc_no', metavar='PROC_NO', nargs='*',
                help='process number at host. If hostname is not specified, localhost is assumed. If no processes are specified all processes on all hosts are assumed.')
    action_group=parser.add_mutually_exclusive_group(required=True)
    action_group.add_argument('-c','--comment',nargs=1, help='append comment to current comment')
    action_group.add_argument('--delete-comment', help='delete comment',action='store_true')
    action_group.add_argument('-k','--kill','--stop','--suspend', help='stop/kill the process', action='store_true')
    action_group.add_argument('-r','--run','--start','--continue', help='start/continue process', action='store_true')
    action_group.add_argument('-s','--status',help='print status of the processes',action='store_true')
    action_group.add_argument('-v','--version', help='print version information and exit', action='store_true')
    action_group.add_argument('--web-server', type=int,metavar="PORT", nargs=1, help='EXPERIMENTAL: starts web server and never exist.')
    action_group.add_argument('-p','--preview',help='preview last VTU shape',action='store_true')
    parser.add_argument('--force', help='if dangerous operation (killing all the processes) is requested, this flag is required to execute the operation. Otherwise, the request will be ignored.', action="store_true")
    parser.add_argument('-H', '--host', nargs=1, help='specifies which host is itended for the operation. Defauts to localhost for all operations except --status and --version, where all configured hosts are assumed.')
    parser.add_argument('--html', help='Generate HTML output', action="store_true")
    parser.add_argument('-n', nargs='+', metavar='PROC_NO', type=int, help='OBSOLETE. Specifies process numbers.')
    parser.add_argument('-R','--raw',help='print status and the rest of the information in raw format', action="store_true")
    parser.add_argument('-x','--local-only',help='do not attempt to contact remote hosts. Run all operations only on local machine',action='store_true')
    args = parser.parse_args(arguments)
    return args
#gets version of trisurf currently running
def getTrisurfVersion():
    p = subprocess.Popen('trisurf --version', shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
    lines=p.stdout.readlines()
@@ -26,67 +66,205 @@
    else:
        return "unknown version"
def start(Runs):
    argv=sys.argv[1:]
    processno=0
    raw=False
def copyConfigAndConnect(hosts):
    print("Connecting to remote hosts and copying config files, tapes and snapshots")
    for host in hosts:
        if(host['name'] !=socket.gethostname()): #if I am not the computer named in host name
    try:
        opts, args = getopt.getopt(argv,"Ra:n:hrskc:")
    except getopt.GetoptError:
        printHelp()
        sys.exit(2)
    for opt, arg in opts:
        if opt == '-R':
            raw=True
        elif opt == '-h':
            printHelp()
            sys.exit()
        elif opt == '-r':
            if processno:
                localRuns=[Runs[processno-1]]
            else:
                localRuns=Runs
            for run in localRuns:
                run.start()
        elif opt == '-s':
                username=host['username']
            except:
                username=os.getusername() #default username is current user user's name
            try:
                port=host['port']
            except:
                port=22 #default ssh port
            rm=Remote.Connection(hostname=host['address'],username=username, port=port)
            rm.connect()
            rm.send_file(__file__,'remote_control.py')
            for run in host['runs']:
                try:
                    rm.send_file(run.tapeFile,run.tapeFile)
                except:
                    pass
                try:
                    rm.send_file(run.snapshotFile,run.snapshotFile)
                except:
                    pass
            host['_conn']= rm
    # we are connected to all hosts...
    return hosts
def getTargetRunIdxList(args):
    target_runs=list(map(int,args['proc_no']))
    if len(target_runs)==0:
        #check if obsolete -n flags have numbers
        target_runs=args['n']
        if target_runs==None:
            return None
    target_runs=list(set(target_runs))
    return target_runs
def status_processes(args,host):
    target_runs=getTargetRunIdxList(args)
    if target_runs==None:
        target_runs=list(range(1,len(host['runs'])+1))
            report=[]
            i=1
            if processno:
                localRuns=[Runs[processno-1]]
            else:
                localRuns=Runs
            for run in localRuns:
                line=run.getStatistics()
    for i in target_runs:
        line=host['runs'][i-1].getStatistics()
                line.insert(0,i)
                report.append(line)
                i=i+1
            if(raw):
    if(args['raw']):
                print(report)
            else:
                print ("\n\nTrisurf running processes report\n")
                print (tabulate.tabulate(report,headers=["Run no.", "Run start time", "ETA", "Status", "PID", "Path", "Comment"], tablefmt='fancy_grid'))
        elif opt == '-n':
            processno=int(arg)
            if processno<1 or processno>len(Runs) :
                processno=0
        elif opt == '-c':
            comment = arg
            if processno:
                Runs[processno-1].writeComment(arg)
        elif opt == '-a':
            comment = arg
            if processno:
                Runs[processno-1].writeComment("\n"+arg, 'a')
        elif opt == '-k':
            if processno:
                Runs[processno-1].stop()
        if(args['html']):
            tablefmt='html'
        else:
            printHelp()
            sys.exit(2)
            tablefmt='fancy_grid'
        print(tabulate.tabulate(report,headers=["Run no.", "Run start time", "ETA", "Status", "PID", "Path", "Comment"], tablefmt=tablefmt))
    return
def run_processes(args,host):
    target_runs=getTargetRunIdxList(args)
    if target_runs==None:
        target_runs=list(range(1,len(host['runs'])+1))
    for i in target_runs:
        host['runs'][i-1].start()
    return
def kill_processes(args,host):
    target_runs=getTargetRunIdxList(args)
    if target_runs==None:
        if args['force']==True:
            target_runs=list(range(1,len(host['runs'])+1))
        else:
            print("Not stopping all processes on the host. Run with --force flag if you are really sure to stop all simulations")
            return
    for i in target_runs:
        host['runs'][i-1].stop()
    return
def comment_processes(args,host):
    target_runs=getTargetRunIdxList(args)
    if target_runs==None:
        target_runs=list(range(1,len(host['runs'])+1))
    for i in target_runs:
        host['runs'][i-1].writeComment(args['comment'][0],'a')
    print("Comment added")
    return
def delete_comments(args,host):
    target_runs=getTargetRunIdxList(args)
    if target_runs==None:
        if args['force']==True:
            target_runs=list(range(1,len(host['runs'])+1))
        else:
            print("Not deleting comments on all posts on the host. Run with --force flag if you are really sure to delete all comments")
            return
    for i in target_runs:
        host['runs'][i-1].writeComment("")
    print("Comment deleted")
    return
def start_web_server(args,host):
    print('Server listening on port {}'.format(args['web_server'][0]))
    if sys.version_info>=(3,0):
        WebTrisurf.WebServer(port=args['web_server'][0])
    else:
        print("Cannot start WebServer in python 2.7")
    exit(0)
def perform_action(args,host):
    #find which flags have been used and act upon them. -r -s -k -v -c --delete-comment are mutually exclusive, so only one of them is active
    if args['run']:
        run_processes(args,host)
    elif args['kill']:
        kill_processes(args,host)
    elif args['status']:
        status_processes(args,host)
    elif args['comment']!= None:
        comment_processes(args,host)
    elif args['delete_comment']:
        delete_comments(args,host)
    elif args['web_server']!=None:
        start_web_server(args,host)
    elif args['preview']:
        preview_vtu(args,host)
    else: #version requested
        print(getTrisurfVersion())
    return
def preview_vtu(args,host):
    #only for localhost at the moment
    if sys.version_info>=(3,0):
        print("Preview works only with python 2.7")
        exit(1)
    if host['name'] == socket.gethostname():
        VTKRendering.Renderer(args,host)
def getListOfHostConfigurationByHostname(hosts,host):
    rhost=[]
    for chost in hosts:
        if chost['name'] in host:
            rhost.append(chost)
    return rhost
def start(hosts,argv=sys.argv[1:]):
    args=vars(ParseCLIArguments(argv))
    #print(vars(args))
    #Backward compatibility... If running just on localmode, the host specification is unnecessary. Check if only Runs are specified
    try:
        test_host=hosts[0]['name']
    except:
        print("Network mode disabled. Old syntax detected.")
        host={'name':socket.gethostname(),'address':'127.0.0.1', 'runs':hosts}
        perform_action(args,host)
        exit(0)
    #find the host at which the action is attended
    if args['host']==None:
        if(args['status']==False and args['version']==False):
            hosts=getListOfHostConfigurationByHostname(hosts,socket.gethostname())
    else:
        hosts=getListOfHostConfigurationByHostname(hosts,args['host'])
    if len(hosts)==0:
        print ('Hostname "{}" does not exist in configuration file. Please check the spelling'.format(args['host'][0]))
        exit(1)
    if not args['local_only']:
            hosts=copyConfigAndConnect(hosts)
    #do local stuff:
    for host in hosts:
        if host['name'] == socket.gethostname():
            if(args['html']):
                print("Host <font color='orange'>"+host['name']+"</font> reports the following:")
            else:
                print("Host "+bcolors.WARNING+host['name']+bcolors.ENDC+" reports the following:")
            perform_action(args,host)
        elif not args['local_only']:
            output=host['_conn'].execute('python3 ./remote_control.py -x '+" ".join(argv))
            for line in output:
                print(line.replace('\n',''))
    if not args['local_only']:
        print("Closing connections to remote hosts")
        for host in hosts:
            if(host['name'] !=socket.gethostname()):
                host['_conn'].disconnect()
src/io.c
@@ -861,8 +861,8 @@
    fprintf(fh, "<?xml version=\"1.0\"?>\n<VTKFile type=\"UnstructuredGrid\" version=\"0.1\" byte_order=\"LittleEndian\" compressor=\"vtkZLibDataCompressor\">\n");
    xml_trisurf_data(fh,vesicle);
    fprintf(fh, " <UnstructuredGrid>\n");
    fprintf(fh, "<Piece NumberOfPoints=\"%u\" NumberOfCells=\"%u\">\n",vlist->n+monono*polyno+fonono*filno, blist->n+monono*polyno+filno*(fonono-1));
    fprintf(fh,"<PointData Scalars=\"vertices_idx\">\n<DataArray type=\"Int64\" Name=\"vertices_idx\" format=\"ascii\">");
    fprintf(fh, "<Piece NumberOfPoints=\"%u\" NumberOfCells=\"%u\">\n",vlist->n+monono*polyno+fonono*filno, blist->n+monono*polyno+filno*(fonono-1)+vesicle->tlist->n);
    fprintf(fh,"<PointData Scalars=\"scalars\">\n<DataArray type=\"Int64\" Name=\"scalars\" format=\"ascii\">");
       for(i=0;i<vlist->n;i++){
        fprintf(fh,"%u ",vtx[i]->idx);
    }
@@ -887,61 +887,6 @@
    }
        fprintf(fh,"</DataArray>\n");
    //here comes additional data as needed. Currently only spontaneous curvature
    fprintf(fh,"<DataArray type=\"Float64\" Name=\"spontaneous_curvature\" format=\"ascii\">");
    for(i=0;i<vlist->n;i++){
        fprintf(fh,"%.17e ",vtx[i]->c);
    }
        //polymeres
        if(poly){
            poly_idx=vlist->n;
            for(i=0;i<vesicle->poly_list->n;i++){
                for(j=0;j<vesicle->poly_list->poly[i]->vlist->n;j++,poly_idx++){
                    fprintf(fh,"%.17e ", vesicle->poly_list->poly[i]->vlist->vtx[j]->c);
                }
            }
        }
        //filaments
        if(fil){
            poly_idx=vlist->n+monono*polyno;
            for(i=0;i<vesicle->filament_list->n;i++){
                for(j=0;j<vesicle->filament_list->poly[i]->vlist->n;j++,poly_idx++){
        //    fprintf(stderr,"was here\n");
                    fprintf(fh,"%.17e ",  vesicle->filament_list->poly[i]->vlist->vtx[j]->c);
                }
            }
        }
    fprintf(fh,"</DataArray>\n");
    //here comes additional data. Energy!
    fprintf(fh,"<DataArray type=\"Float64\" Name=\"bending_energy\" format=\"ascii\">");
    for(i=0;i<vlist->n;i++){
        fprintf(fh,"%.17e ",vtx[i]->energy*vtx[i]->xk);
    }
        //polymeres
        if(poly){
            poly_idx=vlist->n;
            for(i=0;i<vesicle->poly_list->n;i++){
                for(j=0;j<vesicle->poly_list->poly[i]->vlist->n;j++,poly_idx++){
                    fprintf(fh,"%.17e ", vesicle->poly_list->poly[i]->vlist->vtx[j]->energy* vesicle->poly_list->poly[i]->k);
                }
            }
        }
        //filaments
        if(fil){
            poly_idx=vlist->n+monono*polyno;
            for(i=0;i<vesicle->filament_list->n;i++){
                for(j=0;j<vesicle->filament_list->poly[i]->vlist->n;j++,poly_idx++){
        //    fprintf(stderr,"was here\n");
                    fprintf(fh,"%.17e ",  vesicle->filament_list->poly[i]->vlist->vtx[j]->energy*  vesicle->filament_list->poly[i]->k);
                }
            }
        }
    fprintf(fh,"</DataArray>\n");
    
    fprintf(fh,"</PointData>\n<CellData>\n</CellData>\n<Points>\n<DataArray type=\"Float64\" Name=\"Koordinate tock\" NumberOfComponents=\"3\" format=\"ascii\">\n");
    for(i=0;i<vlist->n;i++){
@@ -994,17 +939,24 @@
        }
    }
    for(i=0;i<vesicle->tlist->n;i++){
        fprintf(fh,"%u %u %u\n", vesicle->tlist->tria[i]->vertex[0]->idx, vesicle->tlist->tria[i]->vertex[1]->idx, vesicle->tlist->tria[i]->vertex[2]->idx);
    }
    fprintf(fh,"</DataArray>\n<DataArray type=\"Int64\" Name=\"offsets\" format=\"ascii\">");
    for (i=2;i<(blist->n+monono*polyno+(fonono-1)*filno)*2+1;i+=2){
    fprintf(fh,"%u ",i);
    }
    for(j=i+1;j<i+3*(vesicle->tlist->n);j+=3){ //let's continue counting from where we left of
        fprintf(fh,"%u ", j);
    }
    fprintf(fh,"\n");
    fprintf(fh,"</DataArray>\n<DataArray type=\"UInt8\" Name=\"types\" format=\"ascii\">\n");
     for (i=0;i<blist->n+monono*polyno+fonono*filno;i++){
     for (i=0;i<blist->n+monono*polyno+(fonono-1)*filno;i++){
        fprintf(fh,"3 ");
    }
    for(i=0;i<vesicle->tlist->n;i++){
        fprintf(fh,"5 ");
    }
    fprintf(fh,"</DataArray>\n</Cells>\n</Piece>\n</UnstructuredGrid>\n</VTKFile>\n");
    fclose(fh);
    return TS_SUCCESS;
src/main.c
@@ -54,13 +54,13 @@
        if(fd!=NULL){
            arguments_no=fscanf(fd,"%u", &start_iteration);
            if(arguments_no==0){
                ts_fprintf(stdout,"No information of start iteration in .status file");
                ts_fprintf(stdout,"No information of start iteration in .status file\n");
                }
            fclose(fd);
            start_iteration++;
        }
        else
            ts_fprintf(stdout,"No .status file. The iteration count will start from 0");
            ts_fprintf(stdout,"No .status file. The iteration count will start from 0\n");
/* Here you should read new tape file, reassign some values in vertex from the tape and assign read tape to vesicle->tape */
//        tape=parsetape(command_line_args.tape_fullfilename);
  //      vesicle=vtk2vesicle(command_line_args.dump_from_vtk,tape);
src/tape
@@ -1,6 +1,6 @@
####### Vesicle definitions ###########
# nshell is a number of divisions of dipyramid
nshell=17
nshell=5
# dmax is the max. bond length (in units l_min)
dmax=1.7
# dmin_interspecies in the min. dist. between different vertex species (in units l_min)
@@ -25,26 +25,26 @@
####### Polymer (brush) definitions ###########
# npoly is a number of polymers attached to npoly distinct vertices on vesicle
npoly=3
npoly=0
# nmono is a number of monomers in each polymer
nmono=10
nmono=2
# Spring constant between monomers of the polymer
k_spring=800
####### Filament (inside the vesicle) definitions ###########
# nfil is a number of filaments inside the vesicle
nfil=2
nfil=0
# nfono is a number of monomers in each filament
nfono=300
nfono=3
# Persistence lenght of the filaments (in units l_min)
xi=100
####### Nucleus (inside the vesicle) ###########
# Radius of an impenetrable hard sphere inside the vesicle
R_nucleus=0
R_nucleusX=6.0
R_nucleusY=12.0
R_nucleusZ=6.0
R_nucleusX=0
R_nucleusY=0
R_nucleusZ=0
#######  Cell definitions ############
nxmax=60
nymax=60
@@ -57,7 +57,7 @@
mcsweeps=200
#how many initial mcsweeps*inititer MC sweeps before recording to disk?
#2
inititer=0
inititer=10
#how many records do you want on the disk iteration are there in a run?
#10000
iterations=100
src/timestep.c
@@ -60,11 +60,6 @@
/* RANDOM SEED SET BY CURRENT TIME */
    epochtime=get_epoch();            
    srand48(epochtime);
/*Nir Gov: randomly add spontaneous curvature for some vertices */
    for(i=0;i<20;i++){
        int b=rand() % vesicle->vlist->n;
        vesicle->vlist->vtx[b]->c=-0.5;
    }
    centermass(vesicle);
    cell_occupation(vesicle);
    vesicle_volume(vesicle); //needed for constant volume at this moment