def parseLatticeString(text, facility):
    spaceChargeOn = facility.getSpaceChargeOn()
    multipart = facility.getMultipart()
    twiss = facility.getTwiss()
    beamdata = facility.getBeamdata()
    nbrOfSplits = facility.getNbrOfSplits()
    lattice = Lattice('ParsedLattice', beamdata, twiss, multipart)
    for line in iter(text.splitlines()):
        words = line.split()
        typeOfElem = words[0]
        name = words[1]
        l = float(words[words.index("L:") + 1]) #what comes after "L:"
        if typeOfElem == "cavity":
            cavityOscillations = float(words[words.index("Oscillations:") + 1])
            cavityAmplitudeA = float(words[words.index("AmplitudeA:") + 1])
            cavityAmplitudeB = float(words[words.index("AmplitudeB:") + 1])
            cavityE_0 = float(words[words.index("E_0:") + 1])
            cavitySigma = float(words[words.index("sigma:") + 1])
            cavityP = float(words[words.index("p:") + 1])

            cavityEzofs = [cavityOscillations, cavityAmplitudeA, cavityAmplitudeB, cavityE_0, cavitySigma, cavityP]
            elem = Cavity(name, l, cavityEzofs, beamdata, nbrOfSplits)
            lattice.appendElement(elem)
            continue
        if typeOfElem == "dipole":
            rho = float(words[words.index("rho:") + 1]) #what comes after "rho:"
            #k_x = what comes after "K_x: "
            #k_y = what comes after "K_y: " # not needed for construction
            beta = beamdata[0]
            nparam = float(words[words.index("nparam:") + 1]) #what comes after "nparam:"
            alpha = float(words[words.index("Alpha:") + 1]) #what comes after "Alpha:"
            #elem = Dipole(name, rho, alpha, nparam, spaceChargeOn, multipart, twiss, beamdata, nbrOfSplits)
            lattice.createDipole(name, rho, alpha, nparam)
            continue
        elif typeOfElem != "drift" and typeOfElem != "cavity":
            k = float(words[words.index("K:") + 1]) #what comes after "K:"
        if typeOfElem == "liealgelem":
            hamToUse = words[words.index("HamUsed:") + 1] #what comes after "HamUsed:" and before next whitespace
            order = int(words[words.index("Order:") + 1]) #what comes after "Order:"
            #elem = LieAlgElement(name, hamToUse, k, l, order, spaceChargeOn, multipart, twiss, beamdata, nbrOfSplits)
            lattice.createSextupole(name, k, l, order)
            continue
        
        if typeOfElem == "quad":
            #elem = Quad(name, k, l, spaceChargeOn, multipart, twiss, beamdata, nbrOfSplits)
            lattice.createQuadrupole(name, k, l)
            continue
        if typeOfElem == "drift":
            #elem = Drift(name, l, spaceChargeOn, multipart, twiss, beamdata, nbrOfSplits)
            lattice.createDrift(name, l)
            continue           
    return lattice
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
freq = 704.42e6 # (Hz) from ref. F

rf_lambda = constants.c/freq  # beam data needed
m = constants.m_p
beta = betaFromE(m, E)
q = constants.e
beamdata = [beta, rf_lambda, m, q, E]

#envelopeInComp = np.array([1, 0, 0, 1, 0, 0, 1, 0, 0])
envelopeInComp = envelopeFromMultipart(multipartfromold)
#print "envelopeInComp: " + str(envelopeInComp)

nbrOfSplits = 1

## the lattice will be a FODSO cell (Focusing Quad, Drift, Defocusing Quad, Sextupole, Drift)
compLattice = Lattice('compLattice', beamdata, twissfromold, multipartfromold)

cavityName = "cavity"
cavityLength = 2.0
cavityOscillations = 2
cavityAmplitudeA = 0
cavityAmplitudeB = 30 # 30 MeV / m
cavityE_0 = cavityAmplitudeB
cavitySigma = 1
cavityP = 3
cavityEzofs = [cavityOscillations, cavityAmplitudeA, cavityAmplitudeB, cavityE_0, cavitySigma, cavityP]
cavity = Cavity(cavityName, cavityLength, cavityEzofs, beamdata, nbrOfSplits) # Changes beta in beamdata!
E = cavity.getNewE() # Updates the energy
compLattice.appendElement(cavity)
print compLattice.printLattice()