mirror of
https://github.com/jkriege2/JKQtPlotter.git
synced 2024-12-25 01:51:49 +08:00
added JKQTPDatastore::appendFromContainerToColumn() and JKQTPDatastore::appendToColumn() that extend columns with additional rows (and move the to internal storage implicitly)
This commit is contained in:
parent
db3194898c
commit
8edab9865e
@ -159,6 +159,14 @@ This call results in a column with these 30 values spanning the range between 1
|
||||
1, 1.26896, 1.61026, 2.04336, ..., 8.53168, 10.8264, 13.7382, ..., 72.7895, 92.3671, ..., 788.046, 1000
|
||||
```
|
||||
|
||||
### Appending to Columns
|
||||
You can use the methods `JKQTPDatastore::appendToColumn()` and `JKQTPDatastore::appendFromContainerToColumn()` to extend columns with additional values, e.g.:
|
||||
```.cpp
|
||||
for (double ii=10; ii<=20; ii++) datastore->appendToColumn(columnID, ii);
|
||||
```
|
||||
Note that this operation changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards! If the first append is called on a column that cannot be extended, the contents will be copied and the column will reference the new, internally managed, memory afterwards.
|
||||
|
||||
|
||||
### Using Data from one Column to Calculate Another
|
||||
|
||||
After generating columns, as shown above, you can also use the data in these columns to calculate a second column based on the values in the first. You can do this explicitly:
|
||||
|
@ -85,7 +85,7 @@ void JKQTPColumn::copyData(QVector<double> ©To) const
|
||||
if (cnt>0) {
|
||||
copyTo.resize(static_cast<int>(cnt));
|
||||
for (i=0; i<cnt; i++) {
|
||||
copyTo[i]=d[i];
|
||||
copyTo[static_cast<int>(i)]=d[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -182,24 +182,27 @@ void JKQTPColumn::setAll(double value)
|
||||
**************************************************************************************************************************/
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
JKQTPDatastoreItem::JKQTPDatastoreItem(){
|
||||
this->dataformat=JKQTPSingleColumn;
|
||||
this->dataformat=JKQTPDatastoreItemFormat::SingleColumn;
|
||||
this->allocated=false;
|
||||
this->data=nullptr;
|
||||
this->columns=0;
|
||||
this->rows=0;
|
||||
this->internal=true;
|
||||
this->storageType=StorageType::Internal;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
JKQTPDatastoreItem::JKQTPDatastoreItem(size_t columns, size_t rows){
|
||||
this->internal=true;
|
||||
this->storageType=StorageType::Internal;
|
||||
this->allocated=false;
|
||||
if (columns>1) {
|
||||
this->dataformat=JKQTPMatrixRow;
|
||||
this->dataformat=JKQTPDatastoreItemFormat::MatrixRow;
|
||||
this->data=static_cast<double*>(calloc(columns*rows, sizeof(double)));
|
||||
} else {
|
||||
this->dataformat=JKQTPSingleColumn;
|
||||
this->data=static_cast<double*>(calloc(rows, sizeof(double)));
|
||||
this->dataformat=JKQTPDatastoreItemFormat::SingleColumn;
|
||||
this->storageType=StorageType::Vector;
|
||||
datavec.resize(static_cast<int>(columns*rows));
|
||||
for( double& d: datavec) { d=0.0; }
|
||||
this->data=datavec.data();
|
||||
}
|
||||
this->columns=columns;
|
||||
this->rows=rows;
|
||||
@ -207,15 +210,29 @@ JKQTPDatastoreItem::JKQTPDatastoreItem(size_t columns, size_t rows){
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastoreItem::resizeColumns(size_t new_rows) {
|
||||
if (internal && allocated && data!=nullptr) {
|
||||
bool JKQTPDatastoreItem::resizeColumns(size_t new_rows) {
|
||||
bool dataRetained=false;
|
||||
if (storageType==StorageType::Internal && allocated && data!=nullptr) {
|
||||
free(data);
|
||||
data=nullptr;
|
||||
}
|
||||
data=static_cast<double*>(calloc(columns*new_rows, sizeof(double)));
|
||||
if (columns>1) {
|
||||
this->dataformat=JKQTPDatastoreItemFormat::MatrixRow;
|
||||
this->data=static_cast<double*>(calloc(columns*new_rows, sizeof(double)));
|
||||
storageType=StorageType::Internal;
|
||||
} else {
|
||||
this->dataformat=JKQTPDatastoreItemFormat::SingleColumn;
|
||||
this->storageType=StorageType::Vector;
|
||||
datavec.resize(static_cast<int>(columns*new_rows));
|
||||
if (new_rows>rows) {
|
||||
for( size_t i=rows; i<new_rows; i++) { datavec[static_cast<int>(i)]=0.0; }
|
||||
}
|
||||
this->data=datavec.data();
|
||||
dataRetained=true;
|
||||
}
|
||||
rows=new_rows;
|
||||
internal=true;
|
||||
allocated=true;
|
||||
return dataRetained;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -225,7 +242,7 @@ JKQTPDatastoreItem::JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, doub
|
||||
this->data=data;
|
||||
this->columns=columns;
|
||||
this->rows=rows;
|
||||
this->internal=false;
|
||||
this->storageType=StorageType::External;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -236,12 +253,12 @@ JKQTPDatastoreItem::JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, doub
|
||||
this->data=data;
|
||||
this->columns=columns;
|
||||
this->rows=rows;
|
||||
this->internal=internal;
|
||||
this->storageType=internal?StorageType::Internal:StorageType::External;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
JKQTPDatastoreItem::~JKQTPDatastoreItem(){
|
||||
if (internal && allocated && data!=nullptr) {
|
||||
if (storageType==StorageType::Internal && allocated && data!=nullptr) {
|
||||
free(data);
|
||||
data=nullptr;
|
||||
}
|
||||
@ -390,16 +407,16 @@ JKQTPColumn JKQTPDatastore::getColumn(int i) const
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t JKQTPDatastore::addCopiedItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columnsnum, size_t rows) {
|
||||
JKQTPDatastoreItem* it=nullptr;
|
||||
if ((dataformat==JKQTPSingleColumn)||(columnsnum==1)) {
|
||||
if ((dataformat==JKQTPDatastoreItemFormat::SingleColumn)||(columnsnum==1)) {
|
||||
return addCopiedItem(data, rows);
|
||||
} else if (dataformat==JKQTPMatrixColumn) {
|
||||
} else if (dataformat==JKQTPDatastoreItemFormat::MatrixColumn) {
|
||||
it=new JKQTPDatastoreItem(columnsnum, rows);
|
||||
for (size_t c=0; c<columnsnum; c++) {
|
||||
for (size_t r=0; r<rows; r++) {
|
||||
it->set(c, r, data[c*rows+r]);
|
||||
}
|
||||
}
|
||||
} else if (dataformat==JKQTPMatrixColumn) {
|
||||
} else if (dataformat==JKQTPDatastoreItemFormat::MatrixColumn) {
|
||||
it=new JKQTPDatastoreItem(columnsnum, rows);
|
||||
for (size_t r=0; r<rows; r++) {
|
||||
for (size_t c=0; c<columnsnum; c++) {
|
||||
@ -432,13 +449,13 @@ size_t JKQTPDatastore::addItem(size_t columnsnum, size_t rows) {
|
||||
size_t JKQTPDatastore::addItem(double* data, size_t rows) {
|
||||
/*items.push_back(new JKQTPDatastoreItem(JKQTPSingleColumn, data, 1, rows));
|
||||
return items.size()-1;*/
|
||||
return addItem(new JKQTPDatastoreItem(JKQTPSingleColumn, data, 1, rows));
|
||||
return addItem(new JKQTPDatastoreItem(JKQTPDatastoreItemFormat::SingleColumn, data, 1, rows));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t JKQTPDatastore::addInternalItem(double *data, size_t rows)
|
||||
{
|
||||
JKQTPDatastoreItem* dsi=new JKQTPDatastoreItem(JKQTPSingleColumn, data, 1, rows, true);
|
||||
JKQTPDatastoreItem* dsi=new JKQTPDatastoreItem(JKQTPDatastoreItemFormat::SingleColumn, data, 1, rows, true);
|
||||
return addItem(dsi);
|
||||
};
|
||||
|
||||
@ -485,7 +502,7 @@ size_t JKQTPDatastore::addColumn(double* data, size_t rows, const QString& name)
|
||||
//std::cout<<"added item\n";
|
||||
//size_t it=items.size()-1;
|
||||
//std::cout<<"adding column\n";
|
||||
size_t it=addItem(new JKQTPDatastoreItem(JKQTPSingleColumn, data, 1, rows));
|
||||
size_t it=addItem(new JKQTPDatastoreItem(JKQTPDatastoreItemFormat::SingleColumn, data, 1, rows));
|
||||
return addColumnForItem(it, 0, name);
|
||||
};
|
||||
|
||||
@ -495,7 +512,7 @@ size_t JKQTPDatastore::addInternalColumn(double* data, size_t rows, const QStrin
|
||||
//std::cout<<"added item\n";
|
||||
//size_t it=items.size()-1;
|
||||
//std::cout<<"adding column\n";
|
||||
size_t it=addItem(new JKQTPDatastoreItem(JKQTPSingleColumn, data, 1, rows,true));
|
||||
size_t it=addItem(new JKQTPDatastoreItem(JKQTPDatastoreItemFormat::SingleColumn, data, 1, rows,true));
|
||||
return addColumnForItem(it, 0, name);
|
||||
}
|
||||
|
||||
@ -538,7 +555,7 @@ size_t JKQTPDatastore::copyColumn(size_t old_column, size_t start, size_t stride
|
||||
size_t rows=old.getRows();
|
||||
double* d=static_cast<double*>(malloc(rows*sizeof(double)));
|
||||
double* dd=old.getPointer(0);
|
||||
int j=0;
|
||||
size_t j=0;
|
||||
for (size_t i=start; i<rows; i+=stride) {
|
||||
d[j]=dd[i];
|
||||
//qDebug()<<old_column<<name<<": "<<j<<i<<d[j];
|
||||
@ -666,14 +683,23 @@ size_t JKQTPDatastore::addColumnCalculatedFromColumn(size_t otherColumnX, size_t
|
||||
return addColumnForItem(itemid, 0, name);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
QVector<int> JKQTPDatastore::getColumnIDsIntVec() const {
|
||||
QVector<int> ks;
|
||||
for (const size_t& k: columns.keys()) {
|
||||
ks<<static_cast<int>(k);
|
||||
}
|
||||
return ks;
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int JKQTPDatastore::getNextLowerIndex(size_t column, size_t row, int start, int end) const
|
||||
{
|
||||
const JKQTPColumn& col=columns[column];
|
||||
if (start<0 && end>=0) return getNextLowerIndex(column, row, 0, end);
|
||||
else if (start>=0 && end<0) return getNextLowerIndex(column, row, start, col.getRows()-1);
|
||||
else if (start<0 && end<0) return getNextLowerIndex(column, row, 0, col.getRows()-1);
|
||||
else if (start>=0 && end<0) return getNextLowerIndex(column, row, start, static_cast<int>(col.getRows())-1);
|
||||
else if (start<0 && end<0) return getNextLowerIndex(column, row, 0, static_cast<int>(col.getRows())-1);
|
||||
else {
|
||||
double d=0;
|
||||
const double v=col.getValue(row);
|
||||
@ -698,7 +724,7 @@ int JKQTPDatastore::getNextLowerIndex(size_t column, size_t row, int start, int
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int JKQTPDatastore::getNextLowerIndex(size_t column, size_t row) const
|
||||
{
|
||||
return getNextLowerIndex(column, row, 0, columns[column].getRows()-1);
|
||||
return getNextLowerIndex(column, row, 0, static_cast<int>(columns[column].getRows())-1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -706,8 +732,8 @@ int JKQTPDatastore::getNextHigherIndex(size_t column, size_t row, int start, int
|
||||
{
|
||||
const JKQTPColumn& col=columns[column];
|
||||
if (start<0 && end>=0) return getNextHigherIndex(column, row, 0, end);
|
||||
else if (start>=0 && end<0) return getNextHigherIndex(column, row, start, col.getRows()-1);
|
||||
else if (start<0 && end<0) return getNextHigherIndex(column, row, 0, col.getRows()-1);
|
||||
else if (start>=0 && end<0) return getNextHigherIndex(column, row, start, static_cast<int>(col.getRows())-1);
|
||||
else if (start<0 && end<0) return getNextHigherIndex(column, row, 0, static_cast<int>(col.getRows())-1);
|
||||
else {
|
||||
double d=0;
|
||||
const double v=col.getValue(row);
|
||||
@ -729,7 +755,7 @@ int JKQTPDatastore::getNextHigherIndex(size_t column, size_t row, int start, int
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
int JKQTPDatastore::getNextHigherIndex(size_t column, size_t row) const
|
||||
{
|
||||
return getNextHigherIndex(column, row, 0, columns[column].getRows()-1);
|
||||
return getNextHigherIndex(column, row, 0, static_cast<int>(columns[column].getRows())-1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
@ -751,7 +777,7 @@ int JKQTPDatastore::getNextHigherIndex(int column, size_t row, int start, int en
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t JKQTPDatastore::getMaxRows() {
|
||||
size_t JKQTPDatastore::getMaxRows() const {
|
||||
size_t res=0;
|
||||
/*for (size_t i=0; i<columns.size(); i++) {
|
||||
size_t r=columns[i].getRows();
|
||||
@ -768,7 +794,7 @@ size_t JKQTPDatastore::getMaxRows() {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::saveCSV(const QString& filename, const QSet<int>& userColumns, const QString& separator, const QString& decimal_separator, const QString& comment, const QString& aroundStrings, char floatformat) {
|
||||
void JKQTPDatastore::saveCSV(const QString& filename, const QSet<int>& userColumns, const QString& separator, const QString& decimal_separator, const QString& comment, const QString& aroundStrings, char floatformat) const {
|
||||
//std::cout<<filename<<"\n";
|
||||
|
||||
// find out the decimal and the thousand separator
|
||||
@ -783,7 +809,7 @@ void JKQTPDatastore::saveCSV(const QString& filename, const QSet<int>& userColum
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::saveMatlab(const QString& filename, const QSet<int>& userColumns) {
|
||||
void JKQTPDatastore::saveMatlab(const QString& filename, const QSet<int>& userColumns) const {
|
||||
//std::cout<<filename<<"\n";
|
||||
|
||||
// find out the decimal and the thousand separator
|
||||
@ -811,7 +837,7 @@ QStringList JKQTPDatastore::getColumnNames() const {
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::saveMatlab(QTextStream &txt, const QSet<int>& userColumns) {
|
||||
void JKQTPDatastore::saveMatlab(QTextStream &txt, const QSet<int>& userColumns) const {
|
||||
//std::cout<<filename<<"\n";
|
||||
|
||||
// find out the decimal and the thousand separator
|
||||
@ -868,7 +894,7 @@ void JKQTPDatastore::saveMatlab(QTextStream &txt, const QSet<int>& userColumns)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::saveCSV(QTextStream& txt, const QSet<int>& userColumns, const QString& separator, const QString& decimal_separator, const QString& comment, const QString& aroundStrings, char floatformat) {
|
||||
void JKQTPDatastore::saveCSV(QTextStream& txt, const QSet<int>& userColumns, const QString& separator, const QString& decimal_separator, const QString& comment, const QString& aroundStrings, char floatformat) const {
|
||||
//std::cout<<filename<<"\n";
|
||||
|
||||
// find out the decimal and the thousand separator
|
||||
@ -920,7 +946,7 @@ void JKQTPDatastore::saveCSV(QTextStream& txt, const QSet<int>& userColumns, con
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::saveSYLK(const QString& filename, const QSet<int>& userColumns, const QString& floatformat) {
|
||||
void JKQTPDatastore::saveSYLK(const QString& filename, const QSet<int>& userColumns, const QString& floatformat) const {
|
||||
Q_UNUSED(floatformat)
|
||||
// find out the decimal and the thousand separator
|
||||
QLocale loc=QLocale::c();
|
||||
@ -955,7 +981,7 @@ void JKQTPDatastore::saveSYLK(const QString& filename, const QSet<int>& userColu
|
||||
c=1;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
if (userColumns.isEmpty() || userColumns.contains(i)) {
|
||||
if (userColumns.isEmpty() || userColumns.contains(static_cast<int>(i))) {
|
||||
if (it.value().getRows()>i) {
|
||||
txt<<QString("C;X%1;Y%2;N;K%3\n").arg(c).arg(i+2).arg(get(it.key(), i));
|
||||
}
|
||||
@ -972,7 +998,7 @@ void JKQTPDatastore::saveSYLK(const QString& filename, const QSet<int>& userColu
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
QList<QVector<double> > JKQTPDatastore::getData(QStringList *columnNames, const QSet<int>& userColumns)
|
||||
QList<QVector<double> > JKQTPDatastore::getData(QStringList *columnNames, const QSet<int>& userColumns) const
|
||||
{
|
||||
QStringList cl;
|
||||
QList<QVector<double> > res;
|
||||
@ -1003,7 +1029,7 @@ QList<QVector<double> > JKQTPDatastore::getData(QStringList *columnNames, const
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::saveDIF(const QString& filename, const QSet<int>& userColumns, const QString& floatformat) {
|
||||
void JKQTPDatastore::saveDIF(const QString& filename, const QSet<int>& userColumns, const QString& floatformat) const {
|
||||
Q_UNUSED(floatformat)
|
||||
// find out the decimal and the thousand separator
|
||||
QLocale loc=QLocale::c();
|
||||
@ -1079,7 +1105,7 @@ QVariant JKQTPDatastoreModel::data(const QModelIndex &index, int role) const {
|
||||
int column=index.column();
|
||||
if (datastore) {
|
||||
if (role==Qt::DisplayRole || role==Qt::EditRole) {
|
||||
int col=static_cast<int>(datastore->getColumnIDs().value(column, -1));
|
||||
int col=static_cast<int>(datastore->getColumnIDsIntVec().value(column, -1));
|
||||
if (col>-1 && row>=0 && row<static_cast<int>(datastore->getRows(col))) {
|
||||
return datastore->get(col, static_cast<size_t>(row));
|
||||
}
|
||||
|
@ -73,10 +73,10 @@ class JKQTPDatastoreModel; // forward declaration
|
||||
=C1== =C2== =C3== =CN== =C1== =C2== =C3== =CN==
|
||||
\endverbatim
|
||||
*/
|
||||
enum JKQTPDatastoreItemFormat {
|
||||
JKQTPSingleColumn, /*!< \brief a 1D vector of doubles. (default option) */
|
||||
JKQTPMatrixColumn, /*!< \brief a 1D vector of double that represents a number of columns. The data is store column after column. */
|
||||
JKQTPMatrixRow /*!< \brief a 1D vector of double that represents a number of rows (C standard representation of matrices). The data is stored row after row.*/
|
||||
enum class JKQTPDatastoreItemFormat {
|
||||
SingleColumn, /*!< \brief a 1D C-array of doubles. (default option) */
|
||||
MatrixColumn, /*!< \brief a 1D C-array of doubles that represents a number of columns. The data is store column after column (=column-major). */
|
||||
MatrixRow, /*!< \brief a 1D C-array of doubles that represents a number of rows (C standard representation of matrices). The data is stored row after row (=row-major).*/
|
||||
};
|
||||
|
||||
/** \brief This class manages chunks of memory that are used for column data in JKQTBasePlotter descendents
|
||||
@ -236,9 +236,9 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
|
||||
inline double* getColumnPointer(int column, size_t row=0);
|
||||
/** \brief returns the width of the image, represented by \a column (in row-major ordering).
|
||||
* Internally this returns the imageColumns or image width, if set in the column */
|
||||
inline size_t getColumnImageWidth(int column);
|
||||
inline size_t getColumnImageWidth(int column) const;
|
||||
/** \brief returns the height of the image, represented by \a column (in row-major ordering) */
|
||||
inline size_t getColumnImageHeight(int column);
|
||||
inline size_t getColumnImageHeight(int column) const;
|
||||
|
||||
/** \brief returns the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */
|
||||
inline double get(size_t column, size_t row) const ;
|
||||
@ -270,6 +270,17 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
|
||||
inline void set(size_t column, size_t row, double value);
|
||||
/** \brief sets the value at position (\c column, \c row). \c column is the logical column and will be mapped to the according memory block internally!) */
|
||||
inline void set(int column, size_t row, double value);
|
||||
/** \brief adds a value \a value to the column \a column. This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards */
|
||||
inline void appendToColumn(size_t column, double value);
|
||||
/** \brief adds a values in cintainer \a values to the column \a column. This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards
|
||||
*
|
||||
* \tparam TContainer a container with standard iterators
|
||||
* \param colum the column to extend
|
||||
* \param vales vector with data to append to column \a column
|
||||
*/
|
||||
template<class TContainer>
|
||||
inline void appendFromContainerToColumn(size_t column, const TContainer& values);
|
||||
|
||||
/** \brief returns the value at position (\c x, \c y) in the \a column-th column, which is interpreted with the imageWidth stored in that column */
|
||||
inline double getPixel(size_t column, size_t x, size_t y) const ;
|
||||
/** \brief returns the value at position (\c x, \c y) in the \a column-th column, which is interpreted with the imageWidth stored in that column */
|
||||
@ -833,10 +844,12 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
|
||||
size_t addColumnCalculatedFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function<double(double,double)>& f, const QString& name=QString(""));
|
||||
|
||||
/** \brief returns the number of (logical) columns currently managed by the datastore */
|
||||
inline size_t getColumnCount() { return static_cast<size_t>(columns.size()); }
|
||||
inline size_t getColumnCount() const { return static_cast<size_t>(columns.size()); }
|
||||
|
||||
/** \brief returns a list with all available column IDs */
|
||||
inline QList<size_t> getColumnIDs() { return columns.keys(); }
|
||||
inline QList<size_t> getColumnIDs() const { return columns.keys(); }
|
||||
/** \brief returns a list with all available column IDs */
|
||||
QVector<int> getColumnIDsIntVec() const;
|
||||
|
||||
/** \brief return the num of the first column with the given name, or -1 if none was found */
|
||||
int getColumnNum(const QString& name);
|
||||
@ -846,7 +859,7 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
|
||||
|
||||
|
||||
/** \brief returns the maximum number of rows in all columns */
|
||||
size_t getMaxRows();
|
||||
size_t getMaxRows() const;
|
||||
|
||||
/** \brief save contents of datastore as Comma Separated Values (CSV) file
|
||||
*
|
||||
@ -865,7 +878,7 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
|
||||
* - ...
|
||||
* .
|
||||
*/
|
||||
void saveCSV(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& separator=QString(", "), const QString& decimal_separator=QString("."), const QString& comment=QString("#"), const QString& aroundStrings=QString(""), char floatformat='g');
|
||||
void saveCSV(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& separator=QString(", "), const QString& decimal_separator=QString("."), const QString& comment=QString("#"), const QString& aroundStrings=QString(""), char floatformat='g') const;
|
||||
/** \brief save contents of datastore as Comma Separated Values (CSV) file
|
||||
*
|
||||
* \param txt QTextStream to write to
|
||||
@ -883,7 +896,7 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
|
||||
* - ...
|
||||
* .
|
||||
*/
|
||||
void saveCSV(QTextStream& txt, const QSet<int>& userColumns=QSet<int>(), const QString& separator=QString(", "), const QString& decimal_separator=QString("."), const QString& comment=QString("#"), const QString& aroundStrings=QString(""), char floatformat='g');
|
||||
void saveCSV(QTextStream& txt, const QSet<int>& userColumns=QSet<int>(), const QString& separator=QString(", "), const QString& decimal_separator=QString("."), const QString& comment=QString("#"), const QString& aroundStrings=QString(""), char floatformat='g') const;
|
||||
|
||||
/** \brief save contents of datastore as <a href="http://en.wikipedia.org/wiki/SYmbolic_LinK_(SYLK)">SYLK file (SYmbolic LinK)</a>
|
||||
*
|
||||
@ -891,14 +904,14 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
|
||||
* \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
|
||||
* \param floatformat a \c printf format string that is used to print floating point numbers to the file
|
||||
*/
|
||||
void saveSYLK(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& floatformat=QString("%10.10lf"));
|
||||
void saveSYLK(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& floatformat=QString("%10.10lf")) const;
|
||||
|
||||
/** \brief return contents of datastore as QList<QVector<double> >, i.e. a list of column-vectors
|
||||
*
|
||||
* \param columnNames if \c !=nullptr this will afterwards conatin the column titles
|
||||
* \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
|
||||
*/
|
||||
QList<QVector<double> > getData(QStringList* columnNames=nullptr, const QSet<int>& userColumns=QSet<int>());
|
||||
QList<QVector<double> > getData(QStringList* columnNames=nullptr, const QSet<int>& userColumns=QSet<int>()) const;
|
||||
|
||||
/** \brief save contents of datastore as <a href="http://www.fileformat.info/format/dif/egff.htm">DIF file (data interchange format)</a>
|
||||
*
|
||||
@ -906,20 +919,20 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
|
||||
* \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
|
||||
* \param floatformat a \c printf format string that is used to print floating point numbers to the file
|
||||
*/
|
||||
void saveDIF(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& floatformat=QString("%10.10lf"));
|
||||
void saveDIF(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& floatformat=QString("%10.10lf")) const;
|
||||
|
||||
/** \brief save contents of datastore as a Matlab script
|
||||
*
|
||||
* \param filename the file to create
|
||||
* \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
|
||||
*/
|
||||
void saveMatlab(const QString& filename, const QSet<int>& userColumns=QSet<int>());
|
||||
void saveMatlab(const QString& filename, const QSet<int>& userColumns=QSet<int>()) const;
|
||||
/** \brief save contents of datastore as a Matlab script
|
||||
*
|
||||
* \param txt the QTextStream to write to
|
||||
* \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
|
||||
*/
|
||||
void saveMatlab(QTextStream& txt, const QSet<int>& userColumns=QSet<int>());
|
||||
void saveMatlab(QTextStream& txt, const QSet<int>& userColumns=QSet<int>()) const;
|
||||
|
||||
/** \brief return a list with all columns available in the datastore */
|
||||
QStringList getColumnNames() const;
|
||||
@ -932,6 +945,7 @@ class JKQTP_LIB_EXPORT JKQTPDatastore{
|
||||
|
||||
|
||||
|
||||
|
||||
/** \brief stores information about one data column. See JKQTPDatastore for more information.
|
||||
* \ingroup jkqtpdatastorage
|
||||
*
|
||||
@ -1053,7 +1067,9 @@ class JKQTP_LIB_EXPORT JKQTPColumn {
|
||||
}
|
||||
|
||||
/** \brief returns a pointer to the datastore item representing this column */
|
||||
inline JKQTPDatastoreItem* getDatastoreItem() const { return datastore->getItem(datastoreItem); }
|
||||
inline JKQTPDatastoreItem* getDatastoreItem() { return datastore->getItem(datastoreItem); }
|
||||
/** \brief returns a pointer to the datastore item representing this column */
|
||||
inline const JKQTPDatastoreItem* getDatastoreItem() const { return datastore->getItem(datastoreItem); }
|
||||
|
||||
/** \brief copy data from the given array into the column
|
||||
*
|
||||
@ -1106,10 +1122,17 @@ class JKQTP_LIB_EXPORT JKQTPColumn {
|
||||
*/
|
||||
class JKQTP_LIB_EXPORT JKQTPDatastoreItem {
|
||||
private:
|
||||
enum class StorageType {
|
||||
Internal,
|
||||
External,
|
||||
Vector
|
||||
};
|
||||
/** \brief a pointer to the actual data */
|
||||
double* data;
|
||||
/** \brief iif \a storageType is \c StorageType::Vector, the data is actually save here and data contains a pointer to the data in datavec */
|
||||
QVector<double> datavec;
|
||||
/** \brief specifies whether the datastore manages the memory (\c true ) or whether the user application does this (\c false ) .*/
|
||||
bool internal;
|
||||
StorageType storageType;
|
||||
/** \brief Specifies whether memory for the data has been allocated. This is only used, when \c internal==true. */
|
||||
bool allocated;
|
||||
/** \brief as data may also point to a matrix, this specifies the number of columns in this element (default: 1) */
|
||||
@ -1127,12 +1150,12 @@ class JKQTP_LIB_EXPORT JKQTPDatastoreItem {
|
||||
/** \brief class constructor: initializes the object for external data storage */
|
||||
JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows);
|
||||
/** \brief class constructor: initializes the object for external data storage */
|
||||
JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows, bool internal);
|
||||
JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows, bool storageType);
|
||||
/** \brief class destructor: frees unfreed internal memory */
|
||||
~JKQTPDatastoreItem();
|
||||
|
||||
/** \brief change the size of all columns to the givne number of rows. The data will be lost */
|
||||
void resizeColumns(size_t rows);
|
||||
/** \brief change the size of all columns to the givne number of rows. Returns \c true if the old data could be retained/saved and \c false if the old data was lost (which happens in most of the cases!) */
|
||||
bool resizeColumns(size_t rows);
|
||||
|
||||
/*! \brief returns the property rows ( \copybrief rows ). \details Description of the parameter rows is: <BLOCKQUOTE>\copydoc JKQTPDatastoreItem::JKQTPDatastoreItemrows </BLOCKQUOTE>. \see JKQTPDatastoreItem::rows for more information */ \
|
||||
inline size_t getRows() const
|
||||
@ -1145,11 +1168,11 @@ class JKQTP_LIB_EXPORT JKQTPDatastoreItem {
|
||||
/** \brief returns the data at the position (\a column, \a row ). The column index specifies the column inside THIS item, not the global column number. */
|
||||
inline double get(size_t column, size_t row) {
|
||||
if (data!=nullptr) switch(dataformat) {
|
||||
case JKQTPSingleColumn:
|
||||
case JKQTPDatastoreItemFormat::SingleColumn:
|
||||
return data[row];
|
||||
case JKQTPMatrixColumn:
|
||||
case JKQTPDatastoreItemFormat::MatrixColumn:
|
||||
return data[column*rows+row];
|
||||
case JKQTPMatrixRow:
|
||||
case JKQTPDatastoreItemFormat::MatrixRow:
|
||||
return data[row*columns+column];
|
||||
}
|
||||
return 0;
|
||||
@ -1159,11 +1182,11 @@ class JKQTP_LIB_EXPORT JKQTPDatastoreItem {
|
||||
/** \brief returns the data at the position (\a column, \a row ). The column index specifies the column inside THIS item, not the global column number. */
|
||||
inline double* getPointer(size_t column, size_t row) {
|
||||
if (data!=nullptr) switch(dataformat) {
|
||||
case JKQTPSingleColumn:
|
||||
case JKQTPDatastoreItemFormat::SingleColumn:
|
||||
return &(data[row]);
|
||||
case JKQTPMatrixColumn:
|
||||
case JKQTPDatastoreItemFormat::MatrixColumn:
|
||||
return &(data[column*rows+row]);
|
||||
case JKQTPMatrixRow:
|
||||
case JKQTPDatastoreItemFormat::MatrixRow:
|
||||
return &(data[row*columns+column]);
|
||||
}
|
||||
return nullptr;
|
||||
@ -1172,11 +1195,11 @@ class JKQTP_LIB_EXPORT JKQTPDatastoreItem {
|
||||
/** \brief returns the data at the position (\a column, \a row ). The column index specifies the column inside THIS item, not the global column number. */
|
||||
inline const double* getPointer(size_t column, size_t row) const {
|
||||
if (data!=nullptr) switch(dataformat) {
|
||||
case JKQTPSingleColumn:
|
||||
case JKQTPDatastoreItemFormat::SingleColumn:
|
||||
return &(data[row]);
|
||||
case JKQTPMatrixColumn:
|
||||
case JKQTPDatastoreItemFormat::MatrixColumn:
|
||||
return &(data[column*rows+row]);
|
||||
case JKQTPMatrixRow:
|
||||
case JKQTPDatastoreItemFormat::MatrixRow:
|
||||
return &(data[row*columns+column]);
|
||||
}
|
||||
return nullptr;
|
||||
@ -1184,17 +1207,63 @@ class JKQTP_LIB_EXPORT JKQTPDatastoreItem {
|
||||
/** \brief set the data at the position (\a column, \a row ) to \a value. The column index specifies the column inside THIS item, not the global column number. */
|
||||
inline void set(size_t column, size_t row, double value) {
|
||||
if (data!=nullptr) switch(dataformat) {
|
||||
case JKQTPSingleColumn:
|
||||
case JKQTPDatastoreItemFormat::SingleColumn:
|
||||
data[row]=value;
|
||||
return;
|
||||
case JKQTPMatrixColumn:
|
||||
case JKQTPDatastoreItemFormat::MatrixColumn:
|
||||
data[column*rows+row]=value;
|
||||
return;
|
||||
case JKQTPMatrixRow:
|
||||
case JKQTPDatastoreItemFormat::MatrixRow:
|
||||
data[row*columns+column]=value;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/** \brief adds a new row to the given column. Returns \c true on success and \c false else
|
||||
*
|
||||
* This operation is currently only possible, if \c storageType==StorageType::Vector ! */
|
||||
inline bool push_back(size_t column, double value) {
|
||||
if (storageType==StorageType::Vector && dataformat==JKQTPDatastoreItemFormat::SingleColumn && column==0) {
|
||||
datavec.push_back(value);
|
||||
rows=static_cast<size_t>(datavec.size());
|
||||
data=datavec.data();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** \brief adds a new row to the given column. Returns \c true on success and \c false else
|
||||
*
|
||||
* This operation is currently only possible, if \c storageType==StorageType::Vector ! */
|
||||
inline bool append(size_t column, double value) {
|
||||
return push_back(column, value);
|
||||
}
|
||||
/** \brief adds new rows to the given column. Returns \c true on success and \c false else
|
||||
*
|
||||
* This operation is currently only possible, if \c storageType==StorageType::Vector ! */
|
||||
inline bool append(size_t column, const QVector<double>& values) {
|
||||
if (storageType==StorageType::Vector && dataformat==JKQTPDatastoreItemFormat::SingleColumn && column==0) {
|
||||
datavec.reserve(datavec.size()+values.size());
|
||||
for (const double& d: values) datavec.push_back(d);
|
||||
data=datavec.data();
|
||||
rows=static_cast<size_t>(datavec.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
/** \brief adds new rows to the given column. Returns \c true on success and \c false else
|
||||
*
|
||||
* This operation is currently only possible, if \c storageType==StorageType::Vector ! */
|
||||
inline bool append(size_t column, const std::vector<double>& values) {
|
||||
if (storageType==StorageType::Vector && dataformat==JKQTPDatastoreItemFormat::SingleColumn && column==0) {
|
||||
datavec.reserve(static_cast<int>(datavec.size())+static_cast<int>(values.size()));
|
||||
for (const double& d: values) datavec.push_back(d);
|
||||
data=datavec.data();
|
||||
rows=static_cast<size_t>(datavec.size());
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@ -1277,14 +1346,14 @@ double *JKQTPDatastore::getColumnPointer(int column, size_t row)
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t JKQTPDatastore::getColumnImageWidth(int column)
|
||||
size_t JKQTPDatastore::getColumnImageWidth(int column) const
|
||||
{
|
||||
if (column<0) return 0;
|
||||
return columns[static_cast<size_t>(column)].getImageColumns();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
size_t JKQTPDatastore::getColumnImageHeight(int column)
|
||||
size_t JKQTPDatastore::getColumnImageHeight(int column) const
|
||||
{
|
||||
if (column<0) return 0;
|
||||
return columns[static_cast<size_t>(column)].getRows()/columns[static_cast<size_t>(column)].getImageColumns();
|
||||
@ -1343,6 +1412,31 @@ inline void JKQTPDatastore::set(int column, size_t row, double value) {
|
||||
set(static_cast<size_t>(column), static_cast<size_t>(row), value);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
void JKQTPDatastore::appendToColumn(size_t column, double value)
|
||||
{
|
||||
bool ok=columns[column].getDatastoreItem()->append(columns[column].getDatastoreOffset(), value);
|
||||
if (!ok) {
|
||||
QVector<double> old_data=columns[column].copyData();
|
||||
size_t itemID=addItem(new JKQTPDatastoreItem(1, static_cast<size_t>(old_data.size()+1)));
|
||||
columns[column]=JKQTPColumn(this, columns[column].getName(), itemID, 0);
|
||||
for (int i=0; i<old_data.size(); i++) {
|
||||
columns[column].setValue(static_cast<size_t>(i), old_data[i]);
|
||||
}
|
||||
columns[column].setValue(static_cast<size_t>(old_data.size()), value);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
template<class TContainer>
|
||||
void JKQTPDatastore::appendFromContainerToColumn(size_t column, const TContainer &values)
|
||||
{
|
||||
for(auto it=values.begin(); it!=values.end(); it++) {
|
||||
appendToColumn(column, *it);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
inline double JKQTPDatastore::getPixel(size_t column, size_t x, size_t y) const {
|
||||
return columns.value(column).getPixelValue(x, y);
|
||||
|
Loading…
Reference in New Issue
Block a user