Commit 6a64cecb authored by Breno Rilho Lemos's avatar Breno Rilho Lemos 💬

Add magnetic field and relativistic effects

parent 81167d01
......@@ -2,53 +2,107 @@
# particulas.py - Protótipo de animação de partículas
# Para utilizar este script chame o blender com a opção -P e o nome do arquivo
#
# $ blender -P ./animate_particles.py
# For console only rendering:
# $ blender -noaudio --background -P animate_particles.py
#
# TODO: - Implement command line arguments
# - https://blender.stackexchange.com/questions/6817/how-to-pass-command-line-arguments-to-a-blender-python-script
import bpy
bpy.context.user_preferences.view.show_splash = False
import math
import os
import random
# Import Particle class
filename = os.path.join(os.path.basename(bpy.data.filepath), "particle.py")
exec(compile(open(filename).read(), filename, 'exec'))
t_video=10 # duração da animação em segundos
t_simulado=10
fps = 24 # quadros por segundo
N_quadros=t_video*fps # calculando numero de quadros totais
delta_t=t_simulado/N_quadros # tempo passado por quadro
t_video=10 # total video duration in seconds
t_simulado=0.01 # tempo em microssegundos ~ tempo para percorrer 3m na velocidade da luz
fps = 24 # frames per second
N_frames=t_video*fps # Total number of frames
delta_t=t_simulado/N_frames # time elapsed per frame
particle_types = ["Electron","Pion","Muon","Proton","Kaon"]
clRed = (1, 0, 0)
clGreen = (0, 1, 0)
clBlue = (0, 0, 1)
clMagenta = (0.75, 0, 1)
clYellow = (1, 1, 0)
particle_colors = {"Electron":clRed, "Pion":clGreen, "Muon":clBlue, "Proton":clMagenta, "Kaon": clYellow}
# Particle radius
r_part = 0.10
r_part = 0.05
# Event Multiplicity
n_particles = 10
# Configure Environment
bcs = bpy.context.scene
bcs.world.light_settings.use_environment_light = False
bcs.world.light_settings.environment_energy = 0.1
# Configure Output
bcsr = bcs.render
bcsr.resolution_percentage = 50
bcsr.image_settings.file_format = 'FFMPEG'
bcsr.ffmpeg.format = "MPEG4"
bcsr.ffmpeg.codec = "H264"
bcsr.ffmpeg.use_max_b_frames = False
bcsr.ffmpeg.video_bitrate = 6000
bcsr.ffmpeg.maxrate = 9000
bcsr.ffmpeg.minrate = 0
bcsr.ffmpeg.buffersize = 224 * 8
bcsr.ffmpeg.packetsize = 2048
bcsr.ffmpeg.muxrate = 10080000
xpixels = int(bcsr.resolution_percentage * bcsr.resolution_x / 100)
output_prefix="N"+str(n_particles)+"_Gaussian_"+str(xpixels)+"px_"
bcsr.filepath = "/tmp/blender/"+output_prefix
#bcsr.threads_mode = 'FIXED'
#bcsr.threads = 16
# Function that creates Blender Objects from input list of particles.
## Returns a list of blender objects
def create(particles):
bpy.context.scene.render.fps=fps
bpy.context.scene.frame_start = 0
bpy.context.scene.frame_end = N_quadros
bcsr.fps=fps
bcs.frame_start = 0
bcs.frame_end = N_frames
blender_particles=[]
#Create Materials
for type in particle_types:
bpy.data.materials.new(name=type)
#bpy.context.object.active_material = (1, 0, 0)
bpy.data.materials[type].diffuse_color = particle_colors[type]
# Create blender spheres (particles)
for particle in particles:
this_type=random.choice(particle_types)
print("Adding Sphere - Particle " + str(len(blender_particles))+" of "+str(n_particles-1)+" - "+this_type)
bpy.ops.mesh.primitive_uv_sphere_add()
this_particle = bpy.context.object
this_particle.name = "part"+str(particle.iDx)
this_particle.location=((particle.x,particle.y,particle.z))
this_particle.delta_scale=(r_part,r_part,r_part)
this_particle.data.materials.clear()
this_particle.data.materials.append(bpy.data.materials[this_type])
blender_particles.append(this_particle)
return blender_particles
# Function that animates the scene using the particle propagator class
def animate(objects):
#Animate particles
for f in range(1, N_quadros):
for f in range(1, N_frames):
t=delta_t*f
bpy.context.scene.frame_current = f
bcs.frame_current = f
print("Configuring Frame: "+str(f)+" of "+str(N_frames))
for i in range(0, len(objects)):
bpy.context.scene.objects.active=objects[i]
bcs.objects.active=objects[i]
objects[i].location=(particles[i].Propagate(t))
objects[i].keyframe_insert(data_path='location')
......@@ -56,18 +110,37 @@ def animate(objects):
# Remove cube
bpy.data.objects.remove(bpy.data.objects['Cube'])
camera_forward=bpy.data.objects['Camera']
camera_forward.name = 'ForwardCamera'
camera_forward.location=(0,0,6)
camera_forward.rotation_euler[0] = 0
camera_forward.rotation_euler[2] = 0
bpy.ops.object.camera_add(location=(6, 0, 0), rotation=(0, 1.5708, 0))
#bpy.context.object.rotation_euler[1] = 1.5708
bpy.context.object.name = "BarrelCamera"
# Select scene camera
bpy.context.scene.camera = bpy.data.objects["ForwardCamera"]
# Create particles
particles = createNparticlesProp(1000)
particles = createNparticlesPropGaussian(n_particles)
# Create blender objects
blender_particles = create(particles)
#Animate Scene
animate(blender_particles)
bpy.context.scene.frame_current = 20
## Todo:
## - Lamp and cameras in suitable positions
## - Configure particle and background colors
## - Configure output format and enconding (FFmpeg & H.264 works fine)
## - Add option to keep particle trails
## - Add simple geometry of the ALICE detector
## Save blender file
#bpy.ops.wm.save_as_mainfile(filepath="/home/pezzi/particles_"+str(n_particles)+".blend")
# Render animation
bpy.ops.render.render(animation=True)
#exit()
......@@ -5,7 +5,7 @@ import random
# Basic particle class to store bascic information
class Particle:
def __init__(self, index, x = 0, y = 0, z = 0, charge = 1, mass=1):
def __init__(self, index, x = 0, y = 0, z = 0, charge = 1, mass=0.94):
self.iDx=index
self.x=x
self.y=y
......@@ -28,26 +28,32 @@ def createNparticles(N_particles, x = 0, y = 0, z = 0): # Create particles at g
# Derived class to computes the time evolution particle positions
class ParticlePropagator(Particle):
def SetMagneticField(self,B):
def SetMagneticField(self, B = 0.5):
self.B = B
def SetMomentum(self,Px, Py, Pz):
self.Px = Px
self.Py = Py
self.Pz = Pz
def Propagate(self, time): # Todo: Add relativistic and magnetic field effects
Xprop = self.x + time*self.Px/self.mass
Yprop = self.y + time*self.Py/self.mass
Zprop = self.z + time*self.Pz/self.mass
def SetProperties(self, Px, Py, Pz):
self.Px = Px # unit: Gev/c
self.Py = Py # unit: Gev/c
self.Pz = Pz # unit: Gev/c
self.Velocity = 1/math.sqrt(1+self.mass*self.mass/(Px*Px+Py*Py+Pz*Pz)) # unit: []c
self.LorentzFactor = 1 / math.sqrt( 1 - self.Velocity * self.Velocity )
self.Vz = 300 * Pz / self.LorentzFactor / self.mass # unit: meters/micro seconds
def Propagate(self, time):
Rx = self.Px / (self.charge * self.B) * 3.335641 # unit conversion to meters
Ry = self.Py / (self.charge * self.B) * 3.335641 # unit conversion to meters
omega = self.charge * self.B / ( self.LorentzFactor * self.mass ) * 89.876 # Angular frequency (unit: radians/micro seconds)
Xprop = self.x + Rx * math.sin(omega*time) - Ry * ( math.cos(omega*time) - 1 )
Yprop = self.y + Ry * math.sin(omega*time) + Rx * ( math.cos(omega*time) - 1 )
Zprop = self.z + self.Vz * time
return Xprop, Yprop, Zprop
# Function that creates N particle propagators
# Momentum values to be obtained from real data
def createNparticlesProp(N_particles, x = 0, y = 0, z = 0): # Create particles at given position and return them in a list
def createNparticlesPropGaussian(N_particles, x = 0, y = 0, z = 0): # Create particles at given position and return them in a list
particles=[]
#loop over particles
for i in range(0, N_particles):
part = ParticlePropagator(i,x,y,z)
part.SetMagneticField(0.5)
part.SetMomentum(random.gauss(0,1),random.gauss(0,1),random.gauss(0,1))
part.SetMagneticField()
part.SetProperties(random.gauss(0,1),random.gauss(0,1),random.gauss(0,1))
particles.append(part)
return particles;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment