From a11d8dc93aa7072852eab41c0cb18b648a1a6f49 Mon Sep 17 00:00:00 2001 From: Nate Date: Mon, 25 Mar 2024 13:50:43 +0000 Subject: [PATCH 1/7] Nate added stim_location_history variable to be extracted in nate_OptoBiasedChoiceWorld --- .../nate_optoBiasedChoiceWorld/task.py | 31 ++++++++++++++----- pyproject.toml | 2 +- 2 files changed, 24 insertions(+), 9 deletions(-) diff --git a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py index 9f3d2f4..71b25df 100644 --- a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py +++ b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py @@ -16,6 +16,15 @@ import iblrig from iblrig.base_choice_world import SOFTCODE, BiasedChoiceWorldSession from pybpodapi.protocol import StateMachine +import zapit_python_bridge.bridge as zpb +from importlib import reload +import random + +hZP = zpb.bridge() + +num_cond = hZP.num_stim_cond() + +stim_location_history = [] log = logging.getLogger('iblrig.task') @@ -60,6 +69,7 @@ def add_state(self, **kwargs): class Session(BiasedChoiceWorldSession): protocol_name = 'nate_optoBiasedChoiceWorld' + extractor_tasks = ['TrialRegisterRaw', 'ChoiceWorldTrials', 'TrainingStatus'] def __init__( self, @@ -76,11 +86,6 @@ def __init__( self.task_params['OPTO_STOP_STATES'] = opto_stop_states self.task_params['PROBABILITY_OPTO_STIM'] = probability_opto_stim - # loads in the settings in order to determine the main sync and thus the pipeline extractor tasks - is_main_sync = self.hardware_settings.get('MAIN_SYNC', False) - trials_task = 'OptoTrialsBpod' if is_main_sync else 'OptoTrialsNidq' - self.extractor_tasks = ['TrialRegisterRaw', trials_task, 'TrainingStatus'] - # generates the opto stimulation for each trial self.trials_table['opto_stimulation'] = np.random.choice( [0, 1], @@ -97,16 +102,26 @@ def start_hardware(self): self.bpod.register_softcodes(soft_code_dict) def zapit_arm_laser(self): - log.warning('Arming laser') - # TODO: insert code for arming the laser here + #log.warning('Arming laser') + #this is where you define the laser stim (i.e., arm the laser) + + current_location_idx = random.randrange(1,int(num_cond)) + hZP.send_samples( + conditionNum=current_location_idx, hardwareTriggered=True, logging=True + ) + + stim_location_history.append(current_location_idx) + def zapit_fire_laser(self): # just logging - actual firing will be triggered by the state machine via TTL + #this really only triggers a ttl and sends a log entry - no need to plug in code here log.warning('Firing laser') + def zapit_stop_laser(self): log.warning('Stopping laser') - # TODO: insert code for stopping the laser here + hZP.stop_opto_stim() def _instantiate_state_machine(self, trial_number=None): """ diff --git a/pyproject.toml b/pyproject.toml index 1d9d0b6..7ed8c04 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "project_extraction" -version = "0.2.3" +version = "0.4.0" description = "Custom extractors for satellite tasks" dynamic = [ "readme" ] keywords = [ "IBL", "neuro-science" ] From 565700bf8307f639790aab00ca5997fa6e840270 Mon Sep 17 00:00:00 2001 From: Nate Date: Tue, 26 Mar 2024 19:52:44 +0000 Subject: [PATCH 2/7] Changed code to use TCP/IP connection to run zapit laser (not python bridge)! --- .../nate_optoBiasedChoiceWorld/task.py | 51 +++++++++++++++---- pyproject.toml | 2 +- 2 files changed, 41 insertions(+), 12 deletions(-) diff --git a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py index 71b25df..4994554 100644 --- a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py +++ b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py @@ -7,6 +7,7 @@ Additionally the state machine is modified to add output TTLs for optogenetic stimulation """ import logging +import time from pathlib import Path from typing import Literal @@ -16,13 +17,15 @@ import iblrig from iblrig.base_choice_world import SOFTCODE, BiasedChoiceWorldSession from pybpodapi.protocol import StateMachine -import zapit_python_bridge.bridge as zpb from importlib import reload import random -hZP = zpb.bridge() +import sys +sys.path.append('C:\zapit-tcp-bridge\python') +import Python_TCP_Utils as ptu +from TCPclient import TCPclient -num_cond = hZP.num_stim_cond() +num_cond = 52 #will need to change later - is there a function to automatically detect this?> stim_location_history = [] @@ -71,6 +74,9 @@ class Session(BiasedChoiceWorldSession): protocol_name = 'nate_optoBiasedChoiceWorld' extractor_tasks = ['TrialRegisterRaw', 'ChoiceWorldTrials', 'TrainingStatus'] + + + def __init__( self, *args, @@ -94,24 +100,40 @@ def __init__( ).astype(bool) def start_hardware(self): + + + self.client = TCPclient(tcp_port=1488, tcp_ip='127.0.0.1') + + self.client.close() # need to ensure is closed first; currently nowhere that this is defined at end of task! + self.client.connect() super().start_hardware() # add the softcodes for the zapit opto stimulation soft_code_dict = self.bpod.softcodes soft_code_dict.update({SOFTCODE_STOP_ZAPIT: self.zapit_stop_laser}) soft_code_dict.update({SOFTCODE_FIRE_ZAPIT: self.zapit_fire_laser}) self.bpod.register_softcodes(soft_code_dict) + def zapit_arm_laser(self): - #log.warning('Arming laser') + log.warning('Arming laser') #this is where you define the laser stim (i.e., arm the laser) - current_location_idx = random.randrange(1,int(num_cond)) - hZP.send_samples( - conditionNum=current_location_idx, hardwareTriggered=True, logging=True - ) + self.current_location_idx = random.randrange(1,int(num_cond)) - stim_location_history.append(current_location_idx) - + #hZP.send_samples( + # conditionNum=current_location_idx, hardwareTriggered=True, logging=True + #) + + zapit_byte_tuple, zapit_int_tuple = ptu.gen_Zapit_byte_tuple(trial_state_command = 1, + arg_keys_dict = {'conditionNum_channel': True, 'laser_channel': True, + 'hardwareTriggered_channel': True, 'logging_channel': False, + 'verbose_channel': False}, + arg_values_dict = {'conditionNum': self.current_location_idx, 'laser_ON': True, + 'hardwareTriggered_ON': True, 'logging_ON': False, + 'verbose_ON': False}) + response = self.client.send_receive(zapit_byte_tuple) + log.warning(response) + stim_location_history.append(self.current_location_idx) def zapit_fire_laser(self): # just logging - actual firing will be triggered by the state machine via TTL @@ -121,7 +143,14 @@ def zapit_fire_laser(self): def zapit_stop_laser(self): log.warning('Stopping laser') - hZP.stop_opto_stim() + zapit_byte_tuple, zapit_int_tuple = ptu.gen_Zapit_byte_tuple(trial_state_command = 0, + arg_keys_dict = {'conditionNum_channel': True, 'laser_channel': True, + 'hardwareTriggered_channel': True, 'logging_channel': False, + 'verbose_channel': False}, + arg_values_dict = {'conditionNum': self.current_location_idx, 'laser_ON': True, + 'hardwareTriggered_ON': False, 'logging_ON': False, + 'verbose_ON': False}) + response = self.client.send_receive(zapit_byte_tuple) def _instantiate_state_machine(self, trial_number=None): """ diff --git a/pyproject.toml b/pyproject.toml index 7ed8c04..e1e2320 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "project_extraction" -version = "0.4.0" +version = "0.4.1" description = "Custom extractors for satellite tasks" dynamic = [ "readme" ] keywords = [ "IBL", "neuro-science" ] From b69a5a9a02619c0051ee742f496c0031bcee6f8c Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Tue, 4 Jun 2024 11:39:23 +0100 Subject: [PATCH 3/7] ruff formatting --- .../nate_optoBiasedChoiceWorld/task.py | 78 +++++++++++-------- 1 file changed, 45 insertions(+), 33 deletions(-) diff --git a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py index 4994554..13b2861 100644 --- a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py +++ b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py @@ -6,8 +6,10 @@ Additionally the state machine is modified to add output TTLs for optogenetic stimulation """ + import logging -import time +import random +import sys from pathlib import Path from typing import Literal @@ -17,15 +19,12 @@ import iblrig from iblrig.base_choice_world import SOFTCODE, BiasedChoiceWorldSession from pybpodapi.protocol import StateMachine -from importlib import reload -import random -import sys sys.path.append('C:\zapit-tcp-bridge\python') import Python_TCP_Utils as ptu from TCPclient import TCPclient -num_cond = 52 #will need to change later - is there a function to automatically detect this?> +num_cond = 52 # will need to change later - is there a function to automatically detect this?> stim_location_history = [] @@ -74,9 +73,6 @@ class Session(BiasedChoiceWorldSession): protocol_name = 'nate_optoBiasedChoiceWorld' extractor_tasks = ['TrialRegisterRaw', 'ChoiceWorldTrials', 'TrainingStatus'] - - - def __init__( self, *args, @@ -100,11 +96,9 @@ def __init__( ).astype(bool) def start_hardware(self): - - self.client = TCPclient(tcp_port=1488, tcp_ip='127.0.0.1') - self.client.close() # need to ensure is closed first; currently nowhere that this is defined at end of task! + self.client.close() # need to ensure is closed first; currently nowhere that this is defined at end of task! self.client.connect() super().start_hardware() # add the softcodes for the zapit opto stimulation @@ -112,44 +106,62 @@ def start_hardware(self): soft_code_dict.update({SOFTCODE_STOP_ZAPIT: self.zapit_stop_laser}) soft_code_dict.update({SOFTCODE_FIRE_ZAPIT: self.zapit_fire_laser}) self.bpod.register_softcodes(soft_code_dict) - def zapit_arm_laser(self): log.warning('Arming laser') - #this is where you define the laser stim (i.e., arm the laser) + # this is where you define the laser stim (i.e., arm the laser) - self.current_location_idx = random.randrange(1,int(num_cond)) + self.current_location_idx = random.randrange(1, int(num_cond)) - #hZP.send_samples( + # hZP.send_samples( # conditionNum=current_location_idx, hardwareTriggered=True, logging=True - #) - - zapit_byte_tuple, zapit_int_tuple = ptu.gen_Zapit_byte_tuple(trial_state_command = 1, - arg_keys_dict = {'conditionNum_channel': True, 'laser_channel': True, - 'hardwareTriggered_channel': True, 'logging_channel': False, - 'verbose_channel': False}, - arg_values_dict = {'conditionNum': self.current_location_idx, 'laser_ON': True, - 'hardwareTriggered_ON': True, 'logging_ON': False, - 'verbose_ON': False}) + # ) + + zapit_byte_tuple, zapit_int_tuple = ptu.gen_Zapit_byte_tuple( + trial_state_command=1, + arg_keys_dict={ + 'conditionNum_channel': True, + 'laser_channel': True, + 'hardwareTriggered_channel': True, + 'logging_channel': False, + 'verbose_channel': False, + }, + arg_values_dict={ + 'conditionNum': self.current_location_idx, + 'laser_ON': True, + 'hardwareTriggered_ON': True, + 'logging_ON': False, + 'verbose_ON': False, + }, + ) response = self.client.send_receive(zapit_byte_tuple) log.warning(response) stim_location_history.append(self.current_location_idx) def zapit_fire_laser(self): # just logging - actual firing will be triggered by the state machine via TTL - #this really only triggers a ttl and sends a log entry - no need to plug in code here + # this really only triggers a ttl and sends a log entry - no need to plug in code here log.warning('Firing laser') - def zapit_stop_laser(self): log.warning('Stopping laser') - zapit_byte_tuple, zapit_int_tuple = ptu.gen_Zapit_byte_tuple(trial_state_command = 0, - arg_keys_dict = {'conditionNum_channel': True, 'laser_channel': True, - 'hardwareTriggered_channel': True, 'logging_channel': False, - 'verbose_channel': False}, - arg_values_dict = {'conditionNum': self.current_location_idx, 'laser_ON': True, - 'hardwareTriggered_ON': False, 'logging_ON': False, - 'verbose_ON': False}) + zapit_byte_tuple, zapit_int_tuple = ptu.gen_Zapit_byte_tuple( + trial_state_command=0, + arg_keys_dict={ + 'conditionNum_channel': True, + 'laser_channel': True, + 'hardwareTriggered_channel': True, + 'logging_channel': False, + 'verbose_channel': False, + }, + arg_values_dict={ + 'conditionNum': self.current_location_idx, + 'laser_ON': True, + 'hardwareTriggered_ON': False, + 'logging_ON': False, + 'verbose_ON': False, + }, + ) response = self.client.send_receive(zapit_byte_tuple) def _instantiate_state_machine(self, trial_number=None): From 2b503b90d22065c3c4644d7f4e3dcd81ff83f6f4 Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Tue, 4 Jun 2024 13:24:31 +0100 Subject: [PATCH 4/7] implement masking --- .../nate_optoBiasedChoiceWorld/task.py | 23 ++++++++++++++++++- .../task_parameters.yaml | 15 ++++++++++++ 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py index 13b2861..96b3d39 100644 --- a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py +++ b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py @@ -6,7 +6,7 @@ Additionally the state machine is modified to add output TTLs for optogenetic stimulation """ - +from importlib.util import find_spec import logging import random import sys @@ -21,6 +21,8 @@ from pybpodapi.protocol import StateMachine sys.path.append('C:\zapit-tcp-bridge\python') +if find_spec('Python_TCP_Utils') is None: + raise ImportError(f'{__file__} requires zapit-tcp-bridge') import Python_TCP_Utils as ptu from TCPclient import TCPclient @@ -51,11 +53,13 @@ def __init__( is_opto_stimulation=False, states_opto_ttls=None, states_opto_stop=None, + states_mask_ttls=None, ): super().__init__(bpod) self.is_opto_stimulation = is_opto_stimulation self.states_opto_ttls = states_opto_ttls or [] self.states_opto_stop = states_opto_stop or [] + self.states_mask_ttls = states_mask_ttls or [] def add_state(self, **kwargs): if self.is_opto_stimulation: @@ -66,6 +70,10 @@ def add_state(self, **kwargs): ] elif kwargs['state_name'] in self.states_opto_stop: kwargs['output_actions'] += [('SoftCode', SOFTCODE_STOP_ZAPIT)] + if kwargs['state_name'] in self.states_mask_ttls: + kwargs['output_actions'] += [ + ('PWM1', 255), + ] super().add_state(**kwargs) @@ -80,12 +88,14 @@ def __init__( contrast_set_probability_type: Literal['skew_zero', 'uniform'] = DEFAULTS['CONTRAST_SET_PROBABILITY_TYPE'], opto_ttl_states: list[str] = DEFAULTS['OPTO_TTL_STATES'], opto_stop_states: list[str] = DEFAULTS['OPTO_STOP_STATES'], + mask_ttl_states: list[str] = DEFAULTS['MASK_TTL_STATES'], **kwargs, ): super().__init__(*args, **kwargs) self.task_params['CONTRAST_SET_PROBABILITY_TYPE'] = contrast_set_probability_type self.task_params['OPTO_TTL_STATES'] = opto_ttl_states self.task_params['OPTO_STOP_STATES'] = opto_stop_states + self.task_params['MASK_TTL_STATES'] = mask_ttl_states self.task_params['PROBABILITY_OPTO_STIM'] = probability_opto_stim # generates the opto stimulation for each trial @@ -179,6 +189,8 @@ def _instantiate_state_machine(self, trial_number=None): is_opto_stimulation=is_opto_stimulation, states_opto_ttls=self.task_params['OPTO_TTL_STATES'], states_opto_stop=self.task_params['OPTO_STOP_STATES'], + states_mask_ttls=self.task_params['MASK_TTL_STATES'] + , ) @staticmethod @@ -220,6 +232,15 @@ def extra_parser(): type=str, help='list of the state machine states where opto stim should be stopped', ) + parser.add_argument( + '--mask_ttl_states', + option_strings=['--mask_ttl_states'], + dest='mask_ttl_states', + default=DEFAULTS['MASK_TTL_STATES'], + nargs='+', + type=str, + help='list of the state machine states where mask stim should be delivered', + ) return parser diff --git a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task_parameters.yaml b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task_parameters.yaml index eaf8396..aba5453 100644 --- a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task_parameters.yaml +++ b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task_parameters.yaml @@ -5,4 +5,19 @@ - no_go - error - reward +'MASK_TTL_STATES': # list of the state machine states where mask stim should be delivered + - trial_start + - delay_initiation + - reset_rotary_encoder + - quiescent_period + - stim_on + - interactive_delay + - play_tone + - reset2_rotary_encoder + - closed_loop + - no_go + - freeze_error + - error + - freeze_reward + - reward 'PROBABILITY_OPTO_STIM': 0.2 # probability of optogenetic stimulation From 42769ab140f220db1a86dd74b18ba59c31ea29cc Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Tue, 4 Jun 2024 13:25:20 +0100 Subject: [PATCH 5/7] more ruff --- iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py | 6 +++--- .../test_nate_optoBiasedChoiceWorld.py | 1 + 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py index 96b3d39..67393c0 100644 --- a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py +++ b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py @@ -6,10 +6,11 @@ Additionally the state machine is modified to add output TTLs for optogenetic stimulation """ -from importlib.util import find_spec + import logging import random import sys +from importlib.util import find_spec from pathlib import Path from typing import Literal @@ -189,8 +190,7 @@ def _instantiate_state_machine(self, trial_number=None): is_opto_stimulation=is_opto_stimulation, states_opto_ttls=self.task_params['OPTO_TTL_STATES'], states_opto_stop=self.task_params['OPTO_STOP_STATES'], - states_mask_ttls=self.task_params['MASK_TTL_STATES'] - , + states_mask_ttls=self.task_params['MASK_TTL_STATES'], ) @staticmethod diff --git a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/test_nate_optoBiasedChoiceWorld.py b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/test_nate_optoBiasedChoiceWorld.py index 1f1570e..33faf64 100644 --- a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/test_nate_optoBiasedChoiceWorld.py +++ b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/test_nate_optoBiasedChoiceWorld.py @@ -1,6 +1,7 @@ """ Here we test for the state machine code and the task to be importable by the GUI """ + from iblrig_custom_tasks.nate_optoBiasedChoiceWorld.task import Session task = Session(subject='toto') From 613f527a9b732b6cd52624a74d8585e427ee596e Mon Sep 17 00:00:00 2001 From: Nate Date: Tue, 11 Jun 2024 16:03:57 +0100 Subject: [PATCH 6/7] TCP/IP + masking --- .../nate_optoBiasedChoiceWorld/task.py | 48 +++---------------- 1 file changed, 7 insertions(+), 41 deletions(-) diff --git a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py index 67393c0..f2013ce 100644 --- a/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py +++ b/iblrig_custom_tasks/nate_optoBiasedChoiceWorld/task.py @@ -22,13 +22,10 @@ from pybpodapi.protocol import StateMachine sys.path.append('C:\zapit-tcp-bridge\python') -if find_spec('Python_TCP_Utils') is None: +if find_spec('TCPclient') is None: raise ImportError(f'{__file__} requires zapit-tcp-bridge') -import Python_TCP_Utils as ptu from TCPclient import TCPclient -num_cond = 52 # will need to change later - is there a function to automatically detect this?> - stim_location_history = [] log = logging.getLogger('iblrig.task') @@ -111,6 +108,8 @@ def start_hardware(self): self.client.close() # need to ensure is closed first; currently nowhere that this is defined at end of task! self.client.connect() + self.num_cond = self.client.get_num_conditions()[1][0] + log.warning(f'Number of conditions: {self.num_cond}') super().start_hardware() # add the softcodes for the zapit opto stimulation soft_code_dict = self.bpod.softcodes @@ -122,30 +121,14 @@ def zapit_arm_laser(self): log.warning('Arming laser') # this is where you define the laser stim (i.e., arm the laser) - self.current_location_idx = random.randrange(1, int(num_cond)) + self.current_location_idx = random.randrange(1, int(self.num_cond)) # hZP.send_samples( # conditionNum=current_location_idx, hardwareTriggered=True, logging=True # ) - - zapit_byte_tuple, zapit_int_tuple = ptu.gen_Zapit_byte_tuple( - trial_state_command=1, - arg_keys_dict={ - 'conditionNum_channel': True, - 'laser_channel': True, - 'hardwareTriggered_channel': True, - 'logging_channel': False, - 'verbose_channel': False, - }, - arg_values_dict={ - 'conditionNum': self.current_location_idx, - 'laser_ON': True, - 'hardwareTriggered_ON': True, - 'logging_ON': False, - 'verbose_ON': False, - }, + response = self.client.send_samples( + conditionNum=self.current_location_idx, laser_On=True, hardwareTriggered_On=True, logging_On=True ) - response = self.client.send_receive(zapit_byte_tuple) log.warning(response) stim_location_history.append(self.current_location_idx) @@ -156,24 +139,7 @@ def zapit_fire_laser(self): def zapit_stop_laser(self): log.warning('Stopping laser') - zapit_byte_tuple, zapit_int_tuple = ptu.gen_Zapit_byte_tuple( - trial_state_command=0, - arg_keys_dict={ - 'conditionNum_channel': True, - 'laser_channel': True, - 'hardwareTriggered_channel': True, - 'logging_channel': False, - 'verbose_channel': False, - }, - arg_values_dict={ - 'conditionNum': self.current_location_idx, - 'laser_ON': True, - 'hardwareTriggered_ON': False, - 'logging_ON': False, - 'verbose_ON': False, - }, - ) - response = self.client.send_receive(zapit_byte_tuple) + response = self.client.stop_optostim() def _instantiate_state_machine(self, trial_number=None): """ From e8a958781c536a5bbcd6c6da050cb726c1fcc547 Mon Sep 17 00:00:00 2001 From: Florian Rau Date: Tue, 11 Jun 2024 16:10:50 +0100 Subject: [PATCH 7/7] Update pyproject.toml --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index e1e2320..3c8e9f5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "project_extraction" -version = "0.4.1" +version = "0.2.4" description = "Custom extractors for satellite tasks" dynamic = [ "readme" ] keywords = [ "IBL", "neuro-science" ]