diff --git a/examples/main.c b/examples/main.c
index b3e85987d753d1f54c01dc68e64efce12d34d4f5..edf9610a2ea97acfb0362a0954b3abe941ca31ef 100644
--- a/examples/main.c
+++ b/examples/main.c
@@ -106,6 +106,7 @@ int main(int argc, char *argv[]) {
   struct spart *sparts = NULL;
   struct bpart *bparts = NULL;
   struct unit_system us;
+  struct los_props los_properties;
 
   int nr_nodes = 1, myrank = 0;
 
@@ -1063,6 +1064,9 @@ int main(int argc, char *argv[]) {
                with_hydro, with_self_gravity, with_star_formation,
                with_DM_background_particles, talking, dry_run, nr_nodes);
 
+    /* Initialise the line of sight properties. */
+    los_init(s.dim, &los_properties, params);
+
     if (myrank == 0) {
       clocks_gettime(&toc);
       message("space_init took %.3f %s.", clocks_diff(&tic, &toc),
@@ -1196,7 +1200,7 @@ int main(int argc, char *argv[]) {
         &reparttype, &us, &prog_const, &cosmo, &hydro_properties,
         &entropy_floor, &gravity_properties, &stars_properties,
         &black_holes_properties, &feedback_properties, &mesh, &potential,
-        &cooling_func, &starform, &chemistry, &fof_properties);
+        &cooling_func, &starform, &chemistry, &fof_properties, &los_properties);
     engine_config(/*restart=*/0, /*fof=*/0, &e, params, nr_nodes, myrank,
                   nr_threads, with_aff, talking, restart_file);
 
diff --git a/src/engine.c b/src/engine.c
index 1204095786444ae92a22f5e3a6e0ae763018e19b..856872f60ce0ab1a820fc3dbdbd2b757281bd5f3 100644
--- a/src/engine.c
+++ b/src/engine.c
@@ -2805,8 +2805,12 @@ void engine_check_for_dumps(struct engine *e) {
   }
 
   /* Do we want to write a line of sight file? */
-  ti_output = e->ti_current;
-  type = output_los;
+  if (e->ti_end_min > e->ti_next_los && e->ti_next_los > 0) {
+    if (e->ti_next_los < ti_output) {
+      ti_output = e->ti_next_los;
+      type = output_los;
+    }
+  }
 
   /* Store information before attempting extra dump-related drifts */
   const integertime_t ti_current = e->ti_current;
@@ -2897,6 +2901,8 @@ void engine_check_for_dumps(struct engine *e) {
       case output_los:
         do_line_of_sight(e);
 
+        engine_compute_next_los_time(e);
+
         break;
 
       default:
@@ -2935,6 +2941,14 @@ void engine_check_for_dumps(struct engine *e) {
       }
     }
 
+    /* Do line of sight ? */
+    if (e->ti_end_min > e->ti_next_los && e->ti_next_los > 0) {
+      if (e->ti_next_los < ti_output) {
+        ti_output = e->ti_next_los;
+        type = output_los;
+      }
+    }
+
   } /* While loop over output types */
 
   /* Restore the information we stored */
@@ -3835,7 +3849,7 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params,
                  struct cooling_function_data *cooling_func,
                  const struct star_formation *starform,
                  const struct chemistry_global_data *chemistry,
-                 struct fof_props *fof_properties) {
+                 struct fof_props *fof_properties, struct los_props *los_properties) {
 
   /* Clean-up everything */
   bzero(e, sizeof(struct engine));
@@ -3884,6 +3898,7 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params,
   units_init_default(e->snapshot_units, params, "Snapshots", internal_units);
   e->snapshot_output_count = 0;
   e->stf_output_count = 0;
+  e->los_output_count = 0;
   e->dt_min = parser_get_param_double(params, "TimeIntegration:dt_min");
   e->dt_max = parser_get_param_double(params, "TimeIntegration:dt_max");
   e->dt_max_RMS_displacement = FLT_MAX;
@@ -3916,6 +3931,7 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params,
   e->fof_properties = fof_properties;
   e->parameter_file = params;
   e->stf_this_timestep = 0;
+  e->los_properties = los_properties;
 #ifdef WITH_MPI
   e->usertime_last_step = 0.0;
   e->systime_last_step = 0.0;
@@ -4472,6 +4488,9 @@ void engine_config(int restart, int fof, struct engine *e,
     /* Find the time of the first statistics output */
     engine_compute_next_statistics_time(e);
 
+    /* Find the time of the first line of sight output */
+    engine_compute_next_los_time(e);
+
     /* Find the time of the first stf output */
     if (e->policy & engine_policy_structure_finding) {
       engine_compute_next_stf_time(e);
@@ -4884,6 +4903,77 @@ void engine_compute_next_statistics_time(struct engine *e) {
   }
 }
 
+/**
+ * @brief Computes the next time (on the time line) for a line of sight dump
+ *
+ * @param e The #engine.
+ */
+void engine_compute_next_los_time(struct engine *e) {
+  /* Do output_list file case */
+  if (e->output_list_los) {
+    output_list_read_next_time(e->output_list_los, e, "line of sights",
+                               &e->ti_next_los);
+    return;
+  }
+
+  /* Find upper-bound on last output */
+  double time_end;
+  if (e->policy & engine_policy_cosmology)
+    time_end = e->cosmology->a_end * e->delta_time_los;
+  else
+    time_end = e->time_end + e->delta_time_los;
+
+  /* Find next los above current time */
+  double time;
+  if (e->policy & engine_policy_cosmology)
+    time = e->a_first_los;
+  else
+    time = e->time_first_los;
+
+  int found_los_time = 0;
+  while (time < time_end) {
+
+    /* Output time on the integer timeline */
+    if (e->policy & engine_policy_cosmology)
+      e->ti_next_los = log(time / e->cosmology->a_begin) / e->time_base;
+    else
+      e->ti_next_los = (time - e->time_begin) / e->time_base;
+
+    /* Found it? */
+    if (e->ti_next_los > e->ti_current) {
+      found_los_time = 1;
+      break;
+    }
+
+    if (e->policy & engine_policy_cosmology)
+      time *= e->delta_time_los;
+    else
+      time += e->delta_time_los;
+  }
+
+  /* Deal with last line of sight */
+  if (!found_los_time) {
+    e->ti_next_los = -1;
+    if (e->verbose) message("No further LOS output time.");
+  } else {
+
+    /* Be nice, talk... */
+    if (e->policy & engine_policy_cosmology) {
+      const double next_los_time =
+          exp(e->ti_next_los * e->time_base) * e->cosmology->a_begin;
+      if (e->verbose)
+        message("Next output time for line of sight set to a=%e.",
+                next_los_time);
+    } else {
+      const double next_los_time =
+          e->ti_next_los * e->time_base + e->time_begin;
+      if (e->verbose)
+        message("Next output time for line of sight set to t=%e.",
+                next_los_time);
+    }
+  }
+}
+
 /**
  * @brief Computes the next time (on the time line) for structure finding
  *
@@ -5057,6 +5147,19 @@ void engine_init_output_lists(struct engine *e, struct swift_params *params) {
     else
       e->time_first_stf_output = stf_time_first;
   }
+
+  /* Deal with line of sight */
+  double los_time_first;
+  e->output_list_los = NULL;
+  output_list_init(&e->output_list_los, e, "LineOfSight",
+                   &e->delta_time_los, &los_time_first);
+
+  if (e->output_list_los) {
+    if (e->policy & engine_policy_cosmology)
+      e->a_first_los = stf_time_first;
+    else
+      e->time_first_los = stf_time_first;
+  }
 }
 
 /**
diff --git a/src/engine.h b/src/engine.h
index 3543667a563587e126cf191968d93c7c5e7b4e0a..e8d69f8e060f5b38fed3ffafe4135e0af51e6611 100644
--- a/src/engine.h
+++ b/src/engine.h
@@ -488,6 +488,17 @@ struct engine {
   /* Has there been an stf this timestep? */
   char stf_this_timestep;
 
+  /* Line of sight properties. */
+  struct los_props* los_properties;
+
+  /* Line of sight outputs information. */
+  struct output_list *output_list_los;
+  double a_first_los;
+  double time_first_los;
+  double delta_time_los;
+  integertime_t ti_next_los;
+  int los_output_count;
+
 #ifdef SWIFT_GRAVITY_FORCE_CHECKS
   /* Run brute force checks only on steps when all gparts active? */
   int force_checks_only_all_active;
@@ -510,6 +521,7 @@ void engine_compute_next_snapshot_time(struct engine *e);
 void engine_compute_next_stf_time(struct engine *e);
 void engine_compute_next_fof_time(struct engine *e);
 void engine_compute_next_statistics_time(struct engine *e);
+void engine_compute_next_los_time(struct engine *e);
 void engine_recompute_displacement_constraint(struct engine *e);
 void engine_unskip(struct engine *e);
 void engine_unskip_timestep_communications(struct engine *e);
@@ -538,7 +550,8 @@ void engine_init(struct engine *e, struct space *s, struct swift_params *params,
                  struct cooling_function_data *cooling_func,
                  const struct star_formation *starform,
                  const struct chemistry_global_data *chemistry,
-                 struct fof_props *fof_properties);
+                 struct fof_props *fof_properties,
+                 struct los_props *los_properties);
 void engine_config(int restart, int fof, struct engine *e,
                    struct swift_params *params, int nr_nodes, int nodeID,
                    int nr_threads, int with_aff, int verbose,
diff --git a/src/line_of_sight.c b/src/line_of_sight.c
index 5fa1981b677e4a26fc599ed501a9f3b398960d49..3df5e1002721d0969db64c13a20f8d0244f8d571 100644
--- a/src/line_of_sight.c
+++ b/src/line_of_sight.c
@@ -14,6 +14,36 @@
 #include "line_of_sight.h"
 #include "periodic.h"
 
+void los_init(double dim[3], struct los_props *los_params,
+        struct swift_params *params) {
+  /* How many line of sights in each plane. */
+  los_params->num_along_xy =
+      parser_get_opt_param_int(params, "LineOfSight:num_along_xy", 0);
+  los_params->num_along_yz =
+      parser_get_opt_param_int(params, "LineOfSight:num_along_yz", 0);
+  los_params->num_along_xz =
+      parser_get_opt_param_int(params, "LineOfSight:num_along_xz", 0);
+
+  /* Min/max range across x,y and z where random LOS's are allowed. */
+  los_params->xmin =
+            parser_get_opt_param_double(params, "LineOfSight:xmin", 0.);
+  los_params->xmax =
+            parser_get_opt_param_double(params, "LineOfSight:xmax", dim[0]);
+  los_params->ymin =
+            parser_get_opt_param_double(params, "LineOfSight:ymin", 0.);
+  los_params->ymax =
+            parser_get_opt_param_double(params, "LineOfSight:ymax", dim[1]);
+  los_params->zmin =
+            parser_get_opt_param_double(params, "LineOfSight:zmin", 0.);
+  los_params->zmax =
+            parser_get_opt_param_double(params, "LineOfSight:zmax", dim[2]);
+
+  /* Compute total number of sightlines. */
+  los_params->num_tot = los_params->num_along_xy +
+                        los_params->num_along_yz +
+                        los_params->num_along_xz;
+} 
+
 /**
  * @brief Generates random sightline positions.
  *
@@ -23,7 +53,7 @@
  * @param params Sightline parameters.
  */
 void generate_line_of_sights(struct line_of_sight *Los,
-                             struct line_of_sight_params *params) {
+                             struct los_props *params) {
 
   /* Keep track of number of sightlines. */
   int count = 0;
@@ -84,7 +114,7 @@ void generate_line_of_sights(struct line_of_sight *Los,
  * @param params Sightline parameters.
  */
 void print_los_info(struct line_of_sight *Los,
-                    struct line_of_sight_params *params) {
+                    struct los_props *params) {
 
   printf("\nPrinting LOS information...\n");
   for (int i = 0; i < params->num_tot; i++) {
@@ -100,26 +130,14 @@ void do_line_of_sight(struct engine *e) {
 
   const struct space *s = e->s;
   const size_t nr_parts = s->nr_parts;
-
-  /* LOS params, dummy until included in parameter file. */
-  struct line_of_sight_params LOS_params = {.num_along_xy = 1,
-                                            .num_along_yz = 1,
-                                            .num_along_xz = 1,
-                                            .xmin = 0,
-                                            .xmax = 10,
-                                            .ymin = 0,
-                                            .ymax = 10,
-                                            .zmin = 0,
-                                            .zmax = 10};
-  LOS_params.num_tot = LOS_params.num_along_xy + LOS_params.num_along_yz +
-                       LOS_params.num_along_xz;
+  struct los_props *LOS_params = e->los_properties;
 
   /* Start by generating the random sightline positions. */
   struct line_of_sight *LOS_list = (struct line_of_sight *)malloc(
-      LOS_params.num_tot * sizeof(struct line_of_sight));
-  if (e->nodeID == 0) generate_line_of_sights(LOS_list, &LOS_params);
+      LOS_params->num_tot * sizeof(struct line_of_sight));
+  if (e->nodeID == 0) generate_line_of_sights(LOS_list, LOS_params);
 #ifdef WITH_MPI
-  MPI_Bcast(LOS_list, LOS_params.num_tot * sizeof(struct line_of_sight),
+  MPI_Bcast(LOS_list, LOS_params->num_tot * sizeof(struct line_of_sight),
             MPI_BYTE, 0, MPI_COMM_WORLD);
 #endif
 
@@ -129,7 +147,7 @@ void do_line_of_sight(struct engine *e) {
 
   if (e->nodeID == 0) {
     char filename[200];
-    sprintf(filename, "los_%04i.csv", engine_current_step);
+    sprintf(filename, "los_%04i.csv", e->los_output_count);
     f = fopen(filename, "w");
     if (f == NULL) error("Error opening los file.");
 
@@ -138,7 +156,7 @@ void do_line_of_sight(struct engine *e) {
   }
 
   /* Loop over each random LOS. */
-  for (int j = 0; j < LOS_params.num_tot; j++) {
+  for (int j = 0; j < LOS_params->num_tot; j++) {
 
     /* Loop over each gas particle to find those in LOS. */
     for (size_t i = 0; i < nr_parts; i++) {
@@ -277,9 +295,12 @@ void do_line_of_sight(struct engine *e) {
   if (e->nodeID == 0) fclose(f);
 
   //#ifdef SWIFT_DEBUG_CHECKS
-  if (e->nodeID == 0) print_los_info(LOS_list, &LOS_params);
+  if (e->nodeID == 0) print_los_info(LOS_list, LOS_params);
   //#endif
-  
+ 
+  /* Up the count. */
+  e->los_output_count++;
+
   message("took %.3f %s.", clocks_from_ticks(getticks() - tic),
             clocks_getunit());
 }
diff --git a/src/line_of_sight.h b/src/line_of_sight.h
index e349e96b5512fcf0c13a1113b599dcaccc95bda7..f7d92644ad00c694856d9b30f5abadd856bf0c8a 100644
--- a/src/line_of_sight.h
+++ b/src/line_of_sight.h
@@ -13,7 +13,7 @@ struct line_of_sight_particles {
   float h;
 };
 
-struct line_of_sight_params {
+struct los_props {
   int num_along_xy;
   int num_along_yz;
   int num_along_xz;
@@ -26,11 +26,10 @@ struct line_of_sight_params {
 };
 
 double los_periodic(double x, double dim);
-
 void generate_line_of_sights(struct line_of_sight *Los,
-                             struct line_of_sight_params *params);
-
+                             struct los_props *params);
 void print_los_info(struct line_of_sight *Los,
-                    struct line_of_sight_params *params);
-
+                    struct los_props *params);
 void do_line_of_sight(struct engine *e);
+void los_init(double dim[3], struct los_props *los_params,
+        struct swift_params *params);
diff --git a/src/swift.h b/src/swift.h
index c7a5f8d5acbcc17dd467cbcfb914eac025894dae..3c659aa7dce1d78d9887187da31e4ee500ad6848 100644
--- a/src/swift.h
+++ b/src/swift.h
@@ -50,6 +50,7 @@
 #include "hashmap.h"
 #include "hydro.h"
 #include "hydro_properties.h"
+#include "line_of_sight.h"
 #include "lock.h"
 #include "logger.h"
 #include "logger_io.h"