Resetting time to zero after cloning a climlab process

Brian Rose, 2/2/2026

Here are some notes on how to reset a model’s internal clock to zero after cloning a process with climlab.process_like()

Note: date and time handling in climlab changed substantially as of climlab v0.10. This notebook has been updated to reflect the new functionality.

[1]:
import numpy as np
import climlab

The climlab time dictionary

Every process object contains a time attribute, which is just a dictionary with various counters and information about timesteps.

Here we create a single-column radiation model m1 with a timestep of 1 day, and inspect its time dictionary:

[2]:
mystate = climlab.column_state()
m1 = climlab.radiation.RRTMG(state=mystate,
                             timestep=climlab.utils.constants.seconds_per_day)
m1.time
[2]:
{'initial_time': np.datetime64('1970-01-01T00:00'),
 'current_time': np.datetime64('1970-01-01T00:00'),
 'steps': 0,
 'active_now': True,
 'timestep': np.timedelta64(86400,'s')}

If we take a single time step forward, some elements in this dictionary get updated:

[3]:
m1.step_forward()
m1.time
[3]:
{'initial_time': np.datetime64('1970-01-01T00:00'),
 'current_time': np.datetime64('1970-01-02T00:00:00'),
 'steps': 1,
 'active_now': True,
 'timestep': np.timedelta64(86400,'s')}

In particular, steps has increased by 1, and current_time is now January 2 (using a timestep of 1 day).

Let’s now clone this model. Both the state and the calendar are cloned, so our new model has the same date as m1:

[4]:
m2 = climlab.process_like(m1)
m2.time
[4]:
{'initial_time': np.datetime64('1970-01-01T00:00'),
 'current_time': np.datetime64('1970-01-02T00:00:00'),
 'steps': 1,
 'active_now': True,
 'timestep': np.timedelta64(86400,'s')}

What if we want to clone the state, but reset the calendar back to the initial date?

First, we just make a clone and verify that they are identical:

[5]:
mystate2 = climlab.column_state()
m3 = climlab.radiation.RRTMG(state=mystate2,
                             timestep=climlab.utils.constants.seconds_per_day)
m3.step_forward()
m4 = climlab.process_like(m3)
# Now both m3 and m4 have the same state:
assert m3.Ts == m4.Ts
assert np.all(m3.Tatm == m4.Tatm)
# And they also have the same date and time:
assert m3.current_time == m4.current_time

Now let’s reset the current time of our clone. We can do this simply by setting the current_time property of the model object:

[6]:
m4.current_time = m3.time['initial_time']

Verify what the .time dictionary looks like now:

[7]:
m4.time
[7]:
{'initial_time': np.datetime64('1970-01-01T00:00'),
 'current_time': np.datetime64('1970-01-01T00:00'),
 'steps': 1,
 'active_now': True,
 'timestep': np.timedelta64(86400,'s')}

Note that we didn’t reset the counter 'steps' to zero, but we can also do this if we wish:

[8]:
m4.time['steps'] = 0

Since we haven’t changed any model parameters, they should both evolve exactly the same way on their next timestep so the states remain the same:

[9]:
for model in [m3, m4]:
    model.step_forward()
assert m3.Ts == m4.Ts
assert np.all(m3.Tatm == m4.Tatm)

although now the times are not the same:

[10]:
assert m3.current_time == m4.current_time
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[10], line 1
----> 1 assert m3.current_time == m4.current_time

AssertionError:

The assertion fails, as expected, because the two models have different dates.

But if I now change a parameter in m4, their states will begin to differ:

[11]:
m4.subprocess['SW'].S0 += 10.
for model in [m3, m4]:
    model.step_forward()
print('One step after changing S0 in m4, m3 has taken {} steps, and m4 has taken {} steps.'.format(m3.time['steps'], m4.time['steps']))
print('')
print('Now checking to see if the states are still the same:')
assert m3.Ts == m4.Ts
One step after changing S0 in m4, m3 has taken 3 steps, and m4 has taken 2 steps.

Now checking to see if the states are still the same:
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[11], line 7
      5 print('')
      6 print('Now checking to see if the states are still the same:')
----> 7 assert m3.Ts == m4.Ts

AssertionError:

The assertion fails because the surface temperatures of the two states have diverged, as expected.

Date-sensitive models

In the above examples, the states advance identically on each timestep even though the dates are different. This is because there is no process in this model that is using the date as input.

If we invoke a model with a seasonally-varying insolation process, changing the date will change how the state variables change.

[12]:
ebm1 = climlab.EBM_seasonal()
ebm1.step_forward()
ebm2 = climlab.process_like(ebm1)
ebm2.current_time = ebm1.time['initial_time']

assert np.all(ebm1.Ts == ebm2.Ts)

All good so far!

But if we take a step forward, the states will start to diverge because they have slightly different insolation values:

[13]:
for model in [ebm1, ebm2]:
    model.step_forward()

assert np.all(ebm1.Ts == ebm2.Ts)
---------------------------------------------------------------------------
AssertionError                            Traceback (most recent call last)
Cell In[13], line 4
      1 for model in [ebm1, ebm2]:
      2     model.step_forward()
----> 4 assert np.all(ebm1.Ts == ebm2.Ts)

AssertionError:
[ ]: