Changes in / [5c1c486:b76e65a] in sasview
- Files:
-
- 7 added
- 3 deleted
- 17 edited
Legend:
- Unmodified
- Added
- Removed
-
.pydevproject
r9d93c37 r26c8be3 4 4 <pydev_property name="org.python.pydev.PYTHON_PROJECT_VERSION">python 2.7</pydev_property> 5 5 <pydev_pathproperty name="org.python.pydev.PROJECT_SOURCE_PATH"> 6 <path>/sasview /src</path>6 <path>/sasview4/src</path> 7 7 </pydev_pathproperty> 8 8 </pydev_project> -
README.md
rf9ba422 r7a88adc 6 6 7 7 [![Travis-CI Build Status](https://travis-ci.org/SasView/sasview.svg?branch=master)](https://travis-ci.org/SasView/sasview) 8 [![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.438138.svg)](https://doi.org/10.5281/zenodo.438138) 8 -
src/sas/sascalc/dataloader/data_info.py
r17e257b5 ra1b8fee 1161 1161 final_dataset = None 1162 1162 if isinstance(data, plottable_1D): 1163 final_dataset = Data1D(data.x, data.y , isSesans=datainfo.isSesans)1163 final_dataset = Data1D(data.x, data.y) 1164 1164 final_dataset.dx = data.dx 1165 1165 final_dataset.dy = data.dy 1166 1166 final_dataset.dxl = data.dxl 1167 1167 final_dataset.dxw = data.dxw 1168 final_dataset.x_unit = data._xunit1169 final_dataset.y_unit = data._yunit1170 1168 final_dataset.xaxis(data._xaxis, data._xunit) 1171 1169 final_dataset.yaxis(data._yaxis, data._yunit) -
src/sas/sascalc/dataloader/file_reader_base_class.py
ra78a02f rdcb91cf 6 6 7 7 import os 8 import re9 8 import logging 10 9 import numpy as np … … 107 106 for data in self.output: 108 107 if isinstance(data, Data1D): 109 # Normalize the units for110 data.x_unit = self.format_unit(data.x_unit)111 data.y_unit = self.format_unit(data.y_unit)112 108 # Sort data by increasing x and remove 1st point 113 109 ind = np.lexsort((data.y, data.x)) … … 135 131 for dataset in self.output: 136 132 if isinstance(dataset, Data2D): 137 # Normalize the units for138 dataset.x_unit = self.format_unit(dataset.Q_unit)139 dataset.y_unit = self.format_unit(dataset.I_unit)140 133 dataset.data = dataset.data.astype(np.float64) 141 134 dataset.qx_data = dataset.qx_data.astype(np.float64) … … 162 155 dataset.data = dataset.data.flatten() 163 156 164 def format_unit(self, unit=None):165 """166 Format units a common way167 :param unit:168 :return:169 """170 if unit:171 split = unit.split("/")172 if len(split) == 1:173 return unit174 elif split[0] == '1':175 return "{0}^".format(split[1]) + "{-1}"176 else:177 return "{0}*{1}^".format(split[0], split[1]) + "{-1}"178 179 157 def set_all_to_none(self): 180 158 """ -
src/sas/sascalc/dataloader/readers/cansas_reader.py
ra78a02f rdcb91cf 299 299 self.current_dataset.dx = np.append(self.current_dataset.dx, data_point) 300 300 elif tagname == 'dQw': 301 if self.current_dataset.dxw is None: 302 self.current_dataset.dxw = np.empty(0) 301 if self.current_dataset.dqw is None: self.current_dataset.dqw = np.empty(0) 303 302 self.current_dataset.dxw = np.append(self.current_dataset.dxw, data_point) 304 303 elif tagname == 'dQl': 305 if self.current_dataset.dxl is None: 306 self.current_dataset.dxl = np.empty(0) 304 if self.current_dataset.dxl is None: self.current_dataset.dxl = np.empty(0) 307 305 self.current_dataset.dxl = np.append(self.current_dataset.dxl, data_point) 308 306 elif tagname == 'Qmean': -
src/sas/sascalc/dataloader/readers/danse_reader.py
ra78a02f r713a047 189 189 x_vals = np.tile(x_vals, (size_y, 1)).flatten() 190 190 y_vals = np.tile(y_vals, (size_x, 1)).T.flatten() 191 if (np.all(self.current_dataset.err_data == None) 192 or np.any(self.current_dataset.err_data <= 0)): 191 if self.current_dataset.err_data == np.all(np.array(None)) or np.any(self.current_dataset.err_data <= 0): 193 192 new_err_data = np.sqrt(np.abs(self.current_dataset.data)) 194 193 else: -
src/sas/sasgui/guiframe/local_perspectives/plotting/plotting.py
r2d9526d r235f514 14 14 import wx 15 15 import sys 16 from copy import deepcopy17 16 from sas.sasgui.guiframe.events import EVT_NEW_PLOT 18 17 from sas.sasgui.guiframe.events import EVT_PLOT_QRANGE … … 276 275 action_check = True 277 276 else: 278 if action_string == 'update':279 # Update all existing plots of data with this ID280 for data in event.plots:281 for panel in self.plot_panels.values():282 if data.id in panel.plots.keys():283 plot_exists = True284 # Pass each panel it's own copy of the data285 # that's being updated, otherwise things like286 # colour and line thickness are unintentionally287 # synced across panels288 self.update_panel(deepcopy(data), panel)289 return290 291 277 group_id = event.group_id 292 if group_id in self.plot_panels :278 if group_id in self.plot_panels.keys(): 293 279 #remove data from panel 294 280 if action_string == 'remove': -
src/sas/sasgui/perspectives/fitting/fitting.py
r2d9526d r0900627 1748 1748 @param unsmeared_error: data error, rescaled to unsmeared model 1749 1749 """ 1750 1750 1751 number_finite = np.count_nonzero(np.isfinite(y)) 1751 1752 np.nan_to_num(y) … … 1753 1754 data_description=model.name, 1754 1755 data_id=str(page_id) + " " + data.name) 1755 plots_to_update = [] # List of plottables that have changed since last calculation1756 # Create the new theories1757 1756 if unsmeared_model is not None: 1758 unsmeared_model_plot = self.create_theory_1D(x, unsmeared_model, 1759 page_id, model, data, state, 1757 self.create_theory_1D(x, unsmeared_model, page_id, model, data, state, 1760 1758 data_description=model.name + " unsmeared", 1761 1759 data_id=str(page_id) + " " + data.name + " unsmeared") 1762 plots_to_update.append(unsmeared_model_plot)1763 1760 1764 1761 if unsmeared_data is not None and unsmeared_error is not None: 1765 unsmeared_data_plot = self.create_theory_1D(x, unsmeared_data, 1766 page_id, model, data, state, 1762 self.create_theory_1D(x, unsmeared_data, page_id, model, data, state, 1767 1763 data_description="Data unsmeared", 1768 1764 data_id="Data " + data.name + " unsmeared", 1769 1765 dy=unsmeared_error) 1770 plots_to_update.append(unsmeared_data_plot) 1771 if sq_model is not None and pq_model is not None: 1772 sq_id = str(page_id) + " " + data.name + " S(q)" 1773 sq_plot = self.create_theory_1D(x, sq_model, page_id, model, data, state, 1774 data_description=model.name + " S(q)", 1775 data_id=sq_id) 1776 plots_to_update.append(sq_plot) 1777 pq_id = str(page_id) + " " + data.name + " P(q)" 1778 pq_plot = self.create_theory_1D(x, pq_model, page_id, model, data, state, 1779 data_description=model.name + " P(q)", 1780 data_id=pq_id) 1781 plots_to_update.append(pq_plot) 1782 # Update the P(Q), S(Q) and unsmeared theory plots if they exist 1783 wx.PostEvent(self.parent, NewPlotEvent(plots=plots_to_update, 1784 action='update')) 1766 # Comment this out until we can get P*S models with correctly populated parameters 1767 #if sq_model is not None and pq_model is not None: 1768 # self.create_theory_1D(x, sq_model, page_id, model, data, state, 1769 # data_description=model.name + " S(q)", 1770 # data_id=str(page_id) + " " + data.name + " S(q)") 1771 # self.create_theory_1D(x, pq_model, page_id, model, data, state, 1772 # data_description=model.name + " P(q)", 1773 # data_id=str(page_id) + " " + data.name + " P(q)") 1785 1774 1786 1775 current_pg = self.fit_panel.get_page_by_id(page_id) -
src/sas/sasgui/perspectives/fitting/media/fitting_help.rst
r05b0bf6 r5295cf5 484 484 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 485 485 486 .. _Batch_Fit_Mode:487 488 486 Batch Fit Mode 489 487 -------------- … … 638 636 639 637 Example: radius [2 : 5] , radius [10 : 25] 640 641 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 642 643 Combined Batch Fit Mode 644 ----------------------- 645 646 The purpose of the Combined Batch Fit is to allow running two or more batch 647 fits in sequence without overwriting the output table of results. This may be 648 of interest for example if one is fitting a series of data sets where there is 649 a shape change occurring in the series that requires changing the model part 650 way through the series; for example a sphere to rod transition. Indeed the 651 regular batch mode does not allow for multiple models and requires all the 652 files in the series to be fit with single model and set of parameters. While 653 it is of course possible to just run part of the series as a batch fit using 654 model one followed by running another batch fit on the rest of the series with 655 model two (and/or model three etc), doing so will overwrite the table of 656 outputs from the previous batch fit(s). This may not be desirable if one is 657 interested in comparing the parameters: for example the sphere radius of set 658 one and the cylinder radius of set two. 659 660 Method 661 ^^^^^^ 662 663 In order to use the *Combined Batch Fit*, first load all the data needed as 664 described in :ref:`Loading_data`. Next start up two or more *BatchPage* fits 665 following the instructions in :ref:`Batch_Fit_Mode` but **DO NOT PRESS FIT**. 666 At this point the *Combine Batch Fit* menu item under the *Fitting menu* should 667 be active (if there is one or no *BatchPage* the menu item will be greyed out 668 and inactive). Clicking on *Combine Batch Fit* will bring up a new panel, 669 similar to the *Const & Simult Fit* panel. In this case there will be a 670 checkbox for each *BatchPage* instead of each *FitPage* that should be included 671 in the fit. Once all are selected, click the Fit button on 672 the *BatchPage* to run each batch fit in *sequence* 673 674 .. image:: combine_batch_page.png 675 676 The batch table will then pop up at the end as for the case of the simple Batch 677 Fitting with the following caveats: 678 679 .. note:: 680 The order matters. The parameters in the table will be taken from the model 681 used in the first *BatchPage* of the list. Any parameters from the 682 second and later *BatchPage* s that have the same name as a parameter in the 683 first will show up allowing for plotting of that parameter across the 684 models. The other parameters will not be available in the grid. 685 .. note:: 686 a corralary of the above is that currently models created as a sum|multiply 687 model will not work as desired because the generated model parameters have a 688 p#_ appended to the beginning and thus radius and p1_radius will not be 689 recognized as the same parameter. 690 691 .. image:: combine_batch_grid.png 692 693 In the example shown above the data is a time series with a shifting peak. 694 The first part of the series was fitted using the *broad_peak* model, while 695 the rest of the data were fit using the *gaussian_peak* model. Unfortunately the 696 time is not listed in the file but the file name contains the information. As 697 described in :ref:`Grid_Window`, a column can be added manually, in this case 698 called time, and the peak position plotted against time. 699 700 .. image:: combine_batch_plot.png 701 702 Note the discontinuity in the peak position. This reflects the fact that the 703 Gaussian fit is a rather poor model for the data and is not actually 704 finding the peak. 705 706 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 707 708 .. note:: This help document was last changed by Paul Butler, 10 September 709 2017 638 639 .. ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ 640 641 .. note:: This help document was last changed by Steve King, 10Oct2016 -
src/sas/sasgui/perspectives/fitting/model_thread.py
r0f9ea1c r7432acb 71 71 (self.data.qy_data * self.data.qy_data)) 72 72 73 # For theory, qmax is based on 1d qmax 73 # For theory, qmax is based on 1d qmax 74 74 # so that must be mulitified by sqrt(2) to get actual max for 2d 75 75 index_model = (self.qmin <= radius) & (radius <= self.qmax) … … 91 91 self.data.qy_data[index_model] 92 92 ]) 93 # Initialize output to NaN so masked elements do not get plotted. 94 output = np.empty_like(self.data.qx_data) 93 output = np.zeros(len(self.data.qx_data)) 95 94 # output default is None 96 95 # This method is to distinguish between masked 97 96 #point(nan) and data point = 0. 98 output [:] = np.NaN97 output = output / output 99 98 # set value for self.mask==True, else still None to Plottools 100 99 output[index_model] = value … … 199 198 output[index] = self.model.evalDistribution(self.data.x[index]) 200 199 201 x=self.data.x[index]202 y=output[index]203 200 sq_values = None 204 201 pq_values = None 202 s_model = None 203 p_model = None 205 204 if isinstance(self.model, MultiplicationModel): 206 205 s_model = self.model.s_model 207 206 p_model = self.model.p_model 208 sq_values = s_model.evalDistribution(x) 209 pq_values = p_model.evalDistribution(x) 210 elif hasattr(self.model, "calc_composition_models"): 211 results = self.model.calc_composition_models(x) 212 if results is not None: 213 pq_values, sq_values = results 214 207 elif hasattr(self.model, "get_composition_models"): 208 p_model, s_model = self.model.get_composition_models() 209 210 if p_model is not None and s_model is not None: 211 sq_values = np.zeros((len(self.data.x))) 212 pq_values = np.zeros((len(self.data.x))) 213 sq_values[index] = s_model.evalDistribution(self.data.x[index]) 214 pq_values[index] = p_model.evalDistribution(self.data.x[index]) 215 215 216 216 elapsed = time.time() - self.starttime 217 217 218 self.complete(x= x, y=y,218 self.complete(x=self.data.x[index], y=output[index], 219 219 page_id=self.page_id, 220 220 state=self.state, -
src/sas/sasgui/perspectives/fitting/simfitpage.py
ra9f9ca4 r959eb01 1 1 """ 2 Simultaneous or Batchfit page2 Simultaneous fit page 3 3 """ 4 # Note that this is used for both Simultaneous/Constrained fit AND for5 # combined batch fit. This is done through setting of the batch_on parameter.6 # There are the a half dozen or so places where an if statement is used as in7 # if not batch_on:8 # xxxx9 # else:10 # xxxx11 # This is just wrong but dont have time to fix this go. Proper approach would be12 # to strip all parts of the code that depend on batch_on and create the top13 # level class from which a contrained/simultaneous fit page and a combined14 # batch page inherit.15 #16 # 04/09/2017 --PDB17 18 4 import sys 19 5 from collections import namedtuple … … 414 400 # General Help button 415 401 self.btHelp = wx.Button(self, wx.ID_HELP, 'HELP') 416 if self.batch_on: 417 self.btHelp.SetToolTipString("Combined Batch Fitting help.") 418 else: 419 self.btHelp.SetToolTipString("Simultaneous/Constrained Fitting help.") 402 self.btHelp.SetToolTipString("Simultaneous/Constrained Fitting help.") 420 403 self.btHelp.Bind(wx.EVT_BUTTON, self._on_help) 421 404 … … 544 527 """ 545 528 _TreeLocation = "user/sasgui/perspectives/fitting/fitting_help.html" 546 if not self.batch_on: 547 _PageAnchor = "#simultaneous-fit-mode" 548 _doc_viewer = DocumentationWindow(self, self.ID_DOC, _TreeLocation, 529 _PageAnchor = "#simultaneous-fit-mode" 530 _doc_viewer = DocumentationWindow(self, self.ID_DOC, _TreeLocation, 549 531 _PageAnchor, 550 532 "Simultaneous/Constrained Fitting Help") 551 else:552 _PageAnchor = "#combined-batch-fit-mode"553 _doc_viewer = DocumentationWindow(self, self.ID_DOC, _TreeLocation,554 _PageAnchor,555 "Combined Batch Fit Help")556 533 557 534 def set_manager(self, manager): -
src/sas/sasgui/plottools/plottables.py
r2d9526d r45dffa69 239 239 def replace(self, plottable): 240 240 """Replace an existing plottable from the graph""" 241 # If the user has set a custom color, ensure the new plot is the same color 242 selected_color = plottable.custom_color 241 selected_color = None 243 242 selected_plottable = None 244 243 for p in self.plottables.keys(): 245 244 if plottable.id == p.id: 246 245 selected_plottable = p 247 if selected_color is None: 248 selected_color = self.plottables[p] 246 selected_color = self.plottables[p] 249 247 break 250 if selected_plottable is not None and selected_color is not None:248 if selected_plottable is not None and selected_color is not None: 251 249 del self.plottables[selected_plottable] 252 plottable.custom_color = selected_color253 250 self.plottables[plottable] = selected_color 254 251 -
test/sasdataloader/test/utest_abs_reader.py
ra78a02f rce8c7bd 20 20 def setUp(self): 21 21 reader = AbsReader() 22 data = reader.read("jan08002.ABS") 23 self.data= data[0] 22 self.data = reader.read("jan08002.ABS") 24 23 25 24 def test_abs_checkdata(self): … … 48 47 self.assertEqual(self.data.detector[0].beam_center.y, center_y) 49 48 50 self.assertEqual(self.data.y_unit, ' cm^{-1}')49 self.assertEqual(self.data.y_unit, '1/cm') 51 50 self.assertEqual(self.data.x[0], 0.002618) 52 51 self.assertEqual(self.data.x[1], 0.007854) … … 70 69 # the generic loader should work as well 71 70 data = Loader().load("jan08002.ABS") 72 self.assertEqual(data [0].meta_data['loader'], "IGOR 1D")71 self.assertEqual(data.meta_data['loader'], "IGOR 1D") 73 72 74 73 class DanseReaderTests(unittest.TestCase): … … 76 75 def setUp(self): 77 76 reader = DANSEReader() 78 data = reader.read("MP_New.sans") 79 self.data = data[0] 77 self.data = reader.read("MP_New.sans") 80 78 81 79 def test_checkdata(self): … … 114 112 # the generic loader should work as well 115 113 data = Loader().load("MP_New.sans") 116 self.assertEqual(data [0].meta_data['loader'], "DANSE")114 self.assertEqual(data.meta_data['loader'], "DANSE") 117 115 118 116 … … 146 144 # Data 147 145 self.assertEqual(len(self.data.x), 2) 148 self.assertEqual(self.data.x_unit, ' A^{-1}')149 self.assertEqual(self.data.y_unit, ' cm^{-1}')146 self.assertEqual(self.data.x_unit, '1/A') 147 self.assertEqual(self.data.y_unit, '1/cm') 150 148 self.assertAlmostEqual(self.data.x[0], 0.02, 6) 151 149 self.assertAlmostEqual(self.data.y[0], 1000, 6) … … 259 257 self.assertTrue(item.date in ['04-Sep-2007 18:35:02', 260 258 '03-SEP-2006 11:42:47']) 259 print(item.term) 261 260 for t in item.term: 262 261 if (t['name'] == "ABS:DSTAND" … … 310 309 311 310 self.assertEqual(self.data.meta_data['loader'], "CanSAS XML 1D") 312 self.assertEqual(len(self.data.errors), 0) 311 print(self.data.errors) 312 self.assertEqual(len(self.data.errors), 1) 313 313 314 314 def test_slits(self): … … 324 324 # Data 325 325 self.assertEqual(len(self.data.x), 2) 326 self.assertEqual(self.data.x_unit, ' A^{-1}')327 self.assertEqual(self.data.y_unit, ' cm^{-1}')326 self.assertEqual(self.data.x_unit, '1/A') 327 self.assertEqual(self.data.y_unit, '1/cm') 328 328 self.assertEqual(self.data.x[0], 0.02) 329 329 self.assertEqual(self.data.y[0], 1000) … … 333 333 self.assertEqual(self.data.x[1], 0.03) 334 334 self.assertAlmostEquals(self.data.y[1], 1001.0) 335 self.assertEqual(self.data.dx [0], 0.0)335 self.assertEqual(self.data.dx, None) 336 336 self.assertEqual(self.data.dxl[1], 0.005) 337 337 self.assertEqual(self.data.dxw[1], 0.001) -
test/sasdataloader/test/utest_ascii.py
ra78a02f rad92c5a 32 32 self.assertEqual(self.f1.x[0],0.002618) 33 33 self.assertEqual(self.f1.x[9],0.0497) 34 self.assert True(self.f1.x_unit == 'A^{-1}')35 self.assert True(self.f1.y_unit == 'cm^{-1}')34 self.assertEqual(self.f1.x_unit, '1/A') 35 self.assertEqual(self.f1.y_unit, '1/cm') 36 36 37 37 self.assertEqual(self.f1.meta_data['loader'],"ASCII") -
test/sasdataloader/test/utest_cansas.py
r17e257b5 r1fc50fb2 20 20 21 21 from lxml import etree 22 from lxml.etree import XMLSyntaxError23 22 from xml.dom import minidom 24 23 … … 63 62 """ 64 63 invalid = StringIO.StringIO('<a><c></b></a>') 65 self.assertRaises(XMLSyntaxError, lambda: XMLreader(invalid))64 XMLreader(invalid) 66 65 67 66 def test_xml_validate(self): … … 303 302 self.assertTrue(data._yunit == "cm^{-1}") 304 303 self.assertTrue(data.y.size == 100) 305 self.assertAlmostEqual(data.y[ 40], 0.952749011516985)306 self.assertAlmostEqual(data.x[ 40], 0.3834415188257777)304 self.assertAlmostEqual(data.y[9], 0.952749011516985) 305 self.assertAlmostEqual(data.x[9], 0.3834415188257777) 307 306 self.assertAlmostEqual(len(data.meta_data), 0) 308 307 -
test/sasdataloader/test/utest_sesans.py
ra78a02f ra67c494 4 4 5 5 import unittest 6 from sas.sascalc.dataloader.loader_exceptions import FileContentsException,\7 DefaultReaderException8 6 from sas.sascalc.dataloader.readers.sesans_reader import Reader 9 7 from sas.sascalc.dataloader.loader import Loader … … 19 17 Test .SES in the full loader to make sure that the file type is correctly accepted 20 18 """ 21 file = Loader().load("sesans_examples/sphere2micron.ses") 22 f = file[0] 19 f = Loader().load("sesans_examples/sphere2micron.ses") 23 20 # self.assertEqual(f, 5) 24 21 self.assertEqual(len(f.x), 40) … … 37 34 Test .SES loading on a TOF dataset 38 35 """ 39 file = self.loader("sesans_examples/sphere_isis.ses") 40 f = file[0] 36 f = self.loader("sesans_examples/sphere_isis.ses") 41 37 self.assertEqual(len(f.x), 57) 42 38 self.assertEqual(f.x[-1], 19303.4) … … 52 48 """ 53 49 self.assertRaises( 54 FileContentsException,50 RuntimeError, 55 51 self.loader, 56 52 "sesans_examples/sesans_no_data.ses") … … 61 57 """ 62 58 self.assertRaises( 63 FileContentsException,59 RuntimeError, 64 60 self.loader, 65 61 "sesans_examples/no_spin_echo_unit.ses") 62 63 def test_sesans_no_version(self): 64 """ 65 Confirm that sesans files with no file format version raise an appropriate error 66 """ 67 self.assertRaises( 68 RuntimeError, 69 self.loader, 70 "sesans_examples/no_version.ses") 66 71 67 72 def test_sesans_future_version(self): … … 70 75 """ 71 76 self.assertRaises( 72 FileContentsException,77 RuntimeError, 73 78 self.loader, 74 79 "sesans_examples/next_gen.ses") … … 79 84 """ 80 85 self.assertRaises( 81 FileContentsException,86 RuntimeError, 82 87 self.loader, 83 88 "sesans_examples/no_wavelength.ses") … … 88 93 """ 89 94 self.assertRaises( 90 FileContentsException,95 RuntimeError, 91 96 self.loader, 92 97 "sesans_examples/too_many_headers.ses") -
test/utest_sasview.py
rb54440d raaf5e49 44 44 n_errors = 0 45 45 n_failures = 0 46 46 47 47 for d in (dirs if dirs else os.listdir(test_root)): 48 48 49 49 # Check for modules to be skipped 50 50 if d in SKIPPED_DIRS: 51 51 continue 52 52 53 53 54 54 # Go through modules looking for unit tests … … 64 64 #print std_out 65 65 #sys.exit() 66 has_failed = True 66 67 m = re.search("Ran ([0-9]+) test", std_out) 67 68 if m is not None: 69 has_failed = False 68 70 n_tests += int(m.group(1)) 69 has_tests = True70 else:71 has_tests = False72 71 73 has_failed = "FAILED (" in std_out 74 m = re.search("FAILED \(.*errors=([0-9]+)", std_out) 72 m = re.search("FAILED \(errors=([0-9]+)\)", std_out) 75 73 if m is not None: 74 has_failed = True 76 75 n_errors += int(m.group(1)) 77 m = re.search("FAILED \(.*failures=([0-9]+)", std_out) 76 77 m = re.search("FAILED \(failures=([0-9]+)\)", std_out) 78 78 if m is not None: 79 has_failed = True 79 80 n_failures += int(m.group(1)) 80 81 if has_failed or not has_tests:81 82 if has_failed: 82 83 failed += 1 83 84 print("Result for %s (%s): FAILED" % (module_name, module_dir)) … … 101 102 print(" Test errors: %d" % n_errors) 102 103 print("----------------------------------------------") 103 104 104 105 return failed 105 106 … … 109 110 if run_tests(dirs=dirs, all=all)>0: 110 111 sys.exit(1) 111 112
Note: See TracChangeset
for help on using the changeset viewer.