def test_alignment(self):
        dut_alignment.alignment(
            input_track_candidates_file=analysis_utils.get_data(
                'fixtures/dut_alignment/TrackCandidates_prealigned.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/TrackCandidates_prealigned.h5')),
            input_alignment_file=analysis_utils.get_data(
                'fixtures/dut_alignment/Alignment.h5',
                output=os.path.join(testing_path,
                                    'fixtures/dut_alignment/Alignment.h5')),
            n_pixels=[(1152, 576)] * 6,
            pixel_size=[(18.4, 18.4)] * 6)

        # FIXME: test should check residuals not alignment resulds
        # FIXME: translation error can be in the order of um, angle error not
        data_equal, error_msg = test_tools.compare_h5_files(
            analysis_utils.get_data(
                'fixtures/dut_alignment/Alignment.h5',
                output=os.path.join(testing_path,
                                    'fixtures/dut_alignment/Alignment.h5')),
            analysis_utils.get_data(
                'fixtures/dut_alignment/Alignment_result.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Alignment_result.h5')),
            exact=False,
            rtol=0.01,  # 1 % error allowed
            atol=5)  # 0.0001 absolute tolerance allowed
        self.assertTrue(data_equal, msg=error_msg)
    def test_cluster_correlation(
            self):  # Check the cluster correlation function
        dut_alignment.correlate_cluster(input_cluster_files=self.data_files,
                                        output_correlation_file=os.path.join(
                                            self.output_folder,
                                            'Correlation.h5'),
                                        n_pixels=self.n_pixels,
                                        pixel_size=self.pixel_size)
        data_equal, error_msg = test_tools.compare_h5_files(
            analysis_utils.get_data(
                'fixtures/dut_alignment/Correlation_result.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Correlation_result.h5')),
            os.path.join(self.output_folder, 'Correlation.h5'),
            exact=True)
        self.assertTrue(data_equal, msg=error_msg)

        # Retest with tiny chunk size to force chunked correlation
        dut_alignment.correlate_cluster(input_cluster_files=self.data_files,
                                        output_correlation_file=os.path.join(
                                            self.output_folder,
                                            'Correlation_2.h5'),
                                        n_pixels=self.n_pixels,
                                        pixel_size=self.pixel_size,
                                        chunk_size=293)
        data_equal, error_msg = test_tools.compare_h5_files(
            analysis_utils.get_data(
                'fixtures/dut_alignment/Correlation_result.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Correlation_result.h5')),
            os.path.join(self.output_folder, 'Correlation_2.h5'),
            exact=True)
        self.assertTrue(data_equal, msg=error_msg)
 def test_noisy_pixel_masking(self):
     # Test 1:
     output_mask_file = hit_analysis.generate_pixel_mask(
         input_hits_file=self.noisy_data_file,
         output_mask_file=os.path.join(
             self.output_folder,
             'TestBeamData_Mimosa26_DUT0_small_noisy_pixel_mask.h5'),
         pixel_mask_name="NoisyPixelMask",
         threshold=10.0,
         n_pixel=(1152, 576),
         pixel_size=(18.4, 18.4),
         plot=True)
     output_cluster_file = hit_analysis.cluster_hits(
         input_hits_file=self.noisy_data_file,
         input_noisy_pixel_mask_file=output_mask_file,
         min_hit_charge=1,
         max_hit_charge=1,
         column_cluster_distance=2,
         row_cluster_distance=2,
         frame_cluster_distance=1)
     data_equal, error_msg = test_tools.compare_h5_files(
         analysis_utils.get_data(
             'fixtures/hit_analysis/Mimosa26_noisy_pixels_cluster_result.h5',
             output=os.path.join(
                 testing_path,
                 'fixtures/hit_analysis/Mimosa26_noisy_pixels_cluster_result.h5'
             )),
         output_cluster_file,
         exact=False)
     self.assertTrue(data_equal, msg=error_msg)
     # Test 2: smaller chunks
     output_mask_file = hit_analysis.generate_pixel_mask(
         input_hits_file=self.noisy_data_file,
         output_mask_file=os.path.join(
             self.output_folder,
             'TestBeamData_Mimosa26_DUT0_small_noisy_pixel_mask.h5'),
         pixel_mask_name="NoisyPixelMask",
         threshold=10.0,
         n_pixel=(1152, 576),
         pixel_size=(18.4, 18.4),
         plot=True)
     output_cluster_file = hit_analysis.cluster_hits(
         input_hits_file=self.noisy_data_file,
         input_noisy_pixel_mask_file=output_mask_file,
         min_hit_charge=1,
         max_hit_charge=1,
         column_cluster_distance=2,
         row_cluster_distance=2,
         frame_cluster_distance=1,
         chunk_size=4999)
     data_equal, error_msg = test_tools.compare_h5_files(
         analysis_utils.get_data(
             'fixtures/hit_analysis/Mimosa26_noisy_pixels_cluster_result.h5',
             output=os.path.join(
                 testing_path,
                 'fixtures/hit_analysis/Mimosa26_noisy_pixels_cluster_result.h5'
             )),
         output_cluster_file,
         exact=False)
     self.assertTrue(data_equal, msg=error_msg)
Exemple #4
0
 def test_residuals_calculation(self):
     residuals = result_analysis.calculate_residuals(
         input_tracks_file=analysis_utils.get_data(
             'fixtures/result_analysis/Tracks_result.h5'),
         input_alignment_file=analysis_utils.get_data(
             'fixtures/result_analysis/Alignment_result.h5'),
         output_residuals_file=os.path.join(self.output_folder,
                                            'Residuals.h5'),
         n_pixels=self.n_pixels,
         pixel_size=self.pixel_size)
     # Only test row residuals, columns are too large (250 um) for meaningfull gaussian residuals distribution
     self.assertAlmostEqual(residuals[1],
                            22.9135,
                            msg='DUT 0 row residuals do not match',
                            places=3)
     self.assertAlmostEqual(residuals[3],
                            18.7317,
                            msg='DUT 1 row residuals do not match',
                            places=3)
     self.assertAlmostEqual(residuals[5],
                            22.8645,
                            msg='DUT 2 row residuals do not match',
                            places=3)
     self.assertAlmostEqual(residuals[7],
                            27.2816,
                            msg='DUT 3 row residuals do not match',
                            places=3)
    def setUpClass(cls):
        # virtual X server for plots under headless LINUX travis testing is needed
        if os.getenv('TRAVIS', False) and os.getenv('TRAVIS_OS_NAME',
                                                    False) == 'linux':
            from xvfbwrapper import Xvfb  # virtual X server for plots under headless LINUX travis testing is needed
            cls.vdisplay = Xvfb()
            cls.vdisplay.start()

        cls.big_noisy_data_file = analysis_utils.get_data(
            path='fixtures/hit_analysis/TestBeamData_Mimosa26_DUT0.h5',
            output=os.path.join(
                testing_path,
                'fixtures/hit_analysis/TestBeamData_Mimosa26_DUT0.h5'))

        cls.noisy_data_file = analysis_utils.get_data(
            'fixtures/hit_analysis/TestBeamData_Mimosa26_DUT0_small.h5',
            output=os.path.join(
                testing_path,
                'fixtures/hit_analysis/TestBeamData_Mimosa26_DUT0_small.h5'))
        cls.data_file = analysis_utils.get_data(
            'fixtures/hit_analysis/TestBeamData_FEI4_DUT0_small.h5',
            output=os.path.join(
                testing_path,
                'fixtures/hit_analysis/TestBeamData_FEI4_DUT0_small.h5'))
        cls.output_folder = 'tmp_hit_test_output'
        test_tools.create_folder(cls.output_folder)
        cls.pixel_size = ((250, 50), (250, 50), (250, 50), (250, 50))  # in um
    def setUpClass(cls):
        # virtual X server for plots under headless LINUX travis testing is needed
        if os.getenv('TRAVIS', False) and os.getenv('TRAVIS_OS_NAME',
                                                    False) == 'linux':
            from xvfbwrapper import Xvfb
            cls.vdisplay = Xvfb()
            cls.vdisplay.start()

        # Download example data
        # Reduce the example data to make it possible to test the examples in
        # CI environments
        try:
            cls.examples_fei4_hit_files = [
                analysis_utils.get_data(
                    path='examples/TestBeamData_FEI4_DUT%d.h5' % i,
                    output=os.path.join(
                        testing_path,
                        'examples/TestBeamData_FEI4_DUT%d.h5' % i),
                    fail_on_overwrite=True) for i in [0, 1, 4, 5]
            ]
            data_selection.reduce_hit_files(cls.examples_fei4_hit_files,
                                            fraction=100)
            # Remove old files and rename reduced files
            for file_name in cls.examples_fei4_hit_files:
                os.remove(file_name)
                os.rename(
                    os.path.splitext(file_name)[0] + '_reduced.h5', file_name)
        except RuntimeError:  # Files are already downloaded and reduced
            cls.examples_fei4_hit_files = [
                os.path.join(testing_path,
                             'examples/TestBeamData_FEI4_DUT%d.h5' % i)
                for i in [0, 1, 4, 5]
            ]
        try:
            cls.examples_mimosa_hit_files = [
                analysis_utils.get_data(
                    path='examples/TestBeamData_Mimosa26_DUT%d.h5' % i,
                    output=os.path.join(
                        testing_path,
                        'examples/TestBeamData_Mimosa26_DUT%d.h5' % i),
                    fail_on_overwrite=True) for i in range(6)
            ]
            data_selection.reduce_hit_files(cls.examples_mimosa_hit_files,
                                            fraction=100)
            # Remove old files and rename reduced files
            for file_name in cls.examples_mimosa_hit_files:
                os.remove(file_name)
                os.rename(
                    os.path.splitext(file_name)[0] + '_reduced.h5', file_name)
        except RuntimeError:  # Files are already downloaded and reduced
            cls.examples_mimosa_hit_files = [
                os.path.join(testing_path,
                             'examples/TestBeamData_Mimosa26_DUT%d.h5' % i)
                for i in range(6)
            ]
    def test_prealignment(self):  # Check the hit alignment function
        dut_alignment.prealignment(
            input_correlation_file=analysis_utils.get_data(
                'fixtures/dut_alignment/Correlation_result.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Correlation_result.h5')),
            output_alignment_file=os.path.join(self.output_folder,
                                               'Alignment.h5'),
            z_positions=self.z_positions,
            pixel_size=self.pixel_size,
            non_interactive=True,
            fit_background=False,
            iterations=3
        )  # Due to too little test data the alignment result is only rather stable for more iterations

        # FIXME: residuals should be checked not prealingment data
        data_equal, error_msg = test_tools.compare_h5_files(
            analysis_utils.get_data(
                'fixtures/dut_alignment/Prealignment_result.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Prealignment_result.h5')),
            os.path.join(self.output_folder, 'Alignment.h5'),
            exact=False,
            rtol=0.05,  # 5 % error allowed
            atol=5)  # 5 um absolute tolerance allowed
        self.assertTrue(data_equal, msg=error_msg)

        dut_alignment.prealignment(
            input_correlation_file=analysis_utils.get_data(
                'fixtures/dut_alignment/Correlation_difficult.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Correlation_difficult.h5')),
            output_alignment_file=os.path.join(self.output_folder,
                                               'Alignment_difficult.h5'),
            z_positions=self.z_positions,
            pixel_size=self.pixel_size,
            non_interactive=True,
            fit_background=True,
            iterations=2
        )  # Due to too little test data the alignment result is only rather stable for more iterations
        data_equal, error_msg = test_tools.compare_h5_files(
            analysis_utils.get_data(
                r'fixtures/dut_alignment/Alignment_difficult_result.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Alignment_difficult_result.h5')),
            os.path.join(self.output_folder, 'Alignment_difficult.h5'),
            exact=False,
            rtol=0.05,  # 5 % error allowed
            atol=5)  # 5 um absolute tolerance allowed
        self.assertTrue(data_equal, msg=error_msg)
Exemple #8
0
 def test_3d_index_histograming(
         self):  # check compiled hist_3D_index function
     with tb.open_file(analysis_utils.get_data(
             'fixtures/analysis_utils/hist_data.h5',
             output=os.path.join(testing_path,
                                 'fixtures/analysis_utils/hist_data.h5')),
                       mode="r") as in_file_h5:
         xyz = in_file_h5.root.HistDataXYZ[:]
         x, y, z = xyz[0], xyz[1], xyz[2]
         shape = (100, 100, 100)
         array_fast = analysis_utils.hist_3d_index(x, y, z, shape=shape)
         array = np.histogramdd(np.column_stack((x, y, z)),
                                bins=shape,
                                range=[[0, shape[0] - 1], [0, shape[1] - 1],
                                       [0, shape[2] - 1]])[0]
         shape = (
             50, 200, 200
         )  # shape that is too small for the indices to trigger exception
         exception_ok = False
         try:
             array_fast = analysis_utils.hist_3d_index(x, y, z, shape=shape)
         except IndexError:
             exception_ok = True
         except:  # other exception that should not occur
             pass
         self.assertTrue(exception_ok & np.all(array == array_fast))
 def test_hit_clustering(self):
     # Test 1:
     output_cluster_file = hit_analysis.cluster_hits(
         input_hits_file=self.data_file,
         min_hit_charge=0,
         max_hit_charge=13,
         output_cluster_file=os.path.join(
             self.output_folder,
             'TestBeamData_FEI4_DUT0_small_clustered.h5'),
         column_cluster_distance=1,
         row_cluster_distance=2,
         frame_cluster_distance=2)
     data_equal, error_msg = test_tools.compare_h5_files(
         analysis_utils.get_data(
             'fixtures/hit_analysis/FEI4_cluster_result.h5',
             output=os.path.join(
                 testing_path,
                 'fixtures/hit_analysis/FEI4_cluster_result.h5')),
         output_cluster_file,
         exact=False)
     self.assertTrue(data_equal, msg=error_msg)
     # Test 2: smaller chunks
     output_cluster_file = hit_analysis.cluster_hits(
         input_hits_file=self.data_file,
         min_hit_charge=0,
         max_hit_charge=13,
         output_cluster_file=os.path.join(
             self.output_folder,
             'TestBeamData_FEI4_DUT0_small_clustered.h5'),
         column_cluster_distance=1,
         row_cluster_distance=2,
         frame_cluster_distance=2,
         chunk_size=4999)
     data_equal, error_msg = test_tools.compare_h5_files(
         analysis_utils.get_data(
             'fixtures/hit_analysis/FEI4_cluster_result.h5',
             output=os.path.join(
                 testing_path,
                 'fixtures/hit_analysis/FEI4_cluster_result.h5')),
         output_cluster_file,
         exact=False)
     self.assertTrue(data_equal, msg=error_msg)
 def test_track_finding(self):
     # Test 1:
     track_analysis.find_tracks(input_tracklets_file=analysis_utils.get_data('fixtures/track_analysis/Tracklets_small.h5',
                                                                             output=os.path.join(testing_path,
                                                                                                 'fixtures/track_analysis/Tracklets_small.h5')),
                                input_alignment_file=analysis_utils.get_data('fixtures/track_analysis/Alignment_result.h5',
                                                                             output=os.path.join(testing_path,
                                                                                                 'fixtures/track_analysis/Alignment_result.h5')),
                                output_track_candidates_file=os.path.join(self.output_folder, 'TrackCandidates.h5'))
     data_equal, error_msg = test_tools.compare_h5_files(analysis_utils.get_data('fixtures/track_analysis/TrackCandidates_result.h5',
                                                                                 output=os.path.join(testing_path,
                                                                                                     'fixtures/track_analysis/TrackCandidates_result.h5')), os.path.join(self.output_folder, 'TrackCandidates.h5'))
     self.assertTrue(data_equal, msg=error_msg)
     # Test 2: chunked
     track_analysis.find_tracks(input_tracklets_file=analysis_utils.get_data('fixtures/track_analysis/Tracklets_small.h5',
                                                                             output=os.path.join(testing_path,
                                                                                                 'fixtures/track_analysis/Tracklets_small.h5')),
                                input_alignment_file=analysis_utils.get_data('fixtures/track_analysis/Alignment_result.h5',
                                                                             output=os.path.join(testing_path,
                                                                                                 'fixtures/track_analysis/Alignment_result.h5')),
                                output_track_candidates_file=os.path.join(self.output_folder, 'TrackCandidates_2.h5'),
                                chunk_size=293)
     data_equal, error_msg = test_tools.compare_h5_files(analysis_utils.get_data('fixtures/track_analysis/TrackCandidates_result.h5',
                                                                                 output=os.path.join(testing_path,
                                                                                                     'fixtures/track_analysis/TrackCandidates_result.h5')),
                                                         os.path.join(self.output_folder, 'TrackCandidates_2.h5'))
     self.assertTrue(data_equal, msg=error_msg)
    def test_cluster_merging(self):
        cluster_files = [
            analysis_utils.get_data(
                'fixtures/dut_alignment/Cluster_DUT%d_cluster.h5' % i,
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Cluster_DUT%d_cluster.h5' % i))
            for i in range(4)
        ]
        dut_alignment.merge_cluster_data(cluster_files,
                                         output_merged_file=os.path.join(
                                             self.output_folder, 'Merged.h5'),
                                         n_pixels=self.n_pixels,
                                         pixel_size=self.pixel_size)
        data_equal, error_msg = test_tools.compare_h5_files(
            analysis_utils.get_data(
                'fixtures/dut_alignment/Merged_result.h5',
                output=os.path.join(
                    testing_path, 'fixtures/dut_alignment/Merged_result.h5')),
            os.path.join(self.output_folder, 'Merged.h5'))
        self.assertTrue(data_equal, msg=error_msg)

        # Retest with tiny chunk size to force chunked merging
        dut_alignment.merge_cluster_data(cluster_files,
                                         output_merged_file=os.path.join(
                                             self.output_folder,
                                             'Merged_2.h5'),
                                         pixel_size=self.pixel_size,
                                         n_pixels=self.n_pixels,
                                         chunk_size=293)

        data_equal, error_msg = test_tools.compare_h5_files(
            analysis_utils.get_data(
                'fixtures/dut_alignment/Merged_result.h5',
                output=os.path.join(
                    testing_path, 'fixtures/dut_alignment/Merged_result.h5')),
            os.path.join(self.output_folder, 'Merged_2.h5'))
        self.assertTrue(data_equal, msg=error_msg)
Exemple #12
0
    def test_efficiency_calculation(self):
        efficiencies = result_analysis.calculate_efficiency(
            input_tracks_file=analysis_utils.get_data(
                'fixtures/result_analysis/Tracks_result.h5'),
            input_alignment_file=analysis_utils.get_data(
                'fixtures/result_analysis/Alignment_result.h5'),
            output_efficiency_file=os.path.join(self.output_folder,
                                                'Efficiency.h5'),
            bin_size=[(250, 50)] * 4,
            sensor_size=[(250 * 80., 336 * 50.)] * 4,
            pixel_size=[(250, 50)] * 4,
            n_pixels=[(80, 336)] * 4,
            minimum_track_density=2,
            use_duts=None,
            cut_distance=500,
            max_distance=500,
            #col_range=[(1250, 17500)]*4,
            #row_range=[(1000, 16000)]*4,
            force_prealignment=True)

        self.assertAlmostEqual(efficiencies[0],
                               100.000,
                               msg='DUT 0 efficiencies do not match',
                               places=3)
        self.assertAlmostEqual(efficiencies[1],
                               98.7013,
                               msg='DUT 1 efficiencies do not match',
                               places=3)
        self.assertAlmostEqual(efficiencies[2],
                               97.4684,
                               msg='DUT 2 efficiencies do not match',
                               places=3)
        self.assertAlmostEqual(efficiencies[3],
                               100.000,
                               msg='DUT 3 efficiencies do not match',
                               places=3)
    def test_generate_pixel_mask(self):
        output_mask_file = hit_analysis.generate_pixel_mask(
            input_hits_file=self.big_noisy_data_file,
            output_mask_file=os.path.join(
                self.output_folder,
                'TestBeamData_Mimosa26_DUT0_noisy_pixel_mask.h5'),
            pixel_mask_name="NoisyPixelMask",
            threshold=0.5,
            n_pixel=(1152, 576),
            pixel_size=(18.4, 18.4),
            plot=True)

        data_equal, error_msg = test_tools.compare_h5_files(
            analysis_utils.get_data(
                'fixtures/hit_analysis/TestBeamData_Mimosa26_DUT0_noisy_pixel_mask.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/hit_analysis/TestBeamData_Mimosa26_DUT0_noisy_pixel_mask.h5'
                )), output_mask_file)
        self.assertTrue(data_equal, msg=error_msg)
Exemple #14
0
    def test_simulation(self):
        ''' Check the full simulation '''
        self.simulate_data.reset()
        self.simulate_data.set_std_settings()
        self.assertEqual(self.simulate_data.n_duts, 6)

        self.simulate_data.create_data_and_store('simulated_data',
                                                 n_events=10000)

        for dut_index in range(self.simulate_data.n_duts):
            data_equal, error_msg = test_tools.compare_h5_files(
                'simulated_data_DUT%d.h5' % dut_index,
                analysis_utils.get_data(
                    'fixtures/simulation/simulated_data_DUT%d.h5' % dut_index,
                    output=os.path.join(
                        testing_path,
                        'fixtures/simulation/simulated_data_DUT%d.h5' %
                        dut_index)),
                exact=False)
            self.assertTrue(data_equal, msg=error_msg)
 def setUpClass(cls):
     # virtual X server for plots under headless LINUX travis testing is needed
     if os.getenv('TRAVIS', False) and os.getenv('TRAVIS_OS_NAME',
                                                 False) == 'linux':
         from xvfbwrapper import Xvfb
         cls.vdisplay = Xvfb()
         cls.vdisplay.start()
     # Define test data input files, download if needed
     cls.data_files = [
         analysis_utils.get_data(
             'fixtures/dut_alignment/Cluster_DUT%d_cluster.h5' % i,
             output=os.path.join(
                 testing_path,
                 'fixtures/dut_alignment/Cluster_DUT%d_cluster.h5' % i))
         for i in range(4)
     ]
     # Define and create tests output folder, is deleted at the end of tests
     cls.output_folder = os.path.join(
         os.path.dirname(os.path.realpath(cls.data_files[0])), 'output')
     test_tools.create_folder(cls.output_folder)
     cls.n_pixels = [(80, 336)] * 4
     cls.pixel_size = [(250, 50)] * 4  # in um
     cls.z_positions = [0., 19500, 108800, 128300]
    def test_apply_alignment(self):
        dut_alignment.apply_alignment(
            input_hit_file=analysis_utils.get_data(
                'fixtures/dut_alignment/Merged_result.h5',
                output=os.path.join(
                    testing_path, 'fixtures/dut_alignment/Merged_result.h5')),
            input_alignment_file=analysis_utils.get_data(
                'fixtures/dut_alignment/Prealignment_result.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Prealignment_result.h5')),
            output_hit_file=os.path.join(self.output_folder, 'Tracklets.h5'),
            use_prealignment=True)
        data_equal, error_msg = test_tools.compare_h5_files(
            analysis_utils.get_data(
                'fixtures/dut_alignment/Tracklets_result.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Tracklets_result.h5')),
            os.path.join(self.output_folder, 'Tracklets.h5'))
        self.assertTrue(data_equal, msg=error_msg)

        # Retest with tiny chunk size to force chunked alignment apply
        dut_alignment.apply_alignment(
            input_hit_file=analysis_utils.get_data(
                'fixtures/dut_alignment/Merged_result.h5',
                output=os.path.join(
                    testing_path, 'fixtures/dut_alignment/Merged_result.h5')),
            input_alignment_file=analysis_utils.get_data(
                'fixtures/dut_alignment/Prealignment_result.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Prealignment_result.h5')),
            output_hit_file=os.path.join(self.output_folder, 'Tracklets_2.h5'),
            use_prealignment=True,
            chunk_size=293)
        data_equal, error_msg = test_tools.compare_h5_files(
            analysis_utils.get_data(
                'fixtures/dut_alignment/Tracklets_result.h5',
                output=os.path.join(
                    testing_path,
                    'fixtures/dut_alignment/Tracklets_result.h5')),
            os.path.join(self.output_folder, 'Tracklets_2.h5'))
        self.assertTrue(data_equal, msg=error_msg)
class TestExamples(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        # virtual X server for plots under headless LINUX travis testing is needed
        if os.getenv('TRAVIS', False) and os.getenv('TRAVIS_OS_NAME',
                                                    False) == 'linux':
            from xvfbwrapper import Xvfb
            cls.vdisplay = Xvfb()
            cls.vdisplay.start()

        # Download example data
        # Reduce the example data to make it possible to test the examples in
        # CI environments
        try:
            cls.examples_fei4_hit_files = [
                analysis_utils.get_data(
                    path='examples/TestBeamData_FEI4_DUT%d.h5' % i,
                    output=os.path.join(
                        testing_path,
                        'examples/TestBeamData_FEI4_DUT%d.h5' % i),
                    fail_on_overwrite=True) for i in [0, 1, 4, 5]
            ]
            data_selection.reduce_hit_files(cls.examples_fei4_hit_files,
                                            fraction=100)
            # Remove old files and rename reduced files
            for file_name in cls.examples_fei4_hit_files:
                os.remove(file_name)
                os.rename(
                    os.path.splitext(file_name)[0] + '_reduced.h5', file_name)
        except RuntimeError:  # Files are already downloaded and reduced
            cls.examples_fei4_hit_files = [
                os.path.join(testing_path,
                             'examples/TestBeamData_FEI4_DUT%d.h5' % i)
                for i in [0, 1, 4, 5]
            ]
        try:
            cls.examples_mimosa_hit_files = [
                analysis_utils.get_data(
                    path='examples/TestBeamData_Mimosa26_DUT%d.h5' % i,
                    output=os.path.join(
                        testing_path,
                        'examples/TestBeamData_Mimosa26_DUT%d.h5' % i),
                    fail_on_overwrite=True) for i in range(6)
            ]
            data_selection.reduce_hit_files(cls.examples_mimosa_hit_files,
                                            fraction=100)
            # Remove old files and rename reduced files
            for file_name in cls.examples_mimosa_hit_files:
                os.remove(file_name)
                os.rename(
                    os.path.splitext(file_name)[0] + '_reduced.h5', file_name)
        except RuntimeError:  # Files are already downloaded and reduced
            cls.examples_mimosa_hit_files = [
                os.path.join(testing_path,
                             'examples/TestBeamData_Mimosa26_DUT%d.h5' % i)
                for i in range(6)
            ]

    # Alignments do not converge for reduced data set
    # Thus mock out the alignment steps
    @mock.patch('beam_telescope_analysis.dut_alignment.prealignment',
                side_effect=copy_data(
                    path=analysis_utils.get_data(
                        path='fixtures/examples/eutelescope/Alignment.h5',
                        output=os.path.join(
                            testing_path,
                            'fixtures/examples/eutelescope/Alignment.h5')),
                    out_path=os.path.join(
                        testing_path,
                        'examples/data/output_eutelescope/Alignment.h5')))
    @mock.patch('beam_telescope_analysis.dut_alignment.alignment')
    # TODO: Analysis fails, to be checked why
    @mock.patch('beam_telescope_analysis.track_analysis.fit_tracks',
                side_effect=fit_tracks_fast)
    @mock.patch('beam_telescope_analysis.result_analysis.calculate_residuals')
    def test_mimosa_example(self, m1, m2, m3, m4):
        eutelescope.run_analysis(self.examples_mimosa_hit_files)

    # Prealignment does not converge for reduced data set
    # Thus mock out the prealignment
    @mock.patch('beam_telescope_analysis.dut_alignment.prealignment',
                side_effect=copy_data(
                    path=analysis_utils.get_data(
                        path='fixtures/examples/fei4_telescope/Alignment.h5',
                        output=os.path.join(
                            testing_path,
                            'fixtures/examples/fei4_telescope/Alignment.h5')),
                    out_path=os.path.join(
                        testing_path,
                        'examples/data/output_fei4_telescope/Alignment.h5')))
    def test_fei4_example(self, mock):
        fei4_telescope.run_analysis(self.examples_fei4_hit_files)

    def test_simulated_data_example(self):
        ''' Check the example and the overall analysis that a efficiency of
            about 100% is reached. Not a perfect 100% is expected due to the
            finite propability that tracks are merged since > 2 tracks per
            event are simulated
        '''
        simulated_data.run_analysis(1000)
        with tb.open_file('simulation/Efficiency.h5') as in_file_h5:
            for i in range(5):  # Loop over DUT index
                eff = in_file_h5.get_node('/DUT%d/Efficiency' % i)[:]
                mask = in_file_h5.get_node('/DUT%d/Efficiency_mask' % i)[:]
                self.assertAlmostEqual(eff[~mask].mean(), 100., delta=0.0001)
    def test_track_fitting(self):
        # Test 1: Fit DUTs and always exclude one DUT (normal mode for unbiased residuals and efficiency determination)
        track_analysis.fit_tracks(input_track_candidates_file=analysis_utils.get_data('fixtures/track_analysis/TrackCandidates_result.h5',
                                                                                      output=os.path.join(testing_path,
                                                                                                          'fixtures/track_analysis/TrackCandidates_result.h5')),
                                  input_alignment_file=analysis_utils.get_data('fixtures/track_analysis/Alignment_result.h5',
                                                                               output=os.path.join(testing_path,
                                                                                                   'fixtures/track_analysis/Alignment_result.h5')),
                                  output_tracks_file=os.path.join(self.output_folder, 'Tracks.h5'),
                                  selection_track_quality=1,
                                  use_prealignment=True)
        data_equal, error_msg = test_tools.compare_h5_files(analysis_utils.get_data('fixtures/track_analysis/Tracks_result.h5',
                                                                                    output=os.path.join(testing_path,
                                                                                                        'fixtures/track_analysis/Tracks_result.h5')),
                                                            os.path.join(self.output_folder, 'Tracks.h5'), exact=False)
        self.assertTrue(data_equal, msg=error_msg)

        # Test 2: As test 1 but chunked data analysis, should result in the same tracks
        track_analysis.fit_tracks(input_track_candidates_file=analysis_utils.get_data('fixtures/track_analysis/TrackCandidates_result.h5',
                                                                                      output=os.path.join(testing_path,
                                                                                                          'fixtures/track_analysis/TrackCandidates_result.h5')),
                                  input_alignment_file=analysis_utils.get_data('fixtures/track_analysis/Alignment_result.h5',
                                                                               output=os.path.join(testing_path,
                                                                                                   'fixtures/track_analysis/Alignment_result.h5')),
                                  output_tracks_file=os.path.join(self.output_folder, 'Tracks_2.h5'),
                                  selection_track_quality=1,
                                  use_prealignment=True,
                                  chunk_size=4999)
        data_equal, error_msg = test_tools.compare_h5_files(analysis_utils.get_data('fixtures/track_analysis/Tracks_result.h5',
                                                                                    output=os.path.join(testing_path,
                                                                                                        'fixtures/track_analysis/Tracks_result.h5')),
                                                            os.path.join(self.output_folder, 'Tracks_2.h5'), exact=False)
        self.assertTrue(data_equal, msg=error_msg)

        # Test 3: Fit all DUTs at once (special mode for constrained residuals)
        track_analysis.fit_tracks(input_track_candidates_file=analysis_utils.get_data('fixtures/track_analysis/TrackCandidates_result.h5',
                                                                                      output=os.path.join(testing_path,
                                                                                                          'fixtures/track_analysis/TrackCandidates_result.h5')),
                                  input_alignment_file=analysis_utils.get_data('fixtures/track_analysis/Alignment_result.h5',
                                                                               output=os.path.join(testing_path,
                                                                                                   'fixtures/track_analysis/Alignment_result.h5')),
                                  output_tracks_file=os.path.join(self.output_folder, 'Tracks_All.h5'),
                                  exclude_dut_hit=False,
                                  selection_track_quality=1,
                                  use_prealignment=True)
        # Fit DUTs consecutevly, but use always the same DUTs. Should result in the same data as above
        track_analysis.fit_tracks(input_track_candidates_file=analysis_utils.get_data('fixtures/track_analysis/TrackCandidates_result.h5',
                                                                                      output=os.path.join(testing_path, 'fixtures/track_analysis/TrackCandidates_result.h5')),
                                  input_alignment_file=analysis_utils.get_data('fixtures/track_analysis/Alignment_result.h5',
                                                                               output=os.path.join(testing_path,
                                                                                                   'fixtures/track_analysis/Alignment_result.h5')),
                                  output_tracks_file=os.path.join(self.output_folder, 'Tracks_All_Iter.h5'),
                                  select_hit_duts=range(4),
                                  exclude_dut_hit=False,
                                  selection_track_quality=1,
                                  use_prealignment=True)
        data_equal, error_msg = test_tools.compare_h5_files(os.path.join(self.output_folder, 'Tracks_All.h5'), os.path.join(self.output_folder, 'Tracks_All_Iter.h5'), exact=False)
        self.assertTrue(data_equal, msg=error_msg)
        # Fit DUTs consecutevly, but use always the same DUTs defined for each DUT separately. Should result in the same data as above
        track_analysis.fit_tracks(input_track_candidates_file=analysis_utils.get_data('fixtures/track_analysis/TrackCandidates_result.h5',
                                                                                      output=os.path.join(testing_path,
                                                                                                          'fixtures/track_analysis/TrackCandidates_result.h5')),
                                  input_alignment_file=analysis_utils.get_data('fixtures/track_analysis/Alignment_result.h5',
                                                                               output=os.path.join(testing_path,
                                                                                                   'fixtures/track_analysis/Alignment_result.h5')),
                                  output_tracks_file=os.path.join(self.output_folder, 'Tracks_All_Iter_2.h5'),
                                  select_hit_duts=[range(4), range(4), range(4), range(4)],
                                  exclude_dut_hit=False,
                                  selection_track_quality=1,
                                  use_prealignment=True)
        data_equal, error_msg = test_tools.compare_h5_files(os.path.join(self.output_folder, 'Tracks_All.h5'), os.path.join(self.output_folder, 'Tracks_All_Iter_2.h5'), exact=False)
        self.assertTrue(data_equal, msg=error_msg)

        # Fit tracks and eliminate merged tracks
        track_analysis.fit_tracks(input_track_candidates_file=analysis_utils.get_data('fixtures/track_analysis/TrackCandidates_result.h5',
                                                                                      output=os.path.join(testing_path,
                                                                                                          'fixtures/track_analysis/TrackCandidates_result.h5')),
                                  input_alignment_file=analysis_utils.get_data('fixtures/track_analysis/Alignment_result.h5',
                                                                               output=os.path.join(testing_path,
                                                                                                   'fixtures/track_analysis/Alignment_result.h5')),
                                  output_tracks_file=os.path.join(self.output_folder, 'Tracks_merged.h5'),
                                  selection_track_quality=1,
                                  min_track_distance=True,  # Activate track merge cut,
                                  use_prealignment=True)
        data_equal, error_msg = test_tools.compare_h5_files(analysis_utils.get_data('fixtures/track_analysis/Tracks_merged_result.h5',
                                                                                    output=os.path.join(testing_path, 'fixtures/track_analysis/Tracks_merged_result.h5')), os.path.join(self.output_folder, 'Tracks_merged.h5'), exact=False)
        self.assertTrue(data_equal, msg=error_msg)
    #     select_no_hit_duts=None,
    #     select_quality_duts=[[1, 2, 3, 4, 5], [0, 2, 3, 4, 5], [0, 1, 3, 4, 5], [0, 1, 2, 4, 5], [0, 1, 2, 3, 5], [0, 1, 2, 3, 4]],
    #     query='(track_chi2 < 5.0)')

    # # Calculate the unconstrained residuals from final from final tracks (with chi^2 cut and quality selection)
    # result_analysis.calculate_residuals(
    #     telescope_configuration=aligned_configuration,
    #     input_tracks_file=os.path.join(output_folder, 'Tracks_aligned_kalman_selected.h5'),
    #     output_residuals_file=os.path.join(output_folder, 'Residuals_aligned_kalman.h5'),
    #     select_duts=[0, 1, 2, 3, 4, 5],
    #     nbins_per_pixel=20,
    #     use_limits=True)


# Main entry point is needed for multiprocessing under Windows
if __name__ == '__main__':
    # Get the absolute path of example data
    tests_data_folder = os.path.join(
        os.path.dirname(
            os.path.abspath(inspect.getfile(inspect.currentframe()))), 'data')
    # The location of the data files, one file per DUT
    hit_files = [
        analysis_utils.get_data(
            path='examples/TestBeamData_Mimosa26_DUT%d.h5' % i,
            output=os.path.join(tests_data_folder,
                                'TestBeamData_Mimosa26_DUT%d.h5' % i))
        for i in range(6)
    ]

    run_analysis(hit_files=hit_files)