コード例 #1
0
def sticks_and_ball_dummies(gtab):
    sb_dummies = {}
    S, sticks = sticks_and_ball(gtab,
                                d=0.0015,
                                S0=100,
                                angles=[(0, 0)],
                                fractions=[100],
                                snr=None)
    sb_dummies['1fiber'] = (S, sticks)
    S, sticks = sticks_and_ball(gtab,
                                d=0.0015,
                                S0=100,
                                angles=[(0, 0), (90, 0)],
                                fractions=[50, 50],
                                snr=None)
    sb_dummies['2fiber'] = (S, sticks)
    S, sticks = sticks_and_ball(gtab,
                                d=0.0015,
                                S0=100,
                                angles=[(0, 0), (90, 0), (90, 90)],
                                fractions=[33, 33, 33],
                                snr=None)
    sb_dummies['3fiber'] = (S, sticks)
    S, sticks = sticks_and_ball(gtab,
                                d=0.0015,
                                S0=100,
                                angles=[(0, 0), (90, 0), (90, 90)],
                                fractions=[0, 0, 0],
                                snr=None)
    sb_dummies['isotropic'] = (S, sticks)
    return sb_dummies
コード例 #2
0
def test_dsi_metrics():
    btable = np.loadtxt(get_fnames('dsi4169btable'))
    gtab = gradient_table(btable[:, 0], btable[:, 1:])
    data, _ = sticks_and_ball(gtab,
                              d=0.0015,
                              S0=100,
                              angles=[(0, 0), (60, 0)],
                              fractions=[50, 50],
                              snr=None)

    dsmodel = DiffusionSpectrumModel(gtab, qgrid_size=21, filter_width=4500)
    rtop_signal_norm = dsmodel.fit(data).rtop_signal()
    dsmodel.fit(data).rtop_pdf()
    rtop_pdf = dsmodel.fit(data).rtop_pdf(normalized=False)
    assert_almost_equal(rtop_signal_norm, rtop_pdf, 6)
    dsmodel = DiffusionSpectrumModel(gtab, qgrid_size=21, filter_width=4500)
    mevals = np.array(([0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003]))
    S_0, _ = multi_tensor(gtab,
                          mevals,
                          S0=100,
                          angles=[(0, 0), (60, 0)],
                          fractions=[50, 50],
                          snr=None)
    S_1, _ = multi_tensor(gtab,
                          mevals * 2.0,
                          S0=100,
                          angles=[(0, 0), (60, 0)],
                          fractions=[50, 50],
                          snr=None)
    MSD_norm_0 = dsmodel.fit(S_0).msd_discrete(normalized=True)
    MSD_norm_1 = dsmodel.fit(S_1).msd_discrete(normalized=True)
    assert_almost_equal(MSD_norm_0, 0.5 * MSD_norm_1, 4)
コード例 #3
0
ファイル: test_voxel.py プロジェクト: pombredanne/dipy
def test_sticks_and_ball():
    d = 0.0015
    S, sticks = sticks_and_ball(gtab, d=d, S0=1, angles=[(0,0),],
                                fractions=[100], snr=None)
    assert_array_equal(sticks, [[0, 0, 1]])
    S_st = SingleTensor(gtab, 1, evals=[d, 0, 0], evecs=[[0, 0, 0],
                                                         [0, 0, 0],
                                                         [1, 0, 0]])
    assert_array_almost_equal(S, S_st)
コード例 #4
0
ファイル: test_voxel.py プロジェクト: wrgr/dipy
def test_sticks_and_ball():
    d = 0.0015
    S, sticks = sticks_and_ball(gtab, d=d, S0=1, angles=[(0, 0), ],
                                fractions=[100], snr=None)
    assert_array_equal(sticks, [[0, 0, 1]])
    S_st = SingleTensor(gtab, 1, evals=[d, 0, 0], evecs=[[0, 0, 0],
                                                         [0, 0, 0],
                                                         [1, 0, 0]])
    assert_array_almost_equal(S, S_st)
コード例 #5
0
def test_shore_odf():
    gtab = get_isbi2013_2shell_gtab()

    # load repulsion 724 sphere
    sphere = default_sphere

    # load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    data, golden_directions = sticks_and_ball(gtab,
                                              d=0.0015,
                                              S0=100,
                                              angles=[(0, 0), (90, 0)],
                                              fractions=[50, 50],
                                              snr=None)
    asm = ShoreModel(gtab,
                     radial_order=6,
                     zeta=700,
                     lambdaN=1e-8,
                     lambdaL=1e-8)
    # repulsion724
    asmfit = asm.fit(data)
    odf = asmfit.odf(sphere)
    odf_sh = asmfit.odf_sh()
    odf_from_sh = sh_to_sf(odf_sh, sphere, 6, basis_type=None, legacy=True)
    npt.assert_almost_equal(odf, odf_from_sh, 10)

    expected_phi = shore_matrix(radial_order=6, zeta=700, gtab=gtab)
    npt.assert_array_almost_equal(np.dot(expected_phi, asmfit.shore_coeff),
                                  asmfit.fitted_signal())

    directions, _, _ = peak_directions(odf, sphere, .35, 25)
    npt.assert_equal(len(directions), 2)
    npt.assert_almost_equal(angular_similarity(directions, golden_directions),
                            2, 1)

    # 5 subdivisions
    odf = asmfit.odf(sphere2)
    directions, _, _ = peak_directions(odf, sphere2, .35, 25)
    npt.assert_equal(len(directions), 2)
    npt.assert_almost_equal(angular_similarity(directions, golden_directions),
                            2, 1)

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        asmfit = asm.fit(data)
        odf = asmfit.odf(sphere2)
        directions, _, _ = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            npt.assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            npt.assert_equal(gfa(odf) < 0.1, True)
コード例 #6
0
ファイル: __init__.py プロジェクト: mbeyeler/dipy
def dsi_deconv_voxels():
    gtab = gradient_table(np.loadtxt(get_fnames('dsi515btable')))
    data = np.zeros((2, 2, 2, 515))
    for ix in range(2):
        for iy in range(2):
            for iz in range(2):
                data[ix, iy, iz], _ = sticks_and_ball(gtab,
                                                      d=0.0015,
                                                      S0=1.,
                                                      angles=[(0, 0), (90, 0)],
                                                      fractions=[50, 50],
                                                      snr=None)
    return data, gtab
コード例 #7
0
ファイル: test_shore_odf.py プロジェクト: mbeyeler/dipy
def test_shore_odf():
    gtab = get_isbi2013_2shell_gtab()

    # load symmetric 724 sphere
    sphere = get_sphere('symmetric724')

    # load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    data, golden_directions = sticks_and_ball(gtab,
                                              d=0.0015,
                                              S0=100,
                                              angles=[(0, 0), (90, 0)],
                                              fractions=[50, 50],
                                              snr=None)
    asm = ShoreModel(gtab,
                     radial_order=6,
                     zeta=700,
                     lambdaN=1e-8,
                     lambdaL=1e-8)
    # symmetric724
    asmfit = asm.fit(data)
    odf = asmfit.odf(sphere)
    odf_sh = asmfit.odf_sh()
    odf_from_sh = sh_to_sf(odf_sh, sphere, 6, basis_type=None)
    assert_almost_equal(odf, odf_from_sh, 10)

    directions, _, _ = peak_directions(odf, sphere, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    # 5 subdivisions
    odf = asmfit.odf(sphere2)
    directions, _, _ = peak_directions(odf, sphere2, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        asmfit = asm.fit(data)
        odf = asmfit.odf(sphere2)
        directions, _, _ = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)
コード例 #8
0
def test_dsi():
    # load repulsion 724 sphere
    sphere = default_sphere
    # load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    btable = np.loadtxt(get_fnames('dsi515btable'))
    gtab = gradient_table(btable[:, 0], btable[:, 1:])
    data, golden_directions = sticks_and_ball(gtab,
                                              d=0.0015,
                                              S0=100,
                                              angles=[(0, 0), (90, 0)],
                                              fractions=[50, 50],
                                              snr=None)

    ds = DiffusionSpectrumDeconvModel(gtab)

    # repulsion724
    dsfit = ds.fit(data)
    odf = dsfit.odf(sphere)
    directions, _, _ = peak_directions(odf, sphere, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    # 5 subdivisions
    dsfit = ds.fit(data)
    odf2 = dsfit.odf(sphere2)
    directions, _, _ = peak_directions(odf2, sphere2, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    assert_equal(dsfit.pdf().shape, 3 * (ds.qgrid_size, ))
    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        odf = ds.fit(data).odf(sphere2)
        directions, _, _ = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)

    assert_raises(ValueError,
                  DiffusionSpectrumDeconvModel,
                  gtab,
                  qgrid_size=16)
コード例 #9
0
def test_gqi():
    # load repulsion 724 sphere
    sphere = default_sphere
    # load icosahedron sphere
    sphere2 = create_unit_sphere(5)
    btable = np.loadtxt(get_fnames('dsi515btable'))
    bvals = btable[:, 0]
    bvecs = btable[:, 1:]
    gtab = gradient_table(bvals, bvecs)
    data, golden_directions = sticks_and_ball(gtab,
                                              d=0.0015,
                                              S0=100,
                                              angles=[(0, 0), (90, 0)],
                                              fractions=[50, 50],
                                              snr=None)
    gq = GeneralizedQSamplingModel(gtab, method='gqi2', sampling_length=1.4)

    # repulsion724
    gqfit = gq.fit(data)
    odf = gqfit.odf(sphere)
    directions, values, indices = peak_directions(odf, sphere, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    # 5 subdivisions
    gqfit = gq.fit(data)
    odf2 = gqfit.odf(sphere2)
    directions, values, indices = peak_directions(odf2, sphere2, .35, 25)
    assert_equal(len(directions), 2)
    assert_almost_equal(angular_similarity(directions, golden_directions), 2,
                        1)

    sb_dummies = sticks_and_ball_dummies(gtab)
    for sbd in sb_dummies:
        data, golden_directions = sb_dummies[sbd]
        odf = gq.fit(data).odf(sphere2)
        directions, values, indices = peak_directions(odf, sphere2, .35, 25)
        if len(directions) <= 3:
            assert_equal(len(directions), len(golden_directions))
        if len(directions) > 3:
            assert_equal(gfa(odf) < 0.1, True)
コード例 #10
0
ファイル: viz_canvas.py プロジェクト: zoq/fury
def test_sh():
    from dipy.sims.voxel import multi_tensor, multi_tensor_odf, sticks_and_ball
    from dipy.data import get_sphere, get_fnames
    from dipy.core.gradients import gradient_table
    from dipy.io.gradients import read_bvals_bvecs

    _, fbvals, fbvecs = get_fnames('small_64D')
    bvals, bvecs = read_bvals_bvecs(fbvals, fbvecs)
    gtab = gradient_table(bvals, bvecs)

    d = 0.0015
    S, sticks = sticks_and_ball(gtab,
                                d=d,
                                S0=1,
                                angles=[(0, 0), (30, 30)],
                                fractions=[60, 40],
                                snr=None)

    print(S)
    print(sticks)
    mevals = np.array([[0.0015, 0.0003, 0.0003], [0.0015, 0.0003, 0.0003]])
    angles = [(0, 0), (60, 0)]
    fractions = [50, 50]
    sphere = get_sphere('repulsion724')
    sphere = sphere.subdivide(2)
    odf = multi_tensor_odf(sphere.vertices, mevals, angles, fractions)

    print(odf)
    ren = window.Scene()

    odf_actor = actor.odf_slicer(odf[None, None, None, :],
                                 sphere=sphere,
                                 colormap='plasma')
    # odf_actor.RotateX(90)

    ren.add(odf_actor)
    # window.show(ren)

    odf_test_dec= \
    """
    // Constants, see here: http://en.wikipedia.org/wiki/Table_of_spherical_harmonics
#define k01 0.2820947918 // sqrt(  1/PI)/2
#define k02 0.4886025119 // sqrt(  3/PI)/2
#define k03 1.0925484306 // sqrt( 15/PI)/2
#define k04 0.3153915652 // sqrt(  5/PI)/4
#define k05 0.5462742153 // sqrt( 15/PI)/4
#define k06 0.5900435860 // sqrt( 70/PI)/8
#define k07 2.8906114210 // sqrt(105/PI)/2
#define k08 0.4570214810 // sqrt( 42/PI)/8
#define k09 0.3731763300 // sqrt(  7/PI)/4
#define k10 1.4453057110 // sqrt(105/PI)/4

// unrolled version of the above
float SH_0_0( in vec3 s ) { vec3 n = s.zxy; return  k01; }
float SH_1_0( in vec3 s ) { vec3 n = s.zxy; return -k02*n.y; }
float SH_1_1( in vec3 s ) { vec3 n = s.zxy; return  k02*n.z; }
float SH_1_2( in vec3 s ) { vec3 n = s.zxy; return -k02*n.x; }
float SH_2_0( in vec3 s ) { vec3 n = s.zxy; return  k03*n.x*n.y; }
float SH_2_1( in vec3 s ) { vec3 n = s.zxy; return -k03*n.y*n.z; }
float SH_2_2( in vec3 s ) { vec3 n = s.zxy; return  k04*(3.0*n.z*n.z-1.0); }
float SH_2_3( in vec3 s ) { vec3 n = s.zxy; return -k03*n.x*n.z; }
float SH_2_4( in vec3 s ) { vec3 n = s.zxy; return  k05*(n.x*n.x-n.y*n.y); }
float SH_3_0( in vec3 s ) { vec3 n = s.zxy; return -k06*n.y*(3.0*n.x*n.x-n.y*n.y); }
float SH_3_1( in vec3 s ) { vec3 n = s.zxy; return  k07*n.z*n.y*n.x; }
float SH_3_2( in vec3 s ) { vec3 n = s.zxy; return -k08*n.y*(5.0*n.z*n.z-1.0); }
float SH_3_3( in vec3 s ) { vec3 n = s.zxy; return  k09*n.z*(5.0*n.z*n.z-3.0); }
float SH_3_4( in vec3 s ) { vec3 n = s.zxy; return -k08*n.x*(5.0*n.z*n.z-1.0); }
float SH_3_5( in vec3 s ) { vec3 n = s.zxy; return  k10*n.z*(n.x*n.x-n.y*n.y); }
float SH_3_6( in vec3 s ) { vec3 n = s.zxy; return -k06*n.x*(n.x*n.x-3.0*n.y*n.y); }

vec3 map( in vec3 p )
{
    vec3 p00 = p - vec3( 0.00, 2.5,0.0);
	vec3 p01 = p - vec3(-1.25, 1.0,0.0);
	vec3 p02 = p - vec3( 0.00, 1.0,0.0);
	vec3 p03 = p - vec3( 1.25, 1.0,0.0);
	vec3 p04 = p - vec3(-2.50,-0.5,0.0);
	vec3 p05 = p - vec3(-1.25,-0.5,0.0);
	vec3 p06 = p - vec3( 0.00,-0.5,0.0);
	vec3 p07 = p - vec3( 1.25,-0.5,0.0);
	vec3 p08 = p - vec3( 2.50,-0.5,0.0);
	vec3 p09 = p - vec3(-3.75,-2.0,0.0);
	vec3 p10 = p - vec3(-2.50,-2.0,0.0);
	vec3 p11 = p - vec3(-1.25,-2.0,0.0);
	vec3 p12 = p - vec3( 0.00,-2.0,0.0);
	vec3 p13 = p - vec3( 1.25,-2.0,0.0);
	vec3 p14 = p - vec3( 2.50,-2.0,0.0);
	vec3 p15 = p - vec3( 3.75,-2.0,0.0);

	float r, d; vec3 n, s, res;

    #ifdef SHOW_SPHERES
	#define SHAPE (vec3(d-0.35, -1.0+2.0*clamp(0.5 + 16.0*r,0.0,1.0),d))
	#else
	#define SHAPE (vec3(d-abs(r), sign(r),d))
	#endif
	d=length(p00); n=p00/d; r = SH_0_0( n ); s = SHAPE; res = s;
	d=length(p01); n=p01/d; r = SH_1_0( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p02); n=p02/d; r = SH_1_1( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p03); n=p03/d; r = SH_1_2( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p04); n=p04/d; r = SH_2_0( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p05); n=p05/d; r = SH_2_1( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p06); n=p06/d; r = SH_2_2( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p07); n=p07/d; r = SH_2_3( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p08); n=p08/d; r = SH_2_4( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p09); n=p09/d; r = SH_3_0( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p10); n=p10/d; r = SH_3_1( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p11); n=p11/d; r = SH_3_2( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p12); n=p12/d; r = SH_3_3( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p13); n=p13/d; r = SH_3_4( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p14); n=p14/d; r = SH_3_5( n ); s = SHAPE; if( s.x<res.x ) res=s;
	d=length(p15); n=p15/d; r = SH_3_6( n ); s = SHAPE; if( s.x<res.x ) res=s;

	return vec3( res.x, 0.5+0.5*res.y, res.z );
}

vec3 intersect( in vec3 ro, in vec3 rd )
{
	vec3 res = vec3(1e10,-1.0, 1.0);

	float maxd = 10.0;
    float h = 1.0;
    float t = 0.0;
    vec2  m = vec2(-1.0);
    for( int i=0; i<200; i++ )
    {
        if( h<0.001||t>maxd ) break;
	    vec3 res = map( ro+rd*t );
        h = res.x;
		m = res.yz;
        t += h*0.3;
    }
	if( t<maxd && t<res.x ) res=vec3(t,m);


	return res;
}

vec3 calcNormal( in vec3 pos )
{
    vec3 eps = vec3(0.001,0.0,0.0);

	return normalize( vec3(
           map(pos+eps.xyy).x - map(pos-eps.xyy).x,
           map(pos+eps.yxy).x - map(pos-eps.yxy).x,
           map(pos+eps.yyx).x - map(pos-eps.yyx).x ) );
}

    """



    odf_test_impl = \
    """

        // camera matrix
        vec3 ww = vec3(0.0,0.0,0.0); //MCDCMatrix (2);
        vec3 uu = vec3(0.0,0.0,0.0); //MCDCMatrix (0);
        vec3 vv = vec3(0.0,0.0,0.0); //MCDCMatrix (1);
        vec3 tot = vec3(0.0);
        vec2 p = (-vec2(0.5, 0.5) + (2.0*point,0)) / 0.5;
        vec3 ro = vec3(0.0,0.0,0.0);

        // create view ray
        vec3 rd = normalize( p.x*uu + p.y*vv + 2.0*ww );

        // background
        vec3 col = vec3(0.3) * clamp(1.0-length(point)*0.5,0.0,1.0);

        // raymarch
        vec3 tmat = intersect(ro,rd);
        if( tmat.y>-0.5 )
        {
            // geometry
            vec3 pos = ro + tmat.x*rd;
            vec3 nor = calcNormal(pos);
            vec3 ref = reflect( rd, nor );

            // material
            vec3 mate = 0.5*mix( vec3(1.0,0.6,0.15), vec3(0.2,0.4,0.5), tmat.y );

            float occ = clamp( 2.0*tmat.z, 0.0, 1.0 );
            float sss = pow( clamp( 1.0 + dot(nor,rd), 0.0, 1.0 ), 1.0 );

            // lights
            vec3 lin  = 2.5*occ*vec3(1.0,1.00,1.00)*(0.6+0.4*nor.y);
                 lin += 1.0*sss*vec3(1.0,0.95,0.70)*occ;

            // surface-light interacion
            col = mate.xyz * lin;
        }

        // gamma
        col = pow( clamp(col,0.0,1.0), vec3(0.4545) );
        tot += col;
    fragOutput0 = vec4( tot, 1.0 );
    """

    scene = window.Scene()
    scene.background((0.8, 0.8, 0.8))
    centers = np.array([[2, 0, 0], [0, 0, 0], [-2, 0, 0]])
    # np.random.rand(3, 3) * 3
    # colors = np.array([[255, 0, 0], [0, 255, 0], [0, 0, 255]])
    colors = np.random.rand(3, 3) * 255
    scale = 1  # np.random.rand(3) * 5

    # https://www.shadertoy.com/view/MstXWS
    # https://www.shadertoy.com/view/XsX3R4

    fs_dec = \
        """
        uniform mat4 MCDCMatrix;
        uniform mat4 MCVCMatrix;


        float sdRoundBox( vec3 p, vec3 b, float r )
        {
            vec3 q = abs(p) - b;
            return length(max(q,0.0)) + min(max(q.x,max(q.y,q.z)),0.0) - r;
        }

        float sdEllipsoid( vec3 p, vec3 r )
        {
        float k0 = length(p/r);
        float k1 = length(p/(r*r));
        return k0*(k0-1.0)/k1;
        }
        float sdCylinder(vec3 p, float h, float r)
        {
            vec2 d = abs(vec2(length(p.xz),p.y)) - vec2(h,r);
            return min(max(d.x,d.y),0.0) + length(max(d,0.0));
        }
        float sdSphere(vec3 pos, float r)
        {
            float d = length(pos) - r;

            return d;
        }
        float map( in vec3 pos)
        {
            float d = sdSphere(pos-0.5, .2);
            float d1 = sdCylinder(pos+0.5, 0.05, .5);
            float d2 = sdEllipsoid(pos + vec3(-0.5,0.5,0), vec3(0.2,0.3,0.5));
            float d3 = sdRoundBox(pos + vec3(0.5,-0.5,0), vec3(0.2,0.1,0.3), .05);


            //.xy

            return min(min(min(d, d1), d2), d3);
        }

        vec3 calcNormal( in vec3 pos )
        {
            vec2 e = vec2(0.0001,0.0);
            return normalize( vec3(map(pos + e.xyy) - map(pos - e.xyy ),
                                   map(pos + e.yxy) - map(pos - e.yxy),
                                   map(pos + e.yyx) - map(pos - e.yyx)
                                   )
                            );
        }

        float castRay(in vec3 ro, vec3 rd)
        {
            float t = 0.0;
            for(int i=0; i < 100; i++)
            {
                vec3 pos = ro + t * rd;
                vec3 nor = calcNormal(pos);

                float h = map(pos);
                if (h < 0.001) break;

                t += h;
                if (t > 20.0) break;
            }
            return t;
        }
        """

    fake_sphere = \
    """

    vec3 uu = vec3(MCVCMatrix[0][0], MCVCMatrix[1][0], MCVCMatrix[2][0]); // camera right
    vec3 vv = vec3(MCVCMatrix[0][1], MCVCMatrix[1][1], MCVCMatrix[2][1]); //  camera up
    vec3 ww = vec3(MCVCMatrix[0][2], MCVCMatrix[1][2], MCVCMatrix[2][2]); // camera direction
    vec3 ro = MCVCMatrix[3].xyz * mat3(MCVCMatrix);  // camera position

    // create view ray
    vec3 rd = normalize( point.x*-uu + point.y*-vv + 7*ww);
    vec3 col = vec3(0.0);

    float t = castRay(ro, rd);
    if (t < 20.0)
    {
        vec3 pos = ro + t * rd;
        vec3 nor = calcNormal(pos);
        vec3 sun_dir = vec3(MCVCMatrix[0][2], MCVCMatrix[1][2], MCVCMatrix[2][2]); //normalize()
        float dif = clamp( dot(nor, sun_dir), 0.0, 1.0);
        //vec3 sun_dif = normalize()
        col = color * dot(color,nor); // (color + diffuseColor + ambientColor + specularColor)*nor.zzz;//vec3(1.0);
        fragOutput0 = vec4(col, 1.0);
    }
    else{
        //fragOutput0 = vec4(0,1,0, 1.0);
        discard;
        }


    /*float radius = 1.;
    if(len > radius)
        {discard;}

    //err, lightColor0 vertexColorVSOutput normalVCVSOutput, ambientIntensity; diffuseIntensity;specularIntensity;specularColorUniform;
    float c = len;
    fragOutput0 =  vec4(c,c,c, 1);




    vec3 normalizedPoint = normalize(vec3(point.xy, sqrt(1. - len)));
    vec3 direction = normalize(vec3(1., 1., 1.));
    float df = max(0, dot(direction, normalizedPoint));
    float sf = pow(df, 24);
    fragOutput0 = vec4(max(df * color, sf * vec3(1)), 1);*/
    """

    billboard_actor = actor.billboard(centers,
                                      colors=colors.astype(np.uint8),
                                      scale=scale,
                                      fs_dec=fs_dec,
                                      fs_impl=fake_sphere)
    scene.add(billboard_actor)
    scene.add(actor.axes())
    scene.camera_info()
    matrix = scene.camera().GetViewTransformMatrix()
    mat = np.zeros((4, 4))
    for i in range(4):
        for j in range(4):
            mat[i, j] = matrix.GetElement(i, j)
    print(mat)
    print(np.dot(-mat[:3, 3], mat[:3, :3]))  # camera position
    window.show(scene)