Compare commits

...

199 Commits

Author SHA1 Message Date
06b4c4f870 fix README section about python install 2025-03-09 22:01:43 +01:00
a2f61f7405 comply with PEP 625: adjust README.md 2025-02-12 23:36:40 +01:00
bb10d80489 comply with PEP 625: lower case distribution filenames; bump version 2.1.18 2025-02-12 23:18:49 +01:00
1eea219361 github actions: matrix os ubuntu, win; bump version 2.1.17 2025-02-12 22:57:58 +01:00
400b6eaab9 github actions: separate strategy matrix os; bump version 2.1.16 2025-02-12 22:34:01 +01:00
6f4511e1c2 github actions: remove macos; bump version 2.1.15 2025-02-12 13:53:55 +01:00
fe042b531f github actions: use os latest + macos; bump version 2.1.14 2025-02-12 13:46:58 +01:00
9d5f0cff01 bump version 2.1.13; reuse and extract various text fields, take care of backslash in text w.r.t. to python dict 2025-02-12 01:04:51 +01:00
720acd3b62 github actions: fix Upload binary wheels PyPI 2025-02-03 21:11:21 +01:00
8ca6ee3ddc github actions: fix Upload binary wheels PyPI 2025-02-03 20:56:17 +01:00
379feaa85a github actions: fix Upload binary wheels PyPI 2025-02-02 00:53:16 +01:00
cff2e913fc github actions: fix Upload binary wheels PyPI 2025-02-02 00:47:13 +01:00
75d70a9521 * github actions: fix Unable to download artifact(s): Artifact not found for name: binary-wheels
* README.md: structure and sort references
* bump v2.1.8
2025-02-02 00:30:56 +01:00
mario-fink
36cf0c9c18
Merge pull request #32 from jgoedeke/master
Bugfix trigger-time with XY Datasets
2025-01-25 01:15:19 +01:00
jgoedeke
2326725756 bugfix: set xprec to 9 for XY datasets 2025-01-23 15:07:12 +00:00
jgoedeke
59de48424e Fix absolute_trigger_time for XY datasets and remove addtime from output
Add-time is already implicitly provided by the difference between `trigger-time-nt` and `trigger-time` for normal datasets. For XY datasets the `addtime` parameter is not applicable.
2025-01-23 14:18:08 +00:00
jgoedeke
a44461cba6 Fix wrong keys in runtime errors 2025-01-23 14:15:52 +00:00
cee146593b github actions: fix Unable to download artifact(s): Artifact not found for name: binary-wheels 2025-01-22 19:58:58 +01:00
223f25b6e0 github actions: fix Failed to CreateArtifact: Received non-retryable error: Failed request: (409) 2025-01-22 00:40:24 +01:00
8ec02d21c5 github actions: fix Failed to CreateArtifact: Received non-retryable error: Failed request: (409) 2025-01-22 00:20:57 +01:00
df445bfd7f github actions: update runner-images 2025-01-22 00:04:49 +01:00
af6622492a deprecated version of actions/upload-artifact, upgrade to v4 2025-01-21 00:40:05 +01:00
ef67e14ee7 update samples 2025-01-21 00:34:10 +01:00
Mario Fink
1500943cc4
Merge pull request #29 from RecordEvolution/dependabot/github_actions/dot-github/workflows/actions/download-artifact-4.1.7
Bump actions/download-artifact from 2 to 4.1.7 in /.github/workflows
2025-01-21 00:23:00 +01:00
Mario Fink
be282a8aae
Merge pull request #31 from jgoedeke/master
Add multi component parsing to support XY-datasets
2025-01-20 20:22:12 +01:00
jgoedeke
71121834d5
Add factor and offset transformation for both components and parse common NT and CD keys properly 2024-11-05 12:17:08 +01:00
jgoedeke
0a17b87452
Add multi component parsing to support XY-datasets 2024-11-05 10:47:36 +01:00
dependabot[bot]
9ea7186090
Bump actions/download-artifact from 2 to 4.1.7 in /.github/workflows
Bumps [actions/download-artifact](https://github.com/actions/download-artifact) from 2 to 4.1.7.
- [Release notes](https://github.com/actions/download-artifact/releases)
- [Commits](https://github.com/actions/download-artifact/compare/v2...v4.1.7)

---
updated-dependencies:
- dependency-name: actions/download-artifact
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-09-03 22:06:04 +00:00
befda072e5 include origin comment of NO block 2024-06-12 20:53:59 +02:00
0b1cb2f230 reference correct name of data file format in README.md (issue #14) and add link to imc documentation 2024-06-12 20:32:01 +02:00
ce444814c2 reference correct name of data file format in README.md (issue #14) and add link to imc documentation 2024-06-12 20:31:08 +02:00
eec3853af9 by default use utf-8 for metadata including non-ascii characters while missing codepage info 2024-06-12 12:02:26 +02:00
25e114dbea Fix Github Workflow Badge:
* https://github.com/badges/shields/issues/8733
* https://docs.github.com/en/actions/monitoring-and-troubleshooting-workflows/adding-a-workflow-status-badge
2024-06-12 11:50:35 +02:00
740116c7ba bump version 2.0.20 2024-06-12 11:23:12 +02:00
5899bd646b bump version 2.0.19 2024-06-12 10:39:22 +02:00
1d33a81ad2 bump version 2.0.18 2024-06-12 10:37:54 +02:00
b58efae107 bump version 2.0.17 2024-06-12 10:33:51 +02:00
cc0dd9978f update and fix badges 2024-06-12 10:22:53 +02:00
4834f63a67 update and fix badges 2024-06-12 10:16:56 +02:00
1be78a2c5e Revert "update and fix badges"
This reverts commit f5581557bca14d8e6c200e8b3b57661a18a957cc.
2024-06-12 10:15:23 +02:00
f5581557bc update and fix badges 2024-06-12 10:14:51 +02:00
8cde88848b update and fix badges 2024-06-12 10:08:33 +02:00
0799513ea2 by default use codepage1252 for metadata including non-ascii characters while missing codepage info 2024-06-12 09:45:30 +02:00
effeee105c win32: replace timegm by _mkgmtime, bump version 2.0.15 2023-08-08 23:46:10 +02:00
ed5b366341 imc_channel.hpp: usage of iconv for unix only, bump version 2.0.15 2023-08-08 23:29:48 +02:00
9a520ddd9c bump version 2.0.14 2023-08-08 00:54:07 +02:00
2c43087d15 bump version 2.0.13 2023-08-08 00:52:27 +02:00
60ac1365a5 * imc_channel.hpp: usage of iconv for unix only
* IMCtermite.pyx: add codepage conversion for windows
* bump VERSION
2023-08-08 00:50:52 +02:00
57027e234e fix workflow pypi-deploy.yml for installing libiconv 2023-08-07 23:03:51 +02:00
887d5db635 add docu and fix github workflow pypi-deploy.yml for installing libiconv 2023-08-07 22:50:00 +02:00
ecbae3f79b install libiconv in github workflow for matrix.os windows-2019 2023-08-05 23:01:00 +02:00
b54979aa74 restructure includes and headers 2023-07-11 13:41:34 +02:00
724f3d0bb9 * bump version 2.0.9
* convert to UTF-8 for any non-empty codepage: fix buffer string
  conversion
2023-07-06 00:12:14 +02:00
06c5710412 convert to UTF-8 for any non-empty codepage (issue #23) 2023-07-05 23:47:44 +02:00
b45fae576f strictly stick to UTC/GMT for timestamp calculations (issue #23) 2023-06-27 00:57:11 +02:00
55f093156d - bump VERSION 2.0.8
- add VERSION to MANIFEST.in in order to include VERSION in source dist
  (see https://packaging.python.org/en/latest/guides/using-manifest-in/)
2023-05-25 20:22:14 +02:00
ff69c329cc bump version 2.0.7, fix multichannel block-offset, issues #20 #15 2023-02-17 15:13:57 +01:00
d0accd6e0b add multichannel python example 2023-02-17 15:11:28 +01:00
89b7f045a4 * fix channel dependent buffer offset, issue #15
* add python example multichannel.py
2023-02-17 11:13:45 +01:00
46db4f3fe8 bump version 2.0.6 2023-02-11 20:56:28 +01:00
ef0bb7550d add multichannel support for multiple channels referring to same CS block, issue #15 2023-02-11 18:34:25 +01:00
730b3dad83 bump python version 2.0.5 2022-12-01 01:03:20 +01:00
9c69e94102 bump python version 2.0.4 2022-12-01 00:38:50 +01:00
bd9135820a add non-critical key NT version 2, issue #16 2022-12-01 00:29:15 +01:00
Marko Petzold
4404590c44
put warning into readme 2022-03-03 20:52:00 +01:00
441110afd6 fix spelling in makefile 2021-10-19 17:20:25 +02:00
a81e18eebc some fixes in README e.g. nomenclature of python module 2021-10-19 15:33:25 +02:00
8f1046632c bump VERSION 2.0.3 2021-10-19 15:08:05 +02:00
37ee82037e bump VERSION 2.0.2 2021-10-19 15:05:44 +02:00
028deaa2ce * deal with any extra quotes in xunit,xname,yunit,yname => issue #13
* rename CLI binary to lowercase version
* IMCtermite.pyx: rename boolean data flag
* insert some double quotes in sampleA.raw for testing
* version 2.0.1
2021-10-19 13:48:02 +02:00
ce4a106921 * github workflow: only trigger on pushed tag
* README.md: update python installation
2021-09-22 15:08:57 +02:00
ef5aaac254 github-workflow: flatten directory structure for download artifacts for PyPI upload 2021-09-22 13:45:15 +02:00
86eb20a33b github-workflow: fix relative directory for upload source/binary artifacts 2021-09-22 13:28:16 +02:00
ba275dd62a github-workflow: fix mixed up upload/download source vs. binary wheel artifacts 2021-09-22 13:23:42 +02:00
c2a28fc333 github-workflow: upload/download wheel artifacts for PyPi deployment 2021-09-22 13:20:46 +02:00
71cbe31915 github-workflow: remove macOS from os matrix and reduce set of archs to build for 2021-09-22 12:47:24 +02:00
f6fdb2228b github-workflow: switch to macos-11 to support c++17 2021-09-22 12:41:57 +02:00
b869686f6c github-workflow: download artifacts: specify directory path 2021-09-22 12:32:52 +02:00
3253ad2918 github-workflow: use artifacts to share prepared wheel configuration between jobs 2021-09-22 12:25:57 +02:00
770c0167af * github workflow: add checkout step and use makefile target for file
setup
* add README.rst to gitignore
* makefile: validate wheels, run python example, add README.rst option
* usage.py: fix output directory and simplify for loop
* setup.py: remove unused os module
* setup.cfg: syntax fix
2021-09-22 11:20:28 +02:00
c8bee63942 github workflow: build_setup: employ shell script with GITHUB_WORKSPACE 2021-09-21 17:20:46 +02:00
3e00543028 github workflow: build_setup: employ shell script, MANIFEST.in: include .hpp from lib 2021-09-21 17:16:02 +02:00
0e51c3302f github workflow: build_setup: use current working directory 2021-09-21 17:04:03 +02:00
c9837f5e68 github workflow: fix indent for multiline run 2021-09-21 17:01:01 +02:00
a3f5042c64 github workflow: replace make setup by multiline run 2021-09-21 17:00:01 +02:00
53d607db2c github workflow: sudo required for apt-get 2021-09-21 16:54:44 +02:00
e009ceb826 github workflow: add required whitespace in yml 2021-09-21 16:51:48 +02:00
8c1f068406 * github/workflows: include build_setup as requirement for all wheels
* setup.py: enable c++17 option
* gitignore: add wheelhouse/
* README.md: cibuildwheel references
2021-09-21 16:46:05 +02:00
a099849caa * github-actions: install missing cython package for creating sdist wheel
* remove VERSION from gitignore and keep VERSION file
2021-09-21 15:56:24 +02:00
71a39e90e4 github workflows: remove working directory for upload 2021-09-21 15:35:05 +02:00
372d4a42f5 github workflows: fix working directory 2021-09-21 15:31:54 +02:00
12963bae91 * rename workflows file and add sdist job
* rename CLI executable to IMCtermite
* add workflow badge to README.md
* clean up makefile
* add timestamp of build to CLI binary showing version/help
2021-09-21 15:12:42 +02:00
b71d86f735 * fix issue of 'inconsistent subsequent blocks' when using set_file() by clearing all buffers
* remove schedule from workflows/wheels.yml
2021-09-21 13:22:23 +02:00
2d654d2d2a * clean up repository: remove cython/ pip/ parquet/ assets/
* update python module MANIFEST.in to include sources
2021-09-21 13:00:28 +02:00
e6315ee186 * add github workflow for building wheels
* rename cython module for more consistency
* restructure python code
* proper python module setup
* bump major version 2.0.0
2021-09-21 12:55:19 +02:00
75e792b86c bump version 1.2.12 2021-09-16 16:15:26 +02:00
617ed541e3 reset rescaling factor to 1.0 even if its zero as given in the CR block (issue #12) 2021-09-16 16:10:13 +02:00
Mario Fink
aa020eee0c * add pip/build to gitignore
* makefile for pip: extract proper section of README.md
* bump version 1.2.11
2021-09-02 11:56:06 +02:00
Mario Fink
b110886935 add *.pyd to gitignore, imc_channel.hpp: fix int size_t conversions 2021-09-02 11:22:37 +02:00
Mario Fink
6bc6880d47 fix/disable type conversion warnings 2021-09-02 11:16:01 +02:00
Mario Fink
b51b63dedc enable proper git tag sorting in cython/setup.py for versioning 2021-09-02 11:01:12 +02:00
Mario Fink
601613b6c4 consider platform dependency for building cython extension locally 2021-09-02 10:57:21 +02:00
5e93ed0706 * version 1.2.10
* makefile: versioning and tags: properly deal with multiple digits version tags
* setup.py: support both sdist and bdist pip wheels
2021-09-01 10:58:42 +02:00
Mario Fink
1345f6e4c9 add separate NT trigger time and Cb addtime parameters to output 2021-07-12 13:19:45 +02:00
Mario Fink
1a381f01b7 delete deprecated python example, add new python example dealing with absolute time stamp according to trigger-time 2021-07-12 12:40:23 +02:00
Mario Fink
b42a170650 bump version 1.2.9 2021-07-08 15:39:50 +02:00
Mario Fink
1d30a5f237 include (absolute) trigger-time in channel output => issue #10 2021-07-08 14:06:20 +02:00
Mario Fink
00a869ff07 properly check markers of single file/all files in directory 2021-07-08 10:17:29 +02:00
Mario Fink
69f5e5496b * fix typo in preprocessor flag
* executable --help: provide full repository URL
2021-07-02 13:33:05 +02:00
Mario Fink
56f83b8132 bump version 1.2.8 2021-07-02 09:40:23 +02:00
Mario Fink
cda6673f85 fix MSVC compilation/build issues 2021-07-02 09:39:16 +02:00
Mario Fink
1d7a512fd4 * support pip installation on win32 => issue #8
* bump version 1.2.7
2021-07-02 09:11:30 +02:00
658a73a284 get_info(): show less x,ydata in info-string 2021-07-01 15:46:03 +02:00
71c9bb7a5c fix/optimize floating point precision for file output/info output/json output 2021-07-01 12:13:38 +00:00
45efb06aa2 add support for NL key, issue #6 2021-06-29 12:38:55 +02:00
538b6f4659 README.md: add famosfilekey reference 2021-06-29 11:45:50 +02:00
Mario Fink
08e2589dfd README: fix typo 2021-06-28 16:38:23 +02:00
Mario Fink
d098273816 README.md: udpate to new CLI options 2021-06-28 16:37:16 +02:00
Mario Fink
2f9c550323 bump pip/cython version 1.2.5 2021-06-28 16:33:25 +02:00
Mario Fink
234876c5a9 * cython/*_imc_termite.*: introduce both print_channel/print_channels
methods featuring csv delimiter option
* imc_raw.hpp: add print_channel()
* python/{example.py,usage.py}: adjust to existing sample file names,
  add print_channel() example
* src/main.cpp: add --delimiter option, additional CLI option checks
2021-06-28 16:26:07 +02:00
Mario Fink
bafc018566 CLI version: add option for delimiter token of csv output 2021-06-28 12:51:09 +02:00
fdd107fbb3 README.md: fix typo 2021-05-06 18:11:40 +02:00
cd4ce55e7e badge starts 2021-05-06 16:01:07 +02:00
27683cbbd6 license badge 2021-05-06 15:59:43 +02:00
25a51215a0 adjust README.md header 2021-05-06 15:50:38 +02:00
36c02089aa clean up README.md header 2021-05-06 15:47:31 +02:00
cd75689d32 lgtm code stats 2021-05-06 11:46:43 +02:00
57c7f6021b makefile: cppcheck target 2021-05-05 15:58:10 +02:00
83922c343f * imc_channel, imc_raw: optimize with pass by reference
* imc_object: asc_time, localtime: make threadsafe
* imc_datatype: satisfy 'rule of two'
* python: remove all unused imports
2021-05-05 13:28:11 +02:00
72378877ec add some pipy release documentation 2021-05-02 19:57:13 +02:00
e7094d0125 * py_imc_termite.pyx: remove json loads parse_float option
* imc_raw.hpp: catch empty/invalid file to avoid seg fault
2021-05-02 19:34:08 +02:00
16a77ecf1e bump version 1.2.4 for pip/cython 2021-04-30 11:10:41 +02:00
798fc22d7a imc_conversion.hpp: more comprehensive error message, imc_datatype: imc_Ulongint,imc_Slongint typedef for x86_64 vs. arm 2021-04-27 12:42:24 +02:00
2b2e69f0e5 * add support for datatype 11 = 2-byte-word digital
* usage.py: raise proper exception
* usage_adv.py: use different example file
2021-04-27 11:38:43 +02:00
Mario Fink
8708d2d008 * cython/py_imc_termite.pyx: json loads take care of floats, fix column assignment
* imc_channel.hpp: fix floating precision for get_channel()
* extend/include advanced usage in examples
2021-04-26 19:41:56 +02:00
9feadb50c1 py_imc_termite.pyx: fix special character encoding 2021-04-16 09:37:58 +02:00
dbeb1b862a py_imc_termite.pyx: print_table: encoding, xdata 2021-04-15 23:51:44 +02:00
bda799832c fix Dockerfile, cython: print_table to print all channels in single table 2021-04-15 20:17:02 +02:00
97c2195f98 ignore hexshow.hpp, version 1.2.3 2021-03-05 09:19:06 +01:00
ea7ab9fa85 gitignore: add pip files, pip: add proper README 2021-03-04 18:48:59 +01:00
c281aeae19 clean: include build directory 2021-03-04 11:48:06 +01:00
0403f2bc64 add pip package build/upload, check version tags 2021-03-04 11:47:15 +01:00
Mario Fink
0969d626b8
Merge pull request #5 from ZornitsaD/patch-2
Update README.md
2021-02-18 11:38:42 +01:00
ZornitsaD
37cbc2d45f
Update README.md 2021-02-18 10:50:25 +01:00
8c8ed10a90 README.md: some minor tweak 2021-02-17 10:23:53 +01:00
Mario Fink
ecc1cd8005
Merge pull request #4 from ZornitsaD/patch-1
Update README.md
2021-02-16 12:39:45 +01:00
ZornitsaD
8746519d1a
Update README.md
Hi Mario, I've had a look at the file and made some minor adjustments (punctuation mostly). Marko has asked us to mention the platform in the README files of the open-source projects with a brief explanation of where TDMtermite comes from and how we use it in the platform. I have to say, however, that I'm a bit out of my depth here.
2021-02-16 12:33:36 +01:00
c9f8097c9b README: fix link 2021-02-12 13:32:05 +01:00
5ae6b3f5ba add references 2021-02-12 13:29:53 +01:00
4c082451fa finalize README.md + example + cython interface 2021-02-12 13:22:15 +01:00
133279258f README: installation + usage 2021-02-12 12:14:51 +01:00
dd78b37290 cython setup imc_termite pytho module 2021-02-12 11:30:16 +01:00
3d9305a1be prepare imc_channel + imc_raw for cython interface 2021-02-12 09:52:52 +01:00
40a922893d CLI: fix options vs. argc handling 2021-02-12 09:29:55 +01:00
78c1ec4596 add Dockerfile 2021-02-11 20:11:52 +01:00
3948bfeac6 fix/improve printing and CLI 2021-02-11 19:54:09 +01:00
6b41dbe00a add printing methods 2021-02-11 19:39:11 +01:00
0107e367c4 finished conversion + CLI 2021-02-11 19:21:26 +01:00
3afa7fe345 channel: add origin NO 2021-02-11 17:21:39 +01:00
a03930515e finished metadata extraction 2021-02-11 17:17:09 +01:00
6f9133c638 start extraction 2021-02-11 16:03:49 +01:00
acd55194a5 imc_raw + imc_channels: channel extraction from blocks and environment 2021-02-11 15:49:11 +01:00
1596ca15b5 generate channel_envs 2021-02-11 13:38:07 +01:00
4b510ea91b remove redundant stuff related to imc_object 2021-02-11 12:52:53 +01:00
bed43d6785 * remove usage of imc::object
* introduce imc_channel with collection of affiliate blocks
* imc::keys as list instead of map with custom check/get methods
* imc_raw: start generation of affiliate blocks
2021-02-11 12:48:49 +01:00
fb16935829 makefile: force removal of object files to suppress error 2021-02-11 08:48:32 +01:00
c649961abb makefile: use PYT variable 2021-02-11 08:45:15 +01:00
42583eb51f makefile: restore python targets + readjust cython setup 2021-02-11 08:42:10 +01:00
26ff196676 remove redundant docu 2021-02-10 20:09:20 +01:00
2697e0b578 rename directories 2021-02-10 20:04:47 +01:00
f4ecf48218 start group - channel - component - buffer association 2021-02-10 20:01:11 +01:00
9bac0f1063 * list specific blocks
* key comparison operator
* imc::object: fix timestamp, fix analog vs. digital index
* imc_raw: convert datatype
2021-02-10 18:17:54 +01:00
eb13088257 rename samples and datasets/files 2021-02-10 16:09:33 +01:00
cfca5310ef remove old (makefile + main.cpp) 2021-02-10 15:38:43 +01:00
0eb034196d imc::object: all objects parsed 2021-02-10 15:37:24 +01:00
fe3befc5f2 start parsing imc::objects 2021-02-10 13:08:32 +01:00
eb2c49549a integrate imc::object into parsing workflow 2021-02-10 11:08:08 +01:00
4f3e816dbf wrapper for imc::object, include imc::object in imc::block 2021-02-09 20:57:44 +01:00
a808a001a9 imc::objects: preliminary complete 2021-02-09 19:31:27 +01:00
e952764e4f reduce computational complexity 2021-02-09 18:11:06 +01:00
79c1b19e33 check block consistency, reset block.end for length that exceeds buffer size (e.g. final CS) 2021-02-09 16:40:11 +01:00
c918746d29 add examples from IMC documentation 2021-02-09 15:06:55 +01:00
ee7f70d36f add imc_meta.hpp 2021-02-08 18:09:02 +01:00
09737a93fb imcdatatype: simplify class name 2021-02-08 17:27:17 +01:00
cb8365a897 implement imcdatatype 2021-02-08 17:21:37 +01:00
cf7d51e2fb imc::block: fix parameters parsing 2021-02-08 16:48:22 +01:00
cf6f91a324 extract all block/parameters data 2021-02-08 16:22:28 +01:00
3c91583ede adjust to new revision, main.cpp fix help message typo 2021-02-08 10:27:20 +01:00
584243f466 full imc raw format revision 2021-02-05 19:45:33 +01:00
09011b50ba tidy up parquet from lib 2021-02-05 12:30:01 +01:00
b869c1df3f clean up docu 2021-02-05 11:00:29 +01:00
e6be107950 update name/labeling 2021-02-05 10:14:48 +01:00
21039b5225 use single docu file for format 2021-02-05 09:16:10 +01:00
Mario Fink
700a1bed82 add technical docu 2021-02-04 17:20:25 +01:00
Mario Fink
5d0b330d9e update description 2021-02-04 14:06:00 +01:00
4ca398fa8c README: fix some formatting 2021-02-04 12:06:35 +01:00
debb4c4ec0 docu revision 2021-02-04 12:02:35 +01:00
42f1ebc0b8 update README.md 2021-02-03 16:50:15 +01:00
Mario Fink
acec174b8d
Create LICENSE 2021-02-03 16:41:11 +01:00
160 changed files with 3980 additions and 8761 deletions

101
.github/workflows/pypi-deploy.yml vendored Normal file
View File

@ -0,0 +1,101 @@
name: CI Build Wheel
on:
push:
# branches: [master]
tags: ["v[0-9]+.[0-9]+.[0-9]+"]
jobs:
build_setup:
name: Prepare environment for wheel builds
runs-on: ubuntu-24.04
steps:
- uses: actions/checkout@v2
- name: Prepare wheel build
run: make -C python/ setup
- name: Store wheel configuration files
uses: actions/upload-artifact@v4.6.0
with:
name: wheel-config
path: python/
- name: Display files
run: ls -lR
build_wheels:
name: Build binary wheels on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
needs: [build_setup]
strategy:
matrix:
os: [ubuntu-latest, windows-latest]
steps:
- uses: actions/checkout@v2
- uses: actions/setup-python@v2
- name: Install cibuildwheel
run: python -m pip install cibuildwheel==2.1.2
- name: Get wheel configuration files
uses: actions/download-artifact@v4.1.7
with:
name: wheel-config
path: python/
- name: Build wheels
run: python -m cibuildwheel --output-dir wheelhouse
working-directory: python/
- name: Store binary wheels
uses: actions/upload-artifact@v4.6.0
with:
name: binary-wheels-${{matrix.os}}-${{ strategy.job-index }}
path: python/wheelhouse/*.whl
build_sdist:
name: Build source distribution
runs-on: ubuntu-24.04
needs: [build_setup]
steps:
- uses: actions/checkout@v2
- name: Install cython
run: python -m pip install cython==0.29.24
- name: Get wheel configuration files
uses: actions/download-artifact@v4.1.7
with:
name: wheel-config
path: python/
- name: Build sdist
run: python setup.py sdist
working-directory: python/
- name: Store source wheels
uses: actions/upload-artifact@v4.6.0
with:
name: source-wheels
path: python/dist/*.tar.gz
- name: Display files
run: ls -lR
upload_pypi:
name: Upload wheels to PyPI
runs-on: ubuntu-24.04
needs: [build_wheels, build_sdist]
steps:
- name: Get source wheels
uses: actions/download-artifact@v4.1.7
with:
name: source-wheels
path: dist/
- name: Get binary wheels
uses: actions/download-artifact@v4.1.7
with:
path: dist/
pattern: binary-wheels-*
merge-multiple: true
- name: Display files
run: ls -lR
- uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.IMCTERMITE_GITHUB_WORKFLOW_PYPI_API_TOKEN }}

28
.gitignore vendored
View File

@ -1,6 +1,8 @@
eatraw
eatdev
imctermite
IMCtermite
nohup.out
@ -9,11 +11,35 @@ nohup.out
raw_eater.cpp
raw_meat.cpp
cyt/*.cpp
cython/*.cpp
/build
*.log
*.so
*.pyd
*.o
*.csv
*.parquet
src/*.cpp.cpp
pip/*.cpp
pip/*.hpp
pip/*.pyx
pip/*.pxd
pip/README.md
pip/LICENSE
pip/*egg-info
pip/dist/
pip/build/
python/README.md
python/README.rst
python/LICENSE
python/build
python/*.egg-info
python/dist
python/*.soc
python/lib/
python/*.cpp
python/wheelhouse/

21
Dockerfile Normal file
View File

@ -0,0 +1,21 @@
FROM debian:bullseye-20210111
USER root
RUN apt-get update && apt-get install -y \
build-essential git vim \
python3 python3-pip
RUN python3 -m pip install cython
RUN g++ -v
COPY ./ /IMCtermite/
# install CLI tool
RUN cd /IMCtermite && ls -lh && make install && ls -lh /usr/local/bin/imctermite
# install Python module
RUN cd /IMCtermite && ls -lh && make cython-install
CMD ["sleep","infinity"]

21
LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2021 Record Evolution
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

337
README.md
View File

@ -1,124 +1,249 @@
# raw_eater
[![LICENSE](https://img.shields.io/github/license/RecordEvolution/IMCtermite)](https://img.shields.io/github/license/RecordEvolution/IMCtermite)
[![STARS](https://img.shields.io/github/stars/RecordEvolution/IMCtermite)](https://img.shields.io/github/stars/RecordEvolution/IMCtermite)
![CI Build Wheel](https://github.com/RecordEvolution/IMCtermite/actions/workflows/pypi-deploy.yml/badge.svg?branch=&event=push)
[![PYPI](https://img.shields.io/pypi/v/IMCtermite.svg)](https://pypi.org/project/imctermite/)
The _raw_eater_ package is used to parse files with extension `*.raw`, which
are usually binary files produced by the labsoftware _Famos_ to dump measurement
time series.
# IMCtermite
## .raw-file format structure
_IMCtermite_ provides access to the proprietary data format
_IMC2 Data Format_ with the file extension _.raw_ (or .dat) introduced and developed by
[imc Test & Measurement GmbH](https://www.imc-tm.de/). This data format is
employed i.a. by the measurement hardware
[imc CRONOSflex](https://www.imc-tm.de/produkte/messtechnik-hardware/imc-cronosflex/ueberblick/)
to dump and store data and the software packages
[imc Studio](https://www.imc-tm.de/produkte/messtechnik-software/imc-studio/ueberblick/)
& [imc FAMOS](https://www.imc-tm.de/produkte/messtechnik-software/imc-famos/)
for measurement data control and analysis. Thanks to the integrated Python module,
the extracted measurement data can be stored in any open-source file format
accessible by Python like i.a. _csv_, _json_ or _parquet_.
The binary `*.raw` file features a series of markers that indicate the starting
point of various blocks of information. Every markers is introduced by character
"|" = `0x 7c` followed by two uppercase letters, which characterize the type of
marker. The following markers are defined:
On the [Record Evolution Platform](https://www.record-evolution.de/en/home-en/),
the library can be used both as a command line tool for interactive usage and as a
Python module to integrate the _.raw_ format into any ETL workflow.
1. CF (0x 43 46)
1. CK (0x 43 4b)
1. NO (0x 4e 4f)
1. CG (0x 43 47)
1. CD (0x 43 44)
1. NT (0x 4e 54)
1. CC (0x 43 43)
1. CP (0x 43 50)
1. CR (0x 43 52)
1. CN (0x 43 4e)
1. Cb (0x 43 62)
1. CS (0x 43 53)
## Overview
Each of these markers are followed by multiple commata (0x 2c) separated parameters
and are terminated by a semicolon `;` = 0x 3b, except for the sequence following
the data marker CS, that may have any number of 0x3b occurencies, while still
terminated by a semicolon at the very end of the file (since CS is the last marker
section in the file). The markers have the following meaning:
* [File format](#Fileformat)
* [Build and Installation](#Installation)
* [Usage and Examples](#Usage)
* [References](#References)
- *CF* (3 parameters)
`|CF,2,1,1;`
specifies file format, key length and processor
- *CK* (4 parameters)
`|CK,1,3,1,1;`
start of group of keys
- *NO* (6 parameters)
`|NO,1,85,0,77,imc STUDIO 5.0 R3 (10.09.2015)@imc DEVICES 2.8R7 (26.8.2015)@imcDev__15190567,0,;`
origin of the file, provides some info about the software package/device
and its version
- *CB* (6 parameters)
group definition
- *CT* (8 parameters)
text definition
- *CG* (5 parameters)
`|CG,1,5,1,1,1;`
definition of a data field
|CG,1,KeyLang,AnzahlKomponenten,Feldtyp,Dimension;
- *CD* (mostly 11 parameters)
since we're dealing with measured entities from the lab this markers contains
info about the measurement frequency, i.e. sample rate. For instance
`|CD,2, 63, 5.0000000000000001E-03,1,1,s,0,0,0, 0.0000000000000000E+00,1;`
indicates a measured entity every 0.005 seconds, i.e. a sample rate = 200Hz
- *NT* (7 parameters)
`|NT,1,16,1,1,1980,0,0,0.0;`
|NT,1,KeyLang,Tag,Monat,Jahr,Stunden,Minuten,Sekunden;
triggerzeit
- *CC* (mostly 4 parameters)
`|CC,1,3,1,1;`
Start einer Komponente (component)
- *CP* (9 parameters)
`|CP,1,16,1,4,7,32,0,0,1,0;`
Pack-Information zu dieser Komponente
CP,1,KeyLang,BufferReferenz,Bytes,Zahlenformat,SignBits,Maske,Offset,DirekteFolgeAnzahl,AbstandBytes;
Bytes = 1...8
Zahlenformat : 1 = unsigned byte
2 = signed byte
3 = unsigned short
4 = signed short
5 = unsigned long
6 = signed long
7 = float
8 = double
9 = imc Devices
10 = timestamp ascii
11 =
12 =
13 =
## File format
- *CR* (7 parameters)
Wertebereich der Komponente, nur bei analogen, nicht bei digitalen Daten.
|CR,1,KeyLang,Transformieren,Faktor,Offset,Kalibriert,EinheitLang, Einheit;
provides the _physical unit_ of the measured entity, maybe shows the
minimum and maximum value during the measurment, e.g.
`|CR,1,60,0, 1.0000000000000000E+00, 0.0000000000000000E+00,1,4,mbar;`
Transformieren : 0 = nein
1 = ja, mit faktor und offset transformieren (für ganzzahlige Rohdaten)
Faktor,Offset: physikalischer Wert = Faktor * Rohdatenwerten + Offset
- *CN* (mostly 9 parameters)
gives the _name_ of the measured entity
|CN,1,KeyLang,IndexGruppe,0,IndexBit,NameLang,Name,KommLang,Kommentar;
`|CN,1,27,0,0,0,15,pressure_Vacuum,0,;`
- *Cb* (mostly 14 paramters) (optional?)
this one probably gives the minimum/maximum measured values!!
`|Cb,1,117,1,0,1,1,0,341288,0,341288,1,0.0000000000000000E+00,1.1781711390000000E+09,;`
- *CS* (mostly 4 parameters)
this markers announces the actual measurement data in binary format,
provide the number of values and the actual data,
e.g. `|CS,1, 341299, 1, ...data... ;`
A file of the _IMC2 Data Format_ type with extension _.raw_ (or .dat) is a _mixed text/binary
file_ featuring a set of markers (keys) that indicate the start of various blocks
of data that provide meta information and the actual measurement data. Every single
marker is introduced by the character `"|" = 0x 7c` followed by two uppercase letters that
characterize the type of marker. Each block is further divided into several
parameters separated by commata `"," = 0x 2c` and terminated by a semicolon
`";" = 0x 3b`. For instance, the header - first 600 bytes - of a raw file may
look like this (in UTF-8 encoding):
### Open Issues and question?
```
|CF,2,1,1;|CK,1,3,1,1;
|NO,1,86,0,78,imc STUDIO 5.0 R10 (04.08.2017)@imc DEVICES 2.9R7 (25.7.2017)@imcDev__15190567,0,;
|CG,1,5,1,1,1; |CD,2, 63, 5.0000000000000001E-03,1,1,s,0,0,0, 0.0000000000000000E+00,1;
|NT,1,16,1,1,1980,0,0,0.0; |CC,1,3,1,1;|CP,1,16,1,4,7,32,0,0,1,0;
|CR,1,60,0, 1.0000000000000000E+00, 0.0000000000000000E+00,1,4,mbar;|CN,1,27,0,0,0,15,pressure_Vacuum,0,;
|Cb,1, 117,1,0, 1, 1, 0, 9608, 0, 9608,1, 2.0440300000000000E+03, 1.2416717060000000E+09,;
|CS,1, 9619, 1,<2C>oD <09>nD6<44>nD)<29>nD<6E>
```
- which parameter indicate(s) little vs. big endian?
Line breaks are introduced for readability. Most of the markers introduce
blocks of text, while only the last block identified by `|CS` contains binary data.
The format supports the storage of _multiple data sets (channels)_ in a single
file. The channels may be ordered in _multiplex_ mode (ordering w.r.t. time) or
_block_ mode (ordering w.r.t. to channels).
## .parquet-file writer
The markers (keys) are introduced by `"|" = 0x 7c` followed by two uppercase
letters. There are _two types_ of markers distinguished by the first letter:
The extracted and converted data originating from the *.raw file format may be efficiently grouped and
written as .parquet files
[parquet file writer example](https://github.com/apache/parquet-cpp/blob/master/examples/low-level-api/reader-writer.cc)
1. _critical_ markers: introduced by `|C` featuring uppercase `C`
1. _noncritical_ markers: introduced by `|N` featuring uppercase `N`
The second letter represents further details of the specific key. Note that
while the _noncritical_ keys are optional, any _.raw_ file _cannot be_ correctly
decoded if any of the _critical_ markers are misinterpreted, invalid or damaged.
The second uppercase letter is followed by the first comma and the _version_
of the key starting from 1. After the next comma, an _(long) integer_ (in text
representation) specifies the length of the entire block, i.e. the number of
bytes between the following comma and the block-terminating semicolon. The further
structure of a block is not defined and may feature different numbers of additional
parameters. The format allows for any number of carriage returns (`CR = 0x0d`)
and line feeds (`LF = 0x 0a`) between keys, i.e. the block-terminating semicolon
and the vertical bar (pipe) of the next key. The following _critical markers_
are defined:
| marker | description |
|--------|-----------------------------------------------------------------------------------------------------|
| CF | format version and processor |
| CK | start of group of keys, no. parameters = 3, indicates (in)correct closure of the measurement series |
| CB | defines a group of channels |
| CT | text definition including group association index |
| CG | introduces group of components corresponding to CC keys |
| CD1,2 | old/new version of abscissa description |
| CZ | scaling of z-axis for segments |
| CC | start of a component |
| CP | information about buffer, datatype and samples of component |
| Cb | buffer description |
| CR | permissible range of values in component |
| CN | name and comment of channel |
| CS | raw binary data |
| CI | single numerical value (including unit) |
| Ca | add reference key |
Among the _noncritical_ markers, there are
| marker | description |
|--------|--------------------------------------------|
| NO | origin of data |
| NT | timestamp of trigger |
| ND | (color) display properties |
| NU | user defined key |
| Np | property of a channel |
| NE | extraction rule for channels from BUS data |
The format loosely defines some rules for the ordering of the markers in the
file stream. The rules for critical keys include: _CK_ has to follow up on _CF_,
_CK_ may be followed by any number of _CG_ blocks, each _CG_ has to be followed
by (any number of) component sequences comprised of the series _CC_ , _CP_,
(_CR_), (_ND_) and terminated by either _CS_ or the start of a new group,
component, text field or buffer.
## Installation
The _IMCtermite_ library may be employed both as a _CLI_ tool and a _python_
module.
### CLI tool
To build the CLI tool locally, use the default target `make` resulting
in the binary `imctermite`. To ensure system-wide availability, the installation
of the tool (in the default location `/usr/local/bin`) is done via
```
make install
````
which may require root permissions.
### Python
To integrate the library into a customized ETL toolchain, several python targets
are available. For a local build that enables you to run the examples, use:
```
make python-build
```
#### Installation with pip
The package is also available in the [Python Package Index](https://pypi.org)
at [imctermite](https://pypi.org/project/imctermite/).
To install the latest version simply do
```Shell
python3 -m pip install imctermite
```
which provides binary wheels for multiple architectures on _Windows_ and _Linux_
and most _Python 3.x_ distributions. However, if your platform/architecture is
not supported you can still compile the source distribution yourself, which
requires _python3_setuptools_ and an up-to-date compiler supporting C++11
standard (e.g. _gcc version >= 10.2.0_).
## Usage
### CLI
The usage of the `imctermite` binary looks like this:
```
imctermite <raw-file> [options]
```
You have to provide a single _raw_ file and any option to specify what
to do with the data. All available options can be listed with `imctermite --help`:
```
Options:
-c, --listchannels list channels
-b, --listblocks list IMC key-blocks
-d, --output output directory to print channels
-s, --delimiter csv delimiter/separator char for output
-h, --help show this help message
-v, --version display version
```
For instance, to show a list of all channels included in `sample-data.raw`, you
do `imctermite sample-data.raw --listchannels`. No output files are
written by default. Output files are written only when an existing (!) directory
is provided as argument to the `--output` option. By default, every output file
is written using a `,` delimiter. You may provide any custom separator with the
option `--delimiter`. For example, in order to use `|`, the binary is called with
options `imctermite sample-data.raw -b -c -s '|'`.
### Python
Given the `IMCtermite` module is available, we can import it and declare an instance
of it by passing a _raw_ file to the constructor:
```Python
import imctermite
imcraw = imctermite.imctermite(b"sample/sampleA.raw")
```
An example of how to create an instance and obtain the list of channels is:
```Python
import IMCtermite
# declare and initialize instance of "imctermite" by passing a raw-file
try :
imcraw = IMCtermite.imctermite(b"samples/sampleA.raw")
except RuntimeError as e :
print("failed to load/parse raw-file: " + str(e))
# obtain list of channels as list of dictionaries (without data)
channels = imcraw.get_channels(False)
print(channels)
```
A more complete [example](python/examples/usage.py), including the methods for
obtaining the channels, i.a. their data and/or directly printing them to files,
can be found in the `python/examples` folder.
## References
- https://ch.mathworks.com/matlabcentral/fileexchange/30187-sequnce-to-read-famos-data-into-matlab-workspace
- https://community.ptc.com/t5/PTC-Mathcad/FAMOS-IMC-raw-data-in-MathCAD/td-p/130378
- http://marmatek.com/wp-content/uploads/2014/04/imc_STUDIO_Manual.pdf
### IMC
### Parquet
- https://www.imc-tm.de/produkte/messtechnik-software/imc-famos/funktionen/im-und-export/
- https://www.imc-tm.de/produkte/messtechnik-hardware/imc-cronosflex/ueberblick/
- https://www.imc-tm.de/download-center/produkt-downloads/imc-famos/handbuecher
- https://www.imc-tm.de/fileadmin/Public/Downloads/Manuals/imc_FAMOS/imcGemeinsameKomponenten.pdf
- https://github.com/Apollo3zehn/ImcFamosFile
- https://apollo3zehn.github.io/ImcFamosFile/api/ImcFamosFile.FamosFileKeyType.html
- https://github.com/apache/parquet-cpp
- https://github.com/apache/parquet-cpp/tree/master/examples
### Cython
- https://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html
### PyPI
- https://pypi.org/help/#apitoken
- https://sgoel.dev/posts/uploading-binary-wheels-to-pypi-from-github-actions/
- https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- https://github.com/pypa/cibuildwheel/blob/main/examples/github-deploy.yml
- https://cibuildwheel.readthedocs.io/en/stable/deliver-to-pypi/
- https://github.com/actions/download-artifact#download-all-artifacts
- https://github.com/actions/download-artifact?tab=readme-ov-file#download-multiple-filtered-artifacts-to-the-same-directory
### iconv
- https://www.gnu.org/software/libiconv/
- https://vcpkg.io/en/packages.html
- https://vcpkg.io/en/getting-started

View File

@ -1,41 +0,0 @@
# cython: language_level = 3
# distutils: language = c++
# use some C++ STL libraries
from libcpp.string cimport string
from libcpp.vector cimport vector
from libcpp cimport bool
# to include implemenation/definition file
#cdef extern from "raweat.cpp":
# pass
# these method names have to match the C definitions of the methods!!
#
# for how to overload the constructor see
# https://cython.readthedocs.io/en/latest/src/userguide/wrapping_CPlusPlus.html
# and propagating exceptions from C++ to Python
# http://docs.cython.org/en/latest/src/userguide/wrapping_CPlusPlus.html#exceptions
cdef extern from "../lib/raweat.hpp":
cdef cppclass raw_eater:
# constructor(s)
raw_eater() except +
raw_eater(string) except +
# set new file for decoding
void set_file(string)
# perform conversion (pass any C++ exceptions to Python)
void setup_and_conversion() except +
# get validity of data format
bool get_valid()
# get channel name and unit
string get_name()
string get_unit()
# get time step and time unit
double get_dt()
string get_temp_unit()
# get data array of time and measured quantity's channel
vector[double] get_time()
vector[double] get_data()
# dump all data to .csv
void write_table(const char*,char delimiter)

View File

@ -1,58 +0,0 @@
from raw_eater cimport raweater
import numpy as np
import re
import os
cdef class raweater:
# C++ instance of class => stack allocated (requires nullary constructor!)
cdef raw_eater rawit
# pointer to C++ instance (if there's no nullary constructor)
# cdef raw_eater *rawit
def __cinit__(self, string rawfile = b''):
if rawfile.decode() == "":
self.rawit = raw_eater()
# self.rawit = new raw_eater()
else:
if not os.path.isfile(rawfile) :
raise ValueError("'" + str(rawfile) + "' does not exist")
self.rawit = raw_eater(rawfile)
# self.rawit = new raw_eater(rawfile)
# def __dealloc__(self):
# del self.rawit
def set_file(self, string rawfile):
if not os.path.isfile(rawfile) :
raise ValueError("'" + str(rawfile) + "' does not exist")
self.rawit.set_file(rawfile)
def do_conversion(self):
self.rawit.setup_and_conversion()
def validity(self):
return self.rawit.get_valid()
def channel_name(self):
return self.rawit.get_name()
def unit(self):
return self.rawit.get_unit()
def dt(self):
return self.rawit.get_dt()
def time_unit(self):
return self.rawit.get_temp_unit()
def get_time(self):
return self.rawit.get_time()
def get_channel(self):
return self.rawit.get_data()
def write_table(self, const char* csvfile, char delimiter):
self.rawit.write_table(csvfile,delimiter)

View File

@ -1,37 +0,0 @@
# cython: language_level = 3
# distutils: language = c++
# use some C++ STL libraries
from libcpp.string cimport string
from libcpp.vector cimport vector
from libcpp cimport bool
# these method names have to match the C++ definitions of the methods!!
cdef extern from "../lib/rawmerge.hpp":
cdef cppclass raw_merger:
raw_merger(string) except +
# get validity of data format
bool get_valid()
# get channel name and unit
string get_name()
string get_unit()
# get time step and time unit
double get_dt()
string get_temp_unit()
# get data array of time and measured quantity's channel
vector[double] get_time()
vector[double] get_data()
# dump all data to .csv
void write_table(const char*,char)
# add channel and try to merge it (pass C++ exceptions to Python)
bool add_channel(string) except +
# get total number of (added) channels
int get_num_channels()
# get list of channel names
vector[string] get_channel_names()
# get data of particular channel
vector[double] get_channel(int)
# get total merged time series
vector[double] get_time_series()
# dump all channels to .csv
void write_table_all(const char*,char)

View File

@ -1,58 +0,0 @@
# from <raw_meat> has to match name of .pxd file and cimport name of class defined in .pxd
from raw_meat cimport raw_merger
import numpy as np
import re
cdef class rawmerger:
# pointer to C++ instance (since there's no nullary constructor)
cdef raw_merger *rawit
def __cinit__(self, string rawfile):
self.rawit = new raw_merger(rawfile)
def __dealloc__(self):
del self.rawit
def validity(self):
return self.rawit.get_valid()
def channel_name(self):
return self.rawit.get_name()
def unit(self):
return self.rawit.get_unit()
def dt(self):
return self.rawit.get_dt()
def time_unit(self):
return self.rawit.get_temp_unit()
def get_time(self):
return self.rawit.get_time()
def get_channel(self):
return self.rawit.get_data()
def write_table(self, const char* csvfile, char delimiter):
return self.rawit.write_table(csvfile,delimiter)
def add_channel(self, string rawfile):
return self.rawit.add_channel(rawfile)
def get_num_channels(self):
return self.rawit.get_num_channels()
def get_channel_names(self):
return self.rawit.get_channel_names()
def get_channel_by_index(self, int chidx):
return self.rawit.get_channel(chidx)
def get_time_series(self):
return self.rawit.get_time_series()
def write_table_all(self, const char* csvfile, char delimiter):
return self.rawit.write_table_all(csvfile,delimiter)

View File

@ -1,20 +0,0 @@
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
extensions = Extension(
name="raw_eater",
sources=["cyt/raw_eater.pyx"],
# libraries=[""],
library_dirs=["src"],
include_dirs=["src"],
language='c++',
extra_compile_args=['-std=c++11','-Wno-unused-variable'],
extra_link_args=['-std=c++11'],
#extra_objects=["lib/parquet/libarrow.so.200.0.0"],
)
setup(
name="raw_eater",
ext_modules=cythonize(extensions)
)

View File

@ -1,20 +0,0 @@
from distutils.core import setup
from distutils.extension import Extension
from Cython.Build import cythonize
extensions = Extension(
name="raw_meat",
sources=["cyt/raw_meat.pyx"],
# libraries=[""],
library_dirs=["src"],
include_dirs=["src"],
language='c++',
extra_compile_args=['-std=c++11','-Wno-unused-variable'],
extra_link_args=['-std=c++11'],
#extra_objects=["lib/parquet/libarrow.so.200.0.0"],
)
setup(
name="raw_meat",
ext_modules=cythonize(extensions)
)

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,217 +0,0 @@
function [dataOut]=FAMOSimport(filename)
% Usage: data=FAMOSimport(filename);
%
% FAMOSimport() opens (MARC generated) FAMOS files and imports all signals.
%
% *************************************************************************
%
%
% Preset output to empty;
dataOut=[];
%% Check for valid input file
if exist('filename','var')~=1 ...
|| isempty(filename)
[filename, pathname] = uigetfile( ...
{'*.dat','FAMOS measurement files'; ...
'*.*','All files'},'Select FAMOS measurement file ...');
if isequal(filename,0)
disp('FAMOS-measurement file import cancelled.');
return;
end
filename=fullfile(pathname, filename);
clear pathname;
end
if exist(filename,'file')~=2
disp('Given file could not be found. Aborting import.');
return;
end
%% Load input file
fid=fopen(filename,'r','l');
data=fread(fid,inf,'uint8=>char','l')';
fclose(fid);
clear fid
%% Parse header information
dataOut.FileName=filename;
dataOut.TYPE='AFT MARC (FAMOS)';
header=strfind(data(1:200),[char(13) char(10) '|NO,']);
subIdx=strfind(data(header(1):header(1)+50),',');
dataOut.Device=strtrim(data(header(1)+subIdx(5):header(1)+subIdx(6)-2));
%% Parse measurement entries information
units=strfind(data,[char(13) char(10) '|CR,'])';
dataOut.Unit=cell(size(units));
dataOut.Factor=zeros(size(dataOut.Unit),'double');
dataOut.Offset=zeros(size(dataOut.Unit),'double');
for i=1:length(units)
subIdx=sort([strfind(data(units(i):units(i)+255),',') ...
strfind(data(units(i):units(i)+255),';')]);
dataOut.Factor(i)=str2double( ...
data(units(i)+subIdx(4):units(i)+subIdx(5)-2));
dataOut.Offset(i)=str2double( ...
data(units(i)+subIdx(5):units(i)+subIdx(6)-2));
dataOut.Unit{i}=data(units(i)+subIdx(8):units(i)+subIdx(9)-2);
end
clear units subIdx;
%Extract measurement variables names and corresponding time column
varName=strfind(data,[char(13) char(10) '|CN,'])';
dataOut.TimeIndex=zeros(size(varName),'uint32');
dataOut.Label=cellstr(char(zeros(size(dataOut.TimeIndex))));
dataOut.Data=zeros(size(dataOut.TimeIndex),'double');
for i=1:length(varName)
subIdx=strfind(data(varName(i):varName(i)+255),',');
dataOut.Label{i}=data(varName(i)+subIdx(7):varName(i)+subIdx(8)-2);
end
for i=1:length(varName)
subIdx=sort([strfind(data(varName(i):varName(i)+255),',') ...
strfind(data(varName(i):varName(i)+255),';')]);
TimeVarName=data(varName(i)+subIdx(9):varName(i)+subIdx(10)-2);
if i==1 || ~strcmp(dataOut.TimeIndex(i-1),TimeVarName)
idx=strmatch(TimeVarName,dataOut.Label,'exact');
if ~isempty(idx)
dataOut.TimeIndex(i)=idx(1);
else
warning('FAMOSconnect:invalidTimeLabel', ...
['Signal ''%s'' (%d) refers to non-existing ' ...
'time signal label ''%s''.'], ...
dataOut.Label{i},i,TimeVarName);
end
else
dataOut.TimeIndex(i)=dataOut.TimeIndex(i-1);
end
end
clear varName TimeVarName subIdx;
%Extract measurement value data type and bitlength
dataType=strfind(data,[char(13) char(10) '|CP,1,'])';
dataOut.DataType=cell(size(dataType));
dataOut.DataBits=zeros(size(dataOut.DataType),'uint8');
for i=1:length(dataType)
subIdx=strfind(data(dataType(i):dataType(i)+50),',');
switch (data(dataType(i)+subIdx(5):dataType(i)+subIdx(6)-2))
case '1' % uint8
dataOut.DataType{i}='uint8';
case '2' % int8
dataOut.DataType{i}='int8';
case {'3','9','11'} % uint16
dataOut.DataType{i}='uint16';
case '4' % int16
dataOut.DataType{i}='int16';
case '5' % uint32
dataOut.DataType{i}='uint32';
case '6' % int32
dataOut.DataType{i}='int32';
case '7' % float
dataOut.DataType{i}='single';
case {'8','10','13'} % double
dataOut.DataType{i}='double';
otherwise
dataOut.DataType{i}='UNKNOWN';
end
dataOut.DataBits(i)=str2double( ...
data(dataType(i)+subIdx(6):dataType(i)+subIdx(7)-2));
end
clear dataType subIdx;
%Extract measurement value data block and item number
dataInfo=strfind(data,[char(13) char(10) '|Cb,1,'])';
dataOut.DataBlock=zeros(size(dataInfo),'uint16');
dataOut.DataItem=zeros(size(dataOut.DataBlock),'uint16');
for i=1:length(dataInfo)
subIdx=strfind(data(dataInfo(i):dataInfo(i)+50),',');
dataOut.DataItem(i)=str2double( ...
data(dataInfo(i)+subIdx(5):dataInfo(i)+subIdx(6)-2));
dataOut.DataBlock(i)=str2double( ...
data(dataInfo(i)+subIdx(6):dataInfo(i)+subIdx(7)-2));
end
clear dataInfo subIdx;
%Extract measurement value binary data length and offset
dataBlock=strfind(data,[char(13) char(10) '|CS,'])';
dataOut.DataBlocks=length(dataBlock);
dataOut.DataBlocksLength=zeros(size(dataBlock),'uint32');
dataOut.DataBlocksItemLength=zeros(size(dataBlock),'uint32');
dataOut.DataBlocksOffset=zeros(size(dataBlock),'uint32');
for i=1:length(dataBlock)
subIdx=strfind(data(dataBlock(i):dataBlock(i)+50),',');
dataOut.DataBlocksOffset(i)=dataBlock(i)+subIdx(4)-1;
dataOut.DataBlocksLength(i)=str2double( ...
data(dataBlock(i)+subIdx(2):dataBlock(i)+subIdx(3)-2)) ...
-(subIdx(4)-subIdx(3)); %Fix offset
dataOut.DataBlocksItemLength(i)=dataOut.DataBlocksLength(i) ...
/(sum(dataOut.DataBits(dataOut.DataBlock==i)/8));
end
clear dataBlock subIdx;
%% Sort entries - note: DataItem-value continues over blocks.
[~, dataOrder]=sort(dataOut.DataItem);
dataOutField=fieldnames(dataOut);
for i=1:length(dataOutField)
if length(dataOut.(dataOutField{i}))==length(dataOut.DataItem) ...
&& ~strcmp(dataOutField{i},'DataBlocksLength')
dataOut.(dataOutField{i})=dataOut.(dataOutField{i})(dataOrder);
end
end
clear dataOrder dataOutField;
%% Extract measurement data, format: shots-aligned (not variables aligned)
data=cast(data,'uint8');
dataOut.Data=cell(length(dataOut.DataItem),1);
dataBlockId=1;
dataOffset=dataOut.DataBlocksOffset(dataBlockId);
dataVarIdx1=uint32(1: ...
dataOut.DataBlocksLength(dataBlockId) ...
/dataOut.DataBlocksItemLength(dataBlockId): ...
dataOut.DataBlocksLength(dataBlockId));
dataVarIdx2=reshape([dataVarIdx1; dataVarIdx1+1],1,[]);
dataVarIdx4=reshape([dataVarIdx1; dataVarIdx1+1; ...
dataVarIdx1+2; dataVarIdx1+3],1,[]);
for i=1:length(dataOut.Label)
if dataOut.DataBlock(i)>dataBlockId
dataBlockId=dataOut.DataBlock(i);
dataOffset=dataOut.DataBlocksOffset(dataBlockId);
dataVarIdx1=uint32(1: ...
dataOut.DataBlocksLength(dataBlockId) ...
/dataOut.DataBlocksItemLength(dataBlockId): ...
dataOut.DataBlocksLength(dataBlockId));
dataVarIdx2=reshape([dataVarIdx1; dataVarIdx1+1],1,[]);
dataVarIdx4=reshape([dataVarIdx1; dataVarIdx1+1; ...
dataVarIdx1+2; dataVarIdx1+3],1,[]);
end
switch dataOut.DataBits(i)
case 8
dataVal=cast(typecast(data(dataVarIdx1+dataOffset),...
dataOut.DataType{i}),'double');
dataOffset=dataOffset+1;
case 16
dataVal=cast(typecast(data(dataVarIdx2+dataOffset),...
dataOut.DataType{i}),'double');
dataOffset=dataOffset+2;
case 32
dataVal=cast(typecast(data(dataVarIdx4+dataOffset),...
dataOut.DataType{i}),'double');
dataOffset=dataOffset+4;
otherwise
fprintf(2,['Unsupported data width in item %d:' ...
'%d Bits - Skipping.\n'], ...
dataOut.DataItem(i),dataOut.DataBits(i));
dataOffset=dataOut.DataBits(i)/8;
continue;
end
dataVal=dataVal*dataOut.Factor(i)+dataOut.Offset(i);
dataOut.Data{i}=dataVal';
end
clear dataOffset dataBlockId dataVarIdx1 dataVarIdx2 dataVarIdx4 dataVal;
clear i data;

View File

@ -1,222 +0,0 @@
function Channel=importfamos(FullRawData)
%__________________________________________________________________________
% The sequnce importfamos.m was produced to convert imc raw data(*.raw;
% *.dat) to matlab data. Here, struct is used to manage the channel
% information.
%
% For more information of FAMOS file format, please see the
% manufacturer's website: http://www.imc-berlin.de
%
% Corresponding to Data Structure in Matlab, the channels are stored
% as struct struct: Channel + name (channel name)
% + comment
% + data (channel Value)
% + length
% + yUnit
% + t0
% + dt(sampling period)
% + xUnit
% Version history:
% Version 1.0 (2011.1.19); Current version only can deal with analog rawdata
% from imc devices. The digital and group function is ongoning and will be
% released in version 2.
% Version 1.1 (2013.12.31): In order to solve non-manually save data,
% regular pattern is introduced into sloving data structure without CR and
% LF.
% (only support data(Channel) from imc devices)
%
%%-------------------------------------------------------------------------
% Author: Liang
% Danke.Liang@gmail.com
% Started on Dec.14, 2010
%__________________________________________________________________________
if nargin == 0;
[RawData,FamosPath] = uigetfile({'*.raw';'*.dat'},'Select Famos Raw data');
FullRawData=strcat(FamosPath,RawData);
end
fid = fopen(FullRawData,'r');
if fid==-1,
disp('failed to read rawdata')
return
end
disp(['Info: Read data @' datestr(now) ' from' ])
disp([ ' ' FullRawData '...'])
Textall=fscanf(fid,'%c');
CSstring='\|CS,\d,\D*\d+,\D*\d+,';
CSend=regexp(Textall,CSstring,'end');
InfoSegment=Textall(1,1:CSend);
Cbstr='\|Cb.*?;';
CGstr='\|CG,.*?;';
CDstr='\|CD,.*?;';
NTstr='\|NT,.*?;';
CPstr='\|CP,.*?;';
CRstr='\|CR,.*?;';
CNstr='\|CN,.*?;';
ArrCG=char(regexp(InfoSegment,CGstr,'match'));
ChannelNum=size(ArrCG,1);
ArrCN=char(regexp(InfoSegment,CNstr,'match'));
ArrCD=char(regexp(InfoSegment,CDstr,'match'));
ArrNT=char(regexp(InfoSegment,NTstr,'match'));
ArrCP=char(regexp(InfoSegment,CPstr,'match'));
ArrCb=char(regexp(InfoSegment,Cbstr,'match'));
ArrCR=char(regexp(InfoSegment,CRstr,'match'));
%% CN
ChannelName=cell(ChannelNum,1);
ChannelComment=cell(ChannelNum,1);
%% CD,NT
CDsample=zeros(ChannelNum,1);
CDUnit=cell(ChannelNum,1);
TriggerTime=cell(ChannelNum,1);
%% CP
KeyBufferRef=zeros(ChannelNum,1);
KeyBytes=zeros(ChannelNum,1);
KeyNumberFormat=cell(ChannelNum,1);
KeySignBits=zeros(ChannelNum,1);
%% Cb
KeyBufferRefIndex=zeros(ChannelNum,1);
KeyBufferRefCb=zeros(ChannelNum,1);
KeyOffsetBufferInSamplesKey=zeros(ChannelNum,1);
KeyBufferFilledBytes=zeros(ChannelNum,1);
%% CR
KeyTransformation=zeros(ChannelNum,1);
KeyCRfactor=zeros(ChannelNum,1);
KeyCRoffset=zeros(ChannelNum,1);
KeyUnit=cell(ChannelNum,1);
%% Define Return object
Channel=struct('name','','comment','','data',[],'length',0,'yUnit','','t0','','dt','','xUnit','');
BinaryStart=CSend;
ChannelID=1;
while ChannelID <= ChannelNum
temptext=char(ArrCD(ChannelID,:));
[CDsample(ChannelID,1), CDUnit{ChannelID,1}]=ProcessCD(temptext);
[ChannelName{ChannelID,1},ChannelComment{ChannelID,1}]=ProcessCN(ArrCN(ChannelID,:));
Channel(ChannelID).name=ChannelName{ChannelID,1};
disp(strcat('Channel_',num2str(ChannelID),':',Channel(ChannelID).name))
Channel(ChannelID).comment=ChannelComment{ChannelID,1};
Channel(ChannelID).dt=strcat(num2str(CDsample(ChannelID,1)),CDUnit{ChannelID,1});
Channel(ChannelID).xUnit=CDUnit{ChannelID,1};
TriggerTime{ChannelID,1}=ProcessNT(ArrNT(ChannelID,:));
Channel(ChannelID).t0=TriggerTime{ChannelID,1};
[KeyBufferRef(ChannelID,1),KeyBytes(ChannelID,1),KeyNumberFormat{ChannelID,1},KeySignBits(ChannelID,1)]=ProcessCP(ArrCP(ChannelID,:));
[KeyBufferRefIndex(ChannelID,1),KeyBufferRefCb(ChannelID,1),KeyOffsetBufferInSamplesKey(ChannelID,1),KeyBufferFilledBytes(ChannelID,1)]=ProcessCblittle(ArrCb(ChannelID,:));
[KeyTransformation(ChannelID,1),KeyCRfactor(ChannelID,1),KeyCRoffset(ChannelID,1),KeyUnit{ChannelID,1}]=ProcessCR(ArrCR(ChannelID,:));
Channel(ChannelID).yUnit=KeyUnit{ChannelID,1};
BinaryRead= BinaryStart+KeyOffsetBufferInSamplesKey(ChannelID,1);
ChannelLength=KeyBufferFilledBytes(ChannelID,1)*8/KeySignBits(ChannelID,1);
Channel(ChannelID).data=ReadChannel(fid,BinaryRead,ChannelLength,KeyNumberFormat{ChannelID,1},KeyCRfactor(ChannelID,1),KeyCRoffset(ChannelID,1));
Channel(ChannelID).length=ChannelLength;
ChannelID=ChannelID+1;
end
fclose(fid);
end
%%
function [KeyDx, KeyUnit]= ProcessCD(TxtString)
% disp('Info: Processing key CD...');
CommaLocation=find(TxtString==',');
Txtemp=TxtString(CommaLocation(3)+1:CommaLocation(4)-1);
KeyDx=str2double(Txtemp);
KeyUnit=TxtString(CommaLocation(6)+1:CommaLocation(7)-1);
% disp('Info: Finished Process key CD!');
end
function TimeStart = ProcessNT(TxtString)
CommaLocation=find(TxtString==',');
Txtemp=TxtString(CommaLocation(3)+1:CommaLocation(4)-1);
KeyDay=str2num(Txtemp);
Txtemp=TxtString(CommaLocation(4)+1:CommaLocation(5)-1);
KeyMonth=str2num(Txtemp);
Txtemp=TxtString(CommaLocation(5)+1:CommaLocation(6)-1);
KeyYear=str2num(Txtemp);
Txtemp=TxtString(CommaLocation(6)+1:CommaLocation(7)-1);
KeyHours=str2num(Txtemp);
Txtemp=TxtString(CommaLocation(7)+1:CommaLocation(8)-1);
KeyMinutes=str2num(Txtemp);
Txtemp=TxtString(CommaLocation(8)+1:length(TxtString));
KeySeconds=str2num(Txtemp);
TimeStart=datestr(datenum([KeyYear, KeyMonth,KeyDay,KeyHours,KeyMinutes,KeySeconds]),'yyyy-mm-dd HH:MM:SS');
% disp('Info: Finished Processing key NT!');
end
function [KeyBufferRef,KeyBytes,KeyNumerFormat,KeySignBits]= ProcessCP(TxtString)
% disp('Info: Processing key CP...');
CommaLocation=find(TxtString==',');
Txtemp=TxtString(CommaLocation(3)+1:CommaLocation(4)-1);
KeyBufferRef=str2num(Txtemp);
Txtemp=TxtString(CommaLocation(4)+1:CommaLocation(5)-1);
KeyBytes=str2num(Txtemp);
Txtemp=TxtString(CommaLocation(5)+1:CommaLocation(6)-1);
NumberFormat=str2num(Txtemp);
switch (NumberFormat)
case 1
KeyNumerFormat='*uint';
case 2
KeyNumerFormat='*int';
case 3
KeyNumerFormat='*ushort';
case 4
KeyNumerFormat='*short';
case 5
KeyNumerFormat='*ulong';
case 6
KeyNumerFormat='*long';
case 7
KeyNumerFormat='*float';
case 8
KeyNumerFormat='*float32';
case 9
KeyNumerFormat='*'; % imc Device Transitional Recording
case 10
KeyNumerFormat='*TimeStampASII' ;% TimeStamp is famos type
case 11
KeyNumberFormat='*bit16'; %2-byte-word digital
case 13
KeyNumberFormat='*bit48';
end
Txtemp=TxtString(CommaLocation(6)+1:CommaLocation(7)-1);
KeySignBits=str2num(Txtemp);
end
function [KeyBufferRefIndex,KeyBufferRefCb,KeyOffsetBufferInSamplesKey,KeyBufferFilledBytes] = ProcessCblittle(TxtString)
% disp('Info: Processing key Cb...');
CommaLocation=find(TxtString==',');
Txtemp=TxtString(CommaLocation(3)+1:CommaLocation(4)-1);
KeyBufferRefIndex=str2num(Txtemp);
Txtemp=TxtString(CommaLocation(5)+1:CommaLocation(6)-1);
KeyBufferRefCb=str2double(Txtemp);
Txtemp=TxtString(CommaLocation(7)+1:CommaLocation(8)-1);
KeyOffsetBufferInSamplesKey=str2double(Txtemp);
Txtemp=TxtString(CommaLocation(10)+1:CommaLocation(11)-1);
KeyBufferFilledBytes=str2double(Txtemp);
%disp('Info: Finished Processing key Cb!');
end
function [KeyTransformation,KeyCRfactor,KeyCRoffset,KeyUnit]= ProcessCR(TxtString)
% disp('Info: Processing key CR...')
%
CommaLocation=find(TxtString==',');
Txtemp=TxtString(CommaLocation(3)+1:CommaLocation(4)-1);
KeyTransformation=str2num(Txtemp);
Txtemp=TxtString(CommaLocation(4)+1:CommaLocation(5)-1);
KeyCRfactor=str2double(Txtemp);
Txtemp=TxtString(CommaLocation(5)+1:CommaLocation(6)-1);
KeyCRoffset=str2double(Txtemp);
Txtemp=TxtString(CommaLocation(7)+1:CommaLocation(8)-1);
KeyUnitLength=str2double(Txtemp);
KeyUnit=TxtString(CommaLocation(8)+1:CommaLocation(8)+KeyUnitLength);
% disp('Info: Finished Processing key CR!');
end
function [ChannelName,ChannelComment]= ProcessCN(TxtString)
CommaLocation=find(TxtString==',');
ChannelName=TxtString(CommaLocation(7)+1:CommaLocation(8)-1);
ChannelCommLength=TxtString(CommaLocation(8)+1:CommaLocation(9)-1);
if ChannelCommLength=='0';
ChannelComment='';
else
temp=str2double(ChannelCommLength);
ChannelComment=TxtString(CommaLocation(9)+1:CommaLocation(9)+temp);
end
end
function tempChannel=ReadChannel(FileID, ReadStart,ChannelLength, Datatype,factor,offset)
fseek(FileID,ReadStart,'bof');
tempChannel=double(fread(FileID,ChannelLength,Datatype))*factor+offset;
%disp('Info: a Channle was imported.... ');
end

View File

@ -4,6 +4,7 @@
#define HEXSHOW
#include <sstream>
#include <assert.h>
//---------------------------------------------------------------------------//

178
lib/imc_block.hpp Normal file
View File

@ -0,0 +1,178 @@
//---------------------------------------------------------------------------//
#ifndef IMCBLOCK
#define IMCBLOCK
#include <iomanip>
#include <map>
#include <string>
#include <sstream>
#include <vector>
#include "imc_parameter.hpp"
#include "imc_object.hpp"
//---------------------------------------------------------------------------//
namespace imc
{
// define "magic bytes" announcing start/end of blocks and separation of parameters within
const unsigned char ch_bgn_ = 0x7c, ch_end_ = 0x3b, ch_sep_ = 0x2c;
// define properties of a raw file block
class block
{
// associated IMC key
key thekey_;
// unique identifier for using block in hash maps (e.g. byte-position of block = begin_)
std::string uuid_;
// offset (in byte) of first (=ch_bgn_) and last byte (=ch_end_) of block
// w.r.t. to entire raw file
unsigned long int begin_, end_;
// name and buffer of associated raw file
std::string raw_file_;
const std::vector<unsigned char>* buffer_;
// offset of first/last byte of parameters in block (separated by ch_sep_)
// w.r.t. to first byte of block (=0)
std::vector<imc::parameter> parameters_;
public:
// constructor
block(key thekey, unsigned long int begin, unsigned long int end,
std::string raw_file, const std::vector<unsigned char>* buffer):
thekey_(thekey), uuid_(std::to_string(begin))
{
if ( !imc::check_key(thekey) ) throw std::logic_error("unknown key");
begin_ = begin;
end_ = end;
if ( end_ <= begin_ )
{
throw std::logic_error("block: offset of first byte larger than last byte's offset");
}
raw_file_ = raw_file;
buffer_ = buffer;
// make sure "end_" does not exceed buffer size due to invalid "length" parameter of block
if ( end_ > buffer_->size() )
{
std::cout<<"WARNING: invalid length parameter in "<<thekey_.name_<<"-block "
<<"(block-end:"<<end_<<",buffer-size:"<<buffer_->size()<<")"
<<" => resetting block-end to buffer-size\n";
end_ = (unsigned long int)(buffer_->size());
}
try {
parse_parameters();
} catch (const std::exception& e) {
throw std::runtime_error(
std::string("block: failed to parse parameters/objects: ") + e.what()
);
}
}
private:
// identify/parse parameters in block
void parse_parameters()
{
// parse entire block and check for separator tokens
// (consider only first four of any CS block)
int count = 0;
for ( unsigned long int b = begin_;
b < end_ && ( ! (thekey_.name_== "CS") || count < 4 ); b++ )
{
if ( buffer_->at(b) == imc::ch_sep_ )
{
// define range of parameter with first byte = ch_sep_
parameters_.push_back(imc::parameter(b,b));
count++;
}
}
// set offset of parameters's last byte
for ( unsigned long int p = 0; p < parameters_.size()-1; p++ )
{
parameters_[p].end( parameters_[p+1].begin() - 1 );
}
parameters_.back().end( this->end_ - 1 );
}
public:
// access members
imc::key get_key() { return thekey_; }
std::string get_uuid() { return uuid_; }
unsigned long int get_begin() { return begin_; }
unsigned long int get_end() { return end_; }
// get list of parameters
std::vector<parameter>& get_parameters()
{
return parameters_;
}
// get data of single parameter
std::vector<unsigned char> extract_parameter(parameter& param)
{
// check parameter w.r.t. to block
if ( param.begin() < begin_ || param.end() > end_ )
{
throw std::logic_error("inconsistent parameter offsets");
}
std::vector<unsigned char> parambuff(buffer_->begin()+begin_+param.begin(),
buffer_->begin()+begin_+param.end());
return parambuff;
}
// get single parameter as string
std::string get_parameter(parameter& param)
{
// check parameter w.r.t. to block
if ( param.begin() < begin_ || param.end() > end_ )
{
throw std::logic_error("inconsistent parameter offsets");
}
std::string prm("");
for ( unsigned long int i = param.begin()+1; i <= param.end(); i++ )
{
prm.push_back( (char)((*buffer_)[i]) );
}
return prm;
}
// get info string
std::string get_info(int width = 20)
{
// summarize parameters in single string
std::string prsstr("{");
for ( auto par: parameters_ ) prsstr += par.get_info() + std::string(",");
if ( prsstr.size() > 1 ) prsstr.pop_back();
prsstr += std::string("}");
// construct block info string
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"block:"<<thekey_.name_
<<" version "<<thekey_.version_
<<" ("<<thekey_.description_<<")"<<"\n"
<<std::setw(width)<<std::left<<"uuid:"<<uuid_<<"\n"
<<std::setw(width)<<std::left<<"begin:"<<begin_<<"\n"
<<std::setw(width)<<std::left<<"end:"<<end_<<"\n"
<<std::setw(width)<<std::left<<"rawfile:"<<raw_file_<<"\n"
<<std::setw(width)<<std::left<<"buffersize:"<<buffer_->size()<<"\n"
<<std::setw(width)<<std::left<<"parameters:"<<prsstr<<"\n";
return ss.str();
}
};
}
#endif
//---------------------------------------------------------------------------//

801
lib/imc_channel.hpp Normal file
View File

@ -0,0 +1,801 @@
//---------------------------------------------------------------------------//
#ifndef IMCCHANNEL
#define IMCCHANNEL
#include "imc_datatype.hpp"
#include "imc_conversion.hpp"
#include "imc_block.hpp"
#include <sstream>
#include <math.h>
#include <chrono>
#include <ctime>
#include <time.h>
#if defined(__linux__) || defined(__APPLE__)
#include <iconv.h>
#elif defined(__WIN32__) || defined(_WIN32)
#define timegm _mkgmtime
#endif
//---------------------------------------------------------------------------//
namespace imc
{
struct component_env
{
std::string uuid_;
// required channel components for CG channels only
std::string CCuuid_, CPuuid_;
// optional channel components for CG channels only
std::string CDuuid_, NTuuid_;
std::string Cbuuid_, CRuuid_;
// reset all members
void reset()
{
uuid_.clear();
CCuuid_.clear();
CPuuid_.clear();
CDuuid_.clear();
Cbuuid_.clear();
CRuuid_.clear();
NTuuid_.clear();
}
};
// collect uuid's of blocks required for full channel reconstruction
struct channel_env
{
// define unique identifer for channel_env
std::string uuid_;
// collect common affiliate blocks for every channel
std::string NOuuid_, NLuuid_;
// collect affiliate blocks for a single channel
// channel types
std::string CBuuid_, CGuuid_, CIuuid_, CTuuid_;
std::string CNuuid_, CDuuid_, NTuuid_;
std::string CSuuid_;
component_env compenv1_;
component_env compenv2_;
// reset all members
void reset()
{
uuid_.clear();
NOuuid_.clear();
NLuuid_.clear();
CBuuid_.clear();
CGuuid_.clear();
CIuuid_.clear();
CTuuid_.clear();
CNuuid_.clear();
CDuuid_.clear();
NTuuid_.clear();
CSuuid_.clear();
compenv1_.reset();
compenv2_.reset();
}
// get info
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"uuid:"<<uuid_<<"\n"
<<std::setw(width)<<std::left<<"NOuuid:"<<NOuuid_<<"\n"
<<std::setw(width)<<std::left<<"NLuuid:"<<NLuuid_<<"\n"
//
<<std::setw(width)<<std::left<<"CBuuid:"<<CBuuid_<<"\n"
<<std::setw(width)<<std::left<<"CGuuid:"<<CGuuid_<<"\n"
<<std::setw(width)<<std::left<<"CIuuid:"<<CIuuid_<<"\n"
<<std::setw(width)<<std::left<<"CTuuid:"<<CTuuid_<<"\n"
<<std::setw(width)<<std::left<<"CNuuid:"<<CNuuid_<<"\n"
//
<<std::setw(width)<<std::left<<"CCuuid:"<<compenv1_.CCuuid_<<"\n"
<<std::setw(width)<<std::left<<"CPuuid:"<<compenv1_.CPuuid_<<"\n"
//
<<std::setw(width)<<std::left<<"CDuuid:"<<compenv1_.CDuuid_<<"\n"
<<std::setw(width)<<std::left<<"Cbuuid:"<<compenv1_.Cbuuid_<<"\n"
<<std::setw(width)<<std::left<<"CRuuid:"<<compenv1_.CRuuid_<<"\n"
<<std::setw(width)<<std::left<<"NTuuid:"<<compenv1_.NTuuid_<<"\n"
<<std::setw(width)<<std::left<<"CSuuid:"<<CSuuid_<<"\n";
return ss.str();
}
// get JSON info string
std::string get_json()
{
std::stringstream ss;
ss<<"{"<<"\"uuid\":\""<<uuid_
<<"\",\"NOuuid\":\""<<NOuuid_
<<"\",\"NLuuid\":\""<<NLuuid_
<<"\",\"CBuuid\":\""<<CBuuid_
<<"\",\"CGuuid\":\""<<CGuuid_
<<"\",\"CIuuid\":\""<<CIuuid_
<<"\",\"CTuuid\":\""<<CTuuid_
<<"\",\"CNuuid\":\""<<CNuuid_
<<"\",\"CCuuid\":\""<<compenv1_.CCuuid_
<<"\",\"CPuuid\":\""<<compenv1_.CPuuid_
<<"\",\"CDuuid\":\""<<compenv1_.CDuuid_
<<"\",\"Cbuuid\":\""<<compenv1_.Cbuuid_
<<"\",\"CRuuid\":\""<<compenv1_.CRuuid_
<<"\",\"NTuuid\":\""<<compenv1_.NTuuid_
<<"\",\"CSuuid\":\""<<CSuuid_
<<"\"}";
return ss.str();
}
};
// adjust stream object
void customize_stream(std::ostream& stout, int prec, bool fixed)
{
if ( fixed )
{
stout<<std::setprecision(prec)<<std::fixed;
}
else
{
stout<<std::setprecision(prec);
}
}
// given a list of numeric objects, join it into a string
template<typename dt>
std::string joinvec(std::vector<dt> myvec, unsigned long int limit = 10, int prec = 10, bool fixed = true)
{
// include entire list for limit = 0
unsigned long int myvecsize = (unsigned long int)myvec.size();
limit = (limit == 0) ? myvecsize : limit;
std::stringstream ss;
ss<<"[";
if ( myvec.size() <= limit )
{
for ( dt el: myvec )
{
customize_stream(ss,prec,fixed);
ss<<el<<",";
}
}
else
{
unsigned long int heals = limit/2;
for ( unsigned long int i = 0; i < heals; i++ )
{
customize_stream(ss,prec,fixed);
ss<<myvec[i]<<",";
}
ss<<"...";
for ( unsigned long int i = myvecsize-heals; i < myvecsize; i++ )
{
customize_stream(ss,prec,fixed);
ss<<myvec[i]<<",";
}
}
std::string sumstr = ss.str();
if ( sumstr.size() > 1 ) sumstr.pop_back();
sumstr += std::string("]");
return sumstr;
}
#if defined(__linux__) || defined(__APPLE__)
// convert encoding of any descriptions, channel-names, units etc.
class iconverter
{
std::string in_enc_, out_enc_;
iconv_t cd_;
size_t out_buffer_size_;
public:
iconverter(std::string in_enc, std::string out_enc, size_t out_buffer_size = 1024) :
in_enc_(in_enc), out_enc_(out_enc), out_buffer_size_(out_buffer_size)
{
// allocate descriptor for character set conversion
// (https://man7.org/linux/man-pages/man3/iconv_open.3.html)
cd_ = iconv_open(out_enc.c_str(), in_enc.c_str());
if ( (iconv_t)-1 == cd_ )
{
if ( errno == EINVAL )
{
std::string errmsg = std::string("The encoding conversion from ") + in_enc
+ std::string(" to ") + out_enc + std::string(" is not supported by the implementation.");
throw std::runtime_error(errmsg);
}
}
}
void convert(std::string &astring)
{
if ( astring.empty() ) return;
std::vector<char> in_buffer(astring.begin(),astring.end());
char *inbuf = &in_buffer[0];
size_t inbytes = in_buffer.size();
std::vector<char> out_buffer(out_buffer_size_);
char *outbuf = &out_buffer[0];
size_t outbytes = out_buffer.size();
// perform character set conversion
// ( - https://man7.org/linux/man-pages/man3/iconv.3.html
// - https://www.ibm.com/docs/en/zos/2.2.0?topic=functions-iconv-code-conversion )
while ( inbytes > 0 )
{
size_t res = iconv(cd_,&inbuf,&inbytes,&outbuf,&outbytes);
if ( (size_t)-1 == res )
{
std::string errmsg;
if ( errno == EILSEQ )
{
errmsg = std::string("An invalid multibyte sequence is encountered in the input.");
throw std::runtime_error(errmsg);
}
else if ( errno == EINVAL )
{
errmsg = std::string("An incomplete multibyte sequence is encountered in the input")
+ std::string(" and the input byte sequence terminates after it.");
}
else if ( errno == E2BIG )
{
errmsg = std::string("The output buffer has no more room for the next converted character.");
}
throw std::runtime_error(errmsg);
}
}
std::string outstring(out_buffer.begin(),out_buffer.end()-outbytes);
astring = outstring;
}
};
#elif defined(__WIN32__) || defined(_WIN32)
class iconverter
{
public:
iconverter(std::string in_enc, std::string out_enc, size_t out_buffer_size = 1024) {}
void convert(std::string &astring) {}
};
#endif
struct component_group
{
imc::component CC_;
imc::packaging CP_;
imc::abscissa CD_;
imc::buffer Cb_;
imc::range CR_;
imc::channelobj CN_;
imc::triggertime NT_;
component_env compenv_;
// Constructor to parse the associated blocks
component_group(component_env &compenv, std::map<std::string, imc::block>* blocks, std::vector<unsigned char>* buffer)
: compenv_(compenv)
{
if (blocks->count(compenv.CCuuid_) == 1)
{
CC_.parse(buffer, blocks->at(compenv.CCuuid_).get_parameters());
}
if (blocks->count(compenv.CPuuid_) == 1)
{
CP_.parse(buffer, blocks->at(compenv.CPuuid_).get_parameters());
}
if (blocks->count(compenv.CDuuid_) == 1)
{
CD_.parse(buffer, blocks->at(compenv.CDuuid_).get_parameters());
}
if (blocks->count(compenv.Cbuuid_) == 1)
{
Cb_.parse(buffer, blocks->at(compenv.Cbuuid_).get_parameters());
}
if (blocks->count(compenv.CRuuid_) == 1)
{
CR_.parse(buffer, blocks->at(compenv.CRuuid_).get_parameters());
}
if (blocks->count(compenv.NTuuid_) == 1)
{
NT_.parse(buffer, blocks->at(compenv.NTuuid_).get_parameters());
}
}
};
// channel
struct channel
{
// associated environment of blocks and map of blocks
channel_env chnenv_;
std::map<std::string,imc::block>* blocks_;
std::vector<unsigned char>* buffer_;
imc::origin_data NO_;
imc::language NL_;
imc::text CT_;
imc::groupobj CB_;
imc::datafield CG_;
imc::channelobj CN_;
// collect meta-data of channels according to env,
// just everything valueable in here
// TODO: is this necessary?
std::string uuid_;
std::string name_, comment_;
std::string origin_, origin_comment_, text_;
std::chrono::system_clock::time_point trigger_time_, absolute_trigger_time_;
double trigger_time_frac_secs_;
std::string language_code_, codepage_;
std::string yname_, yunit_;
std::string xname_, xunit_;
double xstepwidth_, xstart_;
int xprec_;
int dimension_;
// buffer and data
int xsignbits_, xnum_bytes_;
int ysignbits_, ynum_bytes_;
// unsigned long int byte_offset_;
unsigned long int xbuffer_offset_, ybuffer_offset_;
unsigned long int xbuffer_size_, ybuffer_size_;
long int addtime_;
imc::numtype xdatatp_, ydatatp_;
std::vector<imc::datatype> xdata_, ydata_;
// range, factor and offset
double xfactor_, yfactor_;
double xoffset_, yoffset_;
// group reference the channel belongs to
unsigned long int group_index_;
std::string group_uuid_, group_name_, group_comment_;
// constructor takes channel's block environment
channel(channel_env &chnenv, std::map<std::string,imc::block>* blocks,
std::vector<unsigned char>* buffer):
chnenv_(chnenv), blocks_(blocks), buffer_(buffer),
xfactor_(1.), yfactor_(1.), xoffset_(0.), yoffset_(0.),
group_index_(-1)
{
// use uuid from CN block
uuid_ = chnenv_.CNuuid_;
// extract associated NO data
if ( blocks_->count(chnenv_.NOuuid_) == 1 )
{
NO_.parse(buffer_, blocks_->at(chnenv_.NOuuid_).get_parameters());
origin_ = NO_.generator_;
comment_ = NO_.comment_;
}
// extract associated NL data
if ( blocks_->count(chnenv_.NLuuid_) == 1 )
{
NL_.parse(buffer_, blocks_->at(chnenv_.NLuuid_).get_parameters());
codepage_ = NL_.codepage_;
language_code_ = NL_.language_code_;
}
// extract associated CB data
if ( blocks_->count(chnenv_.CBuuid_) == 1 )
{
CB_.parse(buffer_, blocks_->at(chnenv_.CBuuid_).get_parameters());
}
// extract associated CT data
if ( blocks_->count(chnenv_.CTuuid_) == 1 )
{
CT_.parse(buffer_, blocks_->at(chnenv_.CTuuid_).get_parameters());
text_ = CT_.name_ + std::string(" - ")
+ CT_.text_ + std::string(" - ")
+ CT_.comment_;
}
// extract associated CN data
if ( blocks_->count(chnenv_.CNuuid_) == 1 )
{
CN_.parse(buffer_, blocks_->at(chnenv_.CNuuid_).get_parameters());
group_index_ = CN_.group_index_;
group_name_ = CN_.name_;
group_comment_ = CN_.comment_;
}
if ( !chnenv_.compenv1_.uuid_.empty() && chnenv_.compenv2_.uuid_.empty() )
{
// normal dataset (single component)
// set common NT and CD keys if no others are specified
if (chnenv_.compenv1_.NTuuid_.empty()) chnenv_.compenv1_.NTuuid_ = chnenv_.NTuuid_;
if (chnenv_.compenv1_.CDuuid_.empty()) chnenv_.compenv1_.CDuuid_ = chnenv_.CDuuid_;
// comp_group1 contains y-data, x-data is based on xstepwidth_, xstart_ and the length of y-data
component_group comp_group1(chnenv_.compenv1_, blocks_, buffer_);
dimension_ = 1;
xstepwidth_ = comp_group1.CD_.dx_;
xunit_ = comp_group1.CD_.unit_;
ybuffer_offset_ = comp_group1.Cb_.offset_buffer_;
ybuffer_size_ = comp_group1.Cb_.number_bytes_;
xstart_ = comp_group1.Cb_.x0_;
yfactor_ = comp_group1.CR_.factor_;
yoffset_ = comp_group1.CR_.offset_;
yunit_ = comp_group1.CR_.unit_;
name_ = comp_group1.CN_.name_;
yname_ = comp_group1.CN_.name_;
comment_ = comp_group1.CN_.comment_;
ynum_bytes_ = comp_group1.CP_.bytes_;
ydatatp_ = comp_group1.CP_.numeric_type_;
ysignbits_ = comp_group1.CP_.signbits_;
// generate std::chrono::system_clock::time_point type
std::time_t ts = timegm(&comp_group1.NT_.tms_); // std::mktime(&tms);
trigger_time_ = std::chrono::system_clock::from_time_t(ts);
trigger_time_frac_secs_ = comp_group1.NT_.trigger_time_frac_secs_;
// calculate absolute trigger-time
addtime_ = static_cast<long int>(comp_group1.Cb_.add_time_);
absolute_trigger_time_ = trigger_time_ + std::chrono::seconds(addtime_);
// + std::chrono::nanoseconds((long int)(trigger_time_frac_secs_*1.e9));
}
else if ( !chnenv_.compenv1_.uuid_.empty() && !chnenv_.compenv2_.uuid_.empty() )
{
// XY dataset (two components)
// set common NT and CD keys if no others are specified
if (chnenv_.compenv1_.NTuuid_.empty()) chnenv_.compenv1_.NTuuid_ = chnenv_.NTuuid_;
if (chnenv_.compenv1_.CDuuid_.empty()) chnenv_.compenv1_.CDuuid_ = chnenv_.CDuuid_;
if (chnenv_.compenv2_.NTuuid_.empty()) chnenv_.compenv2_.NTuuid_ = chnenv_.NTuuid_;
if (chnenv_.compenv2_.CDuuid_.empty()) chnenv_.compenv2_.CDuuid_ = chnenv_.CDuuid_;
// comp_group1 contains x-data, comp_group2 contains y-data
component_group comp_group1(chnenv_.compenv1_, blocks_, buffer_);
component_group comp_group2(chnenv_.compenv2_, blocks_, buffer_);
dimension_ = 2;
xbuffer_offset_ = comp_group2.Cb_.offset_buffer_;
xbuffer_size_ = comp_group2.Cb_.number_bytes_;
ybuffer_offset_ = comp_group1.Cb_.offset_buffer_;
ybuffer_size_ = comp_group1.Cb_.number_bytes_;
xfactor_ = comp_group2.CR_.factor_;
xoffset_ = comp_group2.CR_.offset_;
yfactor_ = comp_group1.CR_.factor_;
yoffset_ = comp_group1.CR_.offset_;
xdatatp_ = comp_group2.CP_.numeric_type_;
xsignbits_ = comp_group2.CP_.signbits_;
ydatatp_ = comp_group1.CP_.numeric_type_;
ysignbits_ = comp_group1.CP_.signbits_;
// generate std::chrono::system_clock::time_point type
std::time_t ts = timegm(&comp_group2.NT_.tms_); // std::mktime(&tms);
trigger_time_ = std::chrono::system_clock::from_time_t(ts);
trigger_time_frac_secs_ = comp_group2.NT_.trigger_time_frac_secs_;
absolute_trigger_time_ = trigger_time_;
}
else
{
// no datafield
}
// start converting binary buffer to imc::datatype
if ( !chnenv_.CSuuid_.empty() ) convert_buffer();
// convert any non-UTF-8 codepage to UTF-8 and cleanse any text
convert_encoding();
cleanse_text();
}
// convert buffer to actual datatype
void convert_buffer()
{
std::vector<imc::parameter> prms = blocks_->at(chnenv_.CSuuid_).get_parameters();
if ( prms.size() < 4)
{
throw std::runtime_error("CS block is invalid and features to few parameters");
}
// extract (channel dependent) part of buffer
unsigned long int buffstrt = prms[3].begin();
std::vector<unsigned char> yCSbuffer( buffer_->begin()+buffstrt+ybuffer_offset_+1,
buffer_->begin()+buffstrt+ybuffer_offset_+ybuffer_size_+1 );
// determine number of values in buffer
unsigned long int ynum_values = (unsigned long int)(yCSbuffer.size()/(ysignbits_/8));
if ( ynum_values*(ysignbits_/8) != yCSbuffer.size() )
{
throw std::runtime_error("CSbuffer and significant bits of y datatype don't match");
}
if (dimension_ == 1)
{
// process y-data
process_data(ydata_, ynum_values, ydatatp_, yCSbuffer);
// find appropriate precision for "xdata_" by means of "xstepwidth_"
xprec_ = (xstepwidth_ > 0 ) ? (int)ceil(fabs(log10(xstepwidth_))) : 10;
// fill xdata_
for ( unsigned long int i = 0; i < ynum_values; i++ )
{
xdata_.push_back(xstart_+(double)i*xstepwidth_);
}
}
else if (dimension_ == 2)
{
// process x- and y-data
std::vector<unsigned char> xCSbuffer( buffer_->begin()+buffstrt+xbuffer_offset_+1,
buffer_->begin()+buffstrt+xbuffer_offset_+xbuffer_size_+1 );
// determine number of values in buffer
unsigned long int xnum_values = (unsigned long int)(xCSbuffer.size()/(xsignbits_/8));
if ( xnum_values*(xsignbits_/8) != xCSbuffer.size() )
{
throw std::runtime_error("CSbuffer and significant bits of x datatype don't match");
}
if ( xnum_values != ynum_values )
{
throw std::runtime_error("x and y data have different number of values");
}
xprec_ = 9;
process_data(xdata_, xnum_values, xdatatp_, xCSbuffer);
process_data(ydata_, ynum_values, ydatatp_, yCSbuffer);
}
else
{
throw std::runtime_error("unsupported dimension");
}
transformData(xdata_, xfactor_, xoffset_);
transformData(ydata_, yfactor_, yoffset_);
}
// handle data type conversion
void process_data(std::vector<imc::datatype>& data_, size_t num_values, numtype datatp_, std::vector<unsigned char>& CSbuffer)
{
// adjust size of data
data_.resize(num_values);
// handle data type conversion
switch (datatp_)
{
case numtype::unsigned_byte:
imc::convert_data_to_type<imc_Ubyte>(CSbuffer, data_);
break;
case numtype::signed_byte:
imc::convert_data_to_type<imc_Sbyte>(CSbuffer, data_);
break;
case numtype::unsigned_short:
imc::convert_data_to_type<imc_Ushort>(CSbuffer, data_);
break;
case numtype::signed_short:
imc::convert_data_to_type<imc_Sshort>(CSbuffer, data_);
break;
case numtype::unsigned_long:
imc::convert_data_to_type<imc_Ulongint>(CSbuffer, data_);
break;
case numtype::signed_long:
imc::convert_data_to_type<imc_Slongint>(CSbuffer, data_);
break;
case numtype::ffloat:
imc::convert_data_to_type<imc_float>(CSbuffer, data_);
break;
case numtype::ddouble:
imc::convert_data_to_type<imc_double>(CSbuffer, data_);
break;
case numtype::two_byte_word_digital:
imc::convert_data_to_type<imc_digital>(CSbuffer, data_);
break;
case numtype::six_byte_unsigned_long:
imc::convert_data_to_type<imc_sixbyte>(CSbuffer, data_);
break;
default:
throw std::runtime_error(std::string("unsupported/unknown datatype ") + std::to_string(datatp_));
}
}
void transformData(std::vector<imc::datatype>& data, double factor, double offset) {
if (factor != 1.0 || offset != 0.0) {
for (imc::datatype& el : data) {
double fact = (factor == 0.0) ? 1.0 : factor;
el = imc::datatype(el.as_double() * fact + offset);
}
}
}
// convert any description, units etc. to UTF-8 (by default)
void convert_encoding()
{
if ( !codepage_.empty() )
{
// construct iconv-compatible name for respective codepage
std::string cpn = std::string("CP") + codepage_;
// set up converter
std::string utf = std::string("UTF-8");
iconverter conv(cpn,utf);
conv.convert(name_);
conv.convert(comment_);
conv.convert(origin_);
conv.convert(origin_comment_);
conv.convert(text_);
conv.convert(language_code_);
conv.convert(yname_);
conv.convert(yunit_);
conv.convert(xname_);
conv.convert(xunit_);
conv.convert(group_name_);
conv.convert(group_comment_);
}
}
void cleanse_text()
{
escape_backslash(name_);
escape_backslash(comment_);
escape_backslash(origin_);
escape_backslash(origin_comment_);
escape_backslash(text_);
escape_backslash(language_code_);
escape_backslash(yname_);
escape_backslash(yunit_);
escape_backslash(xname_);
escape_backslash(xunit_);
escape_backslash(group_name_);
escape_backslash(group_comment_);
}
void escape_backslash(std::string &text)
{
char backslash = 0x5c;
std::string doublebackslash("\\\\");
for ( std::string::iterator it = text.begin(); it != text.end(); ++it )
{
if ( int(*it) == backslash ) {
text.replace(it,it+1,doublebackslash);
++it;
}
}
}
// get info string
std::string get_info(int width = 20)
{
// prepare printable trigger-time
std::time_t tt = std::chrono::system_clock::to_time_t(trigger_time_);
std::time_t att = std::chrono::system_clock::to_time_t(absolute_trigger_time_);
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"uuid:"<<uuid_<<"\n"
<<std::setw(width)<<std::left<<"name:"<<name_<<"\n"
<<std::setw(width)<<std::left<<"comment:"<<comment_<<"\n"
<<std::setw(width)<<std::left<<"origin:"<<origin_<<"\n"
<<std::setw(width)<<std::left<<"origin-comment:"<<origin_comment_<<"\n"
<<std::setw(width)<<std::left<<"description:"<<text_<<"\n"
<<std::setw(width)<<std::left<<"trigger-time-nt:"<<std::put_time(std::gmtime(&tt),"%FT%T")<<"\n"
<<std::setw(width)<<std::left<<"trigger-time:"<<std::put_time(std::gmtime(&att),"%FT%T")<<"\n"
<<std::setw(width)<<std::left<<"language-code:"<<language_code_<<"\n"
<<std::setw(width)<<std::left<<"codepage:"<<codepage_<<"\n"
<<std::setw(width)<<std::left<<"yname:"<<yname_<<"\n"
<<std::setw(width)<<std::left<<"yunit:"<<yunit_<<"\n"
<<std::setw(width)<<std::left<<"datatype:"<<ydatatp_<<"\n"
<<std::setw(width)<<std::left<<"significant bits:"<<ysignbits_<<"\n"
<<std::setw(width)<<std::left<<"buffer-offset:"<<ybuffer_offset_<<"\n"
<<std::setw(width)<<std::left<<"buffer-size:"<<ybuffer_size_<<"\n"
<<std::setw(width)<<std::left<<"xname:"<<xname_<<"\n"
<<std::setw(width)<<std::left<<"xunit:"<<xunit_<<"\n"
<<std::setw(width)<<std::left<<"xstepwidth:"<<xstepwidth_<<"\n"
<<std::setw(width)<<std::left<<"xoffset:"<<xstart_<<"\n"
<<std::setw(width)<<std::left<<"factor:"<<yfactor_<<"\n"
<<std::setw(width)<<std::left<<"offset:"<<yoffset_<<"\n"
<<std::setw(width)<<std::left<<"group:"<<"("<<group_index_<<","<<group_name_
<<","<<group_comment_<<")"<<"\n"
<<std::setw(width)<<std::left<<"ydata:"<<imc::joinvec<imc::datatype>(ydata_,6,9,true)<<"\n"
<<std::setw(width)<<std::left<<"xdata:"<<imc::joinvec<imc::datatype>(xdata_,6,xprec_,true)<<"\n";
// <<std::setw(width)<<std::left<<"aff. blocks:"<<chnenv_.get_json()<<"\n";
return ss.str();
}
// provide JSON string of metadata
std::string get_json(bool include_data = false)
{
// prepare printable trigger-time
std::time_t tt = std::chrono::system_clock::to_time_t(trigger_time_);
std::time_t att = std::chrono::system_clock::to_time_t(absolute_trigger_time_);
std::stringstream ss;
ss<<"{"<<"\"uuid\":\""<<uuid_
<<"\",\"name\":\""<<name_
<<"\",\"comment\":\""<<comment_
<<"\",\"origin\":\""<<origin_
<<"\",\"origin-comment\":\""<<origin_comment_
<<"\",\"description\":\""<<text_
<<"\",\"trigger-time-nt\":\""<<std::put_time(std::gmtime(&tt),"%FT%T")
<<"\",\"trigger-time\":\""<<std::put_time(std::gmtime(&att),"%FT%T")
<<"\",\"language-code\":\""<<language_code_
<<"\",\"codepage\":\""<<codepage_
<<"\",\"yname\":\""<<prepjsonstr(yname_)
<<"\",\"yunit\":\""<<prepjsonstr(yunit_)
<<"\",\"significantbits\":\""<<ysignbits_
<<"\",\"buffer-size\":\""<<ybuffer_size_
<<"\",\"xname\":\""<<prepjsonstr(xname_)
<<"\",\"xunit\":\""<<prepjsonstr(xunit_)
<<"\",\"xstepwidth\":\""<<xstepwidth_
<<"\",\"xoffset\":\""<<xstart_
<<"\",\"group\":{"<<"\"index\":\""<<group_index_
<<"\",\"name\":\""<<group_name_
<<"\",\"comment\":\""<<group_comment_<<"\""<<"}";
if ( include_data )
{
ss<<",\"ydata\":"<<imc::joinvec<imc::datatype>(ydata_,0,9,true)
<<",\"xdata\":"<<imc::joinvec<imc::datatype>(xdata_,0,xprec_,true);
}
// ss<<"\",\"aff. blocks\":\""<<chnenv_.get_json()
ss<<"}";
return ss.str();
}
// prepare string value for usage in JSON dump
std::string prepjsonstr(std::string value)
{
std::stringstream ss;
ss<<quoted(value);
return strip_quotes(ss.str());
}
// remove any leading or trailing double quotes
std::string strip_quotes(std::string astring)
{
// head
if ( astring.front() == '"' ) astring.erase(astring.begin()+0);
// tail
if ( astring.back() == '"' ) astring.erase(astring.end()-1);
return astring;
}
// print channel
void print(std::string filename, const char sep = ',', int width = 25, int yprec = 9)
{
std::ofstream fou(filename);
// header
if ( sep == ' ' )
{
fou<<std::setw(width)<<std::left<<xname_
<<std::setw(width)<<std::left<<yname_<<"\n"
<<std::setw(width)<<std::left<<xunit_
<<std::setw(width)<<std::left<<yunit_<<"\n";
}
else
{
fou<<xname_<<sep<<yname_<<"\n"<<xunit_<<sep<<yunit_<<"\n";
}
for ( unsigned long int i = 0; i < xdata_.size(); i++ )
{
if ( sep == ' ' )
{
fou<<std::setprecision(xprec_)<<std::fixed
<<std::setw(width)<<std::left<<xdata_[i]
<<std::setprecision(yprec)<<std::fixed
<<std::setw(width)<<std::left<<ydata_[i]<<"\n";
}
else
{
fou<<std::setprecision(xprec_)<<std::fixed<<xdata_[i]
<<sep
<<std::setprecision(yprec)<<std::fixed<<ydata_[i]<<"\n";
}
}
fou.close();
}
};
}
#endif
//---------------------------------------------------------------------------//

51
lib/imc_conversion.hpp Normal file
View File

@ -0,0 +1,51 @@
//---------------------------------------------------------------------------//
#ifndef IMCCONVERSION
#define IMCCONVERSION
#include <vector>
//---------------------------------------------------------------------------//
namespace imc
{
// convert raw data in buffer into specific datatype
template<typename datatype>
void convert_data_to_type(std::vector<unsigned char>& subbuffer,
std::vector<imc::datatype>& channel)
{
// check number of elements of type "datatype" in buffer
if ( subbuffer.size() != channel.size()*sizeof(datatype) )
{
throw std::runtime_error( std::string("size mismatch between subbuffer (")
+ std::to_string(subbuffer.size())
+ std::string(") and datatype (")
+ std::to_string(channel.size()) + std::string("*")
+ std::to_string(sizeof(datatype)) + std::string(")") );
}
// extract every single number of type "datatype" from buffer
for ( unsigned long int i = 0; i < channel.size(); i++ )
{
// declare number of required type and point it to first byte in buffer
// representing the number
datatype df;
uint8_t* dfcast = reinterpret_cast<uint8_t*>(&df);
for ( unsigned long int j = 0; j < sizeof(datatype); j++ )
{
dfcast[j] = (int)subbuffer[i*sizeof(datatype)+j];
}
// save number in channel
channel[i] = df;
}
// for ( auto el: channel ) std::cout<<el<<"\n";
}
}
#endif
//---------------------------------------------------------------------------//

232
lib/imc_datatype.hpp Normal file
View File

@ -0,0 +1,232 @@
//---------------------------------------------------------------------------//
#ifndef IMCDATATYPE
#define IMCDATATYPE
//---------------------------------------------------------------------------//
namespace imc
{
// map datatype to machine's datatypes
typedef unsigned char imc_Ubyte;
typedef signed char imc_Sbyte;
//
typedef unsigned short imc_Ushort;
typedef signed short imc_Sshort;
//
// e.g. ARM Cortex-A72 armv7l gcc version 10.2.0 (Ubuntu 10.2.0-13ubuntu1)
// #ifdef __arm__
// typedef unsigned long int imc_Ulongint;
// typedef signed long int imc_Slongint;
// e.g. Intel(R) Core(TM) i7-3520M CPU @ 2.90GHz x86_64 gcc version 10.2.0 (Ubuntu 10.2.0-13ubuntu1)
// #ifdef i386 __i386 __i386__
typedef unsigned int imc_Ulongint;
typedef signed int imc_Slongint;
//
typedef float imc_float;
typedef double imc_double;
//
// TODO not all remaining types are supported yet
// typedef <whatever that is ->... > "imc Devices Transitional Recording"
// typedf <sometimestamptype> "Timestamp Ascii"
typedef char16_t imc_digital;
//
typedef struct {
unsigned char bytes[6];
} imc_sixbyte;
class datatype
{
protected:
imc_Ubyte ubyte_; // 0
imc_Sbyte sbyte_; // 1
imc_Ushort ushort_; // 2
imc_Sshort sshort_; // 3
imc_Ulongint ulint_; // 4
imc_Slongint slint_; // 5
imc_float sfloat_; // 6
imc_double sdouble_; // 7
imc_digital sdigital_; // 10
imc_sixbyte sixbyte_; // 13
short int dtidx_; // \in \{0,...,7,10,13\}
public:
datatype(): ubyte_(0), sbyte_(0),
ushort_(0), sshort_(0),
ulint_(0), slint_(0),
sfloat_(0.0), sdouble_(0.0),
sdigital_(0), sixbyte_({0}),
dtidx_(0) { };
// every supported datatype gets its own constructor
datatype(imc_Ubyte num): ubyte_(num), dtidx_(0) {};
datatype(imc_Sbyte num): sbyte_(num), dtidx_(1) {};
datatype(imc_Ushort num): ushort_(num), dtidx_(2) {};
datatype(imc_Sshort num): sshort_(num), dtidx_(3) {};
datatype(imc_Ulongint num): ulint_(num), dtidx_(4) {};
datatype(imc_Slongint num): slint_(num), dtidx_(5) {};
datatype(imc_float num): sfloat_(num), dtidx_(6) {};
datatype(imc_double num): ubyte_(0), sbyte_(0), ushort_(0), sshort_(0),
ulint_(0), slint_(0), sfloat_(0.0), sdouble_(num),
sdigital_(0), sixbyte_({0}), dtidx_(7) {};
datatype(imc_digital num): ubyte_(0), sbyte_(0), ushort_(0), sshort_(0),
ulint_(0), slint_(0), sfloat_(0.0), sdouble_(0.0),
sdigital_(num), sixbyte_({0}), dtidx_(10) {};
datatype(imc_sixbyte num): ubyte_(0), sbyte_(0), ushort_(0), sshort_(0),
ulint_(0), slint_(0), sfloat_(0.0), sdouble_(0.0),
sdigital_(0), sixbyte_(num), dtidx_(13) {};
// identify type
short int& dtype() { return dtidx_; }
// copy constructor
datatype(const datatype &num)
{
this->ubyte_ = num.ubyte_;
this->sbyte_ = num.sbyte_;
this->ushort_ = num.ushort_;
this->sshort_ = num.sshort_;
this->ulint_ = num.ulint_;
this->slint_ = num.slint_;
this->sfloat_ = num.sfloat_;
this->sdouble_ = num.sdouble_;
this->sdigital_ = num.sdigital_;
this->sixbyte_ = num.sixbyte_;
this->dtidx_ = num.dtidx_;
}
// overall assignment operator
datatype& operator=(const datatype &num)
{
if ( this != &num )
{
this->ubyte_ = num.ubyte_;
this->sbyte_ = num.sbyte_;
this->ushort_ = num.ushort_;
this->sshort_ = num.sshort_;
this->ulint_ = num.ulint_;
this->slint_ = num.slint_;
this->sfloat_ = num.sfloat_;
this->sdouble_ = num.sdouble_;
this->sdigital_ = num.sdigital_;
this->sixbyte_ = num.sixbyte_;
this->dtidx_ = num.dtidx_;
}
return *this;
}
// implement assignment operator for individual datatypes
datatype& operator=(const imc_Ubyte &num)
{
this->ubyte_ = num;
this->dtidx_ = 0;
return *this;
}
datatype& operator=(const imc_Sbyte &num)
{
this->sbyte_ = num;
this->dtidx_ = 1;
return *this;
}
datatype& operator=(const imc_Ushort &num)
{
this->ushort_ = num;
this->dtidx_ = 2;
return *this;
}
datatype& operator=(const imc_Sshort &num)
{
this->sshort_ = num;
this->dtidx_ = 3;
return *this;
}
datatype& operator=(const imc_Ulongint &num)
{
this->ulint_ = num;
this->dtidx_ = 4;
return *this;
}
datatype& operator=(const imc_Slongint &num)
{
this->slint_ = num;
this->dtidx_ = 5;
return *this;
}
datatype& operator=(const imc_float &num)
{
this->sfloat_ = num;
this->dtidx_ = 6;
return *this;
}
datatype& operator=(const imc_double &num)
{
this->sdouble_ = num;
this->dtidx_ = 7;
return *this;
}
datatype& operator=(const imc_digital &num)
{
this->sdigital_ = num;
this->dtidx_ = 10;
return *this;
}
datatype& operator=(const imc_sixbyte &num)
{
this->sixbyte_ = num;
this->dtidx_ = 13;
return *this;
}
// obtain number as double
double as_double()
{
double num = 0.0;
if ( dtidx_ == 0 ) num = (double)ubyte_;
else if ( dtidx_ == 1 ) num = (double)sbyte_;
else if ( dtidx_ == 2 ) num = (double)ushort_;
else if ( dtidx_ == 3 ) num = (double)sshort_;
else if ( dtidx_ == 4 ) num = (double)ulint_;
else if ( dtidx_ == 5 ) num = (double)slint_;
else if ( dtidx_ == 6 ) num = (double)sfloat_;
else if ( dtidx_ == 7 ) num = (double)sdouble_;
else if ( dtidx_ == 10 ) num = static_cast<double>(sdigital_);
else if ( dtidx_ == 13 ) {
unsigned long long value = 0;
for (int i = 0; i < 6; ++i) {
value |= static_cast<unsigned long long>(sixbyte_.bytes[i]) << (8 * i);
}
num = static_cast<double>(value);
}
return num;
}
// define custom stream operator to print the correct type
friend std::ostream& operator<<(std::ostream& out, const datatype& num)
{
if ( num.dtidx_ == 0 ) out<<num.ubyte_;
else if ( num.dtidx_ == 1 ) out<<num.sbyte_;
else if ( num.dtidx_ == 2 ) out<<num.ushort_;
else if ( num.dtidx_ == 3 ) out<<num.sshort_;
else if ( num.dtidx_ == 4 ) out<<num.ulint_;
else if ( num.dtidx_ == 5 ) out<<num.slint_;
else if ( num.dtidx_ == 6 ) out<<num.sfloat_;
else if ( num.dtidx_ == 7 ) out<<num.sdouble_;
else if ( num.dtidx_ == 10 ) out<<static_cast<double>(num.sdigital_);
else if ( num.dtidx_ == 13 ) {
unsigned long long value = 0;
for (int i = 0; i < 6; ++i) {
value |= static_cast<unsigned long long>(num.sixbyte_.bytes[i]) << (8 * i);
}
out<<static_cast<double>(value);
}
return out;
}
};
}
#endif
//---------------------------------------------------------------------------//

136
lib/imc_key.hpp Normal file
View File

@ -0,0 +1,136 @@
//---------------------------------------------------------------------------//
#ifndef IMCKEY
#define IMCKEY
#include <iomanip>
#include <map>
#include <string>
#include <sstream>
#include <vector>
//---------------------------------------------------------------------------//
namespace imc
{
// define "magic bytes" announcing critical (=C) non-critical keys (=N)
const unsigned char key_crit_ = 0x43, key_non_crit_ = 0x4e;
// define properties of marker/key
struct key
{
// (non)critical key
bool critical_;
// name of key (two uppercase letters)
std::string name_;
// short description
std::string description_;
// version of marker
int version_;
// constructor
key(bool critical, std::string name,
std::string description = std::string(""), int version = -1)
{
critical_ = critical;
if ( name.size() != 2 ) throw std::logic_error("invalid key name");
name_ = name;
description_ = description;
version_ = version;
}
// comparison operator
bool operator==(const key& akey)
{
return ( this->critical_ == akey.critical_
&& this->name_ == akey.name_
&& this->description_ == akey.description_
&& this->version_ == akey.version_ );
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"critical:"<<(critical_?"yes":"no")<<"\n"
<<std::setw(width)<<std::left<<"name:"<<name_<<"\n"
<<std::setw(width)<<std::left<<"description:"<<description_<<"\n"
<<std::setw(width)<<std::left<<"version:"<<version_<<"\n";
return ss.str();
}
};
const std::vector<key> keys = {
// critical keys
key(true,"CF","format version and processor",2),
key(true,"CK","start of group of keys",1),
key(true,"CB","group of channels",1),
key(true,"CT","text definition",1),
key(true,"CG","group of components",1),
key(true,"CD","abscissa description",1),
key(true,"CD","abscissa description",2),
key(true,"CZ","scaling of z-axis",1),
key(true,"CC","start of component",1),
key(true,"CP","buffer, datatype and samples of component",1),
key(true,"Cb","buffer description",1),
key(true,"CR","permissible range of values in component",1),
key(true,"CN","name and comment of channel",1),
key(true,"CS","raw binary data",1),
key(true,"CI","single numerical value",1),
key(true,"Ca","add reference key",1),
// noncritical keys
key(false,"NO","origin of data",1),
key(false,"NT","timestamp of trigger",1),
key(false,"NT","timestamp of trigger",2),
key(false,"ND","(color) display properties",1),
key(false,"NU","user defined key",1),
key(false,"Np","property of channel",1),
key(false,"NE","extraction rule for BUS channels",1),
key(false,"NL","language info and code page",1)
};
// check for existence of specific key
bool check_key(key& mykey)
{
for ( key ky: keys ) if ( mykey == ky ) return true;
return false;
}
// get key (with respect to name and evtl. version)
key get_key(bool critical, std::string name, int version = -1)
{
// check validity of required key name
if ( name.size() > 2 || name.size() < 1 )
{
throw std::runtime_error(std::string("invalid key name: ") + name);
}
// declare new key with available data
key mykey(critical,name,std::string(""),version);
// try to find matching key in list of predefined keys
for ( key ky: keys )
{
if ( critical == ky.critical_ && name == ky.name_
&& ( version == ky.version_ || version == -1 ) )
{
mykey = ky;
// provide first match
return mykey;
}
}
return mykey;
}
}
#endif
//---------------------------------------------------------------------------//

703
lib/imc_object.hpp Normal file
View File

@ -0,0 +1,703 @@
//---------------------------------------------------------------------------//
#ifndef IMCOBJECT
#define IMCOBJECT
#include <time.h>
#include <math.h>
#include "imc_key.hpp"
//---------------------------------------------------------------------------//
namespace imc
{
// obtain specific parameters as string
std::string get_parameter(const std::vector<unsigned char>* buffer, const imc::parameter* param)
{
std::string prm("");
for ( unsigned long int i = param->begin()+1; i <= param->end(); i++ )
{
prm.push_back((char)(*buffer)[i]);
}
return prm;
}
// format and processor (corresponds to key CF)
struct format
{
int fileformat_;
int processor_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 3 ) throw std::runtime_error("invalid number of parameters in CF");
fileformat_ = std::stoi(get_parameter(buffer,&parameters[0]));
processor_ = std::stoi(get_parameter(buffer,&parameters[2]));
}
format(): fileformat_(-1), processor_(-1) {}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"format:"<<fileformat_<<"\n"
<<std::setw(width)<<std::left<<"processor:"<<processor_<<"\n";
return ss.str();
}
};
// start of group of keys (corresponds to key CK)
struct keygroup
{
int version_;
int length_;
bool closed_; // corresponds to true = 1 and false = 0 in file
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 2 ) throw std::runtime_error("invalid number of parameters in CK");
version_ = std::stoi(get_parameter(buffer,&parameters[0]));
length_ = std::stoi(get_parameter(buffer,&parameters[1]));
closed_ = ( get_parameter(buffer,&parameters[3])==std::string("1") );
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"version:"<<version_<<"\n"
<<std::setw(width)<<std::left<<"length:"<<length_<<"\n"
<<std::setw(width)<<std::left<<"closed:"<<(closed_?"yes":"no")<<"\n";
return ss.str();
}
};
// group definition (corresponds to key CB)
struct groupobj
{
unsigned long int group_index_;
std::string name_;
std::string comment_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 7 ) throw std::runtime_error("invalid number of parameters in CB");
group_index_ = std::stoul(get_parameter(buffer,&parameters[2]));
name_ = get_parameter(buffer,&parameters[4]);
comment_ = get_parameter(buffer,&parameters[6]);
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"group-index:"<<group_index_<<"\n"
<<std::setw(width)<<std::left<<"name:"<<name_<<"\n"
<<std::setw(width)<<std::left<<"comment:"<<comment_<<"\n";
return ss.str();
}
};
// text definition (corresponds to key CT)
struct text
{
unsigned long int group_index_; // corresponding to group-index in CB block
std::string name_;
std::string text_;
std::string comment_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 9 ) throw std::runtime_error("invalid number of parameters in CT");
group_index_ = std::stoul(get_parameter(buffer,&parameters[2]));
name_ = get_parameter(buffer,&parameters[4]);
text_ = get_parameter(buffer,&parameters[6]);
comment_ = get_parameter(buffer,&parameters[8]);
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"group-index:"<<group_index_<<"\n"
<<std::setw(width)<<std::left<<"name:"<<name_<<"\n"
<<std::setw(width)<<std::left<<"text:"<<text_<<"\n"
<<std::setw(width)<<std::left<<"comment:"<<comment_<<"\n";
return ss.str();
}
};
enum fieldtype {
realnumber = 1, // 1
xmonotony, // 2
xy, // 3
complexrealimag, // 4
complexabsphase, // 5
complexdbphase // 6
};
// definition of data field (corresponds to key CG)
struct datafield
{
unsigned long int number_components_;
fieldtype fldtype_;
int dimension_; // corresponding to fieldtype \in {1,}
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 5 ) throw std::runtime_error("invalid number of parameters in CG");
number_components_ = std::stoul(get_parameter(buffer,&parameters[2]));
fldtype_ = (fieldtype)std::stoi(get_parameter(buffer,&parameters[3]));
dimension_ = std::stoi(get_parameter(buffer,&parameters[4]));
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"#components:"<<number_components_<<"\n"
<<std::setw(width)<<std::left<<"fieldtype:"<<fldtype_<<"\n"
<<std::setw(width)<<std::left<<"dimension:"<<dimension_<<"\n";
return ss.str();
}
};
// definition of abscissa (corresponds to key CD1)
struct abscissa
{
double dx_;
bool calibration_;
std::string unit_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 6 ) throw std::runtime_error("invalid number of parameters in CD1");
dx_ = std::stod(get_parameter(buffer,&parameters[2]));
calibration_ = ( get_parameter(buffer,&parameters[3]) == std::string("1") );
unit_ = get_parameter(buffer,&parameters[5]);
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"dx:"<<dx_<<"\n"
<<std::setw(width)<<std::left<<"calibration:"<<(calibration_?"yes":"no")<<"\n"
<<std::setw(width)<<std::left<<"unit:"<<unit_<<"\n";
return ss.str();
}
};
// definition of abscissa (corresponds to key CD2)
struct abscissa2
{
double dx_;
bool calibration_;
std::string unit_;
bool reduction_;
bool ismultievent_;
bool sortbuffer_;
double x0_;
int pretriggerapp_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 11 ) throw std::runtime_error("invalid number of parameters in CD2");
dx_ = std::stod(get_parameter(buffer,&parameters[2]));
calibration_ = ( get_parameter(buffer,&parameters[3]) == std::string("1") );
unit_ = get_parameter(buffer,&parameters[5]);
reduction_ = ( get_parameter(buffer,&parameters[6]) == std::string("1") );
ismultievent_ = ( get_parameter(buffer,&parameters[7]) == std::string("1") );
sortbuffer_ = ( get_parameter(buffer,&parameters[8]) == std::string("1") );
x0_ = std::stod(get_parameter(buffer,&parameters[9]));
pretriggerapp_ = std::stoi( get_parameter(buffer,&parameters[10]) );
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"dx:"<<dx_<<"\n"
<<std::setw(width)<<std::left<<"calibration:"<<(calibration_?"yes":"no")<<"\n"
<<std::setw(width)<<std::left<<"unit:"<<unit_<<"\n"
<<std::setw(width)<<std::left<<"reduction:"<<reduction_<<"\n"
<<std::setw(width)<<std::left<<"ismultievent:"<<ismultievent_<<"\n"
<<std::setw(width)<<std::left<<"sortbuffer:"<<sortbuffer_<<"\n"
<<std::setw(width)<<std::left<<"x0:"<<x0_<<"\n"
<<std::setw(width)<<std::left<<"pretriggerapp:"<<pretriggerapp_<<"\n";
return ss.str();
}
};
// start of component (corresponds to key CC)
struct component
{
int component_index_;
bool analog_digital_; // 1 => false (analog), 2 => true (digital)
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 4 ) throw std::runtime_error("invalid number of parameters in CC");
component_index_ = std::stoi(get_parameter(buffer,&parameters[2]));
analog_digital_ = ( std::stoi(get_parameter(buffer,&parameters[3])) == 2 );
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"index:"<<component_index_<<"\n"
<<std::setw(width)<<std::left<<"analog/digital:"<<(analog_digital_?"digital":"analog")<<"\n";
return ss.str();
}
};
enum numtype {
unsigned_byte = 1,
signed_byte,
unsigned_short,
signed_short,
unsigned_long,
signed_long,
ffloat,
ddouble,
imc_devices_transitional_recording,
timestamp_ascii,
two_byte_word_digital,
eight_byte_unsigned_long,
six_byte_unsigned_long,
eight_byte_signed_long
};
// packaging information of component (corresponds to key CP)
struct packaging
{
unsigned long int buffer_reference_;
int bytes_;
numtype numeric_type_;
int signbits_;
int mask_;
unsigned long int offset_;
unsigned long int number_subsequent_samples_;
unsigned long int distance_bytes_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 10 ) throw std::runtime_error("invalid number of parameters in CP");
buffer_reference_ = std::stoi(get_parameter(buffer,&parameters[2]));
bytes_ = std::stoi(get_parameter(buffer,&parameters[3]));
numeric_type_ = (numtype)std::stoi(get_parameter(buffer,&parameters[4]));
signbits_ = std::stoi(get_parameter(buffer,&parameters[5]));
mask_ = std::stoi(get_parameter(buffer,&parameters[6]));
offset_ = std::stoul(get_parameter(buffer,&parameters[7]));
number_subsequent_samples_ = std::stoul(get_parameter(buffer,&parameters[8]));
distance_bytes_ = std::stoul(get_parameter(buffer,&parameters[9]));
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"buffer-reference:"<<buffer_reference_<<"\n"
<<std::setw(width)<<std::left<<"datatype:"<<numeric_type_<<"\n"
<<std::setw(width)<<std::left<<"significant bits:"<<signbits_<<"\n"
<<std::setw(width)<<std::left<<"mask:"<<mask_<<"\n"
<<std::setw(width)<<std::left<<"offset:"<<offset_<<"\n"
<<std::setw(width)<<std::left<<"#subseq.-samples:"<<number_subsequent_samples_<<"\n"
<<std::setw(width)<<std::left<<"distance in bytes:"<<distance_bytes_<<"\n";
return ss.str();
}
};
// buffer description (corresponds to key Cb)
struct buffer
{
unsigned long int number_buffers_;
unsigned long int bytes_userinfo_;
// for every single buffer
unsigned long int buffer_reference_; // corresponds to buffer_reference_ in key CP
unsigned long int sample_index_; // corresponds to index of CS key
unsigned long int offset_buffer_; // number of bytes from beginning of CS key
unsigned long int number_bytes_; // number of bytes in buffer
unsigned long int offset_first_sample_;
unsigned long int number_filled_bytes_;
double x0_;
double add_time_; // start of trigger time = NT + add_time
// bool user_info_;
// bool new_event_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 13 ) throw std::runtime_error("invalid number of parameters in Cb");
number_buffers_ = std::stoul(get_parameter(buffer,&parameters[2]));
bytes_userinfo_ = std::stoul(get_parameter(buffer,&parameters[3]));
buffer_reference_ = std::stoul(get_parameter(buffer,&parameters[4]));
sample_index_ = std::stoul(get_parameter(buffer,&parameters[5]));
offset_buffer_ = std::stoul(get_parameter(buffer,&parameters[6]));
number_bytes_ = std::stoul(get_parameter(buffer,&parameters[7]));
offset_first_sample_ = std::stoul(get_parameter(buffer,&parameters[8]));
number_filled_bytes_ = std::stoul(get_parameter(buffer,&parameters[9]));
x0_ = std::stod(get_parameter(buffer,&parameters[11]));
add_time_ = std::stod(get_parameter(buffer,&parameters[12]));
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"#buffers:"<<number_buffers_<<"\n"
<<std::setw(width)<<std::left<<"bytes user info:"<<bytes_userinfo_<<"\n"
<<std::setw(width)<<std::left<<"buffer reference:"<<buffer_reference_<<"\n"
<<std::setw(width)<<std::left<<"sample index:"<<sample_index_<<"\n"
<<std::setw(width)<<std::left<<"offset buffer:"<<offset_buffer_<<"\n"
<<std::setw(width)<<std::left<<"buffer size:"<<number_bytes_<<"\n"
<<std::setw(width)<<std::left<<"offset sample:"<<offset_first_sample_<<"\n"
<<std::setw(width)<<std::left<<"#filled bytes:"<<number_filled_bytes_<<"\n"
<<std::setw(width)<<std::left<<"time offset:"<<x0_<<"\n"
<<std::setw(width)<<std::left<<"add time:"<<add_time_<<"\n";
return ss.str();
}
};
// range of values of component (corresponds to key CR)
struct range
{
bool transform_; // 1 = true: yes, requires offset + factor, 0 = false: no
double factor_, offset_; // value = raw value * factor + offset
bool calibration_; // 1 = true: calibration, 0 = false: no calibration
std::string unit_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 8 ) throw std::runtime_error("invalid number of parameters in CR");
transform_ = (get_parameter(buffer,&parameters[2]) == std::string("1"));
factor_ = std::stod(get_parameter(buffer,&parameters[3]));
offset_ = std::stod(get_parameter(buffer,&parameters[4]));
calibration_ = (get_parameter(buffer,&parameters[5]) == std::string("1"));
unit_ = get_parameter(buffer,&parameters[7]);
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"transform:"<<(transform_?"yes":"no")<<"\n"
<<std::setw(width)<<std::left<<"factor:"<<factor_<<"\n"
<<std::setw(width)<<std::left<<"offset:"<<offset_<<"\n"
<<std::setw(width)<<std::left<<"calibration:"<<(calibration_?"yes":"no")<<"\n"
<<std::setw(width)<<std::left<<"unit:"<<unit_<<"\n";
return ss.str();
}
};
// channel (corresponds to key CN)
struct channelobj
{
unsigned long int group_index_; // corresponds to group-index in CB key
bool index_bit_; // true = 1: digital, false = 0: analog
std::string name_;
std::string comment_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 9 ) throw std::runtime_error("invalid number of parameters in CN");
group_index_ = std::stoul(get_parameter(buffer,&parameters[2]));
index_bit_ = (get_parameter(buffer,&parameters[4]) == std::string("1"));
name_ = get_parameter(buffer,&parameters[6]);
comment_ = get_parameter(buffer,&parameters[8]);
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"group-index:"<<group_index_<<"\n"
<<std::setw(width)<<std::left<<"index-bit:"<<index_bit_<<"\n"
<<std::setw(width)<<std::left<<"name:"<<name_<<"\n"
<<std::setw(width)<<std::left<<"comment:"<<comment_<<"\n";
return ss.str();
}
};
// rawdata (corresponds to key CS)
struct data
{
unsigned long int index_; // starting from 1 in first CS block in file
// std::vector<unsigned char> rawdata_;
// unsigned long int begin_buffer_, end_buffer_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 4 ) throw std::runtime_error("invalid number of parameters in CS");
index_ = std::stoul(get_parameter(buffer,&parameters[2]));
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"index:"<<index_<<"\n";
// <<std::setw(width)<<std::left<<"(begin,end) buffer:"
// <<"("<<begin_buffer_<<","<<end_buffer_<<")"<<"\n";
return ss.str();
}
};
// language (corresponds to key NL)
struct language
{
std::string codepage_;
std::string language_code_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if (parameters.size() < 4) throw std::runtime_error("invalid number of parameters in NL");
codepage_ = get_parameter(buffer, &parameters[2]);
language_code_ = get_parameter(buffer, &parameters[3]);
}
};
// origin of data (corresponds to key NO)
struct origin_data
{
bool origin_; // corresponds to true = 1 ("verrechnet") and false = 0 ("Original")
std::string generator_;
std::string comment_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 7 ) throw std::runtime_error("invalid number of parameters in NO");
origin_ = ( get_parameter(buffer,&parameters[2]) == std::string("1") );
generator_ = get_parameter(buffer,&parameters[4]);
comment_ = get_parameter(buffer,&parameters[6]);
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"origin:"<<(origin_?"verrechnet":"Original")<<"\n"
<<std::setw(width)<<std::left<<"generator:"<<generator_<<"\n"
<<std::setw(width)<<std::left<<"comment:"<<comment_<<"\n";
return ss.str();
}
};
// trigger timestamp (corresponds to key NT1)
struct triggertime
{
std::tm tms_;
double trigger_time_frac_secs_;
// construct members by parsing particular parameters from buffer
void parse(const std::vector<unsigned char>* buffer, const std::vector<parameter>& parameters)
{
if ( parameters.size() < 8 ) throw std::runtime_error("invalid number of parameters in NT1");
tms_ = std::tm();
tms_.tm_mday = std::stoi( get_parameter(buffer,&parameters[2]) );
tms_.tm_mon = std::stoi( get_parameter(buffer,&parameters[3]) ) - 1;
tms_.tm_year = std::stoi( get_parameter(buffer,&parameters[4]) ) - 1900;
tms_.tm_hour = std::stoi( get_parameter(buffer,&parameters[5]) );
tms_.tm_min = std::stoi( get_parameter(buffer,&parameters[6]) );
long double secs = std::stold( get_parameter(buffer,&parameters[7]) );
double secs_int;
trigger_time_frac_secs_ = modf((double)secs,&secs_int);
tms_.tm_sec = (int)secs_int;
}
// get info string
std::string get_info(int width = 20)
{
std::stringstream ss;
ss<<std::setw(width)<<std::left<<"timestamp:"<<std::put_time(&tms_, "%Y-%m-%dT%H:%M:%S")<<"\n";
return ss.str();
}
};
}
namespace imc {
// create wrapper for imc_object types
// (not particularly memory-efficient but it simplifies the remaining stuff
// considerably and the structs are pretty small anyway!)
class rawobject
{
format fmt_; // 0
keygroup kyg_; // 1
groupobj grp_; // 2
text txt_; // 3
datafield dtf_; // 4
abscissa abs_; // 5
component cmt_; // 6
packaging pkg_; // 7
buffer bfr_; // 8
range rng_; // 9
channelobj chn_; // 10
data dat_; // 11
origin_data org_; // 12
triggertime trt_; // 13
abscissa2 abs2_; // 14
int objidx_;
public:
rawobject(): objidx_(-1) { }
void parse(imc::key key, const std::vector<unsigned char>* buffer,
const std::vector<parameter>& parameters)
{
if ( key.name_ == std::string("CF") )
{
fmt_.parse(buffer,parameters);
objidx_ = 0;
}
else if ( key.name_ == std::string("CK") )
{
kyg_.parse(buffer,parameters);
objidx_ = 1;
}
else if ( key.name_ == std::string("CB") )
{
grp_.parse(buffer,parameters);
objidx_ = 2;
}
else if ( key.name_ == std::string("CT") )
{
txt_.parse(buffer,parameters);
objidx_ = 3;
}
else if ( key.name_ == std::string("CG") )
{
dtf_.parse(buffer,parameters);
objidx_ = 4;
}
else if ( key.name_ == std::string("CD") && key.version_ == 1 )
{
abs_.parse(buffer,parameters);
objidx_ = 5;
}
else if ( key.name_ == std::string("CC") )
{
cmt_.parse(buffer,parameters);
objidx_ = 6;
}
else if ( key.name_ == std::string("CP") )
{
pkg_.parse(buffer,parameters);
objidx_ = 7;
}
else if ( key.name_ == std::string("Cb") )
{
bfr_.parse(buffer,parameters);
objidx_ = 8;
}
else if ( key.name_ == std::string("CR") )
{
rng_.parse(buffer,parameters);
objidx_ = 9;
}
else if ( key.name_ == std::string("CN") )
{
chn_.parse(buffer,parameters);
objidx_ = 10;
}
else if ( key.name_ == std::string("CS") )
{
dat_.parse(buffer,parameters);
objidx_ = 11;
}
else if ( key.name_ == std::string("NO") )
{
org_.parse(buffer,parameters);
objidx_ = 12;
}
else if ( key.name_ == std::string("NT") && key.version_ == 1 )
{
trt_.parse(buffer,parameters);
objidx_ = 13;
}
else if ( key.name_ == std::string("CD") && key.version_ == 2 )
{
abs2_.parse(buffer,parameters);
objidx_ = 14;
}
else
{
if ( key.name_.at(0) == 'C' )
{
throw std::logic_error(
std::string("unsupported block associated to critical key ")
+ key.name_ + std::to_string(key.version_)
);
}
else
{
std::cout<<"WARNING: unsupported block associated to noncritical key "
<<key.name_<<key.version_<<"\n";
}
}
}
// provide info string
std::string get_info(int width = 20)
{
switch (objidx_) {
case 0:
return fmt_.get_info();
case 1:
return kyg_.get_info();
case 2:
return grp_.get_info();
case 3:
return txt_.get_info();
case 4:
return dtf_.get_info();
case 5:
return abs_.get_info();
case 6:
return cmt_.get_info();
case 7:
return pkg_.get_info();
case 8:
return bfr_.get_info();
case 9:
return rng_.get_info();
case 10:
return chn_.get_info();
case 11:
return dat_.get_info();
case 12:
return org_.get_info();
case 13:
return trt_.get_info();
case 14:
return abs2_.get_info();
default:
return std::string("");
}
}
};
}
#endif
//---------------------------------------------------------------------------//

73
lib/imc_parameter.hpp Normal file
View File

@ -0,0 +1,73 @@
//---------------------------------------------------------------------------//
#ifndef IMCPARAMETER
#define IMCPARAMETER
#include <iomanip>
#include <map>
#include <string>
#include <sstream>
#include <vector>
//---------------------------------------------------------------------------//
namespace imc
{
// single parameter (in a block) is determined by offset of its first/last byte
class parameter
{
// offset of first/last byte of parameter
unsigned long int begin_, end_;
public:
parameter(unsigned long int begin, unsigned long int end):
begin_(begin), end_(end)
{
if ( end_ < begin_ )
{
throw std::logic_error("parameter: offset of first byte larger than last byte's offset");
}
}
// set members
void begin(unsigned long int begin)
{
if ( end_ < begin )
{
throw std::logic_error("parameter: offset of first byte larger than last byte's offset");
}
begin_ = begin;
}
void end(unsigned long int end)
{
if ( end < begin_ )
{
throw std::logic_error("parameter: offset of first byte larger than last byte's offset");
}
end_ = end;
}
// access members
const unsigned long int& begin() const { return begin_; }
const unsigned long int& end() const { return end_; }
// comparison operator
bool operator==(const parameter& param)
{
return ( this->begin_ == param.begin_ && this->end_ == param.end_ );
}
// get info
std::string get_info() const
{
return ( std::string("[") + std::to_string(begin_) + std::string(",")
+ std::to_string(end_) + std::string("]") );
}
};
}
#endif
//---------------------------------------------------------------------------//

450
lib/imc_raw.hpp Normal file
View File

@ -0,0 +1,450 @@
//---------------------------------------------------------------------------//
#ifndef IMCRAW
#define IMCRAW
#include <fstream>
#include <filesystem>
#include <iostream>
// #include "hexshow.hpp"
#include "imc_key.hpp"
#include "imc_block.hpp"
#include "imc_datatype.hpp"
#include "imc_object.hpp"
#include "imc_result.hpp"
#include "imc_channel.hpp"
//---------------------------------------------------------------------------//
namespace imc
{
class raw
{
// (path of) raw-file and its basename
std::string raw_file_, file_name_;
// buffer of raw-file
std::vector<unsigned char> buffer_;
// list and map of imc-blocks
std::vector<imc::block> rawblocks_;
std::map<std::string,imc::block> mapblocks_;
// check computational complexity for parsing blocks
unsigned long int cplxcnt_;
// list groups and channels (including their affiliate blocks)
std::map<std::string,imc::channel> channels_;
public:
// constructor
raw() { };
raw(std::string raw_file): raw_file_(raw_file) { set_file(raw_file); };
// provide new raw-file
void set_file(std::string raw_file)
{
raw_file_ = raw_file;
this->fill_buffer();
this->parse_blocks();
this->generate_block_map();
this->generate_channel_env();
}
private:
// open file and stream data into buffer
void fill_buffer()
{
buffer_.clear();
// open file and put data in buffer
try {
std::ifstream fin(raw_file_.c_str(),std::ifstream::binary);
if ( !fin.good() ) throw std::runtime_error("failed to open file");
std::vector<unsigned char> buffer((std::istreambuf_iterator<char>(fin)),
(std::istreambuf_iterator<char>()));
buffer_ = buffer;
fin.close();
} catch ( const std::exception& e ) {
throw std::runtime_error(
std::string("failed to open raw-file and stream data in buffer: ") + e.what()
);
}
}
// parse all raw blocks in buffer
void parse_blocks()
{
rawblocks_.clear();
// reset counter to identify computational complexity
cplxcnt_ = 0;
// start parsing raw-blocks in buffer
for ( std::vector<unsigned char>::iterator it=buffer_.begin();
it!=buffer_.end(); ++it )
{
cplxcnt_++;
// check for "magic byte"
if ( *it == ch_bgn_ )
{
// check for (non)critical key
if ( *(it+1) == imc::key_crit_ || *(it+1) == imc::key_non_crit_ )
{
// compose (entire) key
std::string newkey = { (char)*(it+1), (char)*(it+2) };
imc::key itkey(*(it+1) == imc::key_crit_,newkey);
// expecting ch_sep_ after key
if ( *(it+3) == ch_sep_ )
{
// extract key version
std::string vers("");
unsigned long int pos = 4;
while ( *(it+pos) != ch_sep_ )
{
vers.push_back((char)*(it+pos));
pos++;
}
int version = std::stoi(vers);
// try to retrieve full key
itkey.version_ = version;
itkey = imc::get_key(itkey.critical_,itkey.name_,itkey.version_);
// check for known keys (including version)
if ( imc::check_key(itkey) )
{
// get block length
std::string leng("");
pos++;
while ( *(it+pos) != ch_sep_ )
{
leng.push_back((char)*(it+pos));
pos++;
}
unsigned long int length = std::stoul(leng);
// declare and initialize corresponding key and block
// imc::key bkey( *(it+1)==imc::key_crit_ , newkey,
// imc::keys.at(newkey).description_, version );
imc::block blk(itkey,(unsigned long int)(it-buffer_.begin()),
(unsigned long int)(it-buffer_.begin()+pos+1+length),
raw_file_, &buffer_);
// add block to list
rawblocks_.push_back(blk);
// skip the remaining block according to its length
if ( (unsigned long int)(it-buffer_.begin()+length) < (unsigned long int)(buffer_.size()) )
{
std::advance(it,length);
}
}
else
{
// all critical must be known !! while a noncritical may be ignored
if ( *(it+1) == imc::key_crit_ )
{
throw std::runtime_error(
std::string("unknown critical key: ") + newkey + std::to_string(version)
);
}
else
{
std::cout<<"WARNING: unknown noncritical key '"
<<newkey<<version<<"' will be ignored\n";
}
}
}
else
{
throw std::runtime_error(
std::string("invalid block or corrupt buffer at byte: ")
+ std::to_string(it+3-buffer_.begin())
);
}
}
}
}
this->check_consistency();
}
// check consistency of blocks
void check_consistency()
{
for ( unsigned long int b = 0; b < this->rawblocks_.size()-1 && this->rawblocks_.size() > 0; b++ )
{
if ( this->rawblocks_[b].get_end() >= this->rawblocks_[b+1].get_begin() )
{
throw std::runtime_error(
std::string("inconsistent subsequent blocks:\n")
+ std::to_string(b) + std::string("-th block:\n") + this->rawblocks_[b].get_info()
+ std::string("\n")
+ std::to_string(b+1) + std::string("-th block:\n") + this->rawblocks_[b+1].get_info() );
}
}
}
// generate map of blocks using their uuid
void generate_block_map()
{
mapblocks_.clear();
for ( imc::block blk: rawblocks_ )
{
mapblocks_.insert( std::pair<std::string,imc::block>(blk.get_uuid(),blk) );
}
}
// generate channel "environments"
void generate_channel_env()
{
channels_.clear();
// declare single channel environment
imc::channel_env chnenv;
chnenv.reset();
imc::component_env *compenv_ptr = nullptr;
// collect affiliate blocks for every channel WITH CHANNEL and AFFILIATE
// BLOCK CORRESPONDENCE GOVERNED BY BLOCK ORDER IN BUFFER!!
for ( imc::block blk: rawblocks_ )
{
if ( blk.get_key().name_ == "NO" ) chnenv.NOuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "NL" ) chnenv.NLuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CB" ) chnenv.CBuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CG" ) chnenv.CGuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CI" ) chnenv.CIuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CT" ) chnenv.CTuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CN" ) chnenv.CNuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CS" ) chnenv.CSuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CC" )
{
// a new component group is started
// TODO: can we avoid to parse the whole component here?
imc::component component;
component.parse(&buffer_, blk.get_parameters());
if ( component.component_index_ == 1 ) compenv_ptr = &chnenv.compenv1_;
else if ( component.component_index_ == 2 ) compenv_ptr = &chnenv.compenv2_;
else throw std::runtime_error("invalid component index in CC block");
compenv_ptr->CCuuid_ = blk.get_uuid();
compenv_ptr->uuid_ = compenv_ptr->CCuuid_;
}
else if ( blk.get_key().name_ == "CD" )
{
if (compenv_ptr == nullptr) chnenv.CDuuid_ = blk.get_uuid();
else compenv_ptr->CDuuid_ = blk.get_uuid();
}
else if ( blk.get_key().name_ == "NT" )
{
if (compenv_ptr == nullptr) chnenv.NTuuid_ = blk.get_uuid();
else compenv_ptr->NTuuid_ = blk.get_uuid();
}
else if ( blk.get_key().name_ == "Cb" ) compenv_ptr->Cbuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CP" ) compenv_ptr->CPuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CR" ) compenv_ptr->CRuuid_ = blk.get_uuid();
// check for currently associated channel
// TODO: CNuuid is not unique for multichannel data
if ( !chnenv.CNuuid_.empty() )
{
// at the moment only a single channel is supported
// any channel is closed by any of {CB, CG, CI, CT, CS}
if ( blk.get_key().name_ == "CB" || blk.get_key().name_ == "CG"
|| blk.get_key().name_ == "CI" || blk.get_key().name_ == "CT"
|| blk.get_key().name_ == "CS" )
{
// provide UUID for channel
// for multi component channels exactly one CN is available
chnenv.uuid_ = chnenv.CNuuid_;
// for multichannel data there may be multiple channels referring to
// the same (final) CS block (in contrast to what the IMC software
// documentation seems to suggest) resulting in all channels missing
// a CS block except for the very last
if ( chnenv.CSuuid_.empty() ) {
for ( imc::block blkCS: rawblocks_ ) {
if ( blkCS.get_key().name_ == "CS"
&& blkCS.get_begin() > (unsigned long int)stol(chnenv.uuid_) ) {
chnenv.CSuuid_ = blkCS.get_uuid();
}
}
}
// create channel object and add it to the map of channels
channels_.insert( std::pair<std::string,imc::channel>
(chnenv.CNuuid_,imc::channel(chnenv,&mapblocks_,&buffer_))
);
// reset channel uuid
chnenv.CNuuid_.clear();
chnenv.CBuuid_.clear();
chnenv.CGuuid_.clear();
chnenv.CIuuid_.clear();
chnenv.CTuuid_.clear();
chnenv.CSuuid_.clear();
compenv_ptr = nullptr;
}
}
// in contrast to component closed by CS block the blocks CB, CG, CC
// already belong to NEXT component
if ( blk.get_key().name_ == "CB" ) chnenv.CBuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CG" ) chnenv.CGuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CI" ) chnenv.CIuuid_ = blk.get_uuid();
else if ( blk.get_key().name_ == "CT" ) chnenv.CTuuid_ = blk.get_uuid();
}
}
public:
// provide buffer size
unsigned long int buffer_size()
{
return (unsigned long int)buffer_.size();
}
// get blocks
std::vector<imc::block>& blocks()
{
return rawblocks_;
}
// get computational complexity
unsigned long int& computational_complexity()
{
return cplxcnt_;
}
// get list of channels with metadata
std::vector<std::string> get_channels(bool json = false, bool include_data = false)
{
std::vector<std::string> chns;
for ( std::map<std::string,imc::channel>::iterator it = channels_.begin();
it != channels_.end(); ++it)
{
if ( !json )
{
chns.push_back(it->second.get_info());
}
else
{
chns.push_back(it->second.get_json(include_data));
}
}
return chns;
}
// get particular channel including data by its uuid
imc::channel get_channel(std::string uuid)
{
if ( channels_.count(uuid) )
{
return channels_.at(uuid);
}
else
{
throw std::runtime_error(std::string("channel does not exist:") + uuid);
}
}
// list a particular type of block
std::vector<imc::block> list_blocks(const imc::key &mykey)
{
std::vector<imc::block> myblocks;
for ( imc::block blk: this->rawblocks_ )
{
if ( blk.get_key() == mykey ) myblocks.push_back(blk);
}
return myblocks;
}
// list all groups (associated to blocks "CB")
std::vector<imc::block> list_groups()
{
return this->list_blocks(imc::get_key(true,"CB"));
}
// list all channels
std::vector<std::string> list_channels()
{
std::vector<std::string> channels;
for ( imc::block blk: this->rawblocks_ )
{
if ( blk.get_key() == imc::get_key(true,"CN") )
{
imc::parameter prm = blk.get_parameters()[6];
channels.push_back(blk.get_parameter(prm));
}
}
return channels;
}
// print single specific channel
void print_channel(std::string channeluuid, std::string outputfile, const char sep)
{
// check for given parent directory of output file
std::filesystem::path pdf = outputfile;
if ( !std::filesystem::is_directory(pdf.parent_path()) )
{
throw std::runtime_error(std::string("required directory does not exist: ")
+ pdf.parent_path().u8string() );
}
// find channel with given name
if ( channels_.count(channeluuid) == 1 )
{
channels_.at(channeluuid).print(outputfile,sep);
}
else
{
throw std::runtime_error(std::string("channel does not exist:")
+ channeluuid);
}
}
// print all channels into given directory
void print_channels(std::string output, const char sep)
{
// check for given directory
std::filesystem::path pd = output;
if ( !std::filesystem::is_directory(pd) )
{
throw std::runtime_error(std::string("given directory does not exist: ")
+ output);
}
for ( std::map<std::string,imc::channel>::iterator it = channels_.begin();
it != channels_.end(); ++it)
{
// construct filename
std::string chid = std::string("channel_") + it->first;
std::string filenam = it->second.name_.empty() ? chid + std::string(".csv")
: it->second.name_ + std::string(".csv");
std::filesystem::path pf = pd / filenam;
// and print the channel
it->second.print(pf.u8string(),sep);
}
}
};
}
#endif
//---------------------------------------------------------------------------//

30
lib/imc_result.hpp Normal file
View File

@ -0,0 +1,30 @@
//---------------------------------------------------------------------------//
#ifndef IMCRESULT
#define IMCRESULT
#include "imc_datatype.hpp"
//---------------------------------------------------------------------------//
namespace imc
{
struct channel_tab
{
std::string name_;
// abscissa
std::vector<double> xaxis_;
std::string xunit_;
// ordinate
// std::vector<imc::datatype> yaxis_;
std::vector<double> yaxis_;
std::string yunit_;
};
}
#endif
//---------------------------------------------------------------------------//

View File

@ -1,506 +0,0 @@
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/numeric_cast_utils.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/api/reader.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/comparison_op.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/io/buffered.cc
/home/mario/Desktop/arrow/cpp/src/arrow/extension_type.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/ubsan.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/is_subranged.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_time.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/yes_no.hpp
/home/mario/Desktop/arrow/cpp/src/generated/parquet_types.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_primitive.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/variant.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/multiplies.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/detail/is_function_cxx_11.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/status.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/void_fwd.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/concatenate.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/preprocessor/enum.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/strtod.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/config.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_nested.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/less.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_decimal.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/cached-powers.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/string.cc
/home/mario/Desktop/arrow/cpp/src/parquet/exception.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_binary.cc
/home/mario/Desktop/arrow/cpp/src/parquet/encoding.cc
/home/mario/Desktop/arrow/cpp/src/arrow/type_traits.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/transport/TTransportException.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/lambda_fwd.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/adl_barrier.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_nested.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/kernel.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/future.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/formatting.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/include_preprocessed.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/fast-dtoa.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/preprocessor/def_params_tail.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/macros.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/api_vector.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_void.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/intrinsics.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/workaround.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/bignum.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/tuple/rem.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/control/iif.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/logical/bitand.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/kernels/codegen_internal.cc
/home/mario/Desktop/arrow/cpp/src/parquet/column_writer.cc
/home/mario/Desktop/arrow/cpp/src/parquet/encryption.cc
/home/mario/Desktop/arrow/cpp/src/parquet/encoding.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/value_parsing.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/double_conversion.h
/home/mario/Desktop/arrow/cpp/src/arrow/io/file.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/compiler.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/api_aggregate.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/logical/compl.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/bit_block_counter.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/thread_pool.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_common.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/utf8.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_rvalue_reference.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/facilities/identity.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/na_fwd.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/numeric_cast_traits.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/msvc_typename.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/utility/enable_if.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/internal_file_encryptor.cc
/home/mario/Desktop/arrow/cpp/src/arrow/datum.cc
/home/mario/Desktop/arrow/cpp/src/arrow/result.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/arithmetic/inc.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/logical/and.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_function.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/na.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/string.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/api_scalar.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/protocol/TDebugProtocol.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_array.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/windows_compatibility.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/converter_policies.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/schema_internal.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/int_util.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/core/enable_if.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/cstdint.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/remove_cv.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/checked_delete.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_base.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/make_unique.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/api_aggregate.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/sign_mixture.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/type_traits.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/double-conversion.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/declval.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/status.cc
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/xxhash/xxhash.c
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/has_apply.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/time.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/spaced.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/datetime/date.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/bignum.h
/home/mario/Desktop/arrow/cpp/src/arrow/extension_type.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_same.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/utf8cpp/core.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/detail/select_platform_config.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_dict.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/control/while.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/formatting.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/detail/is_binary.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/preprocessed/numeric_cast_traits_long_long.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/adl.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/debug/error.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_binary.h
/home/mario/Desktop/arrow/cpp/src/arrow/io/buffered.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/facilities/overload.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/diff.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/variadic/size.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/integral_constant.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/empty.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_complete.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/align_util.h
/home/mario/Desktop/arrow/cpp/src/arrow/table.h
/home/mario/Desktop/arrow/cpp/src/arrow/memory_pool.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/void.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/overload_resolution.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/ctps.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/ieee.h
/home/mario/Desktop/arrow/cpp/src/parquet/internal_file_encryptor.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/future.cc
/home/mario/Desktop/arrow/cpp/src/arrow/builder.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/range.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/fixed-dtoa.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/eti.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/msvc_eti_base.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/type_wrapper.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/metadata.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/value_parsing.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/forwarding.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/gcc.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/and.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_binary.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/array/size.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/repetition/repeat.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/times.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/bitmap_reader.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/bitmap_builders.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/udt_builtin_mixture.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/checked_cast.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_primitive.cc
/home/mario/Desktop/arrow/cpp/src/parquet/thrift_internal.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/config.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/transport/TTransport.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/static_cast.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/key_value_metadata.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/eval_if.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/arithmetic/sub.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/data.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/arithmetic/dec.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/bitmap_generate.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/hash_util.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/preprocessed/gcc/apply_wrap.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/string_builder.cc
/home/mario/Desktop/arrow/cpp/src/arrow/visitor.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/strptime.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/bitmap_ops.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/byte_stream_split.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/detail/select_compiler_config.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/string_builder.h
/home/mario/Desktop/arrow/cpp/src/parquet/encryption.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/validate.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/vector.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/protocol/TVirtualProtocol.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/protocol/TCompactProtocol.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/data.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/tag.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/api.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/preprocessor/params.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/bounds.hpp
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/transport/PlatformSocket.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/throw_exception.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/stl_allocator.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/na_spec.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/thread_pool.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/cpu_info.h
/home/mario/Desktop/arrow/cpp/src/arrow/buffer.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/smart_ptr/detail/sp_noexcept.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/device.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/xxhash/xxh3.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/validate.h
/home/mario/Desktop/arrow/cpp/src/parquet/api/schema.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/visibility.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/detail/yes_no_type.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/utf8cpp/checked.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/numeric_op.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/platform.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/basic_decimal.cc
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/thrift-config.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/tuple/elem.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/smart_ptr/detail/sp_nullptr_t.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_nested.cc
/home/mario/Desktop/arrow/cpp/src/parquet/schema.cc
/home/mario/Desktop/arrow/cpp/src/arrow/compute/util_internal.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/protocol/TCompactProtocol.tcc
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_base.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/internal_file_decryptor.h
/home/mario/Desktop/arrow/cpp/src/arrow/sparse_tensor.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/cast.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/scalar.h
/home/mario/Desktop/arrow/cpp/src/arrow/io/util_internal.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/logical/bool.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/stdlib/libstdcpp3.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/control/expr_iif.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/parquet_version.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_reference.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/int_fwd.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_abstract.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_adaptive.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/bpacking.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_decimal.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/use_preprocessed.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/io_util.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/integral_wrapper.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/scoped_array.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/io/interfaces.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/add_reference.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/converter.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/preprocessed/gcc/times.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/xxhash/xxhash.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/registry.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/list/fold_right.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/preprocessed/gcc/equal_to.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/identity.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/io/caching.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/optional.h
/home/mario/Desktop/arrow/cpp/src/parquet/schema.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_convertible.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/detail/check.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/cached-powers.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_arithmetic.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_lvalue_reference.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/detail/select_stdlib_config.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/variadic/elem.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/workaround.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/double-conversion.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/bool.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/identity.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/api_vector.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/detail/suffix.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/control/if.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/column_reader.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_binary.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/no_tr1/cmath.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/strtod.cc
/home/mario/Desktop/arrow/cpp/src/arrow/tensor.h
/home/mario/Desktop/arrow/cpp/src/arrow/compare.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/udt_builtin_mixture_enum.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/memory.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/add_lvalue_reference.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/integral.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/record_batch.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/diff.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_decimal.cc
/home/mario/Desktop/arrow/cpp/src/arrow/array/util.cc
/home/mario/Desktop/arrow/cpp/src/parquet/properties.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/bounds.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/detail/posix_features.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/basic_decimal.h
/home/mario/Desktop/arrow/cpp/src/parquet/types.h
/home/mario/Desktop/arrow/cpp/src/parquet/column_writer.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/not.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/file_writer.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_floating_point.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/file_reader.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/arithmetic_op.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/result.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/sort.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_union.cc
/home/mario/Desktop/arrow/cpp/src/arrow/tensor/converter.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_dict.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/compression.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/preprocessor.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/column_scanner.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/repetition/enum_trailing_params.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/nested_type_wknd.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/bit_util.cc
/home/mario/Desktop/arrow/cpp/src/parquet/metadata.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/list/adt.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/chunked_array.cc
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/protocol/TBinaryProtocol.tcc
/home/mario/Desktop/arrow/cpp/src/parquet/level_conversion.h
/home/mario/Desktop/arrow/cpp/src/parquet/properties.cc
/home/mario/Desktop/arrow/cpp/src/arrow/datum.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/has_xxx.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/detail/auto_rec.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/bitmap_ops.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/core/checked_delete.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/exec.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/io_util.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/datetime/tz.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/limits/arity.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/memory_pool.cc
/home/mario/Desktop/arrow/cpp/src/arrow/array/util.h
/home/mario/Desktop/arrow/cpp/src/parquet/types.cc
/home/mario/Desktop/arrow/cpp/src/arrow/chunked_array.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/version.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/exec_internal.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/bit_util.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/smart_ptr/detail/operator_bool.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/bit_stream_utils.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/int_util.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/converter.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/list/fold_left.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/deprecated_io.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/optional.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/repeat.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/file_writer.cc
/home/mario/Desktop/arrow/cpp/src/parquet/encryption_internal.h
/home/mario/Desktop/arrow/cpp/src/arrow/io/interfaces.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/lambda_arity_param.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/kernel.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/lambda.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/io/concurrency.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/atomic_shared_ptr.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/bitmap_builders.cc
/home/mario/Desktop/arrow/cpp/src/arrow/type.cc
/home/mario/Desktop/arrow/cpp/src/arrow/pretty_print.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/comma_if.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/preprocessed/gcc/less.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/sign_mixture_enum.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/logging.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/integral_c.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/windows_compatibility.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/detail/workaround.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/static_assert.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/key_value_metadata.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/tuple/eat.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/column_reader.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/compression_internal.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/bpacking_default.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/equal_to.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/is_msvc_eti_arg.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/value_wknd.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/int_float_mixture_enum.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/config/config.hpp
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/transport/TVirtualTransport.h
/home/mario/Desktop/arrow/cpp/src/parquet/column_scanner.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/compression.cc
/home/mario/Desktop/arrow/cpp/src/arrow/io/memory.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/control/detail/while.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/punctuation/comma_if.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/array/elem.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/printer.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/fast-dtoa.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/smart_ptr/scoped_array.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/static_constant.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/template_arity_fwd.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/sparse_tensor.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/conversion_traits.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/msvc_never_true.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_union.h
/home/mario/Desktop/arrow/cpp/src/arrow/buffer.cc
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/transport/TBufferTransports.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/integral_c_tag.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/has_tag.hpp
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/stdcxx.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/protocol/TProtocolException.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/facilities/expand.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/has_apply.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/table.cc
/home/mario/Desktop/arrow/cpp/src/arrow/io/caching.cc
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/xxhash.h
/home/mario/Desktop/arrow/cpp/src/parquet/api/writer.h
/home/mario/Desktop/arrow/cpp/src/parquet/api/io.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/cast_internal.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_base.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/int.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/numeric_cast.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/simd.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/user.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/rle_encoding.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/bitmap_writer.h
/home/mario/Desktop/arrow/cpp/src/parquet/level_conversion.cc
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/protocol/TBinaryProtocol.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_decimal.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/apply_wrap.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/detail/config.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/intel.hpp
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/Thrift.h
/home/mario/Desktop/arrow/cpp/src/arrow/pretty_print.h
/home/mario/Desktop/arrow/cpp/src/parquet/statistics.cc
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/diy-fp.cc
/home/mario/Desktop/arrow/cpp/src/arrow/array/dict_internal.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/time.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/function.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/utf8.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/cpu_info.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/array/data.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/platform/linux.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/string_view.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/dtp.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/kernels/codegen_internal.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/TBase.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/TApplicationException.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/utils.h
/home/mario/Desktop/arrow/cpp/src/arrow/io/memory.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/lambda_support.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/hashing.h
/home/mario/Desktop/arrow/cpp/src/arrow/record_batch.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/ttp.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/io/file.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/integral_c_fwd.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/type_fwd.h
/home/mario/Desktop/arrow/cpp/src/arrow/scalar.cc
/home/mario/Desktop/arrow/cpp/src/arrow/type.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/decimal.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/function.cc
/home/mario/Desktop/arrow/cpp/src/arrow/device.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/arithmetic/add.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/is_integral.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/type_fwd.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/string_view.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/has_xxx.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/bignum-dtoa.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/nttp_decl.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/inc.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/int_float_mixture.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/functional.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/cast.h
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/fixed-dtoa.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/variant.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/add_rvalue_reference.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/registry_internal.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/meta.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/iterator.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_primitive.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/if.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/bit_block_counter.cc
/home/mario/Desktop/arrow/cpp/src/arrow/array/concatenate.cc
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_dict.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/arity.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/largest_int.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/tuple/detail/is_single_return.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/datetime.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/windows_fixup.h
/home/mario/Desktop/arrow/cpp/src/parquet/internal_file_decryptor.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/iterator.cc
/home/mario/Desktop/arrow/cpp/src/arrow/buffer_builder.h
/home/mario/Desktop/arrow/cpp/src/arrow/tensor.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/list/detail/fold_left.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/decimal.cc
/home/mario/Desktop/arrow/cpp/src/arrow/visitor.cc
/home/mario/Desktop/arrow/cpp/src/arrow/compute/registry.h
/home/mario/Desktop/arrow/cpp/src/arrow/util/memory.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/compare.h
/home/mario/Desktop/arrow/cpp/src/arrow/compare.cc
/home/mario/Desktop/arrow/cpp/src/arrow/util/logging.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/exec.h
/home/mario/Desktop/arrow/cpp/src/parquet/column_page.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/arrays.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/list/detail/fold_right.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/nttp.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/numeric_cast_traits.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_base.h
/home/mario/Desktop/arrow/cpp/src/arrow/visitor_inline.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/cat.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/type_traits/remove_reference.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/diy-fp.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_primitive.cc
/home/mario/Desktop/arrow/cpp/src/arrow/type_fwd.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/repetition/enum_params.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/current_function.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/assert.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/file_reader.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/list/reverse.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/compute/cast.cc
/home/mario/Desktop/arrow/cpp/src/arrow/io/type_fwd.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/protocol/TProtocol.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/exception/exception.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/deprecated_io.cc
/home/mario/Desktop/arrow/cpp/src/parquet/encryption_internal.cc
/home/mario/Desktop/arrow/cpp/src/parquet/platform.h
/home/mario/Desktop/arrow/cpp/src/arrow/compute/api_scalar.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/config/compiler/gcc.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/bit_run_reader.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/preprocessed/gcc/and.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/vendored/double-conversion/bignum-dtoa.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_adaptive.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/config/msvc.hpp
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/TLogging.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/builder_nested.h
/home/mario/Desktop/arrow/cpp/src/arrow/array/array_dict.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/numeric/conversion/detail/conversion_traits.hpp
/home/mario/Desktop/arrow/cpp/src/arrow/util/bit_run_reader.h
/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/thrift/TOutput.h
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/limits.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/stringize.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/bool_fwd.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/facilities/empty.hpp
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/mpl/aux_/preprocessor/default_params.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/printer.cc
/home/mario/Desktop/arrow/cpp/src/arrow/builder.cc
/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/boost/preprocessor/punctuation/comma.hpp
/home/mario/Desktop/arrow/cpp/src/parquet/statistics.h

View File

@ -1,133 +0,0 @@
#-----------------------------------------------------------------------------#
import argparse
import os
#-----------------------------------------------------------------------------#
parser = argparse.ArgumentParser(description='List all source dependencies')
#parser.add_argument('pathToRepo',type=str,help='path of source repository')
parser.add_argument('mainSource',type=str,help='main source file')
parser.add_argument('depFile',type=str,help='file listing all dependencies')
args = parser.parse_args()
libpaths = ["/home/mario/Desktop/arrow/cpp/src/",
"/home/mario/Desktop/arrow/cpp/thrift_ep-install/include/",
"/home/mario/Desktop/arrow/cpp/boost_ep-prefix/src/boost_ep/"]
#-----------------------------------------------------------------------------#
def find_dependencies(srcfile, recdepth, cdeplist) :
"""
Given a source file and its dependencies in the given repository path
list all further dependencies recursively
Args:
srcfile (string): path/name of source file
recdepth (integer): current recursion depth
cdeplist (list): current list of dependencies
Return:
deps (list): list of source files in repository, the source file depends on
"""
# define indentation to visual recursion
indent = recdepth*(" ")
print("\n" + indent + "find_dependencies:"
+ "\n" + indent + "1: " + srcfile
+ "\n" + indent + "2: " + str(recdepth)
+ "\n" + indent + "3: " + str(len(cdeplist)) + "\n")
# show dependencies so far
#print(cdeplist)
# generate dependencies by means of g++
libdeps = (" -I ").join(libpaths)
cmd = "g++ -c -MMD " + srcfile + " -I " + libdeps
print(indent + cmd )
os.system(cmd)
# open dependency file and extract list of sources
basename = srcfile.split('/')[-1].split('.')[0]
depfile = basename + '.d'
print(indent + "reading dependency file " + depfile)
with open(depfile,'r') as fin :
depslist = fin.readlines()
# delete dependencies and object files
os.system("rm " + basename + ".d")
os.system("rm " + basename + ".o")
# remove first line
depslist = depslist[1:]
# delete leading space and trailing backslash
depslistcl = [dep.lstrip(' ').rstrip(' \\\n') for dep in depslist]
# collect dependencies
newdeps = []
# check all dependencies recursively and collect further dependencies
count = 0
for dep in depslistcl :
# append source itself to list
if dep not in cdeplist :
print(indent + "adding dependency " + dep)
newdeps.append(dep)
count = count + 1
print(indent + "=> added " + str(count) + "/" + str(len(depslistcl)) )
# check recursion depth
if recdepth < 20 :
# check all dependencies of every single dependency
for dep in depslistcl :
# try to find corresponding *.cc, (*.cpp) file
depcc = dep.split('.')[0] + '.cc'
print(indent + "checking for " + depcc)
if os.path.exists(depcc) :
if depcc not in cdeplist and depcc not in newdeps :
# add file itself as dependency
newdeps.append(depcc)
# find dependencies of single source
newrecdeps = find_dependencies(depcc,recdepth+1,cdeplist+newdeps)
# append to list
for el in newrecdeps :
if el not in newdeps :
newdeps.append(el)
else :
print(indent + "already in list")
else :
print(indent + "does not exist")
print("\n")
# provide list of dependencies
return newdeps
#-----------------------------------------------------------------------------#
if __name__== "__main__":
print("\nCLI arguments:\n" + str(args) + "\n")
# collect list of dependencies
deps = []
# start recursion with given source file
deps = find_dependencies(args.mainSource,0,[])
print("\nfinal list of dependencies: (" + str(len(deps)) + ")\n")
print(deps)
print("\n")
# remove any duplicates
depsuni = set(deps)
print("\nfinal set of dependencies: (" + str(len(depsuni)) + ")\n")
print(depsuni)
print("\n")
# write list of dependencies
with open(args.depFile,'w') as fout :
for el in depsuni :
fout.write(str(el) + '\n')
#-----------------------------------------------------------------------------#

View File

@ -1,23 +0,0 @@
#-----------------------------------------------------------------------------#
import glob
from pathlib import Path
# find source files
srcpaths = Path("src/").rglob('*.cc')
deps =[ str(path) for path in srcpaths ]
print(deps)
with open('makefileobj','w') as fout :
for el in deps :
basnam = el.split('/')[-1]
print(str(el) + " : " + str(basnam) + " : " + str(basnam.split('.')[1]))
if basnam.split('.')[1] == 'cc' :
objfile = 'bin/' + basnam.replace('.cc','.o')
fout.write(objfile + " : " + el + "\n")
fout.write("\t" + "$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@\n")
fout.write("\n")
#-----------------------------------------------------------------------------#

View File

@ -1,356 +0,0 @@
#-----------------------------------------------------------------------------#
CPP := g++ -std=c++14
CPPFLAGS := -Woverflow -Wpedantic -Wextra -Waddress -Waligned-new -Walloc-zero
SRC := src/
BIN := bin/
LIBS := -I src/src/ -I src/thrift_ep-install/include/ -I src/boost_ep-prefix/src/boost_ep/
#-----------------------------------------------------------------------------#
# prepare source
#
# before: $ cd arrow/cpp/ and compile relevant sources by
# $ cmake . -D ARROW_PARQUET=ON -D PARQUET_BUILD_EXAMPLES=ON -D ARROW_WITH_SNAPPY=ON
# $ cmake .. -D ARROW_PARQUET=ON ARROW_BUILD_EXAMPLES=ON
lib :
cmake . -D ARROW_WITH_BROTLI=ON -D ARROW_WITH_BZ2=ON -D ARROW_WITH_LZ4=ON -D ARROW_WITH_SNAPPY=ON -D ARROW_WITH_ZLIB=ON -D ARROW_PARQUET=ON -D ARROW_PYTHON=ON
# cp-src : deps.log
# ./src_copy.sh
deps.log :
python3 generate_deps.py reader-writer.cc $@
SRC := $(shell find $(SRC) -name '*.cc')
# OBJ := $(apprefix obj/, $(SRC:%.cc=%.o))
OBJ := $(addprefix $(BIN),$(notdir $(SRC:%.cc=%.o)))
check :
@echo $(SRC)
@echo $(OBJ)
# vpath %.cc src/
reader-writer-example : reader-writer.cc $(OBJ) bin/utilmemory.o
$(CPP) $(CPPFLAGS) $< $(LIBS) -o $@ $(OBJ) bin/utilmemory.o
# $(OBJ) : $(SRC)
# $(CPP) $(OPT) -c $< -o $@ -I src/src/
#
# $(BIN)%.o : $(SRC)
# $(CPP) $(OPT) -c $< -I src/src/ -o $@
clean-obj :
rm -f $(OBJ)
# => do build with cmake like here
# https://arrow.apache.org/docs/developers/python.html#build-and-test
#-----------------------------------------------------------------------------#
bin/type.o : src/src/arrow/type.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/result.o : src/src/arrow/result.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder.o : src/src/arrow/builder.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/tensor.o : src/src/arrow/tensor.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/table.o : src/src/arrow/table.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/extension_type.o : src/src/arrow/extension_type.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/device.o : src/src/arrow/device.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/memory_pool.o : src/src/arrow/memory_pool.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/datum.o : src/src/arrow/datum.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/record_batch.o : src/src/arrow/record_batch.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/compare.o : src/src/arrow/compare.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/visitor.o : src/src/arrow/visitor.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/chunked_array.o : src/src/arrow/chunked_array.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/status.o : src/src/arrow/status.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/pretty_print.o : src/src/arrow/pretty_print.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/sparse_tensor.o : src/src/arrow/sparse_tensor.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/buffer.o : src/src/arrow/buffer.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/scalar.o : src/src/arrow/scalar.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/string.o : src/src/arrow/util/string.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/utilmemory.o : src/src/arrow/util/memory.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/future.o : src/src/arrow/util/future.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/iterator.o : src/src/arrow/util/iterator.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/compression.o : src/src/arrow/util/compression.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/utf8.o : src/src/arrow/util/utf8.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/time.o : src/src/arrow/util/time.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/cpu_info.o : src/src/arrow/util/cpu_info.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/thread_pool.o : src/src/arrow/util/thread_pool.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bit_util.o : src/src/arrow/util/bit_util.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/logging.o : src/src/arrow/util/logging.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/basic_decimal.o : src/src/arrow/util/basic_decimal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/decimal.o : src/src/arrow/util/decimal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bit_block_counter.o : src/src/arrow/util/bit_block_counter.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/key_value_metadata.o : src/src/arrow/util/key_value_metadata.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/int_util.o : src/src/arrow/util/int_util.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/io_util.o : src/src/arrow/util/io_util.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bitmap_ops.o : src/src/arrow/util/bitmap_ops.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bitmap_builders.o : src/src/arrow/util/bitmap_builders.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bit_run_reader.o : src/src/arrow/util/bit_run_reader.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/value_parsing.o : src/src/arrow/util/value_parsing.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/string_builder.o : src/src/arrow/util/string_builder.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/formatting.o : src/src/arrow/util/formatting.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_primitive.o : src/src/arrow/array/array_primitive.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_dict.o : src/src/arrow/array/array_dict.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_binary.o : src/src/arrow/array/builder_binary.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_union.o : src/src/arrow/array/builder_union.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/concatenate.o : src/src/arrow/array/concatenate.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_nested.o : src/src/arrow/array/array_nested.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_decimal.o : src/src/arrow/array/array_decimal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_primitive.o : src/src/arrow/array/builder_primitive.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/data.o : src/src/arrow/array/data.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/diff.o : src/src/arrow/array/diff.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_nested.o : src/src/arrow/array/builder_nested.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_decimal.o : src/src/arrow/array/builder_decimal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_dict.o : src/src/arrow/array/builder_dict.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_binary.o : src/src/arrow/array/array_binary.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_adaptive.o : src/src/arrow/array/builder_adaptive.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_base.o : src/src/arrow/array/array_base.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/validate.o : src/src/arrow/array/validate.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_base.o : src/src/arrow/array/builder_base.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/util.o : src/src/arrow/array/util.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/caching.o : src/src/arrow/io/caching.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/memory.o : src/src/arrow/io/memory.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/interfaces.o : src/src/arrow/io/interfaces.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/buffered.o : src/src/arrow/io/buffered.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/file.o : src/src/arrow/io/file.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/strtod.o : src/src/arrow/vendored/double-conversion/strtod.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bignum.o : src/src/arrow/vendored/double-conversion/bignum.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/fixed-dtoa.o : src/src/arrow/vendored/double-conversion/fixed-dtoa.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/fast-dtoa.o : src/src/arrow/vendored/double-conversion/fast-dtoa.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/diy-fp.o : src/src/arrow/vendored/double-conversion/diy-fp.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/double-conversion.o : src/src/arrow/vendored/double-conversion/double-conversion.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bignum-dtoa.o : src/src/arrow/vendored/double-conversion/bignum-dtoa.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/cached-powers.o : src/src/arrow/vendored/double-conversion/cached-powers.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/api_aggregate.o : src/src/arrow/compute/api_aggregate.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/exec.o : src/src/arrow/compute/exec.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/kernel.o : src/src/arrow/compute/kernel.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/registry.o : src/src/arrow/compute/registry.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/function.o : src/src/arrow/compute/function.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/cast.o : src/src/arrow/compute/cast.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/api_vector.o : src/src/arrow/compute/api_vector.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/api_scalar.o : src/src/arrow/compute/api_scalar.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/codegen_internal.o : src/src/arrow/compute/kernels/codegen_internal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/column_scanner.o : src/src/parquet/column_scanner.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/statistics.o : src/src/parquet/statistics.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/internal_file_decryptor.o : src/src/parquet/internal_file_decryptor.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/column_writer.o : src/src/parquet/column_writer.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/encryption.o : src/src/parquet/encryption.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/file_reader.o : src/src/parquet/file_reader.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/properties.o : src/src/parquet/properties.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/encryption_internal.o : src/src/parquet/encryption_internal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/internal_file_encryptor.o : src/src/parquet/internal_file_encryptor.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/types.o : src/src/parquet/types.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/encoding.o : src/src/parquet/encoding.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/metadata.o : src/src/parquet/metadata.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/printer.o : src/src/parquet/printer.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/level_conversion.o : src/src/parquet/level_conversion.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/deprecated_io.o : src/src/parquet/deprecated_io.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/file_writer.o : src/src/parquet/file_writer.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/schema.o : src/src/parquet/schema.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/platform.o : src/src/parquet/platform.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/column_reader.o : src/src/parquet/column_reader.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@

View File

@ -1,96 +0,0 @@
#-----------------------------------------------------------------------------#
PARQUETDIR := /home/mario/Desktop/Record_Evolution/parquet-cpp
ARROWDIR := /home/mario/Desktop/Record_Evolution/arrow/cpp/src
CPP := g++ -std=c++14
OPT := -Wall -Woverflow -Wpedantic -Wextra -Waddress -Waligned-new -Walloc-zero
prepare : collect_parquet modify_parquet collect_arrow modify_arrow
collect_parquet :
cp -r $(PARQUETDIR)/src/parquet ./
cp $(PARQUETDIR)/examples/low-level-api/reader_writer.h ./
cp $(PARQUETDIR)/examples/low-level-api/reader-writer.cc ./
modify_parquet :
cp parquet/parquet_version.h.in parquet/parquet_version.h
sed -i 's/ReadableFileInterface/ReadWriteFileInterface/g' parquet/util/memory.h
sed -i 's/ReadableFileInterface/ReadWriteFileInterface/g' parquet/file_reader.h
sed -i 's/arrow::Codec/arrow::util::Codec/g' parquet/util/memory.h
sed -i 's/valid_bits_writer/valid_bits_offset/g' parquet/column_reader.h
collect_arrow :
cp -r $(ARROWDIR)/arrow ./
modify_arrow :
cp arrow/util/bit_util.h arrow/util/bit-util.h
collect_test :
cp $(PARQUETDIR)/examples/low-level-api/reader-writer.cc ./
subst :
sed -i 's/#include \"arrow\//\/\/#include \"arrow/g' parquet/properties.h
test :
$(CPP) $(OPT) -I$(PWD) reader-writer.cc
clean :
rm -r parquet/ arrow/
rm reader-writer.cc reader_writer.h
#-----------------------------------------------------------------------------#
# choose shell
SHELL:=/bin/bash
SRC = reader-writer
# specify path of cloned directory
ARROWGIT := /home/mario/Desktop/Record_Evolution/arrow
filewriter : parquet/file_writer.cc
$(CPP) -c $(OPT) $<
# build executable (and generate dependency file)
readwrite : reader-writer.cc
$(CPP) $(OPT) -MMD $< -I ./
# generate dependency file
$(SRC).d : $(SRC).cc
$(CPP) -c -MMD $< -I ./ -I $(ARROWGIT)/cpp/src/
# extract source dependencies
extract-dep : $(SRC).d
@# extract relevant dependencies
cat $< | sed 's/ /\n/g' | awk 'NF' | grep -v '\\' | grep '\/' > deps.log
cat deps.log | sed ':a;N;$!ba;s/\n/ /g' > headers.log
cat headers.log | sed 's/.h$$/.cc/g' > sources.log
@# copy required sources
mkdir -p temp/
cp --parents `cat headers.log` temp/
cp --parents `cat sources.log` temp/ 2>/dev/null
mv temp$(ARROWGIT)/cpp/src/* ./
rm -r temp
clean-dep :
rm -f deps.log headers.log sources.log $(SRC).d
#-----------------------------------------------------------------------------#
# only use more recent and up to date repository arrow.git
# build arrow shared/static libraries
build :
cd arrow/cpp
# cmake -LA to show all options
cmake . -D ARROW_PARQUET=ON #ARROW_ARMV8_ARCH=armv8-a
make
example :
cd arrow/cpp/examples/parquet/low-level-api/
g++ reader-writer.cc -I. -I../../../src/ -L../../../../cpp/build/release/ -larrow -lparquet
# set environment variable LD_LIBRARY_PATH=../../../../cpp/build/release/ before launching executable
#------------------------------------------------------------------------------------#

View File

@ -1,303 +0,0 @@
bin/type.o : src/src/arrow/type.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/result.o : src/src/arrow/result.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder.o : src/src/arrow/builder.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/tensor.o : src/src/arrow/tensor.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/table.o : src/src/arrow/table.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/extension_type.o : src/src/arrow/extension_type.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/device.o : src/src/arrow/device.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/memory_pool.o : src/src/arrow/memory_pool.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/datum.o : src/src/arrow/datum.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/record_batch.o : src/src/arrow/record_batch.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/compare.o : src/src/arrow/compare.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/visitor.o : src/src/arrow/visitor.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/chunked_array.o : src/src/arrow/chunked_array.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/status.o : src/src/arrow/status.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/pretty_print.o : src/src/arrow/pretty_print.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/sparse_tensor.o : src/src/arrow/sparse_tensor.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/buffer.o : src/src/arrow/buffer.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/scalar.o : src/src/arrow/scalar.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/string.o : src/src/arrow/util/string.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/memory.o : src/src/arrow/util/memory.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/future.o : src/src/arrow/util/future.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/iterator.o : src/src/arrow/util/iterator.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/compression.o : src/src/arrow/util/compression.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/utf8.o : src/src/arrow/util/utf8.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/time.o : src/src/arrow/util/time.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/cpu_info.o : src/src/arrow/util/cpu_info.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/thread_pool.o : src/src/arrow/util/thread_pool.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bit_util.o : src/src/arrow/util/bit_util.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/logging.o : src/src/arrow/util/logging.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/basic_decimal.o : src/src/arrow/util/basic_decimal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/decimal.o : src/src/arrow/util/decimal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bit_block_counter.o : src/src/arrow/util/bit_block_counter.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/key_value_metadata.o : src/src/arrow/util/key_value_metadata.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/int_util.o : src/src/arrow/util/int_util.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/io_util.o : src/src/arrow/util/io_util.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bitmap_ops.o : src/src/arrow/util/bitmap_ops.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bitmap_builders.o : src/src/arrow/util/bitmap_builders.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bit_run_reader.o : src/src/arrow/util/bit_run_reader.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/value_parsing.o : src/src/arrow/util/value_parsing.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/string_builder.o : src/src/arrow/util/string_builder.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/formatting.o : src/src/arrow/util/formatting.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_primitive.o : src/src/arrow/array/array_primitive.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_dict.o : src/src/arrow/array/array_dict.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_binary.o : src/src/arrow/array/builder_binary.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_union.o : src/src/arrow/array/builder_union.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/concatenate.o : src/src/arrow/array/concatenate.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_nested.o : src/src/arrow/array/array_nested.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_decimal.o : src/src/arrow/array/array_decimal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_primitive.o : src/src/arrow/array/builder_primitive.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/data.o : src/src/arrow/array/data.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/diff.o : src/src/arrow/array/diff.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_nested.o : src/src/arrow/array/builder_nested.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_decimal.o : src/src/arrow/array/builder_decimal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_dict.o : src/src/arrow/array/builder_dict.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_binary.o : src/src/arrow/array/array_binary.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_adaptive.o : src/src/arrow/array/builder_adaptive.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/array_base.o : src/src/arrow/array/array_base.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/validate.o : src/src/arrow/array/validate.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/builder_base.o : src/src/arrow/array/builder_base.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/util.o : src/src/arrow/array/util.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/caching.o : src/src/arrow/io/caching.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/memory.o : src/src/arrow/io/memory.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/interfaces.o : src/src/arrow/io/interfaces.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/buffered.o : src/src/arrow/io/buffered.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/file.o : src/src/arrow/io/file.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/strtod.o : src/src/arrow/vendored/double-conversion/strtod.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bignum.o : src/src/arrow/vendored/double-conversion/bignum.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/fixed-dtoa.o : src/src/arrow/vendored/double-conversion/fixed-dtoa.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/fast-dtoa.o : src/src/arrow/vendored/double-conversion/fast-dtoa.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/diy-fp.o : src/src/arrow/vendored/double-conversion/diy-fp.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/double-conversion.o : src/src/arrow/vendored/double-conversion/double-conversion.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/bignum-dtoa.o : src/src/arrow/vendored/double-conversion/bignum-dtoa.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/cached-powers.o : src/src/arrow/vendored/double-conversion/cached-powers.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/api_aggregate.o : src/src/arrow/compute/api_aggregate.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/exec.o : src/src/arrow/compute/exec.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/kernel.o : src/src/arrow/compute/kernel.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/registry.o : src/src/arrow/compute/registry.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/function.o : src/src/arrow/compute/function.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/cast.o : src/src/arrow/compute/cast.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/api_vector.o : src/src/arrow/compute/api_vector.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/api_scalar.o : src/src/arrow/compute/api_scalar.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/codegen_internal.o : src/src/arrow/compute/kernels/codegen_internal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/column_scanner.o : src/src/parquet/column_scanner.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/statistics.o : src/src/parquet/statistics.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/internal_file_decryptor.o : src/src/parquet/internal_file_decryptor.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/column_writer.o : src/src/parquet/column_writer.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/encryption.o : src/src/parquet/encryption.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/file_reader.o : src/src/parquet/file_reader.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/properties.o : src/src/parquet/properties.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/encryption_internal.o : src/src/parquet/encryption_internal.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/internal_file_encryptor.o : src/src/parquet/internal_file_encryptor.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/types.o : src/src/parquet/types.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/encoding.o : src/src/parquet/encoding.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/metadata.o : src/src/parquet/metadata.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/printer.o : src/src/parquet/printer.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/level_conversion.o : src/src/parquet/level_conversion.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/deprecated_io.o : src/src/parquet/deprecated_io.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/file_writer.o : src/src/parquet/file_writer.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/schema.o : src/src/parquet/schema.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/platform.o : src/src/parquet/platform.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@
bin/column_reader.o : src/src/parquet/column_reader.cc
$(CPP) $(CPPFLAGS) -c $< $(LIBS) -o $@

View File

@ -1,413 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include <cassert>
#include <fstream>
#include <iostream>
#include <memory>
#include "reader_writer.h"
/*
* This example describes writing and reading Parquet Files in C++ and serves as a
* reference to the API.
* The file contains all the physical data types supported by Parquet.
* This example uses the RowGroupWriter API that supports writing RowGroups optimized for
*memory consumption
**/
/* Parquet is a structured columnar file format
* Parquet File = "Parquet data" + "Parquet Metadata"
* "Parquet data" is simply a vector of RowGroups. Each RowGroup is a batch of rows in a
* columnar layout
* "Parquet Metadata" contains the "file schema" and attributes of the RowGroups and their
* Columns
* "file schema" is a tree where each node is either a primitive type (leaf nodes) or a
* complex (nested) type (internal nodes)
* For specific details, please refer the format here:
* https://github.com/apache/parquet-format/blob/master/LogicalTypes.md
**/
constexpr int NUM_ROWS_PER_ROW_GROUP = 500;
const char PARQUET_FILENAME[] = "parquet_cpp_example.parquet";
int main(int argc, char** argv) {
/**********************************************************************************
PARQUET WRITER EXAMPLE
**********************************************************************************/
// parquet::REQUIRED fields do not need definition and repetition level values
// parquet::OPTIONAL fields require only definition level values
// parquet::REPEATED fields require both definition and repetition level values
try {
// Create a local file output stream instance.
using FileClass = ::arrow::io::FileOutputStream;
std::shared_ptr<FileClass> out_file;
PARQUET_ASSIGN_OR_THROW(out_file, FileClass::Open(PARQUET_FILENAME));
// Setup the parquet schema
std::shared_ptr<GroupNode> schema = SetupSchema();
// Add writer properties
parquet::WriterProperties::Builder builder;
builder.compression(parquet::Compression::UNCOMPRESSED);
std::shared_ptr<parquet::WriterProperties> props = builder.build();
// Create a ParquetFileWriter instance
std::shared_ptr<parquet::ParquetFileWriter> file_writer =
parquet::ParquetFileWriter::Open(out_file, schema, props);
// Append a RowGroup with a specific number of rows.
parquet::RowGroupWriter* rg_writer = file_writer->AppendRowGroup();
// Write the Bool column
parquet::BoolWriter* bool_writer =
static_cast<parquet::BoolWriter*>(rg_writer->NextColumn());
for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
bool value = ((i % 2) == 0) ? true : false;
bool_writer->WriteBatch(1, nullptr, nullptr, &value);
}
// Write the Int32 column
parquet::Int32Writer* int32_writer =
static_cast<parquet::Int32Writer*>(rg_writer->NextColumn());
for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
int32_t value = i;
int32_writer->WriteBatch(1, nullptr, nullptr, &value);
}
// Write the Int64 column. Each row has repeats twice.
parquet::Int64Writer* int64_writer =
static_cast<parquet::Int64Writer*>(rg_writer->NextColumn());
for (int i = 0; i < 2 * NUM_ROWS_PER_ROW_GROUP; i++) {
int64_t value = i * 1000 * 1000;
value *= 1000 * 1000;
int16_t definition_level = 1;
int16_t repetition_level = 0;
if ((i % 2) == 0) {
repetition_level = 1; // start of a new record
}
int64_writer->WriteBatch(1, &definition_level, &repetition_level, &value);
}
// Write the INT96 column.
parquet::Int96Writer* int96_writer =
static_cast<parquet::Int96Writer*>(rg_writer->NextColumn());
for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
parquet::Int96 value;
value.value[0] = i;
value.value[1] = i + 1;
value.value[2] = i + 2;
int96_writer->WriteBatch(1, nullptr, nullptr, &value);
}
// Write the Float column
parquet::FloatWriter* float_writer =
static_cast<parquet::FloatWriter*>(rg_writer->NextColumn());
for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
float value = static_cast<float>(i) * 1.1f;
float_writer->WriteBatch(1, nullptr, nullptr, &value);
}
// Write the Double column
parquet::DoubleWriter* double_writer =
static_cast<parquet::DoubleWriter*>(rg_writer->NextColumn());
for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
double value = i * 1.1111111;
double_writer->WriteBatch(1, nullptr, nullptr, &value);
}
// Write the ByteArray column. Make every alternate values NULL
parquet::ByteArrayWriter* ba_writer =
static_cast<parquet::ByteArrayWriter*>(rg_writer->NextColumn());
for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
parquet::ByteArray value;
char hello[FIXED_LENGTH] = "parquet";
hello[7] = static_cast<char>(static_cast<int>('0') + i / 100);
hello[8] = static_cast<char>(static_cast<int>('0') + (i / 10) % 10);
hello[9] = static_cast<char>(static_cast<int>('0') + i % 10);
if (i % 2 == 0) {
int16_t definition_level = 1;
value.ptr = reinterpret_cast<const uint8_t*>(&hello[0]);
value.len = FIXED_LENGTH;
ba_writer->WriteBatch(1, &definition_level, nullptr, &value);
} else {
int16_t definition_level = 0;
ba_writer->WriteBatch(1, &definition_level, nullptr, nullptr);
}
}
// Write the FixedLengthByteArray column
parquet::FixedLenByteArrayWriter* flba_writer =
static_cast<parquet::FixedLenByteArrayWriter*>(rg_writer->NextColumn());
for (int i = 0; i < NUM_ROWS_PER_ROW_GROUP; i++) {
parquet::FixedLenByteArray value;
char v = static_cast<char>(i);
char flba[FIXED_LENGTH] = {v, v, v, v, v, v, v, v, v, v};
value.ptr = reinterpret_cast<const uint8_t*>(&flba[0]);
flba_writer->WriteBatch(1, nullptr, nullptr, &value);
}
// Close the ParquetFileWriter
file_writer->Close();
// Write the bytes to file
DCHECK(out_file->Close().ok());
} catch (const std::exception& e) {
std::cerr << "Parquet write error: " << e.what() << std::endl;
return -1;
}
/**********************************************************************************
PARQUET READER EXAMPLE
**********************************************************************************/
try {
// Create a ParquetReader instance
std::unique_ptr<parquet::ParquetFileReader> parquet_reader =
parquet::ParquetFileReader::OpenFile(PARQUET_FILENAME, false);
// Get the File MetaData
std::shared_ptr<parquet::FileMetaData> file_metadata = parquet_reader->metadata();
// Get the number of RowGroups
int num_row_groups = file_metadata->num_row_groups();
assert(num_row_groups == 1);
// Get the number of Columns
int num_columns = file_metadata->num_columns();
assert(num_columns == 8);
// Iterate over all the RowGroups in the file
for (int r = 0; r < num_row_groups; ++r) {
// Get the RowGroup Reader
std::shared_ptr<parquet::RowGroupReader> row_group_reader =
parquet_reader->RowGroup(r);
int64_t values_read = 0;
int64_t rows_read = 0;
int16_t definition_level;
int16_t repetition_level;
int i;
std::shared_ptr<parquet::ColumnReader> column_reader;
ARROW_UNUSED(rows_read); // prevent warning in release build
// Get the Column Reader for the boolean column
column_reader = row_group_reader->Column(0);
parquet::BoolReader* bool_reader =
static_cast<parquet::BoolReader*>(column_reader.get());
// Read all the rows in the column
i = 0;
while (bool_reader->HasNext()) {
bool value;
// Read one value at a time. The number of rows read is returned. values_read
// contains the number of non-null rows
rows_read = bool_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
// Ensure only one value is read
assert(rows_read == 1);
// There are no NULL values in the rows written
assert(values_read == 1);
// Verify the value written
bool expected_value = ((i % 2) == 0) ? true : false;
assert(value == expected_value);
i++;
}
// Get the Column Reader for the Int32 column
column_reader = row_group_reader->Column(1);
parquet::Int32Reader* int32_reader =
static_cast<parquet::Int32Reader*>(column_reader.get());
// Read all the rows in the column
i = 0;
while (int32_reader->HasNext()) {
int32_t value;
// Read one value at a time. The number of rows read is returned. values_read
// contains the number of non-null rows
rows_read = int32_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
// Ensure only one value is read
assert(rows_read == 1);
// There are no NULL values in the rows written
assert(values_read == 1);
// Verify the value written
assert(value == i);
i++;
}
// Get the Column Reader for the Int64 column
column_reader = row_group_reader->Column(2);
parquet::Int64Reader* int64_reader =
static_cast<parquet::Int64Reader*>(column_reader.get());
// Read all the rows in the column
i = 0;
while (int64_reader->HasNext()) {
int64_t value;
// Read one value at a time. The number of rows read is returned. values_read
// contains the number of non-null rows
rows_read = int64_reader->ReadBatch(1, &definition_level, &repetition_level,
&value, &values_read);
// Ensure only one value is read
assert(rows_read == 1);
// There are no NULL values in the rows written
assert(values_read == 1);
// Verify the value written
int64_t expected_value = i * 1000 * 1000;
expected_value *= 1000 * 1000;
assert(value == expected_value);
if ((i % 2) == 0) {
assert(repetition_level == 1);
} else {
assert(repetition_level == 0);
}
i++;
}
// Get the Column Reader for the Int96 column
column_reader = row_group_reader->Column(3);
parquet::Int96Reader* int96_reader =
static_cast<parquet::Int96Reader*>(column_reader.get());
// Read all the rows in the column
i = 0;
while (int96_reader->HasNext()) {
parquet::Int96 value;
// Read one value at a time. The number of rows read is returned. values_read
// contains the number of non-null rows
rows_read = int96_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
// Ensure only one value is read
assert(rows_read == 1);
// There are no NULL values in the rows written
assert(values_read == 1);
// Verify the value written
parquet::Int96 expected_value;
ARROW_UNUSED(expected_value); // prevent warning in release build
expected_value.value[0] = i;
expected_value.value[1] = i + 1;
expected_value.value[2] = i + 2;
for (int j = 0; j < 3; j++) {
assert(value.value[j] == expected_value.value[j]);
}
i++;
}
// Get the Column Reader for the Float column
column_reader = row_group_reader->Column(4);
parquet::FloatReader* float_reader =
static_cast<parquet::FloatReader*>(column_reader.get());
// Read all the rows in the column
i = 0;
while (float_reader->HasNext()) {
float value;
// Read one value at a time. The number of rows read is returned. values_read
// contains the number of non-null rows
rows_read = float_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
// Ensure only one value is read
assert(rows_read == 1);
// There are no NULL values in the rows written
assert(values_read == 1);
// Verify the value written
float expected_value = static_cast<float>(i) * 1.1f;
assert(value == expected_value);
i++;
}
// Get the Column Reader for the Double column
column_reader = row_group_reader->Column(5);
parquet::DoubleReader* double_reader =
static_cast<parquet::DoubleReader*>(column_reader.get());
// Read all the rows in the column
i = 0;
while (double_reader->HasNext()) {
double value;
// Read one value at a time. The number of rows read is returned. values_read
// contains the number of non-null rows
rows_read = double_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
// Ensure only one value is read
assert(rows_read == 1);
// There are no NULL values in the rows written
assert(values_read == 1);
// Verify the value written
double expected_value = i * 1.1111111;
assert(value == expected_value);
i++;
}
// Get the Column Reader for the ByteArray column
column_reader = row_group_reader->Column(6);
parquet::ByteArrayReader* ba_reader =
static_cast<parquet::ByteArrayReader*>(column_reader.get());
// Read all the rows in the column
i = 0;
while (ba_reader->HasNext()) {
parquet::ByteArray value;
// Read one value at a time. The number of rows read is returned. values_read
// contains the number of non-null rows
rows_read =
ba_reader->ReadBatch(1, &definition_level, nullptr, &value, &values_read);
// Ensure only one value is read
assert(rows_read == 1);
// Verify the value written
char expected_value[FIXED_LENGTH] = "parquet";
ARROW_UNUSED(expected_value); // prevent warning in release build
expected_value[7] = static_cast<char>('0' + i / 100);
expected_value[8] = static_cast<char>('0' + (i / 10) % 10);
expected_value[9] = static_cast<char>('0' + i % 10);
if (i % 2 == 0) { // only alternate values exist
// There are no NULL values in the rows written
assert(values_read == 1);
assert(value.len == FIXED_LENGTH);
assert(memcmp(value.ptr, &expected_value[0], FIXED_LENGTH) == 0);
assert(definition_level == 1);
} else {
// There are NULL values in the rows written
assert(values_read == 0);
assert(definition_level == 0);
}
i++;
}
// Get the Column Reader for the FixedLengthByteArray column
column_reader = row_group_reader->Column(7);
parquet::FixedLenByteArrayReader* flba_reader =
static_cast<parquet::FixedLenByteArrayReader*>(column_reader.get());
// Read all the rows in the column
i = 0;
while (flba_reader->HasNext()) {
parquet::FixedLenByteArray value;
// Read one value at a time. The number of rows read is returned. values_read
// contains the number of non-null rows
rows_read = flba_reader->ReadBatch(1, nullptr, nullptr, &value, &values_read);
// Ensure only one value is read
assert(rows_read == 1);
// There are no NULL values in the rows written
assert(values_read == 1);
// Verify the value written
char v = static_cast<char>(i);
char expected_value[FIXED_LENGTH] = {v, v, v, v, v, v, v, v, v, v};
assert(memcmp(value.ptr, &expected_value[0], FIXED_LENGTH) == 0);
i++;
}
}
} catch (const std::exception& e) {
std::cerr << "Parquet read error: " << e.what() << std::endl;
return -1;
}
std::cout << "Parquet Writing and Reading Complete" << std::endl;
return 0;
}

View File

@ -1,71 +0,0 @@
// Licensed to the Apache Software Foundation (ASF) under one
// or more contributor license agreements. See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership. The ASF licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License. You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied. See the License for the
// specific language governing permissions and limitations
// under the License.
#include <arrow/io/file.h>
#include <arrow/util/logging.h>
#include <parquet/api/reader.h>
#include <parquet/api/writer.h>
using parquet::ConvertedType;
using parquet::Repetition;
using parquet::Type;
using parquet::schema::GroupNode;
using parquet::schema::PrimitiveNode;
constexpr int FIXED_LENGTH = 10;
static std::shared_ptr<GroupNode> SetupSchema() {
parquet::schema::NodeVector fields;
// Create a primitive node named 'boolean_field' with type:BOOLEAN,
// repetition:REQUIRED
fields.push_back(PrimitiveNode::Make("boolean_field", Repetition::REQUIRED,
Type::BOOLEAN, ConvertedType::NONE));
// Create a primitive node named 'int32_field' with type:INT32, repetition:REQUIRED,
// logical type:TIME_MILLIS
fields.push_back(PrimitiveNode::Make("int32_field", Repetition::REQUIRED, Type::INT32,
ConvertedType::TIME_MILLIS));
// Create a primitive node named 'int64_field' with type:INT64, repetition:REPEATED
fields.push_back(PrimitiveNode::Make("int64_field", Repetition::REPEATED, Type::INT64,
ConvertedType::NONE));
fields.push_back(PrimitiveNode::Make("int96_field", Repetition::REQUIRED, Type::INT96,
ConvertedType::NONE));
fields.push_back(PrimitiveNode::Make("float_field", Repetition::REQUIRED, Type::FLOAT,
ConvertedType::NONE));
fields.push_back(PrimitiveNode::Make("double_field", Repetition::REQUIRED, Type::DOUBLE,
ConvertedType::NONE));
// Create a primitive node named 'ba_field' with type:BYTE_ARRAY, repetition:OPTIONAL
fields.push_back(PrimitiveNode::Make("ba_field", Repetition::OPTIONAL, Type::BYTE_ARRAY,
ConvertedType::NONE));
// Create a primitive node named 'flba_field' with type:FIXED_LEN_BYTE_ARRAY,
// repetition:REQUIRED, field_length = FIXED_LENGTH
fields.push_back(PrimitiveNode::Make("flba_field", Repetition::REQUIRED,
Type::FIXED_LEN_BYTE_ARRAY, ConvertedType::NONE,
FIXED_LENGTH));
// Create a GroupNode named 'schema' using the primitive nodes defined above
// This GroupNode is the root node of the schema tree
return std::static_pointer_cast<GroupNode>(
GroupNode::Make("schema", Repetition::REQUIRED, fields));
}

View File

@ -1,6 +0,0 @@
#!/bin/bash
mkdir src
cat deps.log | while read f; do cp --parents $f src/; done;
mv src/home/mario/Desktop/arrow/cpp/* src/
rm -r src/home/

View File

@ -1,171 +0,0 @@
#!/bin/bash
#-----------------------------------------------------------------------------#
# NOTE: before starting to extract the minimal required sources and dependencies
# run
# $ cd cpp/
# $ cmake -D ARROW_PARQUET=ON
# in the arrow repository
# provide
# - local path of clone of https://github.com/apache/arrow.git
# - name/path of main .hpp file of cython extension
repo="$1"
main="$2"
depf="$3"
# check CLI arguments
if [ -z "$repo" ] || [ -z "$main" ] || [ -z "$depf" ]; then
echo "please provide..."
echo "1. local path of arrow repository"
echo "2. name of main .hpp/.cpp"
echo "3. desired name of dependency file"
echo -e "example:\n./setup-sources.sh /home/mario/Desktop/Record_Evolution/arrow/ reader-writer.cc deps.log"
exit 1
fi
echo -e "extracting sources from/for \n1: ${repo}\n2: ${main}\n3: ${depf}\n"
# make sure the dependency file is empty
rm -f ${depf}
touch ${depf}
# define maximal recursion depth
maxdep=8
#-----------------------------------------------------------------------------#
# define function to list dependencies of source file in repository recursively
listDependencies()
{
rep="$1"
src="$2"
dep="$3"
rec="$4"
echo -e "\nstarting 'listDependencies()' for\n1. ${rep}\n2. ${src}\n3. ${dep}\n4. ${rec}"
# generate dependency file (and remove resulting object file)
echo -e "g++ -c -MMD ${src} -I ${rep}cpp/src/\n"
g++ -c -MMD ${src} -I ${rep}cpp/src/
# derive name of dependency and object files
depf=$(basename ${src} | sed 's/.cc/.d/g')
objf=$(basename ${src} | sed 's/.cc/.o/g')
rm ${objf}
# list dependencies by
# 1. removing header
# 2. remove source itself
# 3. delete leading spaces
# 4. delete trailing backslashs
# 5. remove empty lines
cat ${depf} | grep ${rep} | grep -v ${src} | tr -d "^ " | tr -d "\\\\" | awk 'NF' > listdep.log
# rm ${depf}
while IFS= read -r fs
do
echo "$fs"
# check if dependency is already in the list
if grep -Fxq "$fs" "$dep"
then
echo "dep exist"
else
echo "dep does not exist yet => adding it"
# add dependency to list
echo "$fs" >> ${dep}
# check for corresponding source file
fssourc=$(echo ${fs} | sed 's/.h$/.cc/g' | sed 's/.hpp$/.cpp/g')
echo ${fssourc}
if [ -f "$fssourc" ]
then
echo "source file exists"
# list nested dependencies
if [ "$rec" -lt "$maxdep" ]
then
# increment recursion depth
recinc=$(($rec+1))
# call recursion
listDependencies ${rep} ${fssourc} ${dep} ${recinc}
else
echo "maximal recursion depth exceeded"
fi
else
echo "source file does not exist"
fi
fi
echo ""
done < listdep.log
# cat listdep.log | while read fs
# do
# echo $fs
# # check if dependency is already in the list
# inlist=$(cat listdep.log | grep ${fs} | wc -l)
# echo ${inlist}
# # check for any corresponding source files
# # if [ -f ]
# done
}
#-----------------------------------------------------------------------------#
# call function to list dependencies (recursively)
listDependencies ${repo} ${main} ${depf} 0
# # generate dependency file (and remove resulting object file)
# echo -e "generate dependencies:\ng++ -c -MMD ${main} -I ./ -I ${repo}cpp/src/\n"
# g++ -c -MMD ${main} -I ${repo}cpp/src/
# rm $(echo ${main} | sed 's/.cc/.o/g')
#
# # derive name of dependency file
# dep=$(echo ${main} | sed 's/.cc/.d/g')
#
# if [ -f "$dep" ]; then
#
# # list dependencies
# cat ${dep} | sed 's/ /\n/g' | awk 'NF' | grep -v '\\' | grep '\/' > deps.log
#
# # extract list of headers
# cat deps.log | sed ':a;N;$!ba;s/\n/ /g' > deps-headers.log
# echo "list of required headers ($(cat deps.log | wc -l))"
# cat deps-headers.log
# echo ""
#
# # imply list of sources
# cat deps.log | sed 's/.h$/.cc/g' | sed 's/.hpp$/.cpp/g' > sources_raw.log
# cat sources_raw.log | while read f
# do
# if [ -f "$f" ]; then
# echo $f >> sources_check.log
# fi
# done
# cat sources_check.log | sed ':a;N;$!ba;s/\n/ /g' > deps-sources.log
# echo "list of required sources ($(cat sources_check.log | wc -l))"
# cat deps-sources.log
# echo ""
#
# # remove all temporary files
# rm ${dep} deps.log
# rm sources_raw.log sources_check.log
#
# # copy required headers and sources
# echo -e "copy required headers and sources"
# mkdir temp/
# cp --parents `cat deps-headers.log` temp/
# cp --parents `cat deps-sources.log` temp/
# mv temp${repo}cpp/src/* ./
# rm -r temp
#
# # remove dependencies
# #rm deps-headers.log deps-sources.log
#
# # show files
# ls -lh
#
# else
#
# echo -e "\nERROR: failed to generate dependency file\n"
#
# fi

View File

@ -1,26 +0,0 @@
FROM ubuntu:19.10
RUN apt-get update -y && apt-get install -y \
apt-utils \
git g++ \
make cmake \
pkg-config \
#build-essentials \
python3 \
python3-setuptools \
cython3 \
python3-numpy
RUN git clone https://github.com/apache/arrow.git --single-branch --depth=1
COPY . ./
RUN chmod u+x ./build_arrow_cpp.sh
RUN chmod u+x ./build_arrow_python.sh
RUN ./build_arrow_cpp.sh
RUN ./build_arrow_python.sh
#RUN chmod u+x ./build_arrow.sh
#CMD ["./build_arrow.sh"]
CMD ["sleep 1d"]

View File

@ -1,5 +0,0 @@
#!/bin/bash
docker build . --tag=pyarrowbuild:latest
docker run -it pyarrowbuild:latest /bin/bash

View File

@ -1,65 +0,0 @@
#!/bin/bash
sleep infinity
startts=$(date)
echo "starting build process at ${startts}..."
echo -e "\nhome directory is..."
pwd
echo -e "\ncloning apache/arrow..."
git clone https://github.com/apache/arrow.git --single-branch --depth=1
echo -e "\nls -lh /\n"
ls -lh /
echo -e "\nls -lh arrow/\n"
ls -lh arrow/
echo -e "\nls -lh arrow/python/\n"
ls -lh arrow/python
mkdir arrow/cpp/build
pushd arrow/cpp/build
cmake -DCMAKE_INSTALL_PREFIX=$ARROW_HOME \
-DCMAKE_INSTALL_LIBDIR=lib \
-DARROW_WITH_BZ2=ON \
-DARROW_WITH_ZLIB=ON \
-DARROW_WITH_ZSTD=ON \
-DARROW_WITH_LZ4=ON \
-DARROW_WITH_SNAPPY=ON \
-DARROW_WITH_BROTLI=ON \
-DARROW_PARQUET=ON \
-DARROW_PYTHON=ON \
-DARROW_BUILD_TESTS=OFF \
-DARROW_WITH_HDFS=OFF \
..
make -j4
make install
popd
#cython --version
cython3 --version
pushd arrow/python
export ARROW_LIB_DIR=/lib/
export PYARROW_WITH_PARQUET=1
export PYARROW_WITH_CUDA=0
export PYARROW_WITH_FlIGHT=0
export PYARROW_WITH_DATASET=0
export PYARROW_WITH_ORC=0
export PYARROW_WITH_PLASMA=0
export PYARROW_WITH_S3FS=0
export PYARROW_WITH_HDFS=0
export PYARROW_WITH_GANDIVA=0
python3 setup.py build_ext --inplace
popd
echo " started build process at ${startts} ..."
finishts=$(date)
echo "finishing build process at ${finishts}..."

View File

@ -1,23 +0,0 @@
#!/bin/bash
mkdir arrow/cpp/build
pushd arrow/cpp/build
cmake -DCMAKE_INSTALL_PREFIX=$ARROW_HOME \
-DCMAKE_INSTALL_LIBDIR=lib \
-DARROW_WITH_BZ2=ON \
-DARROW_WITH_ZLIB=ON \
-DARROW_WITH_ZSTD=ON \
-DARROW_WITH_LZ4=ON \
-DARROW_WITH_SNAPPY=ON \
-DARROW_WITH_BROTLI=ON \
-DARROW_PARQUET=ON \
-DARROW_PYTHON=ON \
-DARROW_BUILD_TESTS=OFF \
-DARROW_WITH_HDFS=OFF \
-DARROW_WITH_IPC=OFF \
..
make -j4
make install
popd

View File

@ -1,15 +0,0 @@
#!/bin/bash
pushd arrow/python
export PYARROW_WITH_PARQUET=1
export PYARROW_WITH_CUDA=0
export PYARROW_WITH_FlIGHT=0
export PYARROW_WITH_DATASET=0
export PYARROW_WITH_ORC=0
export PYARROW_WITH_PLASMA=0
export PYARROW_WITH_S3FS=0
export PYARROW_WITH_HDFS=0
export PYARROW_WITH_GANDIVA=0
# python3 setup.py build_ext --inplace
python3 setup.py install
popd

View File

@ -1,23 +0,0 @@
build :
docker build . --tag pyarrowbuild
run :
docker run -it pyarrowbuild:latest
run-bash :
docker run -it --volume=$(pwd)/build:/home pyarrowbuild:latest /bin/bash
run-volume :
docker run -it -v /home/pirate/pyarrow/build/:/arrow/python/ pyarrowbuild:latest
#sudo docker run -it --volume=$(pwd)/build:/home ubuntu:latest /bin/bash
rm-container :
cont=$(docker ps -a | tail -n 26 | awk '{print $NF}' | sed ':a;N;$!ba;s/\n/ /g')
echo ${cont}
docker rm ${cont}
rm-image :
img=$(docker image ls --quiet | sed ':a;N;$!ba;s/\n/ /g')
docker image rm ${img}

File diff suppressed because it is too large Load Diff

View File

@ -1,18 +0,0 @@
import pyarrow.parquet as pq
import pyarrow.csv as pv
csvfile = 'pressureVacuum.csv'
tb = pv.read_csv(csvfile,parse_options=pv.ParseOptions(delimiter=','))
print(tb)
parquetfile = 'pressureVacuum.parquet'
pq.write_table(tb,parquetfile,compression='BROTLI')
# {'NONE', 'SNAPPY', 'GZIP', 'LZO', 'BROTLI', 'LZ4', 'ZSTD'}
df = pq.read_table(parquetfile,columns=None)
print(df)

View File

@ -1,8 +0,0 @@
#!/bin/bash
if [ -z "$1" ]
then
exit 1
fi
scp $1 pirate@mf-pi-40:/home/pirate/pyarrow/

160
makefile
View File

@ -1,92 +1,114 @@
#-----------------------------------------------------------------------------#
# choose shell
SHELL := /bin/bash
RAW = ../raw/
# name of executable and CLI tool
EXE = imctermite
# directory names
SRC = src/
LIB = lib/
CYT = cyt/
PYT = python/
# name of executable
EXE = eatraw
# list headers and include directories
HPP = $(wildcard $(LIB)/*.hpp)
IPP = $(shell find $(LIB) -type f -name '*.hpp')
KIB = $(shell find $(LIB) -type d)
MIB = $(foreach dir,$(KIB),-I $(dir))
# compiler and its options
CCC = g++ -std=c++11
#OPT = -O3 -Wall -mavx -mno-tbm -mf16c -mno-f16c
OPT = -O3 -Wall -Werror
# choose compiler and its options
CC = g++ -std=c++17
OPT = -O3 -Wall -Wconversion -Wpedantic -Werror -Wunused-variable -Wsign-compare
# determine git version/commit and release tag
GTAG := $(shell git tag -l --sort=version:refname | tail -n1 | sed "s/$^v//g")
GHSH := $(shell git rev-parse HEAD | head -c8)
GVSN := $(shell cat python/VERSION | tr -d ' \n')
# current timestamp
TMS = $(shell date +%Y%m%dT%H%M%S)
# define install location
INST := /usr/local/bin
#-----------------------------------------------------------------------------#
# C++
# C++ and CLI tool
# build executable
$(EXE) : $(SRC)main.cpp $(LIB)raweat.hpp $(LIB)hexshow.hpp $(LIB)rawmerge.hpp output
$(CCC) $(OPT) $< -o $@
$(EXE): check-tags $(GVSN) main.o
$(CC) $(OPT) main.o -o $@
# development version
eatdev : $(SRC)main_dev.cpp $(LIB)raweat.hpp
$(CCC) $(OPT) $< -o $@
# build main.cpp and include git version/commit tag
main.o: src/main.cpp $(IPP)
@cp $< $<.cpp
@sed -i 's/TAGSTRING/$(GTAG)/g' $<.cpp
@sed -i 's/HASHSTRING/$(GHSH)/g' $<.cpp
@sed -i 's/TIMESTAMPSTRING/$(TMS)/g' $<.cpp
$(CC) -c $(OPT) $(MIB) $<.cpp -o $@
@rm $<.cpp
# build target for conversion set of .raw files
eatall : $(SRC)eatall.cpp $(LIB)raweat.hpp
$(CCC) $(OPT) $< -o $@
# remove executable
clean :
rm -f $(EXE)
rm -f eatall
rm -f eatdev
rm -rf output/
# check existence of name of executable globally
chexe:=$(shell command -v $(EXE))
# install executable if name does not exist yet
install: $(EXE)
ifeq ($(chexe),)
cp $(EXE) /usr/local/bin/
else
@echo "executable with name already exists! choose different name!"
@exit 1
endif
cp $< $(INST)/
# uninstall
uninstall :
rm /usr/local/bin/$(EXE)
uninstall: $(INST)/$(EXE)
rm $<
cpp-clean:
rm -vf $(EXE)
rm -vf *.o
#-----------------------------------------------------------------------------#
# Python
# C++ linter
# build python module
py : $(CYT)setup_raw_eater.py $(CYT)raw_eater.pyx $(CYT)raw_eater.pxd $(LIB)raweat.hpp \
$(CYT)setup_raw_meat.py $(CYT)raw_meat.pyx $(CYT)raw_meat.pxd $(LIB)rawmerge.hpp \
output
python3 $(CYT)setup_raw_eater.py build_ext --inplace
python3 $(CYT)setup_raw_meat.py build_ext --inplace
cp raw_eater.cpython-*.so pyt/
cp raw_meat.cpython-*.so pyt/
rm *.so
py-install: $(CYT)setup_raw_eater.py $(CYT)raw_eater.pyx $(CYT)raw_eater.pxd $(LIB)raweat.hpp \
$(CYT)setup_raw_meat.py $(CYT)raw_meat.pyx $(CYT)raw_meat.pxd $(LIB)rawmerge.hpp
python3 $(CYT)setup_raw_eater.py install --record files_raw_eater.txt
python3 $(CYT)setup_raw_meat.py install --record files_raw_meat.txt
py-clean :
rm -f raw_eater.cpython-*.so
rm -f pyt/raw_eater.cpython-*.so
rm -f $(CYT)raw_eater.cpp
rm -f raw_meat.cpython-*.so
rm -f pyt/raw_meat.cpython-*.so
rm -f $(CYT)raw_meat.cpp
rm -rf build/
rm -f *.txt
rm -rf output/
# prepare directory for test output
output :
mkdir -pv output/
check-code:
cppcheck --enable=all -I lib/ src/main.cpp
#-----------------------------------------------------------------------------#
# versions
$(GTAG):
@echo "consistent versions check successful: building $(GTAG)"
check-tags:
@echo "latest git tag: $(GTAG)"
@echo "latest git hash: $(GHSH)"
@echo "python version: $(GVSN)"
#-----------------------------------------------------------------------------#
# Docker
docker-build:
docker build ./ --tag imctermite:0.1
docker-run:
docker run -it --rm imctermite:0.1 /bin/bash
#-----------------------------------------------------------------------------#
# python
python-build: check-tags $(GVSN)
make -C python/ build-inplace
cp python/imctermite*.so ./ -v
python-clean:
make -C python/ clean
rm -vf imctermite*.so
python-test:
PYTHONPATH=./ python python/examples/usage.py
#-----------------------------------------------------------------------------#
# clean
clean: cpp-clean python-clean
#-----------------------------------------------------------------------------#
# github actions
github-action-lint: .github/workflows/pypi-deploy.yml
actionlint $<
# for reference, see:
# https://github.com/rhysd/actionlint
#-----------------------------------------------------------------------------#

View File

@ -1,138 +0,0 @@
#-----------------------------------------------------------------------------#
import raw_eater
import raw_meat
import pyarrow as pa
import pyarrow.parquet as pq
import glob
from pathlib import Path
fileobj1 = Path("smp/Rangerover_Evoque_F-RR534_2019-05-07/").rglob("*.raw")
rawlist1 = [str(fl) for fl in fileobj1]
fileobj2 = Path("smp/Mercedes_E-Klasse-2019-08-08/").rglob("*.raw")
rawlist2 = [str(fl) for fl in fileobj2]
rawlist = rawlist1 #[rawlist1[0],rawlist1[4],rawlist2[0],rawlist2[6]]
for fil in rawlist2 :
rawlist.append(fil)
rawlist.append("smp/pressure_Vacuum.asc")
print("")
print(rawlist)
print()
#-----------------------------------------------------------------------------#
# alternatively create "empty" instance of "raw_eater" and set file names
eatraw = raw_eater.raweater()
# eatraw.set_file("../smp/pressure_Vacuum.raw".encode())
# convert every single listed file
for rf in rawlist :
print("converting " + str(rf) + "...\n" + 90*("-") + "\n")
# setup instance of "raw_eater" and trigger conversion
# eatraw = raw_eater.raweater(rf.encode())
# eatraw = raw_meat.rawmerger(rf.encode())
# use global instance of "raw_eater" to set file and perform decoding
eatraw.set_file(rf.encode())
try :
eatraw.do_conversion()
except RuntimeError as e :
print("conversion failed: " + str(e))
# check validity of file format
if eatraw.validity() :
# show channel name and its unit
entity = eatraw.channel_name().decode(encoding='UTF-8',errors='ignore')
unit = eatraw.unit().decode(encoding='UTF-8',errors='ignore')
print("\nentity: " + str(entity))
print("unit: " + str(unit) + "\n")
# obtain extracted data
xt = eatraw.get_time()
yt = eatraw.get_channel()
# show excerpt of data
print("time (length: " + str(len(xt)) + ") \n"
+ str(xt[:10]) + "\n...\n" + str(xt[-10:]) + "\n")
yttrunc = [round(y,4) for y in yt]
print(str(entity) + " (length: " + str(len(yttrunc)) + ") \n"
+ str(yttrunc[:10]) + "\n...\n" + str(yttrunc[-10:]) + "\n")
outname = rf.split('/')[-1].replace('raw','csv')
print("write output to : " + outname)
eatraw.write_table(("output/"+outname).encode(),ord(' '))
else :
print("\nerror: invalid/corrupt .raw file")
print("\n")
#-----------------------------------------------------------------------------#
print("convert and merge channels " + "\n" + 90*("-") + "\n")
# setup new instance to merge channels
eatmea = raw_meat.rawmerger(''.encode()) #rawlist[0].encode())
# add every single channel/file in list
for rf in rawlist :
print("\nadding channel " + str(rf))
try :
succ = eatmea.add_channel(rf.encode())
print("\nrecent time series: length: " + str(len(eatmea.get_time_series())) + "\n")
except RuntimeError as e :
print("failed to add channel: " + str(e))
# show summary of successfully merged channels
print("\nmerged channels:\n")
# write merged table to .csv output
eatmea.write_table_all('output/allchannels.csv'.encode(),ord(','))
# get number of successfully merged channels and their names (+units)
numch = eatmea.get_num_channels()
chnames = [chnm.decode(encoding='UTF-8',errors='ignore') for chnm in eatmea.get_channel_names()]
print("number of channels: " + str(numch))
print("channel names: " + str(chnames))
# obtain final time series
timse = eatmea.get_time_series()
print("\nfinal time series:\nlength:" + str(len(timse)) + "\n")
# get time unit and prepend column name
chnames.insert(0,"Time ["+str(eatmea.time_unit().decode(encoding='UTF-8',errors='ignore'))+"]")
# prepare list of pyarrow arrays
pyarrs = []
pyarrs.append(pa.array(timse))
for i in range(0,numch) :
print("\n" + str(i) + " " + str(chnames[i]))
dat = eatmea.get_channel_by_index(i)
print("length: " + str(len(dat)))
pyarrs.append(pa.array(dat))
print("")
# print("\npyarrow arrays\n" + str(pyarrs))
# create pyarrow table from data
pyarwtab = pa.Table.from_arrays(pyarrs,chnames)
print("\n" + 60*"-" + "\n" + str(pyarwtab) + "\n")
# write pyarrow table to .parquet file with compression
pq.write_table(pyarwtab,'output/allchannels.parquet',compression='BROTLI') # compression='BROTLI', 'SNAPPY')
# try to read and decode the .parquet file
df = pq.read_table('output/allchannels.parquet')
print(df.to_pandas())
# df.to_pandas().to_csv('allchannels.csv',index=False,encoding='utf-8',sep=",")
#-----------------------------------------------------------------------------#

View File

@ -1,24 +0,0 @@
import pyarrow as pa
import numpy as np
import pyarrow.parquet as pq
db = pa.array(np.linspace(10,50,6))
print(db)
da = pa.array(np.linspace(0,5,6))
print(db)
filenam = 'pyarrow_testtab.parquet'
patab = pa.Table.from_arrays([da,db],['entity A [unitA]','entity B [unitB]'])
print(patab)
# pq.write_table(patab,filenam,compression='BROTLI')
pq.write_table(patab,filenam,compression='SNAPPY')
df = pq.read_table(filenam)
print(df)
print(df.to_pandas())
#import readline
#readline.write_history_file('generate_pyarrow_table_and_write_parquet.py')

5
python/MANIFEST.in Normal file
View File

@ -0,0 +1,5 @@
include lib/*.hpp
include *.cpp
include *.pyx
include *.pxd
include VERSION

1
python/VERSION Normal file
View File

@ -0,0 +1 @@
2.1.18

View File

@ -0,0 +1,43 @@
import imctermite
import pandas
import datetime
def add_trigger_time(trigger_time, add_time) :
trgts = datetime.datetime.strptime(trigger_time,'%Y-%m-%dT%H:%M:%S')
dt = datetime.timedelta(seconds=add_time)
return (trgts + dt).strftime('%Y-%m-%dT%H:%M:%S:%f')
if __name__ == "__main__" :
# read file and extract data
imctm = imctermite.imctermite(b"Measurement.raw")
chns = imctm.get_channels(True)
# prepare abscissa
xcol = "time ["+chns[0]['xunit']+"]"
#xcol = "timestamp"
xsts = [add_trigger_time(chns[0]['trigger-time'],tm) for tm in chns[0]['xdata']]
# sort channels
chnnms = sorted([chn['name'] for chn in chns], reverse=False)
chnsdict = {}
for chn in chns :
chnsdict[chn['name']] = chn
# construct dataframe
df = pandas.DataFrame()
df[xcol] = pandas.Series(chns[0]['xdata'])
#df[xcol] = pandas.Series(xsts)
#for idx,chn in enumerate(chns) :
for chnnm in chnnms :
chn = chnsdict[chnnm]
#xcol = (chn['xname'] if chn['xname'] != '' else "x_"+str(idx))+" ["+chn['xunit']+"]"
#df[xcol] = pandas.Series(chn['xdata'])
ycol = chn['yname']+" ["+chn['yunit']+"]"
df[ycol] = pandas.Series(chn['ydata'])
# show entire dataframe and write file
print(df)
df.to_csv("Measurement.csv",header=True,sep='\t',index=False)

38
python/examples/usage.py Normal file
View File

@ -0,0 +1,38 @@
import imctermite
import json
import os
# declare and initialize instance of "imctermite" by passing a raw-file
try :
imcraw = imctermite.imctermite(b"samples/exampleB.raw")
except RuntimeError as e :
raise Exception("failed to load/parse raw-file: " + str(e))
# obtain list of channels as list of dictionaries (without data)
channels = imcraw.get_channels(False)
print(json.dumps(channels,indent=4, sort_keys=False))
# obtain data of first channel (with data)
channelsdata = imcraw.get_channels(True)
if len(channelsdata) > 0 :
chnydata = channelsdata[0]['ydata']
chnxdata = channelsdata[0]['xdata']
print(len(chnydata))
print(len(chnxdata))
print()
# print the channels into a specific directory
imcraw.print_channels(b"/tmp/",ord(','))
# print all channels separately
for i,chn in enumerate(channels) :
print(str(i)+" : "+chn['name']+" : "+chn['uuid'])
filname = os.path.join("/tmp/",str(i) + "_" + chn['name']+".csv")
print(filname)
imcraw.print_channel(chn['uuid'].encode(),filname.encode(),ord(','))
# print all channels in single file
imcraw.print_table(b"/tmp/allchannels.csv")

View File

@ -0,0 +1,30 @@
import imctermite
import json
import os
# list files in sample directory
# fileobj1 = Path("samples/").rglob("*.raw")
# rawlist1 = [str(fl) for fl in fileobj1]
rawlist1 = ["samples/datasetB/datasetB_29.raw"]
print(rawlist1)
for fl in rawlist1:
print("converting " + str(fl) + " : " + str(os.path.basename(fl)) )
# declare and initialize instance of "imctermite" by passing a raw-file
try :
imcraw = imctermite.imctermite(fl.encode())
except RuntimeError as e :
raise Exception("failed to load/parse raw-file: " + str(e))
# obtain list of channels as list of dictionaries (without data)
channels = imcraw.get_channels(False)
print(json.dumps(channels,indent=4, sort_keys=False))
# print the channels into a specific directory
imcraw.print_channels(b"./",ord(','))
# print all channels in single file
imcraw.print_table(("./"+str(os.path.basename(fl).split('.')[0])+"_allchannels.csv").encode())

View File

@ -0,0 +1,50 @@
import imctermite
import json
import os
import datetime
# declare and initialize instance of "imctermite" by passing a raw-file
try :
imcraw = imctermite.imctermite(b"samples/sampleB.raw")
except RuntimeError as e :
raise Exception("failed to load/parse raw-file: " + str(e))
# obtain list of channels as list of dictionaries (without data)
channels = imcraw.get_channels(False)
print(json.dumps(channels,indent=4, sort_keys=False))
# obtain all channels (including full data)
channelsdata = imcraw.get_channels(True)
# everything that follows is an example that specifically makes use only of
# the first (index = 0) channel ...
idx = 0
if len(channelsdata) > 0 :
# get first channel's data
chnydata = channelsdata[idx]['ydata']
chnxdata = channelsdata[idx]['xdata']
print("xdata: " + str(len(chnxdata)))
print("ydata: " + str(len(chnydata)))
# extract trigger-time
trigtim = datetime.datetime.fromisoformat(channels[idx]["trigger-time"])
print(trigtim)
# file output of data with absolute timestamp in 1st column
filname = os.path.join("./",channelsdata[idx]['name']+".csv")
print("writing output into " + filname)
with open(filname,'w') as fout :
# include column header
fout.write( str(channelsdata[idx]['xname']) + '[' + str(channelsdata[idx]['xunit']) + "]"
+ ","
+ str(channelsdata[idx]['yname']) + '[' + str(channelsdata[idx]['yunit']) + "]"
+ "\n" )
# add data (introduce time shift according to trigger-time)
for row in range(0,len(chnxdata)) :
fout.write( str( (trigtim + datetime.timedelta(seconds=chnxdata[row])).isoformat() )
+ ","
+ str( chnydata[row])
+ "\n" )

View File

@ -0,0 +1,29 @@
import imctermite import imctermite
def show_results(imcraw) :
channels = imcraw.get_channels(False)
print(channels)
channelsData = imcraw.get_channels(True)
print("number of channels: " + str(len(channelsData)))
for (i,chn) in enumerate(channelsData) :
print(str(i) + " | " + chn['name'])
print(chn['xname'] + " | " + chn['xunit'])
print(chn['xdata'][:10])
print(chn['yname'] + " | " + chn['yunit'])
print(chn['ydata'][:10])
print("")
# create instance of 'imctermite'
imcraw = imctermite(b'samples/sampleA.raw')
show_results(imcraw)
# use previous instance of 'imctermite' to provide new file
imcraw.submit_file(b'samples/sampleB.raw')
show_results(imcraw)

24
python/imctermite.pxd Normal file
View File

@ -0,0 +1,24 @@
# use some C++ STL libraries
from libcpp.string cimport string
from libcpp.vector cimport vector
from libcpp cimport bool
cdef extern from "lib/imc_raw.hpp" namespace "imc":
cdef cppclass cppimctermite "imc::raw":
# constructor(s)
cppimctermite() except +
cppimctermite(string rawfile) except +
# provide raw file
void set_file(string rawfile) except +
# get JSON list of channels
vector[string] get_channels(bool json, bool data) except +
# print single channel/all channels
void print_channel(string channeluuid, string outputdir, char delimiter) except +
void print_channels(string outputdir, char delimiter) except +
void print_table(string outputfile) except +

54
python/imctermite.pyx Normal file
View File

@ -0,0 +1,54 @@
# distutils: language = c++
# cython: language_level = 3
from imctermite cimport cppimctermite
import json as jn
import decimal
import platform
# auxiliary function for codepage conversion
def get_codepage(chn) :
if platform == 'Windows' :
chndec = jn.loads(chn.decode(errors="ignore"))
chncdp = chndec["codepage"]
return 'utf-8' if chncdp is None else chncdp
else :
return 'utf-8'
cdef class imctermite:
# C++ instance of class => stack allocated (requires nullary constructor!)
cdef cppimctermite cppimc
# constructor
def __cinit__(self, string rawfile):
self.cppimc = cppimctermite(rawfile)
# provide raw file
def submit_file(self,string rawfile):
self.cppimc.set_file(rawfile)
# get JSON list of channels
def get_channels(self, bool include_data):
chnlst = self.cppimc.get_channels(True,include_data)
chnlstjn = [jn.loads(chn.decode(get_codepage(chn),errors="ignore")) for chn in chnlst]
return chnlstjn
# print single channel/all channels
def print_channel(self, string channeluuid, string outputfile, char delimiter):
self.cppimc.print_channel(channeluuid,outputfile,delimiter)
def print_channels(self, string outputdir, char delimiter):
self.cppimc.print_channels(outputdir,delimiter)
# print table including channels
def print_table(self, string outputfile):
chnlst = self.cppimc.get_channels(True,True)
chnlstjn = [jn.loads(chn.decode(errors="ignore")) for chn in chnlst]
with open(outputfile.decode(),'w') as fout:
for chn in chnlstjn:
fout.write('#' +str(chn['xname']).rjust(19)+str(chn['yname']).rjust(20)+'\n')
fout.write('#'+str(chn['xunit']).rjust(19)+str(chn['yunit']).rjust(20)+'\n')
for n in range(0,len(chn['ydata'])):
fout.write(str(chn['xdata'][n]).rjust(20)+
str(chn['ydata'][n]).rjust(20)+'\n')

46
python/makefile Normal file
View File

@ -0,0 +1,46 @@
setup:
cat ../README.md | grep '^# IMCtermite' -A 50000 > ./README.md
#pandoc -f markdown -t rst -o README.rst README.md
#python -m rstvalidator README.rst
cp -r ../lib ./
cp -v ../LICENSE ./
setup-clean:
rm -vf README.md README.rst LICENSE
rm -rf lib/
build: setup
python setup.py build
build-inplace: setup
python setup.py build_ext --inplace
build-sdist: setup
python setup.py sdist
python -m twine check dist/*
build-bdist: setup
python setup.py bdist
python -m twine check dist/*
build-clean:
python setup.py clean --all
rm -vf imctermite*.so imctermite*.cpp
rm -vf IMCtermite*.so IMCtermite*.cpp
rm -rvf dist/ IMCtermite.egg-info/
rm -rvf dist/ imctermite.egg-info/
cibuildwheel-build: setup
cibuildwheel --platform linux
cibuildwheel-clean:
rm -rvf wheelhouse/
pypi-upload:
python -m twine upload dist/$(shell ls -t dist/ | head -n1)
clean: setup build-clean cibuildwheel-clean setup-clean
run-example:
PYTHONPATH=$(pwd) python examples/usage_files.py

6
python/pyproject.toml Normal file
View File

@ -0,0 +1,6 @@
[build-system]
requires = ["setuptools", "wheel","Cython"]
build-backend = "setuptools.build_meta"
[tool.cibuildwheel]
before-all = ""

23
python/setup.cfg Normal file
View File

@ -0,0 +1,23 @@
[metadata]
name = imctermite
description = Enables extraction of measurement data from binary files with extension 'raw' used by proprietary software imcFAMOS and imcSTUDIO and facilitates its storage in open source file formats
long_description = file: README.md
# long_description_content_type = text/x-rst
long_description_content_type = text/markdown
version = file: VERSION
author = Record Evolution GmbH
author_email = mario.fink@record-evolution.de
maintainer = Record Evolution GmbH
url= https://github.com/RecordEvolution/IMCtermite.git
license = MIT License
license_files = LICENSE
keywords = IMC, raw, imcFAMOS, imcSTUDIO, imcCRONOS
classifiers =
Programming Language :: Python :: 3
License :: OSI Approved :: MIT License
Operating System :: OS Independent
Topic :: Scientific/Engineering
Topic :: Software Development :: Libraries :: Python Modules
[options]

21
python/setup.py Normal file
View File

@ -0,0 +1,21 @@
from setuptools import Extension, setup
from Cython.Build import cythonize
import sys
print("building on platform: "+sys.platform)
cmpArgs = {
"linux": ['-std=c++17','-Wno-unused-variable'],
"darwin": ['-std=c++17','-Wno-unused-variable'],
"win32": ['/EHsc','/std:c++17']
}
extension = Extension(
"imctermite",
sources=["imctermite.pyx"],
extra_compile_args=cmpArgs[sys.platform]
)
setup(
ext_modules=cythonize(extension,language_level=3)
)

Binary file not shown.

Some files were not shown because too many files have changed in this diff Show More