Exemplo n.º 1
0
    def __init__(self, config, datetime_start, datetime_end):
        self.config = config

        file_name_reader = DiskFileNameReader()

        dataset_reader = NetCDFDatasetReader()

        self.file_reader = FileReader(config, file_name_reader, dataset_reader,
                                      datetime_start, datetime_end)
Exemplo n.º 2
0
    def test_use_start_datetime_equal_to_data_record_start(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)
Exemplo n.º 3
0
    def test_use_end_datetime_equal_to_data_record_start(self):
        # Should be valid during reverse tracking
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 second before data record end
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds after data record start

        self.config.set('SIMULATION', 'time_direction', 'reverse')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)
Exemplo n.º 4
0
    def test_set_time_indices_with_start_datetime_equal_to_data_record_start(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time indices
        test.assert_equal(0, self.file_reader.tidx_first)
        test.assert_equal(1, self.file_reader.tidx_second)
Exemplo n.º 5
0
    def test_set_time_indices_when_reverse_tracking(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 3, 0)  # Valid = 180 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds before data record start

        self.config.set('SIMULATION', 'time_direction', 'reverse')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time indices
        test.assert_equal(2, self.file_reader.tidx_first)
        test.assert_equal(0, self.file_reader.tidx_second)
Exemplo n.º 6
0
    def test_set_time_indices_with_start_datetime_equal_to_the_last_time_point_in_the_first_data_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 2, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time indices
        test.assert_equal(2, self.file_reader.tidx_first)
        test.assert_equal(0, self.file_reader.tidx_second)
Exemplo n.º 7
0
    def test_set_time_indices_with_time_points_repeated_between_adjacent_files(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 5, 0)  # Valid = 300 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time indices
        test.assert_equal(0, self.file_reader.tidx_first)
        test.assert_equal(1, self.file_reader.tidx_second)
Exemplo n.º 8
0
    def test_set_file_names_with_start_datetime_in_the_second_data_file(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 4, 0)  # Valid = 240 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check file names
        test.assert_array_equal('test_file_2',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_2',
                                self.file_reader.second_data_file_name)
Exemplo n.º 9
0
    def test_set_time_indices_when_updating_reading_frames_during_reverse_tracking_into_first_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 3, 0)  # Valid = 180 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds before data record start

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=-90.)

        # Check time indices
        test.assert_equal(1, self.file_reader.tidx_first)
        test.assert_equal(2, self.file_reader.tidx_second)
Exemplo n.º 10
0
    def test_set_time_arrays_with_start_datetime_equal_to_the_last_time_point_in_the_first_data_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 2, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time arrays
        test.assert_array_almost_equal([-120., -60., 0.],
                                       self.file_reader.first_time)
        test.assert_array_almost_equal([60., 120., 180.],
                                       self.file_reader.second_time)
Exemplo n.º 11
0
    def test_set_time_indices_when_updating_reading_frames_at_the_start_of_the_second_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=180.)

        # Check time indices
        test.assert_equal(0, self.file_reader.tidx_first)
        test.assert_equal(1, self.file_reader.tidx_second)
Exemplo n.º 12
0
    def test_set_file_names_when_updating_reading_frames_during_reverse_tracking_between_data_files(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 3, 0)  # Valid = 180 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds before data record start

        self.config.set('SIMULATION', 'time_direction', 'reverse')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=-60.)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_1',
                                self.file_reader.second_data_file_name)
Exemplo n.º 13
0
    def test_set_file_names_when_updating_reading_frames_after_the_end_of_the_first_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=150.)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_2',
                                self.file_reader.second_data_file_name)
Exemplo n.º 14
0
    def __init__(self, config, datetime_start, datetime_end):
        self.config = config

        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        # Only the root process accesses the file system
        if rank == 0:
            try:
                file_name_reader = DiskFileNameReader()
                dataset_reader = NetCDFDatasetReader()
                self.file_reader = FileReader(config, file_name_reader,
                                              dataset_reader, datetime_start,
                                              datetime_end)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when reading input file. '\
                'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            self.file_reader = None
Exemplo n.º 15
0
class MPIMediator(Mediator):
    """ MPI mediator

    MPI mediator for parallel runs.

    Parameters
    ----------
    config : ConfigParser
        Run configuration object

    start_datetime : Datetime
        Simulation start date/time.

    end_datetime : Datetime
        Simulation end date/time.

    Attributes
    ----------
    config : ConfigParser
        Run configuration object

    file_reader : pylag.FileReader
        FileReader object.

    """
    def __init__(self, config, datetime_start, datetime_end):
        self.config = config

        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        # Only the root process accesses the file system
        if rank == 0:
            try:
                file_name_reader = DiskFileNameReader()
                dataset_reader = NetCDFDatasetReader()
                self.file_reader = FileReader(config, file_name_reader,
                                              dataset_reader, datetime_start,
                                              datetime_end)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when reading input file. '\
                'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            self.file_reader = None

    def setup_data_access(self, datetime_start, datetime_end):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                self.file_reader.setup_data_access(datetime_start,
                                                   datetime_end)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when setting up data access. '\
                'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()

    def update_reading_frames(self, time):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                self.file_reader.update_reading_frames(time)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when updating reading frames. '\
                'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()

    def get_dimension_variable(self, var_name):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                var = self.file_reader.get_dimension_variable(var_name)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting dimension variable. '\
                'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            var = None

        var = comm.bcast(var, root=0)

        return var

    def get_grid_variable(self, var_name, var_dims, var_type):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                var = self.file_reader.get_grid_variable(var_name).astype(
                    var_type)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting grid variable. '\
                'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            var = np.empty(var_dims, dtype=var_type)

        comm.Bcast(var, root=0)

        return var

    def get_time_at_last_time_index(self):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                time = self.file_reader.get_time_at_last_time_index()
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting last time index. '\
                'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            time = None

        time = comm.bcast(time, root=0)

        return time

    def get_time_at_next_time_index(self):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                time = self.file_reader.get_time_at_next_time_index()
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting next time index. '\
                'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            time = None

        time = comm.bcast(time, root=0)

        return time

    def get_grid_variable_dimensions(self, var_name):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                dimensions = self.file_reader.get_grid_variable_dimensions(
                    var_name)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting variable dimensions. ' \
                             'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            dimensions = None

        dimensions = comm.bcast(dimensions, root=0)

        return dimensions

    def get_variable_dimensions(self, var_name):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                dimensions = self.file_reader.get_variable_dimensions(var_name)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting variable dimensions. ' \
                             'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            dimensions = None

        dimensions = comm.bcast(dimensions, root=0)

        return dimensions

    def get_variable_shape(self, var_name):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                shape = self.file_reader.get_variable_shape(var_name)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting variable shape. ' \
                             'Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            shape = None

        shape = comm.bcast(shape, root=0)

        return shape

    def get_time_dependent_variable_at_last_time_index(self, var_name,
                                                       var_dims, var_type):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                var = self.file_reader.get_time_dependent_variable_at_last_time_index(
                    var_name).astype(var_type)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting time variable at '\
                'last time index. Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            var = np.empty(var_dims, dtype=var_type)

        comm.Bcast(var, root=0)

        return var

    def get_time_dependent_variable_at_next_time_index(self, var_name,
                                                       var_dims, var_type):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                var = self.file_reader.get_time_dependent_variable_at_next_time_index(
                    var_name).astype(var_type)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting time variable at '\
                'next time index. Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            var = np.empty(var_dims, dtype=var_type)

        comm.Bcast(var, root=0)

        return var

    def get_mask_at_last_time_index(self, var_name, var_dims):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                mask = self.file_reader.get_mask_at_last_time_index(
                    var_name).astype(DTYPE_INT)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting mask at ' \
                             'last time index. Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            mask = np.empty(var_dims, dtype=DTYPE_INT)

        comm.Bcast(mask, root=0)

        return mask

    def get_mask_at_next_time_index(self, var_name, var_dims):
        # MPI objects and variables
        comm = MPI.COMM_WORLD
        rank = comm.Get_rank()

        if rank == 0:
            try:
                mask = self.file_reader.get_mask_at_next_time_index(
                    var_name).astype(DTYPE_INT)
            except Exception as e:
                logger = logging.getLogger(__name__)
                logger.error('Caught exception when getting mask at ' \
                             'next time index. Terminating all tasks ...')
                logger.error(traceback.format_exc())
                comm.Abort()
        else:
            mask = np.empty(var_dims, dtype=DTYPE_INT)

        comm.Bcast(mask, root=0)

        return mask
Exemplo n.º 16
0
class SerialMediator(Mediator):
    """ Serial mediator

    Serial mediator for serial runs.

    Parameters
    ----------
    config : ConfigParser
        Run configuration object

    start_datetime : Datetime
        Simulation start date/time.

    end_datetime : Datetime
        Simulation end date/time.

    Attributes
    ----------
    config : ConfigParser
        Run configuration object

    file_reader : pylag.FileReader
        FileReader object.

    """
    def __init__(self, config, datetime_start, datetime_end):
        self.config = config

        file_name_reader = DiskFileNameReader()

        dataset_reader = NetCDFDatasetReader()

        self.file_reader = FileReader(config, file_name_reader, dataset_reader,
                                      datetime_start, datetime_end)

    def setup_data_access(self, datetime_start, datetime_end):
        self.file_reader.setup_data_access(datetime_start, datetime_end)

    def update_reading_frames(self, time):
        return self.file_reader.update_reading_frames(time)

    def get_dimension_variable(self, var_name):
        return self.file_reader.get_dimension_variable(var_name)

    def get_grid_variable(self, var_name, var_dims, var_type):
        return self.file_reader.get_grid_variable(var_name).astype(var_type)

    def get_time_at_last_time_index(self):
        return self.file_reader.get_time_at_last_time_index()

    def get_time_at_next_time_index(self):
        return self.file_reader.get_time_at_next_time_index()

    def get_grid_variable_dimensions(self, var_name):
        return self.file_reader.get_grid_variable_dimensions(var_name)

    def get_variable_dimensions(self, var_name):
        return self.file_reader.get_variable_dimensions(var_name)

    def get_variable_shape(self, var_name):
        return self.file_reader.get_variable_shape(var_name)

    def get_time_dependent_variable_at_last_time_index(self, var_name,
                                                       var_dims, var_type):
        return self.file_reader.get_time_dependent_variable_at_last_time_index(
            var_name).astype(var_type)

    def get_time_dependent_variable_at_next_time_index(self, var_name,
                                                       var_dims, var_type):
        return self.file_reader.get_time_dependent_variable_at_next_time_index(
            var_name).astype(var_type)

    def get_mask_at_last_time_index(self, var_name, var_dims):
        return self.file_reader.get_mask_at_last_time_index(var_name).astype(
            DTYPE_INT)

    def get_mask_at_next_time_index(self, var_name, var_dims):
        return self.file_reader.get_mask_at_next_time_index(var_name).astype(
            DTYPE_INT)
Exemplo n.º 17
0
class FileReader_test(TestCase):
    def setUp(self):
        # Create config
        self.config = configparser.ConfigParser()
        self.config.add_section("OCEAN_CIRCULATION_MODEL")
        self.config.set('OCEAN_CIRCULATION_MODEL', 'name', 'TEST')
        self.config.set('OCEAN_CIRCULATION_MODEL', 'data_dir', '')
        self.config.set('OCEAN_CIRCULATION_MODEL', 'data_file_stem', '')
        self.config.set('OCEAN_CIRCULATION_MODEL', 'grid_metrics_file',
                        'grid_metrics')
        self.config.set('OCEAN_CIRCULATION_MODEL', 'rounding_interval',
                        rounding_interval)
        self.config.add_section("SIMULATION")

        # Mock file name reader
        self.file_name_reader = MockFileNameReader()

        # Mock dataset reader
        self.dataset_reader = MockDatasetReader()

    def tearDown(self):
        del (self.config)
        del (self.file_name_reader)
        del (self.dataset_reader)

    def test_use_start_datetime_equal_to_data_record_start(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

    def test_use_end_datetime_equal_to_data_record_start(self):
        # Should be valid during reverse tracking
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 second before data record end
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds after data record start

        self.config.set('SIMULATION', 'time_direction', 'reverse')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

    def test_use_start_datetime_equal_to_data_record_end(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 8, 0)  # Invalid - 0 seconds after data record end
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Invalid - 0 seconds after data record start

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.assertRaises(ValueError, FileReader, self.config,
                          self.file_name_reader, self.dataset_reader,
                          start_datetime, end_datetime)

    def test_use_end_datetime_equal_to_data_record_end(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 8, 0)  # Invalid - 0 seconds after data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.assertRaises(ValueError, FileReader, self.config,
                          self.file_name_reader, self.dataset_reader,
                          start_datetime, end_datetime)

    def test_use_start_datetime_before_data_record_start(self):
        start_datetime = datetime.datetime(
            1999, 1, 1, 0, 0, 0)  # Invalid - 1 year before data start date
        end_datetime = datetime.datetime(2000, 1, 1, 0, 8,
                                         0)  # Valid - 480 seconds

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.assertRaises(ValueError, FileReader, self.config,
                          self.file_name_reader, self.dataset_reader,
                          start_datetime, end_datetime)

    def test_use_start_datetime_after_data_record_end(self):
        start_datetime = datetime.datetime(
            2001, 1, 1, 8, 0)  # Invalid - 1 year after data end date
        end_datetime = datetime.datetime(2000, 1, 1, 0, 8,
                                         0)  # Valid - 480 seconds

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.assertRaises(ValueError, FileReader, self.config,
                          self.file_name_reader, self.dataset_reader,
                          start_datetime, end_datetime)

    def test_use_end_datetime_before_data_record_start(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds after data record start
        end_datetime = datetime.datetime(
            1999, 1, 1, 0, 0, 0)  # Invalid - 1 year before data start date

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.assertRaises(ValueError, FileReader, self.config,
                          self.file_name_reader, self.dataset_reader,
                          start_datetime, end_datetime)

    def test_use_end_datetime_after_data_record_start(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds after data record start
        end_datetime = datetime.datetime(
            2001, 1, 1, 0, 8, 0)  # Invalid - 1 year after data end date

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.assertRaises(ValueError, FileReader, self.config,
                          self.file_name_reader, self.dataset_reader,
                          start_datetime, end_datetime)

    def test_set_file_names_with_start_datetime_equal_to_data_record_start(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_1',
                                self.file_reader.second_data_file_name)

    def test_set_file_names_with_start_datetime_in_the_first_data_file(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 1, 0)  # Valid = 60 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_1',
                                self.file_reader.second_data_file_name)

    def test_set_file_names_with_start_datetime_equal_to_the_last_time_point_in_the_first_data_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 2, 0)  # Valid = 120 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_2',
                                self.file_reader.second_data_file_name)

    def test_set_file_names_with_start_datetime_inbetween_two_data_files(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 2,
            30)  # Valid = 150 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_2',
                                self.file_reader.second_data_file_name)

    def test_set_file_names_with_start_datetime_in_the_second_data_file(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 4, 0)  # Valid = 240 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check file names
        test.assert_array_equal('test_file_2',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_2',
                                self.file_reader.second_data_file_name)

    def test_set_file_names_with_time_points_repeated_between_adjacent_files(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 5, 0)  # Valid = 300 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check file names
        test.assert_array_equal('test_file_3',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_3',
                                self.file_reader.second_data_file_name)

    def test_set_time_arrays_with_start_datetime_equal_to_data_record_start(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time arrays
        test.assert_array_almost_equal([0., 60., 120.],
                                       self.file_reader.first_time)
        test.assert_array_almost_equal([0., 60., 120.],
                                       self.file_reader.second_time)

    def test_set_time_arrays_with_start_datetime_equal_to_the_last_time_point_in_the_first_data_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 2, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time arrays
        test.assert_array_almost_equal([-120., -60., 0.],
                                       self.file_reader.first_time)
        test.assert_array_almost_equal([60., 120., 180.],
                                       self.file_reader.second_time)

    def test_set_time_indices_with_start_datetime_equal_to_data_record_start(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time indices
        test.assert_equal(0, self.file_reader.tidx_first)
        test.assert_equal(1, self.file_reader.tidx_second)

    def test_set_time_indices_with_start_datetime_equal_to_the_last_time_point_in_the_first_data_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 2, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time indices
        test.assert_equal(2, self.file_reader.tidx_first)
        test.assert_equal(0, self.file_reader.tidx_second)

    def test_set_time_indices_with_time_points_repeated_between_adjacent_files(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 5, 0)  # Valid = 300 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time indices
        test.assert_equal(0, self.file_reader.tidx_first)
        test.assert_equal(1, self.file_reader.tidx_second)

    def test_set_file_names_when_updating_reading_frames_in_the_first_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=60)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_1',
                                self.file_reader.second_data_file_name)

    def test_set_time_indices_when_updating_reading_frames_in_the_first_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=60)

        # Check time indices
        test.assert_equal(1, self.file_reader.tidx_first)
        test.assert_equal(2, self.file_reader.tidx_second)

    def test_set_file_names_when_updating_reading_frames_at_the_end_of_the_first_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=120.)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_2',
                                self.file_reader.second_data_file_name)

    def test_set_time_indices_when_updating_reading_frames_at_the_end_of_the_first_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=120.)

        # Check time indices
        test.assert_equal(2, self.file_reader.tidx_first)
        test.assert_equal(0, self.file_reader.tidx_second)

    def test_set_file_names_when_updating_reading_frames_after_the_end_of_the_first_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=150.)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_2',
                                self.file_reader.second_data_file_name)

    def test_set_time_indices_when_updating_reading_frames_after_the_end_of_the_first_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=150.)

        # Check time indices
        test.assert_equal(2, self.file_reader.tidx_first)
        test.assert_equal(0, self.file_reader.tidx_second)

    def test_set_file_names_when_updating_reading_frames_at_the_start_of_the_second_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=180.)

        # Check file names
        test.assert_array_equal('test_file_2',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_2',
                                self.file_reader.second_data_file_name)

    def test_set_time_indices_when_updating_reading_frames_at_the_start_of_the_second_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid = 0 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 7, 59)  # Valid - 1 seconds before data record end

        self.config.set('SIMULATION', 'time_direction', 'forward')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=180.)

        # Check time indices
        test.assert_equal(0, self.file_reader.tidx_first)
        test.assert_equal(1, self.file_reader.tidx_second)

    def test_set_file_names_when_reverse_tracking(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 3, 0)  # Valid = 180 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds before data record start

        self.config.set('SIMULATION', 'time_direction', 'reverse')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_2',
                                self.file_reader.second_data_file_name)

    def test_set_file_names_when_updating_reading_frames_during_reverse_tracking_between_data_files(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 3, 0)  # Valid = 180 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds before data record start

        self.config.set('SIMULATION', 'time_direction', 'reverse')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=-60.)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_1',
                                self.file_reader.second_data_file_name)

    def test_set_time_indices_when_reverse_tracking(self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 3, 0)  # Valid = 180 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds before data record start

        self.config.set('SIMULATION', 'time_direction', 'reverse')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Check time indices
        test.assert_equal(2, self.file_reader.tidx_first)
        test.assert_equal(0, self.file_reader.tidx_second)

    def test_set_time_indices_when_updating_reading_frames_during_reverse_tracking_between_data_files(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 3, 0)  # Valid = 180 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds before data record start

        self.config.set('SIMULATION', 'time_direction', 'reverse')

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=-60.)

        # Check time indices
        test.assert_equal(1, self.file_reader.tidx_first)
        test.assert_equal(2, self.file_reader.tidx_second)

    def test_set_file_names_when_updating_reading_frames_during_reverse_tracking_into_first_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 3, 0)  # Valid = 180 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds before data record start

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=-90.)

        # Check file names
        test.assert_array_equal('test_file_1',
                                self.file_reader.first_data_file_name)
        test.assert_array_equal('test_file_1',
                                self.file_reader.second_data_file_name)

    def test_set_time_indices_when_updating_reading_frames_during_reverse_tracking_into_first_file(
            self):
        start_datetime = datetime.datetime(
            2000, 1, 1, 0, 3, 0)  # Valid = 180 seconds after data record start
        end_datetime = datetime.datetime(
            2000, 1, 1, 0, 0, 0)  # Valid - 0 seconds before data record start

        # Create file reader
        self.file_reader = FileReader(self.config, self.file_name_reader,
                                      self.dataset_reader, start_datetime,
                                      end_datetime)

        # Update reading frames
        self.file_reader.update_reading_frames(time=-90.)

        # Check time indices
        test.assert_equal(1, self.file_reader.tidx_first)
        test.assert_equal(2, self.file_reader.tidx_second)