Skip to content

Commit

Permalink
Merge pull request #236 from spacetelescope/feature/CATKIT-96-reduce-…
Browse files Browse the repository at this point in the history
…bmc-overhead

CATKIT-96: Reduce file IO overhead for sending commands to BMC
  • Loading branch information
jamienoss committed May 14, 2021
2 parents d187340 + d122292 commit 319bad2
Show file tree
Hide file tree
Showing 2 changed files with 52 additions and 40 deletions.
82 changes: 46 additions & 36 deletions catkit/hardware/boston/DmCommand.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
m_per_volt_map1 = None # for caching the conversion factor, to avoid reading from disk each time
m_per_volt_map2 = None # for caching the conversion factor, to avoid reading from disk each time

flat_map_dm1 = None # for caching the conversion factor, to avoid reading from disk each time
flat_map_dm2 = None # for caching the conversion factor, to avoid reading from disk each time

class DmCommand(object):
def __init__(self, data, dm_num, flat_map=False, bias=False, as_voltage_percentage=False,
Expand Down Expand Up @@ -107,14 +109,7 @@ def to_dm_command(self):

# OR apply Flat Map (which is itself biased).
elif self.flat_map:
if self.dm_num == 1:
flat_map_file_name = CONFIG_INI.get("boston_kilo952", "flat_map_dm1")
flat_map_volts = fits.open(os.path.join(self.calibration_data_path, flat_map_file_name))
dm_command += flat_map_volts[0].data
else:
flat_map_file_name = CONFIG_INI.get("boston_kilo952", "flat_map_dm2")
flat_map_volts = fits.open(os.path.join(self.calibration_data_path, flat_map_file_name))
dm_command += flat_map_volts[0].data
dm_command += get_flat_map_volts(self.dm_num)

# Convert between 0-1.
dm_command /= self.max_volts
Expand Down Expand Up @@ -187,18 +182,33 @@ def load_dm_command(path, dm_num=1, flat_map=False, bias=False, as_volts=False):


def get_flat_map_volts(dm_num):
"""
Get the flat map for a given dm. The flat map is in volts for each actuator.
:param dm_num: Which DM to lead the command for.
:return: flat map for the selected DM. This function caches the map to avoid multiple disk access.
"""
calibration_data_package = CONFIG_INI.get("optics_lab", "calibration_data_package")
calibration_data_path = os.path.join(catkit.util.find_package_location(calibration_data_package),
"hardware",
"boston")

global flat_map_dm1, flat_map_dm2

if dm_num == 1:
flat_map_file_name = CONFIG_INI.get("boston_kilo952", "flat_map_dm1")
flat_map_volts = fits.open(os.path.join(calibration_data_path, flat_map_file_name))
return flat_map_volts[0].data
else:
flat_map_file_name = CONFIG_INI.get("boston_kilo952", "flat_map_dm2")
flat_map_volts = fits.open(os.path.join(calibration_data_path, flat_map_file_name))
return flat_map_volts[0].data
if flat_map_dm1 is None:
fname = CONFIG_INI.get("boston_kilo952", "flat_map_dm1")
flat_map_dm1 = fits.getdata(os.path.join(calibration_data_path, fname))

return flat_map_dm1

if dm_num == 2:
if flat_map_dm2 is None:
fname = CONFIG_INI.get("boston_kilo952", "flat_map_dm2")
flat_map_dm2 = fits.getdata(os.path.join(calibration_data_path, fname))

return flat_map_dm2

raise ValueError('dm_num should be either 1 or 2.')


def get_m_per_volt_map(dm_num):
Expand All @@ -213,14 +223,22 @@ def get_m_per_volt_map(dm_num):
"boston")

global m_per_volt_map1, m_per_volt_map2
if m_per_volt_map1 is None:
m_per_volt_map1 = fits.getdata(os.path.join(calibration_data_path,
CONFIG_INI.get("boston_kilo952", "gain_map_dm1")))
if m_per_volt_map2 is None:
m_per_volt_map2 = fits.getdata(os.path.join(calibration_data_path,
CONFIG_INI.get("boston_kilo952", "gain_map_dm2")))

return m_per_volt_map1 if dm_num == 1 else m_per_volt_map2
if dm_num == 1:
if m_per_volt_map1 is None:
fname = CONFIG_INI.get("boston_kilo952", "gain_map_dm1")
m_per_volt_map1 = fits.getdata(os.path.join(calibration_data_path, fname))

return m_per_volt_map1

if dm_num == 2:
if m_per_volt_map2 is None:
fname = CONFIG_INI.get("boston_kilo952", "gain_map_dm2")
m_per_volt_map2 = fits.getdata(os.path.join(calibration_data_path, fname))

return m_per_volt_map2

raise ValueError('dm_num should be either 1 or 2.')


def convert_volts_to_m(data, dm_num, meter_to_volt_map=None):
Expand Down Expand Up @@ -262,26 +280,18 @@ def convert_m_to_volts(data, dm_num, meter_to_volt_map=None):


def convert_dm_command_to_image(dm_command):
# Flatten the mask using index952
mask = catkit.util.get_dm_mask()
index952 = np.flatnonzero(mask)
mask = catkit.util.get_dm_mask().astype('bool')
number_of_actuators = np.count_nonzero(mask)

number_of_actuators_per_dimension = CONFIG_INI.getint('boston_kilo952', 'dm_length_actuators')
number_of_actuators = CONFIG_INI.getint("boston_kilo952", "number_of_actuators")
image = np.zeros((number_of_actuators_per_dimension, number_of_actuators_per_dimension))
image[np.unravel_index(index952, image.shape)] = dm_command[:number_of_actuators]
image = np.zeros(mask.shape)
image[mask] = dm_command[:number_of_actuators]

return image


def convert_dm_image_to_command(dm_image, path_to_save=None):
# Flatten the gain_map using index952
mask = catkit.util.get_dm_mask()
index952 = np.flatnonzero(mask)

# Parse using index952.
image_1d = np.ndarray.flatten(dm_image)
dm_command = image_1d[index952]
# Take actuators corresponding to the DM mask
dm_command = dm_image[catkit.util.get_dm_mask().astype('bool')]

# Write new image as fits file
if path_to_save is not None:
Expand Down
10 changes: 6 additions & 4 deletions catkit/util.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,14 +25,16 @@ def find_package_location(package='catkit'):
return importlib.util.find_spec(package).submodule_search_locations[0]


def find_repo_location(package='cakit'):
def find_repo_location(package='catkit'):
return os.path.abspath(os.path.join(find_package_location(package), os.pardir))


def get_dm_mask():
mask_path = os.path.join(find_package_location("catkit"), "hardware", "boston", "kiloCdm_2Dmask.fits")
mask = fits.open(mask_path)[0].data
return mask
if not hasattr(get_dm_mask, 'mask'):
mask_path = os.path.join(find_package_location("catkit"), "hardware", "boston", "kiloCdm_2Dmask.fits")
get_dm_mask.mask = fits.getdata(mask_path)

return get_dm_mask.mask


# Does numpy gotchu?
Expand Down

0 comments on commit 319bad2

Please sign in to comment.