diff --git a/Camera/AbstractCamera.py b/Camera/AbstractCamera.py index 83a3513..4285940 100644 --- a/Camera/AbstractCamera.py +++ b/Camera/AbstractCamera.py @@ -94,13 +94,14 @@ def take_observation(self, observation, headers=None, filename=None, # (see `process_exposure`) observation_event = Event() - (exp_time, gain, temperature, file_path, image_id, metadata, + (exp_time, gain, offset, temperature, file_path, image_id, metadata, is_pointing) = self._setup_observation(observation, headers, filename, *args, **kwargs) kwargs["gain"] = gain + kwargs["offset"] = offset kwargs["temperature"] = temperature exposure_event = self.take_exposure( exposure_time=exp_time, @@ -163,6 +164,7 @@ def _setup_observation(self, observation, headers, filename, **kwargs): # get values exp_time = kwargs.get('exp_time', observation.time_per_exposure) gain = observation.configuration["gain"] + offset = observation.configuration["offset"] temperature = observation.configuration["temperature"] filter_name = observation.configuration.get("filter", "no-filter") @@ -181,12 +183,12 @@ def _setup_observation(self, observation, headers, filename, **kwargs): 'temperature_degC': temperature } metadata.update(headers) - return (exp_time, gain, temperature, file_path, image_id, metadata, - is_pointing) + return (exp_time, gain, offset, temperature, file_path, image_id, metadata, is_pointing) def take_calibration(self, temperature, gain, + offset, exp_time, headers=None, calibration_seq_id=None, @@ -201,6 +203,7 @@ def take_calibration(self, file_path, metadata = self._setup_calibration( temperature=temperature, gain=gain, + offset=offset, exp_time=exp_time, headers=headers, calibration_seq_id=calibration_seq_id, @@ -213,6 +216,7 @@ def take_calibration(self, filename=file_path, temperature=temperature, gain=gain, + offset=offset, exposure_time=exp_time, headers=headers, calibration_seq_id=calibration_seq_id, @@ -231,6 +235,7 @@ def take_calibration(self, def get_calibration_directory(self, temperature, gain, + offset, exp_time, headers, calibration_seq_id=None, @@ -252,6 +257,7 @@ def get_calibration_directory(self, image_dir, f"temp_deg_{temperature}", f"gain_{gain}", + f"offset_{offset}", f"exp_time_sec_{exp_time.to(u.second).value}") if calibration_seq_id is not None: image_dir = os.path.join( @@ -276,6 +282,7 @@ def get_calibration_directory(self, def _setup_calibration(self, temperature, gain, + offset, exp_time, headers=None, calibration_seq_id=None, @@ -293,6 +300,7 @@ def _setup_calibration(self, file_path = self.get_calibration_directory( temperature=temperature, gain=gain, + offset=offset, exp_time=exp_time, headers=headers, calibration_seq_id=calibration_seq_id, @@ -319,6 +327,7 @@ def _setup_calibration(self, 'start_time': start_time, 'exp_time': exp_time.to(u.second).value, 'gain': gain, + 'offset': offset, 'temperature_degC': temperature.to(u.Celsius).value if temperature else "no_target", 'observation_ids': [o.id for o in observations] } diff --git a/Camera/IndiAbstractCamera.py b/Camera/IndiAbstractCamera.py index 64574e2..bdbf77a 100644 --- a/Camera/IndiAbstractCamera.py +++ b/Camera/IndiAbstractCamera.py @@ -46,6 +46,9 @@ def shoot_asyncWithEvent(self, exp_time_sec, filename, exposure_event, # set gain gain = kwargs.get("gain", self.gain) self.set_gain(gain) + # set offset + offset = kwargs.get("offset", self.offset) + self.set_offset(offset) # set temperature temperature = kwargs.get("temperature", None) if temperature is not None: diff --git a/Camera/IndiAltairCameraNonCool.py b/Camera/IndiAltairCameraNonCool.py new file mode 100644 index 0000000..b8ad805 --- /dev/null +++ b/Camera/IndiAltairCameraNonCool.py @@ -0,0 +1,27 @@ +# Basic stuff +import numpy as np + +# Local stuff +from Camera.IndiAltairCamera import IndiAltairCamera + +class IndiAltairCameraNonCool(IndiAltairCamera): + def __init__(self, serv_time, config=None, + connect_on_create=True): + + # Parent initialization + super().__init__( + serv_time=serv_time, + config=config, + connect_on_create=connect_on_create) + + def set_cooling_on(self): + pass + + def set_cooling_off(self): + pass + + def get_temperature(self): + return np.nan + + def set_temperature(self, temperature): + pass diff --git a/Camera/IndiCamera.py b/Camera/IndiCamera.py index dea30e8..1fc92d7 100644 --- a/Camera/IndiCamera.py +++ b/Camera/IndiCamera.py @@ -92,7 +92,8 @@ def __init__(self, logger=None, config=None, connect_on_create=True): # Default exposureTime, gain self.exp_time_sec = 5 - self.gain = 400 + self.gain = 150 + self.offset = 30 # Finished configuring self.logger.debug('Configured Indi Camera successfully') @@ -305,6 +306,13 @@ def get_gain(self): gain = self.get_number('CCD_GAIN') return gain["GAIN"] + def set_offset(self, value): + self.set_number('CCD_OFFSET', {'OFFSET': value}, sync=True, timeout=self.defaultTimeout) + + def get_offset(self): + offset = self.get_number('CCD_OFFSET') + return offset["OFFSET"] + def get_frame_type(self): return self.get_switch('CCD_FRAME_TYPE') diff --git a/Camera/IndiPlayerOneCamera.py b/Camera/IndiPlayerOneCamera.py index 9e01b4c..c235129 100644 --- a/Camera/IndiPlayerOneCamera.py +++ b/Camera/IndiPlayerOneCamera.py @@ -39,3 +39,11 @@ def set_gain(self, value): def get_gain(self): gain = self.get_number('CCD_CONTROLS') return gain["Gain"] + + def set_offset(self, value): + self.set_number('CCD_CONTROLS', {'Offset': value}, sync=True, timeout=self.defaultTimeout) + + def get_offset(self): + offset = self.get_number('CCD_CONTROLS') + return offset["Offset"] + diff --git a/ObservationPlanner/Scheduler.py b/ObservationPlanner/Scheduler.py index c82fdf9..6ca27e8 100644 --- a/ObservationPlanner/Scheduler.py +++ b/ObservationPlanner/Scheduler.py @@ -306,11 +306,13 @@ def initialize_target_list(self): count = config["count"] temperature = config["temperature"] gain = config["gain"] + offset = config["offset"] exp_time_sec = config["exp_time_sec"]*u.second configuration={ 'filter': filter_name, 'temperature': temperature, - 'gain': gain + 'gain': gain, + 'offset': offset } #TODO TN retrieve priority from the file ? priority = 0 if (filter_name == 'Luminance') else 1 diff --git a/apps/calibration_utilities/dark_library_creation.py b/apps/calibration_utilities/dark_library_creation.py index 4972203..20047c9 100644 --- a/apps/calibration_utilities/dark_library_creation.py +++ b/apps/calibration_utilities/dark_library_creation.py @@ -33,7 +33,7 @@ class DarkLibraryBuilder(): - def __init__(self, camera, exp_time_list, gain_list, temp_list=[np.NaN], + def __init__(self, camera, exp_time_list, gain_list, offset_list, temp_list=[np.NaN], outdir=None, nb_image=100): #super(self).__init__() @@ -41,6 +41,7 @@ def __init__(self, camera, exp_time_list, gain_list, temp_list=[np.NaN], self.cam = camera self.exp_time_list = exp_time_list self.gain_list = gain_list + self.offset_list = offset_list self.temp_list = temp_list self.outdir = outdir or './dark_calibration' #TODO TN replace self.nb_image = nb_image @@ -72,42 +73,43 @@ def gen_report_gain_basedirname(self, temperature, gain): temperature.to(u.Celsius).value, gain )) - def gen_calib_basedirname(self, temperature, gain, exp_time): + def gen_calib_basedirname(self, temperature, gain, offset, exp_time): return ("{}/calibration/{}/camera_{}/temperature_{}/gain_{}/exp_time_{}" "".format(self.outdir, 'dark', self.cam.name, temperature.to(u.Celsius).value, gain, + offset, exp_time.to(u.second).value )) - def gen_calib_filename(self, temperature, gain, exp_time, index): - image_dir = self.gen_calib_basedirname(temperature, gain, exp_time) + def gen_calib_filename(self, temperature, gain, offset, exp_time, index): + image_dir = self.gen_calib_basedirname(temperature, gain, offset, exp_time) os.makedirs(image_dir, exist_ok=True) image_name = os.path.join(image_dir,str(index)+'.fits') return image_name - def gen_calib_mastername(self, temperature, gain, exp_time): - image_dir = self.gen_calib_basedirname(temperature, gain, exp_time) + def gen_calib_mastername(self, temperature, gain, offset, exp_time): + image_dir = self.gen_calib_basedirname(temperature, gain, offset, exp_time) os.makedirs(image_dir, exist_ok=True) master_name = os.path.join(image_dir, 'master.tif') return master_name - def gen_calib_masterstdname(self, temperature, gain, exp_time): - image_dir = self.gen_calib_basedirname(temperature, gain, exp_time) + def gen_calib_masterstdname(self, temperature, gain, offset, exp_time): + image_dir = self.gen_calib_basedirname(temperature, gain, offset, exp_time) os.makedirs(image_dir, exist_ok=True) master_std_name = os.path.join(image_dir, 'master_std.tif') return master_std_name - def gen_calib_masterpsnrname(self, temperature, gain, exp_time): - image_dir = self.gen_calib_basedirname(temperature, gain, exp_time) + def gen_calib_masterpsnrname(self, temperature, gain, offset, exp_time): + image_dir = self.gen_calib_basedirname(temperature, gain, offset, exp_time) os.makedirs(image_dir, exist_ok=True) master_psnr_name = os.path.join(image_dir, 'master_psnr.tif') return master_psnr_name - def gen_NLF_figname(self, temperature, gain, exp_time): - base_dir = self.gen_calib_basedirname(temperature, gain, exp_time) + def gen_NLF_figname(self, temperature, gain, offset, exp_time): + base_dir = self.gen_calib_basedirname(temperature, gain, offset, exp_time) os.makedirs(base_dir, exist_ok=True) conv_check = os.path.join(base_dir, 'NLF_conv_check.png') regression = os.path.join(base_dir, 'NLF_regression.png') @@ -483,26 +485,27 @@ def acquire_images(self): self.cam.prepare_shoot() for temperature in self.temp_list: self.set_temperature(temperature) - for gain in self.gain_list: - self.cam.set_gain(gain) - for exp_time in self.exp_time_list: - for i in range(self.nb_image): - print('Temperature {}, gain {}, exp time {}, Acquiring' - ' image {}'.format(temperature,gain,exp_time,i)) - fname = self.gen_calib_filename(temperature, gain, - exp_time,i) - if not os.path.exists(fname): - print('before set exp time') - self.cam.setExpTimeSec(exp_time) - print('before shoot') - self.cam.shoot_async() - print('After shoot_async, going to sync') - self.cam.synchronize_with_image_reception() - print('After sync') - fits = self.cam.get_received_image() - print('Image received') - with open(fname, "wb") as f: - fits.writeto(f) + for offset in self.offset_list: + self.set_offset(offset) + for gain in self.gain_list: + self.cam.set_gain(gain) + for exp_time in self.exp_time_list: + for i in range(self.nb_image): + print('Temperature {}, gain {}, offset {}, exp time {}, Acquiring' + ' image {}'.format(temperature, gain, offset, exp_time, i)) + fname = self.gen_calib_filename(temperature, gain, offset, exp_time, i) + if not os.path.exists(fname): + print('before set exp time') + self.cam.setExpTimeSec(exp_time) + print('before shoot') + self.cam.shoot_async() + print('After shoot_async, going to sync') + self.cam.synchronize_with_image_reception() + print('After sync') + fits = self.cam.get_received_image() + print('Image received') + with open(fname, "wb") as f: + fits.writeto(f) self.cleanup_device() def compute_statistics(self): @@ -626,10 +629,12 @@ def main(config_file='./jsonModel/IndiCCDSimulatorCamera.json', # exp_time_list = np.linspace(1, 30, 8)*u.second exp_time_list = np.array([1,5,10,30,60,120])*u.second # gain_list = np.linspace(0,100,10, dtype=np.int32).tolist() - gain_list = [0,25,50,75,100] + gain_list = [120, 150] + offset_list = [20, 30] temp_list = [np.NaN*u.Celsius] b = DarkLibraryBuilder(cam, exp_time_list, temp_list=temp_list, gain_list=gain_list, + offset_list=offset_list, outdir='./dark_calibration', nb_image=19) b.show_plot = show_plot diff --git a/calibration/ImagingCalibration.py b/calibration/ImagingCalibration.py index 5e7ecf6..6f5f9a0 100644 --- a/calibration/ImagingCalibration.py +++ b/calibration/ImagingCalibration.py @@ -34,6 +34,7 @@ def __init__(self, self.flat_exp_sec = config["flat"]["sec"]*u.second self.flat_nb = config["flat"]["nb"] self.flat_gain = config["flat"]["gain"] + self.flat_offset = config["flat"]["offset"] self.flat_temperature = config["flat"]["temperature"] self.dark_nb = config["dark"]["dark_nb"] @@ -65,6 +66,7 @@ def take_flat(self, observed_list): event = self.camera.take_calibration( temperature=self.flat_temperature, gain=self.flat_gain, + offset=self.flat_offset, exp_time=self.flat_exp_sec, headers={"filter": filter_name}, calibration_name="flat", @@ -83,21 +85,23 @@ def take_dark(self, observed_list): for seq_time, observation in observed_list.items(): temp_deg = observation.configuration['temperature'] conf = (observation.time_per_exposure, - observation.configuration['gain']) + observation.configuration['gain'], + observation.configuration['offset']) if temp_deg in dark_config_dict: dark_config_dict[temp_deg].add(conf) else: dark_config_dict[temp_deg] = set((conf,)) self.controller.close_optical_path_for_dark() - for temp_deg, times_gains in dark_config_dict.items(): + for temp_deg, times_gains_offsets in dark_config_dict.items(): if temp_deg: self.camera.set_temperature(temp_deg) - for (exp_time, gain) in times_gains: + for (exp_time, gain, offset) in times_gains_offsets: for i in range(self.dark_nb): event = self.camera.take_calibration( temperature=temp_deg, gain=gain, + offset=offset, exp_time=exp_time, headers={}, calibration_name="dark", diff --git a/calibration/SpectralCalibration.py b/calibration/SpectralCalibration.py index b8a940d..6c39792 100644 --- a/calibration/SpectralCalibration.py +++ b/calibration/SpectralCalibration.py @@ -31,10 +31,12 @@ def __init__(self, self.spectral_calib_exp_sec = config["spectral_calib"]["sec"]*u.second self.spectral_calib_nb = config["spectral_calib"]["nb"] self.spectral_calib_gain = config["spectral_calib"]["gain"] + self.spectral_calib_offset = config["spectral_calib"]["offset"] self.spectral_calib_temperature = config["spectral_calib"]["temperature"] self.flat_exp_sec = config["flat"]["sec"]*u.second self.flat_nb = config["flat"]["nb"] self.flat_gain = config["flat"]["gain"] + self.flat_offset = config["flat"]["offset"] self.flat_temperature = config["flat"]["temperature"] self.dark_nb = config["dark"]["dark_nb"] @@ -68,6 +70,7 @@ def take_flat(self, observed_list): event = self.camera.take_calibration( temperature=self.flat_temperature, gain=self.flat_gain, + offset=self.flat_offset, exp_time_sec=self.flat_exp_sec, calibration_name="flat", observations=observed_list.values()) @@ -81,6 +84,7 @@ def take_spectral_calib(self, observed_list): event = self.camera.take_calibration( temperature=self.spectral_calib_temperature, gain=self.spectral_calib_gain, + offset=self.spectral_calib_offset, exp_time_sec=self.spectral_calib_exp_sec, calibration_name="spectral_calib", observations=observed_list.values()) @@ -89,27 +93,36 @@ def take_spectral_calib(self, observed_list): self.controller.switch_off_spectro_light() def take_dark(self, observed_list): - dark_config_dict = {} + """ + Temperature is the "most expensive" parameter to change, hence we will use this as our primary key + :param observed_list: + :return: + """ + dark_config_dict = dict() for seq_time, observation in observed_list.items(): - conf = ( - observation.time_per_exposure, - observation.configuration['gain'], - observation.configuration['temperature']) - if conf in dark_config_dict: - dark_config_dict[conf].append(seq_time) + temp_deg = observation.configuration['temperature'] + conf = (observation.time_per_exposure, + observation.configuration['gain'], + observation.configuration['offset']) + if temp_deg in dark_config_dict: + dark_config_dict[temp_deg].add(conf) else: - dark_config_dict[conf] = [seq_time] + dark_config_dict[temp_deg] = set((conf,)) self.controller.close_optical_path_for_dark() - for (exp_time_sec, gain, temperature), seq_times in dark_config_dict.items(): - for i in range(self.dark_nb): - event = self.camera.take_calibration( - temperature=temperature, - gain=gain, - exp_time_sec=exp_time_sec, - calibration_name="dark", - observations=[observed_list[seq_time] for seq_time in seq_times]) - #yield event - event.wait() + for temp_deg, times_gains_offsets in dark_config_dict.items(): + if temp_deg: + self.camera.set_temperature(temp_deg) + for (exp_time, gain, offset) in times_gains_offsets: + for i in range(self.dark_nb): + event = self.camera.take_calibration( + temperature=temp_deg, + gain=gain, + offset=offset, + exp_time=exp_time, + headers={}, + calibration_name="dark", + observations=observed_list.values()) + event.wait() self.controller.open_optical_path() - + return event \ No newline at end of file diff --git a/conf_files/config.yaml b/conf_files/config.yaml index a008b29..4fc2bf9 100644 --- a/conf_files/config.yaml +++ b/conf_files/config.yaml @@ -64,17 +64,19 @@ calibration: #module: ImagingCalibration module: SpectralCalibration spectral_calib: - nb: 11 + nb: 10 sec: 30 - gain: 1 - temperature: + gain: 150 + offset: 30 + temperature: -10 flat: - nb: 1 + nb: 10 sec: 5 - gain: 1 - temperature: + gain: 150 + offset: 30 + temperature: -10 dark: - dark_nb: 1 + dark_nb: 10 controller: module: DummySpectroController device_name: dummy diff --git a/conf_files/config_backyard.yaml b/conf_files/config_backyard.yaml index 6373cf9..30c2fd0 100644 --- a/conf_files/config_backyard.yaml +++ b/conf_files/config_backyard.yaml @@ -121,17 +121,19 @@ calibration: #module: ImagingCalibration module: SpectralCalibration spectral_calib: - nb: 11 + nb: 10 sec: 30 - gain: 1 - temperature: + gain: 150 + offset: 30 + temperature: -10 flat: - nb: 1 + nb: 10 sec: 5 - gain: 1 - temperature: + gain: 150 + offset: 30 + temperature: -10 dark: - dark_nb: 1 + dark_nb: 10 controller: module: IndiSpectroController device_name: Shelyak Spox @@ -228,7 +230,7 @@ cameras: indi_client : indi_host : localhost indi_port : 7625 - - module: IndiAltairCamera + - module: IndiAltairCameraNonCool camera_name: Altair AA183MPRO do_acquisition: true SCOPE_INFO: # 50/242 evoguide diff --git a/conf_files/spectral_targets.yaml b/conf_files/spectral_targets.yaml index 72137a7..a9fe527 100644 --- a/conf_files/spectral_targets.yaml +++ b/conf_files/spectral_targets.yaml @@ -3,27 +3,31 @@ constraints : maxairmass : 17 #for testing, normally use 2 minmoonseparationdeg : 2 # normally put 45 targets : - "HD222404" : #HD214680 + "Arcturus" : #HD214680 #HD222404 priority : 0 count : 1 - temperature : + temperature : 15 gain: 150 + offset: 30 exp_time_sec : 20 # "T CrB" : # priority : 0 # count : 1 -# temperature : +# temperature : 15 # gain: 150 +# offset: 30 # exp_time_sec : 20 # "GK Per" : # priority : 0 # count : 2 -# temperature : +# temperature : 15 # gain: 150 +# offset: 30 # exp_time_sec : 5 reference_observation: - count : 1 - temperature : - gain : 1 + count : 10 + temperature : 15 + gain : 150 + offset: 30 exp_time_sec : 20 diff --git a/conf_files/targets.yaml b/conf_files/targets.yaml index 3bb59f5..4778900 100644 --- a/conf_files/targets.yaml +++ b/conf_files/targets.yaml @@ -9,121 +9,138 @@ targets : count : 60 temperature : gain: 150 + offset: 30 exp_time_sec : 60 "GK Per" : Luminance : count : 60 temperature : gain: 150 + offset: 30 exp_time_sec : 60 # "PKS 2145+067" : # Luminance : # count : 10 # temperature : # gain: 150 +# offset: 30 # exp_time_sec : 360 # "QSO J1824+1044" : # Luminance : # count : 10 # temperature : # gain: 150 +# offset: 30 # exp_time_sec : 360 - # "15h12m43.2s +31d12m43s" : # Luminance : # count : 2+ (you can put a + if you want to acquire minimum 2, and, more if possible # count : 2 # temperature : -# gain : 1 +# gain: 150 +# offset: 30 # exp_time_sec : 100 # M42 : # Luminance : # count : 3 # temperature : -# gain : 1 +# gain: 150 # exp_time_sec : 10 # HCG49 : # Luminance : # count : 3 # temperature : -# gain : 1 +# gain: 150 # exp_time_sec : 10 # HD179527 : # Luminance : # count : 3 # temperature : -# gain : 1 +# gain: 150 +# offset: 30 # exp_time_sec : 10 # Deneb: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # Polaris: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # Alioth: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # Alkaid: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # Dubhe: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # Vega: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # Sheliak: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # Altair: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # Sarin: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # Kornephoros: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # Alphecca: # Luminance: # count: 3 -# temperature: -# gain: 10 +# temperature: 15 +# gain: 150 +# offset: 30 # exp_time_sec: 10 # M51 : # Luminance : # count : 10 # temperature : -# gain : 1 +# gain: 150 +# offset: 30 # exp_time_sec : 200