diff --git a/Code/Mantid/Algorithms/test/SimpleRebinTest.h b/Code/Mantid/Algorithms/test/SimpleRebinTest.h index 50d049a1955055a126b474d336f50dc452e10925..68a1612f60fa039052bc4c3c5deed83411c3af5c 100644 --- a/Code/Mantid/Algorithms/test/SimpleRebinTest.h +++ b/Code/Mantid/Algorithms/test/SimpleRebinTest.h @@ -70,6 +70,29 @@ public: AnalysisDataService::Instance().remove("test_out"); } + + + void testworkspace1D_dist_stupid_bins() + { + Workspace1D_sptr test_in1D = Create1DWorkspace(50); + test_in1D->isDistribution(true); + AnalysisDataService::Instance().add("test_in1D", test_in1D); + + SimpleRebin rebin; + rebin.initialize(); + rebin.setPropertyValue("InputWorkspace","test_in1D"); + rebin.setPropertyValue("OutputWorkspace","test_out"); + // Check it fails if "Params" property not set + TS_ASSERT_THROWS( rebin.execute(), std::runtime_error ); + TS_ASSERT( ! rebin.isExecuted() ); + // Way too many bins + rebin.setPropertyValue("Params", "0.0,1e-8,10"); + // Fails to execute + TS_ASSERT(!rebin.execute()); + TS_ASSERT(!rebin.isExecuted()); + AnalysisDataService::Instance().remove("test_in1D"); + } + void testworkspace1D_nondist() { Workspace1D_sptr test_in1D = Create1DWorkspace(50); @@ -103,6 +126,41 @@ public: AnalysisDataService::Instance().remove("test_out"); } + + void testworkspace1D_logarithmic_binning() + { + Workspace1D_sptr test_in1D = Create1DWorkspace(50); + test_in1D->isDistribution(true); + AnalysisDataService::Instance().add("test_in1D", test_in1D); + + SimpleRebin rebin; + rebin.initialize(); + rebin.setPropertyValue("InputWorkspace","test_in1D"); + rebin.setPropertyValue("OutputWorkspace","test_out"); + // Check it fails if "Params" property not set + TS_ASSERT_THROWS( rebin.execute(), std::runtime_error ); + TS_ASSERT( ! rebin.isExecuted() ); + // Now set the property + rebin.setPropertyValue("Params", "1.0,-1.0,1000.0"); + TS_ASSERT(rebin.execute()); + TS_ASSERT(rebin.isExecuted()); + MatrixWorkspace_sptr rebindata = boost::dynamic_pointer_cast<MatrixWorkspace>(AnalysisDataService::Instance().retrieve("test_out")); + const Mantid::MantidVec outX=rebindata->readX(0); + const Mantid::MantidVec outY=rebindata->readY(0); + const Mantid::MantidVec outE=rebindata->readE(0); + + TS_ASSERT_EQUALS(outX.size(), 11); + TS_ASSERT_DELTA(outX[0], 1.0 , 1e-5); + TS_ASSERT_DELTA(outX[1], 2.0 , 1e-5); + TS_ASSERT_DELTA(outX[2], 4.0 , 1e-5); //and so on... + TS_ASSERT_DELTA(outX[10], 1000.0 , 1e-5); + + bool dist=rebindata->isDistribution(); + TS_ASSERT(dist); + AnalysisDataService::Instance().remove("test_in1D"); + AnalysisDataService::Instance().remove("test_out"); + } + void testworkspace2D_dist() { Workspace2D_sptr test_in2D = Create2DWorkspace(50,20); diff --git a/Code/Mantid/DataHandling/src/Load.cpp b/Code/Mantid/DataHandling/src/Load.cpp index 40cf742a2eb0a5ad7634ae5938e0c31fcd55ea37..16a173f57348208eba933a75d3edb045241e1865 100644 --- a/Code/Mantid/DataHandling/src/Load.cpp +++ b/Code/Mantid/DataHandling/src/Load.cpp @@ -189,7 +189,7 @@ namespace Mantid if (wsg) { std::vector<std::string> names = wsg->getNames(); - for(int i = 1; i < names.size(); ++i) + for(size_t i = 1; i < names.size(); ++i) { std::ostringstream propName; propName << "OutputWorkspace_" << i; diff --git a/Code/Mantid/DataHandling/src/LoadEventPreNeXus.cpp b/Code/Mantid/DataHandling/src/LoadEventPreNeXus.cpp index 79abeb0c5fe1b25e54888a28f5428fd58fc5fea1..f4adb4ba653dd547e56bcd789bd71e972497023d 100644 --- a/Code/Mantid/DataHandling/src/LoadEventPreNeXus.cpp +++ b/Code/Mantid/DataHandling/src/LoadEventPreNeXus.cpp @@ -423,7 +423,7 @@ void LoadEventPreNeXus::procEventsParallel(DataObjects::EventWorkspace_sptr & wo std::cout << "# of unique pixels = " << num_unique_pixels << "\n"; //Will split in blocks of this size. - int num_cpus = 4; + size_t num_cpus = 4; //Size of block is 1/num_cpus, rounded up PixelType block_size = (num_unique_pixels + (num_cpus-1)) / num_cpus; @@ -452,7 +452,7 @@ void LoadEventPreNeXus::procEventsParallel(DataObjects::EventWorkspace_sptr & wo PARALLEL_FOR1(workspace) - for (int block_num=0; block_num < num_cpus; block_num++) + for (size_t block_num=0; block_num < num_cpus; block_num++) { std::cout << "Starting iterating through block " << block_num << "\n"; //Make an iterator into the map @@ -700,8 +700,6 @@ void LoadEventPreNeXus::loadPixelMap(const std::string &filename) this->g_log.debug("Using mapping file \"" + filename + "\""); ifstream * handle = new ifstream(filename.c_str(), std::ios::binary); - //TODO: Something here needs to be able to tell if a bad file is being fed! - size_t file_size = getFileSize<PixelType>(handle); //std::cout << "file is " << file_size << std::endl; size_t offset = 0; @@ -709,6 +707,7 @@ void LoadEventPreNeXus::loadPixelMap(const std::string &filename) PixelType * buffer = new PixelType[buffer_size]; size_t obj_size = sizeof(PixelType); + while (offset < file_size) { // read a section and put it into the object handle->read(reinterpret_cast<char *>(buffer), buffer_size * obj_size); diff --git a/Code/Mantid/DataHandling/test/LoadEventPreNeXusTest.h b/Code/Mantid/DataHandling/test/LoadEventPreNeXusTest.h index 4348db88f8167be1ac62d1d7520579b0bae4cbb9..d9030c9814359e0621218b7c8f2bb033d3e7e5b1 100644 --- a/Code/Mantid/DataHandling/test/LoadEventPreNeXusTest.h +++ b/Code/Mantid/DataHandling/test/LoadEventPreNeXusTest.h @@ -64,7 +64,6 @@ public: } - void test_LoadPreNeXus_TOPAZ() { //std::string eventfile( "/home/janik/data/TOPAZ_1241/preNeXus/TOPAZ_1241_neutron_event.dat" ); diff --git a/Code/Mantid/Kernel/src/RebinParamsValidator.cpp b/Code/Mantid/Kernel/src/RebinParamsValidator.cpp index b00d28fa6d0b942120612dd1c95719b097f4f66b..f1729e003d314f4ce7236009cc236dfbb13ac5dd 100644 --- a/Code/Mantid/Kernel/src/RebinParamsValidator.cpp +++ b/Code/Mantid/Kernel/src/RebinParamsValidator.cpp @@ -32,6 +32,10 @@ std::string RebinParamsValidator::checkValidity( const std::vector<double>& valu double previous = value[0]; for(size_t i=2; i < value.size(); i+=2) { + if ((value[i-1] < 0) && (previous==0)) + { + return "Logarithmic bins cannot start at 0.0"; + } if (value[i] <= previous) { return "Bin boundary values must be given in order of increasing value"; diff --git a/Code/Mantid/Kernel/src/VectorHelper.cpp b/Code/Mantid/Kernel/src/VectorHelper.cpp index 5ecf06a40eaf6cdda0b2153a15cc3070868a1a55..5c33e8c8229eae7a0ca5ff741348de165e1a1fbb 100644 --- a/Code/Mantid/Kernel/src/VectorHelper.cpp +++ b/Code/Mantid/Kernel/src/VectorHelper.cpp @@ -37,6 +37,13 @@ int DLLExport createAxisFromRebinParams(const std::vector<double>& params, std:: xs = params[istep]; else xs = xcurr * fabs(params[istep]); + + if (fabs(xs) == 0.0) + { + //Someone gave a 0-sized step! What a dope. + throw std::runtime_error("Invalid binning step provided! Can't creating binning axis."); + } + /* continue stepping unless we get to almost where we want to */ // Ensure that last bin in a range is not smaller than 25% of previous bin if ( (xcurr + xs*1.25) <= params[ibound] ) @@ -51,6 +58,13 @@ int DLLExport createAxisFromRebinParams(const std::vector<double>& params, std:: } xnew.push_back(xcurr); inew++; + + if (xnew.size() > 10000000) + { + //Max out at 1 million bins + throw std::runtime_error("Over ten million binning steps created. Exiting to avoid infinite loops."); + return inew; + } } return inew; diff --git a/Code/Mantid/Kernel/test/RebinParamsValidatorTest.h b/Code/Mantid/Kernel/test/RebinParamsValidatorTest.h index cb512c72e94a57c186980a3ca8e0fd6a36d6e9e1..bcb7c8f15e9eea648c6de288143a1ec97c1dfc74 100644 --- a/Code/Mantid/Kernel/test/RebinParamsValidatorTest.h +++ b/Code/Mantid/Kernel/test/RebinParamsValidatorTest.h @@ -13,8 +13,8 @@ public: { IValidator<std::vector<double> > *v = new RebinParamsValidator; IValidator<std::vector<double> > *vv = v->clone(); - TS_ASSERT_DIFFERS( v, vv ) - TS_ASSERT( dynamic_cast<RebinParamsValidator*>(vv) ) + TS_ASSERT_DIFFERS( v, vv ); + TS_ASSERT( dynamic_cast<RebinParamsValidator*>(vv) ); delete v; delete vv; } @@ -22,19 +22,19 @@ public: void testCast() { RebinParamsValidator *d = new RebinParamsValidator; - TS_ASSERT( dynamic_cast<IValidator<std::vector<double> >*>(d) ) + TS_ASSERT( dynamic_cast<IValidator<std::vector<double> >*>(d) ); delete d; } void testFailEmpty() { - TS_ASSERT( ! v.isValid(std::vector<double>()).empty() ) + TS_ASSERT( ! v.isValid(std::vector<double>()).empty() ); } void testFailWrongLength() { const std::vector<double> vec(6,1.0); - TS_ASSERT( ! v.isValid(vec).empty() ) + TS_ASSERT( ! v.isValid(vec).empty() ); } void testFailOutOfOrder() @@ -45,7 +45,22 @@ public: vec[2] = 2.0; vec[3] = 0.2; vec[4] = 1.5; - TS_ASSERT( ! v.isValid(vec).empty() ) + TS_ASSERT( ! v.isValid(vec).empty() ); + } + + void testFailZeroBin_or_bad_log() + { + //Don't give a 0 bin + std::vector<double> vec(3); + vec[0] = 1.0; + vec[1] = 0.0; + vec[2] = 2.0; + TS_ASSERT( ! v.isValid(vec).empty() ); + //Logarithmic bin starts at 0 + vec[0] = 0.0; + vec[1] = -1.0; + vec[2] = 200.0; + TS_ASSERT( ! v.isValid(vec).empty() ); } void testCorrect() @@ -56,7 +71,7 @@ public: vec[2] = 2.0; vec[3] = 0.2; vec[4] = 2.5; - TS_ASSERT( v.isValid(vec).empty() ) + TS_ASSERT( v.isValid(vec).empty() ); } private: