def generate_ne_profile(simul,**kwargs):
    global neHatPre
    global dneHatPredpsi
    # for use in d-He scan where the electron profile is fixed
    if "nScale_"+species[e_index] in kwargs.keys():
        neScale=kwargs["nScale_"+species[e_index]]
    else:
        neScale=1.0
    nePed=neScale*kwargs["nped_"+species[e_index]]
    neCoreGrad=neScale*kwargs["dnCoredx_"+species[e_index]]*dxdpsiN_at_a
    nepedGrad=neScale*kwargs["dnpeddx_"+species[e_index]]*dxdpsiN_at_a
    neSOLGrad=neScale*kwargs["dnSOLdx_"+species[e_index]]*dxdpsiN_at_a

    if mtanh:
        (neHat,dneHatds) = generate_m2tanh_profile(nePed,neCoreGrad,nepedGrad,neSOLGrad,psiMaxPed-psiMinPed,psiMinPed)
        (core,ped,sol,ddx_core,ddx_ped,ddx_sol) = extrapolate_m2tanh_sections(neHat,dneHatds,psiMin,psiMinPed,psiMaxPed,psiMax)
        neHatPre = core
        dneHatPredpsi = ddx_core
    else:
        neHatPre =(lambda psiN: (nePed-neCoreGrad*(psiMinPed-psiMin) +  neCoreGrad* (psiN-psiMin)))
        neHatPed =(lambda psiN: (nePed +  nepedGrad* (psiN-psiMinPed)))
        neHatAft =(lambda psiN: (nePed+nepedGrad*(psiMaxPed-psiMinPed) +  neSOLGrad* (psiN-psiMaxPed)))
    
        dneHatPredpsi = (lambda psiN:  neCoreGrad + psiN*0)
        dneHatPeddpsi = (lambda psiN:  nepedGrad + psiN*0)
        dneHatAftdpsi = (lambda psiN:  neSOLGrad + psiN*0)
    
        nelist=[neHatPre,neHatPed,neHatAft]
        dnedpsiList = [dneHatPredpsi,dneHatPeddpsi,dneHatAftdpsi] 
        (neHat,dneHatdpsi)=derivative_bezier_transition(nelist,dnedpsiList,psiList,pairList)
        dneHatds = lambda x : dneHatdpsi(x)

    
    
    return (neHat,dneHatds)
def generate_ni_profile(**kwargs):
    # for use in d-He scan where the electron profile varies
    global niPed
    global niCoreGrad
    global niHatPed
    global niHatAft 
    global dniHatAftdpsi
    if "nScale_"+species[main_index] in kwargs.keys():
        niScale=kwargs["nScale_"+species[main_index]]
    else:
        niScale=1.0
    niPed=niScale*kwargs["nped_"+species[main_index]]
    niCoreGrad=niScale*kwargs["dnCoredx_"+species[main_index]]*dxdpsiN_at_a
    nipedGrad=niScale*kwargs["dnpeddx_"+species[main_index]]*dxdpsiN_at_a
    niSOLGrad=niScale*kwargs["dnSOLdx_"+species[main_index]]*dxdpsiN_at_a
    

    # generate n_i
    if mtanh:
        (niHat,dniHatds) = generate_m2tanh_profile(niPed,niCoreGrad,nipedGrad,niSOLGrad,psiMaxPed-psiMinPed,psiMinPed)
        (core,ped,sol,ddx_core,ddx_ped,ddx_sol) = extrapolate_m2tanh_sections(niHat,dniHatds,psiMin,psiMinPed,psiMaxPed,psiMax)
        niHatPed = ped
        niHatAft = sol
        dniHatAftdpsi = ddx_sol
    else:
        niHatPre =(lambda psiN: (niPed + niCoreGrad*(psiN-psiMinPed)))
        niHatPed =(lambda psiN: (niPed +  nipedGrad* (psiN-psiMinPed)))
        niHatAft =(lambda psiN: (niPed+nipedGrad*(psiMaxPed-psiMinPed) +  niSOLGrad* (psiN-psiMaxPed)))

        dniHatPredpsi = (lambda psiN:  niCoreGrad + 0*psiN)
        dniHatPeddpsi = (lambda psiN:  nipedGrad + 0*psiN)
        dniHatAftdpsi = (lambda psiN:  niSOLGrad + 0*psiN)

        nilist=[niHatPre,niHatPed,niHatAft]
        dnidpsiList = [dniHatPredpsi,dniHatPeddpsi,dniHatAftdpsi] 
        
        (niHat,dniHatds)=derivative_bezier_transition(nilist,dnidpsiList,psiList,pairList)
    
    return (niHat,dniHatds)
def generate_T_profiles(**kwargs):
    global TiHatPed
    global TiHatAft
    global dTiHatAftdpsi
    
    #THats = numpy.zeros((Nspecies,Npsi))
    #dTHatdpsis = numpy.zeros((Nspecies,Npsi))
    THats = [None]*Nspecies
    dTHatdpsis = [None]*Nspecies
    dTHatdss = [None]*Nspecies
    
    TScale=[0]*Nspecies
    Tpeds=[0]*Nspecies
    TCoreGrads=[0]*Nspecies
    TpedGrads=[0]*Nspecies
    TSOLGrads=[0]*Nspecies
    
    #Pre,Ped,Aft will contain functions describe T in core, ped and outwards.
    THatPre=[0]*Nspecies
    THatPed=[0]*Nspecies
    THatAft=[0]*Nspecies

    dTHatPredpsi=[0]*Nspecies
    dTHatPeddpsi=[0]*Nspecies
    dTHatAftdpsi=[0]*Nspecies
    
    #reading T related parameters
    for i in range(Nspecies):
        if "TScale_"+species[i] in kwargs.keys():
            TScale[i]=kwargs["TScale_"+species[i]]
        else:
            TScale[i]=1.0
        Tpeds[i]=TScale[i]*kwargs["Tped_"+species[i]]
        TCoreGrads[i]=TScale[i]*kwargs["dTCoredx_"+species[i]]*dxdpsiN_at_a
        TpedGrads[i]=TScale[i]*kwargs["dTpeddx_"+species[i]]*dxdpsiN_at_a
        TSOLGrads[i]=TScale[i]*kwargs["dTSOLdx_"+species[i]]*dxdpsiN_at_a
        TSOLGrads[i]=TScale[i]*kwargs["dTSOLdx_"+species[i]]*dxdpsiN_at_a
        
    TScale=numpy.array(TScale)
    Tpeds=numpy.array(Tpeds)
    TCoreGrads=numpy.array(TCoreGrads)
    TSOLGrads=numpy.array(TSOLGrads)
    TpedGrads=numpy.array(TpedGrads)
    
    if mtanh:
        for i in range(Nspecies):
            (THats[i],dTHatdss[i]) = generate_m2tanh_profile(Tpeds[i],TCoreGrads[i],TpedGrads[i],TSOLGrads[i],psiMaxPed-psiMinPed,psiMinPed)
        (core,ped,sol,ddx_core,ddx_ped,ddx_sol) = extrapolate_m2tanh_sections(THats[main_index],dTHatdss[main_index],psiMin,psiMinPed,psiMaxPed,psiMax)

        TiHatPed = ped
        TiHatAft = sol
        dTiHatAftdpsi = ddx_sol
    else:
        #Generating functions from the parameters
        for i in range(Nspecies):
            THatPre[i] =(lambda psiN,i=i: (Tpeds[i] + TCoreGrads[i]*(psiN-psiMinPed)))
            THatPed[i] =(lambda psiN,i=i: (Tpeds[i] + TpedGrads[i]*(psiN-psiMinPed)))
            THatAft[i] =(lambda psiN,i=i: (Tpeds[i] + TpedGrads[i]*(psiMaxPed-psiMinPed) + TSOLGrads[i]*(psiN-psiMaxPed)))
            dTHatPredpsi[i] = (lambda psiN,i=i: TCoreGrads[i])
            dTHatPeddpsi[i] = (lambda psiN,i=i: TpedGrads[i])
            dTHatAftdpsi[i] = (lambda psiN,i=i: TSOLGrads[i])
            Tlist=[THatPre[i],THatPed[i],THatAft[i]]
            dTdpsiList = [dTHatPredpsi[i],dTHatPeddpsi[i],dTHatAftdpsi[i]]
            
            (THats[i],dTHatdpsis[i])=derivative_bezier_transition(Tlist,dTdpsiList,psiList,pairList)
            dTHatdss[i]=lambda x,i=i: dTHatdpsis[i](x)
        
    
        TiHatPed = THatPed[main_index]
        TiHatAft = THatAft[main_index]
        dTiHatAftdpsi = dTHatAftdpsi[main_index]
    
    return (THats,dTHatdss)
def generate_T_profiles_sameflux(nt,nb,breakpoint_shift,**kwargs):
    global TiHatPed
    global TiHatAft
    global dTiHatAftdpsi
    
    #THats = numpy.zeros((Nspecies,Npsi))
    #dTHatdpsis = numpy.zeros((Nspecies,Npsi))
    THats = [None]*Nspecies
    dTHatdpsis = [None]*Nspecies
    dTHatdss = [None]*Nspecies
    
    TScale=[0]*Nspecies
    Tpeds=[0]*Nspecies
    TCoreGrads=[0]*Nspecies
    TpedGrads=[0]*Nspecies
    TSOLGrads=[0]*Nspecies

    #Pre,Ped,Aft will contain functions describe T in core, ped and outwards.
    THatPre=[0]*Nspecies
    THatPed=[0]*Nspecies
    THatAft=[0]*Nspecies

    dTHatPredpsi=[0]*Nspecies
    dTHatPeddpsi=[0]*Nspecies
    dTHatAftdpsi=[0]*Nspecies
    
    #reading T related parameters
    for i in range(Nspecies):
        if "TScale_"+species[i] in kwargs.keys():
            TScale[i]=kwargs["TScale_"+species[i]]
        else:
            TScale[i]=1.0
        Tpeds[i]=TScale[i]*kwargs["Tped_"+species[i]]
        TCoreGrads[i]=TScale[i]*kwargs["dTCoredx_"+species[i]]*dxdpsiN_at_a
        TpedGrads[i]=TScale[i]*kwargs["dTpeddx_"+species[i]]*dxdpsiN_at_a
        TSOLGrads[i]=TScale[i]*kwargs["dTSOLdx_"+species[i]]*dxdpsiN_at_a
        
    TScale=numpy.array(TScale)
    Tpeds=numpy.array(Tpeds)
    TCoreGrads=numpy.array(TCoreGrads)
    TSOLGrads=numpy.array(TSOLGrads)
    TpedGrads=numpy.array(TpedGrads)
    
    if mtanh:
        transition_length = 1*(psiMaxPed-psiMinPed)
        (THats[main_index],dTHatdss[main_index]) = match_heat_flux_proxy(Tpeds[main_index],TCoreGrads[main_index],TpedGrads[main_index],TSOLGrads[main_index],transition_length,psiMinPed,nt,nb,psiMin,psiMax)
        (core,ped,sol,ddx_core,ddx_ped,ddx_sol) = extrapolate_m2tanh_sections(THats[main_index],dTHatdss[main_index],psiMin,psiMinPed,psiMaxPed,psiMax)
        
        TiHatPed = ped
        TiHatAft = sol
        dTiHatAftdpsi = ddx_sol
        
        if Nspecies >= 2:
            (THats[e_index],dTHatdss[e_index]) = generate_m2tanh_profile(Tpeds[e_index],TCoreGrads[e_index],TpedGrads[e_index],TSOLGrads[e_index],psiMaxPed-psiMinPed,psiMinPed)
    else:
        breakpoint=psiMinPed + breakpoint_shift
        Tp=Tpeds[main_index] + TCoreGrads[main_index] *(breakpoint-psiMinPed)

        if (TCoreGrads[main_index] != TSOLGrads[main_index]) and (TPedGrads[main_index] != TSOLGrads[main_index]):
            print "generate_compatible_profiles: Warning: sameflux option uses the Core T gradients of the main species everywhere"
        dTdpsi=TCoreGrads[main_index]
        d1=breakpoint - psiMin
        d2=psiMax - breakpoint

        f=lambda x : x*(Tp-d1*x)**(3.0/2.0) - (nb*1.0/nt)*(Tp + dTdpsi*d2)**(3.0/2.0)*dTdpsi
        dTdpsiTop=scipy.optimize.fsolve(f,0)[0] #[0] since returns an numpy.ndarray
        dTdpsiBot=dTdpsi

        THatPre[main_index] =(lambda psiN: (Tpeds[main_index] + dTdpsiTop*(psiN-breakpoint)))
        THatPed[main_index] =(lambda psiN: (Tpeds[main_index] + dTdpsiBot*(psiN-breakpoint)))
        THatAft[main_index] =(lambda psiN: (Tpeds[main_index] + dTdpsiBot*(psiN-breakpoint)))
        dTHatPredpsi[main_index] =(lambda psiN: dTdpsiTop + 0*psiN)
        dTHatPeddpsi[main_index] =(lambda psiN: dTdpsiBot + 0*psiN)
        dTHatAftdpsi[main_index] =(lambda psiN: dTdpsiBot + 0*psiN)


        Tlist=[THatPre[main_index],THatPed[main_index]]
        dTdpsilist=[dTHatPredpsi[main_index],dTHatPeddpsi[main_index]]

        (THats[main_index],dTHatdpsis[main_index])=derivative_bezier_transition(Tlist,dTdpsilist,[breakpoint],pairList[:-1])    
        dTHatdss[main_index]= lambda x : dTHatdpsis[main_index](x)

        #T2=simul.TBar*bezier_transition(Tlist,[breakpoint],pairList[:-1],numpy.array([psiMidPed]))[0]

        TiHatPed = THatPed[main_index]
        TiHatAft = THatAft[main_index]
        dTiHatAftdpsi = dTHatAftdpsi[main_index]
        
        if Nspecies >= 2:
            #T_e:
            THatPre[e_index] =(lambda psiN: (Tpeds[e_index] + TCoreGrads[e_index]*(psiN-psiMinPed)))
            THatPed[e_index] =(lambda psiN: (Tpeds[e_index] + TpedGrads[e_index]*(psiN-psiMinPed)))
            THatAft[e_index] =(lambda psiN: (Tpeds[e_index] + TpedGrads[e_index]*(psiMaxPed-psiMinPed) + TSOLGrads[e_index]*(psiN-psiMaxPed)))
            dTHatPredpsi[e_index] = (lambda psiN: TCoreGrads[e_index] + 0*psiN)
            dTHatPeddpsi[e_index] = (lambda psiN: TpedGrads[e_index] + 0*psiN)
            dTHatAftdpsi[e_index] = (lambda psiN: TSOLGrads[e_index] + 0*psiN)
            Tlist=[THatPre[e_index],THatPed[e_index],THatAft[e_index]]
            dTdpsiList = [dTHatPredpsi[e_index],dTHatPeddpsi[e_index],dTHatAftdpsi[e_index]]

            (THats[e_index],dTHatdpsis[e_index])=derivative_bezier_transition(Tlist,dTdpsiList,psiList,pairList)
            dTHatdss[e_index]=lambda x : dTHatdpsis[e_index](x)

    if Nspecies == 3:
        THats[imp_index]=THats[main_index]
        #dTHatdpsis[imp_index]=dTHatdpsis[main_index]
        dTHatdss[imp_index]=dTHatdss[main_index]


    
    
    return (THats,dTHatdss)