def _pipeline_s3d(self, iX, vgrad, genimg=True):
		"""
		SPARX-3D pipeline
		"""
		# Setup filenames
		src = self.s3d_srcs[iX]
		pop = self.s3d_pops[iX]
		img = self.s3d_imgs[iX]
		cnv = self.s3d_cnvs[iX]
		tmb = self.s3d_tmbs[iX]
		Xmol = self.Xmol_list[iX]

		# Reset inputs (safer)
		inputs.reset_inputs()

		# Generate model grid
		if not exists(src):
			if self.ndiv == None:
				ndiv = 16
			else:
				ndiv = self.ndiv * 2
			tasks.task_leiden3d(out=src, xmol=Xmol, vgrad=vgrad, tk=opts.tk, tcmb=self.tcmb, ndiv=ndiv)

		self._pipeline_sparx(Xmol, src, pop, img, cnv, tmb, genimg)
		return
    table = [
        '# %20s %20s %20s %20s %20s %20s %20s %20s %20s' %
        ('Lambda(mm)', 'Tau_S1D', 'Tau_S3D', 'Tau_Est', 'Tau_Diff(%)',
         'Tb_S1D(K)', 'Tb_S3D(K)', 'Tb_Est(K)', 'Tb_Diff(%)')
    ]

    # Calculate image for different wavelengths
    for wavlen in 0.1, 1, 10, 100, 1000, 10000:
        # Setup file names
        out1d = "%s1d.%7.2emm.xyv" % (name, wavlen)
        tau1d = "%s1d.%7.2emm.tau" % (name, wavlen)
        out3d = "%s3d.%7.2emm.xyv" % (name, wavlen)
        tau3d = "%s3d.%7.2emm.tau" % (name, wavlen)

        # Reset inputs (safer)
        inputs.reset_inputs()

        # Generate synthetic dust observations
        tasks.task_contobs(source=src1d,
                           out=out1d,
                           tau=tau1d,
                           wavelen="%7.2emm" % wavlen,
                           cell="['0.5asec', '0.5asec']",
                           unit='K',
                           chan="[32, '0.2kms^-1']")
        tasks.task_contobs(source=src3d,
                           out=out3d,
                           tau=tau3d,
                           wavelen="%7.2emm" % wavlen,
                           cell="['0.5asec', '0.5asec']",
                           unit='K',
	# Table header
	table = ['# %20s %20s %20s %20s %20s %20s %20s %20s %20s'%('Molec', 'Tau_S1D', 'Tau_S3D', 'Tau_Est', 'Tau_diff(%)', 'Tb_S1D(K)', 'Tb_S3D(K)', 'Tb_Est(K)', 'Tb_Diff(%)')]

	# Calculate image for different wavelengths
	for molec in 'o-h2o_2lev', 'co_2lev', 'hco+_2lev', 'sio_2lev', 'hnco_2lev':
		# Setup file names
		src1d = "%s.%s.src1d"%(name, molec)
		out1d = "%s.%s.xyv1d"%(name, molec)
		tau1d = "%s.%s.tau1d"%(name, molec)
		src3d = "%s.%s.src3d"%(name, molec)
		out3d = "%s.%s.xyv3d"%(name, molec)
		tau3d = "%s.%s.tau3d"%(name, molec)

		# Reset inputs (safer)
		inputs.reset_inputs()

		# Calculate analytical solution
		Tb_est, tau_est = Estimate(molec)

		# Generate model
		tasks.task_valline1d(out=src1d, molec=molec, xmol=1e-10)
		tasks.task_valline3d(out=src3d, molec=molec, xmol=1e-10)

		# Generate synthetic dust observations
		tasks.task_lineobs(source=src1d, out=out1d, tau=tau1d, line="0", cell="['0.5asec', '0.5asec']", unit='K', chan="[32, '0.2kms^-1']")
		tasks.task_lineobs(source=src3d, out=out3d, tau=tau3d, line="0", cell="['0.5asec', '0.5asec']", unit='K', chan="[32, '0.2kms^-1']")

		from subprocess import Popen, PIPE
		# Get brightness temperature
		p = Popen("imspec in=%s options=eformat,nohead region='rel,box(0,0,0,0)' plot=sum | head -n 18 | tail -n 1 | awk '{print $3}'"%out1d, shell=True, stdout=PIPE, stderr=PIPE)