diff --git a/ess/lib_tw.py b/ess/lib_tw.py
new file mode 100644
index 0000000000000000000000000000000000000000..dd0a8800da79bbbf12df59e410940a225cd60800
--- /dev/null
+++ b/ess/lib_tw.py
@@ -0,0 +1,1129 @@
+
+'''
+    Classes and functions for TraceWin
+
+    - Note for clean-up
+
+      * Old LATTICE and MATCH classes can be deleted once trajectory
+        correction is established with new classes.
+'''
+
+#---- Lib
+
+from numpy        import *
+from numpy.linalg import det
+
+from struct    import pack
+from itertools import chain
+
+from subprocess import check_output
+from os         import system
+from os.path    import isdir,isfile
+
+from lib_tw_elem import *
+
+
+
+#-------- Classes
+
+#---- Lattice and project
+
+class LATTICE:
+    '''    
+        2015.10.14
+    '''
+    def __init__(self,file_name_lat,file_name_fmap,freq=352.21,gamma=1.0):
+
+        # In case file_name_fmap is str
+        if isinstance(file_name_fmap,basestring)==True: file_name_fmap=[file_name_fmap]
+        
+        # Elem/comm class dict
+        dic_cls={'DRIFT':DRIFT,
+                 'QUAD':QUAD,'BEND':BEND,'EDGE':EDGE,'THIN_STEERING':THIN_STEERING,
+                 'GAP':GAP,'DTL_CEL':DTL_CEL,
+                 'APERTURE':APERTURE,'DIAG_POSITION':DIAG_POSITION,
+                 'STEERER':STEERER,'CHOPPER':CHOPPER,
+                 'FREQ':FREQ,'MARKER':MARKER}
+        
+        # Field map dict
+        dic_fmap={}
+        for file_name_fmap_i in file_name_fmap:
+            name_fmap='.'.join(file_name_fmap_i.split('/')[-1].split('.')[:-1])  # Remove / and extention
+            dic_fmap[name_fmap]=FIELD_MAP_DATA(file_name_fmap_i)
+
+        # Go through the lat file
+        with open(file_name_lat) as file:
+            lst=[]
+            for lin in file:
+                lin=lin.partition(';')[0]  # Remove comment
+                if lin.split()!=[]:        # Remove empty line
+                    # Split a line
+                    if ':' in lin:
+                        name=lin.partition(':')[0].split()[0 ]
+                        typ =lin.partition(':')[2].split()[0 ].upper()
+                        para=lin.partition(':')[2].split()[1:]
+                    else:
+                        name=''
+                        typ =lin.split()[0 ].upper()
+                        para=lin.split()[1:]
+                    # Map to a class
+                    if   typ == 'FIELD_MAP'   : lst.append(   FIELD_MAP(name,typ,para,dic_fmap))
+                    elif typ in dic_cls.keys(): lst.append(dic_cls[typ](name,typ,para)         )
+                    elif 'DIAG' in typ        : lst.append(        DIAG(name,typ,para)         )
+                    else                      : lst.append(        COMM(name,typ,para)         )
+                    # Break the loop
+                    if typ=='END': break
+
+        # Instances
+        self.gamma=gamma
+        self.freq =freq
+        self.lst  =lst
+        self.fmap =dic_fmap  # Maybe not needed ...
+
+        # Assign idx, idx_elem, s, freq, apt
+        self.update_idx()
+
+    def update_idx(self):
+
+        # Assign/update idx, idx_elem, s, freq
+        for i in range(len(self.lst)):
+            if i==0:
+                self.lst[0].freq=self.freq
+            if i!=0:
+                self.lst[i].idx     =self.lst[i-1].idx
+                self.lst[i].idx_elem=self.lst[i-1].idx_elem
+                self.lst[i].s       =self.lst[i-1].s
+                self.lst[i].freq    =self.lst[i-1].freq
+            self.lst[i].update_idx()
+        # Assign apt (using apt of the previous elem for diag elem)
+        for i in range(len(self.lst)):
+            try:
+                if self.lst[i].apt==None:
+                    if self.lst[i].idx_elem==0:
+                        for k in range(1,len(self.lst)):
+                            try:
+                                if self.lst[k].apt!=None:
+                                    self.lst[i].apt=self.lst[k].apt; break
+                            except: pass
+                    else:
+                        for k in range(i)[::-1]:
+                            try   : self.lst[i].apt=self.lst[k].apt; break
+                            except: pass
+            except: pass                    
+            
+    def update_gamma(self):
+
+        for i in range(len(self.lst)):
+            if i==0: self.lst[0].gamma=self.gamma
+            if i!=0: self.lst[i].gamma=self.lst[i-1].gamma
+            try   : self.lst[i].update_gamma()
+            except: pass
+
+    def update_st(self,file_name):
+        '''
+            Assign/update steerer values from "Steerer_Values.txt".
+        '''
+        # Extract BLx and BLy from the file
+        with open(file_name,'r') as file:
+            BLx={}; BLy={}
+            for lin in file:
+                lin=lin.split()[3:]
+                for i in range(len(lin)):
+                    if lin[i]==':'   : idx_elem     =int(lin[i-1])-1  # "-1" since idx=0,1,2,...
+                    if lin[i]=='BLx=': BLx[idx_elem]=float(lin[i+1])
+                    if lin[i]=='BLy=': BLy[idx_elem]=float(lin[i+1])
+                                
+        # Assign/update steerers
+        for i in range(len(self.lst)):
+            if self.lst[i].idx_elem in BLx.keys():
+                idx_elem=self.lst[i].idx_elem
+                if self.lst[i].typ=='THIN_STEERING':
+                    self.lst[i].BLx=BLx[idx_elem]
+                    self.lst[i].BLy=BLy[idx_elem]
+                if self.lst[i].typ!='THIN_STEERING':
+                    for k in range(i)[::-1]:
+                        if self.lst[k].typ=='STEERER':
+                            self.lst[k].Bx=BLx[idx_elem]/self.lst[i].L
+                            self.lst[k].By=BLy[idx_elem]/self.lst[i].L
+                            break
+            
+    def get_tw(self,file_name):
+
+        with open(file_name,'w') as file:
+            for lat_i in self.lst:
+                file.write(lat_i.get_tw()+'\n')
+
+    def get_madx(self,file_name_elem='elem.madx',file_name_seq='seq.madx'):
+
+        if self.lst[-1].gamma==1.0: self.update_gamma()  # Assign gamma, if not done yet
+        
+        with open(file_name_elem,'w') as file:
+            for lat_i in self.lst:
+                try   : print >>file,lat_i.get_madx()
+                except: pass
+
+        with open(file_name_elem,'r') as file: lst_name=[lin.split(':')[0] for lin in file]
+        with open(file_name_seq ,'w') as file: print >>file,'linac:line=('+','.join(lst_name)+');'
+
+    def get_fluka(self,file_name='elem.dat'):
+
+        if self.lst[-1].gamma==1.0: self.update_gamma()  # Assign gamma, if not done yet
+
+        with open(file_name,'w') as file:
+            for lat_i in self.lst:
+                try   : print >>file,lat_i.get_fluka()
+                except: pass
+    
+    def get_mars(self,file_name='elem.dat'):
+        
+        if self.lst[-1].gamma==1.0: self.update_gamma()  # Assign gamma, if not done yet
+
+        with open(file_name,'w') as file:
+            for lat_i in self.lst:
+                try   : print >>file,lat_i.get_mars()
+                except: pass
+
+class PROJECT:
+    '''
+        - This is for running multiple simulations 1-by-1 under 1 project.
+        - Maybe not very useful...
+    
+        2015.10.15
+    '''
+
+    def __init__(self,file_name_proj='proj.ini'):
+
+        # Instances (Add more options as needed.)
+        self.file_name_proj=file_name_proj
+        self.file_name_lat =None
+        self.path_cal      =None
+        self.seed          =None
+        self.flag_hide     =None
+
+    def exe(self):
+
+        opt_exe ='TraceWin64_noX11 '+self.file_name_proj
+        if self.file_name_lat!=None: opt_exe+=' dat_file='   +self.file_name_lat
+        if self.path_cal     !=None: opt_exe+=' path_cal='   +self.path_cal
+        if self.seed         !=None: opt_exe+=' random_seed='+self.seed
+        if self.flag_hide    !=None: opt_exe+=' hide'
+
+        ## if self.path_cal!=None:
+        ##     if isdir(self.path_cal)==False: system('mkdir '+self.path_cal)
+        
+        system(opt_exe)
+
+#---- Data related
+
+class PARTRAN:
+    '''
+        - The list not complete. Add parameters as needed.
+    
+        2015.11.24
+    '''
+    def __init__(self,file_name):
+
+        # Consts to convert phs to z.
+        mass=938.272029
+        c   =2.99792458        
+        freq=352.21
+
+        # Extract indices.
+        with open(file_name) as file:
+            for lin in file.readlines():
+                lin=lin.split()
+                if lin[0]=='####':
+                    idx_s   =lin.index("z(m)"   ); idx_gamma=lin.index("gama-1")
+                    idx_x   =lin.index("x0"     ); idx_y    =lin.index("y0"    );                              idx_phs =lin.index("p0"   )
+                    idx_sigx=lin.index("SizeX"  ); idx_sigy =lin.index("SizeY" ); idx_sigz=lin.index("SizeZ"); idx_sigp=lin.index("SizeP")
+                    idx_alfx=lin.index("sxx'"   ); idx_alfy =lin.index("syy'"  ); idx_alfz=lin.index("szdp" )
+                    idx_epsx=lin.index("ex"     ); idx_epsy =lin.index("ey"    ); idx_epsz=lin.index("ezdp" ); idx_epsp=lin.index("ep"   )
+                    idx_halx=lin.index("hx"     ); idx_haly =lin.index("hy"    );                              idx_halp=lin.index("hp"   )
+                    idx_loss=lin.index("Powlost")
+                    break
+        
+        # Extract data.
+        with open(file_name) as file:
+            data=[]; flag=0
+            for lin in file.readlines():
+                lin=lin.split()
+                if flag  ==1     : data.append(map(float,lin))
+                if lin[0]=='####': flag=1
+            data=array(data).transpose()
+
+        # Instances
+        self.s   =data[idx_s   ]
+        self.x   =data[idx_x   ]; self.y   =data[idx_y   ];                           self.phs =data[idx_phs ]
+        self.sigx=data[idx_sigx]; self.sigy=data[idx_sigy]; self.sigz=data[idx_sigz]; self.sigp=data[idx_sigp]        
+        self.epsx=data[idx_epsx]; self.epsy=data[idx_epsy]; self.epsz=data[idx_epsz]; self.epsp=data[idx_epsp]
+        self.halx=data[idx_halx]; self.haly=data[idx_haly]; self.halz=data[idx_halp]; self.halp=data[idx_halp]
+        self.loss=data[idx_loss]
+
+        # Additional instances
+        self.gamma= data[idx_gamma]+1.0
+        self.beta = sqrt(1.0-1.0/self.gamma**2)
+        self.z    =-self.phs*self.beta*(c/freq*1e5)/360.0
+        self.betx = self.sigx**2/self.epsx*self.beta*self.gamma
+        self.bety = self.sigy**2/self.epsy*self.beta*self.gamma
+        self.betz = self.sigz**2/self.epsz*self.beta*self.gamma**3
+        self.betp = self.sigp**2/self.epsp
+        self.alfx =-data[idx_alfx]/self.epsx*self.beta*self.gamma
+        self.alfy =-data[idx_alfy]/self.epsy*self.beta*self.gamma
+        self.alfz =-data[idx_alfz]/self.epsz*self.beta*self.gamma**3
+        self.alfp =-self.alfz
+        
+        # Convert to list (not necessary?)
+        self.s   =self.s.tolist()   ; self.gamma=self.gamma.tolist(); self.beta=self.beta.tolist()
+        self.x   =self.x.tolist()   ; self.y    =self.y.tolist()    ; self.z   =self.z.tolist()   ; self.phs =self.phs.tolist()
+        self.sigx=self.sigx.tolist(); self.sigy =self.sigy.tolist() ; self.sigz=self.sigz.tolist(); self.sigp=self.sigp.tolist()
+        self.betx=self.betx.tolist(); self.bety =self.bety.tolist() ; self.betz=self.betz.tolist(); self.betp=self.betp.tolist()
+        self.alfx=self.alfx.tolist(); self.alfy =self.alfy.tolist() ; self.alfz=self.alfz.tolist(); self.alfp=self.alfp.tolist()
+        self.epsx=self.epsx.tolist(); self.epsy =self.epsy.tolist() ; self.epsz=self.epsz.tolist(); self.epsp=self.epsp.tolist()
+        self.halx=self.halx.tolist(); self.haly =self.haly.tolist() ; self.halz=self.halz.tolist(); self.halp=self.halp.tolist()
+        self.loss=self.loss.tolist()
+        
+    def loss_den(self,file_name_dt,dlt_dt=5e-6):
+
+        return loss_elem2den(self.s,self.loss,file_name_dt,dlt_dt)
+
+class DST:
+    '''
+        Class for a TraceWin's .dst file.
+    
+        - TraceWin seems using beta and gamma for each particle
+          so the conversion to (z,z') is based on this assumption.
+        
+        2015.10.06
+    '''
+    def __init__(self,file_name,unit_x='cm',unit_px='rad',unit_z='rad',unit_pz='MeV'):
+
+        # Const
+        c=2.99792458
+
+        # Read the file
+        with open(file_name) as file:
+            dummy=fromfile(file,dtype= uint8 ,count=2      )
+            Nptcl=fromfile(file,dtype= uint32,count=1      )[0]
+            Ibeam=fromfile(file,dtype=float64,count=1      )[0]
+            freq =fromfile(file,dtype=float64,count=1      )[0]
+            dummy=fromfile(file,dtype= uint8 ,count=1      )
+            x    =fromfile(file,dtype=float64,count=Nptcl*6).reshape(Nptcl,6).transpose()
+            mass =fromfile(file,dtype=float64,count=1      )[0]
+        
+        # Adjust units
+        gamma=1.0+x[5]/mass; beta=sqrt(1-1/gamma**2)
+        if unit_x =='mm'  : x[0]= x[0]*1e1; x[2]=x[2]*1e1
+        if unit_px=='mrad': x[1]= x[1]*1e3; x[3]=x[3]*1e3
+        if unit_z =='deg' : x[4]= x[4]*180/pi
+        if unit_z =='mm'  : x[4]=-x[4]*c*beta/(2*pi*freq)*1e5
+        if unit_pz=='mrad': x[5]=(x[5]-mean(x[5]))/(mass*beta**2*gamma**3)*1e3
+
+        # Instances
+        self.x    =x.transpose()        
+        self.mass =mass
+        self.freq =freq
+        self.Ibeam=Ibeam
+
+class DENSITY:
+    '''
+        - Note instances are not identical for Nrun=1 and Nrun>1.
+        - Be careful with # of steps for an envelope file.
+        - When Nrun>1, ave and rms in a file are sum and squared sum.
+        - Double check before a production !!!!
+        - Dim of arrays:
+
+          Nelem(Nidx): idx_elem, s, Nptcl, Ibeam
+
+          2 x Nelem(Nidx): apt                         # x, y
+          3 x Nelem(Nidx): accpt                       # phs+, phs-, ken
+          7 x Nelem(Nidx): cent_(..), sig, xmax, xmin  # x, y, phs, ken, r, z, dpp
+          3 x Nelem(Nidx): eps                         # x, y, phs
+
+          Nrun x Nelem: loss
+          Nelem       : loss_num_(..), loss_pow_(..)
+          
+          Nelem x Nstep: den          
+          
+        2015.11.12
+    '''
+    def __init__(self,file_name):
+
+        #-- Empty arrays
+        
+        idx_elem    =[]; s           =[]
+        apt         =[]; accpt       =[]
+        Nptcl       =[]; Ibeam       =[]
+        cent_ave    =[]; cent_rms    =[]
+        cent_max    =[]; cent_min    =[]
+        sig_ave     =[]; sig_rms     =[]
+        eps_ave     =[]; eps_rms     =[]
+        xmax        =[]; xmin        =[]
+        loss_num    =[]; loss_pow    =[]
+        loss_num_ave=[]; loss_pow_ave=[]
+        loss_num_rms=[]; loss_pow_rms=[]
+        loss_num_max=[]; loss_pow_max=[]
+        loss_num_min=[]; loss_pow_min=[]
+        den         =[]; den_pow     =[]
+        
+        #-- Extract data
+                
+        with open(file_name) as file:
+            while True:
+                try:
+                    # Partran and envelope
+                    ver,year,flag_long=fromfile(file,dtype=uint16,count=3)
+                    Nrun              =fromfile(file,dtype=uint32,count=1)[0]
+                    idx_elem.append(fromfile(file,dtype= uint32,count=1)[0])
+                    Ibeam.append(fromfile(file,dtype=float32,count=1)[0])
+                    s.append(    fromfile(file,dtype=float32,count=1)[0])
+                    apt.append(  fromfile(file,dtype=float32,count=2)   )
+                    Nstep=fromfile(file,dtype=uint32,count=1)[0]
+                    cent_ave.append(fromfile(file,dtype=float32,count=7))
+                    cent_rms.append(fromfile(file,dtype=float32,count=7))
+                    xmax.append(    fromfile(file,dtype=float32,count=7))
+                    xmin.append(    fromfile(file,dtype=float32,count=7))
+                    if ver> 5:
+                        sig_ave.append(fromfile(file,dtype=float32,count=7))
+                        sig_rms.append(fromfile(file,dtype=float32,count=7))
+                    if ver>=6:
+                        cent_min.append(fromfile(file,dtype=float32,count=7))
+                        cent_max.append(fromfile(file,dtype=float32,count=7))
+                    if ver>=7:
+                        eps_ave.append(fromfile(file,dtype=float32,count=3))
+                        eps_rms.append(fromfile(file,dtype=float32,count=3))
+                    if ver>=8:
+                        accpt.append(fromfile(file,dtype=float32,count=3))
+                    Nptcl.append(fromfile(file,dtype=uint64,count=1)[0])
+                    # Partran only
+                    if Nptcl[-1]>0:
+                        loss_num.append([]); loss_pow.append([]); den.append([]); den_pow.append([])
+                        for n in range(Nrun):
+                            loss_num[-1].append(fromfile(file,dtype= uint64,count=1)[0])
+                            loss_pow[-1].append(fromfile(file,dtype=float32,count=1)[0])
+                        loss_num_ave.append(sum(loss_num[-1]))
+                        loss_num_rms.append(fromfile(file,dtype= uint64,count=1)[0])
+                        loss_num_min.append(fromfile(file,dtype= uint64,count=1)[0])
+                        loss_num_max.append(fromfile(file,dtype= uint64,count=1)[0])
+                        loss_pow_ave.append(sum(loss_pow[-1]))                        
+                        loss_pow_rms.append(fromfile(file,dtype=float64,count=1)[0])
+                        loss_pow_min.append(fromfile(file,dtype=float32,count=1)[0])
+                        loss_pow_max.append(fromfile(file,dtype=float32,count=1)[0])
+                        for k in range(7):
+                            if flag_long==1: den[-1].append(fromfile(file,dtype=uint64,count=Nstep))
+                            else           : den[-1].append(fromfile(file,dtype=uint32,count=Nstep))
+                        if Ibeam[-1]>0:
+                            for k in range(3):
+                                den_pow[-1].append(fromfile(file,dtype=float32,count=Nstep))
+                    #print Nrun,Nptcl[-1],idx_elem[-1]  # Diag
+                except:
+                    break
+
+        #-- Reshape arrays
+
+        apt     =swapaxes(     apt,1,0); accpt   =swapaxes(   accpt,1,0)
+        cent_ave=swapaxes(cent_ave,1,0); cent_rms=swapaxes(cent_rms,1,0)
+        cent_max=swapaxes(cent_max,1,0); cent_min=swapaxes(cent_min,1,0)
+        sig_ave =swapaxes( sig_ave,1,0); sig_rms =swapaxes( sig_rms,1,0)
+        eps_ave =swapaxes( eps_ave,1,0); eps_rms =swapaxes( eps_rms,1,0)
+        xmax    =swapaxes(    xmax,1,0); xmin    =swapaxes(    xmin,1,0)
+        if Nptcl[0]>0:
+            loss_num=swapaxes(loss_num,1,0); loss_pow=swapaxes(loss_pow,1,0)
+            den     =swapaxes(     den,1,0); den_pow =swapaxes( den_pow,1,0)
+        
+        #-- Take care ave and rms
+
+        cent_ave=cent_ave/Nrun; cent_rms=sqrt(cent_rms/Nrun)
+        sig_ave = sig_ave/Nrun; sig_rms =sqrt( sig_rms/Nrun)        
+        eps_ave = eps_ave/Nrun; eps_rms =sqrt( eps_rms/Nrun)
+        if Nptcl[0]>0:
+            loss_num_ave=1.0*array(loss_num_ave)/Nrun; loss_num_rms=sqrt(1.0*array(loss_num_rms)/Nrun)
+            loss_pow_ave=    array(loss_pow_ave)/Nrun; loss_pow_rms=sqrt(    array(loss_pow_rms)/Nrun)
+
+        #-- Change units, m => mm, pi-m-rad => pi-mm-mrad
+            
+        apt    *=1e3
+        eps_ave*=1e6; eps_rms*=1e6
+        for k in (0,1,4,5):
+            cent_ave[k]*=1e3; cent_rms[k]*=1e3
+            cent_max[k]*=1e3; cent_min[k]*=1e3
+            sig_ave[k] *=1e3; sig_rms[k] *=1e3
+            xmax[k]    *=1e3; xmin[k]    *=1e3
+
+        #-- Define std (around to avoid sqrt(-eps))
+        
+        if Nrun>1:
+            cent_std=sqrt(around(cent_rms**2-cent_ave**2,12))
+            sig_std =sqrt(around( sig_rms**2- sig_ave**2,12))
+            eps_std =sqrt(around( eps_rms**2- eps_ave**2,12))
+            cent_std=nan_to_num(cent_std)  # Replace nan with 0
+            sig_std =nan_to_num( sig_std)  # Replace nan with 0
+            eps_std =nan_to_num( eps_std)  # Replace nan with 0
+            if Nptcl[0]>0:
+                loss_num_std=sqrt(around(loss_num_rms**2-loss_num_ave**2,16))
+                loss_pow_std=sqrt(around(loss_pow_rms**2-loss_pow_ave**2,16))
+                loss_num_std=nan_to_num(loss_num_std)  # Replace nan with 0
+                loss_pow_std=nan_to_num(loss_pow_std)  # Replace nan with 0
+        
+        #-- Convert to list (just in case...)
+
+        apt     =     apt.tolist(); accpt   =   accpt.tolist(); accpt.append(accpt[0]); del accpt[0]
+        cent_ave=cent_ave.tolist(); cent_rms=cent_rms.tolist()
+        cent_max=cent_max.tolist(); cent_min=cent_min.tolist()
+        sig_ave = sig_ave.tolist(); sig_rms = sig_rms.tolist()
+        eps_ave = eps_ave.tolist(); eps_rms = eps_rms.tolist()
+        xmax    =    xmax.tolist(); xmin=xmin.tolist()
+        if Nptcl[0]>0:
+            loss_num    =    loss_num.tolist(); loss_pow    =    loss_pow.tolist()
+            loss_num_ave=loss_num_ave.tolist(); loss_pow_ave=loss_pow_ave.tolist()
+            loss_num_rms=loss_num_rms.tolist(); loss_pow_rms=loss_pow_rms.tolist()
+            den         =         den.tolist(); den_pow     =     den_pow.tolist()
+
+        if Nrun>1:
+            cent_std=cent_std.tolist()
+            sig_std = sig_std.tolist()
+            eps_std = eps_std.tolist()
+            if Nptcl[0]>0:
+                loss_num_std=loss_num_std.tolist()
+                loss_pow_std=loss_pow_std.tolist()                
+
+        #-- Outputs
+        
+        self.idx_elem=idx_elem
+        self.s       =s
+        self.apt     =apt
+        self.accpt   =accpt
+        self.Nptcl   =Nptcl
+        self.Ibeam   =Ibeam
+        
+        self.Nrun =Nrun
+        self.Nstep=Nstep
+        
+        if Nrun==1:
+            self.cent=cent_ave
+            self.sig = sig_ave
+            self.eps = eps_ave
+            self.xmax=    xmax
+            self.xmin=    xmin
+            if Nptcl[0]>0:
+                self.loss_num=loss_num[0]; self.loss_pow=loss_pow[0]
+                self.den     =        den; self.den_pow =    den_pow
+        else:
+            self.cent_ave=cent_ave; self.cent_rms=cent_rms; self.cent_std=cent_std
+            self.cent_max=cent_max; self.cent_min=cent_min
+            self.sig_ave = sig_ave; self.sig_rms = sig_rms; self.sig_std = sig_std
+            self.eps_ave = eps_ave; self.eps_rms = eps_rms; self.eps_std = eps_std
+            self.xmax    =    xmax; self.xmin    =    xmin
+            if Nptcl[0]>0:
+                self.loss_num    =loss_num    ; self.loss_pow    =loss_pow
+                self.loss_num_ave=loss_num_ave; self.loss_pow_ave=loss_pow_ave
+                self.loss_num_rms=loss_num_rms; self.loss_pow_rms=loss_pow_rms
+                self.loss_num_std=loss_num_std; self.loss_pow_std=loss_pow_std                
+                self.loss_num_max=loss_num_max; self.loss_pow_max=loss_pow_max
+                self.loss_num_min=loss_num_min; self.loss_pow_min=loss_pow_min
+                self.den         = den        ; self.den_pow     = den_pow
+
+        #-- Option outputs
+
+        self.idx_4_elem_end=[len(idx_elem)-1-idx_elem[::-1].index(i) for i in list(set(idx_elem))]
+
+#-------- Functions
+
+#---- Dist related
+
+def x2dst(x,mass,freq,Ibeam,path_file='part_dtl1_new.dst'):
+    '''
+        Output a TraceWin's .dst file from x and etc.
+    
+        Input: x (Nptcl,6)
+
+        For binary characters see https://docs.python.org/2/library/struct.html
+
+        2014.10.03
+    '''
+    
+    file=open(path_file,'w')
+    out =pack('b',125)
+    out+=pack('b',100)
+    out+=pack('i',len(x))
+    out+=pack('d',Ibeam)
+    out+=pack('d',freq)
+    out+=pack('b',125)  # Typo in the manual !!!!
+    x=list(chain(*x))   # Flatten x
+    for x_i in x: out+=pack('d',x_i)
+    out+=pack('d',mass)
+    print >>file,out    
+    file.close()
+    
+def plt2x(path_file):
+    '''
+        Extract x and etc from a TraceWin's binary .plt file.
+        The units are (cm,rad,cm,rad,rad,MeV,loss).
+                
+        Output: x (Nelem,Nptcl,7)
+
+        For binary characters see https://docs.python.org/2/library/struct.html
+
+        2014.10.06
+    '''
+    
+    file=open(path_file,'r')
+    
+    # Hetero info
+    file.read(1); file.read(1)  # 125,100
+    Nelem=unpack('i',file.read(4))[0]
+    Nptcl=unpack('i',file.read(4))[0]
+    Ibeam=unpack('d',file.read(8))[0]
+    freq =unpack('d',file.read(8))[0]
+    mass =unpack('d',file.read(8))[0]
+    
+    # Loop for elem
+    x=[]; i_unk=[]; i_elem=[]; s=[]; phs=[]; ken=[];    
+    for i in range(Nelem):
+        try:
+            i_unk.append(unpack('b',file.read(1))[0])
+            i_elem.append(unpack('i',file.read(4))[0])
+            s.append(unpack('d',file.read(8))[0])
+            phs.append(unpack('d',file.read(8))[0])
+            ken.append(unpack('d',file.read(8))[0])
+            x.append([[unpack('f',file.read(4))[0] for l in range(7)] for k in range(Nptcl)])
+        except:
+            break
+
+    file.close()    
+
+    return x,mass,freq,Ibeam,i_unk,i_elem,s,phs,ken
+
+def x2plt(x,mass,freq,Ibeam,i_unk,i_elem,s,phs,ken,path_file='dtl1_new.plt'):
+    '''
+        Output a TraceWin's .plt file from x and etc.
+
+        Input: x (Nelem,Nptcl,7)
+
+        For binary characters see https://docs.python.org/2/library/struct.html
+        
+        2014.10.07
+    '''
+    
+    file=open(path_file,'w')
+    out =pack('b',125)
+    out+=pack('b',100)
+    out+=pack('i',len(x))
+    out+=pack('i',len(x[0]))
+    out+=pack('d',Ibeam)
+    out+=pack('d',freq)
+    out+=pack('d',mass)
+    for i in range(len(x)):
+        out+=pack('b',i_unk[i])
+        #out+=pack('i',i_elem[i])
+        out+=pack('i',i)  # To truncate the elem number
+        out+=pack('d',s[i])
+        out+=pack('d',phs[i])
+        out+=pack('d',ken[i])
+        x_i=list(chain(*x[i]))
+        for x_ik in x_i: out+=pack('f',x_ik)
+    print >>file,out
+    file.close()
+
+#---- Data related
+    
+def x2twiss(x):
+    '''
+        Calculate twiss from x. Note sig = sqrt(bet*eps).
+        
+        Input : x (Nptcl,6)
+        Output: eps,bet,alf,gam
+
+        2015.07.30
+    '''
+        
+    x  =[x_i-mean(x_i) for x_i in array(x).transpose()]
+    sig=[[mean(x_i*x_k) for x_k in x] for x_i in x]
+    eps=[ sqrt(det(array(sig)[i:i+2][:,i:i+2])) for i in (0,2,4)]
+    bet=[ sig[i  ][i  ]/eps[i/2]                for i in (0,2,4)]
+    alf=[-sig[i  ][i+1]/eps[i/2]                for i in (0,2,4)]
+    gam=[ sig[i+1][i+1]/eps[i/2]                for i in (0,2,4)]
+
+    return eps,bet,alf,gam
+
+def x2twiss_halo(x,sig_cut=(None,None,None)):
+    '''
+        Calculate twiss of halo particles (r > sig_cut).
+        Note halo particles are different for each plane.
+        
+        Input : x (Nptcl,6), sig_cut
+        Output: eps,bet,alf,gam
+
+        2015.07.30
+    '''
+    
+    eps,bet,alf,gam=x2twiss(x)
+    for k in (0,2,4):
+        if sig_cut[k/2]!=None:
+            x=x.transpose();
+            r_nom_sq=(x[k]**2+(alf[k/2]*x[k]+bet[k/2]*x[k+1])**2)/(bet[k/2]*eps[k/2])
+            x=x.transpose();
+            x_halo=[x[i] for i in range(len(x)) if r_nom_sq[i]>sig_cut[k/2]**2]
+            eps_tmp,bet_tmp,alf_tmp,gam_tmp=x2twiss(x_halo)
+            eps[k/2]=eps_tmp[k/2]
+            bet[k/2]=bet_tmp[k/2]
+            alf[k/2]=alf_tmp[k/2]
+            gam[k/2]=gam_tmp[k/2]
+
+    return eps,bet,alf,gam
+    
+def loss_elem2den(s,loss,path_file_dt,dlt_dt=5e-6):
+    '''
+        This function calculates loss density [W/m] from s, loss,
+        and the file of the DTL's cell and DT lengths.
+
+        2015.01.30
+    '''
+    # Define l
+    l=[s[i+1]-s[i] for i in range(len(s)-1)]; l.insert(0,0.0)
+    
+    # DTL cell and DT lengths.
+    file=open(path_file_dt)
+    l_cell,l_dt=array([map(float,lin.split()) for lin in file.readlines()]).transpose()[:2]
+    file.close()
+        
+    # Replace l's in DTL with DT lengths.
+    Ndt=0
+    for i in range(len(l)):
+        dl=list(abs(l_cell-l[i])); dl_min=min(dl)
+        if dl_min<dlt_dt:
+            l[i]=l_dt[dl.index(dl_min)]; Ndt+=1
+
+    # Check the replacement.
+    if Ndt!=len(l_cell):
+        print 'drift-tube # unmatched, in file: '+str(len(l_cell))+', from matching: '+str(Ndt)
+        print 'review the threshold, exiting...'; exit()
+
+    # Treat inf loss den.
+    for i in range(len(l)):
+        if l[i]==0.0 and loss[i]!=0.0:
+            if i==1:
+                print 'The 1st elem has 0 length and yet has a loss, exiting...'; exit()
+            else:
+                k=1
+                while l[i-k]==0.0: k+=1
+                loss[i-k]+=loss[i]; loss[i]=0.0
+                print 'Caution: Inf loss density at elem #',i,'!!!!'
+                
+    # Finally, convert to loss density.
+    loss_den=[]
+    for i in range(len(l)):
+        if loss[i]==0.0: loss_den.append(0.0)
+        else           : loss_den.append(loss[i]/l[i])
+        
+    return loss_den
+
+def partran_end_all(file_name_in_all,file_name_out):
+    '''
+        - Reads multiple partran1.out files and extracts the data at the end.
+        - The same format as partran1.out allows to be used by PARTRAN class.
+        - The elem # is replaced with the file #.
+
+        2015.11.25
+    '''
+    
+    # Extract header from 1 file.
+    with open(file_name_in_all[0],'r') as file:
+        header=''
+        for lin in file.readlines():
+            header+=lin
+            if lin.split()[0]=='####': break
+
+    # Extract output data for each file and write.
+    with open(file_name_out,'w') as file_out:
+        file_out.write(header)
+        for i in range(len(file_name_in_all)):
+            lin=check_output(['tail','-1',file_name_in_all[i]]).split()
+            # Replace elem # with file #.
+            file_out.write('%5s'%str(i))
+            # Just to maintain the same format as partran1.out. Maybe too much...
+            for i in range(1,len(lin)):
+                if '.' in lin[i]: file_out.write(' %13s'%lin[i])
+                else            : file_out.write(' %10s'%lin[i])
+            file_out.write('\n')      
+
+#-------- Obsolete classes and functions
+
+#---- Old MATCH and LATTICE classes from the time of IPAC'15 (more complex)
+
+## class MATCH:
+##     '''
+##         Class for matching. Could be revised.
+
+##         2015.04.26
+##     '''
+##     def __init__(self,typ):
+        
+##         # Instances
+##         self.typ   =typ  # Need typ_knob and etc ??
+##         self.i_diag=[]
+##         self.i_knob=[]
+
+##         # Instances for 'TRAJ'
+##         self.Rx_inv=None
+##         self.Ry_inv=None        
+        
+## class LATTICE:
+##     '''
+##         Class to handle a TraceWin lattice file.
+    
+##         - For now, only for the steerer and BPM. Extend as needed.
+##         - For now, only for the MEBT. Extend as needed.
+##         - For now, reading a file for ken. Implement a method for future ??
+        
+##         2015.04.12
+##     '''
+##     def __init__(self,path_file_lat,path_file_ken):
+
+##         # Consts, need to define globally ??
+##         mass=938.2723; clight=2.99792458
+        
+##         # Some dict and list (MEBT and DTL are supported for now...)
+##         dic_class={'QUAD'          : QUAD          ,
+##                    'THIN_STEERING' : THIN_STEERING ,
+##                    'STEERER'       : STEERER       ,
+##                    'DIAG_POSITION' : DIAG_POSITION ,
+##                    'ADJUST'        : ADJUST        ,
+##                    'ADJUST_STEERER': ADJUST_STEERER}
+##         lst_elem =['DRIFT','QUAD','GAP','DTL_CEL',
+##                    'THIN_STEERING','DIAG_POSITION']
+##         lst_comm =['ADJUST','ADJUST_STEERER']
+##         lst_diag =['DIAG_POSITION']
+
+##         # Load ken from TW's "Energy(MeV).txt" (vs Nelem, starting from 0)
+##         with open(path_file_ken,'r') as file:
+##             ken=[]
+##             for lin in file:
+##                 try   : ken.append(float(lin.split()[2]))
+##                 except: pass
+##             ken.insert(0,ken[0])
+        
+##         # Go through the lat file
+##         with open(path_file_lat) as file:
+##             lst=[]; i=0; Nelem=0
+##             for lin in file:
+##                 lin=lin.partition(';')[0]  # Remove comment
+##                 if lin.split()!=[]:        # Remove empty line
+##                     # Convert an elem/comm to a class (maybe too cryptic...)
+##                     try   : lst.append(dic_class[ALLTYPE(lin).typ](lin))
+##                     except: lst.append(                    ALLTYPE(lin))
+##                     # Assign index
+##                     lst[-1].indx=i; i+=1
+##                     # Assign Nelem
+##                     if lst[-1].typ in lst_elem: Nelem+=1
+##                     lst[-1].Nelem=Nelem
+##                     # Assign gamma, beta, Brho
+##                     gamma=1.0+ken[Nelem]/mass               ; lst[-1].gamma=gamma
+##                     beta =sqrt(1.0-1.0/gamma**2)            ; lst[-1].beta =beta
+##                     Brho =(10.0/clight)*gamma*beta*mass*1e-3; lst[-1].Brho =Brho
+##                     # End at 'END'
+##                     if lst[-1].typ=='END': break
+                    
+##         # Go through lat again and define matchings, extend/modify as needed
+##         match={}
+##         for i in range(len(lst)):
+##             if lst[i].typ in lst_comm:
+##                 lst,match=lst[i].activate(lst,match)
+
+##         # Get index of diagnostics
+##         for i in range(len(lst)):
+##             if lst[i].typ in lst_diag:
+##                 try   : match[lst[i].fam].i_diag.append(i)
+##                 except: pass
+                    
+##         # Instances
+##         self.lst  =lst
+##         self.match=match
+
+##     def get_tw(self,path_file,flag_no_err=None):
+
+##         with open(path_file,'w') as file:
+##             for lst_i in self.lst:
+##                 if 'ERROR' in lst_i.typ:
+##                     if flag_no_err!=None: pass
+##                     else                : file.write(lst_i.get_tw())
+##                 else:
+##                     file.write(lst_i.get_tw())
+
+#---- Old DENSITY class for the envelope calc only
+
+## class DENSITY_ENV:
+##     '''
+##         This class is to handle Density_Env.dat.
+
+##         - For now, this is intended for an individual file and NOT "tot" file.
+##           (Something not clear between an individual file and "tot" file...)
+##         - For now, there are instances of only Nelem, s, x_ave, y_ave.
+##           (Add others when needed.)
+##         - For now, tested only for the MEBT.
+##         - Note there are much more data points than the total number of elems
+##           due to the slicing of the SC calculation. Use i_elem to extract data
+##           at the ends of elems, e.g., array(x_ave)[array(i_elem)].
+
+##         2015.03.29
+##     '''
+##     def __init__(self,path_file):
+
+##         # Go through the file
+##         Nelem=[]; s=[]; x=[]
+##         with open(path_file) as file:
+##             while True:
+##                 try:
+##                     ver=fromfile(file,dtype=uint16,count=3)[0]                  # version, year, vlong
+##                     Nelem.append(fromfile(file,dtype=uint32,count=2)[1])        # Nrun, Nelem
+##                     s.append(fromfile(file,dtype=float32,count=4)[1])           # Ibeam, s, aptx, apty
+##                     fromfile(file,dtype=uint32,count=1)                         # Nslice ??
+##                     x.append(list(fromfile(file,dtype=float32,count=7*4)[:2]))  # ave & etc
+##                     if ver>=5: fromfile(file,dtype=float32,count=7*2)           # ver >= 5 part
+##                     if ver>=6: fromfile(file,dtype=float32,count=7*2)           # ver >= 6 part
+##                     if ver>=7: fromfile(file,dtype=float32,count=3*2)           # ver >= 7 part
+##                     if ver>=8: fromfile(file,dtype=float32,count=1*3)           # ver >= 8 part
+##                     fromfile(file,dtype=uint64,count=1)                         # Nptcl
+##                 except:
+##                     break
+
+##         # Index of n-th elem end, starting from 0                
+##         i_elem=[0]
+##         for n in range(1,Nelem[-1]):
+##             k=1
+##             while True:
+##                 try   : i_elem.append(Nelem.index(n+k)-1); break
+##                 except: k+=1
+##         i_elem.append(len(Nelem)-1)
+                                
+##         # Instances
+##         self.Nelem=Nelem
+##         self.s    =s
+##         self.x    =list(1e3*array(x).transpose()[0])
+##         self.y    =list(1e3*array(x).transpose()[1])
+
+##         # Additional instances
+##         self.i_elem=i_elem
+
+#---- Lattice related functions
+
+## def clean_lat(path_file):
+
+##     '''
+##         Remove comments, names, and etc from a TraceWin file.
+##         To convert the output to str, use: [' '.join(l)+'\n' for l in lat].
+##         The current version not capitalizing.
+        
+##         Output: Lattice in a list
+
+##         2015.03.18
+##     '''
+
+##     with open(path_file) as file:
+##         lat=[]
+##         for lin in file:
+##             lin=lin.partition(';')[0]                          # Remove comment
+##             #lin=lin.upper().partition(';')[0]                 # Remove comment and capitalize
+##             if ':' in lin: lin=lin.partition(':')[-1].split()  # Remove name
+##             else         : lin=lin.split()
+##             if lin!=[]:                                        # Avoid empty line
+##                 lat.append(lin)
+##                 if lin[0].upper()=='END': break
+        
+##     return lat
+
+## def get_steerer(path_file):
+
+##     '''
+##         Extract steerer values from "Adjusted_Values.txt" of TraceWin.
+##         Note the key is the "lat elem #" where commands are not counted.
+        
+##         Output is dic of {lat elem #:[val]} or {lat elem #:[val_x,val_y]}
+
+##         2014.10.17
+##     '''
+
+##     file=open(path_file)
+##     i_elem=0; dic_steerer_val={}
+##     for lin in file.readlines():
+##         lin=lin.split()
+##         for i in range(len(lin)):
+##             if lin[i]==':':
+##                 if int(lin[i-1])!=i_elem:
+##                     i_elem=int(lin[i-1])
+##                     dic_steerer_val[i_elem]=[lin[i+1]]
+##                 else:
+##                     dic_steerer_val[i_elem].append(lin[i+1])
+##     file.close()
+
+##     return dic_steerer_val
+
+## def apply_steerer(lat,dic_steerer_val,lst_typ_elem):
+
+##     '''
+##         Apply steerer values to a TraceWin lattice.
+
+##         Input: lat from "clean_lat, steerer dic from "get_steerer", list of lat elem types
+
+##         2014.10.17
+##     '''
+
+##     #-- 
+##     i_elem=0; dic_steerer={}
+##     for i in range(len(lat)):
+##         if lat[i][0] in lst_typ_elem:
+##             i_elem+=1
+##         if lat[i][0]=='STEERER':
+##             if i_elem+1 in dic_steerer_val.keys():
+##                 if len(dic_steerer_val[i_elem+1])==2:
+##                     dic_steerer[i]=[[1,dic_steerer_val[i_elem+1][0]],[2,dic_steerer_val[i_elem+1][1]]]
+##                 else:
+##                     for k in range(i)[::-1]:
+##                         if lat[k][0]=='ADJUST_STEERER_BX':
+##                             dic_steerer[i]=[[1,dic_steerer_val[i_elem+1][0]]]; break
+##                         if lat[k][0]=='ADJUST_STEERER_BY':
+##                             dic_steerer[i]=[[2,dic_steerer_val[i_elem+1][0]]]; break
+##         if lat[i][0]=='THIN_STEERING':
+##             if i_elem in dic_steerer_val.keys():
+##                 if len(dic_steerer_val[i_elem])==2:
+##                     dic_steerer[i]=[[1,dic_steerer_val[i_elem][0]],[2,dic_steerer_val[i_elem][1]]]
+##                 else:
+##                     for k in range(i)[::-1]:
+##                         if lat[k][0]=='ADJUST' and lat[k][2]=='1':
+##                             dic_steerer[i]=[[1,dic_steerer_val[i_elem][0]]]; break
+##                         if lat[k][0]=='ADJUST' and lat[k][2]=='2':
+##                             dic_steerer[i]=[[2,dic_steerer_val[i_elem][0]]]; break
+
+##     for i in sorted(dic_steerer.keys()):
+##         for k in range(len(dic_steerer[i])):
+##             lat[i][dic_steerer[i][k][0]]=dic_steerer[i][k][1]
+
+##     return lat
+
+## def apply_multipole(lat,typ,r,b3=0.0,b4=0.0,b5=0.0,b6=0.0):
+
+##     '''
+##         Apply multipole components to quads in a TraceWin lattice file.
+##         Note all the quads in all the sections are affected in the same way.
+
+##         Input : lat from "clean_lat, reference r, b3-b6, and dist type
+##                 ("fix", "uniform", "gauss")
+
+##         2015.01.08
+##     '''
+
+##     bn=(b3,b4,b5,b6)
+
+##     for i in range(len(lat)):
+##         if lat[i][0]=='QUAD':
+            
+##             # Adjust format
+##             if len(lat[i])<5:
+##                 for k in range(5): lat[i].append('0')
+##             else:
+##                 lat[i]=lat[i][:5]
+##                 for k in range(4): lat[i].append('0')
+
+##             # Fixed value
+##             if typ=='fix':
+##                 for k in range(4):
+##                     lat[i][k+5]=str(                 bn[k]/r**(k+1)*float(lat[i][2]))
+##             # Uniform dist
+##             if typ=='uniform':
+##                 for k in range(4):
+##                     lat[i][k+5]=str((2.0*rand()-1.0)*bn[k]/r**(k+1)*float(lat[i][2]))
+##             # Gaussian dist
+##             if typ=='gauss':
+##                 for k in range(4):
+##                     lat[i][k+5]=str(         randn()*bn[k]/r**(k+1)*float(lat[i][2]))
+
+##     return lat
+
+#---- Dist related
+
+## def partran2twiss(path_file):
+
+##     '''
+##         MERGE THIS TO PARTRAN CLASS !!!!
+    
+##         Extract output Twiss and halo from partran1.out
+
+##         Longitudinal phase space is z-z'.
+        
+##         2015.01.15
+##     '''
+        
+##     file=open(path_file)
+    
+##     for lin in file.readlines():
+##         lin=lin.split()
+##         if lin[0]=='####':
+##             idx_gamma=lin.index('gama-1')
+##             idx_eps  =[lin.index(p) for p in ("ex"   ,"ey"   ,"ezdp" )]
+##             idx_bet  =[lin.index(p) for p in ("SizeX","SizeY","SizeZ")]
+##             idx_alf  =[lin.index(p) for p in ("sxx'" ,"syy'" ,"szdp" )]
+##             idx_hal  =[lin.index(p) for p in ("hx"   ,"hy"   ,"hp"   )]
+##     file.close()
+            
+##     gamma=float(lin[idx_gamma])+1.0
+##     eps  =array([float(lin[idx])    for idx in idx_eps])
+##     bet  =array([float(lin[idx])**2 for idx in idx_bet])  # Actually Sig_{i,i}
+##     alf  =array([float(lin[idx])    for idx in idx_alf])  # Actually Sig_{i,i+1}
+##     hal  =array([float(lin[idx])    for idx in idx_hal])
+
+##     bet= bet/eps*sqrt(gamma**2-1.0); bet[2]*=gamma**2  # z-dp => z-z'
+##     alf=-alf/eps*sqrt(gamma**2-1.0)
+##     gam= (1.0+alf**2)/bet
+        
+##     return eps,bet,alf,gam,hal
+
+## class PROJECT_SING_CORE:
+##     '''
+##         - Use this for simultaneous mult 1-core-simulations (w/ tracelx64).
+##         - Initial parameters are not meant to be changed, unlike "PROJECT".
+##           (Each run should have its own project.)
+##         - Make sure the project/lattice file is in the calc dir.
+##         - Changing the calc dir option not working for tracelx64.
+        
+##         2015.10.15
+##     '''
+
+##     def __init__(self,path_cal,
+##                  file_name_proj='proj.ini',file_name_lat='lat.dat',seed=None,flag_hide=None):
+
+##         # Make sure "path_cal" ends with "/".
+##         if path_cal[-1]!='/': path_cal+='/'
+            
+##         # Check the calc dir exists.
+##         if isdir(path_cal)==False: print 'Calc dir does not exist !!!! Exiting ...'; exit()
+            
+##         # Check "tracelx64" is in the calc dir.
+##         if isfile(path_cal+'tracelx64')==False:
+##             try   : system('cp /opt/cea/tracelx64 '+path_cal)
+##             except: print 'tracelx64 not in calc dir !!!! Exiting ...'; exit()
+
+##         # Check "tracewin.key" is in the calc dir.
+##         if isfile(path_cal+'tracewin.key')==False:
+##             try   : system('cp /opt/cea/tracewin.key '+path_cal)
+##             except: print 'tracewin.key not in calc dir !!!! Exiting ...'; exit()
+
+##         # Check the project/lattice file is in the calc dir.
+##         if '/' not in file_name_proj: file_name_proj=path_cal+file_name_proj
+##         if '/' not in file_name_lat : file_name_lat =path_cal+file_name_lat        
+##         if isfile(file_name_proj)==False: print 'project file not in calc dir !!!! Exiting ...'; exit()
+##         if isfile(file_name_lat) ==False: print 'lattice file not in calc dir !!!! Exiting ...'; exit()
+                
+##         # Instances (Add more options as needed.)
+##         self.path_cal      =path_cal
+##         self.file_name_proj=file_name_proj
+##         self.file_name_lat =file_name_lat
+##         self.seed          =seed
+##         self.flag_hide     =flag_hide
+
+##     def exe(self):
+
+##         opt_exe =self.path_cal+'tracelx64 '+self.file_name_proj
+##         if self.file_name_lat!=None: opt_exe+=' dat_file='   +self.file_name_lat
+##         if self.seed         !=None: opt_exe+=' random_seed='+self.seed
+##         if self.flag_hide    !=None: opt_exe+=' hide'
+        
+##         system(opt_exe)
diff --git a/ess/lib_tw_elem.py b/ess/lib_tw_elem.py
new file mode 100644
index 0000000000000000000000000000000000000000..fe96ea43346c8692536fc122842e238a117a6ed4
--- /dev/null
+++ b/ess/lib_tw_elem.py
@@ -0,0 +1,1049 @@
+
+'''
+    - Classes for TraceWin elements/commands for external manipulations.
+    - First double check all the used elements/commands.
+    
+    - Element/command types
+
+      * Active elements
+
+        FIELD_MAP
+
+        QUAD
+        THIN_STEERING
+        GAP
+        DTL_CEL
+            
+      * Passive elements
+            
+        DRIFT
+        BEND
+        EDGE
+        APERTURE            
+        DIAG_POSITION
+        DIAG_...
+
+      * Active commands
+
+        STEERER
+        CHOPPER
+
+      * Passive commands
+
+        FREQ
+        MARKER
+
+      * Other commands for just common "COMM"
+
+        END
+        LATTICE
+        LATTICE_END
+
+        SET_ADV
+        SET_SIZE            
+        SET_TWISS
+        SET_ACHROMAT
+        MATCH_FAM_GRAD
+        MATCH_FAM_FIELD
+        MATCH_FAM_PHASE
+        MATCH_FAM_LFOC
+        MIN_PHASE_VARIATION
+        START_ACHROMAT
+
+        ERROR_QUAD_NCPL_STAT
+        ERROR_QUAD_CPL_STAT
+        ERROR_CAV_NCPL_STAT
+        ERROR_CAV_NCPL_DYN
+        ERROR_CAV_CPL_STAT
+        ERROR_CAV_CPL_DYN
+        ADJUST
+        ADJUST_STEERER
+        ADJUST_STEERER_BX
+        ADJUST_STEERER_BY
+        SET_BEAM_PHASE_ERROR
+
+        PLOT_DST
+
+    2015.10.14
+'''
+
+#---- Libs
+
+from numpy import *
+from sys   import exit
+
+#---- Constants
+
+#mass=938.272046  # Wiki
+mass=938.272029  # TraceWin
+c   =2.99792458
+
+#---- Misc functions/classes
+
+def Brho(gamma):
+
+    return (10.0/c)*sqrt(gamma**2-1.0)*mass*1e-3
+
+class FIELD_MAP_DATA:
+    '''
+        - Only 1D (Ez) supported for now.
+    '''
+    def __init__(self,file_name):
+
+        # Read file
+        with open(file_name) as file: lin=file.readlines()
+
+        # Instances
+        self.dL   =float(lin[0].split()[1])/int(lin[0].split()[0])
+        self.field=map(float,lin[2:])
+
+#---- Parent classes
+
+class ELEM:
+    '''
+    '''
+    def __init__(self,name,typ,para):
+
+        # Basic instances
+        self.name=name
+        self.typ =typ
+        self.para=para        
+
+        # Option instances
+        self.L       = 0.0
+        self.apt     = None
+        self.idx     =-1
+        self.idx_elem=-1
+        self.s       = 0.0
+        self.gamma   = 1.0
+        self.freq    = 352.21
+
+    def update_idx(self):
+
+        # Update idx, idx_elem, s
+        self.idx     +=1
+        self.idx_elem+=1
+        self.s       +=self.L
+
+    def get_tw(self):
+
+        if self.name!='': lin=self.name+': '+self.typ+' '+' '.join(self.para)
+        if self.name=='': lin=               self.typ+' '+' '.join(self.para)
+
+        return lin
+
+    ## def get_madx(self):
+
+    ##     i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)        
+
+    ##     if self.name!='': lin= self.name        +': marker;'
+    ##     if self.name=='': lin='elem'+i+'_marker'+': marker;'
+        
+    ##     return lin
+
+class COMM:
+    '''
+        - Same inputs as ELEM class but some may not be needed ...
+    '''
+    def __init__(self,name,typ,para):
+
+        # Basic instances
+        self.name=name
+        self.typ =typ
+        self.para=para
+
+        # Option instances
+        self.idx     =-1
+        self.idx_elem=-1
+        self.s       = 0.0
+        self.gamma   = 1.0
+        self.freq    = 352.21
+
+    def update_idx(self):
+
+        # Update idx
+        self.idx+=1
+                
+    def get_tw(self):
+
+        if self.name!='': lin=self.name+': '+self.typ+' '+' '.join(self.para)
+        if self.name=='': lin=               self.typ+' '+' '.join(self.para)
+
+        return lin
+
+#---- Field map (need an additional input, dic_fmap)
+    
+class FIELD_MAP(ELEM):
+    '''
+        - Calculation of gamma only 1D (Ez) supported.
+    '''
+    def __init__(self,name,typ,para,dic_fmap):
+
+        ELEM.__init__(self,name,typ,para)
+
+        # TW instances
+        self.name_fmap=      para[8]
+        self.typ_fmap =      para[0]
+        self.L        =float(para[1])*1e-3      # mm => m
+        self.phs_rf   =float(para[2])*pi/180.0  # deg => rad
+        self.apt      =float(para[3])
+        self.Bnom     =float(para[4])
+        self.Enom     =float(para[5])
+        self.sc_comp  =float(para[6])
+        self.flag_apt =      para[7]
+
+        # Option instances
+        self.data=dic_fmap[self.name_fmap]
+        
+    def update_gamma(self):
+
+        # Temp error message for field map types
+        if self.typ_fmap!='100': print 'Gamma calc only supported for 1D, exiting ...', exit()
+        
+        # Update gamma (simple ver, closer to TW)
+        dL=self.data.dL; V=self.Enom*array(self.data.field)*dL; phs=self.phs_rf; C=0.0; S=0.0
+        for i in range(len(V)):
+            C+=V[i]*cos(phs); S+=V[i]*sin(phs); self.gamma+=V[i]/mass*cos(phs)
+            beta=sqrt(1.0-1.0/self.gamma**2); phs+=2.0*pi*self.freq*dL/(beta*c*1e2)
+
+        # Update gamma (I think this is more accurate...)
+        ## dL=self.data.dL; V=self.Enom*array(self.data.field)*dL; phs=self.phs_rf; C=0; S=0
+        ## for i in range(len(V)):
+        ##     if i==0        :
+        ##         C+=V[i]*cos(phs); S+=V[i]*sin(phs); self.gamma+=0.5*V[i]/mass*cos(phs)
+        ##         beta=sqrt(1.0-1.0/self.gamma**2); phs+=2.0*pi*self.freq*dL/(beta*c*1e2)
+        ##     if 0<i<len(V)-1:
+        ##         C+=V[i]*cos(phs); S+=V[i]*sin(phs); self.gamma+=    V[i]/mass*cos(phs)
+        ##         beta=sqrt(1.0-1.0/self.gamma**2); phs+=2.0*pi*self.freq*dL/(beta*c*1e2)
+        ##     if i==len(V)-1 :
+        ##         C+=V[i]*cos(phs); S+=V[i]*sin(phs); self.gamma+=0.5*V[i]/mass*cos(phs)
+
+        # Option instances for other codes (MADX?)
+        self.phs_syn=arctan(S/C)
+        self.E0TL   =C/cos(self.phs_syn)
+
+    def get_tw(self):
+
+        if self.name!='': lin=self.name+': '+self.typ+' '
+        if self.name=='': lin=               self.typ+' '
+        lin+=    self.typ_fmap        +' '
+        lin+=str(self.L*1e3          )+' '
+        lin+=str(self.phs_rf*180.0/pi)+' '
+        lin+=str(self.apt            )+' '
+        lin+=str(self.Bnom           )+' '
+        lin+=str(self.Enom           )+' '
+        lin+=str(self.sc_comp        )+' '
+        lin+=    self.flag_apt        +' '
+        lin+=    self.name_fmap
+
+        return lin
+
+    def get_madx(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name          +': RFCAVITY, '
+        if self.name=='': lin='ELEM'+i+'_FIELDMAP'+': RFCAVITY, '
+        lin+='L='   +str(self.L                        )+', '
+        lin+='FREQ='+str(self.freq                     )+', '
+        lin+='VOLT='+str(self.E0TL                     )+', '
+        lin+='LAG=' +str((0.5*pi-self.phs_syn)/(2.0*pi))+'; '  # phs_MADX = pi/2-phs_TW        
+        
+        return lin
+
+    def get_fluka(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name          +'  RFCAVITY  '
+        if self.name=='': lin='ELEM'+i+'_FIELDMAP'+'  RFCAVITY  '
+        lin+=str(self.L)+'  '+str(self.s)+'  '
+        lin+='0.0  0.0  0.0  '
+        lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'
+        
+        return lin
+    
+    def get_mars(self):
+
+        lin ='"RFCAVITY"  ""  ""  '+str(self.s)+'  '+str(self.L)+'  '
+        lin+='0  0  0  0  0'
+
+        return lin
+    
+#---- Active elements
+
+class QUAD(ELEM):
+    '''
+        - Tilt not supported.
+    '''
+    def __init__(self,name,typ,para):
+
+        ELEM.__init__(self,name,typ,para)
+    
+        # TW instances
+        self.L   =float(para[0])*1e-3  # mm => m
+        self.G   =float(para[1])
+        self.apt =float(para[2])
+        self.tilt=0.0
+        
+        # TW option instances
+        try   : self.b3    =float(para[4])
+        except: self.b3    =0.0
+        try   : self.b4    =float(para[5])
+        except: self.b4    =0.0
+        try   : self.b5    =float(para[6])
+        except: self.b5    =0.0
+        try   : self.b6    =float(para[7])
+        except: self.b6    =0.0
+        try   : self.r_good=float(para[8])
+        except: self.r_good=0.0
+            
+    def get_tw(self):
+
+        if self.name!='': lin=self.name+': '+self.typ+' '
+        if self.name=='': lin=               self.typ+' '
+        lin+=str(self.L*1e3 )+' '
+        lin+=str(self.G     )+' '
+        lin+=str(self.apt   )+' '
+        lin+=str(self.tilt  )+' '
+        lin+=str(self.b3    )+' '
+        lin+=str(self.b4    )+' '
+        lin+=str(self.b5    )+' '
+        lin+=str(self.b6    )+' '        
+        lin+=str(self.r_good)
+
+        return lin
+
+    def get_madx(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+        
+        if self.name!='': lin= self.name      +': QUADRUPOLE, '
+        if self.name=='': lin='ELEM'+i+'_QUAD'+': QUADRUPOLE, '
+        lin+='L=' +str(self.L                 )+', '
+        lin+='K1='+str(self.G/Brho(self.gamma))+'; '        
+        
+        return lin
+
+    def get_fluka(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name      +'  QUADRUPOLE  '
+        if self.name=='': lin='ELEM'+i+'_QUAD'+'  QUADRUPOLE  '
+        lin+=str(self.L)+'  '+str(self.s)+'  '
+        lin+='0.0  0.0  '+str(self.G*self.L/Brho(self.gamma))+'  '
+        lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'
+        
+        return lin
+    
+    def get_mars(self):
+        
+        lin ='"QUADRUPOLE"  ""  ""  '+str(self.s)+'  '+str(self.L)+'  '
+        lin+='0  '+str(self.G/Brho(self.gamma))+'  0  0  0  '
+
+        return lin
+
+class THIN_STEERING(ELEM):
+    '''
+        - Only magnetic steerer supported.
+        - Info of plane missing.
+    '''
+    def __init__(self,name,typ,para):
+
+        ELEM.__init__(self,name,typ,para)
+    
+        # TW instances
+        self.BLx   =float(self.para[0])
+        self.BLy   =float(self.para[1])
+        self.apt   =float(self.para[2])
+        self.typ_EM='0'
+
+    def get_tw(self):
+
+        if self.name!='': lin=self.name+': '+self.typ+' '
+        if self.name=='': lin=               self.typ+' '
+        lin+=str(self.BLx   )+' '
+        lin+=str(self.BLy   )+' '        
+        lin+=str(self.apt   )+' '
+        lin+=    self.typ_EM
+
+        return lin
+        
+    def get_madx(self):
+        
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+        
+        if self.name!='': lin= self.name         +': KICKER, L=0, '
+        if self.name=='': lin='ELEM'+i+'_STEERER'+': KICKER, L=0, '
+        lin+='HKICK='+str(-self.BLy/Brho(self.gamma))+', '
+        lin+='VKICK='+str( self.BLx/Brho(self.gamma))+'; '
+
+        return lin
+
+    def get_fluka(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name         +'  KICKER  '
+        if self.name=='': lin='ELEM'+i+'_STEERER'+'  KICKER  '
+        lin+=str(self.L)+'  '+str(self.s)+'  '
+        lin+='0.0  0.0  0.0  '
+        lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'
+        
+        return lin
+    
+    def get_mars(self):
+
+        lin ='"KICKER"  ""  ""  '+str(self.s)+'  '+str(self.L)+'  '
+        lin+='0  0  0  0  0'
+
+        return lin
+    
+class GAP(ELEM):
+    '''
+        - Note there are E0T0L (for TW) and E0TL (for other codes).
+    '''
+    def __init__(self,name,typ,para):
+
+        ELEM.__init__(self,name,typ,para)
+
+        # TW instances
+        self.E0T0L     =float(para[0])*1e-6      # V => MV
+        self.phs_rf    =float(para[1])*pi/180.0  # deg => rad
+        self.apt       =float(para[2])
+        self.phs_rf_typ='0'                      # Relative phase only for now
+
+        # TW option instances
+        try   : self.beta_s=float(para[4])
+        except: self.beta_s=0.0
+        try   : self.T0    =float(para[5])
+        except: self.T0    =0.0
+        try   : self.T1    =float(para[6])
+        except: self.T1    =0.0
+        try   : self.T2    =float(para[7])
+        except: self.T2    =0.0
+
+        # Option instances
+        self.E0TL=self.E0T0L
+            
+    def update_gamma(self):
+                    
+        # Update gamma (and E0TL)
+        if self.beta_s!=0.0 and self.T0!=0.0:
+            gamma_c   =self.gamma+0.5*self.E0TL/mass*cos(self.phs_rf)
+            beta_c    =sqrt(1.0-1.0/gamma_c**2)
+            k         =self.beta_s/beta_c
+            self.E0TL*=(self.T0+self.T1*(k-1.0)+0.5*self.T2*(k-1.0)**2)/self.T0
+        self.gamma+=self.E0TL/mass*cos(self.phs_rf)
+        
+    def get_tw(self):
+
+        if self.name!='': lin=self.name+': '+self.typ+' '
+        if self.name=='': lin=               self.typ+' '
+        lin+=str(self.E0T0L*1e6      )+' '
+        lin+=str(self.phs_rf*180.0/pi)+' '
+        lin+=str(self.apt            )+' '
+        lin+=    self.phs_rf_typ      +' '
+        lin+=str(self.beta_s         )+' '
+        lin+=str(self.T0             )+' '
+        lin+=str(self.T1             )+' '
+        lin+=str(self.T2             )
+
+        return lin
+
+    def get_madx(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name     +': RFCAVITY, L=0, '
+        if self.name=='': lin='ELEM'+i+'_GAP'+': RFCAVITY, L=0, '
+        lin+='FREQ='+str(self.freq                    )+', '
+        lin+='VOLT='+str(self.E0TL                    )+', '
+        lin+='LAG=' +str((0.5*pi-self.phs_rf)/(2.0*pi))+'; '  # phs_MADX = pi/2-phs_TW
+        
+        return lin
+
+    def get_fluka(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name     +'  RFCAVITY  '
+        if self.name=='': lin='ELEM'+i+'_GAP'+'  RFCAVITY  '
+        lin+=str(self.L)+'  '+str(self.s)+'  '
+        lin+='0.0  0.0  0.0  '
+        lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'
+        
+        return lin
+
+    def get_mars(self):
+
+        lin ='"RFCAVITY"  ""  ""  '+str(self.s)+'  '+str(self.L)+'  '
+        lin+='0  0  0  0  0'
+
+        return lin
+
+class DTL_CEL(ELEM):
+    '''
+        - Note there are E0T0L (for TW) and E0TL (for other codes).
+    '''
+    def __init__(self,name,typ,para):
+
+        ELEM.__init__(self,name,typ,para)
+
+        # TW instances
+        self.L         =float(para[0])*1e-3      # mm => m
+        self.L_Q1      =float(para[1])*1e-3      # mm => m
+        self.L_Q2      =float(para[2])*1e-3      # mm => m
+        self.ds_gap    =float(para[3])*1e-3      # mm => m
+        self.G_Q1      =float(para[4])
+        self.G_Q2      =float(para[5])
+        self.E0T0L     =float(para[6])*1e-6      # V => MV
+        self.phs_rf    =float(para[7])*pi/180.0  # deg => rad
+        self.apt       =float(para[8])
+        self.phs_rf_typ='0'                      # Relative phase only for now
+
+        # TW option instances
+        try   : self.beta_s=float(para[10])
+        except: self.beta_s=0.0
+        try   : self.T0    =float(para[11])
+        except: self.T0    =0.0
+        try   : self.T1    =float(para[12])
+        except: self.T1    =0.0
+        try   : self.T2    =float(para[13])
+        except: self.T2    =0.0
+
+        # Option instances
+        self.E0TL=self.E0T0L
+
+    def update_gamma(self):
+
+        # Save the gamma_ini (for MADX)
+        self.gamma_ini=self.gamma
+                
+        # Update gamma (and E0TL)
+        if self.beta_s!=0.0 and self.T0!=0.0:
+            gamma_c   =self.gamma+0.5*self.E0TL/mass*cos(self.phs_rf)
+            beta_c    =sqrt(1.0-1.0/gamma_c**2)
+            k         =self.beta_s/beta_c
+            self.E0TL*=(self.T0+self.T1*(k-1.0)+0.5*self.T2*(k-1.0)**2)/self.T0
+        self.gamma+=self.E0TL/mass*cos(self.phs_rf)
+        
+    def get_tw(self):
+
+        if self.name!='': lin=self.name+': '+self.typ+' '
+        if self.name=='': lin=               self.typ+' '
+        lin+=str(self.L*1e3          )+' '
+        lin+=str(self.L_Q1*1e3       )+' '
+        lin+=str(self.L_Q2*1e3       )+' '
+        lin+=str(self.ds_gap*1e3     )+' '
+        lin+=str(self.G_Q1           )+' '
+        lin+=str(self.G_Q2           )+' '        
+        lin+=str(self.E0T0L*1e6      )+' '
+        lin+=str(self.phs_rf*180.0/pi)+' '
+        lin+=str(self.apt            )+' '
+        lin+=    self.phs_rf_typ      +' '
+        lin+=str(self.beta_s         )+' '
+        lin+=str(self.T0             )+' '
+        lin+=str(self.T1             )+' '
+        lin+=str(self.T2             )
+
+        return lin
+
+    def get_madx(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name         +'_QUAD1: QUADRUPOLE, '
+        if self.name=='': lin='ELEM'+i+'_DTLCELL'+'_QUAD1: QUADRUPOLE, '
+        lin+='L=' +str(self.L_Q1                     )+', '
+        lin+='K1='+str(self.G_Q1/Brho(self.gamma_ini))+'; \n'
+
+        if self.name!='': lin+= self.name         +'_DRIFT1: DRIFT, '
+        if self.name=='': lin+='ELEM'+i+'_DTLCELL'+'_DRIFT1: DRIFT, '
+        lin+='L='+str(0.5*self.L-self.L_Q1-self.ds_gap)+';\n'
+
+        if self.name!='': lin+= self.name         +'_GAP: RFCAVITY, L=0, '
+        if self.name=='': lin+='ELEM'+i+'_DTLCELL'+'_GAP: RFCAVITY, L=0, '
+        lin+='FREQ='+str(self.freq                    )+', '
+        lin+='VOLT='+str(self.E0TL                    )+', '        
+        lin+='LAG=' +str((0.5*pi-self.phs_rf)/(2.0*pi))+'; \n'  # phs_MADX = pi/2-phs_TW
+
+        if self.name!='': lin+= self.name         +'_DRIFT2: DRIFT, '
+        if self.name=='': lin+='ELEM'+i+'_DTLCELL'+'_DRIFT2: DRIFT, '
+        lin+='L='+str(0.5*self.L-self.L_Q2+self.ds_gap)+';\n'
+        
+        if self.name!='': lin+= self.name         +'_QUAD2: QUADRUPOLE, '
+        if self.name=='': lin+='ELEM'+i+'_DTLCELL'+'_QUAD2: QUADRUPOLE, '
+        lin+='L=' +str(self.L_Q2                 )+', '
+        lin+='K1='+str(self.G_Q2/Brho(self.gamma))+'; '
+
+        return lin
+
+    def get_fluka(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        ## if self.name!='': lin= self.name         +'_QUAD1  QUADRUPOLE  '
+        ## if self.name=='': lin='ELEM'+i+'_DTLCELL'+'_QUAD1  QUADRUPOLE  '
+        ## lin+=str(self.L_Q1)+'  '+str(self.s-self.L+self.L_Q1)+'  '
+        ## lin+='0.0  0.0  '+str(self.G_Q1*self.L_Q1/Brho(self.gamma_ini))+'  '
+        ## lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0\n'
+        
+        ## if self.name!='': lin+= self.name         +'_DRIFT1  DRIFT  '
+        ## if self.name=='': lin+='ELEM'+i+'_DTLCELL'+'_DRIFT1  DRIFT  '
+        ## lin+=str(0.5*self.L-self.L_Q1-self.ds_gap)+'  '+str(self.s-0.5*self.L-self.ds_gap)+'  '
+        ## lin+='0.0  0.0  0.0  '
+        ## lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0\n'
+
+        ## if self.name!='': lin+= self.name         +'_GAP  RFCAVITY   '
+        ## if self.name=='': lin+='ELEM'+i+'_DTLCELL'+'_GAP  RFCAVITY   '
+        ## lin+='0.0  '+str(self.s-0.5*self.L-self.ds_gap)+'  '
+        ## lin+='0.0  0.0  0.0  '
+        ## lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0\n'
+        
+        ## if self.name!='': lin+= self.name         +'_DRIFT2  DRIFT  '
+        ## if self.name=='': lin+='ELEM'+i+'_DTLCELL'+'_DRIFT2  DRIFT  '
+        ## lin+=str(0.5*self.L-self.L_Q2+self.ds_gap)+'  '+str(self.s-self.L_Q2)+'  '
+        ## lin+='0.0  0.0  0.0  '
+        ## lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0\n'
+
+        ## if self.name!='': lin+= self.name         +'_QUAD2  QUADRUPOLE  '
+        ## if self.name=='': lin+='ELEM'+i+'_DTLCELL'+'_QUAD2  QUADRUPOLE  '
+        ## lin+=str(self.L_Q2)+'  '+str(self.s)+'  '
+        ## lin+='0.0  0.0  '+str(self.G_Q2*self.L_Q2/Brho(self.gamma))+'  '
+        ## lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'
+
+        if self.name!='': lin= self.name         +'  RFCAVITY  '
+        if self.name=='': lin='ELEM'+i+'_DTLCELL'+'  RFCAVITY  '
+        lin+=str(self.L)+'  '+str(self.s)+'  '
+        lin+='0.0  0.0  0.0  '
+        lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'
+        
+        return lin
+    
+    def get_mars(self):
+
+        lin ='"QUADRUPOLE"  ""  ""  '
+        lin+=str(self.s-self.L+self.L_Q1)+'  '
+        lin+=str(self.L_Q1)              +'  '
+        lin+='0  '+str(self.G_Q1/Brho(self.gamma_ini))+'  0  0  0  \n'
+
+        lin+='"DRIFT"  ""  ""  '
+        lin+=str(self.s-0.5*self.L-self.ds_gap)   +'  '
+        lin+=str(0.5*self.L-self.L_Q1-self.ds_gap)+'  '
+        lin+='0  0  0  0  0  \n'
+        
+        lin+='"RFCAVITY"  ""  ""  '
+        lin+=str(self.s-0.5*self.L-self.ds_gap)+'  '
+        lin+='0  '
+        lin+='0  0  0  0  0  \n'
+
+        lin+='"DRIFT"  ""  ""  '
+        lin+=str(self.s-self.L_Q2)                +'  '
+        lin+=str(0.5*self.L-self.L_Q2+self.ds_gap)+'  '
+        lin+='0  0  0  0  0  \n'        
+
+        lin+='"QUADRUPOLE"  ""  ""  '
+        lin+=str(self.s)   +'  '
+        lin+=str(self.L_Q2)+'  '
+        lin+='0  '+str(self.G_Q2/Brho(self.gamma))+'  0  0  0  '
+        
+        return lin
+    
+#---- Passive elements
+    
+class DRIFT(ELEM):
+    '''
+    '''
+    def __init__(self,name,typ,para):
+
+        ELEM.__init__(self,name,typ,para)
+
+        # TW instances
+        self.L  =float(para[0])*1e-3  # mm => m
+        self.apt=float(para[1])
+
+        # TW option instances
+        try   : self.apty=float(para[2])
+        except: self.apty=0.0
+
+    def get_madx(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name       +': DRIFT, L='+str(self.L)+';'
+        if self.name=='': lin='ELEM'+i+'_DRIFT'+': DRIFT, L='+str(self.L)+';'
+        
+        return lin
+
+    def get_fluka(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name       +'  DRIFT  '
+        if self.name=='': lin='ELEM'+i+'_DRIFT'+'  DRIFT  '
+        lin+=str(self.L)+'  '+str(self.s)+'  '
+        lin+='0.0  0.0  0.0  '
+        if self.apty==0.0: lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'
+        if self.apty!=0.0: lin+='RECTANGLE  '+str(self.apt*1e-3)+'  '+str(self.apty*1e-3)
+
+        return lin
+    
+    def get_mars(self):
+
+        lin ='"DRIFT"  ""  ""  '+str(self.s)+'  '+str(self.L)+'  '
+        lin+='0  0  0  0  0'
+
+        return lin
+
+class BEND(ELEM):
+    '''
+        - For MADX, keeping the sbend+edge structure.
+        - For MADX, if don't export edge, append instances of EDGE.
+          (Otherwise, the matrix is wrong in MADX.)
+        - For MARS/Fluka, assuming the rbend.
+    '''
+    def __init__(self,name,typ,para):
+
+        ELEM.__init__(self,name,typ,para)
+    
+        # TW instances
+        self.angle=float(para[0])*pi/180.0  # deg => rad
+        self.rho  =float(para[1])*1e-3      # mm => m
+        self.apt  =float(para[3])
+        self.plane=      para[4]
+
+        # Option instances
+        if self.plane=='0': self.tilt=0.0
+        if self.plane=='1': self.tilt=0.5*pi
+        self.ds      =self.rho*abs(self.angle)
+        self.L       =2.0*self.rho*sin(0.5*abs(self.angle))
+        self.gap     =0.0  # Get this from EDGE IF not exporting edge for MADX
+        self.ff_coef1=0.0  # Get this from EDGE IF not exporting edge for MADX
+        self.ff_coef2=0.0  # Get this from EDGE IF not exporting edge for MADX
+
+    def update_idx(self):
+
+        # Updata idx, idx_elem, s
+        self.idx     +=1
+        self.idx_elem+=1
+        self.s       +=self.ds  # Need an overwrite because of this
+        
+    def get_madx(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name      +': '
+        if self.name=='': lin='ELEM'+i+'_BEND'+': '
+        lin+='SBEND, L='+str(self.ds      )+', '  # sbend
+        #lin+='RBEND, L='+str(self.L       )+', '  # rbend
+        lin+='ANGLE='   +str(self.angle   )+', '
+        lin+='TILT='    +str(self.tilt    )+', '
+        lin+='HGAP='    +str(self.gap*5e-4)+', '
+        lin+='FINT='    +str(self.ff_coef1)+'; '
+        
+        return lin
+
+    def get_fluka(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name      +'  RBEND  '
+        if self.name=='': lin='ELEM'+i+'_BEND'+'  RBEND  '
+        lin+=str(self.ds)+'  '+str(self.s)+'  '
+        lin+=str(self.tilt)+'  '+str(self.angle)+'  0.0  '
+        lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'
+
+        return lin
+
+    def get_mars(self):
+
+        lin ='"RBEND"  ""  ""  '+str(self.s)+'  '+str(self.L)+'  '
+        lin+=str(self.angle)+'  0  0  0  '+str(self.tilt)
+
+        return lin
+            
+class EDGE(ELEM):
+    '''
+        - For MARS, assuming rbend and the export is commented out.
+    '''
+    def __init__(self,name,typ,para):
+
+        ELEM.__init__(self,name,typ,para)
+    
+        # TW instances
+        self.angle   =float(para[0])*pi/180.0  # deg => rad
+        self.rho     =float(para[1])*1e-3      # mm => m        
+        self.gap     =float(para[2])
+        self.ff_coef1=float(para[3])
+        self.ff_coef2=float(para[4])        
+        self.apt     =float(para[5])
+        self.plane   =      para[6]
+
+        # Option instances
+        if self.plane=='0': self.tilt=0.0
+        if self.plane=='1': self.tilt=0.5*pi
+        
+    def get_madx(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)        
+        
+        if self.name!='': lin= self.name      +': DIPEDGE, '
+        if self.name=='': lin='ELEM'+i+'_EDGE'+': DIPEDGE, '
+        lin+='E1='  +str(self.angle)   +', '  # sbend
+        #lin+='E1='  +'0'               +', '  # rbend
+        lin+='H='   +str(1.0/self.rho) +', '
+        lin+='TILT='+str(self.tilt    )+', '        
+        lin+='HGAP='+str(self.gap*5e-4)+', '        
+        lin+='FINT='+str(self.ff_coef1)+'; '
+        
+        return lin
+
+class APERTURE(ELEM):
+    '''
+        - For MADX, tried "collimator" but didn't work ...?
+    '''
+    def __init__(self,name,typ,para):
+
+        ELEM.__init__(self,name,typ,para)
+
+        # TW instances
+        self.apt    =float(para[0])
+        self.apty   =float(para[1])
+        self.typ_apt=      para[2]
+        
+    def get_madx(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name     +': DRIFT, L=0;'
+        if self.name=='': lin='ELEM'+i+'_APT'+': DRIFT, L=0;'
+        
+        ## if self.name!='': lin= self.name     +': collimator, l=0, '
+        ## if self.name=='': lin='ELEM'+i+'_apt'+': collimator, l=0, '
+        ## if self.typ_apt=='0':
+        ##     lin+='apertype=rectangle, aperture={'+str(self.apt*1e-3)+','+str(self.apty*1e-3)+'};'
+        ## if self.typ_apt=='1':
+        ##     lin+='apertype=CIRCLE, aperture={'+str(self.apt*1e-3)+'};'
+            
+        return lin
+
+    def get_fluka(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name     +'  DRIFT  '
+        if self.name=='': lin='ELEM'+i+'_APT'+'  DRIFT  '
+        lin+=str(self.L)+'  '+str(self.s)+'  '
+        lin+='0.0  0.0  0.0  '
+        if self.typ_apt=='0': lin+='RECTANGLE  '+str(self.apt*1e-3)+'  '+str(self.apty*1e-3)        
+        if self.typ_apt=='1': lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'        
+
+        return lin   
+
+    def get_mars(self):
+
+        lin ='"drift"  ""  ""  '+str(self.s)+'  '+str(self.L)+'  '
+        lin+='0  0  0  0  0'
+
+        return lin
+            
+class DIAG_POSITION(ELEM):
+    '''
+    '''
+    def __init__(self,name,typ,para):
+
+        ELEM.__init__(self,name,typ,para)
+
+    def get_madx(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)        
+
+        if self.name!='': lin= self.name     +': MONITOR, L=0;'
+        if self.name=='': lin='ELEM'+i+'_BPM'+': MONITOR, L=0;'
+        
+        return lin
+
+    def get_fluka(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name     +'  MONITOR  '
+        if self.name=='': lin='ELEM'+i+'_BPM'+'  MONITOR  '
+        lin+=str(self.L)+'  '+str(self.s)+'  '
+        lin+='0.0  0.0  0.0  '
+        lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'
+
+        return lin       
+
+    def get_mars(self):
+
+        lin ='"MONITOR"  ""  ""  '+str(self.s)+'  '+str(self.L)+'  '
+        lin+='0  0  0  0  0'
+        
+        return lin
+
+class DIAG(ELEM):
+    '''
+    '''
+    def __init__(self,name,typ,para):
+
+        ELEM.__init__(self,name,typ,para)
+
+    def get_madx(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)        
+
+        if self.name!='': lin= self.name      +': INSTRUMENT, L=0;'
+        if self.name=='': lin='ELEM'+i+'_DIAG'+': INSTRUMENT, L=0;'
+        
+        return lin
+
+    def get_fluka(self):
+
+        i='0'*(3-int(log10(self.idx_elem+1)))+str(self.idx_elem+1)
+
+        if self.name!='': lin= self.name      +'  INSTRUMENT  '
+        if self.name=='': lin='ELEM'+i+'_DIAG'+'  INSTRUMENT  '
+        lin+=str(self.L)+'  '+str(self.s)+'  '
+        lin+='0.0  0.0  0.0  '
+        lin+='CIRCLE  '+str(self.apt*1e-3)+'  0.0'
+
+        return lin
+    
+    def get_mars(self):
+
+        lin ='"INSTRUMENT"  ""  ""  '+str(self.s)+'  '+str(self.L)+'  '
+        lin+='0  0  0  0  0'
+        
+        return lin
+
+#---- Active commands
+    
+class STEERER(COMM):
+    '''
+        - Only magnetic steerers supported.
+        - Only the ESS type non-linearity supported.
+    '''
+    def __init__(self,name,typ,para):
+
+        COMM.__init__(self,name,typ,para)
+    
+        # TW instances
+        self.Bx=float(para[0])
+        self.By=float(para[1])
+
+        # TW option instances
+        try   : self.max   =float(para[2])
+        except: self.max   =0.0
+        try   : self.nonlin=float(para[5])
+        except: self.nonlin=0.0
+
+    def get_tw(self):
+
+        if self.name!='': lin=self.name+': '+self.typ+' '
+        if self.name=='': lin=               self.typ+' '
+        lin+=str(self.Bx    )+' '
+        lin+=str(self.By    )+' '
+        lin+=str(self.max   )+' '
+        lin+='0'             +' '
+        lin+='0'             +' '        
+        lin+=str(self.nonlin)
+
+        return lin
+
+class CHOPPER(COMM):
+    '''
+    '''
+    def __init__(self,name,typ,para):
+
+        COMM.__init__(self,name,typ,para)
+
+        # TW instances
+        self.Nelem=  int(para[0])
+        self.volt =float(para[1])
+        self.gap  =float(para[2])*2.0
+        self.d_pos=float(para[3])
+        self.plane=      para[4]
+
+    def get_tw(self):
+
+        if self.name!='': lin=self.name+': '+self.typ+' '
+        if self.name=='': lin=               self.typ+' '
+        lin+=str(self.Nelem  )+' '
+        lin+=str(self.volt   )+' '
+        lin+=str(self.gap*0.5)+' '
+        lin+=str(self.d_pos  )+' '
+        lin+=    self.plane
+
+        return lin
+
+#---- Passive commands
+        
+class FREQ(COMM):
+    '''
+    '''
+    def __init__(self,name,typ,para):
+
+        COMM.__init__(self,name,typ,para)
+    
+        # TW instances
+        self.freq_new=float(para[0])
+                    
+    def update_idx(self):
+
+        self.idx +=1
+        self.freq =self.freq_new
+
+class MARKER(COMM):
+    '''
+    '''
+    def __init__(self,name,typ,para):
+
+        COMM.__init__(self,name,typ,para)
+
+    def get_madx(self):
+
+        if self.name!='': lin=self.name   +': MARKER;'
+        if self.name=='': lin=self.para[0]+': MARKER;'
+        
+        return lin
+
+    def get_fluka(self):
+
+        if self.name!='': lin=self.name   +'  MARKER  '
+        if self.name=='': lin=self.para[0]+'  MARKER  '
+        lin+='0.0  '+str(self.s)
+
+        return lin
+    
+    ## def get_mars(self):
+
+    ##     lin ='"marker"  ""  ""  '+str(self.s)+'  0.0  '
+    ##     lin+='0  0  0  0  0'
+
+    ##     return lin
+        
+#---- No longer needed ??
+
+## class ADJUST(COMM):
+##     '''
+##     '''
+##     def __init__(self,name,typ,para):
+
+##         COMM.__init__(self,name,typ,para)
+    
+##         # TW instances
+##         self.fam=    para[0]
+##         self.var=int(para[1])        
+
+##         # TW option instances
+##         try   : self.link=self.para[2]
+##         except: self.link='0'
+##         try   : self.min =float(self.para[3])
+##         except: self.min =0.0
+##         try   : self.max =float(self.para[4])
+##         except: self.max =0.0
+##         try   : self.ini =float(self.para[5])
+##         except: self.ini =0.0