diff --git a/modules/base/src/string_ref.cc b/modules/base/src/string_ref.cc index 46705256523ef07bd300cf016b19bc9f94056ed7..03209b11fabacadbff82daae3f36c80b1140f898 100644 --- a/modules/base/src/string_ref.cc +++ b/modules/base/src/string_ref.cc @@ -18,6 +18,7 @@ //------------------------------------------------------------------------------ #include <ost/string_ref.hh> +#include <math.h> namespace ost { @@ -53,6 +54,11 @@ std::pair<bool, float> StringRef::to_float() const int sig=1; bool after_dot=false; float factor=0.1; + bool after_exponent=false; + float exponent=0.0; + int exponent_sig=1; + bool after_exponent_sign=false; + for (const char* c=begin_; c!=end_; ++c) { if (*c=='-' && empty) { empty=false; @@ -71,17 +77,41 @@ std::pair<bool, float> StringRef::to_float() const if (after_dot==true) { n+=factor*int(*c-'0'); factor*=0.1; + } else if (after_exponent==true) { + exponent=exponent*10+int(*c-'0'); } else { n=n*10+int(*c-'0'); } continue; } + if ((*c=='+' || *c=='-') && after_exponent==true) { + if (after_exponent_sign==true) { + return std::make_pair(false, 0.0f); + } + if (*c=='-') { + exponent_sig=-1; + } + after_exponent_sign=true; + continue; + } + if (*c=='e' || *c=='E') { + if (after_exponent==true) { + return std::make_pair(false, 0.0f); + } + after_exponent=true; + after_dot=false; + continue; + } return std::make_pair(false, 0.0f); } if (empty) { return std::make_pair(false, 0.0f); } - return std::make_pair(true, sig*n); + if (after_exponent==false) { + return std::make_pair(true, sig*n); + } else { + return std::make_pair(true, sig*n*float(pow(10,exponent_sig*exponent))); + } } std::ostream& operator<<(std::ostream& stream, const StringRef& strref) diff --git a/modules/base/tests/test_string_ref.cc b/modules/base/tests/test_string_ref.cc index 50793bff7f83bde41e88047717d31687b7fbe5f8..05ea7701ec963d2d89f0c6098c9272e2cd59d3f2 100644 --- a/modules/base/tests/test_string_ref.cc +++ b/modules/base/tests/test_string_ref.cc @@ -84,6 +84,55 @@ BOOST_AUTO_TEST_CASE( test_string_ref) BOOST_CHECK(r2.first==false); r2=StringRef("12.34.", 6).to_float(); BOOST_CHECK(r2.first==false); + + // to_float_with_exp + std::pair<bool, Real> r3=StringRef("1", 1).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK(r3.second=1.0); + r3=StringRef("1.5", 3).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK(r3.second=1.5); + r3=StringRef("x", 1).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("12.3.4", 6).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("12.34.", 6).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("12.34e5", 7).to_float(); + BOOST_CHECK(r3.first==true); + r3=StringRef("12e4", 4).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK_CLOSE(Real(120000), Real(r3.second), Real(1e-4)); + r3=StringRef("2e+4", 4).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK_CLOSE(Real(20000), Real(r3.second), Real(1e-4)); + r3=StringRef("2.3E+4", 6).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK_CLOSE(Real(23000), Real(r3.second), Real(1e-4)); + r3=StringRef("2.3E-4", 6).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK_CLOSE(Real(0.00023), Real(r3.second), Real(1e-4)); + r3=StringRef("2.010000e+00", 12).to_float(); + BOOST_CHECK(r3.first==true); + BOOST_CHECK_CLOSE(Real(2.01), Real(r3.second), Real(1e-4)); + r3=StringRef("5e-34", 5).to_float(); + BOOST_CHECK(r3.first==true); + r3=StringRef("5E-34", 5).to_float(); + BOOST_CHECK(r3.first==true); + r3=StringRef("5.34e-34", 8).to_float(); + BOOST_CHECK(r3.first==true); + r3=StringRef("5.34e-34e", 9).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("5.34ee34", 8).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("5.34e--34e", 10).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("5.34e+3+4", 9).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("5.34e-+34e", 10).to_float(); + BOOST_CHECK(r3.first==false); + r3=StringRef("5.34e-3-4", 9).to_float(); + BOOST_CHECK(r3.first==false); } BOOST_AUTO_TEST_SUITE_END() diff --git a/modules/gui/pymod/export_data_viewer.cc b/modules/gui/pymod/export_data_viewer.cc index 993f272a8bbf28417568c1118e1b847acb040665..1a3ada014c63e320b7448a0896238fa169a280b0 100644 --- a/modules/gui/pymod/export_data_viewer.cc +++ b/modules/gui/pymod/export_data_viewer.cc @@ -73,6 +73,7 @@ void export_data_viewer() .def("AddOverlay",&DataViewer::AddOverlay,o_AddOverlay()) .def("ClearOverlays",&DataViewer::ClearOverlays) .def("GetSelection",&DataViewer::GetSelection) + .def("SetSelection",&DataViewer::SetSelection) .def("UpdateView",&DataViewer::UpdateView) .def("Recenter",&DataViewer::Recenter) .def("AddDockWidget",add_dock1) diff --git a/modules/gui/src/data_viewer/data_viewer.cc b/modules/gui/src/data_viewer/data_viewer.cc index 14e15380a5c3dbc2e271b8dec3d99cdefb59bea1..a0d75b28f02c392663832d1e4b02d427326115e1 100644 --- a/modules/gui/src/data_viewer/data_viewer.cc +++ b/modules/gui/src/data_viewer/data_viewer.cc @@ -118,6 +118,12 @@ Extent DataViewer::GetSelection() const return panel_->GetSelection(); } +void DataViewer::SetSelection(const Extent& selection) +{ + assert(panel_); + panel_->SetSelection(selection); +} + void DataViewer::SetName(const String& name) { setWindowTitle(QString::fromStdString(name)); diff --git a/modules/gui/src/data_viewer/data_viewer.hh b/modules/gui/src/data_viewer/data_viewer.hh index 3fd08f9775ea06762342272e6ce41d5f40737856..6594b588cfb4a00b9710d8da4dcd618680b64d3b 100644 --- a/modules/gui/src/data_viewer/data_viewer.hh +++ b/modules/gui/src/data_viewer/data_viewer.hh @@ -80,6 +80,9 @@ public: //! return currently active selection Extent GetSelection() const; + //! set currently active selection + void SetSelection(const Extent& selection); + //! set the name, displayed as the window title void SetName(const String& name); diff --git a/modules/gui/src/data_viewer/data_viewer_panel_base.cc b/modules/gui/src/data_viewer/data_viewer_panel_base.cc index ec113e525419d81359650d68106d9a868ec9d7e6..9249bef7d2bf66487ef423ad37f50e9f4e506ae0 100644 --- a/modules/gui/src/data_viewer/data_viewer_panel_base.cc +++ b/modules/gui/src/data_viewer/data_viewer_panel_base.cc @@ -643,6 +643,18 @@ Extent DataViewerPanelBase::GetSelection() const return selection_; } +void DataViewerPanelBase::SetSelection(const Extent& selection) +{ + selection_=selection; + update_rubberband_from_selection_(); + if(selection==Extent()){ + rubberband_->hide(); + }else{ + rubberband_->show(); + } + UpdateView(false); +} + Real DataViewerPanelBase::GetZoomScale() const { return zoom_scale_; diff --git a/modules/gui/src/data_viewer/data_viewer_panel_base.hh b/modules/gui/src/data_viewer/data_viewer_panel_base.hh index 60999a9003355073ef1810d7067c0a7f635a0847..9e165925e8e516f9320ee85da51ca895eb1b806c 100644 --- a/modules/gui/src/data_viewer/data_viewer_panel_base.hh +++ b/modules/gui/src/data_viewer/data_viewer_panel_base.hh @@ -101,6 +101,9 @@ public: */ Extent GetSelection() const; + //! set currently active selection + void SetSelection(const Extent& extent); + //! convert window coordinates to image point Point WinToPoint(int mx, int my) const; Point WinToPoint(const QPoint& p) const; diff --git a/modules/gui/src/messages/message_widget.cc b/modules/gui/src/messages/message_widget.cc index 983a4ec169ee450f4b88ef2a0821c1fa90420582..038840ae1482d064608385c2e62225c8b7f19b88 100644 --- a/modules/gui/src/messages/message_widget.cc +++ b/modules/gui/src/messages/message_widget.cc @@ -61,6 +61,7 @@ MessageWidget::MessageWidget(QWidget* parent) : view_->setDragEnabled(true); view_->setContextMenuPolicy(Qt::CustomContextMenu); view_->setFrameShape(QFrame::NoFrame); + view_->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel); layout->addWidget(view_); connect(view_, SIGNAL(customContextMenuRequested(const QPoint&)), this, diff --git a/modules/index.rst b/modules/index.rst index afc2142cfb81f0b06d9c83755207b29523132d7a..89bb6d3614d7c91c7fb9050a1fc9f9ab73deecc3 100644 --- a/modules/index.rst +++ b/modules/index.rst @@ -93,6 +93,9 @@ Varia **Datasets:** :doc:`tabular data <table>` +**File Formats:** :doc:`supported file formats <io/formats>` + + Extending OpenStructure -------------------------------------------------------------------------------- @@ -102,4 +105,4 @@ Extending OpenStructure - \ No newline at end of file + diff --git a/modules/io/doc/formats.rst b/modules/io/doc/formats.rst index 3912141d21a5a59de7aeb94306e7e014890c1069..fc6fee4cb8e12e0b2ed01731d0a213be18270b76 100644 --- a/modules/io/doc/formats.rst +++ b/modules/io/doc/formats.rst @@ -71,3 +71,116 @@ Promod *Format Name* promod + + +Image File Formats +-------------------------------------------------------------------------------- + +DAT +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + dat, img + +*Format Name* + Simple binary format for square images + +DF3 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + df3 + +*Format Name* + PovRay Density file format + +DM3 +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + dm3 + +*Format Name* + Format used by Gatan Inc.'s Digital Micrograph software + +DX +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + dx + +*Format Name* + Format used by the OpenDX software package + +IPL +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + ipl + +*Format Name* + Ditabis Micron Image Plate Scanner Format + +JPK +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + jpk + +*Format Name* + Format used by JPK Instruments AG's software (Customized Tiff format) + +MRC +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + map, ccp4, mrc + +*Format Name* + Format used by the MRC software package + +NanoScope +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + mod + +*Format Name* + Format used by software from Veeco + +PNG +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + png + +*Format Name* + Portable Network Graphic image format + +Situs +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + situs, sit + +*Format Name* + Format used by the Situs software package + +SPI +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + spi + +*Format Name* + Format used by the Spider software package + +TIFF +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +*Recognized File Extensions* + tif, tiff + +*Format Name* + Tagged Image File Format + diff --git a/modules/io/src/img/map_io_dx_handler.cc b/modules/io/src/img/map_io_dx_handler.cc index 70303c97a08da2e8565cc3241ad5e7d9e27d8af8..4509d327d51187961802658a214d69c8b8bdf245 100644 --- a/modules/io/src/img/map_io_dx_handler.cc +++ b/modules/io/src/img/map_io_dx_handler.cc @@ -24,6 +24,9 @@ #include <sstream> #include <ost/log.hh> +#include <ost/string_ref.hh> +#include <boost/iostreams/filter/gzip.hpp> +#include <boost/iostreams/filtering_stream.hpp> #include <boost/filesystem/fstream.hpp> #include <boost/filesystem/convenience.hpp> #include <boost/lexical_cast.hpp> @@ -43,6 +46,23 @@ namespace ost { namespace io { using boost::format; +namespace { + +bool IEquals(const StringRef& a, const StringRef& b) +{ + if (a.size()!=b.size()) { + return false; + } + for (size_t i=0; i<a.size(); ++i) { + if (toupper(a[i])!=b[i]) { + return false; + } + } + return true; +} + +} + String DX::FORMAT_STRING="defined_dx"; DX::DX (bool normalize_on_save): @@ -68,8 +88,12 @@ void MapIODxHandler::Import(img::MapHandle& mh, const bf::path& loc,const ImageF { throw IOException("could not open "+loc.string()); } - - this->Import(mh,infile,form); + boost::iostreams::filtering_stream<boost::iostreams::input> in; + if (boost::iequals(".gz", boost::filesystem::extension(loc))) { + in.push(boost::iostreams::gzip_decompressor()); + } + in.push(infile); + this->Import(mh,in,form); infile.close(); } @@ -91,6 +115,9 @@ void MapIODxHandler::Import(img::MapHandle& mh, std::istream& infile, const Imag img::MapHandle mh2; std::vector<String> tokens; while (std::getline(infile,line)) { + if (line.empty()) { + continue; + } // read gridpoints line if (boost::iequals(line.substr(0,35), "object 1 class gridpositions counts")) { boost::split(tokens, line, boost::is_any_of(" "), boost::token_compress_on); @@ -183,14 +210,14 @@ void MapIODxHandler::Import(img::MapHandle& mh, std::istream& infile, const Imag Real value=0; for(int i=0; i<num_gridpoints; i+=3) { std::getline(infile,line); - boost::split(tokens, line, boost::is_any_of(" "), boost::token_compress_on); - for (size_t j=0; j<tokens.size()-1; j++) { // three values per line - try { - value=boost::lexical_cast<Real>(boost::trim_copy(tokens[j])); - } catch(boost::bad_lexical_cast&) { - format fmer = format("Bad value line: Can't convert grid point value '%s' to Real constant.") % line; - throw IOException(fmer.str()); - } + StringRef curr_line(line.c_str(), line.size()); + std::vector<StringRef> fields=curr_line.split(' '); + for (size_t j=0; j<fields.size(); j++) { + std::pair<bool, float> result=fields[j].trim().to_float(); + if (!result.first) { + throw IOException((format("Bad value line: Can't convert grid point value '%s' to Real constant.") % line).str()); + } + value=result.second; mh2.SetReal(img::Point(((i+j)/(v_size*w_size))%u_size,((i+j)/w_size)%v_size, (i+j)%w_size), value); } } @@ -266,10 +293,10 @@ bool MapIODxHandler::MatchType(const ImageFormatBase& formatstruct) } bool MapIODxHandler::MatchSuffix(const String& loc) { - if(detail::FilenameEndsWith(loc,".dx") ) { - return true; - } - return false; + if(detail::FilenameEndsWith(loc,".dx") || detail::FilenameEndsWith(loc,".dx.gz")) { + return true; + } + return false; } }} // ns