def loadMultipartFormat_dst(filename):
    with open(filename, "rb") as f: # b is for binary
        fileContent = f.read()
        twoChars = struct.unpack("cc", fileContent[:2]) # ???
        #print "twoChars: " + str(twoChars)
        Np = struct.unpack("i", fileContent[2:6]) # Number of particles
        Np = Np[0]
        #print "Np: " + str(Np)
        Ib = struct.unpack("d",fileContent[6:14]) # Beam current
        Ib = Ib[0]
        #print "Ib: " + str(Ib)
        freq = struct.unpack("d",fileContent[14:22]) # Frequency in MHz
        freq = freq[0]
        #print "freq: " + str(freq)
        thirdChar = struct.unpack("c", fileContent[22:23]) # ???
        #print "thirdChar: " + str(thirdChar)

        # for loop the particles
        x = np.linspace(0,0,Np)
        xp = np.linspace(0,0,Np)
        y = np.linspace(0,0,Np)
        yp = np.linspace(0,0,Np)
        phi = np.linspace(0,0,Np)
        energie = np.linspace(0,0,Np)
        s = np.linspace(0,0,Np)
        nextStart = 23
        nextEnd = 23+8*6
        for i in range(0,Np):
            sixDoubles = struct.unpack("dddddd",fileContent[nextStart:nextEnd]) #[28+i*8*6:28+(i+1)*8*6])
            #print "sixDoubles: " + str(sixDoubles)

            x[i] = sixDoubles[0]/100 # cm to m
            xp[i] = sixDoubles[1] # rad should be the same as unitless
            y[i] = sixDoubles[2]/100 # cm to m
            yp[i] = sixDoubles[3] # rad should be the same as unitless
            phi[i] = sixDoubles[4] # rad
            energie[i] = sixDoubles[5] # MeV and its the actual energy not a diff

            nextStart = nextEnd
            nextEnd = nextStart+8*6
            #print "bla"


        mc2 = struct.unpack("d", fileContent[-8:]) # particle rest mass in MeV ( the usual /c**2 is dropped since c2 is in the name)
        mc2 = mc2[0]
        #print "mc2: " + str(mc2) # Yields the correct value for a proton, wohoo!

        # convert phi and energie to z and zp
        rf_lambda = constants.c/(freq*1000000) # *1000000 is freq converted to Hz, fixed phi to z problems
        m_0 = mc2*1.672621777e-27/938.272046 # conversion from MeV/c**2 to kg
        E = float(input('Enter E [J]: '))
        beta = betaFromE(m_0, E)
        gamma = gammaFromBeta(beta)
        #z, zp = zzpFromPhiEnergie(phi, energie, beta, rf_lambda, gamma, mc2, E)
        z, zp = zdeltaFromPhiEnergie(phi, energie, beta, rf_lambda, gamma, mc2, E)


        # Make the multipart array
        bigMatrix = np.array([x, xp, y, yp, z, zp])
        multipart = [[bigMatrix[:,i], s[i]] for i in xrange(Np)]

        #print "multipart: " + str(multipart)

        #print "tjena" 
        # Should the other beam data be returned as well, such as rf_lambda, beam current and m_0?
        return multipart
    return 0
def loadLatticeFormat_dat(filename, lattice):
    try:
        f = open(filename, 'r')
        latticeString = f.read()
    except:
        print 'Bad datafile! From loadLatticeFormat_dat...'
        return 0

    # Useful parameters from lattice
    beamdata = lattice.getBeamdata()
    m_0 = beamdata[2]
    beta = beamdata[0]
    gamma = gammaFromBeta(beta)
    q = beamdata[3]

    newLattice = Lattice("Loaded Lattice", beamdata, lattice.getTwiss(), lattice.getMultipart())

    try:
        # Parsing
        for line in iter(latticeString.splitlines()):
            words = line.split()
            typeOfElem = words[0]
    
            if typeOfElem == "DRIFT":
               # Useful params
               L = float(words[1])/1000 # /1000 is for converting mm to m
               # Useless params
               R = float(words[2])
               Ry = float(words[3])
               # Params not stated that I need to construct the element
               name = "d"
               # Create the element
               newLattice.createDrift(name, L)
            elif typeOfElem == "QUAD":
                # Useful params
                L = float(words[1])/1000
                G = float(words[2]) # They say G I say K, what is the difference? Ans: See TraceWin documentation page 102 my K is their -k
    
                # Indirect params
                Brho = m_0*constants.c*beta*gamma/q
                k = np.sqrt(float(abs(G/Brho))) # For some reason abs(...) is a sympy float and np.sqrt just can't handle that
                if q*G > 0:
                    K = -k # focus in horiz (x)
                else:
                    K = k # defocus in horiz (x)
                # Useless params
                R = float(words[2])
                # Params not stated that I need construct the element
                name = "q"
                # Create the element
                newLattice.createQuadrupole(name, K, L)
            elif typeOfElem == "MULTIPOLE":
                if int(words[1]) == 3: # sextupole
                    L = float(words[2])/1000
                    k = float(words[4])
                    order = 2 # for the lie transform
                    name = "s"
                    newLattice.createSextupolerel(name, k, L, order)
            elif typeOfElem == "ROTATION":
                nu_x = float(words[1])
                nu_y = float(words[2])
                name = "r"
                newLattice.createRotation(name, nu_x, nu_y)
            elif typeOfElem == "END":
                continue
    
            #if typeOfElem == "":
                # Useful params
                # Useless params
                # Params not stated that I need construct the element
                # Create the element         
        return newLattice
    except:
        print "Parsing failed" + str(sys.exc_info()[-1].tb_lineno)
        return 0