Exemplo n.º 1
0
    def setUp(self):
        data = open(
            os.path.normpath(
                os.path.join(
                    os.path.dirname(__file__),
                    "./resources/files/lifestage_single.json"))).read()
        self.lifestage = LifeStage(json=data)

        start_lat = 38
        start_lon = -76
        start_depth = -5
        temp_time = datetime.utcnow()
        self.start_time = datetime(temp_time.year, temp_time.month,
                                   temp_time.day,
                                   temp_time.hour).replace(tzinfo=pytz.utc)
        self.loc = Location4D(latitude=start_lat,
                              longitude=start_lon,
                              depth=start_depth,
                              time=self.start_time)

        self.particles = []
        # Create particles
        for i in range(0, 3):
            p = LarvaParticle()
            p.location = self.loc
            self.particles.append(p)

        # 48 timesteps at an hour each = 2 days of running
        self.times = list(range(0, 172800, 3600))  # in seconds
        self.temps = []
        self.salts = []
        for w in range(0, 48):
            self.temps.append(random.randint(20, 40))
            self.salts.append(random.randint(10, 30))
Exemplo n.º 2
0
    def test_no_diel(self):
        data = json.loads(
            open(
                os.path.normpath(
                    os.path.join(
                        os.path.dirname(__file__),
                        "./resources/files/lifestage_single.json"))).read())
        data['diel'] = []
        self.lifestage = LifeStage(data=data)

        for p in self.particles:
            for i in range(0, len(self.times)):
                try:
                    modelTimestep = self.times[i + 1] - self.times[i]
                    calculatedTime = self.times[i + 1]
                except Exception:
                    modelTimestep = self.times[i] - self.times[i - 1]
                    calculatedTime = self.times[i] + modelTimestep

                newtime = self.start_time + timedelta(seconds=calculatedTime)

                p.age(seconds=modelTimestep)
                movement = self.lifestage.move(p,
                                               0,
                                               0,
                                               0,
                                               modelTimestep,
                                               temperature=self.temps[i],
                                               salinity=self.salts[i])
                newloc = Location4D(latitude=movement['latitude'],
                                    longitude=movement['longitude'],
                                    depth=movement['depth'],
                                    time=newtime)
                p.location = newloc

        for p in self.particles:
            # Particle should move every timestep
            assert len(p.locations) == len(self.times) + 1
            # A particle should always move in this test
            assert len(set(p.locations)) == len(self.times) + 1
            # A particle should always age
            assert p.get_age(
                units='days') == (self.times[-1] + 3600) / 60. / 60. / 24.
            # First point of each particle should be the starting location
            assert p.linestring().coords[0][0] == self.loc.longitude
            assert p.linestring().coords[0][1] == self.loc.latitude
            assert p.linestring().coords[0][2] == self.loc.depth

            # Lifestages currently influence the Z direction, so a particle should not
            # move horizontally.
            assert p.linestring().coords[-1][0] == self.loc.longitude
            assert p.linestring().coords[-1][1] == self.loc.latitude
    def test_diel_cycles(self):
        data = open(os.path.normpath(os.path.join(os.path.dirname(__file__), "./resources/files/cycles.json"))).read()
        lifestage = LifeStage(json=data)

        eastern = pytz.timezone("US/Eastern")

        loc4d = self.loc

        # RISING:2013-05-13 05:55:35 -04:00
        # SETTING: 2013-05-14 20:05:33 -04:00

        # 1 hour before sunrise, the first migration
        loc4d.time = eastern.localize(datetime(2013, 5, 13,  5, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        # still working off of the 1 hour before runrise, because we haven't hit 1 hour after
        loc4d.time = eastern.localize(datetime(2013, 5, 13,  6, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        loc4d.time = eastern.localize(datetime(2013, 5, 13,  8, 30))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[1]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 19, 10))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 20,  0))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 21,  6))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]

        loc4d.time = eastern.localize(datetime(2013, 5, 14, 02, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]
Exemplo n.º 4
0
    def test_diel_cycles(self):
        data = open(os.path.normpath(os.path.join(os.path.dirname(__file__),"./resources/files/cycles.json"))).read()
        lifestage = LifeStage(json=data)
        
        eastern = pytz.timezone("US/Eastern")
        
        loc4d = self.loc

        # RISING:2013-05-13 05:55:35 -04:00
        # SETTING: 2013-05-14 20:05:33 -04:00

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=5, minute=45)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=6, minute=45)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=8, minute=30)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[1]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=19, minute=10)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=20, minute=00)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=21, minute=06)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=2, minute=45) + timedelta(hours=24)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]
Exemplo n.º 5
0
    def test_from_dict(self):
        data = open(
            os.path.normpath(
                os.path.join(
                    os.path.dirname(__file__),
                    "./resources/files/lifestage_single.json"))).read()
        l = LifeStage(data=json.loads(data))

        assert l.name == 'third'
        assert l.duration == 3
        assert l.linear_a == 0.03
        assert l.linear_b == 0.2
        assert len(l.taxis) == 2
        assert l.taxis[1].min_value == -30.0
        assert l.taxis[1].max_value == -50.0
        assert len(l.diel) == 2
        assert l.diel[1].min_depth == -2.0
        assert l.diel[1].max_depth == -5.0
        assert l.capability.vss == 5.0
        assert l.capability.variance == 2.0
        assert l.capability.non_swim_turning == 'random'
        assert l.capability.swim_turning == 'random'

        t = datetime.utcnow().replace(tzinfo=pytz.utc)
        loc = Location4D(time=t, latitude=35, longitude=-76)
        assert isinstance(l.diel[0].get_time(loc4d=loc), datetime)
    def setUp(self):
        data = open(os.path.normpath(os.path.join(os.path.dirname(__file__), "./resources/files/lifestage_single.json"))).read()
        self.lifestage = LifeStage(json=data)

        start_lat = 38
        start_lon = -76
        start_depth = -5
        temp_time = datetime.utcnow()
        self.start_time = datetime(temp_time.year, temp_time.month, temp_time.day, temp_time.hour).replace(tzinfo=pytz.utc)
        self.loc = Location4D(latitude=start_lat, longitude=start_lon, depth=start_depth, time=self.start_time)

        self.particles = []
        # Create particles
        for i in xrange(0, 3):
            p = LarvaParticle()
            p.location = self.loc
            self.particles.append(p)

        # 48 timesteps at an hour each = 2 days of running
        self.times = range(0, 172800, 3600)  # in seconds
        self.temps = []
        self.salts = []
        for w in xrange(0, 48):
            self.temps.append(random.randint(20, 40))
            self.salts.append(random.randint(10, 30))
Exemplo n.º 7
0
    def test_diel_cycles(self):
        data = open(
            os.path.normpath(
                os.path.join(os.path.dirname(__file__),
                             "./resources/files/cycles.json"))).read()
        lifestage = LifeStage(json=data)

        eastern = pytz.timezone("US/Eastern")

        loc4d = self.loc

        # RISING:2013-05-13 05:55:35 -04:00
        # SETTING: 2013-05-14 20:05:33 -04:00

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=5,
                                                                 minute=45)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=6,
                                                                 minute=45)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=8,
                                                                 minute=30)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[1]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=19,
                                                                 minute=10)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=20,
                                                                 minute=00)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = self.start_time.astimezone(eastern).replace(hour=21,
                                                                 minute=06)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]

        loc4d.time = self.start_time.astimezone(eastern).replace(
            hour=2, minute=45) + timedelta(hours=24)
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]
Exemplo n.º 8
0
    def test_diel_cycles(self):
        data = open(
            os.path.normpath(
                os.path.join(os.path.dirname(__file__),
                             "./resources/files/cycles.json"))).read()
        lifestage = LifeStage(json=data)

        eastern = pytz.timezone("US/Eastern")

        loc4d = self.loc

        # RISING:2013-05-13 05:55:35 -04:00
        # SETTING: 2013-05-14 20:05:33 -04:00

        # 1 hour before sunrise, the first migration
        loc4d.time = eastern.localize(datetime(2013, 5, 13, 5, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        # still working off of the 1 hour before runrise, because we haven't hit 1 hour after
        loc4d.time = eastern.localize(datetime(2013, 5, 13, 6, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 8, 30))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[1]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 19, 10))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 20, 0))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 21, 6))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]

        loc4d.time = eastern.localize(datetime(2013, 5, 14, 2, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]
Exemplo n.º 9
0
    def __init__(self, **kwargs):

        if 'json' in kwargs or 'data' in kwargs:
            data = {}
            try:
                data = json.loads(kwargs['json'])
            except StandardError:
                try:
                    data = kwargs.get('data')
                except StandardError:
                    pass

        self.lifestages = []
        if data.get('lifestages', None) is not None:
            self.lifestages = [LifeStage(data=ls) for ls in data.get('lifestages')]

        # What do to if the model continues but all LifeStages have passed??
        # Be dead.
        self.lifestages.append(DeadLifeStage())
    def test_no_diel(self):
        data = json.loads(open(os.path.normpath(os.path.join(os.path.dirname(__file__), "./resources/files/lifestage_single.json"))).read())
        data['diel'] = []
        self.lifestage = LifeStage(data=data)

        for p in self.particles:
            for i in xrange(0, len(self.times)):
                try:
                    modelTimestep = self.times[i+1] - self.times[i]
                    calculatedTime = self.times[i+1]
                except StandardError:
                    modelTimestep = self.times[i] - self.times[i-1]
                    calculatedTime = self.times[i] + modelTimestep

                newtime = self.start_time + timedelta(seconds=calculatedTime)

                p.age(seconds=modelTimestep)
                movement = self.lifestage.move(p, 0, 0, 0, modelTimestep, temperature=self.temps[i], salinity=self.salts[i])
                newloc = Location4D(latitude=movement['latitude'], longitude=movement['longitude'], depth=movement['depth'], time=newtime)
                p.location = newloc

        for p in self.particles:
            # Particle should move every timestep
            assert len(p.locations) == len(self.times) + 1
            # A particle should always move in this test
            assert len(set(p.locations)) == len(self.times) + 1
            # A particle should always age
            assert p.get_age(units='days') == (self.times[-1] + 3600) / 60. / 60. / 24.
            # First point of each particle should be the starting location
            assert p.linestring().coords[0][0] == self.loc.longitude
            assert p.linestring().coords[0][1] == self.loc.latitude
            assert p.linestring().coords[0][2] == self.loc.depth

            # Lifestages currently influence the Z direction, so a particle should not
            # move horizontally.
            assert p.linestring().coords[-1][0] == self.loc.longitude
            assert p.linestring().coords[-1][1] == self.loc.latitude
Exemplo n.º 11
0
class LifeStageTest(unittest.TestCase):
    def setUp(self):
        data = open(
            os.path.normpath(
                os.path.join(
                    os.path.dirname(__file__),
                    "./resources/files/lifestage_single.json"))).read()
        self.lifestage = LifeStage(json=data)

        start_lat = 38
        start_lon = -76
        start_depth = -5
        temp_time = datetime.utcnow()
        self.start_time = datetime(temp_time.year, temp_time.month,
                                   temp_time.day,
                                   temp_time.hour).replace(tzinfo=pytz.utc)
        self.loc = Location4D(latitude=start_lat,
                              longitude=start_lon,
                              depth=start_depth,
                              time=self.start_time)

        self.particles = []
        # Create particles
        for i in range(0, 3):
            p = LarvaParticle()
            p.location = self.loc
            self.particles.append(p)

        # 48 timesteps at an hour each = 2 days of running
        self.times = list(range(0, 172800, 3600))  # in seconds
        self.temps = []
        self.salts = []
        for w in range(0, 48):
            self.temps.append(random.randint(20, 40))
            self.salts.append(random.randint(10, 30))

    def test_diel_cycles(self):
        data = open(
            os.path.normpath(
                os.path.join(os.path.dirname(__file__),
                             "./resources/files/cycles.json"))).read()
        lifestage = LifeStage(json=data)

        eastern = pytz.timezone("US/Eastern")

        loc4d = self.loc

        # RISING:2013-05-13 05:55:35 -04:00
        # SETTING: 2013-05-14 20:05:33 -04:00

        # 1 hour before sunrise, the first migration
        loc4d.time = eastern.localize(datetime(2013, 5, 13, 5, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        # still working off of the 1 hour before runrise, because we haven't hit 1 hour after
        loc4d.time = eastern.localize(datetime(2013, 5, 13, 6, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 8, 30))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[1]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 19, 10))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 20, 0))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 21, 6))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]

        loc4d.time = eastern.localize(datetime(2013, 5, 14, 2, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]

    def test_no_diel(self):
        data = json.loads(
            open(
                os.path.normpath(
                    os.path.join(
                        os.path.dirname(__file__),
                        "./resources/files/lifestage_single.json"))).read())
        data['diel'] = []
        self.lifestage = LifeStage(data=data)

        for p in self.particles:
            for i in range(0, len(self.times)):
                try:
                    modelTimestep = self.times[i + 1] - self.times[i]
                    calculatedTime = self.times[i + 1]
                except Exception:
                    modelTimestep = self.times[i] - self.times[i - 1]
                    calculatedTime = self.times[i] + modelTimestep

                newtime = self.start_time + timedelta(seconds=calculatedTime)

                p.age(seconds=modelTimestep)
                movement = self.lifestage.move(p,
                                               0,
                                               0,
                                               0,
                                               modelTimestep,
                                               temperature=self.temps[i],
                                               salinity=self.salts[i])
                newloc = Location4D(latitude=movement['latitude'],
                                    longitude=movement['longitude'],
                                    depth=movement['depth'],
                                    time=newtime)
                p.location = newloc

        for p in self.particles:
            # Particle should move every timestep
            assert len(p.locations) == len(self.times) + 1
            # A particle should always move in this test
            assert len(set(p.locations)) == len(self.times) + 1
            # A particle should always age
            assert p.get_age(
                units='days') == (self.times[-1] + 3600) / 60. / 60. / 24.
            # First point of each particle should be the starting location
            assert p.linestring().coords[0][0] == self.loc.longitude
            assert p.linestring().coords[0][1] == self.loc.latitude
            assert p.linestring().coords[0][2] == self.loc.depth

            # Lifestages currently influence the Z direction, so a particle should not
            # move horizontally.
            assert p.linestring().coords[-1][0] == self.loc.longitude
            assert p.linestring().coords[-1][1] == self.loc.latitude

    def test_moving_particle_with_lifestage(self):

        for p in self.particles:
            for i in range(0, len(self.times)):
                try:
                    modelTimestep = self.times[i + 1] - self.times[i]
                    calculatedTime = self.times[i + 1]
                except Exception:
                    modelTimestep = self.times[i] - self.times[i - 1]
                    calculatedTime = self.times[i] + modelTimestep

                newtime = self.start_time + timedelta(seconds=calculatedTime)

                p.age(seconds=modelTimestep)
                movement = self.lifestage.move(p,
                                               0,
                                               0,
                                               0,
                                               modelTimestep,
                                               temperature=self.temps[i],
                                               salinity=self.salts[i])
                newloc = Location4D(latitude=movement['latitude'],
                                    longitude=movement['longitude'],
                                    depth=movement['depth'],
                                    time=newtime)
                p.location = newloc

        for p in self.particles:
            # Particle should move every timestep
            assert len(p.locations) == len(self.times) + 1
            # A particle should always move in this test
            assert len(set(p.locations)) == len(self.times) + 1
            # A particle should always age
            assert p.get_age(
                units='days') == (self.times[-1] + 3600) / 60. / 60. / 24.
            # First point of each particle should be the starting location
            assert p.linestring().coords[0][0] == self.loc.longitude
            assert p.linestring().coords[0][1] == self.loc.latitude
            assert p.linestring().coords[0][2] == self.loc.depth

            # Lifestages currently influence the Z direction, so a particle should not
            # move horizontally.
            assert p.linestring().coords[-1][0] == self.loc.longitude
            assert p.linestring().coords[-1][1] == self.loc.latitude

    def test_from_json(self):

        assert self.lifestage.name == 'third'
        assert self.lifestage.duration == 3
        assert self.lifestage.linear_a == 0.03
        assert self.lifestage.linear_b == 0.2
        assert len(self.lifestage.taxis) == 2
        assert self.lifestage.taxis[0].min_value == -30.0
        assert self.lifestage.taxis[0].max_value == -40.0
        assert len(self.lifestage.diel) == 2
        assert self.lifestage.diel[0].min_depth == -2.0
        assert self.lifestage.diel[0].max_depth == -4.0
        assert self.lifestage.capability.vss == 5.0
        assert self.lifestage.capability.variance == 2.0
        assert self.lifestage.capability.non_swim_turning == 'random'
        assert self.lifestage.capability.swim_turning == 'random'

        t = datetime.utcnow().replace(tzinfo=pytz.utc)
        loc = Location4D(time=t, latitude=35, longitude=-76)
        assert isinstance(self.lifestage.diel[0].get_time(loc4d=loc), datetime)

    def test_from_dict(self):
        data = open(
            os.path.normpath(
                os.path.join(
                    os.path.dirname(__file__),
                    "./resources/files/lifestage_single.json"))).read()
        l = LifeStage(data=json.loads(data))

        assert l.name == 'third'
        assert l.duration == 3
        assert l.linear_a == 0.03
        assert l.linear_b == 0.2
        assert len(l.taxis) == 2
        assert l.taxis[1].min_value == -30.0
        assert l.taxis[1].max_value == -50.0
        assert len(l.diel) == 2
        assert l.diel[1].min_depth == -2.0
        assert l.diel[1].max_depth == -5.0
        assert l.capability.vss == 5.0
        assert l.capability.variance == 2.0
        assert l.capability.non_swim_turning == 'random'
        assert l.capability.swim_turning == 'random'

        t = datetime.utcnow().replace(tzinfo=pytz.utc)
        loc = Location4D(time=t, latitude=35, longitude=-76)
        assert isinstance(l.diel[0].get_time(loc4d=loc), datetime)
class LifeStageTest(unittest.TestCase):

    def setUp(self):
        data = open(os.path.normpath(os.path.join(os.path.dirname(__file__), "./resources/files/lifestage_single.json"))).read()
        self.lifestage = LifeStage(json=data)

        start_lat = 38
        start_lon = -76
        start_depth = -5
        temp_time = datetime.utcnow()
        self.start_time = datetime(temp_time.year, temp_time.month, temp_time.day, temp_time.hour).replace(tzinfo=pytz.utc)
        self.loc = Location4D(latitude=start_lat, longitude=start_lon, depth=start_depth, time=self.start_time)

        self.particles = []
        # Create particles
        for i in xrange(0, 3):
            p = LarvaParticle()
            p.location = self.loc
            self.particles.append(p)

        # 48 timesteps at an hour each = 2 days of running
        self.times = range(0, 172800, 3600)  # in seconds
        self.temps = []
        self.salts = []
        for w in xrange(0, 48):
            self.temps.append(random.randint(20, 40))
            self.salts.append(random.randint(10, 30))

    def test_diel_cycles(self):
        data = open(os.path.normpath(os.path.join(os.path.dirname(__file__), "./resources/files/cycles.json"))).read()
        lifestage = LifeStage(json=data)

        eastern = pytz.timezone("US/Eastern")

        loc4d = self.loc

        # RISING:2013-05-13 05:55:35 -04:00
        # SETTING: 2013-05-14 20:05:33 -04:00

        # 1 hour before sunrise, the first migration
        loc4d.time = eastern.localize(datetime(2013, 5, 13,  5, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        # still working off of the 1 hour before runrise, because we haven't hit 1 hour after
        loc4d.time = eastern.localize(datetime(2013, 5, 13,  6, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[0]

        loc4d.time = eastern.localize(datetime(2013, 5, 13,  8, 30))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[1]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 19, 10))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 20,  0))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[2]

        loc4d.time = eastern.localize(datetime(2013, 5, 13, 21,  6))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]

        loc4d.time = eastern.localize(datetime(2013, 5, 14, 02, 45))
        assert lifestage.get_active_diel(loc4d) == lifestage.diel[3]

    def test_no_diel(self):
        data = json.loads(open(os.path.normpath(os.path.join(os.path.dirname(__file__), "./resources/files/lifestage_single.json"))).read())
        data['diel'] = []
        self.lifestage = LifeStage(data=data)

        for p in self.particles:
            for i in xrange(0, len(self.times)):
                try:
                    modelTimestep = self.times[i+1] - self.times[i]
                    calculatedTime = self.times[i+1]
                except StandardError:
                    modelTimestep = self.times[i] - self.times[i-1]
                    calculatedTime = self.times[i] + modelTimestep

                newtime = self.start_time + timedelta(seconds=calculatedTime)

                p.age(seconds=modelTimestep)
                movement = self.lifestage.move(p, 0, 0, 0, modelTimestep, temperature=self.temps[i], salinity=self.salts[i])
                newloc = Location4D(latitude=movement['latitude'], longitude=movement['longitude'], depth=movement['depth'], time=newtime)
                p.location = newloc

        for p in self.particles:
            # Particle should move every timestep
            assert len(p.locations) == len(self.times) + 1
            # A particle should always move in this test
            assert len(set(p.locations)) == len(self.times) + 1
            # A particle should always age
            assert p.get_age(units='days') == (self.times[-1] + 3600) / 60. / 60. / 24.
            # First point of each particle should be the starting location
            assert p.linestring().coords[0][0] == self.loc.longitude
            assert p.linestring().coords[0][1] == self.loc.latitude
            assert p.linestring().coords[0][2] == self.loc.depth

            # Lifestages currently influence the Z direction, so a particle should not
            # move horizontally.
            assert p.linestring().coords[-1][0] == self.loc.longitude
            assert p.linestring().coords[-1][1] == self.loc.latitude

    def test_moving_particle_with_lifestage(self):

        for p in self.particles:
            for i in xrange(0, len(self.times)):
                try:
                    modelTimestep = self.times[i+1] - self.times[i]
                    calculatedTime = self.times[i+1]
                except StandardError:
                    modelTimestep = self.times[i] - self.times[i-1]
                    calculatedTime = self.times[i] + modelTimestep

                newtime = self.start_time + timedelta(seconds=calculatedTime)

                p.age(seconds=modelTimestep)
                movement = self.lifestage.move(p, 0, 0, 0, modelTimestep, temperature=self.temps[i], salinity=self.salts[i])
                newloc = Location4D(latitude=movement['latitude'], longitude=movement['longitude'], depth=movement['depth'], time=newtime)
                p.location = newloc

        for p in self.particles:
            # Particle should move every timestep
            assert len(p.locations) == len(self.times) + 1
            # A particle should always move in this test
            assert len(set(p.locations)) == len(self.times) + 1
            # A particle should always age
            assert p.get_age(units='days') == (self.times[-1] + 3600) / 60. / 60. / 24.
            # First point of each particle should be the starting location
            assert p.linestring().coords[0][0] == self.loc.longitude
            assert p.linestring().coords[0][1] == self.loc.latitude
            assert p.linestring().coords[0][2] == self.loc.depth

            # Lifestages currently influence the Z direction, so a particle should not
            # move horizontally.
            assert p.linestring().coords[-1][0] == self.loc.longitude
            assert p.linestring().coords[-1][1] == self.loc.latitude

    def test_from_json(self):

        assert self.lifestage.name == 'third'
        assert self.lifestage.duration == 3
        assert self.lifestage.linear_a == 0.03
        assert self.lifestage.linear_b == 0.2
        assert len(self.lifestage.taxis) == 2
        assert self.lifestage.taxis[0].min_value == -30.0
        assert self.lifestage.taxis[0].max_value == -40.0
        assert len(self.lifestage.diel) == 2
        assert self.lifestage.diel[0].min_depth == -2.0
        assert self.lifestage.diel[0].max_depth == -4.0
        assert self.lifestage.capability.vss == 5.0
        assert self.lifestage.capability.variance == 2.0
        assert self.lifestage.capability.non_swim_turning == 'random'
        assert self.lifestage.capability.swim_turning == 'random'

        t = datetime.utcnow().replace(tzinfo=pytz.utc)
        loc = Location4D(time=t, latitude=35, longitude=-76)
        assert isinstance(self.lifestage.diel[0].get_time(loc4d=loc), datetime)

    def test_from_dict(self):
        data = open(os.path.normpath(os.path.join(os.path.dirname(__file__), "./resources/files/lifestage_single.json"))).read()
        l = LifeStage(data=json.loads(data))

        assert l.name == 'third'
        assert l.duration == 3
        assert l.linear_a == 0.03
        assert l.linear_b == 0.2
        assert len(l.taxis) == 2
        assert l.taxis[1].min_value == -30.0
        assert l.taxis[1].max_value == -50.0
        assert len(l.diel) == 2
        assert l.diel[1].min_depth == -2.0
        assert l.diel[1].max_depth == -5.0
        assert l.capability.vss == 5.0
        assert l.capability.variance == 2.0
        assert l.capability.non_swim_turning == 'random'
        assert l.capability.swim_turning == 'random'

        t = datetime.utcnow().replace(tzinfo=pytz.utc)
        loc = Location4D(time=t, latitude=35, longitude=-76)
        assert isinstance(l.diel[0].get_time(loc4d=loc), datetime)