[yt-dev] Testing Intervention

Sam Skillman samskillman at gmail.com
Tue Sep 25 16:18:59 PDT 2012


Gotcha, thanks for the clarification.  I'm just trying to stay caught up on
all the movement.

Having one tests/ folder per dir seems reasonable.

Sam


On Tue, Sep 25, 2012 at 5:12 PM, Casey W. Stark <caseywstark at gmail.com>wrote:

> Hey Sam.
>
> I was suggesting...
>
> yt-hg/
>   test/
>   yt/
>
> So that it is separate from the yt package.
>
> - Casey
>
>
> On Tue, Sep 25, 2012 at 4:05 PM, Sam Skillman <samskillman at gmail.com>wrote:
>
>> Would root in our case be yt-hg/yt, in which case the tests would live at
>> yt-hg/yt/tests/ ?
>>
>> Sorry if I misunderstood.
>> Sam
>>
>>
>> On Tue, Sep 25, 2012 at 5:00 PM, Anthony Scopatz <scopatz at gmail.com>wrote:
>>
>>> Hi Casey,
>>>
>>> The reason I suggested that we do it this way originally was because
>>> this is the way that most other packages in the scientific python ecosystem
>>> are set up.  If you look at numpy, scipy, cython, pytables, ipython, etc.
>>> they all have the following file system structure:
>>>
>>> root/
>>>   module1.py
>>>   module2.py
>>>   tests/
>>>     test_module2.py
>>>     test_module1.py
>>>   subpack1/
>>>     module3.py
>>>     tests/
>>>       test_module3.py
>>>
>>> I think that it is done this way to make it easy/possible for UnitTest
>>> and nose to autodetect the tests.  I am not saying that we have to follow
>>> this de facto standard.  However, I don't really see a reason why we
>>> shouldn't either.  If you do, please let me know ;)
>>>
>>> Notably, matplotlib does not follow this standard.  But then again,
>>> since they are testing GUI and rendering code their tests are a level of
>>> complexity above what we need.
>>>
>>> Be Well
>>> Anthony
>>>
>>> On Tue, Sep 25, 2012 at 5:50 PM, Casey W. Stark <caseywstark at gmail.com>wrote:
>>>
>>>> Hey Matt, Anthony.
>>>>
>>>> Looks like a good start to nosetests. One small thing -- would anyone
>>>> be opposed to moving these out of the yt directory and into a root "test"
>>>> directory?
>>>>
>>>> I can take on CIC deposition and interpolation wherever those are.
>>>>
>>>> - Casey
>>>>
>>>>
>>>> On Tue, Sep 25, 2012 at 11:20 AM, Matthew Turk <matthewturk at gmail.com>wrote:
>>>>
>>>>> Hi all,
>>>>>
>>>>> As a note, Anthony just added this to the 3.0 base.  Here's a set of
>>>>> tests:
>>>>>
>>>>>
>>>>> https://bitbucket.org/yt_analysis/yt-3.0/src/52a1b2ecea94/yt/utilities/lib/tests/test_alt_ray_tracers.py
>>>>>
>>>>> and here's a utilities section he added:
>>>>>
>>>>> https://bitbucket.org/yt_analysis/yt-3.0/src/52a1b2ecea94/yt/testing.py
>>>>>
>>>>> -Matt
>>>>>
>>>>> On Mon, Sep 24, 2012 at 10:01 PM, Matthew Turk <matthewturk at gmail.com>
>>>>> wrote:
>>>>> > Hey Casey,
>>>>> >
>>>>> > On Mon, Sep 24, 2012 at 5:39 PM, Casey W. Stark <
>>>>> caseywstark at gmail.com> wrote:
>>>>> >> Hi Matt.
>>>>> >>
>>>>> >> Glad my example was useful in some way. I guess knowing exactly
>>>>> which Cython
>>>>> >> routines to test for what is what I meant about where to start.
>>>>> >
>>>>> > I completely understand -- and that's a failure of my part in the
>>>>> > code.  So I think what might help is if we start looking at the
>>>>> > routines that could be tested, and then I can jump in when it looks
>>>>> > like they're buried.  I will also volunteer to try to refactor this
>>>>> > code, once it's tested, to make it clearer what is where and why.
>>>>> >
>>>>> >>
>>>>> >> Thanks for the tip about the stream frontend.
>>>>> >
>>>>> > No prob, it should be documented better.
>>>>> >
>>>>> > In terms of generating data, here's an example of what I was meaning:
>>>>> >
>>>>> > https://hub.yt-project.org/nb/ompxtg
>>>>> >
>>>>> > This sets up a random (but small-valued) background density and then
>>>>> > applies a couple top hat spheres on top of it.  I think this could be
>>>>> > a good starting point for unit testing.  I looked at the code that
>>>>> > exists for flagging cells and refining them, and it's currently a bit
>>>>> > too specific for this, as it was designed to take RAMSES data and
>>>>> > partition it, which operates slightly differently.  I'll take a pass
>>>>> > at extracting it and making it work in this case.
>>>>> >
>>>>> > The way I see it working is that one would set up the operators, as
>>>>> is
>>>>> > done here, and then a progressive routine would be applied, something
>>>>> > like this:
>>>>> >
>>>>> > while grids.flag() > 0:
>>>>> >     grids.refine()
>>>>> >     for operator in operators: operator.apply(grids)
>>>>> > pf = grids.convert_to_dataset()
>>>>> >
>>>>> > The missing step in the code base is mostly just the refinement, as
>>>>> > for the smoothed covering grids we have the necessary machinery to
>>>>> > interpolate from one level to the next.  Adding more types of
>>>>> > operators to this library would be beneficial as well.  The
>>>>> > finalization step at the end would then convert the collection of
>>>>> > grids into a Stream dataset.  So with only a couple lines of code we
>>>>> > could in all likelihood be able to generate in-memory datasets.
>>>>> >
>>>>> > (This underscores in my mind why it would be awesome to have GDF in
>>>>> > more places, as with this kind of machinery we've just written
>>>>> initial
>>>>> > conditions generation, especially since we have a GDF writer
>>>>> > already...)
>>>>> >
>>>>> > Anyway, what might be really helpful is if interested people would
>>>>> > volunteer to address a few of the testable areas?  Then we can start
>>>>> > pushing and identifying problem areas.  I'll volunteer to handle at
>>>>> > least the data container stuff, and whatever else slips through the
>>>>> > cracks; although my time will be somewhat limited in the very near
>>>>> > future, I will try to make this a priority.
>>>>> >
>>>>> > -Matt
>>>>> >
>>>>> >>
>>>>> >> - Casey
>>>>> >>
>>>>> >>
>>>>> >> On Mon, Sep 24, 2012 at 1:52 PM, Matthew Turk <
>>>>> matthewturk at gmail.com> wrote:
>>>>> >>>
>>>>> >>> Hey Casey and Anthony,
>>>>> >>>
>>>>> >>> On Mon, Sep 24, 2012 at 4:20 PM, Casey W. Stark <
>>>>> caseywstark at gmail.com>
>>>>> >>> wrote:
>>>>> >>> > Hi Anthony.
>>>>> >>> >
>>>>> >>> > I completely agree that we should target the level of functions
>>>>> actually
>>>>> >>> > performing the projection rather than yt's organization. The mock
>>>>> >>> > frontend
>>>>> >>> > suggestion was just a hack to get there. I don't know if there's
>>>>> a way
>>>>> >>> > around it though...
>>>>> >>> >
>>>>> >>> > Here's an example of what I sorted through to get to projections:
>>>>> >>> > - Load a test plotfile, check pf.h.proj to find it's source.
>>>>> >>> > - Read through data_objects/hierarchy.py and
>>>>> >>> > utilities/parallel_tools/parallel_analysis_interface.py to find
>>>>> where
>>>>> >>> > proj
>>>>> >>> > is attached, can't find it.
>>>>> >>> > - The proj docstring says it is a reference to AMRQuadProj.
>>>>> Can't find a
>>>>> >>> > class by that name.
>>>>> >>> > - Search data_objects sources for "proj", find AMRProjBase.
>>>>> >>> >
>>>>> >>> > So it looks like the functionality is wrapped up in the
>>>>> __project_level
>>>>> >>> > and
>>>>> >>> > _project_grid methods. I can't think of a way to test those
>>>>> without
>>>>> >>> > creating
>>>>> >>> > an AMRProjBase, and that requires a staticoutput object.
>>>>> >>>
>>>>> >>> You're right, the projection stuff as *projections* is not easy to
>>>>> >>> test.  But in terms of testing the underlying code, which is
>>>>> wrapped
>>>>> >>> up in a Cython class called QuadTree, I think it could be done.
>>>>>  The
>>>>> >>> steps you're describing are actually all part of the existing
>>>>> answer
>>>>> >>> testing machinery, which performs a couple things and verifies that
>>>>> >>> they don't change over time:
>>>>> >>>
>>>>> >>> 1) Project some fields from the disk
>>>>> >>> 2) Project a couple derived fields
>>>>> >>> 3) Project a derived field that requires spatial derivatives
>>>>> >>> 4) Project the "Ones" field, which should be 1.0 everywhere.
>>>>> >>>
>>>>> >>> So these things are done, but it is also possible that the specific
>>>>> >>> quadtree functionality could be tested, in isolation from the
>>>>> >>> projection.  I think this may be oneo f the things Anthony is
>>>>> talking
>>>>> >>> about -- answer testing can handle the big, complex items, and by
>>>>> >>> breaking down to the fundamentals we can address isolated items
>>>>> from a
>>>>> >>> unit testing perspective.
>>>>> >>>
>>>>> >>> >
>>>>> >>> > So unfortunately, I think it would still come down to having a
>>>>> fake
>>>>> >>> > frontend. It's not ideal, but it seems like any more isolation
>>>>> would
>>>>> >>> > require
>>>>> >>> > big rewrites to yt.
>>>>> >>>
>>>>> >>> One fun thing that is not usually known is that we have a fake
>>>>> >>> frontend already, it just doesn't get used much.  It's called the
>>>>> >>> "Stream" frontend and it was designed originally to be used in
>>>>> >>> ParaView, but now gets used by the (new,
>>>>> not-yet-documented/released)
>>>>> >>> load_uniform_grid function as well as by Hyperion, the RT code by
>>>>> Tom
>>>>> >>> R.  It can set up AMR as well as static mesh.  It's not terribly
>>>>> well
>>>>> >>> documented, but there are examples on the wiki.
>>>>> >>>
>>>>> >>> One thing I've been thinking about is actually creating a couple
>>>>> fake
>>>>> >>> outputs, which could be defined analytically with spheres of
>>>>> >>> overdensity inside them.  In principle, if we added refinement
>>>>> >>> criteria, we could make this relatively complex data that was
>>>>> defined
>>>>> >>> with only a few lines of code, but spun up a big in-memory dataset.
>>>>> >>>
>>>>> >>> (This exact thing is on my list of things to do and then to output
>>>>> in
>>>>> >>> GDF, by the way...)
>>>>> >>>
>>>>> >>> That I think could come, down the road a bit.  The refinement
>>>>> criteria
>>>>> >>> wouldn't be too bad to implement, especially since we already have
>>>>> the
>>>>> >>> grid splitting routines.  I just don't think we should focus on it
>>>>> at
>>>>> >>> the moment.  But the uniform grid creation and loading works
>>>>> already
>>>>> >>> -- I used it this morning.  You can do it with:
>>>>> >>>
>>>>> >>> from yt.frontends.stream.api import load_uniform_grid
>>>>> >>> ug = load_uniform_grid({"VelocityNorm":data1, "Density":data2},
>>>>> [359,
>>>>> >>> 359, 359], 1.0)
>>>>> >>>
>>>>> >>> the list is the dimensions of the data and the value is the to-cm
>>>>> >>> conversion.
>>>>> >>>
>>>>> >>> >
>>>>> >>> > Of course, I could be missing something. Matt, can you think of
>>>>> a better
>>>>> >>> > way?
>>>>> >>>
>>>>> >>> I think for this specific example (and your damningly complex
>>>>> tracing
>>>>> >>> of things through the source ...) the easiest thing to do is
>>>>> isolate
>>>>> >>> the Cython routine, which it seems I was able to do only because I
>>>>> >>> wrote it and which seems quite buried in the code, and to also
>>>>> provide
>>>>> >>> high-level machinery for faking a frontend.
>>>>> >>>
>>>>> >>> -Matt
>>>>> >>>
>>>>> >>> >
>>>>> >>> > - Casey
>>>>> >>> >
>>>>> >>> >
>>>>> >>> > On Mon, Sep 24, 2012 at 11:02 AM, Anthony Scopatz <
>>>>> scopatz at gmail.com>
>>>>> >>> > wrote:
>>>>> >>> >>
>>>>> >>> >> Helo Casey,
>>>>> >>> >>
>>>>> >>> >> Sorry for taking the whole weekend to respond.
>>>>> >>> >>
>>>>> >>> >>>> I would like to help with this, but it's difficult to figure
>>>>> out
>>>>> >>> >>>> where
>>>>> >>> >>>> to start.
>>>>> >>> >>
>>>>> >>> >>
>>>>> >>> >> Not to worry. I think that any of the items listed at the
>>>>> bottom of
>>>>> >>> >> Matt's
>>>>> >>> >> original email
>>>>> >>> >> would be a great place to start.
>>>>> >>> >>
>>>>> >>> >>>>
>>>>> >>> >>>>
>>>>> >>> >>>> Say I want to test projections. I make a fake 3D density
>>>>> field, maybe
>>>>> >>> >>>> something as simple as np.arange(4**3).reshape((4, 4, 4)). I
>>>>> write
>>>>> >>> >>>> down the
>>>>> >>> >>>> answer to the x-projection. Now all I need to do is call
>>>>> >>> >>>> assert_allclose(yt_result, answer, rtol=1e-15), but I don't
>>>>> know what
>>>>> >>> >>>> pieces
>>>>> >>> >>>> of low-level yt stuff to call to get to `yt_result`.
>>>>> Hopefully that's
>>>>> >>> >>>> clear...
>>>>> >>> >>>>
>>>>> >>> >>>> Maybe this comes down to creating a fake frontend we can
>>>>> attach
>>>>> >>> >>>> fields
>>>>> >>> >>>> to?
>>>>> >>> >>
>>>>> >>> >>
>>>>> >>> >> Actually, I disagree with this strategy, as I told Matt when we
>>>>> spoke
>>>>> >>> >> last
>>>>> >>> >> week.
>>>>> >>> >> What is important is that we test the science and math parts of
>>>>> the
>>>>> >>> >> code
>>>>> >>> >> before, if ever, dealing with the software architecture that
>>>>> surrounds
>>>>> >>> >> them.
>>>>> >>> >>
>>>>> >>> >> Let's taking your example of projections.  What we need to test
>>>>> is the
>>>>> >>> >> actual function
>>>>> >>> >> or method which actually slogs through the projection
>>>>> calculation.  In
>>>>> >>> >> many cases in
>>>>> >>> >> yt these functions are not directly attached to the front end
>>>>> but live
>>>>> >>> >> in
>>>>> >>> >> analysis, visualization
>>>>> >>> >> or utilities subpackages.   It is these such packages that we
>>>>> should
>>>>> >>> >> worry
>>>>> >>> >> about testing.
>>>>> >>> >> We can easily create routines to feed them sample data.
>>>>> >>> >>
>>>>> >>> >> On the other hand, testing or mocking things like frontends
>>>>> should be a
>>>>> >>> >> very low priority.
>>>>> >>> >> At the end of the day what you are testing here is pulling in
>>>>> data from
>>>>> >>> >> disk or other
>>>>> >>> >> sources.  Effectively, this is just re-testing functionality
>>>>> present in
>>>>> >>> >> h5py, etc.  That is not
>>>>> >>> >> really our job.  Yes, in a perfect world, front ends would be
>>>>> tested
>>>>> >>> >> too.
>>>>> >>> >> But I think that the
>>>>> >>> >> priority should be placed on things like the KDTree.
>>>>> >>> >>
>>>>> >>> >> Be Well
>>>>> >>> >> Anthony
>>>>> >>> >>
>>>>> >>> >>>>
>>>>> >>> >>>>
>>>>> >>> >>>> - Casey
>>>>> >>> >>>>
>>>>> >>> >>>>
>>>>> >>> >>>> On Fri, Sep 21, 2012 at 2:42 PM, Matthew Turk <
>>>>> matthewturk at gmail.com>
>>>>> >>> >>>> wrote:
>>>>> >>> >>>>>
>>>>> >>> >>>>> Hi all,
>>>>> >>> >>>>>
>>>>> >>> >>>>> As some of you have seen (at least Stephen), I filed a
>>>>> ticket this
>>>>> >>> >>>>> morning about increasing testing coverage.  The other night
>>>>> Anthony
>>>>> >>> >>>>> and I met up in NYC and he had something of an
>>>>> "intervention" about
>>>>> >>> >>>>> the sufficiency of answer testing for yt; it didn't take too
>>>>> much
>>>>> >>> >>>>> work
>>>>> >>> >>>>> on his part to convince me that we should be testing not just
>>>>> >>> >>>>> against
>>>>> >>> >>>>> a gold standard, but also performing unit tests.  In the
>>>>> past I had
>>>>> >>> >>>>> eschewed unit testing simply because the task of mocking
>>>>> data was
>>>>> >>> >>>>> quite tricky, and by adding tests that use smaller bits we
>>>>> could
>>>>> >>> >>>>> cover
>>>>> >>> >>>>> unit testable areas with answer testing.
>>>>> >>> >>>>>
>>>>> >>> >>>>> But, this isn't really a good strategy.  Let's move to
>>>>> having both.
>>>>> >>> >>>>> The testing infrastructure he recommends is the
>>>>> nearly-omnipresent
>>>>> >>> >>>>> nose:
>>>>> >>> >>>>>
>>>>> >>> >>>>> http://nose.readthedocs.org/en/latest/
>>>>> >>> >>>>>
>>>>> >>> >>>>> The ticket to track this is here:
>>>>> >>> >>>>>
>>>>> >>> >>>>>
>>>>> >>> >>>>>
>>>>> >>> >>>>>
>>>>> https://bitbucket.org/yt_analysis/yt/issue/426/increase-unit-test-coverage
>>>>> >>> >>>>>
>>>>> >>> >>>>> There are a couple sub-items here:
>>>>> >>> >>>>>
>>>>> >>> >>>>> 1) NumPy's nose test plugins provide a lot of necessary
>>>>> >>> >>>>> functionality
>>>>> >>> >>>>> that we have reimplemented in the answer testing utilities.
>>>>>  I'd
>>>>> >>> >>>>> like
>>>>> >>> >>>>> to start using the numpy plugins, which include things like
>>>>> >>> >>>>> conditional test execution, array comparisons, "slow" tests,
>>>>> etc
>>>>> >>> >>>>> etc.
>>>>> >>> >>>>> 2) We can evaluate, using conditional test execution, moving
>>>>> to nose
>>>>> >>> >>>>> for answer testing.  But that's not on the agenda now.
>>>>> >>> >>>>> 3) Writing tests for nose is super easy, and running them is
>>>>> too.
>>>>> >>> >>>>> Just
>>>>> >>> >>>>> do:
>>>>> >>> >>>>>
>>>>> >>> >>>>> nosetest -w yt/
>>>>> >>> >>>>>
>>>>> >>> >>>>> when in your source directory.
>>>>> >>> >>>>>
>>>>> >>> >>>>> 4) I've written a simple sample here:
>>>>> >>> >>>>>
>>>>> >>> >>>>>
>>>>> >>> >>>>>
>>>>> >>> >>>>>
>>>>> https://bitbucket.org/yt_analysis/yt-3.0/src/da10ffc17f6d/yt/utilities/tests/test_interpolators.py
>>>>> >>> >>>>>
>>>>> >>> >>>>> 5) I'll handle writing up some mock data that doesn't require
>>>>> >>> >>>>> shipping
>>>>> >>> >>>>> lots of binary files, which can then be used for checking
>>>>> things
>>>>> >>> >>>>> that
>>>>> >>> >>>>> absolutely require hierarchies.
>>>>> >>> >>>>>
>>>>> >>> >>>>> --
>>>>> >>> >>>>>
>>>>> >>> >>>>> The way to organize tests is easy.  Inside each directory
>>>>> with
>>>>> >>> >>>>> testable items create a new directory called "tests", and in
>>>>> here
>>>>> >>> >>>>> toss
>>>>> >>> >>>>> some scripts.  You can stick a bunch of functions in those
>>>>> scripts.
>>>>> >>> >>>>>
>>>>> >>> >>>>> Anyway, I'm going to start writing more of these (in the
>>>>> main yt
>>>>> >>> >>>>> repo,
>>>>> >>> >>>>> and this change will be grafted there as well) and I'll
>>>>> write back
>>>>> >>> >>>>> once the data mocking is ready.  I'd like it if we started
>>>>> >>> >>>>> encouraging
>>>>> >>> >>>>> or even mandating simple tests (and/or answer tests) for
>>>>> >>> >>>>> functionality
>>>>> >>> >>>>> that gets added, but that's a discussion that should be held
>>>>> >>> >>>>> separately.
>>>>> >>> >>>>>
>>>>> >>> >>>>> The items on the ticket:
>>>>> >>> >>>>>
>>>>> >>> >>>>>  * kD-tree for nearest neighbor
>>>>> >>> >>>>>  * Geometric selection routines
>>>>> >>> >>>>>  * Profiles
>>>>> >>> >>>>>  * Projections -- underlying quadtree
>>>>> >>> >>>>>  * Data object selection of data containers
>>>>> >>> >>>>>  * Data object selection of points
>>>>> >>> >>>>>  * Orientation class
>>>>> >>> >>>>>  * Pixelization
>>>>> >>> >>>>>  * Color maps
>>>>> >>> >>>>>  * PNG writing
>>>>> >>> >>>>>
>>>>> >>> >>>>> Is anyone willing to claim any additional items that they
>>>>> will help
>>>>> >>> >>>>> write unit tests for?
>>>>> >>> >>>>>
>>>>> >>> >>>>> -Matt
>>>>> >>> >>>>> _______________________________________________
>>>>> >>> >>>>> yt-dev mailing list
>>>>> >>> >>>>> yt-dev at lists.spacepope.org
>>>>> >>> >>>>> http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>>>>> >>> >>>>
>>>>> >>> >>>>
>>>>> >>> >>>>
>>>>> >>> >>>> _______________________________________________
>>>>> >>> >>>> yt-dev mailing list
>>>>> >>> >>>> yt-dev at lists.spacepope.org
>>>>> >>> >>>> http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>>>>> >>> >>>>
>>>>> >>> >>
>>>>> >>> >>
>>>>> >>> >> _______________________________________________
>>>>> >>> >> yt-dev mailing list
>>>>> >>> >> yt-dev at lists.spacepope.org
>>>>> >>> >> http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>>>>> >>> >>
>>>>> >>> >
>>>>> >>> >
>>>>> >>> > _______________________________________________
>>>>> >>> > yt-dev mailing list
>>>>> >>> > yt-dev at lists.spacepope.org
>>>>> >>> > http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>>>>> >>> >
>>>>> >>> _______________________________________________
>>>>> >>> yt-dev mailing list
>>>>> >>> yt-dev at lists.spacepope.org
>>>>> >>> http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>>>>> >>
>>>>> >>
>>>>> >>
>>>>> >> _______________________________________________
>>>>> >> yt-dev mailing list
>>>>> >> yt-dev at lists.spacepope.org
>>>>> >> http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>>>>> >>
>>>>> _______________________________________________
>>>>> yt-dev mailing list
>>>>> yt-dev at lists.spacepope.org
>>>>> http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>>>>>
>>>>
>>>>
>>>> _______________________________________________
>>>> yt-dev mailing list
>>>> yt-dev at lists.spacepope.org
>>>> http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>>>>
>>>>
>>>
>>> _______________________________________________
>>> yt-dev mailing list
>>> yt-dev at lists.spacepope.org
>>> http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>>>
>>>
>>
>> _______________________________________________
>> yt-dev mailing list
>> yt-dev at lists.spacepope.org
>> http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>>
>>
>
> _______________________________________________
> yt-dev mailing list
> yt-dev at lists.spacepope.org
> http://lists.spacepope.org/listinfo.cgi/yt-dev-spacepope.org
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.spacepope.org/pipermail/yt-dev-spacepope.org/attachments/20120925/70433b8c/attachment.html>


More information about the yt-dev mailing list