예제 #1
0
def test_DataAnalyzerProcess__processes_change_magnetometer_config_command(
    four_board_analyzer_process_beta_2_mode, ):
    da_process = four_board_analyzer_process_beta_2_mode["da_process"]
    from_main_queue = four_board_analyzer_process_beta_2_mode[
        "from_main_queue"]

    test_num_wells = 24
    expected_wells = [5, 6, 15, 16]
    test_config_dict = create_magnetometer_config_dict(test_num_wells)
    for well_idx in expected_wells:
        module_id = SERIAL_COMM_WELL_IDX_TO_MODULE_ID[well_idx]
        test_config_dict[module_id][3] = True

    expected_sampling_period = 15000
    set_sampling_period_command = {
        "communication_type": "acquisition_manager",
        "command": "change_magnetometer_config",
        "magnetometer_config": test_config_dict,
        "sampling_period": expected_sampling_period,
    }
    put_object_into_queue_and_raise_error_if_eventually_still_empty(
        set_sampling_period_command, from_main_queue)

    invoke_process_run_and_check_errors(da_process)
    assert da_process.get_active_wells() == expected_wells
    expected_buffer_size = MIN_NUM_SECONDS_NEEDED_FOR_ANALYSIS * int(
        1e6 / expected_sampling_period)
    assert da_process.get_buffer_size() == expected_buffer_size
예제 #2
0
def test_get_active_wells_from_config__returns_correct_values():
    test_num_wells = 24
    default_config_dict = create_magnetometer_config_dict(test_num_wells)
    assert get_active_wells_from_config(default_config_dict) == []

    expected_wells = [0, 8, 9, 17]
    test_config_dict = copy.deepcopy(default_config_dict)
    for well_idx in expected_wells:
        module_id = SERIAL_COMM_WELL_IDX_TO_MODULE_ID[well_idx]
        test_config_dict[module_id][0] = True

    assert get_active_wells_from_config(test_config_dict) == expected_wells
예제 #3
0
def create_random_config() -> Dict[int, Dict[int, bool]]:
    random_config_dict: Dict[int,
                             Dict[int,
                                  bool]] = create_magnetometer_config_dict(24)
    num_channels = 0
    for module_dict in random_config_dict.values():
        for cid in module_dict.keys():
            enabled = random_bool()
            num_channels += int(enabled)
            module_dict[cid] = enabled
    # make sure at least one channel is on
    if num_channels == 0:
        random_config_dict[1][0] = True
    return random_config_dict
예제 #4
0
def test_McCommunicationProcess__processes_change_magnetometer_config_command(
    four_board_mc_comm_process_no_handshake,
    mantarray_mc_simulator_no_beacon,
):
    mc_process = four_board_mc_comm_process_no_handshake["mc_process"]
    board_queues = four_board_mc_comm_process_no_handshake["board_queues"]
    simulator = mantarray_mc_simulator_no_beacon["simulator"]
    input_queue = board_queues[0][0]
    output_queue = board_queues[0][1]
    set_connection_and_register_simulator(
        four_board_mc_comm_process_no_handshake, mantarray_mc_simulator_no_beacon
    )
    set_simulator_idle_ready(mantarray_mc_simulator_no_beacon)

    test_num_wells = 24
    # set arbitrary configuration and sampling period
    expected_magnetometer_config = create_magnetometer_config_dict(test_num_wells)
    for key in expected_magnetometer_config[9].keys():
        expected_magnetometer_config[9][key] = True
    expected_sampling_period = 14000
    # send command to mc_process
    expected_response = {
        "communication_type": "acquisition_manager",
        "command": "change_magnetometer_config",
        "magnetometer_config": expected_magnetometer_config,
        "sampling_period": expected_sampling_period,
    }
    put_object_into_queue_and_raise_error_if_eventually_still_empty(
        copy.deepcopy(expected_response), input_queue
    )
    # run mc_process to send command
    invoke_process_run_and_check_errors(mc_process)
    # run simulator to process command and send response
    invoke_process_run_and_check_errors(simulator)
    # assert that sampling period and configuration were updated
    assert simulator.get_sampling_period_us() == expected_sampling_period
    assert simulator.get_magnetometer_config() == expected_magnetometer_config
    # run mc_process to process command response and send message back to main
    invoke_process_run_and_check_errors(mc_process)
    # confirm correct message sent to main
    confirm_queue_is_eventually_of_size(output_queue, 1)
    message_to_main = output_queue.get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    assert message_to_main == expected_response
예제 #5
0
def test_MantarrayMcSimulator__class_attributes():
    assert MantarrayMcSimulator.default_mantarray_nickname == "Mantarray Sim"
    assert MantarrayMcSimulator.default_mantarray_serial_number == "MA2022001000"
    assert MantarrayMcSimulator.default_main_firmware_version == "0.0.0"
    assert MantarrayMcSimulator.default_channel_firmware_version == "0.0.0"
    assert MantarrayMcSimulator.default_barcode == "ML2022001000"
    assert MantarrayMcSimulator.default_metadata_values == {
        BOOT_FLAGS_UUID:
        0b00000000,
        MANTARRAY_SERIAL_NUMBER_UUID:
        MantarrayMcSimulator.default_mantarray_serial_number,
        MANTARRAY_NICKNAME_UUID:
        MantarrayMcSimulator.default_mantarray_nickname,
        MAIN_FIRMWARE_VERSION_UUID:
        MantarrayMcSimulator.default_main_firmware_version,
        CHANNEL_FIRMWARE_VERSION_UUID:
        MantarrayMcSimulator.default_channel_firmware_version,
    }
    assert MantarrayMcSimulator.default_24_well_magnetometer_config == create_magnetometer_config_dict(
        24)
    assert MantarrayMcSimulator.global_timer_offset_secs == 2.5
예제 #6
0
def test_create_magnetometer_config_bytes__returns_correct_values_for_every_module_id(
):
    test_num_wells = 24
    test_dict = create_magnetometer_config_dict(test_num_wells)
    # arbitrarily change values
    for key in test_dict[1].keys():
        test_dict[1][key] = True
    test_dict[2] = convert_bitmask_to_config_dict(0b111000100)
    # create expected bit-masks
    expected_uint16_bitmasks = [0b111111111, 0b111000100]
    expected_uint16_bitmasks.extend([0 for _ in range(test_num_wells - 2)])
    # test actual bytes
    actual = create_magnetometer_config_bytes(test_dict)
    for module_id in range(1, test_num_wells + 1):
        start_idx = (module_id - 1) * 3
        assert actual[
            start_idx] == module_id, f"Incorrect module_id at idx: {module_id}"
        bitmask_bytes = expected_uint16_bitmasks[module_id - 1].to_bytes(
            2, byteorder="little")
        assert (actual[start_idx + 1:start_idx + 3] == bitmask_bytes
                ), f"Incorrect bitmask bytes for module_id: {module_id}"
예제 #7
0
def test_MantarrayProcessesMonitor__passes_magnetometer_config_dict_from_server_to_mc_comm_and__data_analyzer(
        test_process_manager_creator, test_monitor):
    test_process_manager = test_process_manager_creator(
        use_testing_queues=True)
    monitor_thread, *_ = test_monitor(test_process_manager)
    server_to_main_queue = (test_process_manager.queue_container().
                            get_communication_queue_from_server_to_main())
    main_to_ic_queue = test_process_manager.queue_container(
    ).get_communication_to_instrument_comm_queue(0)
    main_to_da_queue = (test_process_manager.queue_container().
                        get_communication_queue_from_main_to_data_analyzer())

    test_num_wells = 24
    expected_sampling_period = 10000
    expected_config_dict = {
        "magnetometer_config": create_magnetometer_config_dict(test_num_wells),
        "sampling_period": expected_sampling_period,
    }
    test_dict_from_server = {
        "communication_type": "set_magnetometer_config",
        "magnetometer_config_dict": expected_config_dict,
    }
    put_object_into_queue_and_raise_error_if_eventually_still_empty(
        test_dict_from_server, server_to_main_queue)
    invoke_process_run_and_check_errors(monitor_thread)
    confirm_queue_is_eventually_of_size(main_to_ic_queue, 1)
    confirm_queue_is_eventually_of_size(main_to_da_queue, 1)

    expected_comm = {
        "communication_type": "acquisition_manager",
        "command": "change_magnetometer_config",
    }
    expected_comm.update(expected_config_dict)
    assert main_to_ic_queue.get(
        timeout=QUEUE_CHECK_TIMEOUT_SECONDS) == expected_comm
    assert main_to_da_queue.get(
        timeout=QUEUE_CHECK_TIMEOUT_SECONDS) == expected_comm
예제 #8
0
def test_DataAnalyzerProcess__data_analysis_stream_is_reconfigured_in_beta_2_mode_upon_receiving_change_magnetometer_config_command(
        four_board_analyzer_process_beta_2_mode, mantarray_mc_simulator,
        mocker):
    da_process = four_board_analyzer_process_beta_2_mode["da_process"]
    da_process.init_streams()

    # mock so waveform data doesn't populate outgoing data queue
    mocker.patch.object(da_process, "_dump_data_into_queue", autospec=True)
    mocker.patch.object(da_process,
                        "_create_outgoing_beta_2_data",
                        autospec=True)
    mocker.patch.object(da_process,
                        "_handle_performance_logging",
                        autospec=True)

    expected_sampling_period_us = 12000
    set_magnetometer_config(
        four_board_analyzer_process_beta_2_mode,
        {
            "magnetometer_config": GENERIC_BOARD_MAGNETOMETER_CONFIGURATION,
            "sampling_period": expected_sampling_period_us,
        },
    )

    da_process = four_board_analyzer_process_beta_2_mode["da_process"]
    board_queues = four_board_analyzer_process_beta_2_mode["board_queues"]
    from_main_queue = four_board_analyzer_process_beta_2_mode[
        "from_main_queue"]
    # make sure data analyzer knows that managed acquisition is running
    put_object_into_queue_and_raise_error_if_eventually_still_empty(
        START_MANAGED_ACQUISITION_COMMUNICATION, from_main_queue)

    single_second_of_data = mantarray_mc_simulator[
        "simulator"].get_interpolated_data(expected_sampling_period_us)

    test_y_data = single_second_of_data.tolist(
    ) * MIN_NUM_SECONDS_NEEDED_FOR_ANALYSIS
    test_x_data = np.arange(0,
                            expected_sampling_period_us * len(test_y_data),
                            expected_sampling_period_us,
                            dtype=np.uint64)

    # send first round of data through will all wells enabled
    test_packet_1 = copy.deepcopy(SIMPLE_BETA_2_CONSTRUCT_DATA_FROM_ALL_WELLS)
    test_packet_1["time_indices"] = test_x_data
    for well_idx in range(24):
        # Tanner (7/14/21): time offsets are currently unused in data analyzer so not modifying them here
        first_channel = list(test_packet_1[well_idx].keys())[1]
        test_packet_1[well_idx][first_channel] = np.array(test_y_data,
                                                          dtype=np.uint16)
    put_object_into_queue_and_raise_error_if_eventually_still_empty(
        test_packet_1, board_queues[0][0])
    invoke_process_run_and_check_errors(da_process)
    confirm_queue_is_eventually_of_size(board_queues[0][1], 1)
    # check all analyzable twitches are reported for each well
    outgoing_msg = board_queues[0][1].get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    outgoing_metrics = json.loads(outgoing_msg["data_json"])
    for well_idx in range(24):
        actual_well_metric_dict = outgoing_metrics[str(well_idx)]
        assert list(actual_well_metric_dict.keys()) == [
            str(AMPLITUDE_UUID),
            str(TWITCH_FREQUENCY_UUID)
        ]
        for metric_id, metric_list in actual_well_metric_dict.items():
            assert (len(metric_list) == MIN_NUM_SECONDS_NEEDED_FOR_ANALYSIS -
                    2), f"Well: {well_idx}, Metric ID: {metric_id}"

    # change magnetometer config so that only wells 20-23 are enabled
    test_config = create_magnetometer_config_dict(24)
    for well_idx in range(20, 24):
        module_id = SERIAL_COMM_WELL_IDX_TO_MODULE_ID[well_idx]
        # enable arbitrary channel
        test_config[module_id][2] = True
    set_magnetometer_config(
        four_board_analyzer_process_beta_2_mode,
        {
            "magnetometer_config": test_config,
            "sampling_period": expected_sampling_period_us
        },
    )

    # send second round of data through will only some wells enabled
    test_packet_2 = copy.deepcopy(SIMPLE_BETA_2_CONSTRUCT_DATA_FROM_ALL_WELLS)
    test_packet_2["time_indices"] = test_x_data
    for well_idx in range(24):
        # Tanner (7/14/21): time offsets are currently unused in data analyzer so not modifying them here
        first_channel = list(test_packet_2[well_idx].keys())[1]
        test_packet_2[well_idx][first_channel] = np.array(test_y_data,
                                                          dtype=np.uint16)
    put_object_into_queue_and_raise_error_if_eventually_still_empty(
        test_packet_2, board_queues[0][0])
    invoke_process_run_and_check_errors(da_process)
    confirm_queue_is_eventually_of_size(board_queues[0][1], 1)
    # check all analyzable twitches are reported only for enabled wells
    outgoing_msg = board_queues[0][1].get(timeout=QUEUE_CHECK_TIMEOUT_SECONDS)
    outgoing_metrics = json.loads(outgoing_msg["data_json"])
    for well_idx in range(24):
        if well_idx < 20:
            assert str(well_idx) not in outgoing_metrics, well_idx
            continue

        actual_well_metric_dict = outgoing_metrics[str(well_idx)]
        assert list(actual_well_metric_dict.keys()) == [
            str(AMPLITUDE_UUID),
            str(TWITCH_FREQUENCY_UUID)
        ]
        for metric_id, metric_list in actual_well_metric_dict.items():
            assert (len(metric_list) == MIN_NUM_SECONDS_NEEDED_FOR_ANALYSIS -
                    2), f"Well: {well_idx}, Metric ID: {metric_id}"