Exemplo n.º 1
0
def earth_model(YeI, YeO, YeM, PREM_file='osc/nuSQuIDS_PREM.dat'):  # pylint: disable=invalid-name
    """Return a `nuSQUIDSpy.EarthAtm` object with
    user-defined electron fractions. Note that a
    temporary Earth model file is produced (over-
    written) each time this function is executed.

    Parameters
    ----------
    YeI, YeO, YeM : float
        electron fractions in Earth's inner core,
        outer core, and mantle
        (defined by spherical shells with radii of
         1121.5, 3480.0, and 6371.0 km)
    PREM_file : str
        path to nuSQuIDS PREM Earth Model file whose
        electron fractions will be modified

    Returns
    -------
    earth_atm : nuSQUIDSpy.EarthAtm
        can be passed to `Set_EarthModel` method of
        a nuSQuIDs propagator object
    """
    logging.debug("Regenerating nuSQuIDS Earth Model with electron"
                  " fractions: YeI=%s, YeO=%s, YeM=%s" % (YeI, YeO, YeM))
    earth_radius = 6371.0 # km
    # radii at which main transitions occur according to PREM
    transition_radii = np.array([1121.5, 3480.0, earth_radius]) # km

    fname_tmp = os.path.join(CACHE_DIR, "nuSQuIDS_PREM_TMP.dat")
    PREM_file = from_file(fname=PREM_file, as_array=True)
    for i, (r, _, _) in enumerate(PREM_file):
        # r is fraction of total radius
        current_radius = r*earth_radius
        if current_radius <= transition_radii[0]:
            # inner core region
            Ye_new = YeI
        elif current_radius <= transition_radii[1]:
            # outer core region
            Ye_new = YeO
        elif current_radius <= transition_radii[2]:
            # mantle region
            Ye_new = YeM
        # update electron fraction
        PREM_file[i][2] = Ye_new
    # make temporary file
    np.savetxt(fname=fname_tmp, X=PREM_file)
    # create and return the Earth model from file
    earth_atm = nsq.EarthAtm(fname_tmp)
    return earth_atm
Exemplo n.º 2
0
def SetNSQParams(nuSQ,flavor_id):
  nuSQ.Set_MixingAngle(0,1,0.59);
  nuSQ.Set_MixingAngle(0,2,0.154085);
  nuSQ.Set_MixingAngle(1,2,th23);
  nuSQ.Set_SquareMassDifference(1,7.54e-05);
  nuSQ.Set_SquareMassDifference(2,dm2*.001);
  nuSQ.Set_CPPhase(0,2,0.0);
  nuSQ.Set_rel_error( 1.0e-15);
  nuSQ.Set_abs_error( 1.0e-15);
  if(flavor_id==1):

   st =(np.array([1 for i in nuSQ.GetERange()]).reshape((200,1)))*(np.array([0.,1.,0.]).reshape(1,3))
  if(flavor_id==0):
    st =(np.array([1 for i in nuSQ.GetERange()]).reshape((200,1)))*(np.array([1.,0.,0.]).reshape(1,3))

  nuSQ.Set_Body(nsq.EarthAtm())
  nuSQ.Set_Track(nsq.EarthAtm.Track(np.arccos(-1.0)))
  nuSQ.Set_initial_state(st,nsq.Basis.flavor);
  nuSQ.EvolveState() 
Exemplo n.º 3
0
def SetNSQParams(zen, nuSQ, flavor_id):
    nuSQ.Set_MixingAngle(0, 1, 0.59)
    nuSQ.Set_MixingAngle(0, 2, 0.154085)
    nuSQ.Set_MixingAngle(1, 2, 0.717)
    nuSQ.Set_SquareMassDifference(1, 7.54e-05)
    nuSQ.Set_SquareMassDifference(2, 0.00243)
    nuSQ.Set_CPPhase(0, 2, 0.0)
    nuSQ.Set_h_max(100.0 * nuSQ.units.km)
    nuSQ.Set_rel_error(1.0e-15)
    nuSQ.Set_abs_error(1.0e-15)
    if (flavor_id == 1):
        st = (np.array([1 for i in nuSQ.GetERange()]).reshape(
            (2, 1))) * (np.array([0., 1., 0.]).reshape(1, 3))
    if (flavor_id == 0):
        st = (np.array([1 for i in nuSQ.GetERange()]).reshape(
            (2, 1))) * (np.array([1., 0., 0.]).reshape(1, 3))
    nuSQ.Set_Body(nsq.EarthAtm())
    nuSQ.Set_Track(nsq.EarthAtm.Track(np.arccos(zen)))
    nuSQ.Set_initial_state(st, nsq.Basis.flavor)
    nuSQ.EvolveState()
Exemplo n.º 4
0
def SetNSQParams(zen, nuSQ, flavor_id):
    nuSQ.Set("th12", 0.59)
    nuSQ.Set("th13", 0.154085)
    nuSQ.Set("th23", 0.717)
    nuSQ.Set("dm21sq", 7.54e-05)
    nuSQ.Set("dm31sq", 0.00243)
    nuSQ.Set("delta1", 0.0)
    nuSQ.Set("h_max", 100.0 * nuSQ.units.km)
    nuSQ.Set("rel_error", 1.0e-15)
    nuSQ.Set("abs_error", 1.0e-15)
    if (flavor_id == 1):
        st = (np.array([1 for i in nuSQ.GetERange()]).reshape(
            (200, 1))) * (np.array([0., 1., 0.]).reshape(1, 3))
    if (flavor_id == 0):
        st = (np.array([1 for i in nuSQ.GetERange()]).reshape(
            (200, 1))) * (np.array([1., 0., 0.]).reshape(1, 3))
    nuSQ.Set_initial_state(st, "flavor")
    nuSQ.Set_Body(nsq.EarthAtm())
    nuSQ.Set_Track(nsq.EarthAtm.Track(np.arccos(zen)))
    nuSQ.EvolveState()
Exemplo n.º 5
0
plt.figure(figsize = (8,6))
plt.xlabel(r"$E_\nu [GeV]$")
plt.ylabel(r"$P(\nu_\mu \to \nu_e)$")
plt.plot(energy_values,nu_mu_to_nu_e, lw = 2, color = 'blue')

# We can now go back to the defaults, which are the values given by Gonzalez-Garcia et al. (arXiv:1409.5439)

nuSQ.Set_MixingParametersToDefault()


# #### Changing where the neutrino propagation takes place

# As in the C++ implementation we can change the `Body` by means of the `Set_Body` function and in similar way we can change the `Track`. Lets do an atmospheric oscillation example =).

nuSQ = nsq.nuSQUIDS(3,nsq.NeutrinoType.neutrino)
nuSQ.Set_Body(nsq.EarthAtm())
nuSQ.Set_Track(nsq.EarthAtm.Track(np.arccos(-1)))
nuSQ.Set_rel_error(1.0e-17)
nuSQ.Set_abs_error(1.0e-17)

energy_values = np.logspace(0,2,120)
nu_mu_to_nu_e = []
nu_mu_to_nu_mu = []
nu_mu_to_nu_tau = []
for Enu in energy_values:
    nuSQ.Set_E(Enu*units.GeV)
    nuSQ.Set_initial_state(np.array([0.,1.,0.]),nsq.Basis.flavor)
    nuSQ.EvolveState()
    nu_mu_to_nu_e.append(nuSQ.EvalFlavor(0))
    nu_mu_to_nu_mu.append(nuSQ.EvalFlavor(1))
    nu_mu_to_nu_tau.append(nuSQ.EvalFlavor(2))
Exemplo n.º 6
0
def NuFlux_Solar(proflux,Enu_min,Enu_max,nodes,ch,DMm,param,theta_12=33.82,theta_23=48.6,theta_13=8.60,delta_m_12=7.39e-5,delta_m_13=2.528e-3,delta=0.,logscale=False,interactions=True,location = 'Earth',time=57754.,angle=None,latitude=-90.,xsec=None):
	''' calculate neutrino flux after propagation for solar wimp (multiple energy mode with interactions)
	@type  proflux  :       str
	@param proflux  :       name of the production flux, e.g. Pythia 
	@type  Enu_min	:	float
	@param Enu_min	:	GeV	
	@type  Enu_max	:	float
	@param Enu_max	:	GeV	
	@type  nodes	:       int	
	@param nodes	:       number of nodes 	
	@type  ch	:       str	
	@param ch	:       channel of the production 	
	@type  DMm	:	float
	@param DMm	:	GeV
	@type  location :       str 
	@param location :       Sunsfc or Earth 
	@type  time     :       float
	@parm  time     :       MJD of the detection time (input can be either the angle or the time) 
	@type  angle    :       float
	@param  angle   :       Zenith angle of the detection in degree (input can be either the angle or the time) 
	@parm  time     :       MJD of the detection time
        @type  latitude :       float
        @param latitude :       latitude of the detector
	@type xsec      :       str
	@param xsec     :       path to neutrino xsec files.  
	@return 	:	flux per annihilation 
	'''
	#Oscillation parameters are from NuFIT 4.1 (2019) normal ordering with delta_cp=0. Adjust according to your need. 
	#default cross section is based on isoscalar target from arXiv: 1106.3723v2. I have also run nusigma which is a neutrino-nucleon cross section writen by J. Edsjo assuming isoscalar target. There files are in `./xsec/`. The choice of the cross sections makes difference.  
	#TODO: implement full MC
	
	#DM_annihilation_rate_Sun = float(np.sum(DM.DMSunAnnihilationRate(DMm*param.GeV,DMsig,param)))*param.sec
	DM_annihilation_rate_Sun = 1.
	E_nodes = nodes
	Enu_min = Enu_min*param.GeV
	Enu_max = Enu_max*param.GeV
	#e_range = np.linspace(Enu_min*pc.GeV,Enu_max*pc.GeV,100)
	if logscale is True:
		e_vector = np.logspace(np.log10(Enu_min),np.log10(Enu_max),E_nodes)
	else:
		e_vector = np.linspace(Enu_min,Enu_max,E_nodes)
	

	
	if proflux == 'Pythia':
	    production = pythiaflux
	elif proflux == 'Herwig':
            production = herwigflux
	elif proflux == 'WimpSim':
	    production = DMSweFluxSun
   	else:	
            print('No Such Production')

	flux = {}
	if xsec == None:
		print(xsec)
		nuSQ = nsq.nuSQUIDS(e_vector,3,nsq.NeutrinoType.both,interactions)
	else:
		print(xsec)
		xsec = nsq.NeutrinoDISCrossSectionsFromTables(xsec+'nusigma_')
		nuSQ = nsq.nuSQUIDS(e_vector,3,nsq.NeutrinoType.both,interactions,xsec)
	energy = nuSQ.GetERange()
	for i in range(3):
		flux[str(i)+'_nu'] = np.array(map(lambda E_nu: production(E_nu/param.GeV,i*2,ch,DMm),energy))
		flux[str(i)+'_nubar'] = np.array(map(lambda E_nu: production(E_nu/param.GeV,i*2+1,ch,DMm),energy))
	nuSQ.Set_Body(nsq.Sun())
	nuSQ.Set_Track(nsq.Sun.Track(param.SUNRADIUS*param.km))
	#nuSQ.Set_Track(nsq.ConstantDensity.Track(param.SUNRADIUS*param.km))
	nuSQ.Set_MixingAngle(0,1,np.deg2rad(theta_12))
	nuSQ.Set_MixingAngle(0,2,np.deg2rad(theta_13))
	nuSQ.Set_MixingAngle(1,2,np.deg2rad(theta_23))
	nuSQ.Set_SquareMassDifference(1,delta_m_12)
	nuSQ.Set_SquareMassDifference(2,delta_m_13)
	nuSQ.Set_abs_error(1.e-10)
	nuSQ.Set_rel_error(1.e-10)
	nuSQ.Set_CPPhase(0,2,delta)
	#nuSQ.Set_ProgressBar(True)
	initial_flux = np.zeros((E_nodes,2,3))
	for j in range(len(flux['0_nu'])):
		for k in range(3):
			initial_flux[j][0][k] = flux[str(k)+'_nu'][j]
			initial_flux[j][1][k] = flux[str(k)+'_nubar'][j]
	nuSQ.Set_initial_state(initial_flux,nsq.Basis.flavor)
	nuSQ.Set_TauRegeneration(True)
	nuSQ.EvolveState()
	
	e_range = np.linspace(Enu_min,Enu_max,nodes)
	flux_surface = np.zeros(len(e_range),dtype = [('Energy','float'),('nu_e','float'),('nu_mu','float'),('nu_tau','float'),('nu_e_bar','float'),('nu_mu_bar','float'),('nu_tau_bar','float'),('zenith','float')]) 
	

	factor = 1. 
	if location == 'Sunsfc':
		#factor = DM_annihilation_rate_Sun/(4.0*np.pi*(param.SUNRADIUS*param.km/param.cm)**2*DMm)
		flux_surface['Energy'] = e_range 
		flux_surface['nu_e'] = factor*np.array([nuSQ.EvalFlavor(0,e,0) for e in   e_range])
		flux_surface['nu_mu'] = factor*np.array([nuSQ.EvalFlavor(1,e,0) for e in  e_range])
		flux_surface['nu_tau'] = factor*np.array([nuSQ.EvalFlavor(2,e,0) for e in e_range])
		flux_surface['nu_e_bar'] = factor*np.array([nuSQ.EvalFlavor(0,e,1) for e in e_range])
		flux_surface['nu_mu_bar'] = factor*np.array([nuSQ.EvalFlavor(1,e,1) for e in e_range])
		flux_surface['nu_tau_bar'] = factor*np.array([nuSQ.EvalFlavor(2,e,1) for e in e_range])
		
		return flux_surface

	elif location == 'Earth':
		flux_earth = flux_surface
		if angle == None:
			zenith = SunZenith(time,latitude)
		else:
			##print (angle)
			zenith = np.deg2rad(angle)
		d_tot, d_vacuum, d_earthatm = Distance(zenith,param)
		
		#factor = DM_annihilation_rate_Sun/(4.0*np.pi*(param.AU/param.cm)**2*DMm)
		#factor = DM_annihilation_rate_Sun/(4.0*np.pi*(d_tot*param.km/param.cm)**2*DMm)

	
		composition_new =np.array([[[nuSQ.EvalFlavor(0,e,0),nuSQ.EvalFlavor(1,e,0),nuSQ.EvalFlavor(2,e,0)],[nuSQ.EvalFlavor(0,e,1),nuSQ.EvalFlavor(1,e,1),nuSQ.EvalFlavor(2,e,1)]] for e in e_range])
	##print composition_new
		
		nuSQ.Set_Body(nsq.Vacuum())
		
		nuSQ.Set_Track(nsq.Vacuum.Track(float(d_vacuum)*param.km))
		nuSQ.Set_ProgressBar(True)
	
		nuSQ.Set_initial_state(composition_new,nsq.Basis.flavor)
		nuSQ.Set_TauRegeneration(True)
		nuSQ.EvolveState()
		
		composition_new =np.array([[[nuSQ.EvalFlavor(0,e,0),nuSQ.EvalFlavor(1,e,0),nuSQ.EvalFlavor(2,e,0)],[nuSQ.EvalFlavor(0,e,1),nuSQ.EvalFlavor(1,e,1),nuSQ.EvalFlavor(2,e,1)]] for e in e_range])
		
		nuSQ.Set_Body(nsq.EarthAtm())
		nuSQ.Set_Track(nsq.EarthAtm.Track(zenith))
		nuSQ.Set_ProgressBar(True)
	
		nuSQ.Set_initial_state(composition_new,nsq.Basis.flavor)
		nuSQ.Set_TauRegeneration(True)
		nuSQ.EvolveState()
		flux_earth['Energy']     = e_range 
		flux_earth['nu_e']       = factor*np.array([nuSQ.EvalFlavor(0,e,0) for e in   e_range])
		flux_earth['nu_mu']      = factor*np.array([nuSQ.EvalFlavor(1,e,0) for e in  e_range])
		flux_earth['nu_tau']     = factor*np.array([nuSQ.EvalFlavor(2,e,0) for e in e_range])
		flux_earth['nu_e_bar']   = factor*np.array([nuSQ.EvalFlavor(0,e,1) for e in e_range])
		flux_earth['nu_mu_bar']  = factor*np.array([nuSQ.EvalFlavor(1,e,1) for e in e_range])
		flux_earth['nu_tau_bar'] = factor*np.array([nuSQ.EvalFlavor(2,e,1) for e in e_range])
		flux_earth['zenith']	   = np.array([zenith]*len(e_range))	
	
		return flux_earth
Exemplo n.º 7
0
def propagate(
    iniflux,
    Ein,
    Eout,
    location_ini,
    location_end,
    theta_12=33.82,
    theta_23=48.6,
    theta_13=8.60,
    delta_m_12=7.39e-5,
    delta_m_13=2.528e-3,
    delta=0.0,
    interactions=True,
    xsec=None,
    secluded=False,
    r=0.0,
    mass_v=0.0,
    zenith=0.0,
    avg=True,
    pathSunModel=None,
    pathEarthModel=None,
):
    r"""propagate neutrino flux

    Parameters
    ----------
    iniflux         :  array
                       initial flux for propagation
    Ein             :  array
                       energies of the initial flux
    Eout            :  array
                       energies of the output flux
    location_ini    :  str
                       location of neutrino production
    location_end    :  str
                       location that the flux propagates to
    pathSunModel    :  str
                       path to the Sun profile
    pathEarthModel  :  str
                       path to the Earth profile
    theta_12        :  float
                       theta_12 in degree
    theta_23        :  float
                       theta_23 in degree
    theta_13        :  float
                       theta_13 in degree
    delta_m_12      :  float
                       delta_m_12 square in eV^2
    delta_m_13      :  float
                       delta_m_13 square in eV^2
    delta           :  float
                       cp phase in degree
    interactions    :  bool
                       whether to included interactions between nodes
    xsec            :  str
                       Use default cross sections if None. Or can use external table of cross section with names    `n(p)_sigma_CC(NC).dat`,`n(p)_dsde_CC(NC).dat`.
    secluded        :  bool
                       standard or secluded
    r               :  float or list
                       if secluded, the distance picked
    mass_v          :   float
                        mediator_mass in GeV
    zenith          :  float
                       zenith angle in radian
    avg             :  bool
                       whether to average out flux
    Returns
    -------
    flux     :  array
                averaged flux of a specific flavor.
    """

    flavor_list = {
        0: "nu_e",
        1: "nu_e_bar",
        2: "nu_mu",
        3: "nu_mu_bar",
        4: "nu_tau",
        5: "nu_tau_bar",
    }
    if xsec == None:
        xsec = nsq.NeutrinoDISCrossSectionsFromTables(dirpath + "/xsec/nusigma_")
        nuSQ = nsq.nuSQUIDS(Ein * pc.GeV, 3, nsq.NeutrinoType.both, interactions, xsec)
    else:
        xsec = nsq.NeutrinoDISCrossSectionsFromTables(xsec)
        nuSQ = nsq.nuSQUIDS(Ein * pc.GeV, 3, nsq.NeutrinoType.both, interactions, xsec)

    nuSQ.Set_MixingAngle(0, 1, np.deg2rad(theta_12))
    nuSQ.Set_MixingAngle(0, 2, np.deg2rad(theta_13))
    nuSQ.Set_MixingAngle(1, 2, np.deg2rad(theta_23))
    nuSQ.Set_SquareMassDifference(1, delta_m_12)
    nuSQ.Set_SquareMassDifference(2, delta_m_13)
    nuSQ.Set_abs_error(1.0e-10)
    nuSQ.Set_rel_error(1.0e-10)
    nuSQ.Set_CPPhase(0, 2, np.deg2rad(delta))
    nuSQ.Set_ProgressBar(True)
    nuSQ.Set_TauRegeneration(True)
    flux_output = np.zeros(
        len(Eout),
        dtype=[
            ("Energy", "float"),
            ("nu_e", "float"),
            ("nu_mu", "float"),
            ("nu_tau", "float"),
            ("nu_e_bar", "float"),
            ("nu_mu_bar", "float"),
            ("nu_tau_bar", "float"),
            ("zenith", "float"),
        ],
    )
    # Standard case
    if not secluded:
        # from Sun
        if location_ini == "Sun":
            if pathSunModel == None:
                nuSQ.Set_Body(nsq.Sun(dirpath + "/models/struct_b16_agss09.dat"))
            else:
                nuSQ.Set_Body(nsq.Sun(pathSunModel))
            nuSQ.Set_Track(nsq.Sun.Track(0.0, pc.SUNRADIUS * pc.km))
            nuSQ.Set_initial_state(iniflux, nsq.Basis.flavor)
            nuSQ.EvolveState()

            # flux at sun surface
            if location_end == "SunSurface":
                zenith = None

            # flux at 1AU
            elif location_end == "1AU":
                nuSQ.Set_Body(nsq.Vacuum())
                nuSQ.Set_Track(nsq.Vacuum.Track(pc.AU - pc.SUNRADIUS * pc.km))
                nuSQ.EvolveState()

            # flux at detector
            elif location_end == "detector":
                nuSQ.Set_Body(nsq.Vacuum())
                d_vacuum = float(Distance(zenith)[1])
                nuSQ.Set_Track(nsq.Vacuum.Track(d_vacuum * pc.km))
                nuSQ.EvolveState()
                if pathEarthModel == None:
                    nuSQ.Set_Body(nsq.EarthAtm())
                else:
                    nuSQ.Set_Body(nsq.EarthAtm(pathEarthModel))
                nuSQ.Set_Track(nsq.EarthAtm.Track(zenith))
                nuSQ.EvolveState()

        # from Earth
        elif location_ini == "Earth":

            # flux at detector
            if location_end == "detector":
                if pathEarthModel == None:
                    nuSQ.Set_Body(nsq.Earth())
                else:
                    nuSQ.Set_Body(nsq.Earth(pathEarthModel))
                # nuSQ.Set_Body(nsq.Earth())
                nuSQ.Set_Track(
                    nsq.Earth.Track(
                        pc.EARTHRADIUS * pc.km,
                        2 * pc.EARTHRADIUS * pc.km,
                        2 * pc.EARTHRADIUS * pc.km,
                    )
                )
                nuSQ.Set_initial_state(iniflux, nsq.Basis.flavor)
                nuSQ.EvolveState()

        # from Halo
        elif location_ini == "Halo":

            osc_matrix = angles_to_u(theta_12, theta_13, theta_23, delta)
            composition_nu = np.array(
                [
                    u_to_fr(
                        [iniflux[j, 0, 0], iniflux[j, 0, 1], iniflux[j, 0, 2]],
                        osc_matrix,
                    )
                    for j in range(len(Ein))
                ]
            )
            composition_nubar = np.array(
                [
                    u_to_fr(
                        [iniflux[j, 1, 0], iniflux[j, 1, 1], iniflux[j, 1, 2]],
                        osc_matrix,
                    )
                    for j in range(len(Ein))
                ]
            )

            # flux at Earth surface before entering matter
            if location_end == "Earth" or zenith <= np.pi / 2.0:
                for i in range(3):
                    inter_nu = interp1d(Ein, composition_nu[:, i])
                    inter_nubar = interp1d(Ein, composition_nubar[:, i])
                    flux_output[flavor_list[2 * i]] = inter_nu(Eout)
                    flux_output[flavor_list[2 * i + 1]] = inter_nubar(Eout)

                flux_output["Energy"] = Eout
                flux_output["zenith"] = np.array([zenith] * len(Eout))
                return flux_output

            # flux at detector
            elif location_end == "detector":
                if pathEarthModel == None:
                    nuSQ.Set_Body(nsq.Earth())
                else:
                    nuSQ.Set_Body(nsq.Earth(pathEarthModel))
                # nuSQ.Set_Body(nsq.Earth())
                nuSQ.Set_Track(
                    nsq.Earth.Track(2 * abs(np.cos(zenith)) * pc.EARTHRADIUS * pc.km)
                )
                surface_flux = np.zeros((len(composition_nu), 2, 3))
                for i in range(3):
                    surface_flux[:, 0, i] = composition_nu[:, i]
                    surface_flux[:, 1, i] = composition_nubar[:, i]
                nuSQ.Set_initial_state(surface_flux, nsq.Basis.flavor)
                nuSQ.EvolveState()

    # Secluded case
    elif secluded:

        theta = 0.0
        # from Sun
        if location_ini == "Sun":
            b_impact = np.sin(theta) * r
            if r < pc.SUNRADIUS:
                if theta <= np.pi / 2.0:
                    xini = xini_Sun(b_impact, r, zenith)[0][1]
                else:
                    xini = xini_Sun(b_impact, r, zenith)[0][0]

                if b_impact != 0:
                    l = 2 * np.sqrt(pc.SUNRADIUS ** 2 - b_impact ** 2)
                    if pathSunModel == None:
                        nuSQ.Set_Body(
                            nsq.SunASnu(dirpath + "/models/struct_b16_agss09.dat")
                        )
                    else:
                        nuSQ.Set_Body(nsq.SunASnu(pathSunModel))
                    nuSQ.Set_Track(
                        nsq.SunASnu.Track(l * pc.km, xini * pc.km, b_impact * pc.km)
                    )

                elif b_impact == 0:
                    if pathSunModel == None:
                        nuSQ.Set_Body(
                            nsq.Sun(dirpath + "/models/struct_b16_agss09.dat")
                        )
                    else:
                        nuSQ.Set_Body(nsq.Sun(pathSunModel))
                    nuSQ.Set_Track(nsq.Sun.Track(xini * pc.km, pc.SUNRADIUS * pc.km))

                nuSQ.Set_initial_state(iniflux, nsq.Basis.flavor)
                nuSQ.EvolveState()

            # flux at sun surface
            if location_end == "SunSurface":
                pass

            # flux at 1AU
            elif location_end == "1AU":
                if r < pc.SUNRADIUS:
                    nuSQ.Set_Body(nsq.Vacuum())
                    nuSQ.Set_Track(nsq.Vacuum.Track(pc.AU - pc.SUNRADIUS * pc.km))
                elif r >= pc.SUNRADIUS and r < pc.AU / pc.km - pc.EARTHRADIUS:
                    nuSQ.Set_Body(nsq.Vacuum())
                    nuSQ.Set_Track(nsq.Vacuum.Track(pc.AU - r * pc.km))
                    nuSQ.Set_initial_state(iniflux, nsq.Basis.flavor)
                nuSQ.EvolveState()

            # flux at detector
            elif location_end == "detector":
                nuSQ.Set_Body(nsq.Vacuum())
                if r < pc.SUNRADIUS:
                    nuSQ.Set_Track(
                        nsq.Vacuum.Track(xini_Sun(b_impact, r, zenith)[1] * pc.km)
                    )
                elif r >= pc.SUNRADIUS and r < pc.AU / pc.km - pc.EARTHRADIUS:
                    nuSQ.Set_Track(
                        nsq.Vacuum.Track(xini_Sun(b_impact, r, zenith)[0][1] * pc.km)
                    )
                    nuSQ.Set_initial_state(iniflux, nsq.Basis.flavor)
                nuSQ.EvolveState()
                if pathEarthModel == None:
                    nuSQ.Set_Body(nsq.EarthAtm())
                else:
                    nuSQ.Set_Body(nsq.EarthAtm(pathEarthModel))
                nuSQ.Set_Track(nsq.EarthAtm.Track(zenith))
                nuSQ.EvolveState()

        # from the Earth
        elif location_ini == "Earth" and location_end == "detector":
            xini = xini_Earth(np.pi, r)[0][1]
            if pathEarthModel == None:
                nuSQ.Set_Body(nsq.Earth())
            else:
                nuSQ.Set_Body(nsq.Earth(pathEarthModel))
            nuSQ.Set_Track(
                nsq.Earth.Track(
                    xini * pc.km, 2 * pc.EARTHRADIUS * pc.km, 2 * pc.EARTHRADIUS * pc.km
                )
            )
            nuSQ.Set_initial_state(iniflux, nsq.Basis.flavor)
            nuSQ.EvolveState()

    flux_output["Energy"] = Eout
    flux_output["zenith"] = np.array([zenith] * len(Eout))
    Eout = Eout * pc.GeV
    if avg:
        flux_output["nu_e"] = average(nuSQ, Eout, [0, 0])
        flux_output["nu_mu"] = average(nuSQ, Eout, [1, 0])
        flux_output["nu_tau"] = average(nuSQ, Eout, [2, 0])
        flux_output["nu_e_bar"] = average(nuSQ, Eout, [0, 1])
        flux_output["nu_mu_bar"] = average(nuSQ, Eout, [1, 1])
        flux_output["nu_tau_bar"] = average(nuSQ, Eout, [2, 1])
    else:
        flux_output["nu_e"] = np.array([nuSQ.EvalFlavor(0, e, 0) for e in Eout])
        flux_output["nu_mu"] = np.array([nuSQ.EvalFlavor(1, e, 0) for e in Eout])
        flux_output["nu_tau"] = np.array([nuSQ.EvalFlavor(2, e, 0) for e in Eout])
        flux_output["nu_e_bar"] = np.array([nuSQ.EvalFlavor(0, e, 1) for e in Eout])
        flux_output["nu_mu_bar"] = np.array([nuSQ.EvalFlavor(1, e, 1) for e in Eout])
        flux_output["nu_tau_bar"] = np.array([nuSQ.EvalFlavor(2, e, 1) for e in Eout])

    return flux_output