![](https://secure.gravatar.com/avatar/0c499e393696ca9a560466b8d4747bb1.jpg?s=120&d=mm&r=g)
Hi, Does anyone know an easy way to include particles positions (i.e. as small spheres) in a volume rendering? It occurred to me that I could add high values to the locations of the particles within the field that is being rendered and then define the transfer function in order to pick them out. However, I'm not sure how to modify the field data to do this. Any suggestions? Thanks! Stella
![](https://secure.gravatar.com/avatar/b279d746f54e2cd6062e8279a767c4bc.jpg?s=120&d=mm&r=g)
Hi Stella,
Does anyone know an easy way to include particles positions (i.e. as small spheres) in a volume rendering? It occurred to me that I could add high values to the locations of the particles within the field that is being rendered and then define the transfer function in order to pick them out. However, I'm not sure how to modify the field data to do this. Any suggestions?
That idea would work, for getting out the particle positions -- but it might not give the best results. Unfortunately, adding on an actual scenegraph to the software volume renderer is quite the task -- right now it's set up just to stride over every grid, accumulating rays. One could imagine inserting a break in this for a specific object, but then you'd need to add on the appropriate culling and so on. More easily you could use a particle deposition mechanism, like the CIC_Deposit, for the particles. Unfortunately you can't define a radius for this, but it might work for relatively large numbers of particles ... but I'm not sure that's the domain you're interested in. For only a few particles, it will not look very good is my guess. The way the fields are set up, you could have this be a field table that is updated along with the others, and it could be an additive process. So I guess ... right now particle rendering probably won't work with the software volume renderer in the way you describe without some work. But you can probably get something out of it. I think the best bet for this kind of thing is some kind of compositing mechanism, which is typically easier to implement in hardware or OpenGL... Although, actually, if you're willing to muck about with the field data (like you mentioned above) you could define a new field that just sets its scale to the distance from any particle. In the limit of relatively few particles, you could define this with a derived field that simply iterates over the list and takes the max. Which I guess is what you proposed initially! Maybe something like: def _ParticleSpheres(field, data): tr = na.ones(data["Ones"].shape) for particle in some_list_of_particles: my_radius = ... tr += my_radius * some_function return tr Or something? I'm not sure the right way to get it out of this. But then you could add an isocontour at the value of some_function at the distance you want. Anyway, sorry for the speculative email, but I hope it's been at least a little helpful! -Matt
![](https://secure.gravatar.com/avatar/c9bbaaaf9328bd8a4ab0cc90e596c197.jpg?s=120&d=mm&r=g)
Hi Stella,
Does anyone know an easy way to include particles positions (i.e. as small spheres) in a volume rendering? It occurred to me that I could add high values to the locations of the particles within the field that is being rendered and then define the transfer function in order to pick them out. However, I'm not sure how to modify the field data to do this. Any suggestions?
I've been doing something similar to this with some (but not great) success, but not exactly the same as you've described. Instead of plotting the particles as small spheres, I translate them into a density using the Cloud In Cell code included in yt, which is then treated like any other density field (like 'Density'). The main is to define a new field that translates particles to density. This example picks out star particles; it should be easy to remove this if you like by eliminating the 'sel' stuff below. import yt.lagos.UniversalFields as uf def _pdensity_pyx(field, data): blank = na.zeros(data.ActiveDimensions, dtype='float32') if data.NumberOfParticles == 0: return blank uf.CICDeposit_3(data["particle_position_x"].astype(na.float64), data["particle_position_y"].astype(na.float64), data["particle_position_z"].astype(na.float64), data["particle_mass"].astype(na.float32), na.int64(data["particle_mass"].size), blank, na.array(data.LeftEdge).astype(na.float64), na.array(data.ActiveDimensions).astype(na.int32), na.float64(data['dx'])) return blank add_field("particle_density_pyx", function=_pdensity_pyx, validators=[uf.ValidateSpatial(0)], convert_function=uf._convertDensity, display_name=r"\mathrm{Particle\ Density})") Then you can use the field "particle_density_pyx" as you would "Density". The one thing to worry about in the case of stars, is there can be cells with no stars in them, which creates problems if you're doing the volume rendering in log space. Let me know if you have problems! _______________________________________________________ sskory@physics.ucsd.edu o__ Stephen Skory http://physics.ucsd.edu/~sskory/ _.>/ _Graduate Student ________________________________(_)_\(_)_______________
![](https://secure.gravatar.com/avatar/b279d746f54e2cd6062e8279a767c4bc.jpg?s=120&d=mm&r=g)
The main is to define a new field that translates particles to density. This example picks out star particles; it should be easy to remove this if you like by eliminating the 'sel' stuff below.
As a quick note for other users, the field Stephen describes is already in Universal fields as "particle_density_pyx", and a similar one ("star_density_pyx") is defined for star particles in Enzo. For Orion the particle situation isn't clear to me, so I don't know how that would work. -Matt
![](https://secure.gravatar.com/avatar/0c499e393696ca9a560466b8d4747bb1.jpg?s=120&d=mm&r=g)
Thanks, Matt and Stephen! The issue here is that I only have a small number of stars (< 100), so calculating a particle density would probably cause problems. It might be possible to use what you suggest below if I don't start with a blank field filled with zeros (I also will likely plot in log space). I will play around with some of these things and let you know if I find something useful... Stella
The main is to define a new field that translates particles to density. This example picks out star particles; it should be easy to remove this if you like by eliminating the 'sel' stuff below.
import yt.lagos.UniversalFields as uf
def _pdensity_pyx(field, data): blank = na.zeros(data.ActiveDimensions, dtype='float32') if data.NumberOfParticles == 0: return blank uf.CICDeposit_3(data["particle_position_x"].astype(na.float64), data["particle_position_y"].astype(na.float64), data["particle_position_z"].astype(na.float64), data["particle_mass"].astype(na.float32), na.int64(data["particle_mass"].size), blank, na.array(data.LeftEdge).astype(na.float64), na.array(data.ActiveDimensions).astype(na.int32), na.float64(data['dx'])) return blank
add_field("particle_density_pyx", function=_pdensity_pyx, validators=[uf.ValidateSpatial(0)], convert_function=uf._convertDensity, display_name=r"\mathrm{Particle\ Density})")
Then you can use the field "particle_density_pyx" as you would "Density". The one thing to worry about in the case of stars, is there can be cells with no stars in them, which creates problems if you're doing the volume rendering in log space. Let me know if you have problems!
![](https://secure.gravatar.com/avatar/d8971e19f9b3d3630b442908e12ad379.jpg?s=120&d=mm&r=g)
Orion particles aren't in yt properly yet to my knowledge, but anyone using them has their own particle readers by this point. I've just started adding the particles to the density field by hand lately (code below). They look blocky and their size depends on the cell width, but the bigger problem is that the particles still aren't visible unless I am extremely careful with the color scheme of the contours. Even if alpha is set to 1, any given contour is mostly transparent. Is there a way to tell the renderer that some particular cell (where a sink particle is) is completely opaque? Charles def _partden(field, data): starlist = particles.readParticles(data.pf) #not part of yt x = data["x"] y = data["y"] z = data["z"] partm = 0 if starlist != None: dx = data["dx"] dy = data["dy"] dz = data["dz"] for i in range(0, len(starlist)): dxp = abs(x-starlist[i]['x'][0]) dyp = abs(y-starlist[i]['x'][1]) dzp = abs(z-starlist[i]['x'][2]) mass = starlist[i]['m']*(dxp < dx/2)*(dyp < dy/2)*(dzp < dz/2) partm = partm + mass partden = partm/data["CellVolume"] return partden add_field("partden", function=_partden) def _dentot(field, data): return (data["density"]+data["partden"]) add_field("dentot", function=_dentot) Stella Offner wrote:
Thanks, Matt and Stephen! The issue here is that I only have a small number of stars (< 100), so calculating a particle density would probably cause problems.
It might be possible to use what you suggest below if I don't start with a blank field filled with zeros (I also will likely plot in log space). I will play around with some of these things and let you know if I find something useful... Stella
The main is to define a new field that translates particles to density. This example picks out star particles; it should be easy to remove this if you like by eliminating the 'sel' stuff below.
import yt.lagos.UniversalFields as uf
def _pdensity_pyx(field, data): blank = na.zeros(data.ActiveDimensions, dtype='float32') if data.NumberOfParticles == 0: return blank uf.CICDeposit_3(data["particle_position_x"].astype(na.float64), data["particle_position_y"].astype(na.float64), data["particle_position_z"].astype(na.float64), data["particle_mass"].astype(na.float32), na.int64(data["particle_mass"].size), blank, na.array(data.LeftEdge).astype(na.float64), na.array(data.ActiveDimensions).astype(na.int32), na.float64(data['dx'])) return blank
add_field("particle_density_pyx", function=_pdensity_pyx, validators=[uf.ValidateSpatial(0)], convert_function=uf._convertDensity, display_name=r"\mathrm{Particle\ Density})")
Then you can use the field "particle_density_pyx" as you would "Density". The one thing to worry about in the case of stars, is there can be cells with no stars in them, which creates problems if you're doing the volume rendering in log space. Let me know if you have problems!
_______________________________________________ yt-users mailing list yt-users@lists.spacepope.org http://lists.spacepope.org/listinfo.cgi/yt-users-spacepope.org
![](https://secure.gravatar.com/avatar/b279d746f54e2cd6062e8279a767c4bc.jpg?s=120&d=mm&r=g)
Hi Charles, I think if you set the alpha and the color values to 1.0, it should be completely opaque. Without seeing your transfer function definition I can't be completely sure, however. If you look at yt/_amr_utils/VolumeIntegrator.pyx in the FIT_get_values you'll see some comments about how the transfer function works... -Matt On Mon, Aug 2, 2010 at 10:45 AM, Charles Hansen <chansen@astro.berkeley.edu> wrote:
Orion particles aren't in yt properly yet to my knowledge, but anyone using them has their own particle readers by this point. I've just started adding the particles to the density field by hand lately (code below). They look blocky and their size depends on the cell width, but the bigger problem is that the particles still aren't visible unless I am extremely careful with the color scheme of the contours. Even if alpha is set to 1, any given contour is mostly transparent. Is there a way to tell the renderer that some particular cell (where a sink particle is) is completely opaque?
Charles
def _partden(field, data): starlist = particles.readParticles(data.pf) #not part of yt x = data["x"] y = data["y"] z = data["z"] partm = 0 if starlist != None: dx = data["dx"] dy = data["dy"] dz = data["dz"] for i in range(0, len(starlist)): dxp = abs(x-starlist[i]['x'][0]) dyp = abs(y-starlist[i]['x'][1]) dzp = abs(z-starlist[i]['x'][2])
mass = starlist[i]['m']*(dxp < dx/2)*(dyp < dy/2)*(dzp < dz/2) partm = partm + mass partden = partm/data["CellVolume"] return partden add_field("partden", function=_partden) def _dentot(field, data): return (data["density"]+data["partden"]) add_field("dentot", function=_dentot)
Stella Offner wrote:
Thanks, Matt and Stephen! The issue here is that I only have a small number of stars (< 100), so calculating a particle density would probably cause problems.
It might be possible to use what you suggest below if I don't start with a blank field filled with zeros (I also will likely plot in log space). I will play around with some of these things and let you know if I find something useful... Stella
The main is to define a new field that translates particles to density. This example picks out star particles; it should be easy to remove this if you like by eliminating the 'sel' stuff below.
import yt.lagos.UniversalFields as uf
def _pdensity_pyx(field, data): blank = na.zeros(data.ActiveDimensions, dtype='float32') if data.NumberOfParticles == 0: return blank uf.CICDeposit_3(data["particle_position_x"].astype(na.float64), data["particle_position_y"].astype(na.float64), data["particle_position_z"].astype(na.float64), data["particle_mass"].astype(na.float32), na.int64(data["particle_mass"].size), blank, na.array(data.LeftEdge).astype(na.float64), na.array(data.ActiveDimensions).astype(na.int32), na.float64(data['dx'])) return blank
add_field("particle_density_pyx", function=_pdensity_pyx, validators=[uf.ValidateSpatial(0)], convert_function=uf._convertDensity, display_name=r"\mathrm{Particle\ Density})")
Then you can use the field "particle_density_pyx" as you would "Density". The one thing to worry about in the case of stars, is there can be cells with no stars in them, which creates problems if you're doing the volume rendering in log space. Let me know if you have problems!
_______________________________________________ yt-users mailing list yt-users@lists.spacepope.org http://lists.spacepope.org/listinfo.cgi/yt-users-spacepope.org
_______________________________________________ yt-users mailing list yt-users@lists.spacepope.org http://lists.spacepope.org/listinfo.cgi/yt-users-spacepope.org
participants (4)
-
Charles Hansen
-
Matthew Turk
-
Stella Offner
-
Stephen Skory