Пример #1
0
def measure(node: MetrolabTHM1176Node,
            N=10,
            max_num_retrials=5,
            average=False):
    """
    Measures the magnetic field with the Metrolab sensor. Returns either raw measured values of field components (x, y, z)
    or mean and standard deviation in each direction.

    Args:
        node (MetrolabTHM1176Node): represents the Metrolab THM 1176 sensor
        N (int, optional): number of data points collected for each average. Defaults to 10.
        max_num_retrials (int, optional): How many times to reattempt measurement before raising an exception. Defaults to 5.
        average (bool, optional): Average over the N measurements. Defaults to False.

    Raises:
        MeasurementError: a problem occured during measurement.

    Returns:
        tuple of 2 np.array(3): This is returned if average is true. mean and std of the three field componenents over N measurements.
        tuple (np.ndarray((N,3)), 0): This is returned if average is false. N measured values of each component are contained. Second return is 0.
    """
    # if dataDir is not None:
    #     ensure_dir_exists(dataDir, verbose=False)

    # perform measurement and collect the raw data
    for _ in range(max_num_retrials):
        try:
            # an N by 3 array
            meas_data = np.array(node.measureFieldArraymT(N)).swapaxes(0, 1)
        except BaseException:
            pass
        else:
            break

    try:
        # due to the setup, transform sensor coordinates to magnet coordinates
        meas_data = sensor_to_magnet_coordinates(meas_data)
    # if it was not possible to obtain valid measurement results after
    # max_num_retrials, raise MeasurementError, too
    except BaseException:
        raise MeasurementException()

    if average:
        # compute the mean and std from raw data for each sensor
        mean_data = np.mean(meas_data, axis=0)
        std_data = np.std(meas_data, axis=0)
        ret1, ret2 = mean_data, std_data
    else:
        # This option is more for getting time-field measurements.
        ret1, ret2 = meas_data, 0

    return ret1, ret2
def get_mean_dataset_MetrolabSensor(node: MetrolabTHM1176Node,
                                    sampling_size,
                                    verbose=False,
                                    max_num_retrials=5):
    """
    Estimate field vectors with Metrolab sensor sampling_size-times and return the mean and std 
    as 1d-ndarrays of length 3. 

    Args: 
    - node (MetrolabTHM1176Node): represents the Metrolab THM 1176 sensor
    - sampling_size (int): sampling size to estimate mean magnetic field vector and std, 
    i.e. number of times the sensor is read out in series before averaging 
    - verbose (bool): switching on/off print-statements for displaying progress

    Return: 
    - mean_data, std_data (ndarrays of of shape (number sensors, 3)): Mean magnetic field and 
    its standard deviation as a vector. 

    Raises MeasurementError if no valid measurement data could be aquired after max_num_retrials tries. 
    """
    # perform measurement and collect the raw data
    for _ in range(max_num_retrials):
        try:
            meas_data = np.array(
                node.measureFieldArraymT(sampling_size)).swapaxes(0, 1)
        except:
            pass
        else:
            break

    try:
        # due to the setup, transform sensor coordinates to magnet coordinates
        meas_data = sensor_to_magnet_coordinates(meas_data)

    # if it was not possible to obtain valid measurement results after max_num_retrials, raise MeasurementError, too
    except UnboundLocalError:
        raise MeasurementError

    # estimate the mean and std from raw data for each sensor
    mean_data = np.mean(meas_data, axis=0)
    std_data = np.std(meas_data, axis=0)

    # # save raw data if desired
    # if save_mean_data:
    #     # if no directory is provided, just take current working directory
    #     if directory is None:
    #         directory = os.getcwd()
    #     save_in_dir(meas_data, directory, 'data', now=True)

    # return mean and std fields either for only this sensor or for all sensors
    return mean_data, std_data
def readoutMetrolabSensor(node: MetrolabTHM1176Node,
                          measure_runs=1,
                          fname_postfix='data_sets',
                          directory='./data_sets',
                          verbose=False,
                          save_data=True):
    """
    Read measurement outcomes of Metrolab THM1176 sensor and return the estimated B-field [mT] in magnet coordinates, 
    also save data if desired.

    Magnet coordinates: coil 2 is mounted along -y axis.

    Args:
    - node (MetrolabTHM1176Node): represents the Metrolab THM 1176 sensor
    - measure_runs (int): Number of samples per fuction call per sensor
    - save_data (bool): if True, the results are stored in a csv-file
    - directory (string): valid path of the folder where data should be stored. The default name of the data file is
    'yy_mm_dd_hh-mm-ss_{fname_postfix}.csv'
    - fname_postfix (string): postfix of data file (csv).

    Return:
    - meas_time (ndarray of length=measure_runs): Contains the time of each measurement relative 
    to start of measurements 
    - meas_data (ndarray of shape=(measure_runs, 3)): Contains the measured field components

    Exceptions: 
    Raise a MeasurementError if something went wrong during measurements. 
    Possible reasons are that a sensor was skipped or that an incomplete message was received from the sensor. 

    """
    if measure_runs == 1:
        # initialize ndarray to store the measurement data and time
        meas_data = np.zeros(3)
        meas_time = 0

        # get current time before starting
        t_start = time()

        # read the current output of sensor and save measured magnetic field
        meas_data = np.array(node.measureFieldmT())

        # save the current time
        meas_time = time() - t_start

    elif measure_runs > 1:
        # get current time before starting
        # t_start = time()

        # read the current output of sensor and save measured magnetic field
        meas_data = np.array(node.measureFieldArraymT(measure_runs)).swapaxes(
            0, 1)

        # assume that each measurement took the same time, such that the times of measurements
        # are equally spaced between initial and final time and offset such that t_start = 0
        meas_time = np.linspace(0, time() - t_start, num=len(meas_data))

    else:
        raise ValueError("measure_runs must be >= 1!")

    # due to the setup, transform sensor coordinates to magnet coordinates
    meas_data = sensor_to_magnet_coordinates(meas_data)

    # save data if desired
    if save_data:

        # Measurement Time (s), Sensor Number, X-Axis (mT), Y-Axis (mT), Z-Axis (mT)
        df = pd.DataFrame({
            'Measurement Time (s)': meas_time,
            'Bx [mT]': meas_data[:, 0],
            'By [mT]': meas_data[:, 1],
            'Bz [mT]': meas_data[:, 2]
        })

        if directory is None:
            directory = os.getcwd()
        ensure_dir_exists(directory)

        now = datetime.now().strftime("%y_%m_%d_%H-%M-%S")
        output_file_name = "{}_{}.csv".format(now, fname_postfix)
        data_filepath = os.path.join(directory, output_file_name)

        try:
            df.to_csv(data_filepath, index=False, header=True)
        except FileNotFoundError:
            data_filepath = os.path.join(os.getcwd(), output_file_name)
            df.to_csv(data_filepath, index=False, header=True)

    return meas_time, meas_data