Before thinking about the reader implementation, lets start by imagining the kind of API we would like to provide to users.
withlogger.Reader(basename)asf:# Create a logger.ParticleSet of the particles we want to track.# This function loops over all the index files and get all the particles# contain cache for the particle set (for later)particle_set=f.get_particles(type="Gas",cache=True)particle_set-=f.get_particles(ids=[...])# remove the use of the cacheparticle_set.cache_enabled(False)# Read some fields for some particles. This generates a new ParticleSet that# contains the particles from `particle_set` that exist at time `time`, and# populates their position and velocities.particles_at_time_t=f.get_particle_data(particles=particle_set,fields=["Coordinates","Velocities"],time=time,interpolation="linear")# Extract the particle positions as an Nx3 matrix.positions=particles_at_time_t["Coordinates"]# Move a set of particles forward in time.# here we should be fast thanks to the cache.particles_at_time_t_plus_one=f.get_particle_data(particles=particles_at_time_t,fields=["Coordinates"],time=time+1)# here we close the logfile and cleanup everything
The main class here is logger.Reader, which manages the log and index files in the directory basename.
The logger.ParticleSet is an abstraction for a set of particles from a Reader. Like regular sets, we can add, subtract, and intersect ParticleSets.
The function Reader.get_particle_data extracts data for a set of particles at a given time.