[prev in list] [next in list] [prev in thread] [next in thread]
List: kde-commits
Subject: [labplot] /: 1. Added NetCDF as import format
From: Stefan Gerlach <stefan.gerlach () uni-konstanz ! de>
Date: 2015-05-31 18:01:56
Message-ID: E1Yz7Ya-0000Nj-Kh () scm ! kde ! org
[Download RAW message or body]
Git commit fc0a3f92354e4bcccc76a0c194be1b85c8a87575 by Stefan Gerlach.
Committed on 31/05/2015 at 18:00.
Pushed by sgerlach into branch 'master'.
1. Added NetCDF as import format
2. Added NetCDF filter for NetCDF file handling
3. Parser for NetCDF files added
M +22 -11 CMakeLists.txt
M +1 -1 ChangeLog
M +1 -0 INSTALL
M +5 -2 src/CMakeLists.txt
M +1 -1 src/backend/datasources/FileDataSource.cpp
A +506 -0 src/backend/datasources/filters/NetCDFFilter.cpp [License: GPL \
(v2+)] A +73 -0 src/backend/datasources/filters/NetCDFFilter.h [License: \
GPL (v2+)] A +85 -0 src/backend/datasources/filters/NetCDFFilterPrivate.h \
[License: GPL (v2+)] M +59 -6 src/kdefrontend/datasources/ImportFileWidget.cpp
M +2 -0 src/kdefrontend/datasources/ImportFileWidget.h
A +41 -0 src/kdefrontend/datasources/NetCDFOptionsWidget.cpp [License: GPL \
(v2+)] A +45 -0 src/kdefrontend/datasources/NetCDFOptionsWidget.h [License: \
GPL (v2+)] A +48 -0 src/kdefrontend/ui/datasources/netcdfoptionswidget.ui
http://commits.kde.org/labplot/fc0a3f92354e4bcccc76a0c194be1b85c8a87575
diff --git a/CMakeLists.txt b/CMakeLists.txt
index aff4795..ce7d2ed 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -80,17 +80,28 @@ ELSE (HDF5_FOUND)
ENDIF (HDF5_FOUND)
# ### NETCDF #####################################
-# FIND_LIBRARY(NETCDF_LIBRARY
-# NAMES netcdf
-# )
-# IF(NETCDF_LIBRARY)
-# MESSAGE ("-- Found NETCDF library: ${NETCDF_LIBRARY}")
-# add_definitions (-DHAVE_NETCDF=1)
-# ELSE(NETCDF_LIBRARY)
-# MESSAGE ("-- NETCDF library NOT FOUND!")
-# SET(NETCDF_LIBRARY "")
-# ENDIF(NETCDF_LIBRARY)
-#
+FIND_LIBRARY(NETCDF_LIBRARY netcdf
+ PATHS
+ /usr/lib
+ /usr/local/lib
+)
+FIND_PATH (NETCDF_INCLUDE_DIR netcdf.h
+ /usr/include/
+ /usr/local/include/
+)
+IF (NETCDF_LIBRARY AND NETCDF_INCLUDE_DIR)
+ SET (NETCDF_FOUND TRUE)
+ELSE (NETCDF_LIBRARY AND NETCDF_INCLUDE_DIR)
+ SET (NETCDF_FOUND FALSE)
+ SET (NETCDF_LIBRARY "")
+ENDIF (NETCDF_LIBRARY AND NETCDF_INCLUDE_DIR)
+IF (NETCDF_FOUND)
+ MESSAGE (STATUS "Found Network Common Data Format (NetCDF) Library: \
${NETCDF_INCLUDE_DIR} ${NETCDF_LIBRARY}") + add_definitions (-DHAVE_NETCDF=1)
+ELSE (NETCDF_FOUND)
+ MESSAGE (STATUS "Network Common Data Format (NetCDF) Library not found.")
+ENDIF (NETCDF_FOUND)
+
# ### CDF #####################################
# FIND_LIBRARY(CDF_LIBRARY
# NAMES cdf
diff --git a/ChangeLog b/ChangeLog
index a676496..5c41ea1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -2,7 +2,7 @@
New features:
* New Matrix view for handling matrix data
* Import of binary, image and HDF data into spreadsheet or matrix
- * Visual HDF parser to view content of files and import data sets
+ * Visual HDF and NetCDF parser to view content of files and import data sets
* Preview of all supported file types in import dialog
* Transparently import compressed data files
* In xy-curve the points may not be connected by the line if there are NANs \
in-between. This behaviour is controlled by the parameter "skip gaps"
diff --git a/INSTALL b/INSTALL
index 4771760..608df2e 100644
--- a/INSTALL
+++ b/INSTALL
@@ -3,6 +3,7 @@ LabPlot requires
* GSL version 1.15 or higher
optional
* HDF5 1.8 or higher
+ * NetCDF 3 or higher
===============================================================================
To build LabPlot just execute
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index c02b85a..3bfb8d1 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -20,10 +20,11 @@ set(GUI_SOURCES
${KDEFRONTEND_DIR}/datasources/AsciiMatrixOptionsWidget.cpp
${KDEFRONTEND_DIR}/datasources/BinaryOptionsWidget.cpp
${KDEFRONTEND_DIR}/datasources/HDFOptionsWidget.cpp
+ ${KDEFRONTEND_DIR}/datasources/FileInfoDialog.cpp
${KDEFRONTEND_DIR}/datasources/ImageOptionsWidget.cpp
${KDEFRONTEND_DIR}/datasources/ImportFileWidget.cpp
${KDEFRONTEND_DIR}/datasources/ImportFileDialog.cpp
- ${KDEFRONTEND_DIR}/datasources/FileInfoDialog.cpp
+ ${KDEFRONTEND_DIR}/datasources/NetCDFOptionsWidget.cpp
${KDEFRONTEND_DIR}/dockwidgets/AxisDock.cpp
${KDEFRONTEND_DIR}/dockwidgets/CartesianPlotDock.cpp
${KDEFRONTEND_DIR}/dockwidgets/CartesianPlotLegendDock.cpp
@@ -64,6 +65,7 @@ set(UI_SOURCES
${KDEFRONTEND_DIR}/ui/datasources/hdfoptionswidget.ui
${KDEFRONTEND_DIR}/ui/datasources/imageoptionswidget.ui
${KDEFRONTEND_DIR}/ui/datasources/importfilewidget.ui
+ ${KDEFRONTEND_DIR}/ui/datasources/netcdfoptionswidget.ui
${KDEFRONTEND_DIR}/ui/dockwidgets/axisdock.ui
${KDEFRONTEND_DIR}/ui/dockwidgets/cartesianplotdock.ui
${KDEFRONTEND_DIR}/ui/dockwidgets/cartesianplotlegenddock.ui
@@ -124,6 +126,7 @@ set(BACKEND_SOURCES
${BACKEND_DIR}/datasources/filters/BinaryFilter.cpp
${BACKEND_DIR}/datasources/filters/HDFFilter.cpp
${BACKEND_DIR}/datasources/filters/ImageFilter.cpp
+ ${BACKEND_DIR}/datasources/filters/NetCDFFilter.cpp
${BACKEND_DIR}/gsl/ExpressionParser.cpp
${BACKEND_DIR}/gsl/parser.tab.c
${BACKEND_DIR}/matrix/Matrix.cpp
@@ -176,7 +179,7 @@ set(LABPLOT_SRCS ${GUI_SOURCES} ${PLOTS_SOURCES})
INCLUDE_DIRECTORIES(. ${GSL_INCLUDE_DIR} ${GSL_INCLUDEDIR}/..)
kde4_add_ui_files(LABPLOT_SRCS ${UI_SOURCES})
kde4_add_executable(labplot2 ${LABPLOT_SRCS} ${BACKEND_SOURCES} \
${DATASOURCES_SOURCES} ${COMMONFRONTEND_SOURCES} ${TOOLS_SOURCES})
-target_link_libraries(labplot2 ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${GSL_LIBRARIES} \
${GSL_CBLAS_LIBRARIES} ${HDF5_LIBRARY}) +target_link_libraries(labplot2 \
${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${GSL_LIBRARIES} ${GSL_CBLAS_LIBRARIES} \
${HDF5_LIBRARY} ${NETCDF_LIBRARY}) # ${OPJ_LIBRARY}
############## installation ################################
diff --git a/src/backend/datasources/FileDataSource.cpp \
b/src/backend/datasources/FileDataSource.cpp index 967bb0d..7102e67 100644
--- a/src/backend/datasources/FileDataSource.cpp
+++ b/src/backend/datasources/FileDataSource.cpp
@@ -105,7 +105,7 @@ QStringList FileDataSource::fileTypes(){
<< i18n("Binary data")
<< i18n("Image")
<< i18n("Hierarchical Data Format (HDF)")
-// << "NetCDF"
+ << i18n("Network Common Data Format (NetCDF)")
// << "CDF"
// << "FITS"
// << i18n("Sound")
diff --git a/src/backend/datasources/filters/NetCDFFilter.cpp \
b/src/backend/datasources/filters/NetCDFFilter.cpp new file mode 100644
index 0000000..5278ab3
--- /dev/null
+++ b/src/backend/datasources/filters/NetCDFFilter.cpp
@@ -0,0 +1,506 @@
+/***************************************************************************
+File : NetCDFFilter.cpp
+Project : LabPlot
+Description : NetCDF I/O-filter
+--------------------------------------------------------------------
+Copyright : (C) 2015 by Stefan Gerlach (stefan.gerlach@uni.kn)
+***************************************************************************/
+
+/***************************************************************************
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the Free Software *
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+* Boston, MA 02110-1301 USA *
+* *
+***************************************************************************/
+#include "backend/datasources/filters/NetCDFFilter.h"
+#include "backend/datasources/filters/NetCDFFilterPrivate.h"
+#include "backend/datasources/FileDataSource.h"
+#include "backend/core/column/Column.h"
+
+#include <math.h>
+
+#include <QFile>
+#include <QTextStream>
+#include <QDebug>
+#include <KLocale>
+#include <KIcon>
+
+/*!
+ \class NetCDFFilter
+ \brief Manages the import/export of data from/to a NetCDF file.
+
+ \ingroup datasources
+*/
+NetCDFFilter::NetCDFFilter():AbstractFileFilter(), d(new NetCDFFilterPrivate(this)){
+
+}
+
+NetCDFFilter::~NetCDFFilter(){
+ delete d;
+}
+
+/*!
+ parses the content of the file \c fileName.
+*/
+void NetCDFFilter::parse(const QString & fileName, QTreeWidgetItem* rootItem){
+ d->parse(fileName, rootItem);
+}
+
+/*!
+ reads the content of the data set \c dataSet from file \c fileName.
+*/
+/*QString NetCDFFilter::readCurrentDataSet(const QString & fileName, \
AbstractDataSource* dataSource, AbstractFileFilter::ImportMode importMode, int \
lines){ + return d->readCurrentDataSet(fileName, dataSource, importMode, lines);
+}*/
+
+/*!
+ reads the content of the file \c fileName to the data source \c dataSource.
+*/
+void NetCDFFilter::read(const QString & fileName, AbstractDataSource* dataSource, \
AbstractFileFilter::ImportMode importMode){ + d->read(fileName, dataSource, \
importMode); +}
+
+/*!
+writes the content of the data source \c dataSource to the file \c fileName.
+*/
+void NetCDFFilter::write(const QString & fileName, AbstractDataSource* dataSource){
+ d->write(fileName, dataSource);
+// emit()
+}
+
+///////////////////////////////////////////////////////////////////////
+/*!
+ loads the predefined filter settings for \c filterName
+*/
+void NetCDFFilter::loadFilterSettings(const QString& filterName){
+ Q_UNUSED(filterName);
+}
+
+/*!
+ saves the current settings as a new filter with the name \c filterName
+*/
+void NetCDFFilter::saveFilterSettings(const QString& filterName) const{
+ Q_UNUSED(filterName);
+}
+
+///////////////////////////////////////////////////////////////////////
+
+/*void NetCDFFilter::setCurrentDataSet(QString ds){
+ d->currentDataSet = ds;
+}
+
+QString NetCDFFilter::currentDataSet() const{
+ return d->currentDataSet;
+}*/
+
+void NetCDFFilter::setStartRow(const int s) {
+ d->startRow = s;
+}
+
+int NetCDFFilter::startRow() const{
+ return d->startRow;
+}
+
+void NetCDFFilter::setEndRow(const int e) {
+ d->endRow = e;
+}
+
+int NetCDFFilter::endRow() const{
+ return d->endRow;
+}
+
+void NetCDFFilter::setStartColumn(const int c){
+ d->startColumn=c;
+}
+
+int NetCDFFilter::startColumn() const{
+ return d->startColumn;
+}
+
+void NetCDFFilter::setEndColumn(const int c){
+ d->endColumn=c;
+}
+
+int NetCDFFilter::endColumn() const{
+ return d->endColumn;
+}
+
+void NetCDFFilter::setAutoModeEnabled(bool b){
+ d->autoModeEnabled = b;
+}
+
+bool NetCDFFilter::isAutoModeEnabled() const{
+ return d->autoModeEnabled;
+}
+//#####################################################################
+//################### Private implementation ##########################
+//#####################################################################
+
+NetCDFFilterPrivate::NetCDFFilterPrivate(NetCDFFilter* owner) :
+ q(owner),startRow(1), endRow(-1),startColumn(1),endColumn(-1) {
+}
+
+#ifdef HAVE_NETCDF
+void NetCDFFilterPrivate::handleError(int status, QString function) {
+ if (status != NC_NOERR) {
+ qDebug()<<"ERROR:"<<function<<"() - "<<nc_strerror(status);
+ }
+}
+
+QString NetCDFFilterPrivate::translateDataType(nc_type type) {
+ QString typeString;
+
+ switch(type) {
+ case NC_BYTE:
+ typeString="BYTE";
+ break;
+ case NC_UBYTE:
+ typeString="UBYTE";
+ break;
+ case NC_CHAR:
+ typeString="CHAR";
+ break;
+ case NC_SHORT:
+ typeString="SHORT";
+ break;
+ case NC_USHORT:
+ typeString="USHORT";
+ break;
+ case NC_INT:
+ typeString="INT";
+ break;
+ case NC_UINT:
+ typeString="UINT";
+ break;
+// case NC_LONG:
+// typeString="LONG";
+// break;
+ case NC_INT64:
+ typeString="INT64";
+ break;
+ case NC_UINT64:
+ typeString="UINT64";
+ break;
+ case NC_FLOAT:
+ typeString="FLOAT";
+ break;
+ case NC_DOUBLE:
+ typeString="DOUBLE";
+ break;
+ case NC_STRING:
+ typeString="STRING";
+ break;
+ default:
+ typeString="UNKNOWN";
+ }
+
+ return typeString;
+}
+
+void NetCDFFilterPrivate::scanAttrs(int ncid, int varid, int nattr, QTreeWidgetItem* \
parentItem) { + int status;
+
+ char name[NC_MAX_NAME + 1];
+ nc_type type;
+ size_t len;
+ for(int i=0;i<nattr;i++) {
+ status = nc_inq_attname(ncid,varid,i,name);
+ handleError(status,"nc_inq_attname");
+
+ status = nc_inq_att(ncid, varid, name, &type, &len);
+ handleError(status,"nc_inq_att");
+ qDebug()<<" attr"<<i+1<<": name/type/len="<<name<<translateDataType(type)<<len;
+
+ //read attribute
+ QStringList valueString;
+ switch(type) {
+ case NC_BYTE: {
+ signed char *value = (signed char *)malloc(len*sizeof(signed char));
+ status = nc_get_att_schar(ncid, varid, name, value);
+ handleError(status,"nc_get_att_schar");
+ for(unsigned int l=0;l<len;l++)
+ valueString<<QString::number(value[l]);
+ free(value);
+ break;
+ }
+ case NC_UBYTE: {
+ unsigned char *value = (unsigned char *)malloc(len*sizeof(unsigned char));
+ status = nc_get_att_uchar(ncid, varid, name, value);
+ handleError(status,"nc_get_att_uchar");
+ for(unsigned int l=0;l<len;l++)
+ valueString<<QString::number(value[l]);
+ free(value);
+ break;
+ }
+ case NC_CHAR: {
+ char *value = (char *)malloc((len+1)*sizeof(char));
+ status = nc_get_att_text(ncid, varid, name, value);
+ handleError(status,"nc_get_att_text");
+ value[len]=0;
+ valueString<<value;
+ free(value);
+ break;
+ }
+ case NC_SHORT: {
+ short *value = (short *)malloc(len*sizeof(short));
+ status = nc_get_att_short(ncid, varid, name, value);
+ handleError(status,"nc_get_att_short");
+ for(unsigned int l=0;l<len;l++)
+ valueString<<QString::number(value[l]);
+ free(value);
+ break;
+ }
+ case NC_USHORT: {
+ unsigned short *value = (unsigned short *)malloc(len*sizeof(unsigned short));
+ status = nc_get_att_ushort(ncid, varid, name, value);
+ handleError(status,"nc_get_att_ushort");
+ for(unsigned int l=0;l<len;l++)
+ valueString<<QString::number(value[l]);
+ free(value);
+ break;
+ }
+ case NC_INT: {
+ int *value = (int *)malloc(len*sizeof(int));
+ status = nc_get_att_int(ncid, varid, name, value);
+ handleError(status,"nc_get_att_int");
+ for(unsigned int l=0;l<len;l++)
+ valueString<<QString::number(value[l]);
+ free(value);
+ break;
+ }
+ case NC_UINT: {
+ unsigned int *value = (unsigned int *)malloc(len*sizeof(unsigned int));
+ status = nc_get_att_uint(ncid, varid, name, value);
+ handleError(status,"nc_get_att_uint");
+ for(unsigned int l=0;l<len;l++)
+ valueString<<QString::number(value[l]);
+ free(value);
+ break;
+ }
+ case NC_INT64: {
+ long long *value = (long long *)malloc(len*sizeof(long long));
+ status = nc_get_att_longlong(ncid, varid, name, value);
+ handleError(status,"nc_get_att_longlong");
+ for(unsigned int l=0;l<len;l++)
+ valueString<<QString::number(value[l]);
+ free(value);
+ break;
+ }
+ case NC_UINT64: {
+ unsigned long long *value = (unsigned long long *)malloc(len*sizeof(unsigned long \
long)); + status = nc_get_att_ulonglong(ncid, varid, name, value);
+ handleError(status,"nc_get_att_ulonglong");
+ for(unsigned int l=0;l<len;l++)
+ valueString<<QString::number(value[l]);
+ free(value);
+ break;
+ }
+ case NC_FLOAT: {
+ float *value = (float *)malloc(len*sizeof(float));
+ status = nc_get_att_float(ncid, varid, name, value);
+ handleError(status,"nc_get_att_float");
+ for(unsigned int l=0;l<len;l++)
+ valueString<<QString::number(value[l]);
+ free(value);
+ break;
+ }
+ case NC_DOUBLE: {
+ double *value = (double *)malloc(len*sizeof(double));
+ status = nc_get_att_double(ncid, varid, name, value);
+ handleError(status,"nc_get_att_double");
+ for(unsigned int l=0;l<len;l++)
+ valueString<<QString::number(value[l]);
+ free(value);
+ break;
+ }
+ default:
+ valueString<<"not supported";
+ }
+
+ QStringList props;
+ props<<translateDataType(type)<<" ("<<QString::number(len)<<")";
+ QTreeWidgetItem *attrItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString(name)<<props.join("")<<valueString.join(", ")); \
+ attrItem->setIcon(0,QIcon(KIcon("accessories-calculator"))); \
+ parentItem->addChild(attrItem); + }
+}
+
+void NetCDFFilterPrivate::scanDims(int ncid, int ndims, QTreeWidgetItem* parentItem) \
{ + int status;
+
+ int ulid;
+ status = nc_inq_unlimdim(ncid,&ulid);
+ handleError(status,"nc_inq_att");
+
+ char name[NC_MAX_NAME + 1];
+ size_t len;
+ for(int i=0;i<ndims;i++) {
+ status = nc_inq_dim(ncid, i, name, &len);
+ handleError(status,"nc_inq_att");
+ qDebug()<<" dim"<<i+1<<": name/len="<<name<<len;
+
+ QStringList props;
+ props<<"length = "<<QString::number(len);
+ QString value;
+ if(i == ulid)
+ value="unlimited";
+ QTreeWidgetItem *attrItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString(name)<<props.join("")<<value); \
+ attrItem->setIcon(0,QIcon(KIcon("accessories-calculator"))); \
+ parentItem->addChild(attrItem); + }
+}
+
+void NetCDFFilterPrivate::scanVars(int ncid, int nvars, QTreeWidgetItem* parentItem) \
{ + int status;
+
+ char name[NC_MAX_NAME + 1];
+ nc_type type;
+ int ndims, nattrs;
+ int dimids[NC_MAX_VAR_DIMS];
+
+ for(int i=0;i<nvars;i++) {
+ status = nc_inq_var(ncid, i, name, &type, &ndims, dimids, &nattrs);
+ handleError(status,"nc_inq_att");
+
+ qDebug()<<" var"<<i+1<<": name/type="<<name<<translateDataType(type);
+ qDebug()<<" ndims/nattr"<<ndims<<nattrs;
+
+ QStringList props;
+ props<<translateDataType(type);
+ char dname[NC_MAX_NAME + 1];
+ size_t dlen;
+ for(int j=0;j<ndims;j++) {
+ status = nc_inq_dim(ncid, dimids[j], dname, &dlen);
+ if(j==0)
+ props<<" ("<<QString::number(dlen);
+ else
+ props<<"x"<<QString::number(dlen);
+ }
+ props<<")";
+
+ QTreeWidgetItem *varItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString(name)<<props.join("")); \
+ varItem->setIcon(0,QIcon(KIcon("x-office-spreadsheet"))); \
+ varItem->setBackground(0,QBrush(QColor(192,255,192))); \
+ parentItem->addChild(varItem); +
+ scanAttrs(ncid,i,nattrs,varItem);
+ }
+}
+#endif
+
+/*!
+ parses the content of the file \c fileName and fill the tree using rootItem.
+*/
+void NetCDFFilterPrivate::parse(const QString & fileName, QTreeWidgetItem* rootItem) \
{ +#ifdef HAVE_NETCDF
+ QByteArray bafileName = fileName.toLatin1();
+
+ int status, ncid;
+ status = nc_open(bafileName.data(), NC_NOWRITE, &ncid);
+ handleError(status,"nc_open");
+
+ int ndims, nvars, nattr, uldid;
+ status = nc_inq(ncid, &ndims, &nvars, &nattr, &uldid);
+ handleError(status,"nc_inq");
+ qDebug()<<" nattr/ndims/nvars ="<<nattr<<ndims<<nvars;
+
+ QTreeWidgetItem *attrItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString("Attributes")); + attrItem->setIcon(0,QIcon(KIcon("folder")));
+ rootItem->addChild(attrItem);
+ scanAttrs(ncid,NC_GLOBAL,nattr,attrItem);
+
+ QTreeWidgetItem *dimItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString("Dimensions")); + dimItem->setIcon(0,QIcon(KIcon("folder")));
+ rootItem->addChild(dimItem);
+ scanDims(ncid,ndims,dimItem);
+
+ QTreeWidgetItem *varItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<QString("Variables")); + varItem->setIcon(0,QIcon(KIcon("folder")));
+ rootItem->addChild(varItem);
+ scanVars(ncid,nvars,varItem);
+
+ //TODO: scan NetCDF file
+#else
+ Q_UNUSED(fileName)
+ Q_UNUSED(rootItem)
+#endif
+}
+
+/*!
+ reads the content of the file \c fileName to the data source \c dataSource.
+ Uses the settings defined in the data source.
+*/
+void NetCDFFilterPrivate::read(const QString & fileName, AbstractDataSource* \
dataSource, AbstractFileFilter::ImportMode mode){ + Q_UNUSED(fileName);
+ Q_UNUSED(dataSource);
+ Q_UNUSED(mode);
+ //TODO
+
+/* if(currentDataSet.isEmpty()) {
+ qDebug()<<" No data set selected";
+ return;
+ }
+
+#ifdef QT_DEBUG
+ else
+ qDebug()<<" current data set ="<<currentDataSet;
+#endif
+*/
+// readCurrentDataSet(fileName,dataSource,mode);
+}
+
+/*!
+ writes the content of \c dataSource to the file \c fileName.
+*/
+void NetCDFFilterPrivate::write(const QString & fileName, AbstractDataSource* \
dataSource){ + Q_UNUSED(fileName);
+ Q_UNUSED(dataSource);
+ //TODO
+}
+
+//##############################################################################
+//################## Serialization/Deserialization ###########################
+//##############################################################################
+
+/*!
+ Saves as XML.
+ */
+void NetCDFFilter::save(QXmlStreamWriter* writer) const {
+ writer->writeStartElement("hdfFilter");
+ writer->writeAttribute("autoMode", QString::number(d->autoModeEnabled) );
+ writer->writeEndElement();
+}
+
+/*!
+ Loads from XML.
+*/
+bool NetCDFFilter::load(XmlStreamReader* reader) {
+ if(!reader->isStartElement() || reader->name() != "hdfFilter"){
+ reader->raiseError(i18n("no hdf filter element found"));
+ return false;
+ }
+
+ QString attributeWarning = i18n("Attribute '%1' missing or empty, default value is \
used"); + QXmlStreamAttributes attribs = reader->attributes();
+
+ // read attributes
+ QString str = attribs.value("autoMode").toString();
+ if(str.isEmpty())
+ reader->raiseWarning(attributeWarning.arg("'autoMode'"));
+ else
+ d->autoModeEnabled = str.toInt();
+
+ return true;
+}
diff --git a/src/backend/datasources/filters/NetCDFFilter.h \
b/src/backend/datasources/filters/NetCDFFilter.h new file mode 100644
index 0000000..245e0f5
--- /dev/null
+++ b/src/backend/datasources/filters/NetCDFFilter.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+File : NetCDFFilter.h
+Project : LabPlot
+Description : NetCDF I/O-filter
+--------------------------------------------------------------------
+Copyright : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn)
+***************************************************************************/
+
+/***************************************************************************
+* *
+* This program is free software; you can redistribute it and/or modify *
+* it under the terms of the GNU General Public License as published by *
+* the Free Software Foundation; either version 2 of the License, or *
+* (at your option) any later version. *
+* *
+* This program is distributed in the hope that it will be useful, *
+* but WITHOUT ANY WARRANTY; without even the implied warranty of *
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+* GNU General Public License for more details. *
+* *
+* You should have received a copy of the GNU General Public License *
+* along with this program; if not, write to the Free Software *
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+* Boston, MA 02110-1301 USA *
+* *
+***************************************************************************/
+#ifndef NETCDFFILTER_H
+#define NETCDFFILTER_H
+
+#include <QStringList>
+#include <QTreeWidgetItem>
+#include "backend/datasources/filters/AbstractFileFilter.h"
+
+class NetCDFFilterPrivate;
+class NetCDFFilter : public AbstractFileFilter{
+ Q_OBJECT
+
+ public:
+
+ NetCDFFilter();
+ ~NetCDFFilter();
+
+ void parse(const QString & fileName, QTreeWidgetItem* rootItem);
+ void read(const QString & fileName, AbstractDataSource* dataSource, \
AbstractFileFilter::ImportMode importMode=AbstractFileFilter::Replace); +// QString \
readCurrentDataSet(const QString & fileName, AbstractDataSource* dataSource, \
AbstractFileFilter::ImportMode importMode=AbstractFileFilter::Replace, int lines=-1); \
+ void write(const QString & fileName, AbstractDataSource* dataSource); +
+ void loadFilterSettings(const QString&);
+ void saveFilterSettings(const QString&) const;
+
+/* void setCurrentDataSet(const QString);
+ QString currentDataSet() const;
+*/
+ void setStartRow(const int);
+ int startRow() const;
+ void setEndRow(const int);
+ int endRow() const;
+ void setStartColumn(const int);
+ int startColumn() const;
+ void setEndColumn(const int);
+ int endColumn() const;
+
+ void setAutoModeEnabled(const bool);
+ bool isAutoModeEnabled() const;
+
+ virtual void save(QXmlStreamWriter*) const;
+ virtual bool load(XmlStreamReader*);
+ private:
+ NetCDFFilterPrivate* const d;
+ friend class NetCDFFilterPrivate;
+};
+
+#endif
diff --git a/src/backend/datasources/filters/NetCDFFilterPrivate.h \
b/src/backend/datasources/filters/NetCDFFilterPrivate.h new file mode 100644
index 0000000..ab9c178
--- /dev/null
+++ b/src/backend/datasources/filters/NetCDFFilterPrivate.h
@@ -0,0 +1,85 @@
+/***************************************************************************
+File : NetCDFFilterPrivate.h
+Project : LabPlot
+Description : Private implementation class for NetCDFFilter.
+--------------------------------------------------------------------
+Copyright : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn)
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ ***************************************************************************/
+#ifndef NETCDFFILTERPRIVATE_H
+#define NETCDFFILTERPRIVATE_H
+
+#ifdef HAVE_NETCDF
+#include <netcdf.h>
+#endif
+
+class AbstractDataSource;
+
+class NetCDFFilterPrivate {
+
+ public:
+ explicit NetCDFFilterPrivate(NetCDFFilter*);
+
+ void parse(const QString & fileName, QTreeWidgetItem* rootItem);
+ void read(const QString & fileName, AbstractDataSource* dataSource,
+ AbstractFileFilter::ImportMode importMode = AbstractFileFilter::Replace);
+ //QString readCurrentDataSet(const QString & fileName, AbstractDataSource* \
dataSource, AbstractFileFilter::ImportMode importMode=AbstractFileFilter::Replace, \
int lines=-1); + void write(const QString & fileName, AbstractDataSource* \
dataSource); +
+ const NetCDFFilter* q;
+
+ //QString currentDataSet;
+ int startRow;
+ int endRow;
+ int startColumn;
+ int endColumn;
+ bool autoModeEnabled;
+
+ private:
+ //const static int MAXNAMELENGTH=1024;
+ //QList<unsigned long> multiLinkList; // used to find hard links
+#ifdef HAVE_NETCDF
+ void handleError(int status, QString function);
+ QString translateDataType(nc_type type);
+ void scanAttrs(int ncid, int varid, int nattr, QTreeWidgetItem* parentItem);
+ void scanDims(int ncid, int ndims, QTreeWidgetItem* parentItem);
+ void scanVars(int ncid, int nvars, QTreeWidgetItem* parentItem);
+/* QString translateHDFOrder(H5T_order_t);
+ QString translateHDFType(hid_t);
+ QString translateHDFClass(H5T_class_t);
+ QStringList readHDFCompound(hid_t tid);
+ template <typename T> QStringList readHDFData1D(hid_t dataset, hid_t type, int \
rows, int lines, QVector<double> *dataPointer=NULL); + QStringList \
readHDFCompoundData1D(hid_t dataset, hid_t tid, int rows, int lines,QVector< \
QVector<double>* >& dataPointer); + template <typename T> QStringList \
readHDFData2D(hid_t dataset, hid_t ctype, int rows, int cols, int lines, QVector< \
QVector<double>* >& dataPointer); + QStringList readHDFCompoundData2D(hid_t dataset, \
hid_t tid, int rows, int cols, int lines); + QStringList readHDFAttr(hid_t aid);
+ QStringList scanHDFAttrs(hid_t oid);
+ QStringList readHDFDataType(hid_t tid);
+ QStringList readHDFPropertyList(hid_t pid);
+ void scanHDFDataType(hid_t tid, char *dataTypeName, QTreeWidgetItem* parentItem);
+ void scanHDFLink(hid_t gid, char *linkName, QTreeWidgetItem* parentItem);
+ void scanHDFDataSet(hid_t dsid, char *dataSetName, QTreeWidgetItem* parentItem);
+ void scanHDFGroup(hid_t gid, char *groupName, QTreeWidgetItem* parentItem);
+*/
+#endif
+};
+
+#endif
diff --git a/src/kdefrontend/datasources/ImportFileWidget.cpp \
b/src/kdefrontend/datasources/ImportFileWidget.cpp index 10e66e6..3e02051 100644
--- a/src/kdefrontend/datasources/ImportFileWidget.cpp
+++ b/src/kdefrontend/datasources/ImportFileWidget.cpp
@@ -33,6 +33,7 @@ Copyright : (C) 2009-2012 Alexander Semke \
(alexander.semke@web.de) #include "backend/datasources/filters/AsciiFilter.h"
#include "backend/datasources/filters/BinaryFilter.h"
#include "backend/datasources/filters/HDFFilter.h"
+#include "backend/datasources/filters/NetCDFFilter.h"
#include "backend/datasources/filters/ImageFilter.h"
#include <QInputDialog>
@@ -85,21 +86,30 @@ ImportFileWidget::ImportFileWidget(QWidget* parent) : \
QWidget(parent) {
QWidget* hdfw=new QWidget(0);
hdfOptionsWidget.setupUi(hdfw);
- QStringList headers;
- headers<<i18n("Name")<<i18n("Link")<<i18n("Type")<<i18n("Properties")<<i18n("Attributes");
- hdfOptionsWidget.twContent->setHeaderLabels(headers);
+ QStringList hdfheaders;
+ hdfheaders<<i18n("Name")<<i18n("Link")<<i18n("Type")<<i18n("Properties")<<i18n("Attributes");
+ hdfOptionsWidget.twContent->setHeaderLabels(hdfheaders);
// link and type column are filled but we don't need to show it
hdfOptionsWidget.twContent->hideColumn(1);
hdfOptionsWidget.twContent->hideColumn(2);
ui.swOptions->insertWidget(FileDataSource::HDF, hdfw);
+ QWidget* netcdfw=new QWidget(0);
+ netcdfOptionsWidget.setupUi(netcdfw);
+ QStringList headers;
+ headers<<i18n("Name")<<i18n("Properties")<<i18n("Values");
+ netcdfOptionsWidget.twContent->setHeaderLabels(headers);
+ ui.swOptions->insertWidget(FileDataSource::NETCDF, netcdfw);
+
// default filter
ui.swOptions->setCurrentIndex(FileDataSource::Ascii);
// disable items
- //ui.cbFileType->setItemData(FileDataSource::Image, 0, Qt::UserRole - 1);
#ifndef HAVE_HDF5
ui.cbFileType->setItemData(FileDataSource::HDF, 0, Qt::UserRole - 1);
#endif
+#ifndef HAVE_NETCDF
+ ui.cbFileType->setItemData(FileDataSource::NETCDF, 0, Qt::UserRole - 1);
+#endif
ui.gbOptions->hide();
@@ -145,6 +155,8 @@ ImportFileWidget::ImportFileWidget(QWidget* parent) : \
QWidget(parent) { // HDF data
connect( hdfOptionsWidget.twContent, SIGNAL(itemActivated(QTreeWidgetItem*,int)), \
SLOT(hdfTreeWidgetItemSelected(QTreeWidgetItem*,int)) );
+ // NetCDF data
+
//general settings
ui.cbFileType->setCurrentIndex(conf.readEntry("Type", 0));
ui.kleFileName->setText(conf.readEntry("LastImportedFile", ""));
@@ -184,7 +196,7 @@ ImportFileWidget::~ImportFileWidget() {
// image data
conf.writeEntry("ImportFormat", imageOptionsWidget.cbImportFormat->currentIndex());
- //HDF data
+ //HDF/NetCDF data
// nothing
}
@@ -313,6 +325,23 @@ AbstractFileFilter* ImportFileWidget::currentFileFilter() const{
return filter;
break;
}
+ case FileDataSource::NETCDF: {
+ NetCDFFilter* filter = new NetCDFFilter();
+ if ( ui.cbFilter->currentIndex()==0 ){ //"automatic"
+ filter->setAutoModeEnabled(true);
+ }else if ( ui.cbFilter->currentIndex()==1 ){ //"custom"
+ filter->setAutoModeEnabled(false);
+ } else {
+// filter->setFilterName( ui.cbFilter->currentText() );
+ }
+ filter->setStartRow( ui.sbStartRow->value() );
+ filter->setEndRow( ui.sbEndRow->value() );
+ filter->setStartColumn( ui.sbStartColumn->value() );
+ filter->setEndColumn( ui.sbEndColumn->value() );
+
+ return filter;
+ break;
+ }
default:
qDebug()<<"Unknown file type!";
}
@@ -420,6 +449,24 @@ void ImportFileWidget::fileNameChanged(const QString& name) {
hdfOptionsWidget.twContent->expandAll();
hdfOptionsWidget.twContent->resizeColumnToContents(0);
hdfOptionsWidget.twContent->resizeColumnToContents(3);
+ } else if (info.contains(("NetCDF Data Format"))) {
+ debug="detected NetCDF file";
+ ui.cbFileType->setCurrentIndex(FileDataSource::NETCDF);
+
+ // update NetCDF tree widget using current selected file
+ netcdfOptionsWidget.twContent->clear();
+ netcdfOptionsWidget.leDataSet->clear();
+
+ QString fileName = ui.kleFileName->text();
+ QFileInfo fileInfo(fileName);
+ QTreeWidgetItem *rootItem = new QTreeWidgetItem((QTreeWidget*)0, \
QStringList()<<fileInfo.baseName()); + NetCDFFilter *filter = (NetCDFFilter \
*)this->currentFileFilter(); + filter->parse(fileName, rootItem);
+ netcdfOptionsWidget.twContent->insertTopLevelItem(0,rootItem);
+ netcdfOptionsWidget.twContent->expandAll();
+ netcdfOptionsWidget.twContent->resizeColumnToContents(0);
+ netcdfOptionsWidget.twContent->resizeColumnToContents(1);
+
} else {
debug="probably BINARY file";
ui.cbFileType->setCurrentIndex(FileDataSource::Binary);
@@ -479,7 +526,8 @@ void ImportFileWidget::fileTypeChanged(int fileType) {
ui.sbEndColumn->hide();
break;
}
- case FileDataSource::HDF: {
+ case FileDataSource::HDF:
+ case FileDataSource::NETCDF: {
break;
}
case FileDataSource::Image: {
@@ -594,6 +642,11 @@ void ImportFileWidget::refreshPreview(){
importedText = filter->readCurrentDataSet(fileName,NULL,AbstractFileFilter::Replace,lines);
break;
}
+ case FileDataSource::NETCDF: {
+ NetCDFFilter *filter = (NetCDFFilter *)this->currentFileFilter();
+ //TODO: importedText = \
filter->readCurrentDataSet(fileName,NULL,AbstractFileFilter::Replace,lines); \
+ break; + }
default:
importedText += "Unknown file type";
}
diff --git a/src/kdefrontend/datasources/ImportFileWidget.h \
b/src/kdefrontend/datasources/ImportFileWidget.h index 206f7ad..23c7579 100644
--- a/src/kdefrontend/datasources/ImportFileWidget.h
+++ b/src/kdefrontend/datasources/ImportFileWidget.h
@@ -35,6 +35,7 @@
#include "BinaryOptionsWidget.h"
#include "HDFOptionsWidget.h"
#include "ImageOptionsWidget.h"
+#include "NetCDFOptionsWidget.h"
class FileDataSource;
class AbstractFileFilter;
@@ -59,6 +60,7 @@ private:
Ui::BinaryOptionsWidget binaryOptionsWidget;
Ui::HDFOptionsWidget hdfOptionsWidget;
Ui::ImageOptionsWidget imageOptionsWidget;
+ Ui::NetCDFOptionsWidget netcdfOptionsWidget;
private slots:
void fileNameChanged(const QString&);
diff --git a/src/kdefrontend/datasources/NetCDFOptionsWidget.cpp \
b/src/kdefrontend/datasources/NetCDFOptionsWidget.cpp new file mode 100644
index 0000000..11f2dd3
--- /dev/null
+++ b/src/kdefrontend/datasources/NetCDFOptionsWidget.cpp
@@ -0,0 +1,41 @@
+/***************************************************************************
+File : NetCDFOptionsWidget.cpp
+Project : LabPlot
+Description : widget providing options for the import of NetCDF data
+--------------------------------------------------------------------
+Copyright : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn)
+***************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ ***************************************************************************/
+#include "NetCDFOptionsWidget.h"
+
+ /*!
+ \class NetCDFOptionsWidget
+ \brief Widget providing options for the import of NetCDF data
+
+ \ingroup kdefrontend
+ */
+
+NetCDFOptionsWidget::NetCDFOptionsWidget(QWidget* parent) : QWidget(parent) {
+ ui.setupUi(this);
+}
+
+NetCDFOptionsWidget::~NetCDFOptionsWidget() {
+}
diff --git a/src/kdefrontend/datasources/NetCDFOptionsWidget.h \
b/src/kdefrontend/datasources/NetCDFOptionsWidget.h new file mode 100644
index 0000000..5642e68
--- /dev/null
+++ b/src/kdefrontend/datasources/NetCDFOptionsWidget.h
@@ -0,0 +1,45 @@
+/***************************************************************************
+File : NetCDFOptionsWidget.h
+Project : LabPlot
+Description : widget providing options for the import of NetCDF data
+--------------------------------------------------------------------
+Copyright : (C) 2015 Stefan Gerlach (stefan.gerlach@uni.kn)
+
+**************************************************************************/
+
+/***************************************************************************
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the Free Software *
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, *
+ * Boston, MA 02110-1301 USA *
+ * *
+ ***************************************************************************/
+#ifndef NETCDFOPTIONSWIDGET_H
+#define NETCDFOPTIONSWIDGET_H
+
+#include "ui_netcdfoptionswidget.h"
+
+
+class NetCDFOptionsWidget : public QWidget{
+ Q_OBJECT
+
+public:
+ explicit NetCDFOptionsWidget(QWidget*);
+ ~NetCDFOptionsWidget();
+
+private:
+ Ui::NetCDFOptionsWidget ui;
+};
+
+#endif
diff --git a/src/kdefrontend/ui/datasources/netcdfoptionswidget.ui \
b/src/kdefrontend/ui/datasources/netcdfoptionswidget.ui new file mode 100644
index 0000000..157abef
--- /dev/null
+++ b/src/kdefrontend/ui/datasources/netcdfoptionswidget.ui
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<ui version="4.0">
+ <class>NetCDFOptionsWidget</class>
+ <widget class="QWidget" name="NetCDFOptionsWidget">
+ <property name="geometry">
+ <rect>
+ <x>0</x>
+ <y>0</y>
+ <width>613</width>
+ <height>505</height>
+ </rect>
+ </property>
+ <layout class="QGridLayout" name="gridLayout">
+ <item row="0" column="0">
+ <layout class="QHBoxLayout" name="horizontalLayout">
+ <item>
+ <widget class="QLabel" name="lDataSet">
+ <property name="text">
+ <string>Data set:</string>
+ </property>
+ </widget>
+ </item>
+ <item>
+ <widget class="QLineEdit" name="leDataSet">
+ <property name="toolTip">
+ <string>Selected data set</string>
+ </property>
+ </widget>
+ </item>
+ </layout>
+ </item>
+ <item row="1" column="0">
+ <widget class="QTreeWidget" name="twContent">
+ <property name="toolTip">
+ <string>Shows the content of a NetCDF file</string>
+ </property>
+ <column>
+ <property name="text">
+ <string notr="true">1</string>
+ </property>
+ </column>
+ </widget>
+ </item>
+ </layout>
+ </widget>
+ <resources/>
+ <connections/>
+</ui>
[prev in list] [next in list] [prev in thread] [next in thread]
Configure |
About |
News |
Add a list |
Sponsored by KoreLogic