Skip to content

Commit 83e10e5

Browse files
authored
Merge pull request #73 from philipstarkey/feature/performance-improvements
Performance improvements
2 parents 9fbd24c + ea17d77 commit 83e10e5

File tree

1 file changed

+25
-33
lines changed

1 file changed

+25
-33
lines changed

labscript/labscript.py

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -824,8 +824,9 @@ def collect_change_times(self, all_outputs, outputs_by_clockline):
824824
raise LabscriptError('Commands have been issued to devices attached to clockline %s at t= %s s and %s s. '%(clock_line.name, str(t),str(change_time_list[i+1])) +
825825
'One or more connected devices on ClockLine %s cannot support update delays shorter than %s sec.'%(clock_line.name, str(1.0/clock_line.clock_limit)))
826826

827+
all_change_times_len = len(all_change_times)
827828
# increment j until we reach the current time
828-
while all_change_times[j] < t and j < len(all_change_times)-1:
829+
while all_change_times[j] < t and j < all_change_times_len-1:
829830
j += 1
830831
# j should now index all_change_times at "t"
831832
# Check that the next all change_time is not too close (and thus would force this clock tick to be faster than the clock_limit)
@@ -1067,21 +1068,18 @@ def generate_clock(self):
10671068
# also generate everytime point each clock line will tick (expand ramps)
10681069
all_times, self.clock = self.expand_change_times(all_change_times, change_times, outputs_by_clockline)
10691070

1071+
# Flatten the clock line times for use by the child devices for writing instruction tables
1072+
self.times = {}
1073+
for clock_line, time_array in all_times.items():
1074+
self.times[clock_line] = fastflatten(time_array,np.dtype(float))
1075+
10701076
# for each clockline
10711077
for clock_line, outputs in outputs_by_clockline.items():
1078+
clock_line_len = len(self.times[clock_line])
10721079
# and for each output
10731080
for output in outputs:
10741081
# evaluate the output at each time point the clock line will tick at
1075-
output.expand_timeseries(all_times[clock_line])
1076-
1077-
# TODO: is this needed? Let's say no...
1078-
# self.all_change_times = fastflatten(all_change_times, float)
1079-
1080-
# Flatten the clock line times for use by the child devices for writing instruction tables
1081-
# TODO: (if this needed or was it just for runviewer meta data that we don't need anymore?)
1082-
self.times = {}
1083-
for clock_line, time_array in all_times.items():
1084-
self.times[clock_line] = fastflatten(time_array,float)
1082+
output.expand_timeseries(all_times[clock_line], clock_line_len)
10851083

10861084
def generate_code(self, hdf5_file):
10871085
self.generate_clock()
@@ -1649,22 +1647,13 @@ def make_timeseries(self, change_times):
16491647
is stored in self.timeseries rather than being returned."""
16501648
self.timeseries = []
16511649
i = 0
1650+
time_len = len(self.times)
16521651
for change_time in change_times:
1653-
try:
1654-
if i < len(self.times):
1655-
while change_time >= self.times[i]:
1656-
i += 1
1657-
except IndexError:
1658-
# We allow the index to go one higher, since we're
1659-
# intentionally overshooting the mark and are then
1660-
# interested in self.times[i-1]. Raise the error
1661-
# otherwise.
1662-
if not i == len(self.times):
1663-
raise
1664-
instruction = self.instructions[self.times[i-1]]
1665-
self.timeseries.append(instruction)
1666-
1667-
def expand_timeseries(self,all_times):
1652+
while i < time_len and change_time >= self.times[i]:
1653+
i += 1
1654+
self.timeseries.append(self.instructions[self.times[i-1]])
1655+
1656+
def expand_timeseries(self,all_times,flat_all_times_len):
16681657
"""This function evaluates the ramp functions in self.timeseries
16691658
at the time points in all_times, and creates an array of output
16701659
values at those times. These are the values that this output
@@ -1674,11 +1663,13 @@ def expand_timeseries(self,all_times):
16741663
# If this output is not ramping, then its timeseries should
16751664
# not be expanded. It's already as expanded as it'll get.
16761665
if not self.parent_clock_line.ramping_allowed:
1677-
self.raw_output = fastflatten(self.timeseries,self.dtype)
1666+
self.raw_output = np.array(self.timeseries, dtype=np.dtype)
16781667
return
1679-
outputarray = []
1668+
outputarray = np.empty((flat_all_times_len,), dtype=np.dtype(self.dtype))
1669+
j=0
16801670
for i, time in enumerate(all_times):
16811671
if iterable(time):
1672+
time_len = len(time)
16821673
if isinstance(self.timeseries[i],dict):
16831674
# We evaluate the functions at the midpoints of the
16841675
# timesteps in order to remove the zero-order hold
@@ -1706,14 +1697,15 @@ def expand_timeseries(self,all_times):
17061697
if ((outarray<self.limits[0])|(outarray>self.limits[1])).any():
17071698
raise LabscriptError('The function %s called on "%s" at t=%d generated a value which falls outside the base unit limits (%d to %d)'%(self.timeseries[i]['function'],self.name,midpoints[0],self.limits[0],self.limits[1]))
17081699
else:
1709-
outarray = empty(len(time),dtype=self.dtype)
1700+
outarray = empty(time_len,dtype=self.dtype)
17101701
outarray.fill(self.timeseries[i])
1711-
outputarray.append(outarray)
1702+
outputarray[j:j+time_len] = outarray
1703+
j += time_len
17121704
else:
1713-
outputarray.append(self.timeseries[i])
1705+
outputarray[j] = self.timeseries[i]
1706+
j += 1
17141707
del self.timeseries # don't need this any more.
1715-
self.raw_output = fastflatten(outputarray, self.dtype)
1716-
1708+
self.raw_output = outputarray
17171709

17181710
class AnalogQuantity(Output):
17191711
"""Base class for :obj:`AnalogOut`.

0 commit comments

Comments
 (0)