JKQTPlotter trunk/v5.0.0
an extensive Qt5+Qt6 Plotter framework (including a feature-richt plotter widget, a speed-optimized, but limited variant and a LaTeX equation renderer!), written fully in C/C++ and without external dependencies
Loading...
Searching...
No Matches
jkqtpdatastorage.h
1/*
2 Copyright (c) 2008-2024 Jan W. Krieger (<jan@jkrieger.de>)
3
4
5
6 This software is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License (LGPL) as published by
8 the Free Software Foundation, either version 2.1 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License (LGPL) for more details.
15
16 You should have received a copy of the GNU Lesser General Public License (LGPL)
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20#ifndef JKQTPDATASTORAGE_H
21#define JKQTPDATASTORAGE_H
22
23
24#include "jkqtplotter/jkqtplotter_imexport.h"
25#include "jkqtplotter/jkqtptools.h"
26#include "jkqtcommon/jkqtpdebuggingtools.h"
27#include "jkqtcommon/jkqttools.h"
28#include <vector>
29#include <cmath>
30#include <iostream>
31#include <memory>
32#include <QString>
33#include <QMap>
34#include <QList>
35#include <QFile>
36#include <QTextStream>
37#include <QLocale>
38#include <QSet>
39#include <QStringList>
40#include <QAbstractTableModel>
41#include <QObject>
42#include <stdexcept>
43
44class JKQTPColumn; // forward declaration
45class JKQTPColumnIterator; // forward declaration
46class JKQTPColumnConstIterator; // forward declaration
47class JKQTPDatastoreItem; // foward declaration
48class JKQTPDatastoreModel; // forward declaration
49class JKQTPColumnBackInserter; // forward declaration
50
51
52/** \brief the types of data in one JKQTdatastoreItem
53 * \ingroup jkqtpdatastorage_classes
54 *
55 * \c JKQTPSingleColumn:
56 * \verbatim
57+-----+-----+-----+....................+-----+
58| 0 | 1 | 2 | + N-1 |
59+-----+-----+-----+....................+-----+
60\endverbatim
61 *
62 *
63 * \c JKQTPMatrixColumn:
64 * \verbatim
65 ================= COLUMN 1 ================= ================= COLUMN 2 =================
66+-----+-----+-----+....................+-----++-----+-----+-----+....................+-----+ .....
67| 0 | 1 | 2 | + N-1 || 0 | 1 | 2 | + N-1 |
68+-----+-----+-----+....................+-----++-----+-----+-----+....................+-----+ .....
69 =R1== =R2== =R3== =RN== =R1== =R2== =R3== =RN==
70\endverbatim
71 *
72 *
73 * \c JKQTPMatrixRow (C standard representation of matrices):
74 * \verbatim
75 ================== ROW 1 ================== ================== ROW 2 ==================
76+-----+-----+-----+....................+-----++-----+-----+-----+....................+-----+ .....
77| 0 | 1 | 2 | + N-1 || 0 | 1 | 2 | + N-1 |
78+-----+-----+-----+....................+-----++-----+-----+-----+....................+-----+ .....
79 =C1== =C2== =C3== =CN== =C1== =C2== =C3== =CN==
80\endverbatim
81 */
83 SingleColumn, /*!< \brief a 1D C-array of doubles. (default option) */
84 MatrixColumn, /*!< \brief a 1D C-array of doubles that represents a number of columns. The data is store column after column (=column-major). */
85 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).*/
86};
87
88/** \brief This class manages data columns (with entries of type \c double ), used by JKQTPlotter/JKQTBasePlotter to represent data for plots
89 * \ingroup jkqtpdatastorage_classes
90 *
91 * \see \ref JKQTPlotterBasicJKQTPDatastore for a detailed description of how to use this class for data management!
92 *
93 *
94 * \section jkqtpdatastore_column_management Column Management
95 *
96 * \subsection jkqtpdatastore_column_management_generation Column Generation/Deletion
97 *
98 * A JKQTPDatastore manages a set of data columns. Each column is a continuous vector of numbers. Optionally it can be interpreted
99 * as a 2D image. In the latter case, the data is assumed to be ordered in row-major ordering (i.e. row for row).
100 *
101 * You can generate new columns e.g. by:
102 * <ul>
103 * <li> addColumn() which either generates internally managed (and extensible) columns, or accepts a simple \c double* pointer
104 * to external. In the latter case owner-ship may be transferred to the datastore, but can also retain externally.
105 * <li> addImageColumn() adds a column that should be interpreted as an image with given width and height (i.e. a row-major
106 * matrix with \c width columns and \c height rows.
107 * <li> copyColumn() duplicates an existing column
108 * <li> addCopiedColumn() copies an external dataset into the datastore. e.g. with code like:
109 * \code{.cpp}
110 * QVector<double> X, Y;
111 * const int Ndata=100;
112 * for (int i=0; i<Ndata; i++) {
113 * const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
114 * X<<x;
115 * Y<<sin(x);
116 * }
117 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
118 * // by calling JKQTPDatastore::addCopiedColumn() the data is COPIED from the vector into the datastore
119 * linegraph->setXColumn(datastore->addCopiedColumn(X, "x"));
120 * linegraph->setYColumn(datastore->addCopiedColumn(Y, "y"));
121 * \endcode
122 * <li> addLinearColumn() adds a column with linearly increasing numbers (in a given range)
123 * <li> addLogColumn() and addDecadeLogColumn() add columns with logarithmically spaced values
124 * <li> addLinearGridColumns() adds two columns which represent x- and y- coordinates of points
125 * on a rectangular grid (useful for calculating image data)
126 * <li> addCalculatedColumn() calculates a column, based on row numbers and a C++ functor
127 * <li> addCalculatedColumnFromColumn() calculates a column, based on another column data
128 * <li> addCopiedMap() copies data from a std::map/QMap into two columns
129 * <li> ... several more functions for specific cases exist.
130 * <li> Also note that there are even library extensions that allow to import data directly from OpenCV matrices: JKQTPCopyCvMatToColumn()
131 * </ul>
132 *
133 * Of course columns can also be deleted by calling:
134 * - deleteColumn()
135 * - deleteAllColumns()
136 * - deleteAllPrefixedColumns()
137 * - clear()
138 * .
139 *
140 * \subsection jkqtpdatastore_column_management_props Column Properties
141 *
142 * The properties of columns may be accessed using:
143 * - getRows() returns the number of rows in a specific column
144 * - getColumnPointer() returns a pointer to the data in the column
145 * - getColumnChecksum() calculated a checksum over the data in the column
146 * - getColumnNames() / getColumnName()
147 * .
148 *
149 * \subsection jkqtpdatastore_column_management_modify Modify Column Contents
150 *
151 * You can modify all data in a column by functions like:
152 * - setAll()
153 * - scaleColumnValues()
154 * .
155 *
156 * Also you can access a single entry from a column, using:
157 * - set() / get() set/read a column entry
158 * - inc() / dec() increment/decrement a column entry
159 * - appendToColumn() (adds a single row/new value to a column, if the column was not internally managed before, it will be copied into a new internal memory segment by the first call to this function!)
160 * - appendToColumns() (adds several values to several columns simultaneously, i.e. a shortcut to prevents writing several consecutive appendToColumn() for each column separately)
161 * - appendFromContainerToColumn() (adds several rows from a container to a column, if the column was not internally managed before, it will be copied into a new internal memory segment by the first call to this function!)
162 * .
163 *
164 * \subsection jkqtpdatastore_column_management_iterators Iterator Interface
165 *
166 * In addition to teh fucntions above, JKQTPDatastore also provides C++-style iteratos to read the data from a column:
167 * - begin()
168 * - end()
169 * .
170 *
171 * ... and also a \c std::back_inserter -style interface to append data to columns:
172 * - backInserter()
173 * .
174 *
175 * These allow to use the C++ standard algorithms to work with columns and also enabled the
176 * library \ref jkqtptools_math_statistics in this software package. You can use the functions
177 * above e.g. for code like:
178 *
179 * \code{.cpp}
180 * auto inserter it=datastore->backInserter(datastore->addColumn("new column"));
181 * for (auto it=datastore->begin(col1); it!=datastore->begin(col1) ++it) {
182 * *++inserter=sqrt(*it);
183 * }
184 * \endcode
185 *
186 * or simply
187 *
188 * \code{.cpp}
189 * // mean of a column in a JKQTPDatastore:
190 * double mean=jkqtpstatAverage(datastore1->begin(col1), datastore1->end(col1));
191 * \endcode
192 *
193 * Also there are functions to add data from iterator-defined ranges, e.g.:
194 * - addCopiedColumn()
195 * - addCopiedMap()
196 * - appendToColumn()
197 * .
198 *
199 * \see \ref JKQTPlotterBasicJKQTPDatastoreIterators
200 *
201 *
202 *
203 * \subsection jkqtpdatastore_column_management_images Image Column
204 *
205 * JKQTPDatastore stores the width and height of the represented image as metadata with any image column.
206 * This metadata is used to provide convenience access to the image pixels with:
207 * - setPixel()
208 * - getPixel()
209 * .
210 *
211 * The image width/height are read using:
212 * - getColumnImageWidth()
213 * - getColumnImageHeight()
214 * .
215 *
216 * This allows to write code like:
217 * \code{.cpp}
218 * for (int iy=0; iy<10; iy++) {
219 * for (int ix=0; ix<10; ix++) {
220 * datastore->setPixel(imgColumn, ix, iy, sin(ix*iy/30.0));
221 * }
222 * }
223 * \endcode
224 *
225 * \section jkqtpdatastore_dataio Data Output
226 *
227 * JKQTPDatastore provides several functions that allow to store its contents into files:
228 * - saveCSV()
229 * - saveSYLK()
230 * - saveMatlab()
231 * - saveDIF()
232 * .
233 *
234 * ... and function to read data into different data structures:
235 * - getData()
236 * .
237 *
238 *
239 *
240 *
241 * \section jkqtpdatastore_internals Internal Working
242 *
243 * This class manages a list if JKQTPDatastoreItem onjects that may each contain a chunk of memory, containig
244 * one or more columns of data. Each item can be accessed with get() by a specific ID which is returned by add().
245 * JKQTPColumn. You may only clear all chunks of memory/items. If you no longer need some of the data, but still want
246 * to access the rest you will simply have to destroy all JKQTPColumn that point to the item with their
247 * JKQTPColumns:datastoreItem property.
248 *
249 * \verbatim
250
251+- JKQTPDatastore ---------------------+ std::vector<JKQTPColumn>:
252| | +- JKQTPColumn ----------------+
253| +- JKQTPDatastoreItem --------+ | 0 | datastore |
254| 0 | JKQTPSingleColumn |<--|-------------------|---datastoreItem = 0 |
255| | 0 # # # # # # # # # # #<--|---|-------------------|---datastoreOffset = 0 |
256| | | | | |
257| +- JKQTPDatastoreItem --------+ | +- JKQTPColumn ----------------+
258| 1 | JKQTPSingleColumn |<--|---\ 1 | datastore |
259| | 0 # # # # # # # # # # #<--|---|-\ \--------------|---datastoreItem = 1 |
260| | | | \----------------|---datastoreOffset = 0 |
261| +- JKQTPDatastoreItem --------+ | | |
262| : : | +------------------------------+
263| : : | : :
264| : : | : :
265| +- JKQTPDatastoreItem --------+ | : :
266|N-1 | JKQTPMatrixRow |<--|---\ : :
267| | 0 # # # # # # # # # # # | | \ +- JKQTPColumn ----------------+
268| | 1 # # # # # # # # # # # | | \ M-1 | datastore |
269| | 2 # # # # # # # # # # #<--|---|--\ \------------|---datastoreItem = N-1 |
270| | | | \---------------|---datastoreOffset = 2 |
271| +-----------------------------+ | | |
272| | +------------------------------+
273+--------------------------------------+
274
275
276\endverbatim
277 *
278 * In addition the JKQTPDatastore manages a std::vector<JKQTPColumn> which may be used to access the data chunks in the logical
279 * notion of data columns. This class provides a set of interface methods for this list:
280 *
281 */
283 private:
284 /** \brief a std::vector that contains all items managed by this datastore */
285 QMap<size_t, JKQTPDatastoreItem*> items;
286 /** \brief a std::vector of all columns that may be used to access the managed chunks of memory. */
287 QMap<size_t, JKQTPColumn> columns;
288
289 /** \brief an internal invalid column object, used e.g. to return invalid column iterators
290 * \internal
291 */
292 std::unique_ptr<JKQTPColumn> m_invalidColumn;
293
294 /** \brief internal variable to keep track about the highest item ID (in items) used so far
295 * \internal
296 * \see items
297 */
298 size_t maxItemID;
299 /** \brief internal variable to keep track about the highest column ID (in columns) used so far
300 * \internal
301 * \see columns
302 */
304 protected:
305
306 /** \brief add a new column to the datastore and return its ID */
308
309 /** \brief add a new item to the datastore and return its ID
310 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
312
313
314 /** \brief add a new columns/item with \a rows rows to the datastore and return its ID. The item uses internal memory management.
315 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
316 size_t addItem(size_t rows);
317
318 /** \brief add a new item with \a rows rows and \a columns columns to the datastore and return its ID. The item uses internal memory management.
319 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
320 size_t addItem(size_t columns, size_t rows);
321
322 /** \brief add one external column to the datastore. It contains \a rows rows.
323 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
324 size_t addItem(double* data, size_t rows);
325 /** \brief add one internal column to the datastore. It contains \a rows rows.
326 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
327 size_t addInternalItem(double* data, size_t rows);
328
329 /** \brief add one external column to the datastore. It contains \a rows rows. The data is copied and the copy managed internally
330 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
331 size_t addCopiedItem(const double *data, size_t rows);
332
333 /** \brief add an external memory block to the datastore. It contains \a rows rows and \a columns columns. \a dataformat determined the memory layout.
334 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
335 size_t addItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows);
336
337 /** \brief add one external data block to the datastore. It contains \a rows rows and \a columns columns. The data is copied and the copy managed internally
338 * This function retuns an item ID (which can be used with getItem() ), not a column ID! */
339 size_t addCopiedItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows);
340
341 /** \brief returns the JKQTPDatastoreItem object for the \a i -th item in the store */
342 inline JKQTPDatastoreItem* getItem(size_t i) {
343 return items.value(i, nullptr);
344 }
345
346 /** \brief returns the JKQTPDatastoreItem object for the \a i -th item in the store */
347 inline const JKQTPDatastoreItem* getItem(size_t i) const {
348 return items.value(i, nullptr);
349 }
350
351 /** \brief add a new columns which references a specified item and a specified column therein.
352 * \see \ref JKQTPlotterBasicJKQTPDatastore
353 */
354 size_t addColumnForItem(size_t itemID, size_t columnInItem, const QString& name=QString(""));
355
356
357 /** \brief mutable iterator for columns in the JKQTPDatastore (\c ColumnIterator::first: column number, \c ColumnIterator::second: column data) */
358 typedef QMap<size_t, JKQTPColumn>::iterator ColumnIterator;
359 /** \brief constant iterator for columns in the JKQTPDatastore (\c ColumnIterator::first: column number, \c ColumnIterator::second: column data) */
360 typedef QMap<size_t, JKQTPColumn>::const_iterator ConstColumnIterator;
361
362 /** \brief returns an iterator to the first column in the JKQTPDatastore \see ColumnIterator */
364 /** \brief returns an iterator behind the last column in the JKQTPDatastore \see ColumnIterator */
366 /** \brief returns a const iterator to the first column in the JKQTPDatastore \see ConstColumnIterator */
368 /** \brief returns a const iterator behind the last column in the JKQTPDatastore \see ConstColumnIterator */
370 public:
371
372 /** \brief class constructor, generates an empty datastore */
374 /** \brief class destructor, destroys all subordered JKQTPDatastoreItem objects */
376
377 /** \brief determines whether a column with the given ID exists */
378 bool hasColumn(size_t i) const;
379
380 /** \brief returns an iterator to the first data entry in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::iterator */
382 /** \brief returns an iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::iterator */
384 /** \brief returns a const iterator to the first data entry in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
386 /** \brief returns a const iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
388
389 /** \brief returns an iterator to the first data entry in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::iterator */
391 /** \brief returns an iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::iterator */
393 /** \brief returns a const iterator to the first data entry in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
395 /** \brief returns a const iterator behind the last data entry data in the \a i -th column in the JKQTPDatastore \see JKQTPColumn::const_iterator */
397
398 /** \brief removes the entry \a pos
399 *
400 * \warning If the memory was externally managed before, it will be internally managed afterwards
401 *
402 * \warning the iterator \a pos is rendered invalid by this column, as the in some cases the internal column is redefined!
403 */
404 inline void eraseFromColumn(const JKQTPColumnIterator &pos);
405 /** \brief removes the entry \a pos
406 *
407 * \warning If the memory was externally managed before, it will be internally managed afterwards
408 *
409 * \warning the iterator \a pos is rendered invalid by this column, as the in some cases the internal column is redefined!
410 */
411 inline void eraseFromColumn(const JKQTPColumnConstIterator &pos);
412 /** \brief removes the entries \a pos to \a posEnd
413 *
414 * \warning If the memory was externally managed before, it will be internally managed afterwards
415 *
416 * \warning the iterator \a pos is rendered invalid by this column, as the in some cases the internal column is redefined!
417 */
418 inline void eraseFromColumn(const JKQTPColumnConstIterator &pos, const JKQTPColumnConstIterator &posEnd);
419 /** \brief removes the entries \a pos to \a posEnd
420 *
421 * \warning If the memory was externally managed before, it will be internally managed afterwards
422 *
423 * \warning the iterator \a pos is rendered invalid by this column, as the in some cases the internal column is redefined!
424 */
425 inline void eraseFromColumn(const JKQTPColumnIterator &pos, const JKQTPColumnIterator &posEnd);
426
427
428 /** \brief returns a back-inserter iterator (JKQTPColumnBackInserter) to the \a i -th column in the JKQTPDatastore \see JKQTPColumnBackInserter */
430 /** \brief returns a back-inserter iterator (JKQTPColumnBackInserter) to the \a i -th column in the JKQTPDatastore \see JKQTPColumnBackInserter */
432
433 /** \brief deletes all items from the datastore and possibly frees the memory they manage */
434 void clear();
435
436
437 /** \brief delete the given column, if no other columns points to the datastore item of the column and \a removeItems is \c true, the item will be removed */
438 void deleteColumn(size_t column, bool removeItems=true);
439
440 /** \brief delete all columns with the given name, if no other columns points to the datastore item of the column and \a removeItems is \c true, the item will be removed */
441 void deleteAllColumns(const QString& name, bool removeItems=true);
442
443 /** \brief delete all columns where the name starts with a given prefix, if no other columns points to the datastore item of the column and \a removeItems is \c true, the item will be removed */
444 void deleteAllPrefixedColumns(QString prefix, bool removeItems=true);
445
446
447 /** \brief returns the number of rows in the column \a column */
448 inline size_t getRows(size_t column) const;
449 /** \brief returns a pointer to the data in column \a column, starting ar row \a row */
450 inline const double* getColumnPointer(size_t column, size_t row=0) const;
451 /** \brief returns a pointer to the data in column \a column, starting ar row \a row */
452 inline double* getColumnPointer(size_t column, size_t row=0);
453 /** \brief returns the number of rows in the column \a column */
454 inline size_t getRows(int column) const;
455 /** \brief returns a pointer to the data in column \a column, starting ar row \a row */
456 inline const double* getColumnPointer(int column, size_t row=0) const;
457 /** \brief returns a pointer to the data in column \a column, starting ar row \a row */
458 inline double* getColumnPointer(int column, size_t row=0);
459 /** \brief returns the width of the image, represented by \a column (in row-major ordering).
460 * Internally this returns the imageColumns or image width, if set in the column */
461 size_t getColumnImageWidth(int column) const;
462 /** \brief returns the height of the image, represented by \a column (in row-major ordering) */
463 size_t getColumnImageHeight(int column) const;
464 /** \brief sets the height of the image, represented by \a column (in row-major ordering) to \a imageHeight */
465 void setColumnImageHeight(size_t column, size_t imageHeight);
466 /** \brief sets the width of the image, represented by \a column (in row-major ordering) to \a imageWidth */
467 void setColumnImageWidth(size_t column, size_t imageWidth);
468
469 /** \brief returns the data checksum of the given column */
470 quint16 getColumnChecksum(int column) const;
471
472 /** \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!) */
473 inline double get(size_t column, size_t row) const ;
474
475 /** \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!) */
476 inline double get(int column, size_t row) const ;
477 /** \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!) */
478 inline double get(int column, int row) const ;
479 /** \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!) */
480 inline double get(size_t column, int row) const ;
481 /** \brief gets the index of the datapoint with the nearest, but lower value in the column (in a given inclusive row range [start ... end] values of -1 for the ranges are "wildcards", i.e. start/end of column)*/
482 int getNextLowerIndex(size_t column, size_t row, int start, int end) const;
483 /** \brief gets the index of the datapoint with the nearest, but lower value in the column */
484 int getNextLowerIndex(size_t column, size_t row) const;
485 /** \brief gets the index of the datapoint with the nearest, but higher value in the column (in a given inclusive row range [start ... end] values of -1 for the ranges are "wildcards", i.e. start/end of column) */
486 int getNextHigherIndex(size_t column, size_t row, int start, int end) const;
487 /** \brief gets the index of the datapoint with the nearest, but higher value in the column */
488 int getNextHigherIndex(size_t column, size_t row) const;
489 /** \brief gets the index of the datapoint with the nearest, but lower value in the column (in a given inclusive row range [start ... end] values of -1 for the ranges are "wildcards", i.e. start/end of column)*/
490 int getNextLowerIndex(int column, size_t row, int start, int end) const;
491 /** \brief gets the index of the datapoint with the nearest, but lower value in the column */
492 int getNextLowerIndex(int column, size_t row) const;
493 /** \brief gets the index of the datapoint with the nearest, but higher value in the column (in a given inclusive row range [start ... end] values of -1 for the ranges are "wildcards", i.e. start/end of column) */
494 int getNextHigherIndex(int column, size_t row, int start, int end) const;
495 /** \brief gets the index of the datapoint with the nearest, but higher value in the column */
496 int getNextHigherIndex(int column, size_t row) const;
497
498 /** \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!) */
499 inline void set(size_t column, size_t row, double value);
500 /** \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!) */
501 inline void set(int column, size_t row, double value);
502 /** \brief copies the data from \a data into an existing column \a toColumn
503 *
504 * \param toColumn target of the copy operation
505 * \param data data to copy
506 *
507 * \warning If the memory in \a toColumn was externally managed before, it will be
508 * internally managed afterwards!
509 */
510 void setColumnData(size_t toColumn, const QVector<double>& data);
511 /** \brief copies the data from \a data into an existing column \a toColumn
512 *
513 * \param toColumn target of the copy operation
514 * \param data data to copy
515 * \param N entries in \a data
516 *
517 * \warning If the memory in \a toColumn was externally managed before, it will be
518 * internally managed afterwards!
519 */
520 void setColumnCopiedData(size_t toColumn, const double* data, size_t N);
521 /** \brief copies the image data from \a data into an existing column \a toColumn
522 *
523 * \param toColumn target of the copy operation
524 * \param data data to copy, size is \a width * \a height
525 * \param width number of columns in \a data
526 * \param height number of rows in \a data
527 *
528 * \warning If the memory in \a toColumn was externally managed before, it will be
529 * internally managed afterwards!
530 */
531 void setColumnCopiedImageData(size_t toColumn, const double* data, size_t width, size_t height);
532 /** \brief adds a value \a value to the column \a column. This changes the column length (number of rows).
533 *
534 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
535 *
536 * \see appendToColumns()
537 */
538 void appendToColumn(size_t column, double value);
539 /** \brief resizes the column \a column to have \a new_rows rows
540 *
541 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
542 *
543 * \see resizeImageColumn(), appendToColumn()
544 */
545 void resizeColumn(size_t column, size_t new_rows);
546 /** \brief resizes the column \a column to have enough rows to be interpreted as an image of size \a new_image_width * \a new_image_height pixels, also sets the internally store image size in the column!
547 *
548 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
549 *
550 * \see resizeColumn(), appendToColumn()
551 */
552 void resizeImageColumn(size_t column, size_t new_image_width, size_t new_image_height);
553 /** \brief adds a value \a value1 to the column \a column1 and a value \a value2 to \a column2.
554 *
555 * This is equivalent to
556 * \code
557 * appendToColumn(column1, value1);
558 * appendToColumn(column2, value2);
559 * \endcode
560 *
561 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
562 *
563 * \see appendToColumn()
564 */
565 void appendToColumns(size_t column1, size_t column2, double value1, double value2);
566
567 /** \brief adds a the x-coordinate of \a value to the column \a columnX and the y-coordinate to \a columnY.
568 *
569 * This is equivalent to
570 * \code
571 * appendToColumn(columnX, value.x());
572 * appendToColumn(columnY, value.y());
573 * \endcode
574 *
575 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
576 *
577 * \see appendToColumn()
578 */
579 void appendToColumns(size_t columnX, size_t columnY, const QPointF& value);
580
581 /** \brief adds a the x-coordinate of \a value to the column \a columnX and the y-coordinate to \a columnY.
582 *
583 * This is equivalent to
584 * \code
585 * appendToColumn(columnX, value.x());
586 * appendToColumn(columnY, value.y());
587 * \endcode
588 *
589 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
590 *
591 * \see appendToColumn()
592 */
593 void appendToColumns(size_t columnX, size_t columnY, const QPoint& value);
594
595 /** \brief adds a value \a value1 to the column \a column1, a value \a value2 to \a column2, etc.
596 *
597 * This is equivalent to
598 * \code
599 * appendToColumn(column1, value1);
600 * appendToColumn(column2, value2);
601 * appendToColumn(column3, value3);
602 * \endcode
603 *
604 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
605 *
606 * \see appendToColumn()
607 */
608 void appendToColumns(size_t column1, size_t column2, size_t column3, double value1, double value2, double value3);
609
610 /** \brief adds a value \a value1 to the column \a column1, a value \a value2 to \a column2, etc.
611 *
612 * This is equivalent to
613 * \code
614 * appendToColumn(column1, value1);
615 * appendToColumn(column2, value2);
616 * appendToColumn(column3, value3);
617 * appendToColumn(column4, value4);
618 * \endcode
619 *
620 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
621 *
622 * \see appendToColumn()
623 */
624 void appendToColumns(size_t column1, size_t column2, size_t column3, size_t column4, double value1, double value2, double value3, double value4);
625
626 /** \brief adds a value \a value1 to the column \a column1, a value \a value2 to \a column2, etc.
627 *
628 * This is equivalent to
629 * \code
630 * appendToColumn(column1, value1);
631 * appendToColumn(column2, value2);
632 * appendToColumn(column3, value3);
633 * appendToColumn(column4, value4);
634 * appendToColumn(column5, value5);
635 * \endcode
636 *
637 * \warning This changes the column length (number of rows). If the memory was externally managed before, it will be internally managed afterwards .
638 *
639 * \see appendToColumn()
640 */
641 void appendToColumns(size_t column1, size_t column2, size_t column3, size_t column4, size_t column5, double value1, double value2, double value3, double value4, double value5);
642
643
644
645
646 /** \brief adds a values in container \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
647 *
648 * \tparam TContainer a container with standard iterators
649 * \param column the column to extend
650 * \param values vector with data to append to column \a column
651 */
652 template<class TContainer>
653 inline void appendFromContainerToColumn(size_t column, const TContainer& values);
654 /** \brief adds a values from a range \a first ... \a last (defined by C++ iterators) 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
655 *
656 * \tparam TIterator a standard C++ iterator
657 * \param column the column to extend
658 * \param first points to the first value in the range of values to add
659 * \param last points behind the last value in the range of values to add
660 */
661 template<class TIterator>
662 inline void appendToColumn(size_t column, TIterator first, TIterator last);
663
664 /** \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 */
665 inline double getPixel(size_t column, size_t x, size_t y) const ;
666 /** \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 */
667 inline void setPixel(size_t column, size_t x, size_t y, double value) ;
668 /** \brief sets all entries in column \a column to \a value
669 *
670 * \see \ref JKQTPlotterFilledGraphs
671 */
672 inline void setAll(size_t column, double value);
673 /** \brief scales (multiplies) all entries in column \a column by \a factor
674 *
675 * \see \ref JKQTPlotterFilledGraphs
676 */
677 inline void scaleColumnValues(size_t column, double factor);
678 /** \brief increases entry in row \a row of column \a column by \a increment
679 *
680 * \see \ref JKQTPlotterFilledGraphs
681 */
682 inline void inc(size_t column, size_t row, double increment=1);
683 /** \brief decrements entry in row \a row of column \a column by \a decrement
684 *
685 * \see \ref JKQTPlotterFilledGraphs
686 */
687 inline void dec(size_t column, size_t row, double decrement=1);
688
689
690
691 /** \brief add a new columns with \a rows rows to the datastore and return its column ID. The new item uses internal memory management.
692 * \param rows number of rows in the data array
693 * \param name name for the column
694 * \return the ID of the newly created column
695 * \see \ref JKQTPlotterBasicJKQTPDatastore
696 */
697 size_t addColumn(size_t rows, const QString& name=QString(""));
698
699 /** \brief add a new and empty column to the datastore and return its column ID. The new item uses internal memory management.
700 * \param name name for the column
701 * \return the ID of the newly created column
702 * \see \ref JKQTPlotterBasicJKQTPDatastore
703 */
704 size_t addColumn(const QString& name=QString(""));
705
706 /** \brief add one external column to the datastore. It contains \a rows rows. This returns its logical column ID.
707 * Data is not owned by the JKQTPDatastore!
708 *
709 * \param data data array to be copied
710 * \param rows number of rows in the data array
711 * \param name name for the column
712 * \return the ID of the newly created column
713 *
714 * \code
715 * #define NDATA 5
716 * double XCA[NDATA]= { 1, 2, 3, 4, 5 };
717 * double YCA[NDATA]= { 1, 0, 1, 0, 1 };
718 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
719 * linegraph->setXColumn(datastore->addColumn(XCA, NDATA, "xca (C-array)"));
720 * linegraph->setYColumn(datastore->addColumn(YCA, NDATA, "yca (C-array)"));
721 * \endcode
722 * \see \ref JKQTPlotterBasicJKQTPDatastore
723 */
724 size_t addColumn(double* data, size_t rows, const QString& name=QString(""));
725 /** \brief add a column with \a rows entries from the array \a data,
726 * ownership of the memory behind \a data is transfered to the datastore
727 *
728 * \param data data array to be copied
729 * \param rows number of rows in the data array
730 * \param name name for the column
731 * \return the ID of the newly created column
732 *
733 * \code
734 * #define NDATA 5
735 * double* XCA=(double*)malloc(NDATA, sizeof(double));
736 * double* YCA=(double*)malloc(NDATA, sizeof(double));
737 * ...
738 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
739 * linegraph->setXColumn(datastore->addInternalColumn(XCA, NDATA, "x"));
740 * linegraph->setXColumn(datastore->addInternalColumn(YCA, NDATA, "y"));
741 * \endcode
742 * \see \ref JKQTPlotterBasicJKQTPDatastore
743 */
744 size_t addInternalColumn(double *data, size_t rows, const QString& name);
745
746
747 /** \brief add a new columns with \a width * \a height rows to the datastore and return its column ID. The new item uses internal memory management.
748 * The column is meant to represent an image in row-major order with x-dimention \a width and y-dimension \a height .
749 *
750 * \param width width of the image represented by the data array
751 * \param height height of the image represented by the data array
752 * \param name name for the column
753 * \return the ID of the newly created column
754 * \see addImageColumn(), addInternalImageColumn(), \ref JKQTPlotterBasicJKQTPDatastore
755 */
756 size_t addImageColumn(size_t width, size_t height, const QString& name=QString(""));
757
758 /** \brief add one external column to the datastore. It contains \a width * \a height rows. This returns its logical column ID.
759 * Data is not owned by the JKQTPDatastore!
760 * The column is meant to represent an image in row-major order with x-dimention \a width and y-dimension \a height .
761 *
762 *
763 * \param data data array to be copied
764 * \param width width of the image represented by the data array
765 * \param height height of the image represented by the data array
766 * \param name name for the column
767 * \return the ID of the newly created column
768 *
769 * \see addColumn(), addImageColumn(), addInternalImageColumn(), \ref JKQTPlotterBasicJKQTPDatastore
770 */
771 size_t addImageColumn(double* data, size_t width, size_t height, const QString& name=QString(""));
772 /** \brief add a column with \a width * \a height entries from the array \a data,
773 * ownership of the memory behind \a data is transfered to the datastore
774 * The column is meant to represent an image in row-major order with x-dimention \a width and y-dimension \a height .
775 *
776 *
777 * \param data data array to be copied
778 * \param width width of the image represented by the data array
779 * \param height height of the image represented by the data array
780 * \param name name for the column
781 * \return the ID of the newly created column
782 *
783 * \see addInternalColumn(), addImageColumn(), addInternalImageColumn(), \ref JKQTPlotterBasicJKQTPDatastore
784 */
785 size_t addInternalImageColumn(double *data, size_t width, size_t height, const QString& name);
786
787
788
789 /** \brief copies the given \a old_column into a new one, reading the data with the given start column and stride
790 *
791 * \param old_column the column to be duplicated
792 * \param start for row in column \a old_column to copy
793 * \param stride stride for iterating through \a old_column when copying
794 * \param name name for the new column
795 * \return ID of the newly created column
796 *
797 * Pseuo-Code:
798 * \code
799 * newColumn=addColumn(rowcount(old_column), name)
800 * forall ( r: rows(old_column)) {
801 * set(newColumn, r, get(old_column, r))
802 * }
803 * return newColumn;
804 * \endcode
805 */
806 size_t copyColumn(size_t old_column, size_t start, size_t stride, const QString& name=QString(""));
807 /** \brief copies the given \a old_column into a new one
808 *
809 * \param old_column the column to be duplicated
810 * \param name name for the new column
811 * \return ID of the newly created column
812 * \see \ref JKQTPlotterBasicJKQTPDatastore
813 */
814 size_t copyColumn(size_t old_column, const QString& name=QString(""));
815 /** \brief copies the data from \a fromColumn into an existing column \a toColumn
816 *
817 * \param toColumn target of the copy operation
818 * \param fromColumn source of the copy operation
819 *
820 * \warning If the memory in \a toColumn was externally managed before, it will be
821 * internally managed afterwards!
822 */
823 void copyColumnData(size_t toColumn, size_t fromColumn);
824
825
826
827 /** \brief add two columns to the datastore. They will be filled with the values from \a points (first column: x-value, second column: y-value)
828 *
829 * \param points list of datapoints to add
830 * \param namex name for the column with the x-values
831 * \param namey name for the column with the y-values
832 * \return the IDs of the newly created column
833 *
834 */
835 std::pair<size_t,size_t> addCopiedPoints(const QList<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
836 std::pair<size_t,size_t> addCopiedPoints(const QList<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
837#if QT_VERSION<QT_VERSION_CHECK(6,0,0)
838 std::pair<size_t,size_t> addCopiedPoints(const QVector<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
839 std::pair<size_t,size_t> addCopiedPoints(const QVector<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
840#endif
841 std::pair<size_t,size_t> addCopiedPoints(const std::vector<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
842 std::pair<size_t,size_t> addCopiedPoints(const std::vector<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
843 std::pair<size_t,size_t> addCopiedPoints(const std::list<QPointF>& points, const QString& namex=QString(""), const QString &namey=QString(""));
844 std::pair<size_t,size_t> addCopiedPoints(const std::list<QPoint>& points, const QString& namex=QString(""), const QString &namey=QString(""));
845
846 /** \brief add one column to the datastore. It will be filled with the values from \a first ... \a last
847 *
848 * \tparam TIterator a standard C++ iterator
849 * \param first points to the first value in the range of values to add
850 * \param last points behind the last value in the range of values to add
851 * \param name name for the column
852 * \return the ID of the newly created column
853 *
854 * \code
855 * QVector<double> X, Y;
856 * const int Ndata=100;
857 * for (int i=0; i<Ndata; i++) {
858 * const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
859 * X<<x;
860 * Y<<sin(x);
861 * }
862 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
863 * // by calling JKQTPDatastore::addCopiedColumn() the data is COPIED from the vector into the datastore
864 * linegraph->setXColumn(datastore->addCopiedColumn(X.begin(), X.end(), "x"));
865 * linegraph->setYColumn(datastore->addCopiedColumn(Y.begin(), Y.end(), "y"));
866 * \endcode
867 *
868 * \see \ref JKQTPlotterBasicJKQTPDatastore
869 */
870 template <typename TIterator>
871 size_t addCopiedColumn(TIterator first, TIterator last, const QString& name=QString("")) {
872 const size_t N=static_cast<size_t>(std::abs(std::distance(first,last)));
873 double* d=static_cast<double*>(malloc(static_cast<size_t>(N)*sizeof(double)));
874 if (N>0) {
875 size_t r=0;
876 for (auto it=first; it!=last; ++it) {
877 d[r]=jkqtp_todouble(*it);
878 r++;
879 }
880 }
881 size_t itemid=addInternalItem(d, N);
882 return addColumnForItem(itemid, 0, name);
883 }
884
885 /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data.
886 *
887 * \tparam TContainer datatype of the container, which need to support standard C++ iterators. The contents needs to be convertible to double.
888 * \param data data vector to be copied
889 * \param name name for the column
890 * \return the ID of the newly created column
891 *
892 * \code
893 * QVector<double> X, Y;
894 * const int Ndata=100;
895 * for (int i=0; i<Ndata; i++) {
896 * const double x=double(i)/double(Ndata)*8.0*JKQTPSTATISTICS_PI;
897 * X<<x;
898 * Y<<sin(x);
899 * }
900 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
901 * // by calling JKQTPDatastore::addCopiedColumn() the data is COPIED from the vector into the datastore
902 * linegraph->setXColumn(datastore->addCopiedColumn(X, "x"));
903 * linegraph->setYColumn(datastore->addCopiedColumn(Y, "y"));
904 * \endcode
905 *
906 * \see \ref JKQTPlotterBasicJKQTPDatastore
907 */
908 template <typename TContainer>
909 size_t addCopiedColumn(const TContainer& data, const QString& name=QString("")) {
910 return addCopiedColumn(data.begin(), data.end(), name);
911 }
912
913 /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data.
914 *
915 * \tparam TContainer datatype of the container, which need to support standard C++ iterators and the function \c size(). The contents needs to be convertible to double.
916 * The iterator of TContainer needs to support \c ++ and \c +=
917 * \param data data vector to be copied
918 * \param name name for the column
919 * \param stride strides through the container \a data with the given stride
920 * \param start starts copying from \a data with the element \a start
921 * \return the ID of the newly created column
922 *
923 * Pseudocode:
924 * \code
925 * it=data.begin();
926 * it += start; // shift by start items
927 * while (it!=data.end()) {
928 * newColumn.push_back(jkqtp_todouble(*it));
929 * it += stride;
930 * }
931 * \endcode
932 *
933 * \see \ref JKQTPlotterBasicJKQTPDatastore
934 */
935 template <typename TContainer>
936 size_t addCopiedColumn(const TContainer& data, const QString& name, size_t stride, size_t start=0) {
937 const size_t N=static_cast<size_t>(data.size()-start)/stride;
938 double* d=static_cast<double*>(malloc(static_cast<size_t>(N)*sizeof(double)));
939 if (N>0) {
940 size_t r=0;
941 auto it=data.begin();
942 if (start>0) it+=start;
943 for (; it!=data.end(); it+=stride) {
944 d[r]=jkqtp_todouble(*it);
945 r++;
946 }
947 }
948 size_t itemid=addInternalItem(d, N);
949 return addColumnForItem(itemid, 0, name);
950 }
951
952
953
954 /** \brief copy an external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
955 * afterwards you can delete the external arrayThis returns its logical column ID.
956 *
957 * \tparam T datatype of the element in the vector, this has to be convertible to double!
958 * \param data pointer to the data to be copied
959 * \param rows items in data
960 * \param name name for the column
961 * \return the ID of the newly created column
962 *
963 * \note This function converts the input array \a data into an array of double!
964 * \see \ref JKQTPlotterBasicJKQTPDatastore
965 */
966 template<typename T>
967 size_t addCopiedColumn(const T* data, size_t rows, const QString& name=QString("")){
968 double* d=static_cast<double*>(malloc(static_cast<size_t>(rows)*sizeof(double)));
969 if (d) {
970 if (data) {
971 for (size_t r=0; r<rows; r++) {
972 d[r]=jkqtp_todouble(data[r]);
973 }
974 }
975 const size_t itemid=addInternalItem(d, rows);
976 return addColumnForItem(itemid, 0, name);
977 } else {
978 throw std::runtime_error("could not allocate memory in JKQTPDataStore::addCopiedColumn()");
979 }
980 }
981
982 /** \brief copy an external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
983 * afterwards you can delete the external arrayThis returns its logical column ID.
984 *
985 * \tparam T datatype of the element in the vector, this has to be convertible to double!
986 * \param data pointer to the data to be copied
987 * \param rows number of items to copy from \a data
988 * \param stride when copying, this function steps throught the data with the given stride, so only eleemnts <code>[start, start+stride, start+2*stride, ... start+(rows-1)*stride]</code> are copied!
989 * \param start first element to copy
990 * \param name name for the column
991 * \return the ID of the newly created column
992 *
993 * Pseudocode:
994 * \code
995 * for (i=start; i<rows; i+=stride) {
996 * newColumn.push_back(jkqtp_todouble(data[i]));
997 * }
998 * \endcode
999
1000 * \note This function converts the input array \a data into an array of double!
1001 * \see \ref JKQTPlotterBasicJKQTPDatastore
1002 */
1003 template<typename T>
1004 size_t addCopiedColumn(const T* data, size_t rows, size_t stride, int start, const QString& name) {
1005 double* d=static_cast<double*>(malloc(static_cast<size_t>(rows)*sizeof(double)));
1006 if (d) {
1007 if (data) {
1008 for (size_t r=0; r<rows; r++) {
1009 d[r]=jkqtp_todouble(data[static_cast<size_t>(start+static_cast<int64_t>(r*stride))]);
1010 }
1011 }
1012 size_t itemid=addInternalItem(d, rows);
1013 return addColumnForItem(itemid, 0, name);
1014 } else {
1015 throw std::runtime_error("could not allocate memory in JKQTPDataStore::addCopiedColumn()");
1016 }
1017 }
1018
1019 /** \brief copy an external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
1020 * afterwards you can delete the external arrayThis returns its logical column ID.
1021 *
1022 * \tparam T datatype of the element in the vector, this has to be convertible to double!
1023 * \param data pointer to the data to be copied
1024 * \param rows items in data
1025 * \param name name for the column
1026 * \param stride when copying, this function steps throught the data with the given stride, so only eleemnts <code>[0, stride, 2*stride, ... (rows-1)*stride]</code> are copied!
1027 * \return the ID of the newly created column
1028 *
1029 *
1030 * Pseudocode:
1031 * \code
1032 * for (i=0; i<rows; i+=stride) {
1033 * newColumn.push_back(jkqtp_todouble(data[i]));
1034 * }
1035 * \endcode
1036
1037 * \note This function converts the input array \a data into an array of double!
1038 * \see \ref JKQTPlotterBasicJKQTPDatastore
1039 */
1040 template<typename T>
1041 size_t addCopiedColumn(const T* data, size_t rows, size_t stride, const QString& name) {
1042 return addCopiedColumn<T>(data, rows, stride, 0, name);
1043 }
1044
1045
1046 /** \brief add one external column to the datastore. It contains \a width * \a height rows. The external data is assumed to be organized as a row-major image and is copied as such. The external data is copied to an internal array, so
1047 * afterwards you can delete the external arrayThis returns its logical column ID.*/
1048 template <typename T>
1049 inline size_t addCopiedImageAsColumn(const T* data, size_t width, size_t height, const QString& name=QString(""), size_t stride=1, size_t start=0);
1050
1051 /** \brief add one external column to the datastore. It contains \a width * \a height rows. The external data is assumed to be organized as a row-major image and is copied as such. The external data is copied to an internal array, so
1052 * afterwards you can delete the external arrayThis returns its logical column ID.
1053 *
1054 * \tparam TContainer datatype of the container, which need to support standard C++ iterators and the function \c size(). The contents needs to be convertible to double.
1055 * \param data data vector to be copied
1056 * \param width width of the image, stored in \a data
1057 * \param name name for the column
1058 * \return the ID of the newly created column
1059 */
1060 template <typename TContainer>
1061 inline size_t addCopiedImageAsColumn(const TContainer& data, size_t width, const QString& name=QString(""));
1062
1063
1064 /** \brief add a new column to the datastore, which is filled from the transposed column-major array \a data with
1065 * the given \a width and \a height.
1066 *
1067 * The external data is assumed to be organized as a column-major image and is copied as row-major (i.e. is transposed).
1068 * The external data is copied to an internal array, so afterwards you can delete the external arrayThis returns its logical column ID.
1069 *
1070 * \tparam T data type of the array \a data, needs to be convertible to \c double by jkqtp_todouble()
1071 * \param data a column major image
1072 * \param width width of \a data
1073 * \param height height of \a data
1074 * \param name name of the new column
1075 * \param stride stride to use, when reading \a data. Use this to e.g. read one channel from a packed RGB-image (\c stride=3, \c start=0/1/2 )
1076 * \param start first entry from \a data top copy \a data. Use this to e.g. read one channel from a packed RGB-image (\c stride=3, \c start=0/1/2 )
1077 * \return ID of the newly added column
1078 */
1079 template <typename T>
1080 size_t addCopiedImageAsColumnTranspose(const T* data, size_t width, size_t height, const QString& name=QString(""), size_t stride=1, size_t start=0);
1081
1082
1083 /** \brief add one external column to the datastore. It contains \a width * \a height rows.
1084 *
1085 * The external data is assumed to be organized as a column-major image and is copied as row-major (i.e. is transposed).
1086 * The external data is copied to an internal array, so afterwards you can delete the external array This returns its
1087 * logical column ID.
1088 *
1089 * \tparam T data type of the array \a data, needs to be convertible to \c double by jkqtp_todouble()
1090 * \param data data vector to be copied
1091 * \param width width of the image, stored in \a data
1092 * \param name name for the column
1093 * \return the ID of the newly created column
1094 */
1095 template <typename T>
1096 inline size_t addCopiedImageAsColumnTranspose(const QVector<T>& data, size_t width, const QString& name=QString(""));
1097
1098 /** \brief add one external column to the datastore. It contains \a rows rows. The external data is copied to an internal array, so
1099 * afterwards you can delete the external arrayThis returns its logical column ID.
1100 *
1101 * \tparam T datatype of the element in the vector, this has to be convertible to double!
1102 * \param data pointer to the data to be copied
1103 * \param mask boolean array with \a rows entries, used to mask data when copying from \a data
1104 * \param rows items in data
1105 * \param name name for the column
1106 * \param useIfMaskEquals data from \a data is copied if and only if the corresponding entry of \a mask equals this value
1107 * \note This function converts the input array \a data into an array of double!
1108 * \see \ref JKQTPlotterBasicJKQTPDatastore
1109 */
1110 template <typename T>
1111 size_t addCopiedColumnMasked(const T* data, const bool* mask, size_t rows, const QString& name=QString(""), bool useIfMaskEquals=false) {
1112 double* d=static_cast<double*>(calloc(rows, sizeof(double)));
1113 size_t rrs=0;
1114 if (data) {
1115 for (size_t r=0; r<rows; r++) {
1116 if (!mask || (mask && (mask[r]==useIfMaskEquals))) {
1117 d[rrs]=jkqtp_todouble(data[r]);
1118 rrs++;
1119 }
1120 }
1121 }
1122
1123
1124 size_t col= addInternalColumn(d, rrs, name);
1125 return col;
1126 }
1127
1128 /** \brief add one external column to the datastore. It will be filled with the contents of vector \a data.
1129 *
1130 * \tparam TContainer datatype of the container \a data, which need to support standard C++ iterators and the function \c size(). The contents needs to be convertible to double.
1131 * \tparam TContainerMask datatype of the container \a mask, which need to support standard C++ iterators and the function \c size(). The contents needs to be convertible to bool.
1132 * \param data data vector to be copied
1133 * \param mask data vector to be copied
1134 * \param name name for the column
1135 * \param useIfMaskEquals data from \a data is copied if and only if the corresponding entry of \a mask equals this value
1136 * \return the ID of the newly created column
1137 * \see \ref JKQTPlotterBasicJKQTPDatastore
1138 *
1139 * Pseudocode:
1140 * \code
1141 * for (i=0; i<data.size(); i++) {
1142 * if (static_cast<bool>(mask[i])==useIfMaskEquals) {
1143 * newColumn.push_back(jkqtp_todouble(data[i]));
1144 * }
1145 * }
1146 * return newColumn;
1147 * \endcode
1148 */
1149 template <typename TContainer, typename TContainerMask>
1150 size_t addCopiedColumnMasked(const TContainer& data, const TContainerMask& mask, const QString& name=QString(""), bool useIfMaskEquals=false) {
1151 const size_t N=static_cast<size_t>(data.size());
1152 double* d=static_cast<double*>(malloc(static_cast<size_t>(N)*sizeof(double)));
1153 size_t rrs=0;
1154 if (data) {
1155 auto itmask=mask.begin();
1156 auto itdata=data.begin();
1157 for (size_t r=0; r<N; r++) {
1158 if (static_cast<bool>(*itmask)==useIfMaskEquals) {
1159 d[rrs]=jkqtp_todouble(*itdata);
1160 rrs++;
1161 }
1162 ++itmask;
1163 ++itdata;
1164 }
1165 }
1166 size_t col= addInternalColumn(d, rrs, name);
1167 return col;
1168
1169 }
1170
1171
1172 /** \brief copies the contents of the map-like container \a c into two columns of the datastore,
1173 * returns the two IDs of the items as a std::pair
1174 * \see \ref JKQTPlotterBasicJKQTPDatastore, jkqtp_todouble()
1175 *
1176 * \tparam TIterator a standard C++ iterator for a map, dereferencing with \a it->first and \a it->second
1177 * \param first points to the first value in the range of values to add
1178 * \param last points behind the last value in the range of values to add
1179 * \param nameKey name for the column with the map keys
1180 * \param nameValue name for the column with the map values
1181 * \return a pair of IDs to the newly created columns (IDkeyColumn, IDvalueColumn)
1182 * Example of usage:
1183 * \code
1184 * std::map<int, double> datamap;
1185 * datamap[1]=1.1;
1186 * datamap[2]=1.4;
1187 * datamap[4]=1.2;
1188 * datamap[5]=1.8;
1189 * datamap[7]=0.9;
1190 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
1191 * linegraph->setXYColumns(datastore->addCopiedMap(datamap.begin(), datamap.end(), "map_x", "map_y"));
1192 * linegraph->setTitle(QObject::tr("copied map"));
1193 * \endcode
1194 */
1195 template <typename TIterator>
1196 std::pair<size_t, size_t> addCopiedMap(TIterator first, TIterator last, const QString& nameKey=QString("map_key"), const QString& nameValue=QString("map_value")) {
1197 const size_t N=static_cast<size_t>(std::abs(std::distance(first,last)));
1198 double* xvals=static_cast<double*>(malloc(N*sizeof(double)));
1199 double* yvals=static_cast<double*>(malloc(N*sizeof(double)));
1200 size_t i=0;
1201 for (auto it=first; it!=last; ++it) {
1202 xvals[i]=(jkqtp_todouble(it->first));
1203 yvals[i]=(jkqtp_todouble(it->second));
1204 i++;
1205 }
1206 const size_t cx=addInternalColumn(xvals, N, nameKey);
1207 const size_t cy=addInternalColumn(yvals, N, nameValue);
1208 return std::pair<size_t, size_t>(cx,cy);
1209 }
1210
1211 /** \brief copies the contents of the map-like container \a c into two columns of the datastore,
1212 * returns the two IDs of the items as a std::pair
1213 * \see \ref JKQTPlotterBasicJKQTPDatastore, jkqtp_todouble()
1214 *
1215 * \tparam TContainer datatype of the map-typed container (e.g. \c std::map or \c QMap ) The requiremen to this container is
1216 * that it supports standard iterators with \c begin() and \c end() .
1217 * \param c the map to copy to the datastore
1218 * \param nameKey name for the column with the map keys
1219 * \param nameValue name for the column with the map values
1220 * \return a pair of IDs to the newly created columns (IDkeyColumn, IDvalueColumn)
1221 * Example of usage:
1222 * \code
1223 * std::map<int, double> datamap;
1224 * datamap[1]=1.1;
1225 * datamap[2]=1.4;
1226 * datamap[4]=1.2;
1227 * datamap[5]=1.8;
1228 * datamap[7]=0.9;
1229 * plot.addGraph(linegraph=new JKQTPXYLineGraph(&plot));
1230 * linegraph->setXYColumns(datastore->addCopiedMap(datamap, "map_x", "map_y"));
1231 * linegraph->setTitle(QObject::tr("copied map"));
1232 * \endcode
1233 */
1234 template <typename TContainer>
1235 std::pair<size_t, size_t> addCopiedMap(const TContainer& c, const QString& nameKey=QString("map_key"), const QString& nameValue=QString("map_value")) {
1236 return addCopiedMap(c.begin(), c.end(), nameKey, nameValue);
1237 }
1238
1239
1240
1241
1242 /** \brief add a column to the datastore that contains \a rows rows with monotonely increasing value starting at \a start and ending at \a end.
1243 * the values are equidistant between \a start end \a end
1244 * \see addLogColumn(), addDecadeLogColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1245 */
1246 size_t addLinearColumn(size_t rows, double start, double end, const QString& name=QString(""));
1247 /** \brief add a column to the datastore that contains \a rows rows with monotonely increasing value starting at \a start and ending at \a end.
1248 * the values are logarithmically spaced between \a start end \a end
1249 * \see addLinearColumn(), addDecadeLogColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1250 */
1251 size_t addLogColumn(size_t rows, double start, double end, const QString& name=QString(""));
1252 /** \brief add a column to the datastore that contains \a rows rows with monotonely increasing value starting at 10^start and ending at 10^end.
1253 * the values are logarithmically spaced between 10^start end 10^end
1254 * \see addLinearColumn(), addLogColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1255 */
1256 size_t addDecadeLogColumn(size_t rows, double startDecade, double endDecade, const QString& name=QString(""));
1257
1258
1259 /** \brief add two columns to the datastore that contains the x- and y- coordinates of a rectangular grid with \a width points in x- and \a height
1260 * points in y-direction.
1261 *
1262 * \param width number of columns in the mesh grid
1263 * \param startX x-coordinate of the first column of the mesh grid
1264 * \param endX x-coordinate of the last column of the mesh grid
1265 * \param height number of rows in the mesh grid
1266 * \param startY y-coordinate of the first row of the mesh grid
1267 * \param endY y-coordinate of the last row of the mesh grid
1268 * \param nameX name for the x-coordinate column
1269 * \param nameY name for the y-coordinate column
1270 * \return IDs of two column that contain the x- and y- coordinates od the mesh points (in row-major order), where the
1271 * x-coordinates are linearly distributed between \a startX and \a endX and the x-coordinates are linearly
1272 * distributed between \a startY and \a endY .
1273 *
1274 * \see addLogGridColumns(), addDecadeLogGridColumns(), addCalculatedColumnFromColumn(), JKQTPXYParametrizedScatterGraph, \ref JKQTPlotterBasicJKQTPDatastore
1275 */
1276 std::pair<size_t,size_t> addLinearGridColumns(size_t width, double startX, double endX, size_t height, double startY, double endY, const QString& nameX=QString(""), const QString& nameY=QString(""));
1277
1278
1279 /** \brief add a column with \a rows entries, that is calculated by calling \a f for each entry
1280 *
1281 * Pseudocode:
1282 * \code
1283 * for (i=0; i<rows; i++) {
1284 * newColumn.push_back(f(i, this));
1285 * }
1286 * return newColumn;
1287 * \endcode
1288 *
1289 * \see addCalculatedColumnFromColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1290 */
1291 size_t addCalculatedColumn(size_t rows, const std::function<double(size_t, JKQTPDatastore*)>& f, const QString& name=QString(""));
1292 /** \brief add a column with \a rows entries, that is calculated by calling \a f for each entry
1293 *
1294 * Pseudocode:
1295 * \code
1296 * for (i=0; i<rows; i++) {
1297 * newColumn.push_back(f(i));
1298 * }
1299 * return newColumn;
1300 * \endcode
1301 *
1302 * \see addCalculatedColumnFromColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1303 */
1304 size_t addCalculatedColumn(size_t rows, const std::function<double(size_t)>& f, const QString& name=QString(""));
1305 /** \brief add an image column with width \a cols and height \a rows (i.e. \a rows * \a cols entries), that is calculated by calling \a f for each entry
1306 *
1307 * Pseudocode:
1308 * \code
1309 * for (y=0; y<rows; y++) {
1310 * for (x=0; x<cols; x++) {
1311 * newColumn.push_back(f(x,y));
1312 * }
1313 * }
1314 * return newColumn;
1315 * \endcode
1316 *
1317 * \see addCalculatedColumnFromColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1318 */
1319 size_t addCalculatedImageColumn(size_t cols, size_t rows, const std::function<double(size_t,size_t)>& f, const QString& name=QString(""));
1320 /** \brief add a column with the same number of entries, as in the other column \a otherColumn , that are calculated by calling \a f for each entry in \a otherColumn
1321 *
1322 * Pseudocode:
1323 * \code
1324 * for (i=0; i<rows(otherColumn); i++) {
1325 * newColumn.push_back(f(getValue(otherColumn, i));
1326 * }
1327 * return newColumn;
1328 * \endcode
1329 *
1330 * \see addCalculatedColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1331 */
1332 size_t addCalculatedColumnFromColumn(size_t otherColumn, const std::function<double(double)>& f, const QString& name=QString(""));
1333 inline size_t addColumnCalculatedFromColumn(size_t otherColumn, const std::function<double(double)>& f, const QString& name=QString("")) {
1334 return addCalculatedColumnFromColumn(otherColumn, f, name);
1335 }
1336 /** \brief add a column with the same number of entries, as in the other column \a otherColumn , that are calculated by calling \a f for each pair of entries in \a otherColumnX and \a otherColumnY
1337 *
1338 * Pseudocode:
1339 * \code
1340 * for (i=0; i<std::min(rows(otherColumnX), rows(otherColumnY)); i++) {
1341 * newColumn.push_back(f(getValue(otherColumnX, i), getValue(otherColumnY, i));
1342 * }
1343 * return newColumn;
1344 * \endcode
1345 *
1346 * \see addCalculatedColumn(), \ref JKQTPlotterBasicJKQTPDatastore
1347 */
1348 size_t addCalculatedColumnFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function<double(double,double)>& f, const QString& name=QString(""));
1349 inline size_t addColumnCalculatedFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function<double(double,double)>& f, const QString& name=QString("")) {
1350 return addCalculatedColumnFromColumn(otherColumnX, otherColumnY, f, name);
1351 }
1352 inline size_t addCalculatedColumnFromColumn(const std::pair<size_t, size_t>& otherColumn, const std::function<double(double,double)>& f, const QString& name=QString("")) {
1353 return addCalculatedColumnFromColumn(otherColumn.first, otherColumn.second, f, name);
1354 }
1355
1356 /** \brief returns the number of (logical) columns currently managed by the datastore */
1357 inline size_t getColumnCount() const { return static_cast<size_t>(columns.size()); }
1358
1359 /** \brief returns a list with all available column IDs */
1360 inline QList<size_t> getColumnIDs() const { return columns.keys(); }
1361 /** \brief returns a list with all available column IDs */
1362 QVector<int> getColumnIDsIntVec() const;
1363
1364 /** \brief return the num of the first column with the given name, or -1 if none was found */
1365 int getColumnNum(const QString& name);
1366
1367 /** \brief return the title of the first column with the given name, or -1 if none was found */
1368 QString getColumnName(size_t column);
1369
1370 /** \brief return the num of the first column with the given name, if none was found this creates a new column with no rows and returns its num */
1371 int ensureColumnNum(const QString& name);
1372
1373
1374 /** \brief returns the maximum number of rows in all columns */
1375 size_t getMaxRows() const;
1376
1377 /** \brief save contents of datastore as Comma Separated Values (CSV) file
1378 *
1379 * \param filename the file to create
1380 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1381 * \param separator the column separator char
1382 * \param decimal_separator the decimal separator ('.' by default)
1383 * \param comment comments are started with this string and end with a linebreak. If this parameter is empty no comments will be output
1384 * \param aroundStrings strings (in column headers) are surrounded by these characters!
1385 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1386 *
1387 * Here are some default configuration:
1388 * - <code>saveCSV(filename, ", ", ".", "#")</code> will generate a standard CSV file with commas between the columns and a point as decimal separator. Comments start with \c #
1389 * - <code>saveCSV(filename, "; ", ",", "")</code> will generate a CSV file which may be read by a german Excel version: separated by ; and comma as decimal separator
1390 * - <code>saveCSV(filename, "\t", ".", "#")</code> will generate a tab separated values file
1391 * - ...
1392 * .
1393 */
1394 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;
1395 /** \brief save contents of datastore as Comma Separated Values (CSV) file
1396 *
1397 * \param txt QTextStream to write to
1398 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1399 * \param separator the column separator char
1400 * \param decimal_separator the decimal separator ('.' by default)
1401 * \param comment comments are started with this string and end with a linebreak. If this parameter is empty no comments will be output
1402 * \param aroundStrings strings (in column headers) are surrounded by these characters!
1403 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1404 *
1405 * Here are some default configuration:
1406 * - <code>saveCSV(filename, ", ", ".", "#")</code> will generate a standard CSV file with commas between the columns and a point as decimal separator. Comments start with \c #
1407 * - <code>saveCSV(filename, "; ", ",", "")</code> will generate a CSV file which may be read by a german Excel version: separated by ; and comma as decimal separator
1408 * - <code>saveCSV(filename, "\t", ".", "#")</code> will generate a tab separated values file
1409 * - ...
1410 * .
1411 */
1412 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;
1413
1414 /** \brief save contents of datastore as <a href="http://en.wikipedia.org/wiki/SYmbolic_LinK_(SYLK)">SYLK file (SYmbolic LinK)</a>
1415 *
1416 * \param filename the file to create
1417 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1418 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1419 */
1420 void saveSYLK(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& floatformat=QString("%10.10lf")) const;
1421
1422 /** \brief return contents of datastore as QList<QVector<double> >, i.e. a list of column-vectors
1423 *
1424 * \param columnNames if \c !=nullptr this will afterwards conatin the column titles
1425 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1426 */
1427 QList<QVector<double> > getData(QStringList* columnNames=nullptr, const QSet<int>& userColumns=QSet<int>()) const;
1428
1429 /** \brief return contents of a given column as QVector<double>
1430 *
1431 * \param column column to copy
1432 * \param columnName if \c !=nullptr this will afterwards conatin the column title
1433 */
1434 QVector<double> getData(size_t column, QString* columnName=nullptr) const;
1435
1436 /** \brief save contents of datastore as <a href="http://www.fileformat.info/format/dif/egff.htm">DIF file (data interchange format)</a>
1437 *
1438 * \param filename the file to create
1439 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1440 * \param floatformat a \c printf format string that is used to print floating point numbers to the file
1441 */
1442 void saveDIF(const QString& filename, const QSet<int>& userColumns=QSet<int>(), const QString& floatformat=QString("%10.10lf")) const;
1443
1444 /** \brief save contents of datastore as a Matlab script
1445 *
1446 * \param filename the file to create
1447 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1448 */
1449 void saveMatlab(const QString& filename, const QSet<int>& userColumns=QSet<int>()) const;
1450 /** \brief save contents of datastore as a Matlab script
1451 *
1452 * \param txt the QTextStream to write to
1453 * \param userColumns a list of all columns to export, an empty list means: export all, the indexes in the list refer to getColumnsNames()
1454 */
1455 void saveMatlab(QTextStream& txt, const QSet<int>& userColumns=QSet<int>()) const;
1456
1457 /** \brief return a list with all columns available in the datastore */
1458 QStringList getColumnNames() const;
1459
1460
1461
1462
1463 friend class JKQTPColumn;
1466};
1467
1468
1469
1470
1471
1472/** \brief internally stores information about one data column. See JKQTPDatastore for more information.
1473 * \ingroup jkqtpdatastorage_classes
1474 * \internal
1475 *
1476 * \see JKQTPDatastore
1477 */
1479 private:
1480 /** \brief index of the item in the datastore that contains the data for this column */
1482 /** \brief offset, if the datastore item contains more than one column */
1484 /** \brief number of columns, if interpreted as a row-major image */
1486 /** \brief pointer to the datastore object used to manage the data of the plot */
1488 /** \brief a name describing the column */
1489 QString name;
1490 /** \brief is this item valid?/usable? */
1491 bool valid;
1492 public:
1495
1496
1498 /** \brief class constructor that binds the column to a specific datastore object.
1499 *
1500 * The use of this constructor is mandatory. The default constructor (no arguments) is hidden. Also note
1501 * that you cannot change the binding of a column to a datastore object after creation of the column.
1502 */
1503 JKQTPColumn(JKQTPDatastore* datastore, const QString& name=QString(""), size_t datastoreItem=0, size_t datastoreOffset=0, size_t imageColumns=1);
1504
1505 inline bool isValid() const { return valid; }
1506
1507 /** \brief two columns are equal, if the same memory in the same datastore is referenced */
1508 inline bool operator==(const JKQTPColumn& other) const {
1509 return (datastoreItem==other.datastoreItem)
1510 && (datastoreOffset==other.datastoreOffset)
1511 && (datastore==other.datastore)
1512 && (valid==other.valid);
1513 }
1514
1515 /** \copydoc name */
1516 void setName (const QString& __value);
1517 /** \copydoc name */
1518 QString getName () const;
1519
1520 /** \copydoc imageColumns */
1521 void setImageColumns (size_t imageWidth);
1522 /** \copydoc imageColumns */
1523 inline size_t getImageColumns () const { return imageColumns; }
1524
1525 /** \brief returns the number of rows in this column (accesses the datastore) */
1526 size_t getRows() const;
1527
1528 /** \brief copies the contained data into a QVector */
1529 void copyData(QVector<double>& copyTo) const;
1530 /** \brief returns a QVector with the contained data (as a copy) */
1531 QVector<double> copyData();
1532
1533 /** \brief reads the \a n'th value from the column
1534 *
1535 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1536 * column.
1537 */
1538 inline double getValue(size_t n) const;
1539 /** \brief reads the \a n'th value from the column
1540 *
1541 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1542 * column.
1543 */
1544 inline double getValue(int n) const;
1545 /** \brief returns a reference to the \a n -th row in this column (possibly throwing an exception if it does not exist!)
1546 *
1547 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1548 * column.
1549 *
1550 * \see iterator
1551 */
1552 inline double& at(int n);
1553 /** \brief returns a reference to the \a n -th row in this column (possibly throwing an exception if it does not exist!)
1554 *
1555 * This method accesses the datastore and returns the double value stored in the \a n'th row of the according
1556 * column.
1557 *
1558 * \see const_iterator
1559 */
1560 inline const double& at(int n) const;
1561 /** \brief gets a pointer to the n-th value in the column */
1562 double* getPointer(size_t n=0) ;
1563 /** \brief gets a pointer to the n-th value in the column */
1564 const double* getPointer(size_t n=0) const;
1565
1566 /** \brief sets the \a n'th value from the column
1567 *
1568 * This method accesses the datastore and sets the value stored in the \a n'th row of the according
1569 * column.
1570 */
1571 inline void setValue(size_t n, double val);
1572
1573 /** \brief increment the \a n'th value from the column
1574 *
1575 */
1576 inline void incValue(size_t n, double increment=1.0);
1577
1578 /** \brief decrement the \a n'th value from the column
1579 *
1580 */
1581 inline void decValue(size_t n, double decrement=1.0) {
1582 incValue(n, -1.0*decrement);
1583 }
1584
1585
1586 /** \brief sets the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matrix of the given width
1587 *
1588 * This method accesses the datastore and returns the double value stored in the \c (y*width+x)'th row of the according
1589 * column.
1590 */
1591 inline void setPixelValue(size_t x, size_t y, size_t width, double val) {
1592 setValue(y*width+x, val);
1593 }
1594
1595
1596 /** \brief sets the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matrix of the width imageWidth
1597 *
1598 * This method accesses the datastore and returns the double value stored in the \c (y*imageColumns+x)'th row of the according
1599 * column.
1600 */
1601 inline void setPixelValue(size_t x, size_t y, double val) {
1602 setValue(y*imageColumns+x, val);
1603 }
1604
1605 /** \brief returns the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matrix of the width imageWidth
1606 *
1607 * This method accesses the datastore and returns the double value stored in the \c (y*imageColumns+x)'th row of the according
1608 * column.
1609 */
1610 inline double getPixelValue(size_t x, size_t y) const {
1611 return getValue(y*imageColumns+x);
1612 }
1613
1614 /** \brief returns a pointer to the datastore item representing this column */
1615 inline JKQTPDatastoreItem* getDatastoreItem() { return datastore->getItem(datastoreItem); }
1616 /** \brief returns a pointer to the datastore item representing this column */
1617 inline const JKQTPDatastoreItem* getDatastoreItem() const { return datastore->getItem(datastoreItem); }
1618
1619 /** \brief copy data from the given array into the column
1620 *
1621 * This copies \a N elements from \a data into the column where the first overwritten column
1622 * line is \a offset, so you can shift the location where the copy process starts.
1623 */
1624 void copy(const double* data, size_t N, size_t offset=0);
1625
1626 /** \brief exchange every occurence of a given \a value by a \a replace value */
1627 void exchange(double value, double replace);
1628
1629 /** \brief subtracts a given value from all members of the column */
1630 void subtract(double value);
1631 /** \brief scales all members of the column with the given factor */
1632 void scale(double factor);
1633
1634 /** \brief set all values in the column to a specific \a value */
1635 void setAll(double value);
1636
1637 /** \brief calculates a checksum over the contents of the column (using <a href="https://doc.qt.io/qt-5/qbytearray.html#qChecksum">qChecksum()</a>) */
1638 inline quint16 calculateChecksum() const;
1639
1640 /** \copydoc datastoreItem */ \
1641 inline size_t getDatastoreItemNum() const \
1642 { return this->datastoreItem; }
1643 /** \copydoc datastoreOffset */ \
1644 inline size_t getDatastoreOffset() const \
1645 { return this->datastoreOffset; }
1646
1647 /** \brief returns an iterator to the internal data
1648 * \see JKQTPColumnIterator */
1649 inline iterator begin();
1650 /** \brief returns an iterator to the internal data
1651 * \see JKQTPColumnIterator */
1652 inline iterator end();
1653
1654 /** \brief returns an iterator to the internal data
1655 * \see JKQTPColumnIterator */
1656 inline const_iterator begin() const;
1657 /** \brief returns an iterator to the internal data
1658 * \see JKQTPColumnIterator */
1659 inline const_iterator end() const;
1660
1661
1662 friend class JKQTPDatastore;
1665
1666 protected:
1667 inline JKQTPDatastore* getDatastore() { return datastore; }
1668 inline const JKQTPDatastore* getDatastore() const { return datastore; }
1669 inline void replaceMemory(size_t datastoreItem_=0, size_t datastoreOffset_=0) {
1670 datastoreItem=datastoreItem_;
1671 datastoreOffset=datastoreOffset_;
1672 }
1673 /** \brief removes the entry \a row */
1674 inline void erase(size_t row);
1675 /** \brief removes the entries \a row to \a rowEnd */
1676 inline void erase(size_t row, size_t rowEnd);
1677
1678};
1679
1680#pragma pack(push,1)
1681/** \brief iterator over the data in the column of a JKQTPDatastore
1682 * \ingroup jkqtpdatastorage_classes
1683 *
1684 * \see JKQTPColumn, JKQTPDatastore::begin(), JKQTPDatastore::end(), JKQTPDatastore, JKQTPConstColumnIterator
1685 */
1687 private:
1688 /** \brief references the column this iterator iterates over */
1690 /** \brief current row in col_ this iterator points to */
1691 int pos_;
1692 protected:
1693 /** \brief constructs an iterator for the data represented by \a col, starting with row \a startpos */
1694 inline JKQTPColumnIterator(JKQTPColumn* col, int startpos=0) : col_(col), pos_(startpos) { }
1695 public:
1697 typedef double value_type;
1698 typedef double& reference;
1699 typedef const double& const_reference;
1700 typedef double* pointer;
1701 typedef std::forward_iterator_tag iterator_category;
1702 typedef int difference_type;
1703 /** \brief constructs an invalid iterator */
1704 inline JKQTPColumnIterator() : col_(nullptr), pos_(-1) { }
1709 inline self_type operator++(int /*junk*/) {
1710 self_type i = *this;
1711 if (!isValid()) pos_++;
1712 return i;
1713 }
1715 if (!isValid()) return self_type(col_);
1716 pos_++; return *this;
1717 }
1718 inline self_type operator--(int /*junk*/) {
1719 self_type i = *this;
1720 if (isValid()) {
1721 pos_--;
1722 } else {
1724 pos_=static_cast<int>(col_->getRows())-1;
1725 }
1726 return i;
1727 }
1729 if (isValid()) {
1730 pos_--;
1731 } else {
1733 pos_=static_cast<int>(col_->getRows())-1;
1734 }
1735 return *this;
1736 }
1737 inline self_type operator+=(int inc) {
1738 if (isValid()) {
1739 pos_+=inc;
1740 } else if (inc<0) {
1742 pos_=static_cast<int>(col_->getRows())+inc;
1743 }
1744 return *this;
1745 }
1746 inline self_type operator-=(int dec) {
1747 if (isValid()) {
1748 pos_-=dec;
1749 } else {
1751 pos_=static_cast<int>(col_->getRows())-dec;
1752 }
1753
1754 return *this;
1755 }
1756
1757 friend self_type operator+(difference_type off, const self_type& right) {
1758 if (right.isValid()) {
1759 return self_type(right.col_, off + right.pos_);
1760 } else {
1761 if (off<0) return self_type(right.col_, off + static_cast<int>(right.col_->getRows()));
1762 else return self_type(right.col_);
1763 }
1764 }
1765 friend self_type operator-(difference_type off, const self_type& right) {
1766 if (right.isValid()) {
1767 return self_type(right.col_, off - right.pos_);
1768 } else {
1769 return self_type(right.col_);
1770 }
1771 }
1773 if (isValid()) {
1774 return self_type(col_, pos_+rhs);
1775 } else if (rhs<0){
1777 return self_type(col_, static_cast<int>(col_->getRows())+rhs);
1778 } else {
1779 return self_type(col_);
1780 }
1781 }
1783 if (isValid()) {
1784 return self_type(col_, pos_-rhs);
1785 } else {
1787 return self_type(col_, static_cast<int>(col_->getRows())-rhs);
1788 }
1789 }
1791 if (!isValid() && !rhs.isValid()) return 0;
1792 if (!isValid() && rhs.isValid() && col_==rhs.col_) return static_cast<difference_type>(col_->getRows())-rhs.pos_;
1793 if (isValid() && !rhs.isValid() && col_==rhs.col_) return pos_-static_cast<difference_type>(col_->getRows());
1795 JKQTPASSERT(rhs.isValid());
1796 JKQTPASSERT(col_==rhs.col_);
1797 return pos_-rhs.pos_;
1798 }
1799
1800 /** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
1801 inline reference operator*() const {
1802 JKQTPASSERT((col_!=nullptr) );
1803 JKQTPASSERT( (pos_>=0) );
1804 JKQTPASSERT( (pos_<static_cast<int>(col_->getRows())));
1805 return col_->at(pos_);
1806 }
1807 /** \brief dereferences the iterator at offset \a off, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
1809 {
1810 if (!isValid() && off<0) {
1811 return col_->at(static_cast<int>(col_->getRows())+off);
1812 }
1813 JKQTPASSERT((col_!=nullptr) );
1814 JKQTPASSERT( (pos_+off>=0) );
1815 JKQTPASSERT( (pos_+off<static_cast<int>(col_->getRows())));
1816 return col_->at(pos_+off);
1817 }
1818
1819 /** \brief comparison operator (equals)
1820 *
1821 * two iterators are equal, if:
1822 * - they are both invalid (see isValid() )
1823 * - they point to the same column and are both invalid (isValid()) or equal to end()
1824 * - they point to the same column and the same row therein
1825 * .
1826 *
1827 * \see operator!=()
1828 * */
1829 inline bool operator==(const self_type& rhs) const {
1830 if (!isValid() && !rhs.isValid()) return true;
1831 if (col_ == rhs.col_) {
1832 if ((pos_<0 || pos_>=static_cast<int>(rhs.col_->getRows())) && (pos_<0 || rhs.pos_>=static_cast<int>(rhs.col_->getRows()))) return true;
1833 return pos_==rhs.pos_;
1834 }
1835 return false;
1836 }
1837 /** \brief comparison operator (less than)
1838 *
1839 * rules:
1840 * - ivalid iterators are never smaller than valid operators
1841 * - two valid operator must reference the same column
1842 * - a valid operator is smaller than another, if it points to a pos_ before another
1843 * .
1844 *
1845 * \see operator<=(), operator>(), operator>=()
1846 * */
1847 inline bool operator<(const self_type& rhs) const {
1848 if (!isValid() && !rhs.isValid()) return false;
1849 else if (!isValid() && rhs.isValid()) {
1850 return false;
1851 } else if (isValid() && !rhs.isValid()) {
1852 return true;
1853 } else {
1854 JKQTPASSERT(col_ == rhs.col_);
1855 return pos_<rhs.pos_;
1856 }
1857 }
1858 /** \brief comparison operator (less than, or equal)
1859 * \see operator==(), operator<(), operator>(), operator>=()
1860 * */
1861 inline bool operator<=(const self_type& rhs) const {
1862 return operator==(rhs) || operator<(rhs);
1863 }
1864 /** \brief comparison operator (larger than)
1865 *
1866 * rules:
1867 * - ivalid iterators are always larger than valid operators
1868 * - two valid operator must reference the same column
1869 * - a valid operator is smaller than another, if it points to a pos_ before another
1870 * .
1871 *
1872 * \see operator<=(), operator<(), operator>=()
1873 * */
1874 inline bool operator>(const self_type& rhs) const {
1875 if (!isValid() && !rhs.isValid()) return false;
1876 else if (!isValid() && rhs.isValid()) {
1877 return true;
1878 } else if (isValid() && !rhs.isValid()) {
1879 return false;
1880 } else {
1881 JKQTPASSERT(col_ == rhs.col_);
1882 return pos_>rhs.pos_;
1883 }
1884 }
1885 /** \brief comparison operator (larger than, or equal)
1886 * \see operator==(), operator<(), operator>(), operator<=()
1887 * */
1888 inline bool operator>=(const self_type& rhs) const {
1889 return operator==(rhs) || operator>(rhs);
1890 }
1891 /** \brief comparison operator (unequals), inverse result of operator==()
1892 *
1893 * \see operator==()
1894 * */
1895 inline bool operator!=(const self_type& rhs) const { return !this->operator==(rhs); }
1896 /** \brief checks the iterator for validity (i.e. points to an existing column and position is in a valid range) */
1897 inline bool isValid() const {
1898 return col_ && pos_>=0 && pos_<static_cast<int>(col_->getRows());
1899 }
1900 /** \copydoc isValid() */
1901 inline operator bool() const { return isValid(); }
1902 /** \brief returns the referenced position/row, or -1 for an invalid iterator */
1903 inline int getPosition() const {
1904 if (!isValid()) return -1;
1905 return pos_;
1906 }
1907 /** \brief returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid operator */
1908 inline QPoint getImagePosition() const {
1909 if (!isValid()) return QPoint(-1,-1);
1910 return QPoint(pos_ % static_cast<int>(col_->getImageColumns()), pos_ / static_cast<int>(col_->getImageColumns()));
1911 }
1912 /** \brief returns the referenced position/row interpreted as an image pixel, x-component, returns -1 for an invalid operator */
1913 inline int getImagePositionX() const {
1914 if (!isValid()) return -1;
1915 return pos_ % static_cast<int>(col_->getImageColumns());
1916 }
1917 /** \brief returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an invalid operator */
1918 inline int getImagePositionY() const {
1919 if (!isValid()) return -1;
1920 return pos_ / static_cast<int>(col_->getImageColumns());
1921 }
1922 /*! \brief if the data in the column is interpreted as an image, this is the number of columns (x-dimension) of the image
1923 \see JKQTPColumn::imageColumns */
1924 inline size_t getImageColumns () const {
1925 if (!isValid()) return 0;
1926 return col_->getImageColumns();
1927 }
1928 /*! \brief if the data in the column is interpreted as an image, this is the number of rows (y-dimension) of the image
1929 \see JKQTPColumn::imageColumns */
1930 inline size_t getImageRows () const {
1931 if (!isValid()) return 0;
1932 return col_->getRows() / col_->getImageColumns();
1933 }
1935 friend class JKQTPColumn;
1936 friend class JKQTPDatastore;
1937 protected:
1938 /** \brief returns the referenced column */
1939 inline JKQTPColumn* getColumn() { return col_; }
1940 /** \brief returns the referenced column */
1941 inline const JKQTPColumn* getColumn() const { return col_; }
1942};
1943
1944
1945
1946
1947
1948
1949/** \brief iterator, which allows to insert into a column of a JKQTPDatastore
1950 * \ingroup jkqtpdatastorage_classes
1951 *
1952 * \see JKQTPDatastore::backInserter(), JKQTPDatastore, http://www.cplusplus.com/reference/iterator/insert_iterator/
1953 */
1955 private:
1956 /** \brief references the datastore to access */
1958 /** \brief references the column to access */
1959 size_t col_;
1960 protected:
1961 /** \brief constructs an iterator for the data represented by \a col, starting with row \a startpos */
1962 inline JKQTPColumnBackInserter(JKQTPDatastore* ds, size_t col) : ds_(ds), col_(col) { }
1963 public:
1965 typedef double value_type;
1966 typedef double& reference;
1967 typedef const double& const_reference;
1968 typedef double* pointer;
1969 typedef std::output_iterator_tag iterator_category;
1970 typedef int difference_type;
1971 /** \brief constructs an invalid iterator */
1972 inline JKQTPColumnBackInserter() : ds_(nullptr), col_(0) { }
1977 inline JKQTPColumnBackInserter& operator=(const double& val) {
1979 ds_->appendToColumn(col_, val);
1980 return *this;
1981 }
1982 inline JKQTPColumnBackInserter& operator=(double&& val) {
1984 ds_->appendToColumn(col_, std::move(val));
1985 return *this;
1986 }
1987 inline self_type operator++(int /*junk*/) { return *this; }
1988 inline self_type operator++() { return *this; }
1990 return *this;
1991 }
1992 friend class JKQTPDatastore;
1993};
1994
1995/** \brief iterator over the data in the column of a JKQTPDatastore
1996 * \ingroup jkqtpdatastorage_classes
1997 *
1998 * \see JKQTPColumn, JKQTPDatastore::begin(), JKQTPDatastore::end(), JKQTPDatastore, JKQTPColumnIterator
1999 */
2001 private:
2002 /** \brief references the column this iterator iterates over */
2004 /** \brief current row in col_ this iterator points to */
2005 int pos_;
2006 protected:
2007 /** \brief constructs an iterator for the data represented by \a col, starting with row \a startpos */
2008 inline JKQTPColumnConstIterator(const JKQTPColumn* col, int startpos=0) : col_(col), pos_(startpos) { }
2009 public:
2011 typedef double value_type;
2012 typedef const double& reference;
2014 typedef const double* pointer;
2015 typedef std::forward_iterator_tag iterator_category;
2016 typedef int difference_type;
2017 /** \brief constructs an invalid iterator */
2018 inline JKQTPColumnConstIterator() : col_(nullptr), pos_(-1) { }
2023 col_(std::move(rhs.col_)), pos_(std::move(rhs.pos_))
2024 {
2025 rhs.col_=nullptr;
2026 rhs.pos_=-1;
2027 }
2031 col_=rhs.col_;
2032 pos_=rhs.pos_;
2033 return *this;
2034 }
2036 col_=rhs.col_;
2037 pos_=rhs.pos_;
2038 rhs.col_=nullptr;
2039 rhs.pos_=-1;
2040 return *this;
2041 }
2042 inline self_type operator++(int /*junk*/) {
2043 self_type i = *this;
2044 if (!isValid()) pos_++;
2045 return i;
2046 }
2048 if (!isValid()) return self_type(col_);
2049 pos_++; return *this;
2050 }
2051 inline self_type operator--(int /*junk*/) {
2052 self_type i = *this;
2053 if (isValid()) {
2054 pos_--;
2055 } else {
2057 pos_=static_cast<int>(col_->getRows())-1;
2058 }
2059 return i;
2060 }
2062 if (isValid()) {
2063 pos_--;
2064 } else {
2066 pos_=static_cast<int>(col_->getRows())-1;
2067 }
2068 return *this;
2069 }
2070 inline self_type operator+=(int inc) {
2071 if (isValid()) {
2072 pos_+=inc;
2073 } else if (inc<0) {
2075 pos_=static_cast<int>(col_->getRows())+inc;
2076 }
2077 return *this;
2078 }
2079 inline self_type operator-=(int dec) {
2080 if (isValid()) {
2081 pos_-=dec;
2082 } else {
2084 pos_=static_cast<int>(col_->getRows())-dec;
2085 }
2086
2087 return *this;
2088 }
2089
2090 friend self_type operator+(difference_type off, const self_type& right) {
2091 if (right.isValid()) {
2092 return self_type(right.col_, off + right.pos_);
2093 } else {
2094 if (off<0) return self_type(right.col_, off + static_cast<int>(right.col_->getRows()));
2095 else return self_type(right.col_);
2096 }
2097 }
2098 friend self_type operator-(difference_type off, const self_type& right) {
2099 if (right.isValid()) {
2100 return self_type(right.col_, off - right.pos_);
2101 } else {
2102 return self_type(right.col_);
2103 }
2104 }
2106 if (isValid()) {
2107 return self_type(col_, pos_+rhs);
2108 } else if (rhs<0){
2110 return self_type(col_, static_cast<int>(col_->getRows())+rhs);
2111 } else {
2112 return self_type(col_);
2113 }
2114 }
2116 if (isValid()) {
2117 return self_type(col_, pos_-rhs);
2118 } else {
2120 return self_type(col_, static_cast<int>(col_->getRows())-rhs);
2121 }
2122 }
2124 if (!isValid() && !rhs.isValid()) return 0;
2125 if (!isValid() && rhs.isValid() && col_==rhs.col_) return static_cast<difference_type>(col_->getRows())-rhs.pos_;
2126 if (isValid() && !rhs.isValid() && col_==rhs.col_) return pos_-static_cast<difference_type>(col_->getRows());
2127 JKQTPASSERT(isValid() );
2128 JKQTPASSERT( rhs.isValid() );
2129 JKQTPASSERT( col_==rhs.col_);
2130 return pos_-rhs.pos_;
2131 }
2132
2133 /** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
2135 JKQTPASSERT(col_!=nullptr );
2136 JKQTPASSERT( pos_>=0 );
2137 JKQTPASSERT( pos_<static_cast<int>(col_->getRows()));
2138 return col_->at(pos_);
2139 }
2141 {
2142 if (!isValid() && off<0) {
2143 JKQTPASSERT(col_!=nullptr);
2144 return col_->at(static_cast<int>(col_->getRows())+off);
2145 }
2146 JKQTPASSERT(col_!=nullptr );
2147 JKQTPASSERT( pos_+off>=0 );
2148 JKQTPASSERT( pos_+off<static_cast<int>(col_->getRows()));
2149 return col_->at(pos_+off);
2150 }
2151 /** \brief dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the value does not exist in the column */
2153 JKQTPASSERT(col_!=nullptr );
2154 JKQTPASSERT( pos_>=0 );
2155 JKQTPASSERT( pos_<static_cast<int>(col_->getRows()));
2156 return col_->at(pos_);
2157 }
2158 /** \brief comparison operator (less than)
2159 *
2160 * rules:
2161 * - ivalid iterators are never smaller than valid operators
2162 * - two valid operator must reference the same column
2163 * - a valid operator is smaller than another, if it points to a pos_ before another
2164 * .
2165 *
2166 * \see operator<=(), operator>(), operator>=()
2167 * */
2168 inline bool operator<(const self_type& rhs) const {
2169 if (!isValid() && !rhs.isValid()) return false;
2170 else if (!isValid() && rhs.isValid()) {
2171 return false;
2172 } else if (isValid() && !rhs.isValid()) {
2173 return true;
2174 } else {
2175 JKQTPASSERT(col_ == rhs.col_);
2176 return pos_<rhs.pos_;
2177 }
2178 }
2179 /** \brief comparison operator (less than, or equal)
2180 * \see operator==(), operator<(), operator>(), operator>=()
2181 * */
2182 inline bool operator<=(const self_type& rhs) const {
2183 return operator==(rhs) || operator<(rhs);
2184 }
2185 /** \brief comparison operator (larger than)
2186 *
2187 * rules:
2188 * - ivalid iterators are always larger than valid operators
2189 * - two valid operator must reference the same column
2190 * - a valid operator is smaller than another, if it points to a pos_ before another
2191 * .
2192 *
2193 * \see operator<=(), operator<(), operator>=()
2194 * */
2195 inline bool operator>(const self_type& rhs) const {
2196 if (!isValid() && !rhs.isValid()) return false;
2197 else if (!isValid() && rhs.isValid()) {
2198 return true;
2199 } else if (isValid() && !rhs.isValid()) {
2200 return false;
2201 } else {
2202 JKQTPASSERT(col_ == rhs.col_);
2203 return pos_>rhs.pos_;
2204 }
2205 }
2206 /** \brief comparison operator (larger than, or equal)
2207 * \see operator==(), operator<(), operator>(), operator<=()
2208 * */
2209 inline bool operator>=(const self_type& rhs) const {
2210 return operator==(rhs) || operator>(rhs);
2211 }
2212 /** \brief comparison operator (equals)
2213 *
2214 * two iterators are equal, if:
2215 * - they are both invalid (see isValid() )
2216 * - they point to the same column and are both invalid (isValid()) or equal to end()
2217 * - they point to the same column and the same row therein
2218 * .
2219 *
2220 * \see operator!=()
2221 * */
2222 inline bool operator==(const self_type& rhs) const {
2223 if (!isValid() && !rhs.isValid()) return true;
2224 if (col_ == rhs.col_) {
2225 if ((pos_<0 || pos_>=static_cast<int>(rhs.col_->getRows())) && (pos_<0 || rhs.pos_>=static_cast<int>(rhs.col_->getRows()))) return true;
2226 return pos_==rhs.pos_;
2227 }
2228 return false;
2229 }
2230 /** \brief comparison operator (unequals), inverse result of operator==()
2231 *
2232 * \see operator==()
2233 * */
2234 inline bool operator!=(const self_type& rhs) const { return !this->operator==(rhs); }
2235
2236 /** \brief checks the iterator for validity (i.e. points to an existing column and position is in a valid range) */
2237 inline bool isValid() const {
2238 return col_ && pos_>=0 && pos_<static_cast<int>(col_->getRows());
2239 }
2240 /** \copydoc isValid() */
2241 inline operator bool() const { return isValid(); }
2242 /** \brief returns the referenced position/row, or -1 for an invalid iterator */
2243 inline int getPosition() const {
2244 if (!isValid()) return -1;
2245 return pos_;
2246 }
2247 /** \brief returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid operator */
2248 inline QPoint getImagePosition() const {
2249 if (!isValid()) return QPoint(-1,-1);
2250 return QPoint(pos_ % static_cast<int>(col_->getImageColumns()), pos_ / static_cast<int>(col_->getImageColumns()));
2251 }
2252 /** \brief returns the referenced position/row interpreted as an image pixel, x-component, returns -1 for an invalid operator */
2253 inline int getImagePositionX() const {
2254 if (!isValid()) return -1;
2255 return pos_ % static_cast<int>(col_->getImageColumns());
2256 }
2257 /** \brief returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an invalid operator */
2258 inline int getImagePositionY() const {
2259 if (!isValid()) return -1;
2260 return pos_ / static_cast<int>(col_->getImageColumns());
2261 }
2262 /*! \brief if the data in the column is interpreted as an image, this is the number of columns (x-dimension) of the image
2263 \see JKQTPColumn::imageColumns */
2264 inline size_t getImageColumns () const {
2265 if (!isValid()) return 0;
2266 return col_->getImageColumns();
2267 }
2268 /*! \brief if the data in the column is interpreted as an image, this is the number of rows (y-dimension) of the image
2269 \see JKQTPColumn::imageColumns */
2270 inline size_t getImageRows () const {
2271 if (!isValid()) return 0;
2272 return col_->getRows() / col_->getImageColumns();
2273 }
2274
2275 friend class JKQTPColumn;
2276 friend class JKQTPDatastore;
2277 protected:
2278 /** \brief returns the referenced column */
2279 inline const JKQTPColumn* getColumn() const { return col_; }
2280};
2281
2282
2283/** \brief this represents one chunk of memory which can represent one or more columns of data for JKQTBasePlotter.
2284 * See JKQTPDatastore for more information.
2285 * \ingroup jkqtpdatastorage_classes
2286 *
2287 * Each chunk of memory is pointed at by a simple double* pointer \c data. the memory layout of the memory layout of
2288 * the RAM segment pointed at by \c data is determined by the parameter \c dataformat:
2289 * \copydoc JKQTPDatastoreItemFormat
2290 *
2291 * The properties \c columns and \c rows determine how many columns and rows are represented by this item (access via
2292 * getColumns() and getRows() ). This class may manage chunks of "internal" and "external" memory (which is indicated by
2293 * the boolean property \c internal. Internal memory will be allocated (in the constructor) and freed (in the destructor) by this
2294 * object. External memory may be accessed via this class, but will neither by allocated nor freed. These tasks are up to the
2295 * user. Use this option, if you don't want to generate copies of huge datasets, or you want to change the data while the program
2296 * is running and don't want to do the change at more than one spot.
2297 *
2298 * you can use get() and set() to access the memory chunc.
2299 *
2300 * \see JKQTPDatastore
2301 */
2303 private:
2304 /** \brief how data is represented in this JKQTPDatastoreItem */
2305 enum class StorageType {
2306 Internal, /*!< \brief data is stored in an internally managed (=owned, i.e. freed in the destructor) C-array */
2307 External, /*!< \brief data is stored in an externally managed (=not owned) C-array */
2308 Vector /*!< \brief data is stored in the internal \a QVector<double> datavec */
2309 };
2310 /** \brief a pointer to the actual data */
2311 double* data;
2312 /** \brief as data may also point to a matrix, this specifies the number of columns in this element (default: 1) */
2313 size_t columns;
2314 /** \brief number of rows in this item */
2315 size_t rows;
2316 /** \brief iif \a storageType is \c StorageType::Vector, the data is actually save here and data contains a pointer to the data in datavec */
2317 QVector<double> datavec;
2318 /** \brief memory format of the data in this item */
2320 /** \brief specifies whether the datastore manages the memory (\c true ) or whether the user application does this (\c false ) .*/
2322 /** \brief Specifies whether memory for the data has been allocated. This is only used, when \c internal==true. */
2324 protected:
2325 /** \brief hidden default constructor */
2327
2328 public:
2329 /** \brief class constructor: initializes the object for internal data storage */
2330 JKQTPDatastoreItem(size_t columns, size_t rows);
2331 /** \brief class constructor: initializes the object for internal data storage with the given data */
2332 JKQTPDatastoreItem(const QVector<double> &data);
2333 /** \brief class constructor: initializes the object for external data storage */
2334 JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows);
2335 /** \brief class constructor: initializes the object for external data storage */
2336 JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double* data, size_t columns, size_t rows, bool storageType);
2337 /** \brief class destructor: frees unfreed internal memory */
2339
2340 /** \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!) */
2341 bool resizeColumns(size_t rows);
2342
2343 /** \copydoc JKQTPDatastoreItem::rows */
2344 inline size_t getRows() const
2345 { return rows; }
2346 /** \copydoc JKQTPDatastoreItem::columns */
2347 inline size_t getColumns() const
2348 { return columns; }
2349
2350 /** \brief checks whether dataformat==JKQTPDatastoreItemFormat::SingleColumn and storageType==StorageType::Vector */
2351 inline bool isVector() const {
2352 return dataformat==JKQTPDatastoreItemFormat::SingleColumn && storageType==StorageType::Vector;
2353 }
2354
2355 /** \brief if \c isValid() : resize the row to have \a rows_new rows */
2356 inline void resize(size_t rows_new) {
2357 JKQTPASSERT(isVector());
2358 datavec.resize(static_cast<int>(rows_new));
2359 rows=static_cast<size_t>(datavec.size());
2360 data=datavec.data();
2361 }
2362
2363 /** \brief if \c isValid() : erase the row \a row */
2364 inline void erase(size_t row) {
2365 JKQTPASSERT(isVector());
2366 datavec.erase(datavec.begin()+row, datavec.end());
2367 rows=static_cast<size_t>(datavec.size());
2368 data=datavec.data();
2369 }
2370 /** \brief if \c isValid() : erase all rows (and including) from \a row to \a rowEnd */
2371 inline void erase(size_t row, size_t rowEnd) {
2372 if (row>rowEnd) erase(rowEnd, row);
2373 else if (row==rowEnd) erase(row);
2374 else {
2375 JKQTPASSERT(isVector());
2376 if (rowEnd>=static_cast<size_t>(datavec.size())) datavec.erase(datavec.begin()+row, datavec.end());
2377 else datavec.erase(datavec.begin()+row, datavec.begin()+rowEnd);
2378 rows=static_cast<size_t>(datavec.size());
2379 data=datavec.data();
2380 }
2381 }
2382 /** \brief returns the data at the position (\a column, \a row ).
2383 *
2384 * \note The column index specifies the column inside THIS item, not the global column number. */
2385 inline double get(size_t column, size_t row) {
2386 if (data!=nullptr) switch(dataformat) {
2388 return data[row];
2390 return data[column*rows+row];
2392 return data[row*columns+column];
2393 }
2394 return 0;
2395 }
2396
2397
2398 /** \brief returns a reference to the data at the position (\a column, \a row ). Throws an exception when the entry does not exist!
2399 *
2400 * \note The column index specifies the column inside THIS item, not the global column number. */
2401 inline double& at(size_t column, size_t row) {
2402 if (data!=nullptr) {
2403 switch(dataformat) {
2405 return data[row];
2407 return data[column*rows+row];
2409 return data[row*columns+column];
2410 }
2411 }
2412 throw std::out_of_range("index does not exist in JKQTPDatastoreItem");
2413 }
2414
2415 /** \brief returns a const reference to the data at the position (\a column, \a row ). Throws an exception when the entry does not exist!
2416 *
2417 * \note The column index specifies the column inside THIS item, not the global column number. */
2418 inline const double& at(size_t column, size_t row) const {
2419 if (data!=nullptr) {
2420 switch(dataformat) {
2422 return data[row];
2424 return data[column*rows+row];
2426 return data[row*columns+column];
2427 }
2428 }
2429 throw std::out_of_range("index does not exist in JKQTPDatastoreItem");
2430 }
2431
2432
2433 /** \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. */
2434 inline double* getPointer(size_t column, size_t row) {
2435 if (data!=nullptr) switch(dataformat) {
2437 return &(data[row]);
2439 return &(data[column*rows+row]);
2441 return &(data[row*columns+column]);
2442 }
2443 return nullptr;
2444 }
2445
2446 /** \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. */
2447 inline const double* getPointer(size_t column, size_t row) const {
2448 if (data!=nullptr) switch(dataformat) {
2450 return &(data[row]);
2452 return &(data[column*rows+row]);
2454 return &(data[row*columns+column]);
2455 }
2456 return nullptr;
2457 }
2458 /** \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. */
2459 inline void set(size_t column, size_t row, double value) {
2460 if (data!=nullptr) switch(dataformat) {
2462 data[row]=value;
2463 return;
2465 data[column*rows+row]=value;
2466 return;
2468 data[row*columns+column]=value;
2469 return;
2470 }
2471 }
2472
2473 /** \brief adds a new row to the given column. Returns \c true on success and \c false else
2474 *
2475 * This operation is currently only possible, if \c storageType==StorageType::Vector ! */
2476 inline bool push_back(size_t column, double value) {
2477 if (storageType==StorageType::Vector && dataformat==JKQTPDatastoreItemFormat::SingleColumn && column==0) {
2478 datavec.push_back(value);
2479 rows=static_cast<size_t>(datavec.size());
2480 data=datavec.data();
2481 return true;
2482 }
2483 return false;
2484 }
2485
2486 /** \brief adds a new row to the given column. Returns \c true on success and \c false else
2487 *
2488 * This operation is currently only possible, if \c storageType==StorageType::Vector ! */
2489 inline bool append(size_t column, double value) {
2490 return push_back(column, value);
2491 }
2492 /** \brief adds new rows to the given column. Returns \c true on success and \c false else
2493 *
2494 * This operation is currently only possible, if \c storageType==StorageType::Vector ! */
2495 inline bool append(size_t column, const QVector<double>& values) {
2496 if (storageType==StorageType::Vector && dataformat==JKQTPDatastoreItemFormat::SingleColumn && column==0) {
2497 datavec.reserve(datavec.size()+values.size());
2498 for (const double& d: values) datavec.push_back(d);
2499 data=datavec.data();
2500 rows=static_cast<size_t>(datavec.size());
2501 return true;
2502 }
2503 return false;
2504 }
2505 /** \brief adds new rows to the given column. Returns \c true on success and \c false else
2506 *
2507 * This operation is currently only possible, if \c storageType==StorageType::Vector ! */
2508 inline bool append(size_t column, const std::vector<double>& values) {
2509 if (storageType==StorageType::Vector && dataformat==JKQTPDatastoreItemFormat::SingleColumn && column==0) {
2510 datavec.reserve(static_cast<int>(datavec.size())+static_cast<int>(values.size()));
2511 for (const double& d: values) datavec.push_back(d);
2512 data=datavec.data();
2513 rows=static_cast<size_t>(datavec.size());
2514 return true;
2515 }
2516 return false;
2517 }
2518};
2519#pragma pack(pop)
2520
2521
2522/** \brief QAbstractTableModel descendent that allows to view data in a JKQTPDatastore
2523 * \ingroup jkqtpdatastorage_classes
2524 *
2525 * \see JKQTPDatastore
2526 */
2527class JKQTPLOTTER_LIB_EXPORT JKQTPDatastoreModel: public QAbstractTableModel {
2528 Q_OBJECT
2529 public:
2530 JKQTPDatastoreModel(JKQTPDatastore* datastore, QObject* parent=nullptr);
2531 virtual ~JKQTPDatastoreModel() override;
2532
2533
2534 virtual QVariant data(const QModelIndex &index, int role) const override;
2535 virtual Qt::ItemFlags flags(const QModelIndex &index) const override;
2536 virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override;
2537 virtual int rowCount(const QModelIndex &parent = QModelIndex()) const override;
2538 virtual int columnCount(const QModelIndex &parent = QModelIndex()) const override;
2539
2540 public Q_SLOTS:
2542
2543 protected:
2545
2546};
2547
2548
2549
2550
2551
2552////////////////////////////////////////////////////////////////////////////////////////////////
2553inline void JKQTPColumn::setValue(size_t n, double val){
2554 if (!datastore) return ;
2555 if (!datastore->getItem(datastoreItem)) return ;
2557}
2558
2559////////////////////////////////////////////////////////////////////////////////////////////////
2560inline void JKQTPColumn::incValue(size_t n, double increment){
2561 if (!datastore) return ;
2562 if (!datastore->getItem(datastoreItem)) return ;
2564}
2565
2566////////////////////////////////////////////////////////////////////////////////////////////////
2568{
2569 if (!datastore) return 0;
2570 if (!datastore->getItem(datastoreItem)) return 0;
2571 return jkqtp_checksum(reinterpret_cast<const char*>(getPointer(0)), static_cast<uint>(getRows()*sizeof(double)));
2572}
2573
2574////////////////////////////////////////////////////////////////////////////////////////////////
2578
2579////////////////////////////////////////////////////////////////////////////////////////////////
2583
2584////////////////////////////////////////////////////////////////////////////////////////////////
2588
2589////////////////////////////////////////////////////////////////////////////////////////////////
2593
2594////////////////////////////////////////////////////////////////////////////////////////////////
2595void JKQTPColumn::erase(size_t row) {
2597}
2598
2599////////////////////////////////////////////////////////////////////////////////////////////////
2600void JKQTPColumn::erase(size_t row, size_t rowEnd) {
2601 datastore->getItem(datastoreItem)->erase(row, rowEnd);
2602}
2603
2604
2605////////////////////////////////////////////////////////////////////////////////////////////////
2606inline double JKQTPColumn::getValue(size_t n) const {
2607 if (!datastore) return JKQTP_NAN;
2610}
2611
2612////////////////////////////////////////////////////////////////////////////////////////////////
2613inline double JKQTPColumn::getValue(int n) const {
2614 if (!datastore) return JKQTP_NAN;
2616 if (n<0) return JKQTP_NAN;
2617 return datastore->getItem(datastoreItem)->get(datastoreOffset, static_cast<size_t>(n));
2618}
2619
2620////////////////////////////////////////////////////////////////////////////////////////////////
2621inline const double& JKQTPColumn::at(int n) const {
2624 JKQTPASSERT(n>=0);
2625 return datastore->getItem(datastoreItem)->at(datastoreOffset, static_cast<size_t>(n));
2626}
2627
2628////////////////////////////////////////////////////////////////////////////////////////////////
2629inline double& JKQTPColumn::at(int n) {
2632 JKQTPASSERT(n>=0);
2633 return datastore->getItem(datastoreItem)->at(datastoreOffset, static_cast<size_t>(n));
2634}
2635
2636
2637////////////////////////////////////////////////////////////////////////////////////////////////
2638size_t JKQTPDatastore::getRows(size_t column) const {
2639 return columns.value(column).getRows();
2640}
2641
2642////////////////////////////////////////////////////////////////////////////////////////////////
2643const double *JKQTPDatastore::getColumnPointer(int column, size_t row) const
2644{
2645 if (column<0) return nullptr;
2646 return columns.value(static_cast<size_t>(column)).getPointer(row);
2647}
2648
2649////////////////////////////////////////////////////////////////////////////////////////////////
2650double *JKQTPDatastore::getColumnPointer(int column, size_t row)
2651{
2652 if (column<0) return nullptr;
2653 return columns[static_cast<size_t>(column)].getPointer(row);
2654}
2655
2656////////////////////////////////////////////////////////////////////////////////////////////////
2657size_t JKQTPDatastore::getRows(int column) const {
2658 if (column<0) return 0;
2659 return columns.value(static_cast<size_t>(column)).getRows();
2660}
2661
2662////////////////////////////////////////////////////////////////////////////////////////////////
2663const double *JKQTPDatastore::getColumnPointer(size_t column, size_t row) const
2664{
2665 return columns.value(column).getPointer(row);
2666}
2667
2668////////////////////////////////////////////////////////////////////////////////////////////////
2669double *JKQTPDatastore::getColumnPointer(size_t column, size_t row)
2670{
2671 return columns[column].getPointer(row);
2672}
2673
2674////////////////////////////////////////////////////////////////////////////////////////////////
2675inline double JKQTPDatastore::get(size_t column, size_t row) const {
2676 return columns[column].getValue(row);
2677}
2678
2679////////////////////////////////////////////////////////////////////////////////////////////////
2680inline double JKQTPDatastore::get(int column, size_t row) const {
2681 if (column<0) return JKQTP_NAN;
2682 return get(static_cast<size_t>(column), static_cast<size_t>(row));
2683}
2684
2685////////////////////////////////////////////////////////////////////////////////////////////////
2686inline double JKQTPDatastore::get(int column, int row) const {
2687 if (column<0) return JKQTP_NAN;
2688 if (row<0) return JKQTP_NAN;
2689 return get(static_cast<size_t>(column), static_cast<size_t>(row));
2690}
2691
2692
2693////////////////////////////////////////////////////////////////////////////////////////////////
2694inline double JKQTPDatastore::get(size_t column, int row) const {
2695 if (row<0) return JKQTP_NAN;
2696 return get(static_cast<size_t>(column), static_cast<size_t>(row));
2697}
2698
2699////////////////////////////////////////////////////////////////////////////////////////////////
2700inline void JKQTPDatastore::set(size_t column, size_t row, double value) {
2701 columns[column].setValue(row, value);
2702}
2703
2704////////////////////////////////////////////////////////////////////////////////////////////////
2705inline void JKQTPDatastore::set(int column, size_t row, double value) {
2706 set(static_cast<size_t>(column), static_cast<size_t>(row), value);
2707}
2708
2709
2710////////////////////////////////////////////////////////////////////////////////////////////////
2711template<class TContainer>
2712void JKQTPDatastore::appendFromContainerToColumn(size_t column, const TContainer &values)
2713{
2714 appendToColumn(column, values.begin(), values.end());
2715}
2716
2717////////////////////////////////////////////////////////////////////////////////////////////////
2718template<class TIterator>
2719inline void JKQTPDatastore::appendToColumn(size_t column, TIterator first, TIterator last)
2720{
2721 for(auto it=first; it!=last; it++) {
2722 appendToColumn(column, *it);
2723 }
2724}
2725
2726////////////////////////////////////////////////////////////////////////////////////////////////
2728 if (pos.isValid()) {
2729 bool ok=pos.getColumn()->getDatastoreItem()->isVector();
2730 auto itc=columns.key(*pos.getColumn());
2731 if (!ok) {
2732 QVector<double> old_data;
2733 for (auto it=pos.getColumn()->begin(); it!=pos; ++it) old_data.push_back(*it);
2734
2735
2736 size_t itemID=addItem(new JKQTPDatastoreItem(old_data));
2737 columns[itc].replaceMemory(itemID, 0);
2738 } else {
2739 columns[itc].erase(static_cast<size_t>(pos.getPosition()));
2740 }
2741 }
2742}
2743
2744////////////////////////////////////////////////////////////////////////////////////////////////
2746 if (pos.isValid()) {
2747 bool ok=pos.getColumn()->getDatastoreItem()->isVector();
2748 auto itc=columns.key(*pos.getColumn());
2749 if (!ok) {
2750 QVector<double> old_data;
2751 for (auto it=pos.getColumn()->begin(); it!=pos; ++it) old_data.push_back(*it);
2752
2753
2754 size_t itemID=addItem(new JKQTPDatastoreItem(old_data));
2755 columns[itc].replaceMemory(itemID, 0);
2756 } else {
2757 columns[itc].erase(static_cast<size_t>(pos.getPosition()));
2758 }
2759 }
2760}
2761
2762////////////////////////////////////////////////////////////////////////////////////////////////
2764 if (pos.isValid()) {
2765 bool ok=pos.getColumn()->getDatastoreItem()->isVector();
2766 auto itc=columns.key(*pos.getColumn());
2767 if (!ok) {
2768 QVector<double> old_data;
2769 for (auto it=pos.getColumn()->begin(); it!=pos.getColumn()->end(); ++it) old_data.push_back(*it);
2770 size_t itemID=addItem(new JKQTPDatastoreItem(old_data));
2771 columns[itc].replaceMemory(itemID, 0);
2772 }
2773 if (posEnd.isValid()) columns[itc].erase(static_cast<size_t>(pos.getPosition()), static_cast<size_t>(posEnd.getPosition()));
2774 else columns[itc].erase(static_cast<size_t>(pos.getPosition()), static_cast<size_t>(pos.getPosition())+columns[itc].getRows()+1);
2775 }
2776}
2777
2778////////////////////////////////////////////////////////////////////////////////////////////////
2780 if (pos.isValid()) {
2781 bool ok=pos.getColumn()->getDatastoreItem()->isVector();
2782 auto itc=columns.key(*pos.getColumn());
2783 if (!ok) {
2784 QVector<double> old_data;
2785 for (auto it=pos.getColumn()->begin(); it!=pos.getColumn()->end(); ++it) old_data.push_back(*it);
2786 size_t itemID=addItem(new JKQTPDatastoreItem(old_data));
2787 columns[itc].replaceMemory(itemID, 0);
2788 }
2789 if (posEnd.isValid()) columns[itc].erase(static_cast<size_t>(pos.getPosition()), static_cast<size_t>(posEnd.getPosition()));
2790 else columns[itc].erase(static_cast<size_t>(pos.getPosition()), static_cast<size_t>(pos.getPosition())+columns[itc].getRows()+1);
2791 }
2792}
2793
2794////////////////////////////////////////////////////////////////////////////////////////////////
2795inline double JKQTPDatastore::getPixel(size_t column, size_t x, size_t y) const {
2796 return columns.value(column).getPixelValue(x, y);
2797}
2798
2799////////////////////////////////////////////////////////////////////////////////////////////////
2800inline void JKQTPDatastore::setPixel(size_t column, size_t x, size_t y, double value) {
2801 return columns[column].setPixelValue(x, y, value);
2802}
2803
2804////////////////////////////////////////////////////////////////////////////////////////////////
2805void JKQTPDatastore::setAll(size_t column, double value)
2806{
2807 columns[column].setAll(value);
2808}
2809
2810////////////////////////////////////////////////////////////////////////////////////////////////
2811void JKQTPDatastore::scaleColumnValues(size_t column, double factor)
2812{
2813 columns[column].scale(factor);
2814}
2815
2816////////////////////////////////////////////////////////////////////////////////////////////////
2817void JKQTPDatastore::inc(size_t column, size_t row, double increment)
2818{
2819 columns[column].incValue(row, increment);
2820}
2821
2822////////////////////////////////////////////////////////////////////////////////////////////////
2823void JKQTPDatastore::dec(size_t column, size_t row, double decrement)
2824{
2825 columns[column].decValue(row, decrement);
2826}
2827
2828
2829////////////////////////////////////////////////////////////////////////////////////////////////
2830template <typename T>
2831inline size_t JKQTPDatastore::addCopiedImageAsColumn(const T* data, size_t width, size_t height, const QString& name, size_t stride, size_t start){
2832 size_t col=addCopiedColumn<T>(data, width*height, stride, start, name);
2833 columns[col].setImageColumns(width);
2834 return col;
2835}
2836
2837////////////////////////////////////////////////////////////////////////////////////////////////
2838template <typename TContainer>
2839inline size_t JKQTPDatastore::addCopiedImageAsColumn(const TContainer& data, size_t width, const QString& name){
2840 size_t col= addCopiedColumn<TContainer>(data, name);
2841 columns[col].setImageColumns(width);
2842 return col;
2843}
2844
2845
2846////////////////////////////////////////////////////////////////////////////////////////////////
2847template <typename T>
2848size_t JKQTPDatastore::addCopiedImageAsColumnTranspose(const T* data, size_t width, size_t height, const QString& name, size_t stride, size_t start){
2849 double* temp=static_cast<double*>(malloc(width*height*sizeof(double)));
2850
2851 for (size_t x=0; x<width; x++) {
2852 for (size_t y=0; y<height; y++) {
2853 temp[x*height+y]=jkqtp_todouble<T>(data[start+(y*width+x)*stride]);
2854 }
2855
2856 }
2857
2858 size_t idx=addInternalColumn(temp, width*height, name);
2859 columns[idx].setImageColumns(height);
2860 return idx;
2861}
2862
2863
2864////////////////////////////////////////////////////////////////////////////////////////////////
2865template <typename T>
2866inline size_t JKQTPDatastore::addCopiedImageAsColumnTranspose(const QVector<T>& data, size_t width, const QString& name) {
2867 return addCopiedImageAsColumnTranspose<T>(data.data(), width, static_cast<size_t>(data.size())/width, name);
2868}
2869
2870#endif // JKQTPDATASTORAGE_H
iterator, which allows to insert into a column of a JKQTPDatastore
Definition jkqtpdatastorage.h:1954
JKQTPColumnBackInserter & operator=(JKQTPColumnBackInserter &&)=default
JKQTPColumnBackInserter(JKQTPDatastore *ds, size_t col)
constructs an iterator for the data represented by col, starting with row startpos
Definition jkqtpdatastorage.h:1962
JKQTPColumnBackInserter & operator=(double &&val)
Definition jkqtpdatastorage.h:1982
double * pointer
Definition jkqtpdatastorage.h:1968
int difference_type
Definition jkqtpdatastorage.h:1970
JKQTPColumnBackInserter & operator=(const JKQTPColumnBackInserter &)=default
double value_type
Definition jkqtpdatastorage.h:1965
const double & const_reference
Definition jkqtpdatastorage.h:1967
std::output_iterator_tag iterator_category
Definition jkqtpdatastorage.h:1969
JKQTPDatastore * ds_
references the datastore to access
Definition jkqtpdatastorage.h:1957
self_type operator++()
Definition jkqtpdatastorage.h:1988
JKQTPColumnBackInserter(const JKQTPColumnBackInserter &)=default
JKQTPColumnBackInserter(JKQTPColumnBackInserter &&)=default
double & reference
Definition jkqtpdatastorage.h:1966
size_t col_
references the column to access
Definition jkqtpdatastorage.h:1959
JKQTPColumnBackInserter self_type
Definition jkqtpdatastorage.h:1964
JKQTPColumnBackInserter & operator=(const double &val)
Definition jkqtpdatastorage.h:1977
self_type operator*()
Definition jkqtpdatastorage.h:1989
JKQTPColumnBackInserter()
constructs an invalid iterator
Definition jkqtpdatastorage.h:1972
self_type operator++(int)
Definition jkqtpdatastorage.h:1987
iterator over the data in the column of a JKQTPDatastore
Definition jkqtpdatastorage.h:2000
difference_type operator-(self_type rhs) const
Definition jkqtpdatastorage.h:2123
const_reference operator*() const
dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the val...
Definition jkqtpdatastorage.h:2152
reference operator*()
dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the val...
Definition jkqtpdatastorage.h:2134
JKQTPColumnConstIterator(const JKQTPColumnConstIterator &)=default
friend self_type operator-(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:2098
bool operator<(const self_type &rhs) const
comparison operator (less than)
Definition jkqtpdatastorage.h:2168
bool operator>=(const self_type &rhs) const
comparison operator (larger than, or equal)
Definition jkqtpdatastorage.h:2209
const double & reference
Definition jkqtpdatastorage.h:2012
bool operator>(const self_type &rhs) const
comparison operator (larger than)
Definition jkqtpdatastorage.h:2195
JKQTPColumnConstIterator & operator=(const JKQTPColumnConstIterator &)=default
bool operator<=(const self_type &rhs) const
comparison operator (less than, or equal)
Definition jkqtpdatastorage.h:2182
bool isValid() const
checks the iterator for validity (i.e. points to an existing column and position is in a valid range)
Definition jkqtpdatastorage.h:2237
self_type operator+=(int inc)
Definition jkqtpdatastorage.h:2070
self_type operator++(int)
Definition jkqtpdatastorage.h:2042
friend self_type operator+(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:2090
self_type operator++()
Definition jkqtpdatastorage.h:2047
bool operator!=(const self_type &rhs) const
comparison operator (unequals), inverse result of operator==()
Definition jkqtpdatastorage.h:2234
self_type operator+(difference_type rhs) const
Definition jkqtpdatastorage.h:2105
JKQTPColumnConstIterator & operator=(const JKQTPColumnIterator &rhs)
Definition jkqtpdatastorage.h:2030
JKQTPColumnConstIterator & operator=(JKQTPColumnIterator &&rhs)
Definition jkqtpdatastorage.h:2035
const double * pointer
Definition jkqtpdatastorage.h:2014
self_type operator-(difference_type rhs) const
Definition jkqtpdatastorage.h:2115
JKQTPColumnConstIterator & operator=(JKQTPColumnConstIterator &&)=default
double value_type
Definition jkqtpdatastorage.h:2011
JKQTPColumnConstIterator(JKQTPColumnIterator &&rhs)
Definition jkqtpdatastorage.h:2022
size_t getImageColumns() const
if the data in the column is interpreted as an image, this is the number of columns (x-dimension) of ...
Definition jkqtpdatastorage.h:2264
int getImagePositionY() const
returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an inv...
Definition jkqtpdatastorage.h:2258
int difference_type
Definition jkqtpdatastorage.h:2016
JKQTPColumnConstIterator(JKQTPColumnConstIterator &&)=default
int getImagePositionX() const
returns the referenced position/row interpreted as an image pixel, x-component, returns -1 for an inv...
Definition jkqtpdatastorage.h:2253
QPoint getImagePosition() const
returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid ope...
Definition jkqtpdatastorage.h:2248
int pos_
current row in col_ this iterator points to
Definition jkqtpdatastorage.h:2005
self_type operator--(int)
Definition jkqtpdatastorage.h:2051
self_type operator-=(int dec)
Definition jkqtpdatastorage.h:2079
bool operator==(const self_type &rhs) const
comparison operator (equals)
Definition jkqtpdatastorage.h:2222
reference const_reference
Definition jkqtpdatastorage.h:2013
int getPosition() const
returns the referenced position/row, or -1 for an invalid iterator
Definition jkqtpdatastorage.h:2243
const JKQTPColumn * col_
references the column this iterator iterates over
Definition jkqtpdatastorage.h:2003
JKQTPColumnConstIterator(const JKQTPColumn *col, int startpos=0)
constructs an iterator for the data represented by col, starting with row startpos
Definition jkqtpdatastorage.h:2008
std::forward_iterator_tag iterator_category
Definition jkqtpdatastorage.h:2015
const JKQTPColumn * getColumn() const
returns the referenced column
Definition jkqtpdatastorage.h:2279
self_type operator--()
Definition jkqtpdatastorage.h:2061
reference operator[](difference_type off) const
Definition jkqtpdatastorage.h:2140
size_t getImageRows() const
if the data in the column is interpreted as an image, this is the number of rows (y-dimension) of the...
Definition jkqtpdatastorage.h:2270
JKQTPColumnConstIterator(const JKQTPColumnIterator &rhs)
Definition jkqtpdatastorage.h:2021
JKQTPColumnConstIterator()
constructs an invalid iterator
Definition jkqtpdatastorage.h:2018
JKQTPColumnConstIterator self_type
Definition jkqtpdatastorage.h:2010
internally stores information about one data column. See JKQTPDatastore for more information.
Definition jkqtpdatastorage.h:1478
void setName(const QString &__value)
a name describing the column
size_t datastoreOffset
offset, if the datastore item contains more than one column
Definition jkqtpdatastorage.h:1483
JKQTPDatastore * datastore
pointer to the datastore object used to manage the data of the plot
Definition jkqtpdatastorage.h:1487
JKQTPColumnConstIterator const_iterator
Definition jkqtpdatastorage.h:1494
size_t getRows() const
returns the number of rows in this column (accesses the datastore)
bool isValid() const
Definition jkqtpdatastorage.h:1505
size_t getDatastoreItemNum() const
index of the item in the datastore that contains the data for this column
Definition jkqtpdatastorage.h:1641
size_t getImageColumns() const
number of columns, if interpreted as a row-major image
Definition jkqtpdatastorage.h:1523
quint16 calculateChecksum() const
calculates a checksum over the contents of the column (using qChecksum())
Definition jkqtpdatastorage.h:2567
void replaceMemory(size_t datastoreItem_=0, size_t datastoreOffset_=0)
Definition jkqtpdatastorage.h:1669
void setValue(size_t n, double val)
sets the n'th value from the column
Definition jkqtpdatastorage.h:2553
void setAll(double value)
set all values in the column to a specific value
size_t datastoreItem
index of the item in the datastore that contains the data for this column
Definition jkqtpdatastorage.h:1481
void copyData(QVector< double > &copyTo) const
copies the contained data into a QVector
const JKQTPDatastoreItem * getDatastoreItem() const
returns a pointer to the datastore item representing this column
Definition jkqtpdatastorage.h:1617
void scale(double factor)
scales all members of the column with the given factor
double getValue(size_t n) const
reads the n'th value from the column
Definition jkqtpdatastorage.h:2606
const JKQTPDatastore * getDatastore() const
Definition jkqtpdatastorage.h:1668
JKQTPDatastoreItem * getDatastoreItem()
returns a pointer to the datastore item representing this column
Definition jkqtpdatastorage.h:1615
JKQTPDatastore * getDatastore()
Definition jkqtpdatastorage.h:1667
double * getPointer(size_t n=0)
gets a pointer to the n-th value in the column
JKQTPColumnIterator iterator
Definition jkqtpdatastorage.h:1493
void setImageColumns(size_t imageWidth)
number of columns, if interpreted as a row-major image
const double * getPointer(size_t n=0) const
gets a pointer to the n-th value in the column
void incValue(size_t n, double increment=1.0)
increment the n'th value from the column
Definition jkqtpdatastorage.h:2560
bool valid
is this item valid?/usable?
Definition jkqtpdatastorage.h:1491
iterator begin()
returns an iterator to the internal data
Definition jkqtpdatastorage.h:2575
void erase(size_t row)
removes the entry row
Definition jkqtpdatastorage.h:2595
bool operator==(const JKQTPColumn &other) const
two columns are equal, if the same memory in the same datastore is referenced
Definition jkqtpdatastorage.h:1508
void copy(const double *data, size_t N, size_t offset=0)
copy data from the given array into the column
QString name
a name describing the column
Definition jkqtpdatastorage.h:1489
double & at(int n)
returns a reference to the n -th row in this column (possibly throwing an exception if it does not ex...
Definition jkqtpdatastorage.h:2629
iterator end()
returns an iterator to the internal data
Definition jkqtpdatastorage.h:2580
double getPixelValue(size_t x, size_t y) const
returns the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matr...
Definition jkqtpdatastorage.h:1610
void exchange(double value, double replace)
exchange every occurence of a given value by a replace value
void setPixelValue(size_t x, size_t y, double val)
sets the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matrix ...
Definition jkqtpdatastorage.h:1601
void subtract(double value)
subtracts a given value from all members of the column
JKQTPColumn(JKQTPDatastore *datastore, const QString &name=QString(""), size_t datastoreItem=0, size_t datastoreOffset=0, size_t imageColumns=1)
class constructor that binds the column to a specific datastore object.
QVector< double > copyData()
returns a QVector with the contained data (as a copy)
QString getName() const
a name describing the column
void setPixelValue(size_t x, size_t y, size_t width, double val)
sets the element at (x,y) in the column, where the data is interpreted as a row-major ordered Matrix ...
Definition jkqtpdatastorage.h:1591
size_t imageColumns
number of columns, if interpreted as a row-major image
Definition jkqtpdatastorage.h:1485
size_t getDatastoreOffset() const
offset, if the datastore item contains more than one column
Definition jkqtpdatastorage.h:1644
void decValue(size_t n, double decrement=1.0)
decrement the n'th value from the column
Definition jkqtpdatastorage.h:1581
iterator over the data in the column of a JKQTPDatastore
Definition jkqtpdatastorage.h:1686
size_t getImageRows() const
if the data in the column is interpreted as an image, this is the number of rows (y-dimension) of the...
Definition jkqtpdatastorage.h:1930
friend self_type operator-(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:1765
const JKQTPColumn * getColumn() const
returns the referenced column
Definition jkqtpdatastorage.h:1941
self_type operator++()
Definition jkqtpdatastorage.h:1714
self_type operator++(int)
Definition jkqtpdatastorage.h:1709
bool isValid() const
checks the iterator for validity (i.e. points to an existing column and position is in a valid range)
Definition jkqtpdatastorage.h:1897
bool operator>=(const self_type &rhs) const
comparison operator (larger than, or equal)
Definition jkqtpdatastorage.h:1888
bool operator!=(const self_type &rhs) const
comparison operator (unequals), inverse result of operator==()
Definition jkqtpdatastorage.h:1895
bool operator==(const self_type &rhs) const
comparison operator (equals)
Definition jkqtpdatastorage.h:1829
int difference_type
Definition jkqtpdatastorage.h:1702
bool operator<(const self_type &rhs) const
comparison operator (less than)
Definition jkqtpdatastorage.h:1847
JKQTPColumnIterator self_type
Definition jkqtpdatastorage.h:1696
JKQTPColumnIterator(const JKQTPColumnIterator &)=default
int getImagePositionX() const
returns the referenced position/row interpreted as an image pixel, x-component, returns -1 for an inv...
Definition jkqtpdatastorage.h:1913
self_type operator--(int)
Definition jkqtpdatastorage.h:1718
JKQTPColumnIterator(JKQTPColumn *col, int startpos=0)
constructs an iterator for the data represented by col, starting with row startpos
Definition jkqtpdatastorage.h:1694
self_type operator-=(int dec)
Definition jkqtpdatastorage.h:1746
self_type operator+(difference_type rhs) const
Definition jkqtpdatastorage.h:1772
friend self_type operator+(difference_type off, const self_type &right)
Definition jkqtpdatastorage.h:1757
JKQTPColumnIterator(JKQTPColumnIterator &&)=default
reference operator*() const
dereferences the iterator, throws an exception if the iterator is invalid (see isValid() ) or the val...
Definition jkqtpdatastorage.h:1801
double * pointer
Definition jkqtpdatastorage.h:1700
self_type operator-(difference_type rhs) const
Definition jkqtpdatastorage.h:1782
JKQTPColumn * col_
references the column this iterator iterates over
Definition jkqtpdatastorage.h:1689
QPoint getImagePosition() const
returns the referenced position/row interpreted as an image pixel, returns (-1,-1) for an invalid ope...
Definition jkqtpdatastorage.h:1908
int pos_
current row in col_ this iterator points to
Definition jkqtpdatastorage.h:1691
reference operator[](difference_type off) const
dereferences the iterator at offset off, throws an exception if the iterator is invalid (see isValid(...
Definition jkqtpdatastorage.h:1808
difference_type operator-(self_type rhs) const
Definition jkqtpdatastorage.h:1790
self_type operator+=(int inc)
Definition jkqtpdatastorage.h:1737
bool operator>(const self_type &rhs) const
comparison operator (larger than)
Definition jkqtpdatastorage.h:1874
JKQTPColumn * getColumn()
returns the referenced column
Definition jkqtpdatastorage.h:1939
JKQTPColumnIterator & operator=(JKQTPColumnIterator &&)=default
std::forward_iterator_tag iterator_category
Definition jkqtpdatastorage.h:1701
double & reference
Definition jkqtpdatastorage.h:1698
self_type operator--()
Definition jkqtpdatastorage.h:1728
double value_type
Definition jkqtpdatastorage.h:1697
JKQTPColumnIterator()
constructs an invalid iterator
Definition jkqtpdatastorage.h:1704
size_t getImageColumns() const
if the data in the column is interpreted as an image, this is the number of columns (x-dimension) of ...
Definition jkqtpdatastorage.h:1924
bool operator<=(const self_type &rhs) const
comparison operator (less than, or equal)
Definition jkqtpdatastorage.h:1861
int getImagePositionY() const
returns the referenced position/row interpreted as an image pixel, y-component, returns -1 for an inv...
Definition jkqtpdatastorage.h:1918
const double & const_reference
Definition jkqtpdatastorage.h:1699
JKQTPColumnIterator & operator=(const JKQTPColumnIterator &)=default
int getPosition() const
returns the referenced position/row, or -1 for an invalid iterator
Definition jkqtpdatastorage.h:1903
This class manages data columns (with entries of type double ), used by JKQTPlotter/JKQTBasePlotter t...
Definition jkqtpdatastorage.h:282
size_t maxItemID
internal variable to keep track about the highest item ID (in items) used so far
Definition jkqtpdatastorage.h:298
size_t addCalculatedImageColumn(size_t cols, size_t rows, const std::function< double(size_t, size_t)> &f, const QString &name=QString(""))
add an image column with width cols and height rows (i.e. rows * cols entries), that is calculated by...
JKQTPDatastore()
class constructor, generates an empty datastore
QList< size_t > getColumnIDs() const
returns a list with all available column IDs
Definition jkqtpdatastorage.h:1360
friend class JKQTPDatastoreItem
Definition jkqtpdatastorage.h:1464
QMap< size_t, JKQTPColumn >::const_iterator ConstColumnIterator
constant iterator for columns in the JKQTPDatastore (ColumnIterator::first: column number,...
Definition jkqtpdatastorage.h:360
void appendFromContainerToColumn(size_t column, const TContainer &values)
adds a values in container values to the column column. This changes the column length (number of row...
Definition jkqtpdatastorage.h:2712
QString getColumnName(size_t column)
return the title of the first column with the given name, or -1 if none was found
size_t getRows(size_t column) const
returns the number of rows in the column column
Definition jkqtpdatastorage.h:2638
const JKQTPDatastoreItem * getItem(size_t i) const
returns the JKQTPDatastoreItem object for the i -th item in the store
Definition jkqtpdatastorage.h:347
QMap< size_t, JKQTPColumn >::iterator ColumnIterator
mutable iterator for columns in the JKQTPDatastore (ColumnIterator::first: column number,...
Definition jkqtpdatastorage.h:358
size_t addImageColumn(double *data, size_t width, size_t height, const QString &name=QString(""))
add one external column to the datastore. It contains width * height rows. This returns its logical c...
int getNextLowerIndex(size_t column, size_t row, int start, int end) const
gets the index of the datapoint with the nearest, but lower value in the column (in a given inclusive...
void saveSYLK(const QString &filename, const QSet< int > &userColumns=QSet< int >(), const QString &floatformat=QString("%10.10lf")) const
save contents of datastore as SYLK file (SYmbolic LinK)
const double * getColumnPointer(size_t column, size_t row=0) const
returns a pointer to the data in column column, starting ar row row
Definition jkqtpdatastorage.h:2663
std::pair< size_t, size_t > addCopiedPoints(const std::list< QPoint > &points, const QString &namex=QString(""), const QString &namey=QString(""))
QMap< size_t, JKQTPDatastoreItem * > items
a std::vector that contains all items managed by this datastore
Definition jkqtpdatastorage.h:285
int ensureColumnNum(const QString &name)
return the num of the first column with the given name, if none was found this creates a new column w...
JKQTPColumnBackInserter backInserter(int i)
returns a back-inserter iterator (JKQTPColumnBackInserter) to the i -th column in the JKQTPDatastore
int getNextLowerIndex(size_t column, size_t row) const
gets the index of the datapoint with the nearest, but lower value in the column
size_t addItem(size_t columns, size_t rows)
add a new item with rows rows and columns columns to the datastore and return its ID....
size_t addColumn(double *data, size_t rows, const QString &name=QString(""))
add one external column to the datastore. It contains rows rows. This returns its logical column ID....
size_t addInternalItem(double *data, size_t rows)
add one internal column to the datastore. It contains rows rows. This function retuns an item ID (whi...
size_t addCopiedColumnMasked(const TContainer &data, const TContainerMask &mask, const QString &name=QString(""), bool useIfMaskEquals=false)
add one external column to the datastore. It will be filled with the contents of vector data.
Definition jkqtpdatastorage.h:1150
JKQTPColumnConstIterator end(int i) const
returns a const iterator behind the last data entry data in the i -th column in the JKQTPDatastore
JKQTPColumnConstIterator begin(int i) const
returns a const iterator to the first data entry in the i -th column in the JKQTPDatastore
void deleteAllColumns(const QString &name, bool removeItems=true)
delete all columns with the given name, if no other columns points to the datastore item of the colum...
void setColumnData(size_t toColumn, const QVector< double > &data)
copies the data from data into an existing column toColumn
void saveDIF(const QString &filename, const QSet< int > &userColumns=QSet< int >(), const QString &floatformat=QString("%10.10lf")) const
save contents of datastore as DIF file (data interchange format)
void appendToColumn(size_t column, double value)
adds a value value to the column column. This changes the column length (number of rows).
size_t addImageColumn(size_t width, size_t height, const QString &name=QString(""))
add a new columns with width * height rows to the datastore and return its column ID....
size_t addCopiedColumn(TIterator first, TIterator last, const QString &name=QString(""))
add one column to the datastore. It will be filled with the values from first ... last
Definition jkqtpdatastorage.h:871
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
save contents of datastore as Comma Separated Values (CSV) file
JKQTPColumnIterator begin(size_t i)
returns an iterator to the first data entry in the i -th column in the JKQTPDatastore
void set(size_t column, size_t row, double value)
sets the value at position (column, row). column is the logical column and will be mapped to the acco...
Definition jkqtpdatastorage.h:2700
JKQTPColumnBackInserter backInserter(size_t i)
returns a back-inserter iterator (JKQTPColumnBackInserter) to the i -th column in the JKQTPDatastore
void dec(size_t column, size_t row, double decrement=1)
decrements entry in row row of column column by decrement
Definition jkqtpdatastorage.h:2823
~JKQTPDatastore()
class destructor, destroys all subordered JKQTPDatastoreItem objects
size_t addCopiedColumn(const T *data, size_t rows, size_t stride, const QString &name)
copy an external column to the datastore. It contains rows rows. The external data is copied to an in...
Definition jkqtpdatastorage.h:1041
std::pair< size_t, size_t > addCopiedPoints(const std::list< QPointF > &points, const QString &namex=QString(""), const QString &namey=QString(""))
size_t addCopiedImageAsColumnTranspose(const T *data, size_t width, size_t height, const QString &name=QString(""), size_t stride=1, size_t start=0)
add a new column to the datastore, which is filled from the transposed column-major array data with t...
Definition jkqtpdatastorage.h:2848
size_t addCopiedItem(JKQTPDatastoreItemFormat dataformat, double *data, size_t columns, size_t rows)
add one external data block to the datastore. It contains rows rows and columns columns....
void saveMatlab(QTextStream &txt, const QSet< int > &userColumns=QSet< int >()) const
save contents of datastore as a Matlab script
size_t maxColumnsID
internal variable to keep track about the highest column ID (in columns) used so far
Definition jkqtpdatastorage.h:303
size_t getColumnCount() const
returns the number of (logical) columns currently managed by the datastore
Definition jkqtpdatastorage.h:1357
size_t addItem(JKQTPDatastoreItem *item)
add a new item to the datastore and return its ID This function retuns an item ID (which can be used ...
void setColumnCopiedImageData(size_t toColumn, const double *data, size_t width, size_t height)
copies the image data from data into an existing column toColumn
double getPixel(size_t column, size_t x, size_t y) const
returns the value at position (x, y) in the column-th column, which is interpreted with the imageWidt...
Definition jkqtpdatastorage.h:2795
size_t addCopiedColumn(const T *data, size_t rows, size_t stride, int start, const QString &name)
copy an external column to the datastore. It contains rows rows. The external data is copied to an in...
Definition jkqtpdatastorage.h:1004
bool hasColumn(size_t i) const
determines whether a column with the given ID exists
size_t addCopiedImageAsColumn(const T *data, size_t width, size_t height, const QString &name=QString(""), size_t stride=1, size_t start=0)
add one external column to the datastore. It contains width * height rows. The external data is assum...
Definition jkqtpdatastorage.h:2831
size_t addLinearColumn(size_t rows, double start, double end, const QString &name=QString(""))
add a column to the datastore that contains rows rows with monotonely increasing value starting at st...
size_t addCopiedColumnMasked(const T *data, const bool *mask, size_t rows, const QString &name=QString(""), bool useIfMaskEquals=false)
add one external column to the datastore. It contains rows rows. The external data is copied to an in...
Definition jkqtpdatastorage.h:1111
std::pair< size_t, size_t > addCopiedPoints(const QList< QPoint > &points, const QString &namex=QString(""), const QString &namey=QString(""))
size_t addInternalColumn(double *data, size_t rows, const QString &name)
add a column with rows entries from the array data, ownership of the memory behind data is transfered...
size_t addColumnCalculatedFromColumn(size_t otherColumn, const std::function< double(double)> &f, const QString &name=QString(""))
Definition jkqtpdatastorage.h:1333
void resizeColumn(size_t column, size_t new_rows)
resizes the column column to have new_rows rows
void inc(size_t column, size_t row, double increment=1)
increases entry in row row of column column by increment
Definition jkqtpdatastorage.h:2817
QVector< double > getData(size_t column, QString *columnName=nullptr) const
return contents of a given column as QVector<double>
size_t addCopiedColumn(const T *data, size_t rows, const QString &name=QString(""))
copy an external column to the datastore. It contains rows rows. The external data is copied to an in...
Definition jkqtpdatastorage.h:967
ColumnIterator begin()
returns an iterator to the first column in the JKQTPDatastore
size_t addColumnForItem(size_t itemID, size_t columnInItem, const QString &name=QString(""))
add a new columns which references a specified item and a specified column therein.
int getNextHigherIndex(int column, size_t row, int start, int end) const
gets the index of the datapoint with the nearest, but higher value in the column (in a given inclusiv...
JKQTPColumnConstIterator begin(size_t i) const
returns a const iterator to the first data entry in the i -th column in the JKQTPDatastore
size_t addItem(double *data, size_t rows)
add one external column to the datastore. It contains rows rows. This function retuns an item ID (whi...
std::pair< size_t, size_t > addCopiedMap(TIterator first, TIterator last, const QString &nameKey=QString("map_key"), const QString &nameValue=QString("map_value"))
copies the contents of the map-like container c into two columns of the datastore,...
Definition jkqtpdatastorage.h:1196
size_t addDecadeLogColumn(size_t rows, double startDecade, double endDecade, const QString &name=QString(""))
add a column to the datastore that contains rows rows with monotonely increasing value starting at 10...
void scaleColumnValues(size_t column, double factor)
scales (multiplies) all entries in column column by factor
Definition jkqtpdatastorage.h:2811
size_t getColumnImageHeight(int column) const
returns the height of the image, represented by column (in row-major ordering)
size_t getMaxRows() const
returns the maximum number of rows in all columns
size_t addCalculatedColumnFromColumn(const std::pair< size_t, size_t > &otherColumn, const std::function< double(double, double)> &f, const QString &name=QString(""))
Definition jkqtpdatastorage.h:1352
JKQTPColumnIterator end(int i)
returns an iterator behind the last data entry data in the i -th column in the JKQTPDatastore
size_t addCalculatedColumn(size_t rows, const std::function< double(size_t, JKQTPDatastore *)> &f, const QString &name=QString(""))
add a column with rows entries, that is calculated by calling f for each entry
size_t addItem(JKQTPDatastoreItemFormat dataformat, double *data, size_t columns, size_t rows)
add an external memory block to the datastore. It contains rows rows and columns columns....
void deleteAllPrefixedColumns(QString prefix, bool removeItems=true)
delete all columns where the name starts with a given prefix, if no other columns points to the datas...
void clear()
deletes all items from the datastore and possibly frees the memory they manage
JKQTPColumnIterator begin(int i)
returns an iterator to the first data entry in the i -th column in the JKQTPDatastore
int getNextHigherIndex(size_t column, size_t row) const
gets the index of the datapoint with the nearest, but higher value in the column
QList< QVector< double > > getData(QStringList *columnNames=nullptr, const QSet< int > &userColumns=QSet< int >()) const
return contents of datastore as QList<QVector<double> >, i.e. a list of column-vectors
QStringList getColumnNames() const
return a list with all columns available in the datastore
int getNextLowerIndex(int column, size_t row) const
gets the index of the datapoint with the nearest, but lower value in the column
size_t addColumn(size_t rows, const QString &name=QString(""))
add a new columns with rows rows to the datastore and return its column ID. The new item uses interna...
QVector< int > getColumnIDsIntVec() const
returns a list with all available column IDs
JKQTPDatastoreItem * getItem(size_t i)
returns the JKQTPDatastoreItem object for the i -th item in the store
Definition jkqtpdatastorage.h:342
std::pair< size_t, size_t > addCopiedPoints(const std::vector< QPointF > &points, const QString &namex=QString(""), const QString &namey=QString(""))
void appendToColumns(size_t columnX, size_t columnY, const QPoint &value)
adds a the x-coordinate of value to the column columnX and the y-coordinate to columnY.
JKQTPColumnIterator end(size_t i)
returns an iterator behind the last data entry data in the i -th column in the JKQTPDatastore
void deleteColumn(size_t column, bool removeItems=true)
delete the given column, if no other columns points to the datastore item of the column and removeIte...
size_t addCopiedItem(const double *data, size_t rows)
add one external column to the datastore. It contains rows rows. The data is copied and the copy mana...
std::pair< size_t, size_t > addCopiedPoints(const std::vector< QPoint > &points, const QString &namex=QString(""), const QString &namey=QString(""))
std::pair< size_t, size_t > addLinearGridColumns(size_t width, double startX, double endX, size_t height, double startY, double endY, const QString &nameX=QString(""), const QString &nameY=QString(""))
add two columns to the datastore that contains the x- and y- coordinates of a rectangular grid with w...
void resizeImageColumn(size_t column, size_t new_image_width, size_t new_image_height)
resizes the column column to have enough rows to be interpreted as an image of size new_image_width *...
size_t addCalculatedColumn(size_t rows, const std::function< double(size_t)> &f, const QString &name=QString(""))
add a column with rows entries, that is calculated by calling f for each entry
QMap< size_t, JKQTPColumn > columns
a std::vector of all columns that may be used to access the managed chunks of memory.
Definition jkqtpdatastorage.h:287
void appendToColumns(size_t column1, size_t column2, size_t column3, size_t column4, double value1, double value2, double value3, double value4)
adds a value value1 to the column column1, a value value2 to column2, etc.
ColumnIterator end()
returns an iterator behind the last column in the JKQTPDatastore
void appendToColumns(size_t column1, size_t column2, size_t column3, double value1, double value2, double value3)
adds a value value1 to the column column1, a value value2 to column2, etc.
int getNextLowerIndex(int column, size_t row, int start, int end) const
gets the index of the datapoint with the nearest, but lower value in the column (in a given inclusive...
void eraseFromColumn(const JKQTPColumnIterator &pos)
removes the entry pos
Definition jkqtpdatastorage.h:2727
void setColumnCopiedData(size_t toColumn, const double *data, size_t N)
copies the data from data into an existing column toColumn
void setAll(size_t column, double value)
sets all entries in column column to value
Definition jkqtpdatastorage.h:2805
void appendToColumns(size_t column1, size_t column2, size_t column3, size_t column4, size_t column5, double value1, double value2, double value3, double value4, double value5)
adds a value value1 to the column column1, a value value2 to column2, etc.
std::unique_ptr< JKQTPColumn > m_invalidColumn
an internal invalid column object, used e.g. to return invalid column iterators
Definition jkqtpdatastorage.h:292
size_t addCopiedColumn(const TContainer &data, const QString &name, size_t stride, size_t start=0)
add one external column to the datastore. It will be filled with the contents of vector data.
Definition jkqtpdatastorage.h:936
JKQTPColumnConstIterator end(size_t i) const
returns a const iterator behind the last data entry data in the i -th column in the JKQTPDatastore
size_t getColumnImageWidth(int column) const
returns the width of the image, represented by column (in row-major ordering). Internally this return...
size_t addItem(size_t rows)
add a new columns/item with rows rows to the datastore and return its ID. The item uses internal memo...
void setPixel(size_t column, size_t x, size_t y, double value)
returns the value at position (x, y) in the column-th column, which is interpreted with the imageWidt...
Definition jkqtpdatastorage.h:2800
size_t addColumnCalculatedFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function< double(double, double)> &f, const QString &name=QString(""))
Definition jkqtpdatastorage.h:1349
std::pair< size_t, size_t > addCopiedMap(const TContainer &c, const QString &nameKey=QString("map_key"), const QString &nameValue=QString("map_value"))
copies the contents of the map-like container c into two columns of the datastore,...
Definition jkqtpdatastorage.h:1235
void copyColumnData(size_t toColumn, size_t fromColumn)
copies the data from fromColumn into an existing column toColumn
size_t addInternalImageColumn(double *data, size_t width, size_t height, const QString &name)
add a column with width * height entries from the array data, ownership of the memory behind data is ...
ConstColumnIterator end() const
returns a const iterator behind the last column in the JKQTPDatastore
size_t addCalculatedColumnFromColumn(size_t otherColumnX, size_t otherColumnY, const std::function< double(double, double)> &f, const QString &name=QString(""))
add a column with the same number of entries, as in the other column otherColumn ,...
size_t addColumn(JKQTPColumn col)
add a new column to the datastore and return its ID
void setColumnImageWidth(size_t column, size_t imageWidth)
sets the width of the image, represented by column (in row-major ordering) to imageWidth
void saveMatlab(const QString &filename, const QSet< int > &userColumns=QSet< int >()) const
save contents of datastore as a Matlab script
size_t copyColumn(size_t old_column, const QString &name=QString(""))
copies the given old_column into a new one
void appendToColumns(size_t column1, size_t column2, double value1, double value2)
adds a value value1 to the column column1 and a value value2 to column2.
size_t addCalculatedColumnFromColumn(size_t otherColumn, const std::function< double(double)> &f, const QString &name=QString(""))
add a column with the same number of entries, as in the other column otherColumn ,...
void appendToColumns(size_t columnX, size_t columnY, const QPointF &value)
adds a the x-coordinate of value to the column columnX and the y-coordinate to columnY.
quint16 getColumnChecksum(int column) const
returns the data checksum of the given column
void setColumnImageHeight(size_t column, size_t imageHeight)
sets the height of the image, represented by column (in row-major ordering) to imageHeight
int getNextHigherIndex(size_t column, size_t row, int start, int end) const
gets the index of the datapoint with the nearest, but higher value in the column (in a given inclusiv...
size_t addColumn(const QString &name=QString(""))
add a new and empty column to the datastore and return its column ID. The new item uses internal memo...
int getColumnNum(const QString &name)
return the num of the first column with the given name, or -1 if none was found
std::pair< size_t, size_t > addCopiedPoints(const QList< QPointF > &points, const QString &namex=QString(""), const QString &namey=QString(""))
add two columns to the datastore. They will be filled with the values from points (first column: x-va...
ConstColumnIterator begin() const
returns a const iterator to the first column in the JKQTPDatastore
double get(size_t column, size_t row) const
returns the value at position (column, row). column is the logical column and will be mapped to the a...
Definition jkqtpdatastorage.h:2675
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
save contents of datastore as Comma Separated Values (CSV) file
size_t copyColumn(size_t old_column, size_t start, size_t stride, const QString &name=QString(""))
copies the given old_column into a new one, reading the data with the given start column and stride
size_t addCopiedColumn(const TContainer &data, const QString &name=QString(""))
add one external column to the datastore. It will be filled with the contents of vector data.
Definition jkqtpdatastorage.h:909
int getNextHigherIndex(int column, size_t row) const
gets the index of the datapoint with the nearest, but higher value in the column
size_t addLogColumn(size_t rows, double start, double end, const QString &name=QString(""))
add a column to the datastore that contains rows rows with monotonely increasing value starting at st...
this represents one chunk of memory which can represent one or more columns of data for JKQTBasePlott...
Definition jkqtpdatastorage.h:2302
JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double *data, size_t columns, size_t rows, bool storageType)
class constructor: initializes the object for external data storage
bool isVector() const
checks whether dataformat==JKQTPDatastoreItemFormat::SingleColumn and storageType==StorageType::Vecto...
Definition jkqtpdatastorage.h:2351
double get(size_t column, size_t row)
returns the data at the position (column, row ).
Definition jkqtpdatastorage.h:2385
JKQTPDatastoreItemFormat dataformat
memory format of the data in this item
Definition jkqtpdatastorage.h:2319
bool push_back(size_t column, double value)
adds a new row to the given column. Returns true on success and false else
Definition jkqtpdatastorage.h:2476
size_t columns
as data may also point to a matrix, this specifies the number of columns in this element (default: 1)
Definition jkqtpdatastorage.h:2313
void set(size_t column, size_t row, double value)
set the data at the position (column, row ) to value. The column index specifies the column inside TH...
Definition jkqtpdatastorage.h:2459
double * data
a pointer to the actual data
Definition jkqtpdatastorage.h:2311
QVector< double > datavec
iif storageType is StorageType::Vector, the data is actually save here and data contains a pointer to...
Definition jkqtpdatastorage.h:2317
const double & at(size_t column, size_t row) const
returns a const reference to the data at the position (column, row ). Throws an exception when the en...
Definition jkqtpdatastorage.h:2418
JKQTPDatastoreItem(JKQTPDatastoreItemFormat dataformat, double *data, size_t columns, size_t rows)
class constructor: initializes the object for external data storage
void erase(size_t row, size_t rowEnd)
if isValid() : erase all rows (and including) from row to rowEnd
Definition jkqtpdatastorage.h:2371
StorageType storageType
specifies whether the datastore manages the memory (true ) or whether the user application does this ...
Definition jkqtpdatastorage.h:2321
~JKQTPDatastoreItem()
class destructor: frees unfreed internal memory
size_t getRows() const
number of rows in this item
Definition jkqtpdatastorage.h:2344
bool append(size_t column, const std::vector< double > &values)
adds new rows to the given column. Returns true on success and false else
Definition jkqtpdatastorage.h:2508
bool append(size_t column, double value)
adds a new row to the given column. Returns true on success and false else
Definition jkqtpdatastorage.h:2489
void erase(size_t row)
if isValid() : erase the row row
Definition jkqtpdatastorage.h:2364
bool resizeColumns(size_t rows)
change the size of all columns to the givne number of rows. Returns true if the old data could be ret...
bool append(size_t column, const QVector< double > &values)
adds new rows to the given column. Returns true on success and false else
Definition jkqtpdatastorage.h:2495
size_t rows
number of rows in this item
Definition jkqtpdatastorage.h:2315
bool allocated
Specifies whether memory for the data has been allocated. This is only used, when internal==true.
Definition jkqtpdatastorage.h:2323
size_t getColumns() const
as data may also point to a matrix, this specifies the number of columns in this element (default: 1)
Definition jkqtpdatastorage.h:2347
void resize(size_t rows_new)
if isValid() : resize the row to have rows_new rows
Definition jkqtpdatastorage.h:2356
double * getPointer(size_t column, size_t row)
returns the data at the position (column, row ). The column index specifies the column inside THIS it...
Definition jkqtpdatastorage.h:2434
StorageType
how data is represented in this JKQTPDatastoreItem
Definition jkqtpdatastorage.h:2305
double & at(size_t column, size_t row)
returns a reference to the data at the position (column, row ). Throws an exception when the entry do...
Definition jkqtpdatastorage.h:2401
JKQTPDatastoreItem(const QVector< double > &data)
class constructor: initializes the object for internal data storage with the given data
JKQTPDatastoreItem(size_t columns, size_t rows)
class constructor: initializes the object for internal data storage
const double * getPointer(size_t column, size_t row) const
returns the data at the position (column, row ). The column index specifies the column inside THIS it...
Definition jkqtpdatastorage.h:2447
JKQTPDatastoreItem()
hidden default constructor
QAbstractTableModel descendent that allows to view data in a JKQTPDatastore.
Definition jkqtpdatastorage.h:2527
virtual Qt::ItemFlags flags(const QModelIndex &index) const override
JKQTPDatastore * datastore
Definition jkqtpdatastorage.h:2544
virtual int columnCount(const QModelIndex &parent=QModelIndex()) const override
JKQTPDatastoreModel(JKQTPDatastore *datastore, QObject *parent=nullptr)
virtual QVariant headerData(int section, Qt::Orientation orientation, int role=Qt::DisplayRole) const override
virtual QVariant data(const QModelIndex &index, int role) const override
virtual int rowCount(const QModelIndex &parent=QModelIndex()) const override
virtual ~JKQTPDatastoreModel() override
JKQTPDatastoreItemFormat
the types of data in one JKQTdatastoreItem
Definition jkqtpdatastorage.h:82
@ SingleColumn
a 1D C-array of doubles. (default option)
@ MatrixColumn
a 1D C-array of doubles that represents a number of columns. The data is store column after column (=...
@ MatrixRow
a 1D C-array of doubles that represents a number of rows (C standard representation of matrices)....
#define JKQTPLOTTER_LIB_EXPORT
Definition jkqtplotter_imexport.h:89
#define JKQTPASSERT(condition)
dynamic assertion, throws an exception with the given message, when the given condition condition eva...
Definition jkqtpdebuggingtools.h:77
JKQTCOMMON_LIB_EXPORT quint16 jkqtp_checksum(const void *data, size_t len)
convert a QString (created by jkqtp_MouseButton2String() ) to Qt::MouseButton
#define JKQTP_NAN
double-value NotANumber
Definition jkqtpmathtools.h:87
constexpr double jkqtp_todouble(const T &d)
converts a boolean to a double, is used to convert boolean to double by JKQTPDatastore
Definition jkqtpmathtools.h:113