Skip to content

Commit

Permalink
Merge pull request #1 from SchwarzNeuroconLab/dev
Browse files Browse the repository at this point in the history
New Feature release!
  • Loading branch information
JensBlack authored Sep 17, 2020
2 parents f558599 + fe432a8 commit e53cfa0
Show file tree
Hide file tree
Showing 26 changed files with 2,343 additions and 30 deletions.
25 changes: 13 additions & 12 deletions DeepLabStream.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@
import click

from utils.configloader import RESOLUTION, FRAMERATE, OUT_DIR, MODEL, MULTI_CAM, STACK_FRAMES, \
ANIMALS_NUMBER, STREAMS, VIDEO
ANIMALS_NUMBER, STREAMS, VIDEO, IPWEBCAM
from utils.poser import load_deeplabcut, get_pose, find_local_peaks_new, calculate_skeletons
from utils.plotter import plot_bodyparts, plot_metadata_frame
from experiments.experiments import ExampleExperiment


def create_video_files(directory, devices, resolution, framerate, codec):
Expand Down Expand Up @@ -132,6 +131,13 @@ def set_camera_manager():
from utils.generic import VideoManager
manager = VideoManager()
return manager

elif IPWEBCAM:
from utils.generic import WebCamManager
manager = WebCamManager()
return manager


else:
manager_list = []
# loading realsense manager, if installed
Expand Down Expand Up @@ -430,15 +436,8 @@ def calculate_fps(self, current_analysis_time):
##################
@staticmethod
def set_up_experiment():
import importlib
from utils.configloader import EXP_NAME
mod = importlib.import_module('experiments.experiments')
try:
experiment_class = getattr(mod, EXP_NAME)
experiment = experiment_class()
except AttributeError:
raise ValueError(f'Experiment: {EXP_NAME} not in experiments.py.')

from experiments.utils.exp_setup import setup_experiment
experiment = setup_experiment()
return experiment

def start_experiment(self):
Expand Down Expand Up @@ -519,9 +518,9 @@ def create_dataframes(self):
Outputting dataframes to csv
"""
for num, camera in enumerate(self._data_output):
print("Saving database for device {}".format(camera))
df = pd.DataFrame(self._data_output[camera])
df.index.name = 'Frame'
print("Saving database for device {}".format(camera))
df.to_csv(OUT_DIR + '/DataOutput{}'.format(camera) + '-' + time.strftime('%d%m%Y-%H%M%S') + '.csv', sep=';')
print("Database saved")

Expand All @@ -530,8 +529,10 @@ def create_dataframes(self):
######
@staticmethod
def greetings():
from utils.configloader import EXP_NAME, EXP_ORIGIN
print("This is DeepLabStream")
print("Developed by: Jens Schweihoff and Matvey Loshakov")
print(f'Initializing {EXP_ORIGIN.lower()} experiment: {EXP_NAME}...')

def get_camera_manager(self):
return self._camera_manager
Expand Down
18 changes: 13 additions & 5 deletions Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,21 @@ DeepLabStreams core feature is the real-time analysis using any type of camera-b

### 2. [How to use DLStream GUI](https://github.com/SchwarzNeuroconLab/DeepLabStream/wiki/How-to-use-DLStream)

### 3. [Introduction to experiments](https://github.com/SchwarzNeuroconLab/DeepLabStream/wiki/Introduction)
### 3. Check out our [Out-of-the-Box](https://github.com/SchwarzNeuroconLab/DeepLabStream/wiki/Out-Of-The-Box:-Overview)

### 4. [Design your first experiment](https://github.com/SchwarzNeuroconLab/DeepLabStream/wiki/My-first-experiment)
### 4. [Design an Out-of-the-Box Experiment](https://github.com/SchwarzNeuroconLab/DeepLabStream/wiki/Out-Of-The-Box:-Design-Experiments)

### 5. [Adapting an existing experiment to your own needs](https://github.com/SchwarzNeuroconLab/DeepLabStream/wiki/Adapting-an-existing-experiment-to-your-own-needs)
### What's underneath?:

#### Check out our [Out-of-the-Box](https://github.com/SchwarzNeuroconLab/DeepLabStream/wiki/Out-Of-The-Box:-What-Triggers-are-available%3F) section to get a good idea, what DLStream has in stock for your own experiments!
### 5. [Introduction to experiments](https://github.com/SchwarzNeuroconLab/DeepLabStream/wiki/Introduction)

### For advanced users:

### 6. [Design your first experiment](https://github.com/SchwarzNeuroconLab/DeepLabStream/wiki/My-first-experiment)

### 7. [Adapting an existing experiment to your own needs](https://github.com/SchwarzNeuroconLab/DeepLabStream/wiki/Adapting-an-existing-experiment-to-your-own-needs)



### How to use DeepLabStream

Expand All @@ -52,7 +60,7 @@ To start working with DeepLabStream, press the `Start Stream` button. It will ac
After that you can `Start Analysis` to start DeepLabCut and receive a pose estimations for each frame, or, additionally, you can `Start Recording` to record a
video of the current feed (visible in the stream window). You will see your current video timestamp (counted in frames) and FPS after you pressed the `Start Analysis` button.

![Analisys](https://user-images.githubusercontent.com/44863941/91173049-7ac34580-e6dd-11ea-80b6-ad56cb9cf22c.png)
![Analysis](https://user-images.githubusercontent.com/44863941/91173049-7ac34580-e6dd-11ea-80b6-ad56cb9cf22c.png)

As you can see, we track three points that represent three body parts of the mouse - nose, neck and tail root.
Every single frame where the animal was tracked is outputted to the dataframe, which would create a .csv file after the analysis is finished.
Expand Down
118 changes: 118 additions & 0 deletions design_experiment.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
from experiments.utils.exp_setup import DlStreamConfigWriter
import click

@click.command()
@click.option('--default', 'default', is_flag=True)
def design_experiment(default):
config = DlStreamConfigWriter()
input_dict = dict(EXPERIMENT = None,
TRIGGER = None,
PROCESS = None,
STIMULATION = None)

def get_input(input_name):
click.echo(f'Choosing {input_name}... \n Available {input_name}s are: ' + ', '.join(config.get_available_module_names(input_name)))
input_value = click.prompt(f'Enter a base {input_name} module',type=str)
while not config.check_if_default_exists(input_value,input_name):
click.echo(f'{input_name} {input_value} does not exists.')
input_value = click.prompt(f'Enter a base {input_name} module',type=str)
return input_value
"""Experiment"""

input_value = get_input('EXPERIMENT')
input_dict['EXPERIMENT'] = input_value
if input_value == 'BaseOptogeneticExperiment':
input_dict['STIMULATION'] = 'BaseStimulation'
input_dict['PROCESS'] = 'BaseProtocolProcess'

elif input_value == 'BaseTrialExperiment':
click.echo(f'Available Triggers are: ' + ', '.join(config.get_available_module_names('TRIGGER')))
click.echo('Note, that you cannot select the same Trigger as selected in TRIGGER.')

input_value = click.prompt(f'Enter TRIAL_TRIGGER for BaseTrialExperiment', type=str)
while not config.check_if_default_exists(input_value, 'TRIGGER'):
click.echo(f'TRIGGER {input_value} does not exists.')
input_value = click.prompt(f'Enter a base TRIGGER module', type=str)

input_dict['TRIAL_TRIGGER'] = input_value
click.echo(f'TRIAL_TRIGGER for BaseTrialExperiment set to {input_value}.')

"""TRIGGER"""

input_value = get_input('TRIGGER')
input_dict['TRIGGER'] = input_value


"""Process"""

if input_dict['PROCESS'] is None:
input_value = get_input('PROCESS')
input_dict['PROCESS'] = input_value

"""STIMULATION"""
if input_dict['STIMULATION'] is None:
input_value = get_input('STIMULATION')
input_dict['STIMULATION'] = input_value

"""Setting Process Type"""

if input_dict['EXPERIMENT'] == 'BaseTrialExperiment':
input_dict['PROCESS_TYPE'] = 'trial'
elif input_dict['STIMULATION'] == 'BaseStimulation':
input_dict['PROCESS_TYPE'] = 'switch'
elif input_dict['STIMULATION'] == 'ScreenStimulation' or input_dict['STIMULATION'] == 'RewardDispenser':
input_dict['PROCESS_TYPE'] = 'supply'


if input_dict['EXPERIMENT'] == 'BaseTrialExperiment':
config.import_default(experiment_name=input_dict['EXPERIMENT'], trigger_name=input_dict['TRIGGER'],
process_name=input_dict['PROCESS'], stimulation_name=input_dict['STIMULATION'],
trial_trigger_name=input_dict['TRIAL_TRIGGER'])

else:
config.import_default(experiment_name=input_dict['EXPERIMENT'], trigger_name=input_dict['TRIGGER'],
process_name=input_dict['PROCESS'], stimulation_name=input_dict['STIMULATION'])

if 'PROCESS_TYPE' in input_dict.keys():
config._change_parameter(module_name=input_dict['PROCESS'],parameter_name='TYPE',
parameter_value=input_dict['PROCESS_TYPE'])


if click.confirm('Do you want to set parameters as well (Not recommended)? \n Note, that you can change them in the created file later.'):
current_config = config.get_current_config()
ignore_list = ['EXPERIMENT', 'BaseProtocolProcess']
inner_ignore_list = ['EXPERIMENTER', 'PROCESS', 'STIMULATION', 'TRIGGER', 'DEBUG']
try:
for module in current_config.keys():
parameter_dict = config.get_parameters(module)
if module not in ignore_list:
for input_key in parameter_dict.keys():
if input_key not in inner_ignore_list:
click.echo(f'Default {input_key} is: ' + str(parameter_dict[input_key]))
input_value = click.prompt(f'Enter new value: ',type=str)
config._change_parameter(module_name=module,parameter_name=input_key,
parameter_value=input_value)
except:
click.echo('Failed to set individual parameters. Please change them later in the config file...')
else:
click.echo('Skipping parameters. Experiment config will be created with default values...')
"""Finish up"""
# Name of experimentor
experimenter = click.prompt('Enter an experimenter name',type=str)
click.echo(f'Experimenter set to {experimenter}.')
config.set_experimenter(experimenter)

click.echo('Current modules are:\n BaseExperiment: {}\n Trigger: {}\n Process: {} \n Stimulation: {}'.format(
input_dict['EXPERIMENT'],
input_dict['TRIGGER'],
input_dict['PROCESS'],
input_dict['STIMULATION']))


if click.confirm('Do you want to continue?'):
config.write_ini()
click.echo('Config was created. It can be found in experiments/configs')


if __name__ == '__main__':
design_experiment()
Binary file added docs/design_experiment_gif.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file added experiments/base/__init__.py
Empty file.
Loading

0 comments on commit e53cfa0

Please sign in to comment.