Exemple #1
0
    def compute(self, records_nv, start, end):
        hits = strax.find_hits(records_nv, min_amplitude=self.config['hit_min_amplitude_nv'])
        hits = remove_switched_off_channels(hits, self.to_pe)

        temp_hitlets = strax.create_hitlets_from_hits(hits,
                                                      self.config['save_outside_hits_nv'],
                                                      self.channel_range,
                                                      chunk_start=start,
                                                      chunk_end=end)
        del hits

        # Get hitlet data and split hitlets:
        temp_hitlets = strax.get_hitlets_data(temp_hitlets, records_nv, to_pe=self.to_pe)

        temp_hitlets = strax.split_peaks(temp_hitlets,
                                         records_nv,
                                         self.to_pe,
                                         data_type='hitlets',
                                         algorithm='local_minimum',
                                         min_height=self.config['min_split_nv'],
                                         min_ratio=self.config['min_split_ratio_nv']
                                         )

        # Compute other hitlet properties:
        # We have to loop here 3 times over all hitlets...
        strax.hitlet_properties(temp_hitlets)
        entropy = strax.conditional_entropy(temp_hitlets, template='flat', square_data=False)
        temp_hitlets['entropy'][:] = entropy

        # Remove data field:
        hitlets = np.zeros(len(temp_hitlets), dtype=strax.hitlet_dtype())
        strax.copy_to_buffer(temp_hitlets, hitlets, '_copy_hitlets')
        return hitlets
Exemple #2
0
    def compute(self, records_nv, start, end):
        # Search again for hits in records:
        hits = strax.find_hits(
            records_nv, min_amplitude=self.config['hit_min_amplitude_nv'])

        # Merge concatenate overlapping  within a channel. This is important
        # in case hits were split by record boundaries. In case we
        # accidentally concatenate two PMT signals we split them later again.
        hits = strax.concat_overlapping_hits(
            hits, self.config['save_outside_hits_nv'],
            self.config['channel_map']['nveto'], start, end)
        hits = strax.sort_by_time(hits)

        # Now convert hits into temp_hitlets including the data field:
        if len(hits):
            nsamples = hits['length'].max()
        else:
            nsamples = 0
        temp_hitlets = np.zeros(
            len(hits), strax.hitlet_with_data_dtype(n_samples=nsamples))

        # Generating hitlets and copying relevant information from hits to hitlets.
        # These hitlets are not stored in the end since this array also contains a data
        # field which we will drop later.
        strax.refresh_hit_to_hitlets(hits, temp_hitlets)
        del hits

        # Get hitlet data and split hitlets:
        strax.get_hitlets_data(temp_hitlets, records_nv, to_pe=self.to_pe)

        temp_hitlets = strax.split_peaks(
            temp_hitlets,
            records_nv,
            self.to_pe,
            data_type='hitlets',
            algorithm='local_minimum',
            min_height=self.config['min_split_nv'],
            min_ratio=self.config['min_split_ratio_nv'])

        # Compute other hitlet properties:
        # We have to loop here 3 times over all hitlets...
        strax.hitlet_properties(temp_hitlets)
        entropy = strax.conditional_entropy(temp_hitlets,
                                            template='flat',
                                            square_data=False)
        temp_hitlets['entropy'][:] = entropy
        strax.compute_widths(temp_hitlets)

        # Remove data field:
        hitlets = np.zeros(len(temp_hitlets), dtype=strax.hitlet_dtype())
        drop_data_field(temp_hitlets, hitlets)

        return hitlets
Exemple #3
0
def test_hitlet_properties(hits_n_data):
    """
    Function which tests refresh_hit_to_hitlets, hitlet_with_data_dtype,
    and hitlet_properties.

    :param hits_n_data:
    :return:
    """
    hits, data = hits_n_data

    hits['time'] += 100
    # Step 1.: Produce fake hits and convert them into hitlets:
    nsamples = 0
    if len(hits) >= 1:
        nsamples = hits['length'].max()
    nsamples = np.max((nsamples, 2))

    hitlets = np.zeros(len(hits), dtype=strax.hitlet_with_data_dtype(nsamples))
    if len(hitlets):
        assert hitlets['data'].shape[
            1] >= 2, 'Data buffer is not at least 2 samples long.'
    strax.copy_to_buffer(hits, hitlets,
                         '_refresh_hit_to_hitlet_properties_test')

    # Testing refresh_hit_to_hitlets for free:
    assert len(hits) == len(
        hitlets), 'Somehow hitlets and hits have different sizes'
    # Testing interval fields:
    dummy = np.zeros(0, dtype=strax.interval_dtype)
    for name in dummy.dtype.names:
        assert np.all(hitlets[name] == hits[name]), f'The entry of the field {name} did not match between hit and ' \
                                                    f'hitlets '

    # Step 2.: Add to each hit(let) some data
    for ind, d in enumerate(data):
        h = hitlets[ind]
        h['data'][:h['length']] = d[:h['length']]

    # Step 3.: Add np.nan in data but outside of length:
    for h in hitlets:
        if h['length'] < len(h['data']):
            h['data'][-1] = np.nan
            # It is enough to test this for a single hitlet:
            break

    # Step 4.: Compute properties and apply tests:
    strax.hitlet_properties(hitlets)
    for ind, d in enumerate(data):
        h = hitlets[ind]
        d = d[:h['length']]
        pos_max = np.argmax(d)

        # Checking amplitude things:
        assert pos_max == h[
            'time_amplitude'], 'Wrong amplitude position found!'
        assert d[pos_max] == h['amplitude'], 'Wrong amplitude value found!'

        # Checking FHWM and FWTM:
        fractions = [0.1, 0.5]
        for f in fractions:
            # Get field names for the correct test:
            if f == 0.5:
                left = 'left'
                fwxm = 'fwhm'
            else:
                left = 'low_left'
                fwxm = 'fwtm'

            amplitude = np.max(d)
            if np.all(d[0] == d) or np.all(d > amplitude * f):
                # If all samples are either the same or greater than required height FWXM is not defined:
                mes = 'All samples are the same or larger than require height.'
                assert np.isnan(
                    h[left]
                ), mes + f' Left edge for {f} should have been np.nan.'
                assert np.isnan(
                    h[left]), mes + f' FWXM for X={f} should have been np.nan.'
            else:
                le = np.argwhere(d[:pos_max] <= amplitude * f)
                if len(le):
                    le = le[-1, 0]
                    m = d[le + 1] - d[le]
                    le = le + 0.5 + (amplitude * f - d[le]) / m
                else:
                    le = 0

                re = np.argwhere(d[pos_max:] <= amplitude * f)

                if len(re) and re[0, 0] != 0:
                    re = re[0, 0] + pos_max
                    m = d[re] - d[re - 1]
                    re = re + 0.5 + (amplitude * f - d[re]) / m
                else:
                    re = len(d)

                assert math.isclose(
                    le, h[left], rel_tol=10**-4, abs_tol=10**
                    -4), f'Left edge does not match for fraction {f}'
                assert math.isclose(
                    re - le, h[fwxm], rel_tol=10**-4,
                    abs_tol=10**-4), f'FWHM does not match for {f}'
Exemple #4
0
def test_hitlet_properties(hits_n_data):
    """
    Function which tests refresh_hit_to_hitlets, hitlet_with_data_dtype,
    and hitlet_properties.

    :param hits_n_data:
    :return:
    """
    hits, data = hits_n_data

    hits['time'] += 100
    # Step 1.: Produce fake hits and convert them into hitlets:
    if len(hits) >= 1:
        nsamples = hits['length'].max()
    else:
        nsamples = 2

    hitlets = np.zeros(len(hits), dtype=strax.hitlet_with_data_dtype(nsamples))
    if len(hitlets):
        assert hitlets['data'].shape[
            1] >= 2, 'Data buffer is not at least 2 samples long.'
    strax.refresh_hit_to_hitlets(hits, hitlets)

    # Testing refresh_hit_to_hitlets for free:
    assert len(hits) == len(
        hitlets), 'Somehow hitlets and hits have different sizes'
    # Tetsing interval fields:
    dummy = np.zeros(0, dtype=strax.interval_dtype)
    for name in dummy.dtype.names:
        assert np.all(hitlets[name] == hits[name]), f'The entry of the field {name} did not match between hit and ' \
                                                    f'hitlets '

    # Step 2.: Add to each hit(let) some data
    for ind, d in enumerate(data):
        h = hitlets[ind]
        h['data'][:h['length']] = d[:h['length']]

    strax.hitlet_properties(hitlets)

    # Step 4.: Apply tests.
    for ind, d in enumerate(data):
        h = hitlets[ind]
        d = d[:h['length']]
        pos_max = np.argmax(d)

        # Checking amplitude things:
        assert pos_max == h[
            'time_amplitude'], 'Wrong amplitude position found!'
        assert d[pos_max] == h['amplitude'], 'Wrong amplitude value found!'

        # Checking FHWM and FWTM:
        fractions = [0.1, 0.5]
        for f in fractions:
            amplitude = np.max(d)
            le = np.argwhere(d[:pos_max] <= amplitude * f)
            if len(le):
                le = le[-1, 0]
                m = d[le + 1] - d[le]
                le = le + 0.5 + (amplitude * f - d[le]) / m
            else:
                le = 0

            re = np.argwhere(d[pos_max:] <= amplitude * f)

            if len(re) and re[0, 0] != 0:
                re = re[0, 0] + pos_max
                m = d[re] - d[re - 1]
                re = re + 0.5 + (amplitude * f - d[re]) / m
            else:
                re = len(d)

            if f == 0.5:
                left = 'left'
                fwxm = 'fwhm'
            else:
                left = 'low_left'
                fwxm = 'fwtm'

            assert math.isclose(
                le, h[left], rel_tol=10**-4,
                abs_tol=10**-4), f'Left edge does not match for fraction {f}'
            assert math.isclose(re - le,
                                h[fwxm],
                                rel_tol=10**-4,
                                abs_tol=10**-4), f'FWHM does not match for {f}'
Exemple #5
0
def test_hitlet_properties(hits_n_data):
    """
    Function which tests refresh_hit_to_hitlets, hitlet_with_data_dtype,
    and hitlet_properties.

    :param hits_n_data:
    :return:
    """
    hits, data = hits_n_data

    hits['time'] += 100
    # Step 1.: Produce fake hits and convert them into hitlets:
    if len(hits) >= 1:
        nsamples = hits['length'].max()
    else:
        nsamples = 2

    hitlets = np.zeros(len(hits), dtype=strax.hitlet_with_data_dtype(nsamples))
    if len(hitlets):
        assert hitlets['data'].shape[1] >= 2, 'Data buffer is not at least 2 samples long.'
    strax.refresh_hit_to_hitlets(hits, hitlets)

    # Testing refresh_hit_to_hitlets for free:
    assert len(hits) == len(hitlets), 'Somehow hitlets and hits have different sizes'
    # Tetsing interval fields:
    dummy = np.zeros(0, dtype=strax.interval_dtype)
    for name in dummy.dtype.names:
        assert np.all(hitlets[name] == hits[name]), f'The entry of the field {name} did not match between hit and ' \
                                                    f'hitlets '

    # Step 2.: Add to each hit(let) some data
    for ind, d in enumerate(data):
        h = hitlets[ind]
        h['data'][:h['length']] = d[:h['length']]

    strax.hitlet_properties(hitlets)

    # Step 4.: Apply tests.
    for ind, d in enumerate(data):
        h = hitlets[ind]
        d = d[:h['length']]
        pos_max = np.argmax(d)

        # Checking amplitude things:
        assert pos_max == h['time_amplitude'], 'Wrong amplitude position found!'
        assert d[pos_max] == h['amplitude'], 'Wrong amplitude value found!'

        # Checking FHWM and FWTM:
        fractions = [0.1, 0.5]
        for f in fractions:
            # Get field names for the correct test:
            if f == 0.5:
                left = 'left'
                fwxm = 'fwhm'
            else:
                left = 'low_left'
                fwxm = 'fwtm'

            amplitude = np.max(d)
            if np.all(d[0] == d) or np.all(d > amplitude*f):
                # If all samples are either the same or greater than required height FWXM is not defined:
                mes = 'All samples are the same or larger than require height.'
                assert np.isnan(h[left]),  mes + f' Left edge for {f} should have been np.nan.'
                assert np.isnan(h[left]), mes + f' FWXM for X={f} should have been np.nan.'
            else:
                le = np.argwhere(d[:pos_max] <= amplitude * f)
                if len(le):
                    le = le[-1, 0]
                    m = d[le + 1] - d[le]
                    le = le + 0.5 + (amplitude * f - d[le]) / m
                else:
                    le = 0

                re = np.argwhere(d[pos_max:] <= amplitude * f)

                if len(re) and re[0, 0] != 0:
                    re = re[0, 0] + pos_max
                    m = d[re] - d[re - 1]
                    re = re + 0.5 + (amplitude * f - d[re]) / m
                else:
                    re = len(d)

                assert math.isclose(le, h[left],
                                    rel_tol=10**-4, abs_tol=10**-4), f'Left edge does not match for fraction {f}'
                assert math.isclose(re - le, h[fwxm], rel_tol=10**-4,
                                    abs_tol=10**-4), f'FWHM does not match for {f}'

    # Step 5.: Unity test for not defined get_fhwm-cases:
    # This is a specific unity test for some edge-cases in which the full
    # width half maximum is not defined.
    odd_hitlets = np.zeros(3, dtype=strax.hitlet_with_data_dtype(10))
    odd_hitlets[0]['data'][:5] = [2, 2, 3, 2, 2]
    odd_hitlets[0]['length'] = 5
    odd_hitlets[1]['data'][:2] = [5, 5]
    odd_hitlets[1]['length'] = 2
    odd_hitlets[2]['length'] = 3

    for oh in odd_hitlets:
        res = strax.get_fwxm(oh)
        mes = (f'get_fxhm returned {res} for {oh["data"][:oh["length"]]}!'
               'However, the FWHM is not defined and the return should be nan!'
               )
        assert np.all(np.isnan(res)), mes