Exemplo n.º 1
0
def create_subject(project_name,
                   subject_name: str = "_iblrig_test_mouse",
                   force=False):
    project_name = alyx2local_names.get(project_name, project_name)
    project_path = IBLRIG_PARAMS_FOLDER / project_name
    p = Project()
    print(f"Loading [{project_path}]")
    p.load(project_path)
    subject = p.find_subject(subject_name)
    if force or subject is None:
        subject = p.create_subject()
        subject.name = subject_name
        p.save(project_path)
        print(f"  Created subject: [{subject_name}]")
    # Create default subjects for project {project_name} if they don't exist
    if p.find_subject("_iblrig_test_mouse") is None:
        create_subject(project_name,
                       subject_name="_iblrig_test_mouse",
                       force=True)
    if p.find_subject("_iblrig_calibration") is None:
        create_subject(project_name,
                       subject_name="_iblrig_calibration",
                       force=True)

    return subject
Exemplo n.º 2
0
def create_experiment_setups(iblproject_path, exp_name: str):
    p = Project()
    p.load(iblproject_path)
    exp = [e for e in p.experiments if e.name == exp_name]
    if not exp:
        print(f'Experiment {exp} not found')
        raise KeyError
    else:
        exp = exp[0]

    if exp.name == '_iblrig_calibration':
        screen = create_setup(exp, 'screen', p.boards[0].name,
                              exp.name)  # noqa
        water = create_setup(exp, 'water', p.boards[0].name, exp.name)  # noqa

    if exp.name == '_iblrig_misc':
        flush_water = create_setup(  # noqa
            exp, 'flush_water', p.boards[0].name, '_iblrig_test_mouse')

    if exp.name == '_iblrig_tasks':
        biasedChoiceWorld = create_setup(  # noqa
            exp, 'biasedChoiceWorld', p.boards[0].name, None)
        habituationChoiceWorld = create_setup(  # noqa
            exp, 'habituationChoiceWorld', p.boards[0].name, None)
        trainingChoiceWorld = create_setup(  # noqa
            exp, 'trainingChoiceWorld', p.boards[0].name, None)
        ephysChoiceWorld = create_setup(  # noqa
            exp, 'ephysChoiceWorld', p.boards[0].name, None)

    p.save(iblproject_path)
Exemplo n.º 3
0
def config_task(iblproject_path, task_name: str):
    p = Project()
    p.load(iblproject_path)
    task = p.find_task(task_name)
    print(f"  Configuring task <{task.name}>")
    task._commands = []

    if task.name == '_iblrig_calibration_screen':
        task = create_task_bonsai_stop_command(task, port=7110)
        task = create_task_cleanup_command(task)
    if task.name == '_iblrig_calibration_water':
        task = create_task_cleanup_command(task)
    if task.name == '_iblrig_misc_flush_water':
        task = create_task_cleanup_command(task)
    # For all of tasks stop the stim 7110, stop the recording 7111 and cleanup
    if '_iblrig_tasks' in task.name:
        task = create_task_bonsai_stop_command(task, port=7110)
        task = create_task_bonsai_stop_command(task, port=7111)
        task = create_task_cleanup_command(task)
        task = create_task_bpod_lights_command(task, onoff=1, when='POST')
    if task.name == '_iblrig_tasks_habituationChoiceWorld':
        task = create_task_create_command(task, patch=True)
    if task.name == '_iblrig_tasks_trainingChoiceWorld':
        task = create_task_create_command(task, patch=True)
    if task.name == '_iblrig_tasks_biasedChoiceWorld':
        task = create_task_create_command(task, patch=False)
    if task.name == '_iblrig_tasks_ephysChoiceWorld':
        task = create_task_create_command(task, patch=False)

    p.save(iblproject_path)
    print("    Task configured")
Exemplo n.º 4
0
def create_experiment_setups(iblproject_path, exp_name: str):  # XXX:THIS!
    p = Project()
    p.load(iblproject_path)
    exp = [e for e in p.experiments if e.name == exp_name]
    calib_subj = [s for s in p.subjects if s.name == "_iblrig_calibration"][0]
    test_subj = [s for s in p.subjects if s.name == "_iblrig_test_mouse"][0]
    if not exp:
        raise KeyError(f"Experiment {exp} not found")
    else:
        exp = exp[0]

    if exp.name == "_iblrig_calibration":
        screen = create_setup(exp, "screen", p.boards[0].name, calib_subj)  # noqa
        water = create_setup(exp, "water", p.boards[0].name, calib_subj)  # noqa
        input_listner = create_setup(  # noqa
            exp, "input_listner", p.boards[0].name, calib_subj
        )
        frame2TTL = create_setup(exp, "frame2TTL", p.boards[0].name, calib_subj)  # noqa

    if exp.name == "_iblrig_misc":
        flush_water = create_setup(  # noqa
            exp, "flush_water", p.boards[0].name, test_subj
        )
        bpod_ttl_test = create_setup(  # noqa
            exp, "bpod_ttl_test", p.boards[0].name, test_subj
        )
        frame2TTL_freq_test = create_setup(  # noqa
            exp, "frame2TTL_freq_test", p.boards[0].name, test_subj
        )

    if exp.name == "_iblrig_tasks":
        biasedChoiceWorld = create_setup(  # noqa
            exp, "biasedChoiceWorld", p.boards[0].name, None
        )
        habituationChoiceWorld = create_setup(  # noqa
            exp, "habituationChoiceWorld", p.boards[0].name, None
        )
        trainingChoiceWorld = create_setup(  # noqa
            exp, "trainingChoiceWorld", p.boards[0].name, None
        )
        ephys_certification = create_setup(  # noqa
            exp, "ephys_certification", p.boards[0].name, None
        )
        ephysChoiceWorld = create_setup(  # noqa
            exp,
            "ephysChoiceWorld_testing",
            p.boards[0].name,
            test_subj,
            task="_iblrig_tasks_ephysChoiceWorld",
        )
        passiveChoiceWorld = create_setup(  # noqa
            exp,
            "passiveChoiceWorld_testing",
            p.boards[0].name,
            test_subj,
            task="_iblrig_tasks_passiveChoiceWorld",
        )

    p.save(iblproject_path)
Exemplo n.º 5
0
def create_subject(iblproject_path, subject_name: str):
    p = Project()
    p.load(iblproject_path)
    # if p.find_subject(subject_name) is None:
    subject = p.create_subject()
    subject.name = subject_name
    p.save(iblproject_path)
    print(f"  Created subject: {subject_name}")
Exemplo n.º 6
0
def config_task(iblproject_path, task_name: str):  # XXX: THIS!
    p = Project()
    p.load(iblproject_path)
    task = p.find_task(task_name)
    print(f"  Configuring task <{task.name}>")
    task._commands = []

    if task.name == "_iblrig_calibration_screen":
        task = create_task_bonsai_stop_command(task, port=7110)
        task = create_task_cleanup_command(task)
    if task.name == "_iblrig_calibration_water":
        task = create_task_cleanup_command(task)
    if task.name == "_iblrig_calibration_input_listner":
        task = create_task_cleanup_command(task)
    if task.name == "_iblrig_calibration_frame2TTL":
        task = create_task_cleanup_command(task)
    if task.name == "_iblrig_misc_flush_water":
        task = create_task_cleanup_command(task)
    if task.name == "_iblrig_misc_bpod_ttl_test":
        task = create_task_bonsai_stop_command(task, port=7110)
        task = create_task_cleanup_command(task)
    if task.name == "_iblrig_misc_frame2TTL_freq_test":
        task = create_task_cleanup_command(task)
    # For all bpod tasks turn off bpod lights, stop the stim 7110, stop the camera 7111 and cleanup
    btasks = [
        "_iblrig_tasks_habituationChoiceWorld",
        "_iblrig_tasks_trainingChoiceWorld",
        "_iblrig_tasks_biasedChoiceWorld",
        "_iblrig_tasks_ephysChoiceWorld",
    ]
    if task.name in btasks:
        task = create_task_bonsai_stop_command(task, port=7110)  # visual stimulus
        task = create_task_bonsai_stop_command(task, port=7111)  # camera recording
        task = create_task_cleanup_command(task)
        task = create_task_bpod_lights_command(task, 1, when="POST")
    if task.name == "_iblrig_tasks_habituationChoiceWorld":
        task = create_task_create_command(task, poop=True)
    if task.name == "_iblrig_tasks_trainingChoiceWorld":
        task = create_task_create_command(task, poop=True)
    if task.name == "_iblrig_tasks_biasedChoiceWorld":
        task = create_task_create_command(task, poop=False)
    if task.name == "_iblrig_tasks_ephysChoiceWorld":
        task = create_task_create_command(task, poop=False)
    if task.name == "_iblrig_tasks_ephys_certification":
        task = create_task_cleanup_command(task)
        task = create_task_bpod_lights_command(task, 0, when="PRE")
        task = create_task_bpod_lights_command(task, 1, when="POST")
    if task.name == "_iblrig_tasks_passiveChoiceWorld":
        task = create_task_cleanup_command(task)
        task = create_task_poop_command(task, when="POST")
        task = create_task_bonsai_stop_command(task, port=7110)  # stim
        task = create_task_bonsai_stop_command(task, port=7112)  # record_mic
        task = create_task_bpod_lights_command(task, 0, when="PRE")
        task = create_task_bpod_lights_command(task, 1, when="POST")
        task = create_task_move_passive_command(task, when="POST")

    p.save(iblproject_path)
    print("    Task configured")
Exemplo n.º 7
0
def create_experiment(iblproject_path, exp_name: str):
    p = Project()
    p.load(iblproject_path)
    exp = [e for e in p.experiments if e.name == exp_name]
    # if not exp:
    exp = p.create_experiment()
    exp.name = exp_name
    p.save(iblproject_path)
    print(f"Created experiment: {exp.name}")
Exemplo n.º 8
0
def create_task(iblproject_path, task_name: str):
    p = Project()
    p.load(iblproject_path)
    task = p.find_task(task_name)
    # if task is None:
    task = p.create_task()
    task.name = task_name
    p.save(iblproject_path)
    print(f"Created task: {task_name}")
Exemplo n.º 9
0
def create_ibl_project(iblproject_path):
    p = Project()
    try:
        p.load(iblproject_path)
        print(f"Skipping creation: IBL project found <{iblproject_path}>")
    except:  # noqa
        p.name = 'IBL'
        p.save(iblproject_path)
        print("Created: IBL project")
def config_task(iblproject_path, task_name: str):  # XXX: THIS!
    p = Project()
    p.load(iblproject_path)
    task = p.find_task(task_name)
    print(f"  Configuring task <{task.name}>")
    task._commands = []

    if task.name == '_iblrig_calibration_screen':
        task = create_task_bonsai_stop_command(task, port=7110)
        task = create_task_cleanup_command(task)
    if task.name == '_iblrig_calibration_water':
        task = create_task_cleanup_command(task)
    if task.name == '_iblrig_calibration_input_listner':
        task = create_task_cleanup_command(task)
    if task.name == '_iblrig_calibration_frame2TTL':
        task = create_task_cleanup_command(task)
    if task.name == '_iblrig_misc_flush_water':
        task = create_task_cleanup_command(task)
    if task.name == '_iblrig_misc_bpod_ttl_test':
        task = create_task_bonsai_stop_command(task, port=7110)
        task = create_task_cleanup_command(task)
    if task.name == '_iblrig_misc_frame2TTL_freq_test':
        task = create_task_cleanup_command(task)
    # For all bpod tasks turn off bpod lights, stop the stim 7110, stop the camera 7111 and cleanup
    btasks = [
        '_iblrig_tasks_habituationChoiceWorld',
        '_iblrig_tasks_trainingChoiceWorld',
        '_iblrig_tasks_biasedChoiceWorld',
        '_iblrig_tasks_ephysChoiceWorld',
    ]
    if task.name in btasks:
        task = create_task_bonsai_stop_command(task, port=7110)
        task = create_task_bonsai_stop_command(task, port=7111)
        task = create_task_cleanup_command(task)
        task = create_task_bpod_lights_command(task, onoff=1, when='POST')
    if task.name == '_iblrig_tasks_habituationChoiceWorld':
        task = create_task_create_command(task, poop=True)
    if task.name == '_iblrig_tasks_trainingChoiceWorld':
        task = create_task_create_command(task, poop=True)
    if task.name == '_iblrig_tasks_biasedChoiceWorld':
        task = create_task_create_command(task, poop=False)
    if task.name == '_iblrig_tasks_ephysChoiceWorld':
        task = create_task_create_command(task, poop=False)
    if task.name == '_iblrig_tasks_ephys_certification':
        task = create_task_cleanup_command(task)
        task = create_task_bpod_lights_command(task, onoff=0, when='PRE')
        task = create_task_bpod_lights_command(task, onoff=1, when='POST')
    if task.name == '_iblrig_tasks_passiveChoiceWorld':
        task = create_task_cleanup_command(task)
        task = create_task_poop_command(task, when='POST')
        task = create_task_bpod_lights_command(task, onoff=0, when='PRE')
        task = create_task_bpod_lights_command(task, onoff=1, when='POST')
        task = create_task_move_passive_command(task, when='POST')

    p.save(iblproject_path)
    print("    Task configured")
Exemplo n.º 11
0
def create_ibl_project(iblproject_path):
    p = Project()
    print("Creating IBL project")
    try:
        p.load(iblproject_path)
        print(f"  Skipping creation: IBL project found in: {iblproject_path}")
    except:  # noqa
        p.name = "IBL"
        p.save(iblproject_path)
        print("  Created: IBL project")
Exemplo n.º 12
0
def create_subject(iblproject_path, subject_name: str):
    p = Project()
    p.load(iblproject_path)
    if p.find_subject(subject_name) is None:
        subject = p.create_subject()
        subject.name = subject_name
        p.save(iblproject_path)
        print(f"Created subject: {subject_name}")
    else:
        subject = p.find_subject(subject_name)
        print(f"Skipping creation: Subject <{subject.name}> already exists")
Exemplo n.º 13
0
def create_ibl_users(iblproject_path):
    p = Project()
    p.load(iblproject_path)
    if p.find_user('_iblrig_test_user') is None:
        user = p.create_user()
        user.name = '_iblrig_test_user'
        p.save(iblproject_path)
        print(f"Created: IBL default user <{user.name}>")
    else:
        user = p.find_user('_iblrig_test_user')
        print(f"Skipping creation: User <{user.name}> already exists")
Exemplo n.º 14
0
def create_ibl_board(iblproject_path):
    p = Project()
    p.load(iblproject_path)
    if not p.boards:
        BOARD_NAME = 'SELECT_BOARD_NAME_(e.g.[_iblrig_mainenlab_behavior_0])'
        b = p.create_board()
        b.name = BOARD_NAME
        p.save(iblproject_path)
        print("Created: IBL default board (please remember to rename it)")
    else:
        print(f"Skipping creation: Board found with name <{p.boards[0].name}>")
Exemplo n.º 15
0
def create_task(iblproject_path, task_name: str):
    p = Project()
    p.load(iblproject_path)
    task = p.find_task(task_name)
    if task is None:
        task = p.create_task()
        task.name = task_name
        p.save(iblproject_path)
        print(f"Created task: {task_name}")
    else:
        print(f"Skipping creation: Task {task.name} already exists")
Exemplo n.º 16
0
def create_experiment(iblproject_path, exp_name: str):
    p = Project()
    p.load(iblproject_path)
    exp = [e for e in p.experiments if e.name == exp_name]
    if not exp:
        exp = p.create_experiment()
        exp.name = exp_name
        p.save(iblproject_path)
        print(f"Created experiment: {exp.name}")
    else:
        exp = exp[0]
        print(f"Skipping creation: Experiment {exp.name} already exists")
def create_experiment_setups(iblproject_path, exp_name: str):  # XXX:THIS!
    p = Project()
    p.load(iblproject_path)
    exp = [e for e in p.experiments if e.name == exp_name]
    calib_subj = [s for s in p.subjects if s.name == '_iblrig_calibration'][0]
    test_subj = [s for s in p.subjects if s.name == '_iblrig_test_mouse'][0]
    if not exp:
        raise KeyError(f'Experiment {exp} not found')
    else:
        exp = exp[0]

    if exp.name == '_iblrig_calibration':
        screen = create_setup(exp, 'screen', p.boards[0].name,
                              calib_subj)  # noqa
        water = create_setup(exp, 'water', p.boards[0].name,
                             calib_subj)  # noqa
        input_listner = create_setup(exp, 'input_listner', p.boards[0].name,
                                     calib_subj)  # noqa
        frame2TTL = create_setup(exp, 'frame2TTL', p.boards[0].name,
                                 calib_subj)  # noqa

    if exp.name == '_iblrig_misc':
        flush_water = create_setup(  # noqa
            exp, 'flush_water', p.boards[0].name, test_subj)
        bpod_ttl_test = create_setup(  # noqa
            exp, 'bpod_ttl_test', p.boards[0].name, test_subj)
        frame2TTL_freq_test = create_setup(  # noqa
            exp, 'frame2TTL_freq_test', p.boards[0].name, test_subj)

    if exp.name == '_iblrig_tasks':
        biasedChoiceWorld = create_setup(  # noqa
            exp, 'biasedChoiceWorld', p.boards[0].name, None)
        habituationChoiceWorld = create_setup(  # noqa
            exp, 'habituationChoiceWorld', p.boards[0].name, None)
        trainingChoiceWorld = create_setup(  # noqa
            exp, 'trainingChoiceWorld', p.boards[0].name, None)
        ephys_certification = create_setup(  # noqa
            exp, 'ephys_certification', p.boards[0].name, None)
        ephysChoiceWorld = create_setup(  # noqa
            exp,
            'ephysChoiceWorld_testing',
            p.boards[0].name,
            test_subj,
            task='_iblrig_tasks_ephysChoiceWorld')
        passiveChoiceWorld = create_setup(  # noqa
            exp,
            'passiveChoiceWorld_testing',
            p.boards[0].name,
            test_subj,
            task='_iblrig_tasks_passiveChoiceWorld')

    p.save(iblproject_path)
Exemplo n.º 18
0
def create_project(project_name, force=False):
    project_name = alyx2local_names.get(project_name, project_name)
    project_path = IBLRIG_PARAMS_FOLDER / project_name
    p = Project()
    if force or not pybpod_project_exists(project_name):
        p.name = project_name
        p.save(project_path)
        print(f"  Project created: [{project_name}]")
    else:
        print(
            f"  Skipping creation: project [{project_name}] found in: [{project_path}]"
        )
        p = Project()
        p.load(project_path)
    return p
Exemplo n.º 19
0
def setups_to_remove(iblproject_path):
    p = Project()
    p.load(iblproject_path)
    exp = [e for e in p.experiments if e.name == "_iblrig_calibration"]
    if not exp:
        raise KeyError(f"Experiment {exp} not found")
    else:
        exp = exp[0]
        setup = [s for s in exp.setups if s.name == "screen"]
        if not setup:
            print(f"Setup {setup} not found")
        else:
            setup = setup[0]
            print()
            exp -= setup
            p.save(iblproject_path)
Exemplo n.º 20
0
def create_board_from_main_project_to(project_name, force=False):
    project_name = alyx2local_names.get(project_name, project_name)
    if project_name == "IBL":
        print("Can't create board of main project")
        return
    project_path = IBLRIG_PARAMS_FOLDER / project_name
    iblproj = Project()
    iblproj.load(IBLRIG_PARAMS_FOLDER / "IBL")
    print("Looking for boards in default project")
    if not iblproj.boards or len(iblproj.boards) > 1:
        print(
            f"0 or 2+ boards found in main project: {[x.name for x in iblproj.boards]}"
        )
        return

    bname = iblproj.boards[0].name
    print("Board found: [{}]".format(bname))
    p = Project()
    if not pybpod_project_exists(project_name):
        return

    print(f"Loading [{project_path}]")
    p.load(project_path)
    if force or not p.boards:
        board = p.create_board()
        board.name = iblproj.boards[0].name
        p.save(project_path)
        print(f"  Created board: [{board.name}] in project [{project_name}]")
    elif len(p.boards) > 1:
        print(
            f"  Skipping creation: project [{project_name}] already has [{len(p.boards)}] boards"
        )
    elif len(p.boards) == 1:
        bname = p.boards[0].name
        print(
            f"  Skipping creation: Board [{bname}] already exists in project [{project_name}]"
        )

    return
Exemplo n.º 21
0
def create_user(project_name, username="******", force=False):
    project_name = alyx2local_names.get(project_name, project_name)
    project_path = IBLRIG_PARAMS_FOLDER / project_name
    p = Project()
    print(f"Loading [{project_path}]")
    if not pybpod_project_exists(project_name):
        return

    p.load(project_path)
    if force or p.find_user(username) is None:
        user = p.create_user()
        user.name = username
        p.save(project_path)
        print(f"  Created user: [{user.name}] in project [{project_name}]")
    else:
        user = p.find_user(username)
        print(
            f"  Skipping creation: User [{user.name}] already exists in project [{project_name}]"
        )

    if p.find_user("_iblrig_test_user") is None:
        create_user(project_name, username="******", force=True)

    return user
Exemplo n.º 22
0
 def save(self, project_path=None):
     if project_path:
         Project.save(self, project_path)
     elif self.path:
         Project.save(self, self.path)
     else:
         folder = QFileDialog.getExistingDirectory(
             self, "Select a directory to save the project: {0}".format(
                 self.name))
         if folder:
             folder = os.path.join(folder, self.name)
             try:
                 Project.save(self, str(folder))
             except FileExistsError as err:
                 logger.warning(str(err))
                 QMessageBox.warning(
                     self, 'Project exists',
                     'Project with same name already exists. Please select another path.'
                 )
Exemplo n.º 23
0
# add a setup to the project
stp = exp.create_setup()
stp.name = 'First setup'

# add a board to the project
board = proj.create_board()
board.name = 'First board'
board.serial_port = 'COM3'

# add subjects to the project
subj = proj.create_subject()
subj.name = 'First animal'

subj2 = proj.create_subject()
subj2.name = 'Second animal'

# add a new task\protocol to the project
task = proj.create_task()
task.name = 'First task'

exp.task = task         # set the task\protocol to the experiment
stp.board = board       # set the board to the setup
stp += [subj, subj2]    # add a subject to the setup

proj.save('my-project-folder')

task.code = 'print("My first protocol")'

proj.save(proj.path)
Exemplo n.º 24
0
class pybpod_helper():
    def __init__(self, root_path, project_path):
        self.root_path = root_path
        self.project_path = project_path
        self.project = Project()
        self.hostname = os.environ['COMPUTERNAME']

    def populate_project_folder(self):
        """copy all the necessary files for the bpod setup to the folder of this setup"""
        # create project
        self.create_project()
        # boards
        print("Creating: Bpod board")
        board = self.create_board()

        # create project.json files
        user, subject = self.create_defaults()

        # tasks
        # gambl task
        exp_gamble = self.create_experiment("gamble_task")
        #   training
        task_name = 'gamble_task_training'
        self.create_task(task_name)
        self.create_setup(exp_gamble, task_name, board, subject)
        #   recording
        task_name = 'gamble_task_recording'
        self.create_task(task_name)
        self.create_setup(exp_gamble, task_name, board, subject)
        # choice task
        # self.create_experiment("choice_task")
        #   habituation
        #   training
        #   recording

        # calibration, administer reward etc
        self.create_experiment("calibration_etc")

        print("Creating: default usersettings, user, and subject")
        self.create_defaults()
        # create project.json files

    # helper functions for task folder createion =======================================

    def create_task(self, task_name):
        """copy files for given task to poject dir

        Args:
            task_name (str): name of the task
        """
        print(f"Creating {task_name} setup")
        task = self.project.find_task(task_name)
        if task != None:
            print(
                f"Found task config file in {str(self.project_path)}/{str(task_name)}",
                "\nDo you want to overwrite config? (y/n)",
            )
            user_input = input()
            if user_input == "n":
                return
            elif user_input == "y":
                # copy files to new task
                src = self.root_path / "tasks" / task_name
                dest = self.project_path / "tasks" / task_name
                task = self.project.create_task()
                task.name = task_name
                self.project.save(self.project_path)
                self.copytree(src, dest)
                print(f"Created task: {task_name}")
        else:
            # copy files to new task
            src = self.root_path / "tasks" / task_name
            dest = self.project_path / "tasks" / task_name
            task = self.project.create_task()
            task.name = task_name
            self.project.save(self.project_path)
            self.copytree(src, dest)
            print(f"Created task: {task_name}")

    def create_board(self):
        """create new bpod board for new setup

        Returns:
            bpod.board:
        """
        if not self.project.boards:
            # copy files to new board
            board = self.project.create_board()
            board.name = ("board_" + self.hostname)
            self.project.save(self.project_path)
            print("Created borad")
        else:
            print("Board already exists")
            board = self.project.boards[0].name
        return board

    def create_experiment(self, exp_name):
        """create new experiment for setup

        Args:
            exp_name (str): name of the experiment to create

        Returns:
            bpod.experiment:
        """
        exp = self.project.create_experiment()
        exp.name = exp_name
        self.project.save(self.project_path)
        print(f"Created experiment: {exp.name}")
        return exp

    def create_setup(self, experiment, setup_name, board, subject):
        """create new setup for setup

        Args:
            experiment (bpod.experiment): experminet under which the setup is created
            setup_name (str): name of the setup
            board (bpod.board): board which will be added as default to the setup
            subject (bpod.subject): subject which will be added as default to the setup
        """
        # create experiment
        setup = experiment.create_setup()
        setup.name = setup_name
        setup.task = setup_name
        setup + subject
        setup.detached = True
        self.project.save(self.project_path)

    def create_defaults(self):
        """routine to create default elements for new bpod setup
                user: create new default user - test_user
                subject: create new default subject - test_subject

        Returns:
            bpod.user:
            bpod.subject:
        """
        # copy usersettings
        src = self.root_path / ("scripts/user_settings.py")
        dest = self.project_path / "user_settings.py"
        shutil.copy(src, dest)
        # add default prject to user settings
        with open(dest, 'a') as f:
            f.write(f"\nDEFAULT_PROJECT_PATH = \"{self.project_path}\"\n")
        # create default user
        if self.project.find_user("test_user") is None:
            user = self.project.create_user()
            user.name = "test_user"
            self.project.save(self.project_path)
            print(f"  Created: default user {user.name}")
        else:
            user = self.project.find_user("test_user")
            print(f"  Skipping creation: User {user.name} already exists")
        # create default subject
        subject_name = "test_subject"
        subject = self.project.find_subject(subject_name)
        if subject is None:
            subject = self.project.create_subject()
            subject.name = subject_name
            self.project.save(self.project_path)
            print(f"  Created subject: {subject_name}")
        else:
            print(
                f"Skipping creation: Subject <{subject.name}> already exists")
        return user, subject

    def create_project(self):
        """create maxland project for new setup"""
        print("Creating default project")
        try:
            self.project.load(self.project_path)
            print(
                f"  Skipping creation: maxland project found in: {self.project_path}"
            )
        except:  # noqa
            self.project.name = ("maxland_" + self.hostname)
            self.project.save(self.project_path)
            print(f"Created: project maxland_{self.hostname}")

    def copytree(self, src, dst, symlinks=False, ignore=None):
        """helper function to copy all files from one directory to another

        Args:
            src (os.path): path to source folder
            dst (os.path): path to destination folder
            symlinks (bool, optional): dont copy but use symbolic links to original files. Defaults to False.
            ignore (list, optional): ignore items in source. Defaults to None.
        """
        for item in os.listdir(src):
            s = os.path.join(src, item)
            d = os.path.join(dst, item)
            if os.path.isdir(s):
                copytree(s, d, symlinks, ignore)
            elif item in os.listdir(dst):
                os.remove(d)
                shutil.copy2(s, d)
            else:
                shutil.copy2(s, d)