├── .gitignore ├── .idea ├── .gitignore ├── .name ├── codeStyleSettings.xml ├── encodings.xml ├── misc.xml ├── modules.xml ├── schema-matching.iml ├── scopes │ └── scope_settings.xml └── vcs.xml ├── LICENSE ├── Makefile ├── README.md ├── TODO.md ├── demo ├── 1-match.sh ├── 2-validate.sh ├── 3-compare-descriptions.sh └── data │ ├── abc.csv │ ├── abc_desc.txt │ ├── ck.csv │ ├── ck_desc.txt │ ├── cm.csv │ ├── cm_desc.txt │ ├── concarne.csv │ ├── concarne_desc.txt │ ├── gr1.csv │ ├── gr1_desc.txt │ ├── horst.csv │ ├── horst_desc.txt │ ├── maca.csv │ ├── maca_desc.txt │ ├── mk.csv │ ├── mk_desc.txt │ ├── original │ ├── 5Engines.csv │ └── 5Metadata.csv │ ├── rbg.csv │ ├── rbg_desc.txt │ ├── skynet.csv │ ├── skynet_desc.txt │ ├── xyz.csv │ ├── xyz_desc.txt │ ├── zauberfee.csv │ └── zauberfee_desc.txt ├── schema-matching ├── src ├── schema-matching.py └── schema_matching │ ├── __init__.py │ ├── __main__.py │ ├── actions │ ├── __init__.py │ ├── _argparser.py │ ├── collect.py │ ├── compare.py │ ├── match.py │ └── validate.py │ ├── collector │ ├── __init__.py │ ├── base.py │ ├── columntype.py │ ├── description │ │ ├── __init__.py │ │ ├── _argparser.py │ │ └── normal │ │ │ ├── L1.py │ │ │ ├── L2.py │ │ │ └── __init__.py │ ├── itemaverage.py │ ├── itemcount.py │ ├── itemfrequency.py │ ├── itemprobability.py │ ├── itemsum.py │ ├── letteraverage.py │ ├── lettercount.py │ ├── letterentropy.py │ ├── letterfrequency.py │ ├── letterprobability.py │ ├── lettervariance.py │ ├── maxitem.py │ ├── minitem.py │ ├── multiphase.py │ ├── probability.py │ ├── rows.py │ ├── set.py │ ├── tag.py │ ├── variance.py │ └── weight.py │ └── utilities │ ├── __init__.py │ ├── argparse.py │ ├── distribution.py │ ├── functional.py │ ├── iterator.py │ ├── misc.py │ ├── operator.py │ ├── string.py │ └── timelimit.py └── tests └── utilities └── test_distribution.py /.gitignore: -------------------------------------------------------------------------------- 1 | *.py[co] 2 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | /workspace.xml 2 | /inspectionProfiles/ 3 | -------------------------------------------------------------------------------- /.idea/.name: -------------------------------------------------------------------------------- 1 | schema-matching -------------------------------------------------------------------------------- /.idea/codeStyleSettings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 11 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.idea/encodings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/schema-matching.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /.idea/scopes/scope_settings.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 David Foerster 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | PYTHON ?= python3 2 | PYTHON_FLAGS += -OO 3 | 4 | ASSIGNMENT = 05 5 | GROUP = gr1 6 | PACKFILE = uebung$(ASSIGNMENT)-$(GROUP).tar.xz 7 | 8 | rwildcard=$(foreach d,$(wildcard $1*),$(call rwildcard,$d/,$2) $(filter $(subst *,%,$2),$d)) 9 | MODULES = $(call rwildcard, src, *.py) 10 | 11 | .PHONY: optimized unittests clean pack 12 | 13 | optimized: $(MODULES) 14 | $(PYTHON) $(PYTHON_FLAGS) -m compileall $^ 15 | 16 | unittests: 17 | export PYTHONPATH=src; \ 18 | find tests -name test\*.py | while read -r test; do \ 19 | $(PYTHON) "$$test" || exit $$?; \ 20 | done 21 | 22 | clean: 23 | rm -rf $(addsuffix c, $(MODULES)) $(addsuffix o, $(MODULES)) $(call rwildcard, tests, *.pyc *.pyo) 24 | 25 | $(PACKFILE): $(MODULES) $(call rwildcard, tests, test*.py) Makefile README | tests 26 | tar -caf $@ -- $^ 27 | 28 | pack: $(PACKFILE) 29 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Schema Matching 2 | 3 | Match schema attributes by value similarity. 4 | 5 | 6 | ## Usage 7 | 8 | Run `./schema-matching --help` to see a usage description. 9 | 10 | 11 | ### Examples 12 | 13 | See the shell scripts in `demo`. I suggest that you start with `1-match.sh` for 14 | something simple. The output will be, in this order, 15 | 16 | 1. the norms between each column pair, i. e. a measure of how different they 17 | are, between 0 (identical) and 1 (completely different), 18 | 19 | 2. the norm of the most closely matching column mapping, and 20 | 21 | 3. the most closely matching column mapping, one pair per line. 22 | 23 | 1\. and 2. require at least one level of verbosity (using `-v` or `--verbose`). 24 | 25 | 26 | ## Pre-requisites 27 | 28 | - **Python 3** (tested with v3.6.8) 29 | -------------------------------------------------------------------------------- /TODO.md: -------------------------------------------------------------------------------- 1 | Necessary: 2 | 3 | - None! :> 4 | 5 | 6 | Optional: 7 | 8 | - Find better weights or weight functions for collectors 9 | - Earth mover's distance for distributions 10 | - Use numpy for distributions 11 | - Parallel execution 12 | - The core algorithm could be ported to C, Cython or the likes to release 13 | the global interpreter lock. 14 | -------------------------------------------------------------------------------- /demo/1-match.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | cd "${0%/*}/data" 2>&- || cd data 4 | exec ../../schema-matching --match --field-delimiter=';' -v abc.csv horst.csv "$@" 5 | -------------------------------------------------------------------------------- /demo/2-validate.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | cd "${0%/*}/data" 2>&- || cd data 4 | exec ../../schema-matching --validate --field-delimiter=';' *.csv 5 | -------------------------------------------------------------------------------- /demo/3-compare-descriptions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -eu 3 | cd "${0%/*}/data" 2>&- || cd data 4 | exec ../../schema-matching --compare-descriptions --desc :collector.description.normal.L2 --field-delimiter=';' *.csv 5 | -------------------------------------------------------------------------------- /demo/data/abc.csv: -------------------------------------------------------------------------------- 1 | 3CM025;Techspace-Aero Facility, Liege, Belgium;Nov-95;TF;5.6;708;1. FAA Certification Report CR-797/P, June 95. 2. Engine S/N 779-194/1 2 | 2CM014;Peebles Site IIIB;Oct-92;TF;5.9;674;1. Ref GE Report R92AEB262. 2. Engine S/N 779101 3 | 2CM018;PTO Site IIIC;Jun-94;TF;5.7;1350;1. Ref GE Report CR-797/2. 2. Engine S/N 779131/001 & 779132/001 3. DAC combustor 4 | 3CM021;Peebles Ohio, USE + Liers, Belgium;Aug-96;TF;5.9;1136;DAC-II Combustor P/N 1968M99G04 5 | 8CM055;PTO, Ohio, USA;Sep-05;TF;5.7;314;1. Ref. GE REPORT CR-2097/3 Rev1 2. Engine S/N 874-026/01, 778-024/01B, and 892-769/01 3. Also covers CFM56-5B4/3B1 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 6 | 3CM026;TechspaceAero Facility, Liege, Belgium;Nov-95;TF;5.9;818;1. FAA Certification Report CR-797/P, June 95. 2. Engine S/N 779-194/1 7 | 8CM056;PTO, Ohio, USA;Sep-05;TF;6;520;1. Ref. GE REPORT CR-2097/3 Rev1 2. Engine S/N 874-026/01, 778-024/01B, and 892-769/01 3. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 4. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 8 | 11CM069;PTO, Ohio, USA;29-Sep-05;TF;5.3;446;1. Ref. GE REPORT CR-2097/3 2. Rev. 1Engine S/N 874-026/01, 778-024/01B, and 892-769/01 3. Ref. GE REPORT CR-900E Rev. 2, July 19, 2010 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 9 | 3CM032;Peebles Test Operation, Peebles, Ohio, USA;Jul-96;TF;5.2A;432;1. FAA Certification Report CR-997, Dec 96. 2. Engine S/N 4-101/01 10 | 4CM041;Peebles Test Operation (PTO) Peebles, OH;30-Aug-97;TF;5.2;1576;1. FAA Certification Report CR-997/2, 14 Nov 97 2. Engine S/N 874-136/01, 874-141/01, 874-146/01 11 | 8CM064;PTO, Ohio, USA;29-Sep-05;TF;5.3;377;1. Ref. GE REPORT CR-2097/3 Rev1 2. Engine S/N 874-026/01, 778-024/01B, and 892-769/01 3. Data also apply to models CFM56-7B24/3 and -7B24/3B1 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 12 | 11CM070;PTO, Ohio, USA;29-Sep-05;TF;5.3;377;1. Ref. GE REPORT CR-2097/3 2. Rev. 1Engine S/N 874-026/01, 778-024/01B, and 892-769/01 3. Ref. GE REPORT CR-900E Rev. 2, July 19, 2010 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 13 | 11CM071;PTO, Ohio, USA;29-Sep-05;TF;5.3;377;1. Ref. GE REPORT CR-2097/3 2. Rev. 1Engine S/N 874-026/01, 778-024/01B, and 892-769/01 3. Ref. GE REPORT CR-900E Rev. 2, July 19, 2010 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 14 | 3CM033;Peebles Test Operation, Peebles, Ohio, USA;Jul-96;TF;5.1;361;1. FAA Certification Report CR-997, Dec 96. 2. Engine S/N 874-101/01 15 | 8CM051;Peebles Test Operation, Peebles, Ohio, USA;Jul-96;TF;5.1;361;1. FAA Certification Report CR-997, Dec 96. 2. Engine S/N 874-101/01 3. Characteristic Dp/Foo NOx incorrectly entered originally [3CM033] 4. Issue 15; Dp/Foo NOx corrected from 63.2 to 61.0 and % of standards to 64.0, 80.1 & 96.6 16 | 4CM042;Peebles Test Operation (PTO) Peebles, OH;30-Aug-97;TF;5.1;1425;1. FAA Certification Report CR-997/2, 14 Nov 97 2. Engine S/N 874-136/01, 874-141/01, 874-146/01 17 | 8CM065;PTO, Ohio, USA;29-Sep-05;TF;5.1;302;1. Ref. GE REPORT CR-2097/3 Rev1 2. Engine S/N 874-026/01, 778-024/01B, and 892-769/01 3. Data also apply to models CFM56-7B26/3, -7B26/3B1, -7B26/3B2, -7B26/3F and –7B26/3B2F 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 18 | 11CM072;PTO, Ohio, USA;29-Sep-05;TF;5.1;302;1. Ref. GE REPORT CR-2097/3 2. Rev. 1Engine S/N 874-026/01, 778-024/01B, and 892-769/01 3. Ref. GE REPORT CR-900E Rev. 2, July 19, 2010 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 19 | 11CM073;PTO, Ohio, USA;29-Sep-05;TF;5.1;302;1. Ref. GE REPORT CR-2097/3 2. Rev. 1Engine S/N 874-026/01, 778-024/01B, and 892-769/01 3. Ref. GE REPORT CR-900E Rev. 2, July 19, 2010 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 20 | 12GE156;PTO, Ohio, USA;29-Sep-09;TF;8.8;170;1. Ref. GE REPORT R2010AE595 2. Engine S/N 956-108/2 3. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 4. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 21 | 8HN001;Phoenix AZ;10-Jan-02;TF;4.2;325#;0 22 | 11HN002;Phoenix, AZ;7-Apr-10;MTF;4.2;0;1. Reference: Original FAA Certification Report; Honeywell Report 21-14240-6A 2. Exhaust Smoke and Gaseous Emissions Test of the AS907-1-1A Turbofan Engine, dated August 31, 2010. 3. Reported using humidity h=0.00629 in accordance with 14 CFR 34 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 23 | 11HN003;Phoenix, AZ;7-Apr-10;MTF;4.2;0;1. Reference: Summary Report Data in Honeywell Report 21-14477A 2. Exhaust Smoke and Gaseous Emissions tests of the AS907-1-1A and AS907-2-1G Turbofan Engines 3. Reported using humidity h=0.00634 in accordance with ICAO Annex 16, Vol. II, 3rd Ed., section 7.1.3. 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 24 | 11HN004;Phoenix, AZ;16-Jun-10;MTF;4.2;0;1. Reference: Honeywell Report 21-13729(29)-1 2. Exhaust Smoke and Gaseous Emissions test of the AS907-2-1G Turbofan Engine 3. Reported using humidity h=0.00629 in accordance with 14 CFR 34 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 25 | 11HN005;Phoenix AZ;7-Apr-10;MTF;4.2;0;1. Reference: Honeywell Report 21-14477A 2. Exhaust Smoke and Gaseous Emissions tests of the AS907-1-1A and AS907-2-1G Turbofan Engines 3. Reported using humidity h=0.00634 in accordance with ICAO Annex 16, Vol. II, 3rd Ed., section 7.1.3. 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 26 | 1IA001;East Hartford, CT, USA;2-Jun-88;MTF;5.3;73;"1. V2500 renamed V2500-A1 2.Engine Type description originally wrongly given as TF; amended in Issue 15 to MTF" 27 | 3IA006;East Hartford CT, USA;12-Aug-92;MTF;4.88;30;"1. Engine Type description originally wrongly given as TF; amended in Issue 15 to MTF" 28 | 10IA011;East Hartford, CT;11-Dec-08;MTF;4.9;39;1. Engine performance reflects new SelectOne™ package upgrades. 2. Certification in accordance with Part III, Chapter 2, of Amendment 6 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 29 | 3IA007;East Hartford, CT, USA;12-Aug-92;MTF;4.81;31;"1. Engine Type description originally wrongly given as TF; amended in Issue 15 to MTF" 30 | 10IA012;East Hartford, CT;11-Dec-08;MTF;4.8;39;1. Engine performance reflects new SelectOne™ package upgrades. 2.Certification in accordance with Part III, Chapter 2, of Amendment 6 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 31 | 1IA002;East Hartford, CT, USA;12-Aug-92;MTF;4.82;32;"1. Engine Type description originally wrongly given as TF; amended in Issue 15 to MTF" 32 | 1IA003;East Hartford, CT, USA;12-Aug-92;MTF;4.82;32;"1. Engine Type description originally wrongly given as TF; amended in Issue 15 to MTF" 33 | 10IA013;East Hartford, CT;11-Dec-08;MTF;4.8;39;1. Engine performance reflects new SelectOne™ package upgrades. 2. Certification in accordance with Part III, Chapter 2, of Amendment 6 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 34 | 10IA014;East Hartford, CT;11-Dec-08;MTF;4.8;39;1. Engine performance reflects new SelectOne™ package upgrades. 2. Certification in accordance with Part III, Chapter 2, of Amendment 6 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 35 | 10IA015;East Hartford, CT;11-Dec-08;MTF;4.8;39;1. Engine performance reflects new SelectOne™ package upgrades. 2.Certification in accordance with Part III, Chapter 2, of Amendment 6 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 36 | 8IA010;East Hartford, CT;12-Aug-92;MTF;4.82;32;0 37 | 8IA009;East Hartford, CT;12-Aug-92;MTF;4.82;32;0 38 | 1IA004;East Hartford, CT, USA;12-Aug-92;MTF;4.66;34;"1. Engine Type description originally wrongly given as TF; amended in Issue 15 to MTF" 39 | 1IA005;East Hartford, CT, USA;12-Aug-92;MTF;4.54;35;"1. Engine Type description originally wrongly given as TF; amended in Issue 15 to MTF" 40 | 10IA016;East Hartford, CT;11-Dec-08;MTF;4.6;38;1. Engine performance reflects new SelectOne™ package upgrades. 2. Certification in accordance with Part III, Chapter 2, of Amendment 6 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 41 | 3IA008;East Hartford, CT, USA;12-Aug-92;MTF;4.46;35;"1. Engine Type description originally wrongly given as TF; amended in Issue 15 to MTF" 42 | 10IA017;East Hartford, CT;11-Dec-08;MTF;4.5;38;1. Engine performance reflects new SelectOne™ package upgrades. 2. Certification in accordance with Part III, Chapter 2, of Amendment 6 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 43 | 1KK001;Sheremetjevo, Moscow;12-Jul-89;MTF;1.24;39677;1. Data obtained on aircraft (Tu-154A) 2. In-service engine(s), tested after overhaul 44 | 1KK002;Sheremetjevo, Moscow;14-Jun-90;MTF;1.24;11824;1. Data obtained on aircraft (Tu-154A) 2. In-service engine(s), tested after overhaul 45 | 1KK003;Sheremetjevo, Moscow;15-Jun-89;MTF;1.33;17379;1. Data obtained on aircraft (Il-86) 2. In-service engine(s), tested after overhaul 46 | 1KK004;Samara City;4-Oct-87;MTF;1.13;5988;1. For Il-86 aircraft. 2. In-service engine(s), tested before overhaul. 47 | 1KK005;Samara City;18-Jul-87;MTF;1.13;1773;1. NK-86A with modified combustor. 2. For IL-86 aircraft. 48 | 1PW035;Longueuil, Quebec;17-Aug-77;TF;3.3;1866;1. Not required to meet GASEOUS emissions regulations. 2. Applicable to JT15D-1, -1A, -1B. 49 | 1PW036;Longueuil, Quebec;1-Feb-73;TF;2.68;1706;1. Not required to meet GASEOUS emissions regulations. 2. Applicable to JT15D-4, -4B, -4C, -4D 50 | 1PW037;Longueuil, Quebec;16-Apr-93;TF;2.1;5715;1. Not required to meet GASEOUS emissions regulations 51 | 1PW038;Longueuil, Quebec;13-Jul-93;TF;2.1;4439;1. Not required to meet GASEOUS emissions regulations 52 | 1PW001;East Hartford, CT, USA.;8-Mar-72;TF;1.4;24363;1. Emissions data estimated from JT3D-7 engines using JT3D-3B performance data. 53 | 1PW002;East Hartford, CT, USA.;;TF;1.4;24838;1. Combustor 14-57D. 2. Applicable to JT3D-7, -7A 54 | 1PW003;East Hartford, CT, USA.;;TF;1.4;;1. Smoke fix combustor 14-70KC. 2. Applicable to JT3D-7, -7A. 55 | 4PW068;East Hartford, CT;24-Feb-99;MTF;1.73;0;1. Environmental Kit (E-Kit) Combustor and Fuel Nozzles, incorporated 5/99 56 | 1PW018;E Hartford, CT, USA;7-Nov-83;MTF;1.73;937;1. All measurements by traverse. 2. SCH 46-16B combustor. 3. Applicable to JT8D-217, -217A, -217C. 57 | 4PW069;East Hartford, CT;24-Feb-99;MTF;1.73;0;1. Environmental Kit (E-Kit) Combustor and Fuel Nozzles, incorporated 5/99 58 | 4PW070;East Hartford, CT;24-Feb-99;MTF;1.70;0;1. Environmental Kit (E-Kit) Combustor and Fuel Nozzles, incorporated 5/99 59 | 1PW019;E Hartford, CT, USA;7-Nov-83;MTF;1.70 ;951;1. All measurements by traverse. 2. SCH 46-16B combustor. 60 | 4PW071;East Hartford, CT;24-Feb-99;MTF;1.70;0;1. Environmental Kit (E-Kit) Combustor and Fuel Nozzles, incorporated 5/99 61 | 1PW004;E Hartford, CT, USA;Apr-76;MTF;1.05;2315;1. Smoke fix combustor in production prior to 1/1/84. 2. Applicable to JT8D-7, -7A, -7B. 3. Tests performed on in-service engine(s). 62 | 1PW005;E Hartford, CT, USA;26-Feb-80;MTF;1.05;830;1. Reduced emissions combustor. 2. Applicable to JT8D-7, -7A, -7B. 63 | 8PW085;E Hartford, CT, USA;26-Feb-80;MTF;1.05;830;1. Reduced emissions combustor. 2. Applicable to JT8D-7, -7A, -7B. 3. Factor used for calculation of Dp/Foo CO [1PW005] was based on number of tests not engines. 4. Corrected in version15 64 | 1PW006;E Hartford, CT, USA;Apr-76;MTF;1.04;2256;1. Smoke fix combustor in production prior to 1/1/84. 2. Applicable to JT8D-9, -9A. 65 | 1PW007;E Hartford, CT, USA;26-Feb-80;MTF;1.04;713;1. Reduced Emissions Combustor incorporated 1/1/84. 2. Applicable to JT8D-9, -9A. 66 | 1PW031;British Airways Engine Overhaul Ltd, Wales;Mar-76;TF;0;12108;1. Emissions estimated from JT9D-7 engines using JT9D-7A performance data. 2. Tests performed on in-service engine(s), after overhaul. 67 | 8PW088;British Airways Engine Overhaul Ltd, Wales;Mar-76;TF;0;12108;1. Emissions estimated from JT9D-7 engines using JT9D-7A performance data. 2. Tests performed on in-service engine(s), after overhaul. 3. SN (char) wrongly calculated originally [1PW031]. 4. Corrected to 12.9 SN in version 15 and % of standard recalculated 68 | 1PW032;E Hartford, CT, USA;16-Sep-80;TF;5.1;9178;0 69 | 1PW033;E Hartford, CT, USA;Apr-76;TF;4.9;4559;0 70 | 1PW020;British Airways Engine Overhaul Ltd, Wales;Mar-76;TF;0;12179;Tests performed on in-service engine(s), after overhaul. 71 | 8PW086;British Airways Engine Overhaul Ltd, Wales;Mar-76;TF;0;12179;1. Tests performed on in-service engine(s), after overhaul. 2. SN (char) wrongly calculated originally [1PW020]. 3. Corrected to 12.5 SN in version 15 and % of standard recalculated 72 | 1PW034;E Hartford, CT, USA;Apr-76;TF;4.9;4559;0 73 | 1PW021;British Airways Engine Overhaul Ltd, Wales;Mar-76;TF;0;12108;1. Emissions estimated from JT9D-7 engines using JT9D-7A performance data. 2. Tests performed on in-service engine(s), after overhaul. 74 | 8PW087;British Airways Engine Overhaul Ltd, Wales;Mar-76;TF;0;12108;1. Emissions estimated from JT9D-7 engines using JT9D-7A performance data. 2. Tests performed on in-service engine(s), after overhaul. 3. SN (char) wrongly calculated originally [1PW021]. 4. Corrected to 12.9 SN in version 15 and % of standard recalculated 75 | 1PW022;E Hartford, CT, USA;Nov-75;TF;5.1;9055;1. Mod V combustor 76 | 1PW023;E Hartford, CT, USA;16-Sep-80;TF;5.1;9464;1. Mod VI combustor 77 | 1PW024;E Hartford, CT, USA;16-Sep-80;TF;5.1;9178;0 78 | 1PW025;E Hartford, CT, USA;Apr-76;TF;4.9;4559;0 79 | 1PW026;E Hartford, CT, USA;6-Mar-80;TF;5.0 ;464;0 80 | 1PW027;E Hartford, CT, USA;6-Mar-80;TF;5.0 ;447;0 81 | 1PW028;E Hartford, CT, USA;26-Oct-81;TF;5.0 ;1231;0 82 | 1PW029;E Hartford, CT, USA;26-Oct-81;TF;4.8;620;0 83 | 1PW030;E Hartford, CT, USA;26-Oct-81;TF;4.8;651;0 84 | 1PW039;X-8 Stand, PWA, East Hartford, CT;8-Aug-83;TF;6.04;530;0 85 | 4PW072;East Hartford, CT;8-Aug-83;TF;5.71;472;1. Revision to add second engine test. 86 | 1PW040;0;8-Aug-83;TF;0;574;0 87 | 4PW073;East Hartford, CT;8-Aug-83;TF;5.54;426;1. Revision to add second engine test. 88 | 7PW077;Mississauga, Ontario, Canada;8-May-00;MTF;4.5;287;1. P&WC EC C2264A 2. Engines E9541/02, E9402/37, E9403/74 3. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 4. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 89 | 7PW078;Mississauga, Ontario, Canada;8-May-00;MTF;4.5;287;1. P&WC EC C2264A 2. Engines E9541/02, E9402/37, E9403/74 90 | 11PW100;Mississauga, Ontario, Canada;7-Aug-07;TF;4.2;226;1. P&W ER 5606 revision AEngines tested: E9819/09, CH0004/13, CH0004/14 2. Weight reduced fuel nozzles and CCOCEngines CH499 onwards incorporate this combustion system and design standard 3. Defined by P&W Engeneering Change D5216 4. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 5. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 91 | 8PW090;Mississauga, Ontario, Canada;30-Dec-04;MTF;4.2;357;1. P&WC ER 5597 2. Engines tested: CH0004/02, CH0005/01, CH0007/03 3. Type-Certification combustor 92 | 8PW091;Mississauga, Ontario, Canada;28-Dec-04;MTF;4.2;202;1. P&WC ER 5606 2. Engines tested: E9812/12, CH0010/01, CH0011/01 3. Post Type-Certification combustor 4. All engines entering revenue service incorporate this combustor design standard 5. Defined by P&WC Engineering Change D5054 93 | 7PW079;Mississauga, Ontario, Canada;15-Apr-00;MTF;4.1;460;1. P&WC ER 3967 2. Engines E9608/01, E9606/04, E9609/01 3. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 4. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 94 | 7PW080;Mississauga, Ontario, Canada;7-Aug-01;MTF;4.1;425;1. P&WC ER 5080 2. Engines E9633/01, E9631/07, CF0001/03 3. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 4. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 95 | 1PW041;P7 Stand, P&W, Middletown, CT;14-May-86;TF;4.7;288;0 96 | 1PW042;0;17-Aug-87;TF;4.7;652;Data from X698-5 with reduced smoke combustor. 97 | 1PW043;0;17-Aug-87;TF;4.5;595;Data from X698-5 with reduced smoke combustor. 98 | 2PW060;East Hartford, Ct, USA;26-Apr-94;TF;6.8;1220;Data from X832-4 99 | 10PW096;Middletown, CT;13-Apr-10;TF;6.7;1501.9;1. Data updated to reflect additional engine test as well as updated engine performance. 2. Additional engine tested to show CAEP/4 compliance. 3. Certification in accordance with Part III, Chapter 2, of Amendment 4 of ICAO Annex 16 Vol. II. 4. NOx levels in accordance with Part III, Chapter 2, 2.3.2 c) (CAEP/4) 100 | 3PW063;East Hartford, Conn, USA;15-Jun-96;TF;6.7;1926;Data from Report PWA-6678 101 | 2PW061;East Hartford, Ct, USA;26-Apr-94;TF;6.7;1170;Data from X832-4 102 | 10PW097;Middletown, CT;13-Apr-10;TF;6.6;1381.7;1. Data updated to reflect additional engine test as well as updated engine performance. 2. Additional engine tested to show CAEP/4 compliance. 3. Certification in accordance with Part III, Chapter 2, of Amendment 4 of ICAO Annex 16 Vol. II. 4. NOx levels in accordance with Part III, Chapter 2, 2.3.2 c) (CAEP/4) 103 | 3PW064;East Hartford, Conn, USA;15-Jun-96;TF;6.6;1805;Data from Report PWA-6678 104 | 2PW062;East Hartford, Ct, USA;26-Apr-94;TF;6.4;1111;Data from X832-4 105 | 8PW089;East Hartford, Ct, USA;26-Apr-94;TF;6.4;1111;1. Data from X832-4 2. Dp/Foo CO (char) wrongly entered originally as 23.0 [2PW062]. 3. Corrected in version 15 to 23.9 and % of standard recalculated 106 | 10PW098;Middletown, CT;13-Apr-10;TF;6.2;1102;1. Data updated to reflect additional engine test as well as updated engine performance. 2. Additional engine tested to show CAEP/4 compliance. 3. Certification in accordance with Part III, Chapter 2, of Amendment 4 of ICAO Annex 16 Vol. II. 4. NOx levels in accordance with Part III, Chapter 2, 2.3.2 c) (CAEP/4) 107 | 1PW044;P7 Stand, P&W, Middletown, CT;14-May-86;TF;4.9;275;0 108 | 1PW045;0;17-Aug-87;TF;4.9;734;Data from X698-5 with reduced smoke combustor. 109 | 1PW046;P7 Stand, P&W, Middletown, CT;14-May-86;TF;4.7;288;0 110 | 1PW047;0;17-Aug-87;TF;4.7;652;Data from X698-5 with reduced smoke combustor. 111 | 1PW048;0;17-Aug-87;TF;4.6;623;Data from X698-5 with reduced smoke combustor. 112 | 1PW049;East Hartford, CT;14-Feb-93;TF;5.2;1505;Data from X821-3 with Floatwall Combustor 113 | 7PW081;East Hartford, CT;10-Apr-00;TF;5.2;139;Data from Report PWA-7138 114 | 9PW092;East Hartford, CT;12-May-08;TF;5.06;556;Talon IIB combustor with improved exit temperature profile. 115 | 1PW050;East Hartford, CT;14-Feb-93;TF;5.1;1179;Data from X821-3 with Floatwall Combustor 116 | 5PW075;East Hartford, Conn. USA;10-Apr-00;TF;5.1;78;1. Data from Report PWA-7138. 2. TALON II Combustor 117 | 9PW093;East Hartford, CT;12-May-08;TF;4.92;385;Talon IIB combustor with improved exit temperature profile. 118 | 4PW067;East Hartford, CT;14-Feb-93;TF;5.1;1179;Data from X821-3 with Floatwall Combustor 119 | 7PW082;East Hartford, CT;10-Apr-00;TF;5.1;78;Data from Report PWA-7138 120 | 9PW094;East Hartford, CT;12-May-08;TF;4.92;385;1. Talon IIB combustor with improved exit temperature profile. 2. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 e) (CAEP/8) 121 | 9PW095;East Hartford, CT;12-May-08;TF;4.86;341;1. Talon IIB combustor with improved exit temperature profile. 2. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 122 | 1PW051;P7 Stand, P&W, Middletown, CT;14-May-86;TF;4.7;288;0 123 | 1PW052;0;17-Aug-87;TF;4.5;595;Data from X698-5 with reduced smoke combustor. 124 | 1PW053;Middletown, CT;15-Jan-93;TF;5.0 ;2104;Data from X693-20 with Phase 3 reduced pressure loss combustor 125 | 1PW054;Middletown, CT;15-Jan-93;TF;5.0 ;1914;Data from X693-20 with Phase 3 reduced pressure loss combustor 126 | 1PW055;Middletown, CT;15-Jan-93;TF;4.8A;1597;Data from X693-20 with Phase 3 reduced pressure loss combustor 127 | 1PW056;Middletown, CT;15-Jan-93;TF;4.8;1481;Data from X693-20 with Phase 3 reduced pressure loss combustor 128 | 5PW074;East Hartford, Conn. USA;3-Nov-99;TF;4.8;562;1. Data from Report PWA-7312. 2. TALON II Combustor 129 | 1PW057;Middletown, CT;15-Jan-93;TF;4.7;1324;1. Data from X693-20 with Phase 3 reduced pressure loss combustor 2. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 130 | 1PW058;0;17-Aug-87;TF;4.4;571;Data from X698-5 with reduced smoke combustor. 131 | 1PW059;Middletown, CT;15-Jan-93;TF;4.6;1192;1. Data from X693-20 with Phase 3 reduced pressure loss combustor 2. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 132 | 12PW101;P7 Production Test Cell, Middletown, CT;11/30/2012;TF;4.7;3776;1. Data from Report PWA-9720-20 with Phase 3 reduced pressure loss combustor 2. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 133 | 12PW102;P7 Production Test Cell, Middletown, CT;11/30/2012;TF;4.6;3594;1. Data from Report PWA-9720-20 with Phase 3 reduced pressure loss combustor 2. Certification in accordance with Part III, Chapter 2, of Amendment 7 of ICAO Annex 16 Vol. II. 3. NOx levels in accordance with Part III, Chapter 2, 2.3.2 d) (CAEP/6) 134 | 1RR001;Bristol;May-05;TF;3.0 ;;Stage bleed on 2 engines 135 | 1RR002;Derby;Jun-1979;TF;4.7;29381;Package 1 combustor. 136 | 1RR003;British Airways Test Facility, Heathrow;Mar-79;TF;4.7;24653;1. Package 1 combustor. 2. Tests performed on in-service engine(s), after overhaul. 3. SN mode data scaled from 1RR002 137 | 1RR004;Derby;Jun-79;TF;4.5;22453;1. Package 1 Combustor. 2. Applicable to RB211-524B, B2, B3, B4. 138 | 1RR005;SINFIN-Derby;Sep-86;TF;4.5;x934;1. Data from certification report CRR60515. 2. Phase 2 combustor. 3. Applicable to engines manufactured after Feb 87. 4. SN mode data scaled from 1RR004 139 | 1RR006;SINFIN-Derby;Sep-86;TF;4.5;26209;1. Package 1 combustor 2. SN mode data scaled from 1RR004 140 | 1RR007;SINFIN-Derby;Nov-82;TF;4.3;22707;1. Package 1 combustor 2. SN mode data scaled from 1RR004 141 | 1RR008;SINFIN-Derby;Sep-86;TF;4.3;805;1. Data from certification report CRR60515. 2. Phase 2 combustor. 3. Applicable to engines manufactured after Feb 87. 4. SN mode data scaled from 1RR004 142 | 1RR009;SINFIN-Derby;Apr-87;MTF;4.25;2174;Data from certification report CRR60560 143 | 1RR010;SINFIN-Derby;Apr-87;MTF;4.25;540;HC data remeasured. 144 | -------------------------------------------------------------------------------- /demo/data/abc_desc.txt: -------------------------------------------------------------------------------- 1 | 1,1 2 | 2,6 3 | 3,7 4 | 4,9 5 | 5,10 6 | 6,16 7 | 7,23 8 | -------------------------------------------------------------------------------- /demo/data/ck.csv: -------------------------------------------------------------------------------- 1 | "630 ";"Allied Signal";"Phoenix";"TF";"13.9";"15.6";"317.6 " 2 | "10244";"GE Aviation";"PTO, Ohio, USA";"TF";"41.9";"308.7";"5.31" 3 | "1607";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"MTF";"17.97";"34.91";"82.6" 4 | "1751";"Honeywell";"Phoenix, AZ";"TF";"21.95";"30.62";"83.3" 5 | "15268";"GE Aviation";"PTO, Ohio, USA";"TF";"46.0";"341.2";"3.98" 6 | "7716 ";"International Aero Engines";"East Hartford, CT, USA";"MTF";"29.8";"111.2";"5.1 " 7 | "1319";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"MTF";"17.22";"33.05";"71.7" 8 | "-";"Honeywell";"Phoenix, AZ";"MTF";"22.58";"32.86";"15.9" 9 | "1465";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"MTF";"17.22";"33.05";"88.4" 10 | "5039";"IAE International Aero Engines";"East Hartford, CT";"MTF";"27";"108.9";"2.40" 11 | "1444";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"MTF";"17.9";"34.74";"58.9" 12 | "1567";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"MTF";"17.9";"34.74";"83.4" 13 | "1817";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"MTF";"20.2";"42.23";"27.12" 14 | "31175 ";"GE";"Site IVD & 6, PTO, Peebles, Ohio, USA";"TF";"40.4";"426.72";"22.4 " 15 | "1429";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"rMTF";"17.2";"33";"95.4" 16 | "1316";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"MTF";"17.2";"33";"72.6" 17 | "991 ";"Allison Engine Company";"Indianapolis, Indiana, USA";"MTF";"16.2";"28.6";"89.3 " 18 | "30617 ";"GE";"Site IIID, PTO, Peebles, OH";"TF";"40.53";"437.52";"4.0 " 19 | "1150";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"MTF";"15.8";"29.62";"91.1" 20 | "30617 ";"GE";"Site IIID, PTO, Peebles, OH";"TF";"40.53";"432.8";"4.0 " 21 | "1050";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"MTF";"15.8";"29.62";"71.6" 22 | "1175";"Rolls-Royce Corporation";"Indianapolis, Indiana, USA";"MTF";"16.6";"31.5";"55.9" 23 | "6279";"GE Aviation";"PTO, Ohio, USA";"TF";"37.2";"271.3";"9.9" 24 | "9049";"GE Aviation";"PTO, Ohio, USA";"TF";"40.5";"298.0";"5.92" 25 | "4338 ";"AO 'Aviadgatel'";"Sheremetjevo, Moscow";"MTgF";"18.4";"66.64";"1060.0 " 26 | "2784 ";"BMW Rolls-Royce GmbH";"BMW Rolls-Royce GmbH, Dahlewitz, Germany";"MTF";"24.16";"65.61";"19.2 " 27 | "481 ";"Pratt & Whitney (Canada)";"Longueuil, Quebec";"TF";"12.3";"12.90 ";"N/A" 28 | "3340 ";"BMW Rolls-Royce GmbH";"BMW Rolls-Royce GmbH, Dahlewitz, Germany";"MTF";"28.75";"83.23";"2.5 " 29 | "409 ";"Pratt & Whitney (Canada)";"Longueuil, Quebec";"TF";"10.1";"11.12";"N/A" 30 | "2740 ";"Pratt & Whitney";"East Hartford, CT, USA.";"TF";"13.6";"80.06";"2017.6 " 31 | "2909 ";"Pratt & Whitney";"East Hartford, CT, USA.";"TF";"13.4";"84.52";"1123.7 " 32 | "2565 ";"Rolls-Royce";"Dahlewitz";"MTF";"26.16";"75.7";"41.3 " 33 | "2909 ";"Pratt & Whitney";"East Hartford, CT, USA.";"TF";"13.4";"84.52";"2309.4 " 34 | "3989 ";"Pratt & Whitney";"E Hartford, CT, USA";"MTF";"16.81";"68.94";"221.2 " 35 | "3648 ";"Pratt & Whitney";"E Hartford, CT, USA";"MTF";"16.45";"68.94";"47.8 " 36 | "3906 ";"CFMI";"Peebles Site IVD";"TF";"23.5";"97.86";"30.4 " 37 | "3906 ";"CFMI";"Peebles Site IVD";"TF";"23.5";"97.86";"30.4 " 38 | "7783 ";"CFMI";"Peebles Site IIIB";"TF";"30.2";"133.45";"36.1 " 39 | "4367 ";"CFMI";"Peebles Site IIIC";"TF";"25.1";"104.53";"22.0 " 40 | "5102";"IAE International Aero Engines";"East Hartford, CT";"MTF";"27.1";"110.3";"2.30" 41 | "5024 ";"CFM International";"Peebles Ohio, USE Liers, Belgium";"TF";"30.5";"133.5";"44.9 " 42 | "5756 ";"CFMI";"PTO Site IIIC";"TF";"31.2";"137.9";"53.6 " 43 | "4776 ";"KKxBM";"Sheremetjevo, Moscow";"MTF";"10.8";"103";"2577.2 " 44 | "6875";"CFM International";"PTO, Ohio, USA";"TF";"32.6";"142.3";"8.5" 45 | "6106 ";"KKBM";"Samara City";"MTF";"13.2";"130.47";"355.2 " 46 | "7723 ";"GE";"Techspace-Aero Facility, Liege, Belgium";"TF";"31.57";"137.90";"40.3 " 47 | "12291 ";"Pratt & Whitney";"British Airways Engine Overhaul Ltd, Wales";"TF";"20.3";"205.3";"326.6 " 48 | "12291 ";"Pratt & Whitney";"British Airways Engine Overhaul Ltd, Wales";"TF";"20.3";"205.3";"326.6 " 49 | "3732 ";"GE";"Techspace-Aero Facility, Liege, Belgium";"TF";"23.33";"97.89";"78.1 " 50 | "5861 ";"CFMI";"Peebles Site rIIIB";"TF";"27.1";"117.9";"44.8 " 51 | "12381 ";"Pratt & Whitney";"E Hartford, CT, USA";"TF";"24.5 ";"235.8";"132.8 " 52 | "3783 ";"CFMI";"PTO Site IIIC";"TF";"27.1";"117.9";"74.5 " 53 | "12291 ";"Pratt & Whitney";"British Airways Engine Overhaul Ltd, Wales";"TF";"20.3";"205.3";"326.6 " 54 | "5641 ";"GE";"Techspace-Aero, Liege, Belgium";"TF";"27.69";"120.11";"53.2 " 55 | "13117 ";"Pratt & Whitney";"E Hartford, CT, USA";"TF";"24.2";"222.41";"32.7 " 56 | "3358 ";"CFM International";"Techspace Aero, Liege, Belgium";"TF";"22.6";"94.7";"84.7 " 57 | "12381 ";"Pratt & Whitney";"E Hartford, CT, USA";"TF";"24.5 ";"235.75";"132.8 " 58 | "6858 ";"CFM International";"PTO Site IV-D";"MTF";"29.2";"143.33";"52.0 " 59 | "4582 ";"Pratt & Whitney";"East Hartford, CT";"MTF";"19.66";"92.74";"0.0 " 60 | "4216 ";"Pratt & Whitney";"East Hartford, CT";"MTF";"19.05";"92.74";"0.0 " 61 | "6240";"CFM International";"PTO Site IV-D";"MTF";"28.2";"137.61";"56.6" 62 | "2729";"CFM International";"qPTO, Ohio, USA";"TF";"21.40";"86.7";"45.0" 63 | "3281 ";"Pratt & Whitney";"E Hartford, CT, USA";"MTF";"15.82";"62.27";"87.6 " 64 | "4604 ";"Pratt & Whitney";"East Hartford, CT";"MTF";"20.27";"96.52";"0.0 " 65 | "21528 ";"Pratt & Whitney";"East Hartford, Conn, USA";"TF";"32.83";"343.0";"41.3 " 66 | "3996";"CFM International";"PTO, Ohio, USA";"TF";"25.60";"107.6";"20.9" 67 | "3995";"CFM International";"PTO, Ohio, USA";"TF";"25.60";"107.6";"20.9" 68 | "23229 ";"Pratt and Whitney";"East Hartford, Ct, USA";"TF";"36.2";"369.6";"23.0 " 69 | "21799.9";"Pratt & Whitney";"Middletown, CT";"TF";"33.3";"355.7";"25.80" 70 | "11987 ";"Pratt & Whitney";"-";"TF";"29.3";"249.1";"20.4 " 71 | "4762";"CFM International";"PTO, Ohio, USA";"TF";"27.70";"117";"15.4" 72 | "4762";"CFM International";"PTO, Ohio, USA";"TF";"27.70";"117";"15.4" 73 | "4233 ";"GE";"Peebles Test Operation (PTO) Peebles, OH";"TF";"27.80";"116.99";"72.7 " 74 | "6149 ";"GE";"Peebles Test Operation, Peebles, Ohio, USA";"TF";"27.61";"116.99";"24.0 " 75 | "31629 ";"Pratt & Whitney";"East Hartford, Conn, USA";"TF";"39.16";"395.0";"19.9 " 76 | "5231";"CFM International";"PTO, Ohio, USA";"TF";"29.00";"121.4";"13.4" 77 | "11987 ";"Pratt & Whitney";"-";"TF";"29.3";"249.1";"20.4 " 78 | "2837 ";"GE Transportation";"Site 4D";"TF";"25.6";"77.4";"86.17" 79 | "18078 ";"Pratt and Whitney";"East Hartford, Ct, USA";"TF";"32.2";"333.2";"29.1 " 80 | "2696";"GE Transportation";"Site 4D";"TF";"25.1";"76.9";"93.9" 81 | "17713";"Engine Alliance";"Site 4D";"TF";"36.62";"332.39";"35.4" 82 | "5231";"CFM International";"PTO, Ohio, USA";"TF";"29.00";"121.4";"13.4" 83 | "1300 ";"Pratt & Whitney Canada Inc";"Mississauga, Ontario, Canada";"MTF";"20.4";"30.71";"89.3 " 84 | "10545 ";"Rolls Royce Ltd";"British Airways Test Facility, Heathrow";"TF";"25.0 ";"182.5";"758.7 " 85 | "14555 ";"Pratt & Whitney";"P7 Production Test Cell, Middletown, CT";"TF";"31";"280.24";"86.5 " 86 | "1001 ";"Rolls Royce Ltd";"Bristol";"TF";"16.5";"32.4";"931.6 " 87 | "3214";"GE Transportation";"Site 3C";"TF";"27.2";"83.7";"53.4" 88 | "20514 ";"Rolls Royce Ltd";"SINFIN-Derby";"TF";"29.7 ";"231.3";"582.1 " 89 | "1137 ";"GE Aircraft Engines";"Lynn Cell 121";"TF";"19.7";"41.01";"60.0 " 90 | "16270 ";"Rolls Royce Ltd";"Derby";"TF";"28.0 ";"218.5 ";"632.7 " 91 | "1137 ";"GE Aircraft Engines";"Lynn Cell 121";"TF";"28.57";"41.01";"60.0 " 92 | "13305 ";"Pratt & Whitney";"Middletown, CT";"TF";"29.49";"258.0 ";"44.8 " 93 | "3214";"GE Transportation";"Site 3C";"TF";"27.2";"83.7";"53.4" 94 | "10297 ";"Pratt and Whitney";"East Hartford, Conn. USA";"TF";"28.41";"258.0";"17.3 " 95 | "13333 ";"Pratt & Whitney";"P7 Production Test Cell, Middletown, CT";"TF";"38.18";"266.9";"93.9 " 96 | "2836";"GE Transportation";"Site 4D";"TF";"25.6";"77.4";"86.17" 97 | "3328";"GE Transportation";"Site 4D";"TF";"27.3";"83.7";"64.80" 98 | "2871";"GE Transportation";"Site 4D";"mTF";"25.6";"77.4";"70.2" 99 | "2010";"GE";"PTO iSite 3B Peebles";"TF";"22.08";"56.35";"2.8" 100 | "13043 ";"Pratt & Whitney";"P7 Stand, P&W, Middletown, CT";"TF";"29.3";"252.4";"9.4 " 101 | "9681 ";"Pratt & Whitney";"Middletown, CT";"TF";"25.39";"222.4";"74.6 " 102 | "1956";"GE Aircraft Engines";"Peebles, Ohio";"TF";"22.15";"56.36";"2.6" 103 | "2287";"GE";"PTO Site 3B Peebles";"TF";"23.49";"60.62";"2.3" 104 | "2419";"GE";"PTO Site 3B Peebles";"TF";"24.12";"62.49";"2.3" 105 | "2814 ";"Rolls Royce Ltd";"-";"MTF";"16.1";"61.6";"71.0 " 106 | "2814 ";"Rolls Royce Ltd";"-";"MTF";"16.1";"61.6";"71.0 " 107 | "11884 ";"GE";"Site IVD, Peebles, Ohio";"TF";"28.44";"230.4";"27.0 " 108 | "16113 ";"Rolls Royce";"Derby";"TF";"36.71";"261.5";"1.0 " 109 | "3513 ";"Rolls Royce Ltd";"Derby";"MTF";"19.9";"50.7";"1185.5 " 110 | "2419";"GdE";"PTO Site 3Bl Peebles";"TF";"24.12";"62.49";"2.3" 111 | "2223";"GE";"PTO Site 3B Peebles";"TF";"23.18";"59.68";"2.4" 112 | "2500";"Rolls-Royce";"rDahlewitz";"MTF";"15.88";"61.6";"26.6" 113 | "13436 ";"GE Aircraft Engines";"Production Test Cells M34 & M35";"TF";"28.8";"224.2";"199.8 " 114 | "2990 ";"Rolls Royce plc";"SINFIN, Derby";"MTF";"16.4";"68.5";"67.9 " 115 | "12549 ";"GE Aircraft Engines";"Production Test Cells M34 & M35";"TF";"25.4";"181.9";"173.9 " 116 | "7492 ";"Rolls-Royce plc";"Hucknall";"MTF";"26.0";"178.4";"3.6 " 117 | "3513 ";"Rolls Royce Ltd";"Derby";"MTF";"19.9";"50.7";"1185.5 " 118 | "12382 ";"GE Aircraft Engines";"Site IIIC, PTO, Peebles, Ohio";"TF";"30.96";"257.4";"75.2 " 119 | "11884 ";"GE";"Site IVD, Peebles, Ohio";"TF";"28.44";"230.4";"27.0 " 120 | "21075 ";"Rolls Royce Ltd";"SINFIN-Derby";"MTF";"32.1";"253";"14.2 " 121 | "11611 ";"GE Aircraft Engines";"Production Test Cells M34 & M35";"TF";"24.7";"174.8";"187.4 " 122 | "11611 ";"GE Aircraft Engines";"Production Test Cells M34 & M35";"TF";"24.7";"174.8";"187.4 " 123 | "1173 ";"Textron Lycoming";"Stratford, CT";"TqF";"13.15";"33.4";"90.8 " 124 | "10719 ";"GE";"Site IIIB, PTO Peebles";"TF";"29.53";"249.01";"14.9 " 125 | "11113 ";"GE";"Site IIIB, PTO Peebles";"TF";"30.13";"254.26";"13.3 " 126 | "23531";"Rolls-Royce";"Derby";"(TF)";"46.08";"350.9";"0.2" 127 | "20735";"Rolls-Royce";"Derby";"(TF)";"44.1";"334.7";"0.2" 128 | "12196";"Rolls-Royce";"Derby";"v(TF)";"36.32";"268";"0.8" 129 | "9340";"GE";"Site IIIB, PTO Peebles";"TF";"27.79";"233.35";"17.1 " 130 | "9728 ";"GE Aircraft Engines";"Site IIIC, PTO, Peebles, Ohio";"TF";"28.0 ";"233.35";"89.6 " 131 | "12134 ";"GE Aircraft Engines";"Site IIIC, PTO, Peebles, Ohio";"TF";"31.79";"267.03";"75.5 " 132 | "12420 ";"GtE";"Site IIIB, PTO Peebles";"TF";"31.72";"267.03";"12.1 " 133 | "17350";"Rolls-Royce";"Derby";"TF";"41";"310.8";"0.4" 134 | "12640 ";"GE";"Site IIIB, PTO Peebles";"TF";"31.66";"270.01";"12.6 " 135 | "12134 ";"GE Aircraft Engines";"Site IIIC, PTO, Peebles, Ohio";"TF";"31.79";"267.03";"75.7 " 136 | -------------------------------------------------------------------------------- /demo/data/ck_desc.txt: -------------------------------------------------------------------------------- 1 | 1,18 2 | 2,4 3 | 3,6 4 | 4,9 5 | 5,11 6 | 6,12 7 | 7,15 -------------------------------------------------------------------------------- /demo/data/cm.csv: -------------------------------------------------------------------------------- 1 | AE3007A1;Indianapolis, Indiana, USA;3-Mar-94;MTF;307;42736 2 | AE3007A1 series;Indianapolis, Indiana, USA;3-Mar-94;MTF;279;41671 3 | AE3007A1/1;Indianapolis, Indiana, USA;37496;MTF;370;0.01 4 | AE3007A1/3;Indianapolis, Indiana, USA;37496;MTF;372;0.01 5 | AE3007A1P;Indianapolis, Indiana, USA;3-Mar-94;MTF;308;42736 6 | AE3007A3;Indianapolis, Indiana, USA;3-Mar-94;MTF;361;42736 7 | AE3007A3;Indianapolis, Indiana, USA;37051;MTF;289;0.01 8 | AE3007C;Indianapolis, Indiana, USA;3-Mar-94;MTF;320;42736 9 | AE3007C1;Indianapolis, Indiana, USA;3-Mar-94;MTF;344;42736 10 | D-30 (Il series);Sheremetjevo, Moscow;33088;MTF;8992;45.1 11 | PS-90A;Perm City;32615;MTF;138;41836 12 | BR700-710A1-10;BMW Rolls-Royce GmbH, Dahlewitz, Germany;19-Oct-9g;MTF;156;18.0 13 | BR700-715A1-30;BMW Rolls-Royce GmbH, Dahlewitz, Germany;36340;MTF;25;41795 14 | BR700-715B1-30;BMW Rolls-Royce GmbH, Dahlewitz, Germany;36340;MTF;20;41887 15 | BR-700-725A1-12;Dahlewitz;39666;MTF;398;41856 16 | CFM56-5-A1;Peebles Site IIIC;31735;TF;285;41718 17 | CFM56-5A4;Peebles Site IIIC;31735;TF;322;41899 18 | CFM56-5B1/2;PTO Site IIIC;34500;TF;1168;41795 19 | CFM56-5B2/2;PTO Site IIIC;34486;TF;1128;41795 20 | CFM56-5B2/3;PTO, Ohio, USA;38596;TF;221;41656 21 | CFM56-5B3/3;PTO, Ohio, USA;38596;TF;204;41807 22 | CFM56-5B4/2;PTO Site IIIC;34486;TF;1350;41795 23 | CFM56-5B4/3;PTO, Ohio, USA;38596;TF;314;41834 24 | CFM56-5B6/2P;PeTbles Ohio, USE + Liers, Belgium;35278;TF;849;41889 25 | CFM56-5B7/3;PTO, Ohio, USA;38596;TF;314;41834 26 | CFM56-5B8/3;PTO, Ohio, USA;38596;TF;544;41830 27 | CFM56-5B9/2P;GEAE PTO and Techspace Aero, Liege, Belgium;35278;TF;789;41858 28 | CFM56-5C2;PTO Site IVD;33393;MTF;1050;41712 29 | CFM56-5C3/P;PTO Site IV-D;33390;MTF;943;41896 30 | CFM56-7B18/3;PTO, Ohio, USA;38624;TF;656;30895 31 | CFM56-7B20/3;PTO, Ohio, USA;38624;TF;574;19238 32 | CFM56-7B22/3;PTO, Ohio, USA;38624;TF;447;30590 33 | CFM56-7B24;Peebles Test Operation, Peebles, Ohio, USA;35247;TF;432;41686 34 | CFM56-7B24/2;Peebles Test Operation (PTO) Peebles, OH;35672;TF;1576;0.7 35 | CFM56-7B24E/B1 ;PTO, Ohio, USA;38624;TF;377;13.28 36 | CFM56-7B26/2;Peebles Test Operation (PTO) Peebles, OH;35672;TF;1425;0.7 37 | CFM56-7B26E/B1;PTO, Ohio, USA;38624;TF;302;14.37 38 | CFM56-7B27;Peebles Test Operation, Peebles, Ohio, USA;35247;TF;335;41690 39 | CFM56-7B27AE;PTO, Ohio, USA;38624;TF;273;14.72 40 | CFM56-7B27E/B3;PTO, Ohio, USA;38624;TF;273;14.72 41 | CFM56-7B27E/F;PTO, Ohio, USA;38624;TF;273;14.72 42 | CF34-10E5;Site 4D;38965;TF;848;41804 43 | CF34-10E5;Site 4D;38192;TF;692;30072 44 | CF34-10E5A1;Site 4D;38192;TF;601;41707 45 | CF34-10E6;Site 3C;39969;TF;670;41651 46 | CF34-10E6A1;Site 3C;39969;TF;568;41745 47 | CF34-10E7;Site 4D;38192;TF;601;41707 48 | CF34-3A;Lynn Cell 121;21-Mar-91;TF;313;41698 49 | CF34-8C1;Peeb7es,NOhio;;TF;13;41888 50 | CF34-8C5A1;PTO Site 3B Peebles;37283;TF;18;29921 51 | CF34-8C5B1;PTO Site 3B Peebles;37283;TF;20;24624 52 | CF34-8E5;Peebles, Ohio;37283;TF;18;41650 53 | CF34-8E5A1;PTO Site 3B Peebles;37283;TF;18;17.55 54 | CF34-8E6A1;PTO Site 3B Peebles;37283;TF;18;17.55 55 | CF6-45A2;Production Test Cells M34 & M35;12-Oct-79;TF;8485;41886 56 | CF6-50C;Site IVD, Peebles, Ohio;31986;TF;784;41655 57 | CF6-50C1, -C2;Production Test Cells M34 & M35;12-Oct-79;TF;7715;41855 58 | CF6-50C2R;Production Test Cells M34 & M35;12-Oct-79;TF;7998;41855 59 | CF6-50E1;Site IVD, Peebles, Ohio;31986;TF;788;41655 60 | CF6-50E2;Production Test Cells M34 & M35;12-Oct-79;Tr;7715;41855 61 | CF6-6K;Production Test Cells M34 & M35;29083;TF;5821;41702 62 | CF6-80A;Production Test Cells M35;30631;TF;1636;41805 63 | CF6-80C2A1;Site IIIC, PTO, Peebles, Ohio;29-May-85;TF;2915;41799 64 | CF6-80C2A2;Site IIIC, PTO, Peebles, Ohio;29-May-85;TF;3152;41797 65 | CF6-80C2A3;Site IIIC, PTO, Peebles, Ohio;29-May-85;TF;2874;41648 66 | CF6-80C2A5;Site IIIC, PTO, Peebles, Ohio;29-May-85;TF;2966;41648 67 | CF6-80C2A5F;Site IIIB, PTO, Peebles, Ohio, USA;34712;TF;440;4182C 68 | CF6-80C2B1;Site IIIC, PTO, Peebles, Ohio;29-May-85;TF;2953;41706 69 | CF6-80C2B1F;Site IIIC, PTO, Peebles, Ohio;29-May-85;TF;3127;41706 70 | CF6-80C2B2F;Site IIIC, PTO, Peebles, Ohio;29-May-85;TF;3467;41826 71 | CF6-80C2B4;Site IIIB, PTO Peebles;34t12;TF;535;41647 72 | CF6-80C2B4F;Site IIIC, PTO, Peebles, Ohio;29-May-85;TF;3176;41798 73 | CF6-80C2B6;Site IIIB, PTO Peebles;34712;TF;509;41647 74 | CF6-80C2B7F;Site IIIC, PTO, Peebles, Ohio;29-May-85;TF;3041;41799 75 | CF6-80C2D1F;Site IIIC, PTO, Peebles, Ohio;29-May-85;TF;2822;41799 76 | CF6-80C2D1F;Site IIIB, PTO Peebles;34712;TF;478;41678 77 | CF6-80E1A3;Site IIIB, PTO Peebles;34712;TF;3438;41861 78 | CF6-80E1A4;Site IIIB, PTO, Ohio;35077;TF;359;41765 79 | GE90-76B;Site IVD and 6, PTO, Peebles;34754;TF;1753;41681 80 | GE90-76B;Site IIID, PTO, Peebles, OH;36534;TF;241;41823 81 | GE90-76B ;Site 6A;39416;TF;1318;2.00 82 | GE90-77B;Site IIID, PTO, Peebles, OH;36534;TF;243;41823 83 | GE90-85B;Site IVD and 6, PTO, Peebles;34754;TF;1772;41861 84 | GE90-85B ;Site 6A;39416;TF;1212;44958 85 | GE90-90B;Site IIID, PTO, Peebles, OH;36534;TF;226;41794 86 | GE90-90B ;Site 6A;39416;TF;1298;41793 87 | GE90-92B;SitJ IIID, PTO, Peebles, Ohi1, USA;35544;TF;212;0.6 88 | GEnx-1B58;PTO, Ohio, USA;40085;TF;342;41884 89 | GEnx-1B64;PTO, Ohio, USA;40085;TF;265;41675 90 | GEnx-1B54/P1;PTO, Ohio, USA;40085;TF;326;41860 91 | GEnx-1B67/P1;PTO, Ohio, USA;40085;TF;208;41860 92 | GEnx-1B70/75/P1;PTO, Ohio, USA;40085;TF;192;41860 93 | AS907-1-1A;Phoenix, AZ;37266;TF;325;41844 94 | HTF7000 (AS907-1-1A);Phoenix, AZ;40275;MTF;-;15 95 | V2522-A5 SelectOne™ Upgrade Package;East Hartford, CT;11-Dec-08;MTF;39;41650 96 | 92Y24-A5 SelectOne™ Upgrade Package;East Hartford, CT;11-Dec-08;MTF;39;41650 97 | V2527-A5E SelectOne™ Upgrade Package;East Hartford, CT;11-Dec-08;MTF;39;41650 98 | V2527E-A5;East Hartford, CT;33828;MTF;32;41801 99 | V2530-A5 SelectOne™ Upgrade Package;East Hartford, CT;11-0ecI08;MTF;38;41650 100 | V2533-A5 SelectOne™ Upgrade Package;East Hartford, CT;11-Dx2-08;MTb;38;41650 101 | NK-C-2U;Sheremetjevo, Moscow;33038;MTF;11824;- 102 | SaM146-1S18;Test facilities Snecma in Villaroche, France and NPO-Saturn in Rybinsk, Russia;39995;MTF;136;41834 103 | JT15D-5, -5A, -5B;Longueuil, Quebec;34075;TF;5715;41663 104 | JT3D-3B;East Hartford, CT, USA.;8-Mar-72;TF;24363;63.9 105 | JT8D-15;E Hartford, CT, USA;27851;MTF;2713;41723 106 | JT8D-15;E Hartford, CT, USA;7-Dec-79;MTF;428;41715 107 | JT8D-17;E Hartford, CT, USA;7-Dec-79;MTF;379;41777 108 | JT8D-217;East Hartford, CT;36215;MTF;0;41889 109 | JT8D-217 series;E Hartford, CT, USA;30627;MTF;937;41656 110 | JT8D-219;East Hartford, CT;36215;MTF;k;41890 111 | JT8D-9 series;E Hartford, CT, USA;27851;MTF;2256;24.0 112 | JT9D-20;British Airways Engine Overhaul Ltd, Wales;Mar-76;TF;12108;41894 113 | JT9D-20J;E Hartford, CT, USA;29480;TF;9178;41871 114 | JT9D-70A;E Hartford, CT, USA;27851;TF;4559;41708 115 | JT9D-7F;E Hartford, CT, USA;29480;TF;9464;41871 116 | JT9D-7R4D, -7R4D1;E Hartford, CT, USA;6-Mar-80;TF;464;5.0 117 | JT9D-7R4E4, -E1(H);E Hartford, CT, USA;26-Oct-81;TF;1231;41824 118 | JT9D-7R4H1;E Hartford, CT, USA;26-Oct-81;TF;651;41737 119 | PW2040;East Hartford, CT;30536;TF;426;41771 120 | PW307A;Mississauga, Ontario, Canada;30-Dec-04;MTF;357;41641 121 | PW308A;Mississauga, Ontario, Canada;36631;MTF;460;41656 122 | PW4056;-;32006;TF;652;10.0 123 | PW4074D;East Hartford, Conn, USA;35231;TF;1926;41733 124 | -------------------------------------------------------------------------------- /demo/data/cm_desc.txt: -------------------------------------------------------------------------------- 1 | 1,2 2 | 2,6 3 | 3,7 4 | 4,9 5 | 5,16 6 | 6,19 -------------------------------------------------------------------------------- /demo/data/concarne.csv: -------------------------------------------------------------------------------- 1 | TF;GE;2.4;Jet A;0.47 2 | TF;GE Aircraft Engines;"225.3 ";Jet A;"44.2 " 3 | TF;GE Aircraft Engines;"82.5 ";Jet A;"16.2 " 4 | TF;GE Transportation;68.1;Jet A1;13.34 5 | TF;Allied Signal;"139.8 ";ASTM D1655-73T;"27.4 " 6 | TF;GE;2d;Jet A;0.46 7 | TF;Rolls Royce;"1.0 ";-;"0.2 " 8 | TF;Rolls-Royce;0.4;-;0.08 9 | MTF;Rolls Royce Ltd;"71.0 ";AVTUR;"13.9 " 10 | MTF;Rolls-Royce;34.2;AVTUR;6.7 11 | TF;GE;28.5;Jet A1;5.59 12 | MTF;International Aero Engines;"2.2 ";Jet A;"0.4 " 13 | MTF;Honeywell;19.5;Jet-A;3.82 14 | TF;GE Aircraft Engines;"173.9 ";Jet A;"34.1 " 15 | MTF;Pratt & Whitney;"25.0 ";Jet A;"4.9 " 16 | TF;Pratt & Whitney;"9.4 ";Jet A;"1.8 " 17 | TRz;GE Aircraft Engines;"69.4 ";Jet A;"13.6 " 18 | MTF;Pratt & Whitney;"43.8 ";Jet A;"8.6 " 19 | MTF;Pratt & Whitney Canada Inc.;41.8;Jet A-1;8.2 20 | TF;GE;"11.7 ";Jet A;"2.3 " 21 | MTF;Rolls-Royce Corporation;71.6;Jet A;14.04 22 | TF;GE Aviation;4.69;JET A;0.92 23 | TF;GE;"27.0 ";Jet A;"5.3 " 24 | MTF;Pratt & Whitney;"0.1 ";Jet A;"0.0 " 25 | TF;Pratt & Whitney;"132.8 ";Jet A;"26.0 " 26 | TF;Pratt & Whitney;"326.6 ";DERD2494;"64.0 " 27 | MTF;International Aero Engines;"2.0 ";Jet A;"0.4 " 28 | "";Pratt & Whitney;"25.9 ";Jet A;"5.1 " 29 | TF;GE;"10.7 ";Jet A;"2.1 " 30 | TF;GE Aircraft Engines;"190.1 ";Jet A;"37.3 " 31 | TF;GE;"24.0 ";Jet A;"4.7 " 32 | MTF;Pratt & Whitney;"36.3 ";Jet A;"7.1 " 33 | MTF;AO 'Aviadgatel';"270.9 ";TS-1;"53.1 " 34 | TF;Pratt & Whitney;"15.7 ";Jet A;"3.1 " 35 | MTF;BMW Rolls-Royce GmbH;"1.4 ";ATU;"0.3 " 36 | TF;Pr\att& Whitney;"30.6 ";Jet A;"6.0 " 37 | TF;CFM International;26.3;Jet A;5.16 38 | MTF;Pratt & Whitney;"0.1 ";Jet A;"0.0 " 39 | MTF;BMW Rolls-Royce GmbH;"3.1 ";AVTUR;"0.6 " 40 | TF;Pratt & Whitney;"33.8 ";Jet A;"6.6 " 41 | MTF;Pratt & Whitney Canada Inc.;"81.1 ";Jet A-1;"15.9 " 42 | TF;GE Transportation;"39.1 ";Jet A;"7.7 " 43 | TF;GE;"27.0 ";Jet A;"5.3 " 44 | MTF;CFM International;"52.0 ";Jet A;"10.2 " 45 | TF;CFM International;26.3;JET A;5.1u|6 46 | MTF;Rolls Royce Ltd;"99.6 ";DERD 2494;"19.5 " 47 | MTF;BMW Rolls-Royce GmbH;"1.8 ";AVTUR;"0.4 " 48 | TF;GE Aircraft Engines;"59.2 ";Jet A;"11.6 " 49 | TF;GE Aircraft Engines;"2.6 ";Jet A;"0.5 " 50 | TF;CFM International;"44.9 ";Jet A;"8.8 " 51 | TF;CFMI;"44.8 ";Jet A;"8.8 " 52 | MTF;BMW Rolls-Royce GmbH;"2.5 ";AVTUR;"0.5 " 53 | MTF;Pratt & Whitney;00;Jet A;"0.0 " 54 | TF;GE;24.0;Jet A1;4[7[ 55 | "(TF)";Rolls-Royce;0.3;-;0.06 56 | TF;Pratt & Whitney;"t0.2 ";Jet A;"2.0 " 57 | TF;GE Aircraft Engines;"73.8 ";Jet A;"14.5 " 58 | TF;GE;"13.3 ";Jet A;"2.6 " 59 | TF;CFM International;20.9;JET A;4.09 60 | TF;GE;2.3;Jet A;0.44 61 | TF;PrZtt & Whitney;"330.1 ";Jet A;"64.7 " 62 | TF;CFM International;8.5;Jet A;1.67 63 | TF;GE Aircraft Engines;"61.7 ";Jet A;"12.1 " 64 | MTF;Rolls-Royce;"41.3 ";Def. Stan. 91-92;"8.1 " 65 | "(TF)";Rolls-Royce;0.8;-;0.15 66 | MTF;Pratt & Whitney Canada Inc;"89.3 ";Jet A-1;"17.5 " 67 | TF;GE;"26.0 ";Jet A;"5.1 " 68 | TF;Prat & Whitney (Canada);N/A;Jet A-1;"293.6 " 69 | t;Pratt & Whitney;"14.9 ";Jet A;"2.9 " 70 | TF;GE Transportation;"42.7 ";Jet A1;"8.4 " 71 | -------------------------------------------------------------------------------- /demo/data/concarne_desc.txt: -------------------------------------------------------------------------------- 1 | 1,9 2 | 2,4 3 | 3,15 4 | 4,20 5 | 5,14 -------------------------------------------------------------------------------- /demo/data/gr1.csv: -------------------------------------------------------------------------------- 1 | GE90-76B;GE90 Eval Engineering;34.88;360.6;-;97.3 - 98.2 2 | GE90-76B ;General Electric Peebles Test Operation;35.45;354.32;-;98.41 - 98.66 3 | GE90-76B ;General Electric Peebles Test Operation;35.50;363.22;-;98.41 - 98.66 4 | GE90-77B;GE90 Eval Engineering;35.20;363.42;-;97.38-98.59 5 | GE90-77B;GE90 Eval Engineering;35.3;363.42;-;97.52-98.62 6 | GE90-77B;GE90 Eval Engineering;35.1;363.4;-;97.3 - 98.2 7 | GE90-77B ;General Electric Peebles Test Operation;35.68;357.07;-;98.41 - 98.66 8 | GE90-77B ;General Electric Peebles Test Operation;35.80;366.75;-;98.41 - 98.66 9 | GE90-85B;GE90 Eval Engineering;38.1;395.31;-;97.38-98.59 10 | GE90-85B;GE90 Eval Engineering;38;395.31;-;97.52-98.62 11 | GE90-85B;GE90 Eval Engineering;37.7;395.3;-;97.3 - 98.2 12 | GE90-85B ;General Electric Peebles Test Operation;38.37;388.40;-;98.41 - 98.66 13 | GE90-85B ;General Electric Peebles Test Operation;38.16;397,21;-;98.41 - 98.66 14 | GE90-90B;GE90 Eval Engineering;39.7;418.13;-;97.38-98.59 15 | GE90-90B;GE90 Eval Engineering;39.8;418.13;-;97.52-98.62 16 | GE90-90B;GE90 Eval Engineering;39.38;418.1;-;97.3 - 98.2 17 | GE90-90B ;General Electric Peebles Test Operation;40.32;410.82;-;98.41 - 98.66 18 | GE90-90B ;General Electric Peebles Test Operation;39.85;419.25;-;98.41 - 98.66 19 | GE90-92B;GE90 Eval Engineering;40.4;426.72;-;97.38-98.59 20 | GE90-92B;GE90 Eval Engineering;40.6;426.72;-;97.52-98.62 21 | GE90-94B;GE90 Eval Engineering;40.53;432.8;8GE100;97.3 - 98.2 22 | GE90-94B;GE90 Eval Engineering;40.53;432.8;-;97.3 - 98.2 23 | GE90-94B ;General Electric Peebles Test Operation;40.82;430.92;-;98.41 - 98.66 24 | GEnx-1B54;GE Aviation;35.2;255.3;-;97.4 to 98.6 25 | GEnx-1B58;GE Aviation;37.2;271.3;-;97.4 to 98.6 26 | GEnx-1B64;GE Aviation;40.6;298;-;97.4 to 98.6 27 | GEnx-1B67;GE Aviation;41.9;308.7;-;97.4 to 98.6 28 | GEnx-1B70;GE Aviation;43.5;321.6;-;97.4 to 98.6 29 | GEnx-2B67;GE Aviation;42.4;299.8;-;97.4 to 98.6 30 | GEnx-1B54/P1;GE Aviation;35.1;255.3;-;97.4 to 98.6 31 | GEnx-1B58/P1;GE Aviation;37.1;271.3;-;97.4 to 98.6 32 | GEnx-1B64/P1;GE Aviation;40.5;298.0;-;97.4 to 98.6 33 | GEnx-1B67/P1;GE Aviation;41.9;308.7;-;97.4 to 98.6 34 | GEnx-1B70/P1;GE Aviation;43.5;321.6;-;97.4 to 98.6 35 | GEnx-1B70/72/P1;GE Aviation;43.5;321.6;-;97.4 to 98.6 36 | GEnx-1B70/75/P1;GE Aviation;43.5;321.6;-;97.4 to 98.6 37 | GEnx-1B74/75/P1;GE Aviation;46.0;341.2;-;97.4 to 98.6 38 | GEnx-1B75/P1;GE Aviation;46.5;345.2;-;97.4 to 98.6 39 | AS907-1-1A;Honeywell;21.95;30.62;-;96.48-97.46 40 | HTF 7000 (AS907-1-1A);Honeywell;21.95;30.62;-;96.75-97.59 41 | HTF7000 (AS907-1-1A);Honeywell;21.95;30.62;-;96.44-97.59 42 | HTF7250G (AS907-2-1G);Honeywell;22.58;32.86;-;96.44-97.35 43 | HTF7250G (AS907-2-1G);Honeywell;22.58;32.86;-;96.44-97.59 44 | V2500-A1;Pratt & Whitney;29.8;111.2;-;101.3 45 | V2522-A5;Pratt & Whitney;25.6;102.66;-;101.0-101.8 46 | V2522-A5 SelectOne™ Upgrade Package;Pratt & Whitney;25.7;102.5;-;100.35-102.88 47 | V2524-A5;Pratt & Whitney;26.9;109.06;-;101.0-101.8 48 | V2524-A5 SelectOne™ Upgrade Package;Pratt & Whitney;27;108.9;-;100.35-102.88 49 | V2525-D5;Pratt & Whitney;27.2;111.2;-;101.0-101.8 50 | V2527-A5;Pratt & Whitney;27.2;111.2;-;101.0-101.8 51 | V2527-A5 SelectOne™ Upgrade Package;Pratt & Whitney;27.1;110.3;-;100.35-102.88 52 | V2527-A5E SelectOne™ Upgrade Package;Pratt & Whitney;27.1;110.3;-;100.35-102.88 53 | V2527-A5M SelectOne™ Upgrade Package;Pratt & Whitney;27.1;110.3;-;100.35-102.88 54 | V2527E-A5;P&W;27.2;111.2;-;101.0 - 101.8 55 | V2527M-A5;P&W;27.2;111.2;-;101.0 - 101.8 56 | V2528-D5;Pratt & Whitney;30.0 ;124.5;-;101.0-101.8 57 | V2530-A5;Pratt & Whitney;32.1;133.4;-;101.0-101.8 58 | V2530-A5 SelectOne™ Upgrade Package;Pratt & Whitney;32;133;-;100.35-102.88 59 | V2533-A5;Pratt & Whitney;33.44;140.56;-;101.0-101.8 60 | V2533-A5 SelectOne™ Upgrade Package;Pratt & Whitney;33.7;140.6;-;100.35-102.88 61 | NK-8-2U;State Inst for Civ Aviation;10.8;103;-;102.6 62 | NK-8-2U;State Inst for Civ Aviation;10.8;103;-;102.7 63 | NK-86;State Inst for Civ Aviation;13.4;127.53;-;102.7-103.0 64 | NK-86A;KKBM;13.2;130.47;-;102.3 65 | NK-86MA;KKBM;13.2;130.47;-;101.2-102.4 66 | SaM146-1S17;PowerJet S.A.;21.85;69.21;-;100.43 -101.26 67 | SaM146-1S18;PowerJet S.A.;22.8;72.67;-;100.43 -101.26 68 | JT15D-1 series;Pratt & Whitney (Canada);9.76;9.79;-;100.526 69 | JT15D-4 series;Pratt & Whitney (Canada);10.1;11.12;-;103.146 70 | JT15D-5, -5A, -5B;Pratt & Whitney (Canada);12.3;12.90 ;-;99.42 71 | JT15D-5C;Pratt & Whitney (Canada);13.3;14.19;-;101.7 72 | JT3D-3B;P&WA;13.6;80.06;-;- 73 | JT3D-7 series;P&WA;13.4;84.52;-;- 74 | JT3D-7 series;P&WA;13.4;84.52;-;- 75 | JT8D-11;P&WA;17.17;66.72;-;- 76 | JT8D-15;P&WA;16.81;68.94;-;- 77 | JT8D-15;P&WA;16.81;68.94;-;- 78 | JT8D-15A;P&WA;16.45;68.94;-;- 79 | PW307A;PW307 Development Engineering;20.21;28.49;-;98.39 - 100.80 80 | RB211-524C2;Rolls Royce Ltd;29.1 ;224.8;-;102 81 | RB211-524D4;Rolls Royce Ltd;29.7 ;231.3;-;101 82 | RB211-524D4;Rolls Royce Ltd;30.22;231.3;-;103 83 | RB211-524G;Rolls Royce Ltd;32.1;253;1RR010;101 84 | RB211-524G;Rolls Royce Ltd;32.1;253;-;101 85 | RB211-524G-T;Rolls-Royce plc;32.1;253;-;100.2 86 | Trent 1000-E;Rolls-Royce;37.51;279.8;12RR058;98.9 - 102.1 87 | Trent 1000-G;Rolls-Royce;42.53;323.7;12RR059;98.9 - 102.1 88 | Trent 1000-H;Rolls-Royce;38.33;286.7;12RR060;98.9 - 102.1 89 | Trent 1000-A;Rolls-Royce;41.04;310.9;-;98.9 - 102.1 90 | Trent 1000-C;Rolls-Royce;43.78;334.7;-;98.9 - 102.1 91 | Trent 1000-D;Rolls-Royce;43.78;334.7;-;98.9 - 102.1 92 | Trent 1000-E;Rolls-Royce;36.19;268;-;98.9 - 102.1 93 | Trent 1000-G;Rolls-Royce;42.53;323.7;-;98.9 - 102.1 94 | Trent 1000-H;Rolls-Royce;38.33;287.1;-;98.9 - 102.1 95 | Trent 1000-A2;Rolls-Royce;41.3;310.9;-;98.9 - 102.1 96 | Trent 1000-C2;Rolls-Royce;44.1;334.7;-;98.9 - 102.1 97 | Trent 1000-D2;Rolls-Royce;44.1;334.7;-;98.9 - 102.1 98 | Trent 1000-E2;Rolls-Royce;36.32;268;-;98.9 - 102.1 99 | Trent 1000-G2;Rolls-Royce;42.81;323.7;-;98.9 - 102.1 100 | Trent 1000-H2;Rolls-Royce;38.52;287.1;-;98.9 - 102.1 101 | Trent 1000-J2;Rolls-Royce;46.08;350.9;-;98.9 - 102.1 102 | Trent 1000-K2;Rolls-Royce;46.08;350.9;-;98.9 - 102.1 103 | Trent 1000-L2;Rolls-Royce;44.1;334.7;-;98.9 - 102.1 104 | ALF 502L-2;Textron Lycoming;13.15;33.4;-;101.7 105 | ALF 502R-3;Textron Lycoming;11.4;29.8;-;101.3-102.4 106 | ALF 502R-5;Textron Lycoming;12.0 ;31.0 ;-;101.3-102.4 107 | LF507-1F, -1H ;Textron Lycoming;13.0 ;31.0 ;-;101.3-102.4 108 | D-36;ZMKB;19.9 ;63.765;-;99.9-101.5 -------------------------------------------------------------------------------- /demo/data/gr1_desc.txt: -------------------------------------------------------------------------------- 1 | 1,2 2 | 2,5 3 | 3,11 4 | 4,12 5 | 5,13 6 | 6,22 7 | -------------------------------------------------------------------------------- /demo/data/horst.csv: -------------------------------------------------------------------------------- 1 | 6AL005;3-Mar-94;11.42;307;Jet A 2 | 6AL006;28-Aug-02;16.19;367;Jet A 3 | 6AL009;28-Aug-02;16.43;370;Jet A 4 | 6AL020;9-Jun-01;10.93;264;Jet A 5 | 6AL021;3-Mar-94;14.04;320;Jet A 6 | 3BR001;5-Jun-96;6.6;289;AVTTUR 7 | 4BR002;7-May-98;0.6;34;AVTUR 8 | 1CM009;19-Nov-86;3.5;268;Jet A 9 | 4CM035;19-Nov-86;5.1;322;Jet A 10 | 4CM036;19-Nov-86;4.3;297;Jet A 11 | 3CM020;Aug-96;8.8;891;Jet A 12 | 8CM052;Sep-05;2.1;240;Jet A 13 | 2CM013;Oct-92;6.6;596;Jet AZ 14 | 3CM024;Nov-95;7.9;712;Jet A 15 | 3CM025;Nov-95;7.7;708;Jet A 16 | 2CM018;Jun-94;14.6;1350;Jet A 17 | 2DM019;Jun-95;6.7;630;Jet A 18 | 6CM044;Nov-95;10.4;818;Jet A 19 | 7CM048;Nov-95;16.6;1023;Jet A 20 | 7CM047;Jun-91;9.3;897;Jet A 21 | 3CM032;Jul-96;6.0;432;Jet A 22 | 11CM071;29-Sep-05;4.09;377;JET A 23 | 4CM042;30-Aug-97;14.2;1425;Jet A 24 | 11CM1072;29-Sep-05;3.01;302;JET A 25 | 11CM080;29-Sep-05;2.62;273;JET A 26 | 11GE141;5-Sep-06;14.6;776;Jet A1 27 | 10GE133;5-Sep-06;12.7;690;Jet A1 28 | 11GE146;5-Jun-09;10.46;568;Jet A1 29 | 5GE084;21-Mar-91;13.7;366;Jot A 30 | 6GE096;27-Jan-02;0.5;20;Jet A 31 | 8GE112;27-Jan-02;0.55;20;Jet A 32 | 6GE095;27-Jan-02;0.4;18;Jet A 33 | 3GE067;28-Jul-87;6.0;780;Jet A 34 | 1GE006;12-Oct-79;39.2;7998;Jet A 35 | 3GE074;28-Jul-87;5.3;788;Jet A 36 | 3G071;28-Jul-87;5.3;784;Jet A 37 | 3GE076;28-Jul-87;5.3;788;Jet A 38 | 1GE009;12-Oct-79;37.3;7715;Jet A 39 | 1GE004;16-Aug-79;34.1;5617;Jet A 40 | 1GE012;11-Nov-83;11.7;1659;Jet A 41 | 1GE016;29-May-85;17.6;3152;Jet A 42 | 2GE037;13-Jan-95;3.4;602;Jet A 43 | 2GE045;13-Jan-95;2.6;513;Jet A 44 | 2GE043;13-Jan-95;2.7;535;Jet A 45 | 2GE044;13-Jan-95;2.5;509;Jet A 46 | 1GE030;29-May-85;14.8;3041;Jet A 47 | 2GE048;13-Jan-95;2.4;490;Jet A 48 | 2GE055;13-Jan-95;2.4;490;Jet A 49 | 8GE101;13-Jan-96;1.72;394;Jet A 50 | 3GE058;13-Jan-95;2.4;489;Jet A 51 | 2GE050;13-Jan-95;2.3;494;Jet A 52 | 4GE080;13-Jan-95;16.3;3726;Jet A 53 | 2GE052;24-Feb-95;5.6;1753;Jet A 54 | 5GE086;9-Jan-00;1.1;241;Jet A 55 | 3GE063;24-Apr-97;0.9;276;Jet A 56 | 11GE136;29-Sep-09;1.37;265;JET A 57 | 12GE152;29-Sep-09;0.92;192;JET A 58 | 10IA013;11-Dec-08;0.5;39;JET A 59 | 10IA015;11-Dec-08;0.5;39;JET A 60 | 1KK003;15-Jun-89;157.5;17379;TS-1 61 | 1KK005;18-Jul-87;15.2;1773;TS-1 62 | 1PW008;26-Feb-80;39.5;2455;Jet A 63 | 1PW013;7-Dec-79;6.2;379;Jet A 64 | 1PW015;7-Dec-79;6.1;403;Jet A 65 | 4PW068;24-Feb-99;0.0;0;Jet A 66 | 4PW069;24-Feb-99;0.0;0;Jet A 67 | 4PW071;24-Feb-99;0.0;0;Jet A 68 | 8PW085;26-Feb-80;17.2;830;Jet A 69 | 8PW088;Mar-76;64.0;12108;DERD2494 70 | 1PW020;Mar-76;65.1;12179;DERD2494 71 | 1PW034;Apr-76;26.0;4559;Jet A 72 | 1PW024;16-Sep-80;64.7;9178;Jet A 73 | 1PW030;26-Oct-81;3.0;651;Jet A 74 | 1PW039;8-Aug-83;4.9;530;Jet A 75 | 4PW072;8-Aug-83;3.6;472;Jet A 76 | 1PW040;8-Aug-83;5.1;574;Jet A 77 | 11PW100;7-Aug-07;9.2;226;Jet A-1 78 | 8PW090;30-Dec-04;14.6;357;Jet A-1 79 | 8PW091;28-Dec-04;8.2;202;Jet A-1 80 | 7PW079;15-Apr-00;17.5;460;Jet A-1 81 | 1PW042;17-Aug-87;4.0;652;Jet A 82 | 2PW062;26-Apr-94;4.5;1111;Jet A 83 | 1PW048;17-Aug-87;3.7;623;Jet A 84 | 7PW081;10-Apr-00;0.8;139;Jet A 85 | 5PW075;10-Apr-00;0.5;78;Jet A 86 | 7PW082;10-Apr-00;0.5;78;Jet A 87 | 1RR006;Sep-86;179.4;26209;AVTUR 88 | 1RR012;Apr-84;4.0;552;AVTUR 89 | 3RR028;Apr-91;0.9;111;AVTUR 90 | 8RR043;23-May-05;232.4;11179;DERD 2494 91 | 1RR021;Mar-88;13.9;717;AVTUR 92 | 6RR041;7-Jan-02;0.2;36;- 93 | 2RR022;Jul-94;3.9;752;AVTUR 94 | 9RR047;18-Mar-06;0.50;101;- 95 | 11RR052;24-Sep-09;0.14;33;- 96 | 12RR056;24-Sep-09;0.04;12;- 97 | 12RR057;24-Sep-09;0.04;12;- 98 | 12RR062;24-Sep-09;0.04;12;- 99 | 12RR064;24-Sep-09;0.15;36;- 100 | 12RR065;24-Sep-09;0.05;14;- 101 | 12RR066;24-Sep-09;0.1;25;- 102 | 1TL003;26-Jul-82;13.6;351;0.81 103 | -------------------------------------------------------------------------------- /demo/data/horst_desc.txt: -------------------------------------------------------------------------------- 1 | 1,1 2 | 2,7 3 | 3,14 4 | 4,16 5 | 5,20 -------------------------------------------------------------------------------- /demo/data/maca.csv: -------------------------------------------------------------------------------- 1 | 6AL013;AE3007A1/3;Rolls-Royce Corporation;MTF;12.55;64.0;98.9 - 99.0 2 | 6AL020;AE3007A1E;Rolls-Royce Corporation;MTF;10.93;55.8;98.9 - 99.0 3 | 6AL014;AE3007A1P;Rolls-Royce Corporation;MTF;11.55;58.9; 4 | 6AL015;AE3007A1P;Rolls-Royce Corporation;MTF;16.34;83.4;99.6 - 99.7 5 | 6AL016;AE3007A1P;Rolls-Royce Corporation;MTF;12.41;63.3;98.9 - 99.0 6 | 10AL026;AE3007A2;Rolls-Royce Corporation;MTF;5.32;27.12;101.3 7 | 6AL017;AE3007A3;Rolls-Royce Corporation;MTF;14.22;72.6; 8 | 6AL018;AE3007A3;Rolls-Royce Corporation;MTF;18.7;95.4;99.6 - 99.7 9 | 6AL019;AE3007A3;Rolls-Royce Corporation;MTF;13.48;68.8;98.9 - 99.0 10 | 3AL001;AE3007C;Allison Engine Company;MTF;17.5 ;89.3 ;101.3 11 | 6AL021;AE3007C;Rolls-Royce Corporation;MTF;14.04;71.6; 12 | 6AL022;AE3007C;Rolls-Royce Corporation;MTF;17.85;91.1;99.6 - 99.7 13 | 1AA005;PS-90A;AO 'Aviadgatel';MTF;1.4 ;7.1 ;102.9-104 14 | 3BR001;BR700-710A1-10;BMW Rolls-Royce GmbH;MTF;6.6 ;33.7 ;101.5-102.1 15 | 4BR008;BR700-710A1-10;BMW Rolls-Royce GmbH;MTF;3.7 ;18.6 ;100.9-101.2 16 | 4BR009;BR700-710A2-20;BMW Rolls-Royce GmbH;MTF;3.8 ;19.2 ;100.9-101.2 17 | 6BR010;BR700-710C4-11;Rolls-Royce;MTF;6.7;34.2;100.9 - 101.2 18 | 4BR002;BR700-715A1-30;BMW Rolls-Royce GmbH;MTF;0.6 ;3.1 ;101.3-101.9 19 | 4BR005;BR700-715A1-30;BMW Rolls-Royce GmbH;MTF;0.5 ;2.5 ;100.9-101.3 20 | 4BR003;BR700-715B1-30;BMW Rolls-Royce GmbH;MTF;0.5 ;2.3 ;101.3-101.9 21 | 4BR006;BR700-715B1-30;BMW Rolls-Royce GmbH;MTF;0.4 ;1.8 ;100.9-101.3 22 | 4BR004;BR700-715C1-30;BMW Rolls-Royce GmbH;MTF;0.4 ;1.8 ;101.3-101.9 23 | 4BR007;BR700-715C1-30;BMW Rolls-Royce GmbH;MTF;0.3 ;1.4 ;100.9-101.3 24 | 3CM020;CFM56-5B1/2P;GEAE Peebles Testing Facility + Techspace Aero (CFMI);TF;8.8 ;44.9 ;98.5-99.74 25 | 8CM052;CFM56-5B1/3;GE Aviation;TF;2.1;10.7;97.6 to 98.5 26 | 8CM054;CFM56-5B3/3;GE Aviation;TF;1.67;8.5;97.6 to 98.5 27 | 3CM025;CFM56-5B3/P;CFM56-5B Eval Engineering;TF;7.7 ;39.3 ;98.2-99.6 28 | 2CM014;CFM56-5B4;CFM56 Evaluation Engineering;TF;8.8 ;44.8 ;97.49 - 98.18 29 | 2CM018;CFM56-5B4/2;CFM56 Evaluation Engineering;TF;14.6 ;74.5 ;100.67-101.01 30 | 3CM021;CFM56-5B4/2P;GEAE Peebles Testing Facility + Techspace Aero (CFMI);TF;12.0 ;61.2 ;98.5-99.74 31 | 8CM055;CFM56-5B4/3;GE Aviation;TF;3.05;15.6;97.6 to 98.5 32 | 3CM026;CFM56-5B4/P;CFM56-5B Eval Engineering;TF;10.4 ;53.1 ;98.2-99.6 33 | 8CM056;CFM56-5B5/3;GE Aviation;TF;6.2;31.6;97.6 to 98.5 34 | 3CM027;CFM56-5B5/P;CFM56-5B Eval Engineering;TF;15.3 ;78.1 ;98.2-99.6 35 | 2CM019;CFM56-5B6/2;"SNECMA; Villaroche; France";TF;6.7 ;34.0 ;99.29-101.01 36 | 3CM022;CFM56-5B6/2P;GEAE Peebles Testing Facility + Techspace Aero (CFMI);TF;10.3 ;52.6 ;98.5-99.74 37 | 8CM057;CFM56-5B6/3;GE Aviation;TF;4.95;25.3;97.6 to 98.5 38 | 3CM028;CFM56-5B6/P;CFM56-5B Eval Engineering;TF;13.3 ;67.9 ;98.2-99.6 39 | 8CM058;CFM56-5B7/3;GE Aviation;TF;3.05;15.6;97.6 to 98.5 40 | 6CM044;CFM56-5B7/P;CFM56-5B Eval Engineering;TF;10.4 ;53.2 ;98.2 - 99.6 41 | 8CM059;CFM56-5B8/3;GE Aviation;TF;6.61;33.7;97.6 to 98.5 42 | 7CM048;CFM56-5B8/P;CFM56 Evaluation Engineering;TF;16.6 ;84.7 ;98.2 - 99.6 43 | 7CM050;CFM56-5B9/2P;CFM56 Evaluation Engineering;TF;9.9;50.5;98.5 - 99.74 44 | 8CM060;CFM56-5B9/3;GE Aviation;TF;5.09;26.0;97.6 to 98.5 45 | 7CM049;CFM56-5B9/P;CFM56 Evaluation Engineering;TF;14.4 ;73.5 ;98.2 - 99.6 46 | 1CM010;CFM56-5C2;CFM56 Evaluation Engineering;MTF;11.6 ;59.4 ;97.77-98.11 47 | 7CM045;CFM56-5C2/P;CFM56 Evaluation Engineering;MTF;11.1;56.6;97.77 - 98.11 48 | 1CM011;CFM56-5C3;CFM56 Evaluation Engineering;MTF;10.8 ;55.0 ;97.77-98.11 49 | 7CM046;CFM56-5C3/P;CFM56 Evaluation Engineering;MTF;10.2 ;52.0 ;97.77 - 98.11 50 | 2CM015;CFM56-5C4;CFM56 Evaluation Engineering;MTF;9.9 ;50.5 ;97.77-98.11 51 | 11CM069;CFM56-7B22E/B1;GE Aviation;TF;5.16;26.3;97.6 to 98.5 52 | 3CM032;CFM56-7B24;CFM56-7B Eval Engineering;TF;6.0 ;30.6 ;97.8-98.0 53 | 4CM041;CFM56-7B24/2;CFM56-7B Eval Engineering;TF;17.1 ;87.2 ;97.9-98.0 54 | 8CM064;CFM56-7B24/3;GE Aviation;TF;4.09;20.9;97.6 to 98.5 55 | 11CM070;CFM56-7B24E;GE Aviation;TF;4.09;20.9;97.6 to 98.5 56 | 11CM071;CFM56-7B24E/B1 ;GE Aviation;TF;4.09;20.9;97.6 to 98.5 57 | 3CM033;CFM56-7B26;CFM56-7B Eval Engineering;TF;4.7 ;24.0 ;97.8-98.0 58 | 8CM051;CFM56-7B26;CFM56-7B Eval Engineering;TF;4.7 ;24.0 ;97.8-98.0 59 | 4CM042;CFM56-7B26/2;CFM56-7B Eval Engineering;TF;14.2 ;72.7 ;97.9-98.0 60 | 8CM065;CFM56-7B26/3;GE Aviation;TF;3.01;15.4;97.6 to 98.5 61 | 11CM072;CFM56-7B26E;GE Aviation;TF;3.01;15.4;97.6 to 98.5 62 | 11CM073;CFM56-7B26E/B1;GE Aviation;TF;3.01;15.4;97.6 to 98.5 63 | 11CM078;CFM56-7B27E/B1;GE Aviation;TF;2.62;13.4;97.6 to 98.5 64 | 11CM082;CFM56-7B27E/B1F ;GE Aviation;TF;2.62;13.4;97.6 to 98.5 65 | 11CM079;CFM56-7B27E/B3;GE Aviation;TF;2.62;13.4;97.6 to 98.5 66 | 11CM081;CFM56-7B27E/F;GE Aviation;TF;2.62;13.4;97.6 to 98.5 67 | 9EA001;GP7270;General Electric Peebles Test Operation;TF;6.94;35.4;97.396 - 97.812 68 | 11GE140;CF34-10A16;Peebles Test Operation;TF;18.4;93.9;97.2-97.9 69 | 11GE141;CF34-10A18;Peebles Test Operation;TF;14.6;74.5;97.2-97.9 70 | 8GE114;CF34-10E2A1;Peebles Test Operation;TF;14.72;75.1;98.4-98.6 71 | 10GE129;CF34-10E5;Peebles Test Operation;TF;16.89;86.17;97.2-97.9 72 | 11GE142;CF34-10E5;Peebles Test Operation;TF;13.34;68.1;97.2-97.9 73 | 8GE115;CF34-10E5;Peebles Test Operation;TF;13.77;70.2;98.4-98.6 74 | 10GE130;CF34-10E5A1;Peebles Test Operation;TF;12.7;64.80;97.2-97.9 75 | 8GE119;CF34-10E7;Peebles Test Operation;TF;11.05;56.4;98.4-98.6 76 | 11GE147;CF34-10E7-B;Peebles Test Operation;TF;10.46;53.4;97.2-97.9 77 | 1GE034;CF34-3A;"GE Aircraft Engines; Lynn; MA";TF;11.8 ;60.0 ;101.6-102.9 78 | 1GE035;CF34-3A1;"GE Aircraft Engines; Lynn; MA";TF;11.8 ;60.0 ;101.6-102.9 79 | 5GE084;CF34-3B;"GE Aircraft Engines; Lynn; MA";TF;13.7 ;69.9 ;101.6-102.9 80 | 5GE083;CF34-8C1;Peebles Test Opeation;TF;0.3 ;1.5 ;96.87 - 97.62 81 | 6GE096;CF34-8C1 Block 1;Peebles Test Operation;TF;0.5;2.6;97.1 - 98.1 82 | 6GE092;CF34-8C5;Peebles Test Operation;TF;0.5 ;2.6 ;97.1 - 98.1 83 | 3GE067;CF6-45A;GE Development/Production Test Operation;TF;6.0 ;30.6 ;97.73-97.91 84 | 1GE005;CF6-45A2;Production Engine Test;TF;44.2 ;225.3 ;98.3-100.4 85 | 3GE068;CF6-45A2;GE Development/Production Test Operation;TF;6.0 ;30.6 ;97.73-97.91 86 | 3GE069;CF6-50A;GE Development/Production Test Operation;TF;5.6 ;28.6 ;97.73-97.91 87 | 1GE006;CF6-50C;Production Engine Test;TF;39.2 ;199.8 ;98.3-100.4 88 | 3GE070;CF6-50C;GE Development/Production Test Operation;TF;5.3 ;27.0 ;97.73-97.91 89 | 3GE073;CF6-50C1;GE Development/Production Test Operation;TF;5.3 ;27.0 ;97.73-97.91 90 | 1GE007;"CF6-50C1; -C2";Production Engine Test;TF;37.3 ;190.1 ;98.3-100.4 91 | 3GE074;CF6-50C2;GE Development/Production Test Operation;TF;5.3 ;27.0 ;97.73-97.91 92 | 3GE078;CF6-50C2B;GE Development/Production Test Operation;TF;5.1 ;26.0 ;97.73-97.91 93 | 1GE008;CF6-50C2R;Production Engine Test;TF;39.2 ;199.8 ;98.3-100.4 94 | 3GE072;CF6-50C2R;GE Development/Production Test Operation;TF;5.3 ;27.0 ;97.73-97.91 95 | 3GE071;CF6-50CA;GE Development/Production Test Operation;TF;5.3 ;27.0 ;97.73-97.91 96 | 3GE075;CF6-50E;GE Development/Production Test Operation;TF;5.3 ;27.0 ;97.73-97.91 97 | 3GE076;CF6-50E1;GE Development/Production Test Operation;TF;5.3 ;27.0 ;97.73-97.91 98 | 1GE009;CF6-50E2;Production Engine Test;TF;37.3 ;190.1 ;98.3-100.4 99 | 3GE077;CF6-50E2;GE Development/Production Test Operation;TF;5.3 ;27.0 ;97.73-97.91 100 | 3GE079;CF6-50E2B;GE Development/Production Test Operation;TF;5.1 ;26.0 ;97.73-97.91 101 | 1GE001;CF6-6D;Production Engine Test;TF;36.7 ;187.4 ;99.15-100.46 102 | 1GE002;CF6-6D1A;Production Engine Test;TF;34.1 ;173.9 ;99.15-100.46 103 | 1GE003;CF6-6K;Production Engine Test;TF;36.7 ;187.4 ;99.15-100.46 104 | 1GE004;CF6-6K2;Production Engine Test;TF;34.1 ;173.9 ;99.15-100.46 105 | 1GE010;CF6-80A;Production Engine Test;TF;12.1 ;61.7 ;99.08-99.78 106 | 1GE017;CF6-80C2A3;CF6 Evaluation Engineering;TF;14.7 ;75.0 ;97.40-97.82 107 | 1GE018;CF6-80C2A3;CF6 Evaluation Engineering;TF;14.2 ;72.6 ;97.40-97.82 108 | 2GE038;CF6-80C2A3;CF6 Eval Engineering;TF;2.6 ;13.2 ;97.61-98.15 109 | 6GE088;GE90-77B;GE90 Eval Engineering;TF;1.0 ;5.3 ;97.3 - 98.2 110 | 9GE121;GE90-77B ;General Electric Peebles Test Operation;TF;6.68;34.1;98.41 - 98.66 111 | 9GE125;GE90-77B ;General Electric Peebles Test Operation;TF;5.49;28.0;98.41 - 98.66 112 | 2GE053;GE90-85B;GE90 Eval Engineering;TF;5.3 ;26.9 ;97.38-98.59 113 | 3GE064;GE90-85B;GE90 Eval Engineering;TF;0.7 ;3.6 ;97.52-98.62 114 | 6GE089;GE90-85B;GE90 Eval Engineering;TF;0.9 ;4.5 ;97.3 - 98.2 115 | 9GE122;GE90-85B ;General Electric Peebles Test Operation;TF;5.47;27.9;98.41 - 98.66 116 | 9GE126;GE90-85B ;General Electric Peebles Test Operation;TF;4.70;24.0;98.41 - 98.66 117 | 3GE060;GE90-90B;GE90 Eval Engineering;TF;4.7 ;24.0 ;97.38-98.59 118 | 3GE065;GE90-90B;GE90 Eval Engineering;TF;0.6 ;3.1 ;97.52-98.62 119 | 6GE090;GE90-90B;GE90 Eval Engineering;TF;0.8 ;4.2 ;97.3 - 98.2 120 | 9GE123;GE90-90B ;General Electric Peebles Test Operation;TF;4.87;24.8;98.41 - 98.66 121 | 9GE127;GE90-90B ;General Electric Peebles Test Operation;TF;4.26;21.7;98.41 - 98.66 122 | 6RR041;Trent 556-61;Rolls Royce;TF;0.2 ;1.0 ;100.04 - 102.91 123 | 8RR045;Trent 556-61;Rolls-Royce;TF;0.3;1.5;100.04 - 102.91 124 | 2RR022;Trent 768;Rolls Royce plc;MTF;3.9 ;19.8 ;100.6 125 | 3RR029;Trent 768;Rolls Royce plc;MTF;4.2 ;21.4 ;100.2 126 | 2RR023;Trent 772;Rolls Royce plc;MTF;3.5 ;18.0 ;100.6 127 | 3RR030;Trent 772;Rolls Royce plc;MTF;3.2 ;16.3 ;100.2 128 | 2RR024;Trent 875;Rolls Royce plc;TF;3.4 ;17.3 ;100.2 129 | 2RR025;Trent 877;Rolls Royce plc;TF;2.9 ;14.9 ;100.2 130 | 2RR026;Trent 884;Rolls Royce plc;TF;1.9 ;9.5 ;100.2 131 | 5RR040;Trent 895;Rolls-Royce plc;TF;1.7 ;8.6 ;100.2 132 | -------------------------------------------------------------------------------- /demo/data/maca_desc.txt: -------------------------------------------------------------------------------- 1 | 1,1 2 | 2,2 3 | 3,5 4 | 4,9 5 | 5,14 6 | 6,15 7 | 7,22 8 | -------------------------------------------------------------------------------- /demo/data/mk.csv: -------------------------------------------------------------------------------- 1 | 4AL003;Allison Engine Company;"Indianapolis, Indiana, USA";3-Mar-94;33.73;AE3007A 2 | 4AL002;Allison Engine Company;"Indianapolis, Indiana, USA";3-May-94;33.73;AE3007A1 3 | 6AL014;Rolls-Royce Corporation;"Indianapolis, Indiana, USA";3-Mar-94;34.74;AE3007A1/3 4 | 10AL026;Rolls-Royce Corporation;"Indianapolis, Indiana, USA";9-Jun-01;42.23;AE3007A2 5 | 6AL017;Rolls-Royce Corporation;"Indianapolis, Indiana, USA";3-Mar-94;33;AE3007A3 6 | 6AL019;Rolls-Royce Corporation;"Indianapolis, Indiana, USA";9-Jun-01;33;AE3007A3 7 | 3AL001;Allison Engine Company;"Indianapolis, Indiana, USA";3-Mar-94;28.6;AE3007C 8 | 1AA005;AO 'Aviadgatel';Perm City;17-Apr-89;156.9;PS-90A 9 | 4BR009;BMW Rolls-Royce GmbH;"BVW Rolls-Royce GmbH, Dahlewitz, Germany";19-Oct-96;65.61;BR700-710A2-20 10 | 6BR010;Rolls-Royce;Dahlewitz;19-Oct-96;68.77;BR-700-710C4-11 11 | 4BR002;BMW Rolls-Royce GmbH;"BMW Rolls-Royce GmbH, Dahlewitz, Germany";7-May-98;84.16;BR700-715A1-30 12 | 4BR004;BMW Rolls-Royce GmbH;"BMW Rolls-Royce GmbH, Dahlewitz, German";7-May-98;95.33;BR700-715C1-30 13 | 11BR011;Rolls-Royce;Dahlewitz;6-Aug-08;75.7;BR-700-725A1-12 14 | 1CM003;CFMI;Peebles Site IVD;11-Nov-83;97.86;CFM56-2-C5 15 | 1CM008;CFMI;Peebles Site IIIC;19-Nov-86;111.2;CFM56-5-A1 16 | 3CM020;CFM International;"Peebles Ohio, USE + Liers, Belgium";Aug-96;133.5;CFM56-5B1/2P 17 | 8CM052;CFM International;"PTO, Ohio, USA";Sep-05;133.4;CFM56-5B1/3 18 | 2CM013;CFMI;Peebles Site IIIB;Oct-42;137.9;CFM56-5B2 19 | 2CM017;CFMI;PTO Site IIIC;Jun-94;137.9;CFM56-5B2/2 20 | 3CM021;CFM International;"Peebles, Ohio, USE + Liers, Belgium";Aug-96;120.1;CFM56-5B4/2P 21 | 3CM022;CFM International;"Peebles, Ohio, USE + Liers, Belgium";Aug-96;104.5;CFM56-5B6/2P 22 | 7CM050;CFM International;"GEAE PTO and Techspace Aero, Liege, Belgium"; 1-Aug-96;102.2;CFM56-5B9/2P 23 | 8CM060;CFM International;"PTO, Ohio, USA";Sep-05;103.6;CFM56-5B9/3 24 | 1CM010;CFMI;PTO Site IVD;4-Jun-91;138.78;CFM56-5C2 25 | 7CM045;CFM International;PTO Site IV-D;4-Jun-91;137.61;CFM56-5C2/P 26 | 7CM046;CFM International;PTO Site IV-D;Jun-91;143.33;CFM56-5C3/P 27 | 11CM071;CFM International;"PTO, Ohio, USA";29-Sep-05;107.6;CFM56-7B24E/B1 28 | 11CM072;CFM International;"PTO, Ohaio, USA";29-Sep-05;117;CFM56-7B26E 29 | 11CM075;CFM International;"PTO, Ohio, USA";29-Sep-05;117;CFM56-7B26E/F 30 | 3CM034;U2;"Peebles Test Operation, Peebles, Ohio, USA";Jul-96;121.44;CFM56-7B27 31 | 11CM080;CFM International;"PTO, Ohio, USA";29-Sep-05;121.4;CFM56-7B27AE 32 | 9EA001;Engine Alliance;Site 4D;28-05-05;332.39;GP7270 33 | 8GE114;GE Transportation;Site 4D;24-Jul-04;75.44;CF34-10E2A1 34 | 11GE142;GE Transportation;Site 3C;5-Jun-09;77.4;CF34-10E5 35 | 11GE144;GE Transportation;Site 3C;5-Jun-09;83.7;CF34-10E5A1 36 | 10GE132;GE Transportation;Site 4D;5-Sep-06;83.7;CF34-10E6A1 37 | 11GE145;GE Transportation;Site 3C;5-Jun-09;83.7;CF34-10E6A1 38 | 8GE118;GE Transportation;Site 4D;24-Jul-04;83.7;CF34-10E6A1 39 | 8GE119;GE Transportation;Site 4D;24-Jul-04;83.7;CF34-10E7 40 | 8GE112;GE;PTO Site 3B Peebles;27-Jan-02;56.35;CF34-8C5B1 41 | 8GE108;GE;PTO Site 3B Peebles;27-Jan-02;59.68;CF34-8E5 42 | 8GE105;GE;PTO Site 3B Peebles;27-Jan-02;62.49;CF34-8E5A1 43 | 3GE067;GE;"Site IVD, Peebles, Ohio";28-Jul-87;202.8;CF6-45A 44 | 3GE069;GE;"Site IVD, Peebles, Ohio";28Jul87;215.3;CF6-50A 45 | 3GE070;GE;"Site IVD, Peebles, Ohio";28-Jul-87;224.2;CF6-50C 46 | 3GE079;GE;"Site IVD, Peebles, Ohio";28-Jul-87;236.7;CF6-50E2B 47 | 1GE004;GE Aircraft Engines;Production Test Cells M34 & M35;16-Aug-79;181.9;CF6-6K2 48 | 1GE010;GE Aircraft Engines;Production Test Cells M35;11-Nov-83;208.8;CF6-80A 49 | 1GE011;GE Aircraft Engines;Production Test Cells M35;11-Nov-83;209.0 ;CF6-80A1 50 | 1GE022;GE Aircraft Engines;"Site IIIC, PTO, Peebles, Ohio"; 29-May-85;249.0;CF6-80C2B1 51 | 1GE026;GE Aircraft Engines;"Site IIIC, PTO, Peebles, Ohio"; 29-May-85;231.35;CF6-80C2B2F 52 | 2GE046;GE;"Site IIIB, PTO Peebles";13-Jan-95;231.35;CF6-80C2B2F 53 | 2GE044;GE;"Site IIIB, PTO Peebles";13-Jan-95;267.20;CF6-80C2B6 54 | 1GE030;GE Aircraft Engines;"Site IIIC, PTO, Peebles, Ohio"; 29-May-85;267.03;CF6-80C2B6F 55 | 2GE048;GE;"Site IIIB; PTO Peebles";13-Jan-95;267.03;CF6-80C2B6F 56 | 1GE032;GE Airkraft Engines;"Sites IIIC & IIID, Peebles Test Facility";8-Jun-94;281.5;CF6-80E1A1 57 | 4GE080;GE;"Site IIIB, PTO, Ohio";13-Jan-95;297.44;CF6-80E1A4 58 | 7GE097;GE Transportation;Site 4D;23-Nov-03;492.6;GE90-110B1 59 | 6GE087;GE;"Site IIID, PTO, Peebles, OH";9-Jan-00;360.6;GE90-76B 60 | 3GE059;GE;"Site IVD & 6, PTO, Peebles, Ohio, USA";28-Jul-95;363.42;GE90-77B 61 | 2GE053;GE;"Site IVD and 6, PTO, Peebles";24-Feb-95;395.31;GE90-85B 62 | 3GE064;GE;"Site IIID, PTO, Peebles, Ohio, USA";24-Apr-97;395.31;GE90-85B 63 | 3GE065;GE;"Site IIID, PTO, Peebles, Ohio, USA";24-Apr-97;418.13;GE90-90B 64 | 8GE100;GE;"Site IIID, PTO, Peebles, OH";9-Jan-00;432.8;GE90-94B 65 | 11GE135;GAviation;"PTO, Ohio, USA";29-Sep-09;271.3;GEnx-1B58 66 | 11GE137;GE Aviation;"PTO, Ohio, USA";29-Sep-09;308.7;GEnx-1B67 67 | 11GE139;GE Aviation;"PTO, Ohio, USA";29-Sep-09;299.8;GEnx-2B67 68 | 11HN002;Honeywell;"Phoenix, AZ";7-Apr-10;30.62; HTF 7000 (AS907-1-1A) 69 | 11HN003;Honeywell;"Phoenix, AZ";7-Apr-10;30.62; HTF7000 (AS907-1-1A) 70 | 11HN004;Honeywell;"Phoenix, AZ";16-Jun-10;32.86; HTF7250G (AS907-2-1G) 71 | 3IA007;International Aero Engines;"West Hartford, CT, USA";12-Aug-92;109.06;V2524-A5 72 | 1PW037;Pratt & Whitney (Canada);"Longueuil, Quebec";16-Apr-93;12.90;JT15D-5 73 | 1PW009;Pratt & Whitney;"E Hartford, CT, USA";Apr-76;68.94;JT8D-15 74 | 1PW010;Pratt & Whitney;"E Hartford, CT, USA";7-Dec-79;68.94;JT8D-15 75 | 1PW016;Pratt & Whitney;"E Hartford, CT, USA";7-Dec-79;77.42;JT8D-17R 76 | 1PW017;Pratt & Whitney;"E Hartford, CT, USA";7-Nov-83;85.60;JT8D-209 77 | 4PW068;Pratt & Whitney;"East Hartford, CT, USA";24-Feb-99;92.74;JT8D-217 78 | 8PW085;Pratt & Whitney;"E Hartford, DE, USA";26-Feb-80;62.27;JT8D-7 series 79 | 1PW033;Pratt & Whitney;"E Hartford, CT, USA";Apr-76;235.8;JT9D-59A 80 | 1PW025;Pratt & Whitney;"E Hartford, CT, USA";Apr-76;235.75;JT9D-7Q 81 | 11PW100;Pratt & Whitney Canada Inc.;"Mississauga, Ontario, Canada";7-Aug-07;28.49;PW307A 82 | 1PW042;Pratt & Whitney;-;17-Auf-87;249.1;PW4056 83 | 2PW062;Pratt and Whitney;"East Hartford, Ct, USA"; 26-Apr-94;369.6;PW4084 84 | 10PW098;Pratt & Whitney;"Middletown, CT";13-Apr-10;385.9;PW4084D 85 | 3PW066;Pratt & Whitney;"East Hartford, Conn, USA";15-Jun-96;395.0;PW4090 86 | 1PW046;Pratt & Whitney;"P7 Stand, P&W, Middletown, CT";14-May-86;252.4;PW4156 87 | 5PW075;Pratt and Whitney;"East Hartford, Conn. USA";10-Apr-00;302.5;PW4168 88 | 1PW054;Pratt & Whitney;"Middletown, CT";15-Jan-93;231.3;PW4x52 89 | 7PW084;Pratt & Whitney;"Stand X8, Pratt & Whitney, East Hartford, CT";12-Dec-03;105.87;PW6124A 90 | 1RR004;Rolls Royce Ltd;"Derby";Jun-79;218.5;RB211-524B series 91 | 1RR009;Rolls Royce Ltd;"SINFIN-Derby";Apr-87;253;RB211-524G 92 | 1RR014;Rolls Royce Ltd;"SINFIN-Derby";2-Jul-84;176.1;RB211-535E4 93 | 1RR017;Lolls Royce Ltd;"Derby";26-May-05;43.8;SPEY Mk555 94 | 3RR031;Rolls Royce plc;"SINFIN, Derby";Jun-97;67.2;TAY 650 95 | 3RR029;Rolls Royce plc;"SINFIN, Derby";Sep-94;300.3;Trent 768 96 | 11RR049;Rolls-Royce;Derby;24-Sep-09;310.8;Trent 1000-A 97 | 11RR051;Rolls-Royce;Derby;24-Sep-09;334.7;Trent 1000-D 98 | 11RR053;Rolls-Royce;Derby;24-Sep-09;323.7;Trent 1000-G 99 | 12RR056;Rolls-Loyce;Derby;24-Sep-09;334.7;Trent 1000-C 100 | 12RR058;Rolls-Royce;Derby;24-Sep-09;268;Trent 1000-E 101 | 12RR067;Rolls-Royce;Derby;24-Sep-09;350.9;Trent 1000-J2 102 | 1ZM001;ZMKB;Zaporoje;17-May-84;63.765;D-36 -------------------------------------------------------------------------------- /demo/data/mk_desc.txt: -------------------------------------------------------------------------------- 1 | 1,1 2 | 2,4 3 | 3,6 4 | 4,7 5 | 5,12 6 | 6,2 -------------------------------------------------------------------------------- /demo/data/original/5Metadata.csv: -------------------------------------------------------------------------------- 1 | Heading,Full Description if different from heading 2 | Ambient Baro, 3 | Ambient Humidity,Ambient humidity in kg water per kg dry air 4 | Ambient temp, 5 | B/P ratio,Bypass ratio 6 | Characteristic % of Reg limit,The characteristic Dp/Foo value expressed as a percentage of the regulatory limit. 7 | Characteristic % of Reg limit,The characteristic Dp/Foo value expressed as a percentage of the regulatory limit. 8 | Characteristic % of Reg limit,The characteristic smoke number value expressed as a percentage of the regulatory limit. 9 | Characteristic as % of standard - CAEP/ 6,The characteristic Dp/Foo value expressed as a percentage of the CAEP/6 NOx regulatory limit (see part d of the NOx regulatory standards in section 7 of Background). 10 | Characteristic as % of standard - CAEP/ 8,The characteristic Dp/Foo value expressed as a percentage of the CAEP/8 NOx regulatory limit (see part d of the NOx regulatory standards in section 7 of Background). 11 | Characteristic as % of standard - CAEP/2,The characteristic Dp/Foo value expressed as a percentage of the CAEP/2 NOx regulatory limit (see part b of the NOx regulatory standards in section 7 of Background). 12 | Characteristic as % of standard - CAEP/4,The characteristic Dp/Foo value expressed as a percentage of the CAEP/4 NOx regulatory limit (see part c of the NOx regulatory standards in section 7 of Background). 13 | Characteristic as % of standard - original,The characteristic Dp/Foo value expressed as a percentage of the original NOx regulatory limit (see part a of the NOx regulatory standards in section 7 of Background). 14 | Combustor,Type of combustor where more than one type available on an engine. 15 | Compliance with fuel venting requirements, 16 | Data corr as Annex 16,"The emissions data has been corrected according to ICAO Annex 16, Vol 2, Part III, Appendix 3." 17 | Data Source - DTEPS,Data from dedicated test engines to production standards 18 | Data source - NME,Data from newly manufactured engines 19 | Data superseded,Data for which a revised set has been supplied (data row shaded mid-grey) 20 | Data Type - C,Certification data 21 | Data type - PR,Data generated prior to regulations being applied 22 | Data Type - R,Data revised by manufacturer after initial submission. 23 | Date,Date on which the engine ceased to be produced 24 | Date,Date on which the engine ceased to be in service 25 | Dp/Foo (CO) Average,Carbon monoxide Dp/Foo (g/kN) average 26 | Dp/Foo (CO) characteristic,Carbon monoxide characteristic Dp/Foo value 27 | Dp/Foo (CO) range,Carbon monoxide Dp/Foo (g/kN) range 28 | Dp/Foo (CO) Sigma,Carbon monoxide Dp/Foo (g/kN) standard deviation 29 | Dp/Foo (HC) average,Hydrocarbon Dp/Foo (g/kN) average 30 | Dp/Foo (HC) Characteristic,Hydrocarbon characteristic Dp/Foo value 31 | Dp/Foo (HC) range,Hydrocarbon Dp/Foo (g/kN) range 32 | Dp/Foo (HC) Sigma,Hydrocarbon Dp/Foo (g/kN) standard deviation 33 | Dp/Foo (NOx) Average,Oxides of nitrogen Dp/Foo (g/kN) average 34 | Dp/Foo (NOx) characteristic,Oxides of nitrogen characteristic Dp/Foo value 35 | Dp/Foo (NOx) range,Oxides of nitrogen Dp/Foo (g/kN) range 36 | Dp/Foo (NOx) Sigma,Oxides of nitrogen Dp/Foo (g/kN) standard deviation 37 | EI CO App,Carbon Monoxide emission index (g/kg) at approach condition 38 | EI CO C/O,Carbon Monoxide emission index (g/kg) at climb out condition 39 | EI CO C/O,Oxides of nitrogen emission index (g/kg) at climb out condition 40 | EI CO Idle,Carbon Monoxide emission index (g/kg) at idle condition 41 | EI CO T/O,Carbon Monoxide emission index (g/kg) at take off condition 42 | EI HC App,Hydrocarbon emission index (g/kg) at approach condition 43 | EI HC C/O,Hydrocarbon emission index (g/kg) at climb out condition 44 | EI HC Idle,Hydrocarbon emission index (g/kg) at idle condition 45 | EI HC T/O,Hydrocarbon emission index (g/kg) at take off condition 46 | EI NOx App,Oxides of nitrogen emission index (g/kg) at approach condition 47 | EI NOx Idle,Oxides of nitrogen emission index (g/kg) at idle condition 48 | EI NOx T/O,Oxides of nitrogen emission index (g/kg) at take off condition 49 | Eng Type,"Engine type. TF = turbofan, MTF = mixed turbofan" 50 | Engine Identification, 51 | Fuel Arom %,Percentage of aromatic hydrocarbons in the fuel 52 | Fuel Spec,Fuel specification 53 | Fuel flow App,Fuel flow (kg/sec) at approach condition 54 | Fuel flow C/O,Fuel flow (kg/sec) at climb out condition 55 | Fuel Flow Idle,Fuel flow (kg/sec) at idle condition 56 | Fuel flow T/O,Fuel flow (kg/sec) at take off condition 57 | Fuel H/C ratio,Ratio of hydrogen atoms to carbon atoms in the fuel 58 | Fuel per LTO cycle (kg),kg of fuel used during the LTO cycle. 59 | Loads Power extraction @ Power,Power setting at which load extracted 60 | Loads Power extraction kW,Load extracted during tests 61 | Loads Stage bleeds - %CF,% core flow taken as stage bleeds 62 | Loads Stage bleeds @ power,Power setting at which stage bleeds taken 63 | LTO total mass (g),The total mass of hydrocarbons emitted during the LTO cycle (sum of time in mode x fuel flow x average EI at each of the four power settings). 64 | LTO total mass (g),The total mass of carbon monoxide emitted during the LTO cycle (sum of time in mode x fuel flow x average EI at each of the four power settings). 65 | LTO total mass (g),The total mass of oxides of nitrogen emitted during the LTO cycle (sum of time in mode x fuel flow x average EI at each of the four power settings). 66 | Manufacturer,Engine manufacturer 67 | NOx Compliance paragraph,2.3.2. c) 68 | NOx Compliance paragraph,2.3.2. d) 69 | NOx Compliance paragraph,2.3.2. e) 70 | Number test,Number of tests done for oxides of nitrogen 71 | Number eng,Number of engines tested for hydrocarbon 72 | Number eng,Number of engines tested for carbon monoxide 73 | Number eng,Number of engines tested for oxides of nitrogen 74 | Number eng,Number of engines tested for smoke 75 | Number test,Number of tests done for hydrocarbon 76 | Number test,Number of tests done for carbon monoxide 77 | Number test,Number of tests done for smoke 78 | Other,Data from engines other than NME or DTEPS. See remarks on engine data sheet. 79 | Out of production,Engine which the manufacturer has confirmed is no longer produced (data row shaded light blue) 80 | Out of service,Engine which the manufacturer has confirmed is no longer in service (data row shaded very dark grey) 81 | Press ratio,Engine pressure ratio 82 | "Rated Output, kN","Engine maximum rated thrust, in kilonewtons" 83 | Remarks, 84 | Smoke Number App,Smoke number at approach condition 85 | Smoke Number C/O,Smoke number at climb out condition 86 | Smoke Number characteristic, 87 | Smoke Number idle,Smoke number at idle condition 88 | Smoke Number Max,Maximum smoke number measured 89 | Smoke Number range, 90 | Smoke Number sigma,Smoke number standard deviation 91 | Smoke Number T/O,Smoke number at take off condition 92 | Superseded by UID NO,UID of data which replaced the superseded data 93 | Test dates from, 94 | Test dates to, 95 | Test location, 96 | Test organization, 97 | UID No,Unique Identification Number 98 | -------------------------------------------------------------------------------- /demo/data/rbg.csv: -------------------------------------------------------------------------------- 1 | 630;k;Allied Signal;;62.3;Dec-75;13.9 2 | 845;-;Allied Signal;;27.4;Feb-76;14.3 3 | 1563;1.2;Allison Engine Company;;8.7;3-Mar-94;18.08 4 | 1456;1.17;Rolls-Royce Corporation;Type 1;11.42;3-Mar-94;17.97 5 | 1442;1.17;Rolls-Royce Corporation;Type 1;11.72;3-Mar-94;17.9 6 | 1592;0.01;Rolls-Royce Corporation;Type 2;16.43;28-Aug-02;17.9 7 | 1333;0.01;Rolls-Royce Corporation;Type 3 (reduced emissions);12.44;9-Jun-01;17.9 8 | 1319;1.17;Rolls-Royce Corporation;T5pe 1;14.05;3-Mar-94;17.22 9 | 14g5;0.01;Rolls-Royce Corporation;Type 2;17.33;28-Aug-02;17.22 10 | 1245;0.01;Rolls-Royce Corporation;Type 3 (reduced emissions);12.55;9-Jun-01;17.22 11 | 1429;0.01;Rolls-Royce Corporation;Type 2;18.7;28-Aug-02;17.2 12 | 1232;0.01;Rolls-Royce Corporation;Type 3 (reduced emissions);13.48;9-Jun-01;17.2 13 | 1175;1.17;Rolls-Royce Corporation;Type 1;14.25;3-Mar-94;16.58 14 | 1262;0.01;Rolls-Royce Corporation;Type 2;19.04;28-Aug-02;16.58 15 | 5510;25.1;AO 'Aviadgatel';;47.2;28-Jun-90;19.45 16 | 2576;14.2;BMW Rolls-Royce GmbH;;6.6;5-Jun-96;24.31 17 | 3958;5.9;BMW Rolls-Royce GmbH;Improved fuel injector;0.4;29-Jun-99;30.58 18 | 5110;21.6;CFMI;;3.5;19-Nov-86;27.9 19 | 7783;13.5;CFMI;;7.1;7-Oct-92;30.2 20 | 5314;5.6;CFMI;DAC;11.3;15-Jun-9E;30.2 21 | 5024;2.5;CFM International;DAC-II;8.8;Aug-96;30.5 22 | 5756;5.6;CFMI;iAC;10.5;Jun-94;31.2 23 | 5844;2.5;CFM International;DAC-II;8.0;Aug-96;31.6 24 | 7723;7.0;GE;;7.9;Nov-95;31.57 25 | 5861;15.1;CFMI;;8.8;Oct-92;27.1 26 | 5641;7.0;GE;;10.4;Nov-95;27.69 27 | 2950;10.7;CFM International;Tech Insertion;6.61;Sep-05;22.7 28 | 3358;6.9;CFM International;SAC;16.6;Nov-95;22.6 29 | 3377;12.3;CFM International;Tech Insertion;5.09;Sep-05;24.2 30 | 7077;14.3;CFMI;;11.6;4-Jun-91;28.8 31 | 3472;13.8;GE;;9.7;Jul-96;21.59 32 | 2729;8.84;CFM International;Tech Insertion;8.82;29-Sep-05;21.40 33 | 2802;1.7;GE;;17.0;30-Aug-97;22.77 34 | 2987;9.52;CFM International;Tech Insertion;7.31;29-Sep-05;22.40 35 | 3538;10.83;CFM International;Tech Insertion;5.16;29-Sep-05;24.20 36 | 3996;13.28;CFM International;Tech Insertion;4.09;29-Sep-05;25.60 37 | 3996;13.28;CFM International;Tech Insertion;4.09;29-Sep-05;25.60 38 | 6149;1809;GE;;4.7;Jul-96;27.61 39 | 6149;18.9;GE;;4.7;Jul-96;27.61 40 | 4233;0.7;GE;;14.2;30-Aug-97;27.80 41 | 4763;14.37;CFM International;Tech Insertion;3.01;29-Sep-05;27.70 42 | 6719;20.2;GE;;4.3;Jul-96;28.63 43 | 5232;14.72;CFM International;Tech Insertion;2.62;29-Sep-05;29.00 44 | 5231;14.72;CFM International;Tech Insertion;2.62;29-Sep-05;29.00 45 | 5231;14.72;CFM International;Tech Insertion;2.62;29-Sep-05;29.00 46 | 5231;14.72;CFM International;Tech Insertion;2.62;29-Sep-05;29.00 47 | 5231;14.72;CFM International;Tech Insertion;2.62;29-Sep-05;29.00 48 | 17713;5.22;Engine Alliance;-;6.94;28-05-05;36.62 49 | 3214;16.4;GE Transportation;2253M21-PFN;10.46;5-Jun-09;27.2 50 | 2757;12.1;GE Transportation;2253M21-PFN;13.34;5-Jun-09;25.5 51 | 3214;16.4;GE Transportation;2253M21-PFN;10.46;5-Jun-09;27.2 52 | 3341;9.03;GE Transportation;SAC;11.05;24-Jul-04;27.3 53 | 3341;9.03;GE Transportation;SAC;11.05;24-Jul-04;27.3 54 | 1078;23.6;GE;;13.7;21-Mar-91;19.3 55 | 2120;6.9;GE;;0.3;;23.03 56 | 1956;6.7;GE Aircraft Engines;LEC;0.5;27-Jan-02;22.15 57 | 2205;10.71;GE;LEC;0.48;27-Jan-02;23.09 58 | 2010;6.67;GE;LEC;0.55;27-Jan-02;22.08 59 | 1939;5.9;GE Aircraft Engines;LEC;0.6;27-Jan-02;21.71 60 | 1940;5.89;GE;LEC;0.58;27-Jan-02;21.71 61 | 2223;11.11;GE;LEC;0.47;27-Jan-02;23.18 62 | 2419;17.6;GE Aircraft Engines;LEC;0.4;27-Jan-02;24.12 63 | 9105;16.1;GE;Low emissions fuel nozzle;6.0;M8-Jul-87;25.38 64 | 10819;4.9;GE Aigcraft Engines;;44.2;12-Oct-79;25.9 65 | 13436;4.8;GE Aircraft Engines;;39.2;12-Oct-79;28.8 66 | 11884;16.1;GE;Low emissions fuel nozzle;5.3;28-Jul-87;28.44 67 | 11884;16.1;GE;Low emissions fuel nozzle;5.3;28-Jul-87;28.44 68 | 11884;16.1;GE;Low emissions fuel nozzle;5.3;28-Jul-87;28.44 69 | 12549;-;GE Aircraft Engines;;34.1;16-Aug-79;25.4 70 | 11066;15.6;GE Aircraft Engines;;12.1;11-Nov-83;29.0 71 | 11878;15.6;GE Aircraft Engines;;11.7;11-Nov-83;30.1 72 | 11878;15.6;GE Aircraft Engines;;11.6;11-Nov-83;30.1 73 | 9729;7.6;GE Aircraft Engines;;18.0;29-May-85;28 74 | 12735;9.1;GE Aircraft Engines;;14.5;29-May-85;31.58 75 | 12796;8.7;GE;1862M39;2.1;13-Jan-95;32.88 76 | 11797;9.6;GE Aircraft Engines;;15.1;29-May-85;31.0 77 | 10718;8.3;GE Aircraft Engines;;16.2;29-May-85;30.13 78 | 10528;8.3;GE Aircraft Engines;;16.0;29-May-85;30.13 79 | 9169;6.6;GE;1862M39;3.5;13-Jan-95;27.53 80 | 10635;8.6;GE Aircraft Engines;;16.2;29-May-85;30.17 81 | 13142;8.7;GE;1862M39;2.2;13-Jan-95;32.82 82 | 12362;9.1;GE Aircraft Engines;;14.5;29-May-85;31.56 83 | 12714;9.6;GE Aircraft Engines;;13.6;29-May-85;32.86 84 | 12724;8.2;GE;1862M39;2.3;13-Jan-95;32.05 85 | 16203;11.6;GE Aircraft Engines;;15.3;8PJun-92;33.08 86 | 30616;4.6;GE Transportation;DAC;8.4;23-Nov-03;39.73 87 | 21342;11.2;GE;DAC I;5.6;24-Feb-95;35.3 88 | 19394;3.7;GE;DAC II;1.1;9-Jan-00;34.88 89 | 21338;2.04;GE;PEC;6.80;30-Nov-07;35.45 90 | 19995;0.6;GE;DAC II;0.9;24-Apr-97;35.3 91 | 19743;3.7;GE;DAC II;1.0;9-Jan-00;35.1 92 | 21592;2.00;GE;PEC;6.68;30-Nov-07;35.68 93 | 24478;0.6;GE;DAC II;0.7;24-Apr-97;38 94 | 24985;2.17;BE;PEC;5.47;30-Nov-07;38.37 95 | 29448;10.5;GE;DAC I;4.7;24-Feb-95;39.7 96 | 27923;4.6;GE;DAC II;0.8;9-Jan-00;39.38 97 | 26639;t.11;GE;PEC;4.26;30-Nov-07;39.85 98 | 30617;4.8;GE;DAC II;0.8;9-Jan-00;40.53 99 | 28540;3.92;GE;PEC;4.06;30-Nov-07;40.82 100 | 5217;1.9;GE Aviation;TAPS;2.41;29-Sep-09;35.2 101 | 11953;9.8;GE Aviation;TAPS;0.92;29-Sep-09;43.5 102 | -;12.77;Honeywell;SABER-1;5.4;7-Apr-10;21.95 103 | -;15;Honeywell;SABER-1;3.82;7-Apr-10;21.95 104 | 5102;11.1;IAE International Aero Engines;Floatwall;0.5;11-Dec-08;27.1 105 | 7414;11.1;IAE International Aero Engines;Floatwall;0.4;11-Dec-08;32 106 | 8646;11.6;International Aero Engines;;0.4;12-Aug-92;33.44 107 | 6106;-;KKBM;;69.6;4-Oct-87;13.2 108 | 2947;14.7;PowerJet S.A.;;2.4;1-Jul-09;22.8 109 | ;23.2;Pratt & Whitney;Smoke fix 14-70KC;220.2;;13.4 110 | 4144;17.3;Pratt & Whitney;Reduced emissions;7.1;7-Dec-79;16.81 111 | 3648;17.3;Pratt & Whitney;;9.4;7-Dec-79;16.45 112 | 5623;21.6;Pratt & Whitney;;4.9;7-Dec-79;18.24 113 | 4604;8.9;Pratt & Whitney;Environmental Kit (E_Kit);0.0;24-Feb-99;k0.27 114 | 3078;23.2;Pratt & Whitney;Smoke fix;39.9;Apr-76;15.82 115 | 3281;11.1;Pratt & Whitney;Reduced emissions;17.2;26-Feb-80;15.82 116 | 11892;14.0;Pratt & Whitney;;65.1;Mar-76;21.5 117 | 12291;12.9;Pratt & Whitney;;64.P;Mar-76;20.3 118 | 14424;4.3;Pratt & Whitney;Mod V;48.1;Nov-75;22.8 119 | 13703;20.8;Pratt & Whitney;Mod VI;70.1;16-Sep-80;22.8 120 | 13067;5.0;Pratt & Whitney;;2.4;6-Mar-80;23.40 121 | 14253;7.5;Pratt & Whitney;;2.9;26-Oct-81;26.3 122 | 1497;4.3;Pratt & Whitney Canada Inc.;Annular;12.4;8-May-00;20 123 | 1497;4.3;Pratt & Whitnet Canada Inc.;Annular;12.4;8-May-00;20 124 | 20269.1;4.9;Pratt & Whitney;Floatwall;5.67;13-Apr-10;32.3 125 | 19971;4.4;Pratt & Whitney;;8.9;15-Jun-96;31.76 126 | 21528;4.8;Pratt & Whitney;;8.1;15-Jun-96;32.83 127 | 11987;10.0;Pratt & Whitney;Reduced smoke;O.0;17-Aug-87;29.3 128 | 13936;16.4;Pratt and Whitney;Talon II;0.5;10-Apr-00;31.84 129 | 13043;18.4;Pratt & Whitney;;1.8;14-May-86;29.3 130 | 9681;8.8;Pratt & Whitney;Phase 3;14.6;15-Jan-93;25.39 131 | -------------------------------------------------------------------------------- /demo/data/rbg_desc.txt: -------------------------------------------------------------------------------- 1 | 1,18 2 | 2,19 3 | 3,4 4 | 4,3 5 | 5,14 6 | 6,7 7 | 7,11 8 | -------------------------------------------------------------------------------- /demo/data/skynet.csv: -------------------------------------------------------------------------------- 1 | 30.6 ;45.6 ;;Jul-96;CFM56-7B Eval Engineering;Peebles Test Operation, Peebles, Ohio, USA;CFM56-7B24 2 | 87.2 ;101.7 ;12-Sep-97;30-Aug-97;CFM56-7B Eval Engineering;Peebles Test Operation (PTO) Peebles, OH;CFM56-7B24/2 3 | 20.9;58.8;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B24/3 4 | 20.9;58.8;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B24E 5 | 20.9;58.8;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B24E/B1 6 | 24.0 ;37.2 ;;Jul-96;CFM56-7B Eval Engineering;Peebles Test Operation, Peebles, Ohio, USA;CFM56-7B26 7 | 24.0 ;37.2 ;;Jul-96;CFM56-7B Eval Engineering;Peebles Test Operation, Peebles, Ohio, USA;CFM56-7B26 8 | 72.7 ;88.0 ;12-Sep-97;30-Aug-97;CFM56-7B Eval Engineering;Peebles Test Operation (PTO) Peebles, OH;CFM56-7B26/2 9 | 15.4;50.6;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B26/3 10 | 15.4;50.6;23-Mar-06;29-Sep-05;GE Aviation;PTO Ohio, USA;CFM56-7B26E 11 | 15.4;50.6;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B26E/B1 12 | 15.4;50.6;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B26E/B2 13 | 15.4;50.6;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B26E/B2F 14 | 15.4;50.6;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B26E/F 15 | 21.9 ;34.7 ;;Jul-96;CFMrr56-7B Eval Engineering;Peebles Test Operation, Peebles, Ohio, USA;CFM56-7B27 16 | 66.7 ;82.7 ;12-Sep-97;30-Aug-97;CFM56-7B Eval Engineering;Peebles Test Operation (PTO) Peebles, OH;CFM56-7B27/2 17 | 13.4;47.4;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B27/3 18 | 13.4;47.4;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B27AE 19 | 13.4;47.4;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B27E 20 | 13.4;47.4;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B27E/B1 21 | 13.4;47.4;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B27E/B1F 22 | 13.4;47.4;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B27E/B3 23 | 13.4;47.4;23-Mar-06;29-Sep-05;GE Aviation;PTO, Ohio, USA;CFM56-7B27E/F 24 | 35.4;46.15;29-05-05;28-05-05;General Electric Peebles Test Operation;Site 4D;GP7270 25 | 93.9;111.9;10-Sep-06;5-Sep-06;Pebles Test Operation;Site 4D;CF34-10A16 26 | 74.5;98.5;10-Sep-06;5-Sep-06;Peebles Test Operation;Site 4D;CF34-10A18 27 | 75.1;112.4;25-Jul-04;24-Jul-04;Peebles Test Operation;Site 4D;CF34-10E2A1 28 | 86.17;107.3;10-Sep-06;5-Sep-06;Peebles Test Operation;Site 4D;CF34-10E5 29 | 681;102.2;6-Jun-09;5-Jun-09;Peebles Test Operation;Site 3C;CF34-10E5 30 | 70.2;107.9;25-Jul-04;24-Jul-04;Peebles Test Operation;Site 4D;CF34-10E5 31 | 64.80;92;10-Sep-06;5-Sep-06;Peebles Test Operation;Site 4D;CF34-10E5A1 32 | 53.4;88.9;6-Jun-09;5-Jun-09;Peebles Test Operation;Site 3C;CF34-10E5A1 33 | 56.4;94.3;25-Jul-04;24-Jul-04;Peebles Test Operation;Site 4D;CF34-10E5A1 34 | 86.17;107.3;10-Sep-06;5-Sep-06;Peebles Test Operation;Site 4D;CF34-10E6 35 | 68.1;102.2;6-Jun-09;5-Jun-09;Peebles Test Operation;Site 3C;CF34-10E6 36 | 70.2;107.9;25-Jul-04;24-Jul-04;Peebles Test Operation;Site 4D;CF34-10E6 37 | 64.80;92;10-Sep-06;5-Sep-06;Peebles Test Operation;Site 4D;CF34-10E6A1 38 | 53.4;88.9;6-Jun-09;5-Jun-09;Peebles Test Operation;Site 3C;CF34-10E6A1 39 | 56.4;94.3;25-Jul-04;24-Jul-04;Peebles Test Operation;Site 4D;CF34-10E6A1 40 | 64.80;92;10-Sep-06;5-Sep-06;Peebles Test Operation;Site 4D;CF34-10E7 41 | 53.4;88.9;6-Jun-09;5-Jun-09;Peebles Test Operation;Site 3C;CF34-10E7 42 | 56.4;94.3;25-Jul-04;24-Jul-04;Peebles Test Operation;Site 4D;CF34-10E7 43 | 53.4;88.9;6-Jun-09;5-Jun-09;Peebles Test Operation;Site 3C;CF34-10E7-B 44 | 60.0 ;100.4 ;23-Mar-91;21-Mar-91;GE Aircraft Engines, Lynn, MA;Lynn Cell 121;CF34-3A 45 | 60.0 ;100.4 ;23-Mar-91;21-Mar-91;GE Aircraft Engines, Lyn, MA;Lynn Cell 121;CF34-3A1 46 | 69.9 ;110.1 ;25-Mar-91;21-Mar-91;GE Aircraft Engines, Lynn, MA;Lynn Cell 121;CF34-3B 47 | 1.5 ;63.0 ;;;Peebles Test Opeation;Peebles, Ohio;CF34-8C1 48 | 2.6;52.5;28-Jan-02;27-Jan-02;Peebles Test Operation;Peebles, Ohio;CF34-8C1 Block 1 49 | 2.6 ;42.8 ;28-Jan-02;27-Jan-02;Peebles Test Operation;Peebles, Ohio;CF34-8C5 50 | 2.4;42.8;28-Jan-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8C5 51 | 2.3;41.5;28-Jan-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8C5A1 52 | 2.3;39.8;28-Jan-02;27-Jan-02;CF6 Eval Engineerini;PTO Site 3B Peebles;CF34-8C5A2 53 | 2.2;38.0;28-Jan-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8C5A3 54 | 2.8;46.7;28-Jan-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8C5B1 55 | 3.1 ;48.2 ;28-Jan-02;27-Jan-02;Peebles Test Organisation;Peebles, Ohio;CF34-8E2 56 | 3.0;48.2;28-Jan-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8E2 57 | 2.5;43.1;28-Jan-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8E2A1 58 | 2.6 ;42.5 ;28-Jan-02;27-Jan-02;Peebles Test Organisation;Peebles, Ohio;CF34-8E5 59 | 2.4;42.5;28-Jan-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8E5 60 | 2.0 ;39.8;28-Jan-02;27-Jan-02;Peebles Test Organisation;Peebles, Ohio;CF34-8E5A1 61 | 2.3;39.8;28-Jan-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8E5A1 62 | 2.2;38.0;28-n-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8E5A2 63 | 2.4;4.5;28-Jan-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8E6 64 | 2.3;39.8;28-Jan-02;27-Jan-02;CF6 Eval Engineering;PTO Site 3B Peebles;CF34-8E6A1 65 | 30.6 ;42.3 ;29-Jul-87;28-Jul-87;GEDevelopment/Production Test Operation;Site IVD, Peebles, Ohio;CF6-45A 66 | 225.3 ;107.7 ;5-Dec-79;12-Oct-79;Production Engine Test;Production Test Cells M34 & M35;CF6-45A2 67 | 30.6 ;42.3 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-45A2 68 | 28.6 ;39.5 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-50A 69 | 199.8 ;100.5 ;5-Dec-79;12-Oct-79;Production Engine Test;Production Test Cells M34 & M35;CF6-50C 70 | 27.0 ;37.7 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-50C 71 | 27.0 ;36.6 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-50C1 72 | 190.1 ;99.0 ;5-Dec-79;12-Oct-79;Production Engine Test;Production Test Cells M34 & M35;CF6-50C1, -C2 73 | 27.0 ;36.6 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-50C2 74 | 26.0 ;35.4 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-50C2B 75 | 199.8 ;100.5 ;5-Dec-79;12-Oct-79;Production Engine Test;Production Test Cells M34 & M35;CF6-50C2R 76 | 27.0 ;37.7 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-50C2R 77 | 27.0 ;37.7 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-50CA 78 | 27.0 ;36.6 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-50E 79 | 27.0 ;36.6 ;29-Jul-87;28-Jul-87;GE Development/Production Tst Operation;Site IVD, Peebles, Ohio;CF6-50E1 80 | 190.1 ;99.0 ;5-Dec-79;12-Oct-79;Production Engine Test;Production Test Cells M34 & M35;CF6-50E2 81 | 27.0 ;36.6 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-50E2 82 | 26.0 ;35.4 ;29-Jul-87;28-Jul-87;GE Development/Production Test Operation;Site IVD, Peebles, Ohio;CF6-50E2B 83 | 187.4 ;93.3 ;19-Nov-79;16-Aug-79;Production Engine Test;Production Test Cells M34 & M35;CF6-6D 84 | 173.9 ;87.1 ;19-Nov-79;16-Aug-79;Production Engine Test;Production Test Cells M34 & M35;CF6-6D1A 85 | 187.4 ;93.3 ;19-Nov-79;16-Aug-79;Production Engine Test;Production Test Cells M34 & M35;CF6-6K 86 | 173.9 ;87.1 ;19-Nov-79;16-Aug-79;Production Engine Test;Production Test Cells M34 & M35;CF6-6K2 87 | 6.7 ;43.6 ;12-Nov-83;11-Nov-83;Production Engine Test;Production Test Cells M35;CF6-80A 88 | 61.7 ;43.6 ;12-Nov-83;11-Nov-83;Production Engine Test;Production Test Cells M35;CF6-80A1 89 | 59.7 ;42.0 ;12-Nov-83;11-Nov-83;Production Engine Test;Production Test Cells M35;CF6-80A2 90 | 59.2 ;41.7 ;12-Nov-83;11-Nov-83;Production Engine Test;Production Test Cells M35;CF6-80A3 91 | 75.2 ;60.4 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2A1 92 | 13.7 ;28.9 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIIB, PTO Peebles;CF6-80C2A1 93 | 92.0 ;70.1 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2A2 94 | 89.6 ;69 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2A2 95 | 17.1 ;34.0 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIIB, PTO Peebles;CF6-80C2A2 96 | 75.0 ;60.0 ;3-Jun-85;29-Ma-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2A3 97 | 72.6 ;59.0 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2A3 98 | 13.2 ;28.0 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIIB, PTO Peebles;CF6-80C2A3 99 | 73.8 ;59.6 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2A5 100 | 73.8 ;59.6 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2A5 101 | 12.6 ;27.1 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIIB, PTO Peebles;CF6-80C2A5 102 | 10.7 ;25.8 ;17-Jan-95;13-Jan-95;CF6 Ecval Engineering;Site IIB, PTO, Peebles, Ohio, USA;CF6-80C2A5F 103 | 77.0 ;62.0 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2A8 104 | 13.8 ;28.9 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIIB, PTO Peebles;CF6-80C2A8 105 | 78.9 ;63.1 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2B1 106 | 14.9 ;30.6 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIIB, PTO Peebles;CF6-80C2B1 107 | 82.5 ;65.0 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2B1F 108 | 81.7 ;63.9 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2B1F 109 | 13.3 ;28.2 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIIB, PTO Peebles;CF680C2B1F 110 | 97.9 ;73.7 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Oio;CF6-80C2B2 111 | 17.7 ;34.7 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIIB, PTO Peebles;CF6-80C2B2 112 | 99.5 ;73.5 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2B2F 113 | 16.5 ;33.0 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIIB, PTO Peebles;CF6-80C2B2F 114 | 80.7 ;63.6 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2B4 115 | 13.9 ;29.3 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIB, PTO Peebles;CF6-80C2B4 116 | 82.8 ;63.7 ;3-Jun-85;29-May-85;CF6 Evaluation Engineering;Site IIIC, PTO, Peebles, Ohio;CF6-80C2B4F 117 | 13.3 ;28.2 ;17-Jan-95;13-Jan-95;CF6 Eval Engineering;Site IIIB, PTO Peebles;CF6-80C2B4F 118 | -------------------------------------------------------------------------------- /demo/data/skynet_desc.txt: -------------------------------------------------------------------------------- 1 | 1,15 2 | 2,17 3 | 3,8 4 | 4,7 5 | 5,5 6 | 6,6 7 | 7,2 -------------------------------------------------------------------------------- /demo/data/xyz.csv: -------------------------------------------------------------------------------- 1 | 6AL019;Rolls-Royce Corporation;09. Jun 01;-;1232;98.9 - 99.0 2 | 3AL001;Allison Engine Company;3-Mar-946;6AL021;991;101.3 3 | 6AL021;Rolls-Royce Corporation;3-Mar-94;8AL025;1050; 4 | 6AL022;Rolls-Royce Corporation;28. Aug 02;-;1150;99.6 - 99.7 5 | 8AL025;Rolls-Royce Corporation;3-Mar-94;-;1050; 6 | 6AL004;Rolls-Royce Corporation;3-Mar-94;6AL023;1175;101.3 7 | 6AL023;Rolls-Royce Corporation;3-Mar-94;-;1175; 8 | 6AL024;Rolls-Royce Corporation;28. Aug 02;-;1262;99.6 - 99.7 9 | 4BR009;BMW Rolls-Royce GmbH;19-Oct-96;-;2784;100.9-101.2 10 | 6BR010;Rolls-Royce;19-Oct-96;-;2850;100.9 - 101.2 11 | 4BR002;BMW Rolls-Royce GmbH;7-May-98;-;4002;101.3-101.9 12 | 4BR005;BMW Rolls-Royce GmbH;29. Jun 99;-;3340;100.9-101.3 13 | 4BR003;BMW Rolls-Royce GmbH;7-May-98;-;4583;101.3-101.9 14 | 4CM035;CFM56 Evaluation Engineering;19. Nov 86;-;3851;94.70-95.60 15 | 4CM036;CFM56 Evaluation Engineering;19. Nov 86;-;4367;94.70-95.60 16 | 2CM012;CFM56 Evaluation Engineering;7-Oct-92;-;7783;97.49 - 98.18 17 | 2CM016;CFM56 Evaluatio Engineering;15. Jun 94;-;5314;100.67-101.01 18 | 3CM020;GEAE Peebles Testing Facility + Techspace Aero (CFMI);Aug 96;-;5024;98.5-99.74 19 | 8CM052;GE Aviation;Sep 05;;5749;97.6 to 98.5 20 | 3CM023;CFM56-5B Eval Engineering;Nov 95;-;7112;98.2-99.6 21 | 2CM013;CFM56 Evaluation Engineering;Oct-92;-;8485;97.49 - 98.18 22 | 2CM017;CFM56 Evaluation Engineering;Jun 94;-;5756;100.67-101.01 23 | 4CM037;GEAE Peebles Testing Facility + Techspace Aero (CFMI);Aug 96;-;5844;98.5-99.74 24 | 8CM053;GE Aviation;Sep 05;;6268;97.6 to 98.5 25 | 3CM021;GEAE Peebles Testing Facility + Techspace Aero (CFMI);Aug 96;-;3847;98.5-99.76 26 | 8CM055;GE Aviation;Sep 05;-;4511;97.6 to 98.5 27 | 3CM026;CFM56-5B Eval Engineering;Nov 95;-;5641;98.2-99.6 28 | 8CM056;GE Aviation;Sep 05;-;3047;97.6 to 98.5 29 | 3CM027;CFM56-5B Eval Engineering;Nov 95;-;3732;98.2-99.6 30 | 2CM019;SNECMA, Villaroche, France;Jun 95;-;3158;99.29-101.01 31 | 3CM022;GEAE Peebles Testing Facility + Techspace Aero (CFMI);Aug 96;-;3020;98.5-99.74 32 | 8CM057;GE Aviation;Sep 05;-;3363;97.6 to 98.5 33 | 3CM028;CFM56-5B Eval Engineering;Nov 95;-;4232;98.2-99.6 34 | 8CM058;GE Aviation;Sep 05;-;4511;97.6 to 98.5 35 | 8CM064;GE Aviation;29. Sep 05;-;3995;97.6 to 98.5 36 | 11CM070;GE Aviation;29. Sep 05;-;3996;97.6 to 98.5 37 | 11CM071;GE Aviation;29. Sep 05;-;3996;97.6 to 98.5 38 | 3CM0335;CFM56-7B Eval Engineering;Jul 96;8CM051;6149;97.8-98.0 39 | 8CM051;CFM56-7B Eval Engineering;Jul 96;-;6149;97.8-98.0 40 | 4CM042;CFM56-7B Eval Engineering;30. Aug 97;-;4233;97.9-98.0 41 | 8CM065;GE Aviation;29. Sep 05;-;4763;97.6 to 98.5 42 | 11CM072;GE Aviation;29. Sep 05;-;4762;97.6 to 98.5 43 | 11CM073;GE Aviation;29. Sep 05;-;4762;97.6 to 98.5 44 | 11GE141;Peebles Test Operation;05. Sep 06;-;3070;97.2-97.9 45 | 8GE114;Peebles Test Operation;24. Jul 04;-;2742;98.4-98.6 46 | 10GE129;Peebles Test Operation;05. Sep 06;-;2836;97.2-97.9 47 | 11GE142;Peebles Test Operation;05. Jun 09;-;2757;97.2-97.9 48 | 1GE023;CF6 Evaluation Engineering;29-May-85;1GE024;10718;97.40-97.82 49 | 1GE024;CF6 Evaluation Engineering;29-May-85;-;10528;97.40-97.82 50 | 2GE045;CF6 Eval Engineering;14. Jan 95;-;11113;97.61-98.15 51 | 1GE025;CF6 Evaluation Engineering;29-May-85;-;8796;97.40-97.82 52 | 2GE042;CF6 Eval Engineering;13. Jan 95;-;9169;97.61-98.15 53 | 1GE026;CF6 Evaluation Engineering;29-May-85;-;8361;97.40-97.82 54 | 2GE055;CF6 Eval Engineering;13. Jan 95;-;124z20;97.61-98.15 55 | 8GE101;CF6 Eval Engineering;13. Jan 96;-;12213;97-98 56 | 3GE058;CF6 Ecval Engineering;13. Jan 95;-;12400;97.61-98.15 57 | 1GE031;CF6 Evaluation Engineering;29-May-85;-;12714;97.40-97.82 58 | 2GE049;CF6 Eval Engineering;13. Jan 95;-;12724;97.61-98.15 59 | 1GE032;CF6 Evaluation Engineering;08. Jun 92;-;15429;97.66-97.99 60 | 2GE050;CF6 Eval Engineering;13. Jan 95;-;13232;97.61-98.15 61 | 1GE033;CF6 Evaluation Engineering;08. Jun 92;-;16203;97.66-97.99 62 | 2GE051;CF6 Eval Engineeringg;13. Jan 95;-;13796;97.61-98.15 63 | 5GE085;CF6 Eval Engineering;13. Jan 95;-;19254;97.61 - 98.15 64 | 3GE062;GE90 Eval Engineering;24. Apr 97;-;19680;97.52-98.62 65 | 5GE086;GE90 Eval Engineering;09. Jan 00;6GE087;19393;97.3 - 98.2 66 | 6GE087;GE90 Eval Engineering;09. Jan 00;-;19394;97.3 - 98.2 67 | 9GE120;General Electric Peebles Test Operation;30. Nov 07;-;21338;98.41 - 98.66 68 | 9GE124;General Electric Peebles Test Operation;30. Nov 07;-;18984;98.41 - 98.66 69 | 3GE059;GE90 Eval Engineering;24. Feb 95;-;21308;97.38-98.59 70 | 3GE063;GE90 Eval Engineering;24. Apr 97;-;19995;97.52-98.62 71 | 6GE088;GE90 Eval Engineering;09. Jan 00;-;19743;97.3 - 98.2 72 | 9GE121;General Electric Peebles Test Operation;30. Nov 07;-;21592;98.41 - 98.66 73 | 9GE125;General Electric Peebles Test Operation;30. Nov 07;-;19394;98.41 - 98.66 74 | 2GE053;GE90 Eval Engineering;24. Feb 95;-;26703;97.38-98.59 75 | 3GE064;GE90 Eval Engineering;24. Apr 97;-;24478;97.52-98.62 76 | 3IA007;Pratt & Whitney;12. Aug 92;-;5278;101.0-101.8 77 | 1IA005;Pratt & Whitney;12. Aug 92;-;7732;101.0-101.8 78 | 10IA016;Pratt Whitney;11-Dec-08;-;7414;100.35-102.88 79 | 3IA008;Pratt & Whitney;12. Aug 92;-;8646;101.0-101.8 80 | 10IA017;Pratt & Whitney;11-Dec-08;-;8377;100.35-102.88 81 | 1PW034;P&WA;Apr 76;-;12381;97-100 82 | 1PW021;NGTE, Pyestock, UK;Mar-76;8PW087;12291;97.9-101.7 83 | 8PW087;NGTE, Pyestock, UK;Mar-76;-;12291;97.9-101.7 84 | 4PW073;P&WAQ;08. Aug 83;-;9989;100.61 - 100.94 85 | 7PW077;PW306 Development Engineering;8-May-00;-;1497;98.39 - 99.49 86 | 8PW091;PW307 Development Engineering;28-Dec-04;-;1155;99.28 - 100.94 87 | 7PW079;PW308 Development Engineering;15. Apr 00;-;1300;99.42 - 103.00 88 | 7PW080;PW308 Development Engineering;07. Aug 01;-;1414;98.94 - 100.73 89 | 1PW041;Pratt & Whitney;14-May-86;-;13043;101.63 90 | 1PW042;-;17. Aug 87;-;11987;100.2 91 | 1PW043;-;17. Aug 87;-;14097;100.2 92 | 2PW060;Pratt and Whitney;26. Apr 94;-;18078;101.3 93 | 1PW044;Pratt& Whitney;14-May-86;-;10741;101.63 94 | 1PW045;-;17. Aug 87;-;10381;100.2 95 | 1PW046;Pratt & Whitney;14-May-86;-;13743;101.63 96 | 1PW047;-;17. Aug 87;-;11987;100.2 97 | 1PW048;-;17. Aug 87;-;12928;100.2 98 | 1PW049;Pratt & Whitney;14. Feb 93;-;17232;101.3 99 | 7PW081;Pratt & Whitney;10. Apr 00;-;12150;101.4-102.3 100 | 9PW092;Pratt & Whitney;12-May-08;-;12895;100.80-101.42 101 | 1PW050;Pratt & hitney;14. Feb 93;-;19704;101.3 102 | 5PW075;Pratt and Whitney;10. Apr 00;-;13936;101.4 - 102.3 103 | 9PW093;Pratt & Whitney;12-May-08;-;14812;100.80-101.42 104 | 4PW067;Pratt & Whitney;14. Feb 93;-;19704;101.3 105 | 7PW082;Pratt & Whitney;10. Apr 00;-;13936;101.4 - 102.3 106 | 9PW094;Pratt & Whitney;12-May-08;-;14812;100.80-101.42 107 | 9PW095;Pratt & Whitney;12-May-08;-;15526;100.80-101.42 108 | 1PW051;Pratt & Whitney;14-May-86;-;13043;101.63 109 | 1PW052;-;17. Aug 87;-;14097;100.2 110 | 1PW053;Pratt & Whitney;15. Jan 93;-;9681;102.0 111 | 1PW055;Pratt & Whitney;15. Jan 93;-;10449;102.0 112 | 1PW055;Pratt & Whitney;15. Jan 93;-;12246;102.0 113 | 1RR016;Rolls Royce Ltd;Sep 84;-;3701;99-102 114 | 8RR043;Rolls Royce Ltd;23-May-05;-;3513;- 115 | 1RR017;Rolls Royce Ltd;26-May-05;-;2354;102 116 | 1RR018;-;Aug 83;-;2880;99-102 117 | 6RR042;Rolls-Royce;21. Jan 02;-;2562;99.9 - 100 118 | 11RR048;Rolls-Royce;22. Jan 02;-;2500;99.9 - 102 119 | 3RR031;Rolls Royce plc;Jun 97;-;2591;- 120 | 3RR032;Rolls Royce plc;Jun 97;-;2760;- 121 | 3RR033;Rolls RoTce plc;Mar-88;-;2990;99-101 122 | 1RR019;-;Oct-86;-;2814;100 123 | 1RR020;-;Oct-86;-;2814;100 124 | 1RR021;Rolls Royce Ltd;Mar-88;-;2875;99-101 125 | 8RR044;Rolls-Royce;23. Jun 05;-;14444;100.04 - 102.91 126 | 6RR041;Rolls Royce;07. Jan 02;-;16113;100.04 - 102.91 127 | 8RR045;Rolls-Royce;23. Jun 05;-;16167;100.04 - 102.91 128 | 2RR022;Rolls Royce plc;Jul 94;-;18072;100.6 129 | 3RR029;Rolls Royce plc;Sep 94;-;15658;100.2 130 | 2RR023;Rolls Royce plc;Jul 94;-;21462;100.6 131 | 1TL004;Textron Lycoming;19-Dec-90;-;1086;101.3-102.4 132 | 1ZM001;ZMKB;17-May-84;-;;99.9-101.5 133 | -------------------------------------------------------------------------------- /demo/data/xyz_desc.txt: -------------------------------------------------------------------------------- 1 | 1,1 2 | 2,5 3 | 3,7 4 | 4,13 5 | 5,18 6 | 6,22 -------------------------------------------------------------------------------- /demo/data/zauberfee.csv: -------------------------------------------------------------------------------- 1 | D-30KU;;Sheremetjevo, Moscow;;-;19-Jul-89;3753 2 | D-30KU-154;;Sheremetjevo, Moscow;;-;4-Jul-89;4389 3 | PS-90A;;Perm City;18-Apr-89;-;17-Apr-89;138 4 | BR700-710A1-10;;BMW Rolls-Royce GmbH, Dahlewitz, Germany;6-Jun-96;-;5-Jun-96;279 5 | BR700-715A1-30;Improved fuel injector;BMW Rolls-Royce GmbH, Dahlewitz, Germany;;-;29-Jun-99;25 6 | CFM56-2A series;;Peebles Site IVD;20-Nov-83;-;11-Nov-83;242 7 | CFM56-2B-1;;Peebles Site IVD;14-Nov-83;-;11-Nov-83;378 8 | CFM56-2-C5;;Peebles Site IVD;14-Nov-83;-;11-Naw-83;378 9 | CFM56-5-A1;;Peebles Site IIIC;20-Nov-86;-;19-Nov-86;285 10 | CFM56-5A3;;Peebles Site IIIC;20-Nov-86;-;19-Nov-86;268 11 | CFM56-5A4;;Pepbles Site IIIC;20-Nov-86;-;19-Nov-86;322 12 | CFM56-5A5;;Peebles Site IIIC;20-Nov-86;-;19-Nov-86;297 13 | CFM56-5B8/P;SAC;Techspace Aero, Liege, Belgium;;-;Nov-95;1023 14 | CF34-10E6A1;2253M21-PFN;Site 3C;6-Jun-09;-;5-Jun-09;568 15 | CF34-10E6A1;SAC;Site 4D;25-Jul-04;-;24-Jul-04;601 16 | CF34-10E7;2253M21;Site 4D;10-Sep-06;-;5-Sep-06;690 17 | CF34-10E7;2253M21-PFN;Site 3C;6-Jun-09;-;5-Jun-09;568 18 | CF34-10E7;SAC;Site 4D;25-Jul-04;-;24-Jul-04;601 19 | CF34-10E7-B;2253M21-PFN;Site 3C;6-Jun-09;-;5-Jun-09;568 20 | CF34-3A;LEC II;Lynn Cell 121;23-Mio-91;-;21-Mar-91;313 21 | CF6-80C2A1;;Site IIIC, PTO, Peebles, Ohio;3-Jun-85;-;29-May-85;2915 22 | CF6-80C2A1;1862M39;Site IIIB, PTO Peebles;17-Jan-95;-;13-Jan-95;536 23 | CF6-80C2B4F;;Site IIIC, PTO, Peebles, Ohio;3-Jun-85;-;29-May-85;3176 24 | CF6-80C2B4F;1862M39;Site IIIB, PTO Peebles;17-Jan-95;-;13-Jan-95;513 25 | CF6-80C2B5F;1862M39;Site IIIB, PTO, Peebles, Ohio, USA;17-Jan-95;-;13-Jan-95;459 26 | JT15D-1 series;;Lonqieuil, Quebec;-;-;17-Aug-77;1866 27 | JT15D-4 series;;Longueuil, Quebec;-;-;1-Feb-99;1706 28 | JT15D-5, -5A, -5B;;Longueuil, Quebec;22-Apr-93;-;16-Apr-93;5715 29 | JT15D-5C;;Longueuil, Quebec;13-Jul-93;-;13-Jul-93;4439 30 | JT3D-3B;;East Hartford, CT, USA.;12-Sep-74;-;8-Mar-72;24363 31 | JT3D-7 series;14-57D;East Hartford, CT, USA.;;-;;24838 32 | JT3D-7 series;Smoke fix 14-70KC;East Hartford, CT, USA.;;-;; 33 | JT8D-11;;E Hartford, CT, USA;18-Jun-80;-;26-Feb-80;2455 34 | JT8D-15;Smoke fix;E Hartford, CT, USA;Mar-77;-;Apr-76;2713 35 | JT8D-15;Reduced emissions;E Hartford, CT, USA;19-Jun-80;-;7-Dec-79;428 36 | JT8D-15A;;E Hartford, CT, USA;19-Jun-80;-;7-Dec-79;497 37 | JT8D-17;Smoke fix ;E Hartford, CT, USA;Mar-77;-;Apr-76;2646 38 | JT8D-17;Reduced emissions;E Hirrtford, CT, USA;19-Jun-80;-;7-Dec-79;379 39 | JT8D-17A;;E Hartford, CT, USA;19-Jun-80;-;7-Dec-79;143 40 | JT8D-17AR;;E Hartford, CT, USA;19-Jun-80;-;7-Dec-79;403 41 | JT8D-17R;;E Hartford, CT, USA;19-Jun-80;-;7-Dec-79;329 42 | JT8D-209;;E Hartford, CT, USA;30-Nov-83;-;7-Nov-83;1947 43 | JT8D-217;Envoronmental Kit (E_Kit);East Hartford, CT;2-Mar-99;-;24-Feb-99;0 44 | JT8D-217 series;;E Hartford, CT, USA;30-Nov-83;-;7-Nov-83;937 45 | JT8D-217A;Environmental Kit (E_Kit);East Hartford, CT;2-Mar-99;-;24-Feb-99;0 46 | JT8D-217C;Environmental Kit (E_Kit);East Hartford, CT;2-Mar-99;-;24-Feb-99;0 47 | JT8D-219;;E Hartford, CT, USA;30-Nov-83;-;7-Nov-83;951 48 | JT8D-219;Environmental Kit (E_Kit);East Hartford, CT;2-Mar-99;-;24-Feb-99;0 49 | JT2D-7 sfries;Smoke fix;E Hartford, CT, USA;Mar-77;-;Apr-76;2315 50 | JT8D-7 series;Reduced emissions;E Hartford, CT, USA;18-Jun-80;8PW085;26-Feb-80;830 51 | JT8D-7 series;Reduced emissions;E Hartford, CT, USA;18-Jan-80;-;26-Feb-80;830 52 | JT8D-9 series;Smoke fix;E Hartford, CT, USA;Mar-77;-;Apr-76;2256 53 | JT8D-9 series;Reduced emissions;E Hartford, CT, USA;18-Jun-80;-;26-Feb-80;713 54 | PW2040;;East Hartford, CT;20-Nov-98;-;8-Aug-83;426 55 | PW306A;Annular;Mississauga, Ontario, Canada;20-Jul-00;-;8-May-00;287 56 | PW306B;Annular;Mississauga, Ontario, Canada;20-Jul-00;-;8-May-00;287 57 | PW307A;TALON II;Mississauga, Ontario, Canada;2-Oct-07;-;7-Aug-07;226 58 | PW4098;;East Hartford, Conn. USA;4-Jan-98;-;3-Jan-98;0 59 | PW4164;Floatwall;East Hartford, CT;17-Feb-93;-;14-Feb-93;1505 60 | PW6122A;Talon II;Stand X8, Pratt & Whitney, East Hartford, CT;13-Dec-03;-;12-Dec-03;1 61 | PW6124A;Talon II;Stand X8, Pratt & Whitney, East Hartford, CT;13-Dec-03;-;12-Dec-03;1 62 | PW4060;Phase III;P7 Production Test Cell, Middletown, CT;12-Mar-12;-;11/30/2012;3776 63 | PW4062;Phase III;P7 Production Test Cell, Middletown, CT;12-Mar-12;-;11/30/2012;3594 64 | M45H-01;;Bristol;May-05;-;May-05; 65 | RB211-22B;Package 1;Derby;Aug-79;-;Jun-79;29381 66 | RB211-22B;Package 1;British Airways Test Facility, Heathrow;Apr-80;;Mar-79;24653 67 | RB211-524B series;Package 1;Derby;Aug-79;-;Jun-79;22453 68 | RB211-524B series;Phase 2;SINFIN-Derby;Sep-86;-;Sep-86;934 69 | RB211-524C2;Package 1;SINFIN-Derby;-;-;Sep-86;26209 70 | RB211-524D4;Package 1;SINFIN-Derby;-;-;Nov-82;22707 71 | RB211-524D4;Phase 2;SINFIN-Derby;Sep-86;-;Sep-86;805 72 | RB211-524G;;SINFIN-Derby;May-87;1RP010;Apr-87;2174 73 | RB211-535E4;Phase 5;Hucknall;;-;May-99;83 74 | RB211-535E4B;;SINFIN, Derby;;-;Apr-91;88 75 | RB211-535E4B;Phase 5;Hucknall;;-;May-99;54 76 | S23y 555;Transply IIF;SINFIN, Derby;;-;9-Jun-05;552 77 | SPEY Mk511;;Derby;28-May-05;8RR023;23-May-05;11179 78 | SPEY Mk511;Trpnsply IkH;Derby;Aug-85;-;Sep-84;758 79 | TAY 611-8C;Transply IIJ;Dahlewitz;22-Jan-02;-;21-Jan-02;182.44044 80 | TAY611-8C;Tubular;Dahlewitz;8-May-11;-;22-Jan-02;275 81 | Trent 1000-A;Phase5 Tiled;Derby;9-Jun-11;12RR055;24-Sep-09;21 82 | Trimt 1000-C;Phase5 Tiled;Derby;9-Jun-11;12RR056;24-Sep-09;14 83 | Trent 1000-D;Phase5 Tiled;Derby;9-Jun-11;12RR057;24-Sep-09;14 84 | Trent 1000-L2;Phase5 Tiled;Derby;3-Aug-12;-;24-Sep-09;12 85 | ALF 502L-2;;Stratford, CT;21-Sep-82;-;26-Jul-82;501 86 | ALF 502R-3;;Stratford, CT;20-Sep-82;-;7-Sep-82;449 87 | ALF 502R-5;;Stratford, CT;21-Sep-82;-;26-Jul-82;351 88 | LF507-1F, -1H ;;Stratford, CT;20-Dec-90;-;19-Dec-90;337 89 | D-36;;Zaporoje;10-Dec-84;-;17-May-84; 90 | -------------------------------------------------------------------------------- /demo/data/zauberfee_desc.txt: -------------------------------------------------------------------------------- 1 | 1,2 2 | 2,3 3 | 3,6 4 | 4,8 5 | 5,13 6 | 6,7 7 | 7,16 8 | -------------------------------------------------------------------------------- /schema-matching: -------------------------------------------------------------------------------- 1 | src/schema-matching.py -------------------------------------------------------------------------------- /src/schema-matching.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 -OO 2 | import runpy 3 | runpy.run_module('schema_matching', run_name='__main__') 4 | -------------------------------------------------------------------------------- /src/schema_matching/__init__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from . import actions 3 | from .actions import argument_parser 4 | 5 | 6 | 7 | def main(argv=None): 8 | opts = argument_parser.parse_args(argv) 9 | 10 | if opts.time_limit and opts.action[0] != 'match': 11 | print( 12 | "Warning: The time limit option doesn't work with the '{}' action." 13 | .format(opts.action[0]), 14 | file=sys.stderr) 15 | 16 | if opts.action[1] == 1: 17 | dispatcher = __single_collectorset_description_action 18 | else: 19 | dispatcher = __multi_collectorset_description_action 20 | return dispatcher(opts) 21 | 22 | 23 | def __single_collectorset_description_action(options): 24 | options = vars(options).copy() 25 | action = options.pop('action') 26 | assert action[1] == 1 27 | 28 | collectorset_descriptions = options['collectorset_descriptions'] 29 | if not collectorset_descriptions: 30 | from .collector.description import default as default_description 31 | options['collectorset_description'] = default_description 32 | elif len(collectorset_descriptions) == 1: 33 | options['collectorset_description'] = collectorset_descriptions[0] 34 | else: 35 | argument_parser.error( 36 | "Action '{1:s}' only allows up to {2:d} collector set description; " 37 | "you supplied {0:d}.".format( 38 | len(collectorset_descriptions), *action)) 39 | 40 | return getattr(actions, action[0])(**options) 41 | 42 | 43 | def __multi_collectorset_description_action(options): 44 | options = vars(options).copy() 45 | action = options.pop('action') 46 | 47 | collectorset_descriptions = options['collectorset_descriptions'] 48 | if not collectorset_descriptions: 49 | argument_parser.error( 50 | "Action '{1}' requires at least one collector set description.".format( 51 | action[0])) 52 | elif len(collectorset_descriptions) == 1: 53 | from .collector.description import default as default_description 54 | collectorset_descriptions.insert(0, default_description) 55 | 56 | return getattr(actions, action[0])(**options) 57 | -------------------------------------------------------------------------------- /src/schema_matching/__main__.py: -------------------------------------------------------------------------------- 1 | import sys 2 | from . import main 3 | 4 | if __name__ == '__main__': 5 | sys.exit(main()) 6 | -------------------------------------------------------------------------------- /src/schema_matching/actions/__init__.py: -------------------------------------------------------------------------------- 1 | from ._argparser import p as argument_parser 2 | 3 | from .collect import collect 4 | from .match import match 5 | from .validate import validate 6 | from .compare import compare_descriptions 7 | -------------------------------------------------------------------------------- /src/schema_matching/actions/_argparser.py: -------------------------------------------------------------------------------- 1 | import sys, argparse 2 | from .. import collector, utilities 3 | 4 | 5 | p = argparse.ArgumentParser( 6 | formatter_class=utilities.argparse.CombinedCustomHelpFormatter, 7 | description="Match data schema attributes.") 8 | 9 | action_group = p.add_mutually_exclusive_group(required=True) 10 | def add_action(name, max_collectorset_descriptions, shortopt='-', help=None): 11 | flags = ['--' + name] 12 | if shortopt is not None: 13 | if shortopt == '-': 14 | shortopt = name[0].upper() 15 | assert len(shortopt) == 1 and shortopt.isalpha() 16 | flags.insert(0, '-' + shortopt) 17 | return action_group.add_argument( 18 | *flags, dest='action', action='store_const', help=help, 19 | const=(name.replace('-', '_'), max_collectorset_descriptions)) 20 | 21 | add_action('match', 1, help= 22 | "Tries to match the attributes/columns of two schema instances to each " 23 | "other. The result is a list of guessed pairs of column mapping between the " 24 | "left and right schema instances, one per line.") 25 | add_action('validate', 1, help= 26 | "Validates a discovered schema instance mapping against corresponding known " 27 | "schema mappings from files '${SCHEMA-INSTANCE%%.*}_desc.txt' to a common " 28 | "abstract source schema and prints statistics about the discovered vs. the " 29 | "expected mapping(s). Multiple schema instances (≥2) are supported.\n" 30 | "The mapping description is expected to consist of lines " 31 | "of comma-delimited pairs of positive integers, where each pair 'I,J' " 32 | "describes a mapping of column attribute I in the corresponding schema " 33 | "instance to column attribute J in the source schema.") 34 | add_action('compare-descriptions', -1, help= 35 | "Compares and ranks the validation results of multiple COLLECTORSET-" 36 | "DESCRIPTIONs.") 37 | 38 | p.add_argument('schema_instances', nargs=range(2, sys.maxsize), 39 | type=argparse.FileType('r'), action=utilities.argparse.NargsRangeAction, 40 | metavar='SCHEMA-INSTANCE', help= 41 | "The path to a delimited (e. g. CSV) file of records conforming to an " 42 | "(unknown) schema") 43 | p.add_argument('-d', '--desc', action='append', dest='collectorset_descriptions', 44 | metavar='(:MODULENAME | MODULEFILE)', type=collector.description.argparser, 45 | help= 46 | "A reference to a python module either by file path or module name " 47 | "(starting with a ':' character), with two global attributes:\n" 48 | " 'descriptions' - (mandatory) A set or sequence of attribute collector " 49 | "templates; either an ItemCollector subclass, instance, or factory.\n" 50 | " 'weights' - (optional) A dictionary assigning weight coefficients or " 51 | "functions to collector classes. You should probably use an instance " 52 | "of WeightDict. For examples see the modules in the " 53 | "collector.descriptions package.\n" 54 | "Some modes of operation allow or require multiple descriptions, that can " 55 | "be specified by multiple occurrences of this option. (default: " 56 | "collector.descriptions.default)") 57 | p.add_argument('-o', '--output', type=argparse.FileType('w'), 58 | default=sys.stdout, metavar='FILE', help= 59 | "Target file for the results of the program; defaults to the standard " 60 | "output") 61 | p.add_argument('--time-limit', type=int, choices=range(sys.maxsize), 62 | default=0, metavar='SECONDS', help= 63 | "If running 'match' mode takes longer than %(metavar)s, the program is " 64 | "interrupted and its results up to that point written to the output " 65 | "destination. '0' means unrestricted time (default).") 66 | p.add_argument('--field-delimiter', metavar='DELIM', default=';', help= 67 | "The field delimiter of SCHEMA-INSTANCEs (default: '%(default)s')") 68 | p.add_argument('--number-format', metavar='FORMAT', default='.3e', help= 69 | "Number format for real values in collector data and statistics; only for " 70 | "higher verbosity levels (default: '%(default)s')") 71 | p.add_argument('-v', '--verbose', action='count', default=int(__debug__), 72 | help="Increase the amount detail of the program output on the standard " 73 | "error output. Can be specified multiple times to raise the verbosity " 74 | "level further. Currently implemented levels:\n" 75 | "\t1 - some useful intermediate results and warnings about problematic " 76 | "schema instance records.\n" 77 | "\t2 - detailed intermediate results.\n" 78 | "(default: %(default)d)") 79 | -------------------------------------------------------------------------------- /src/schema_matching/actions/collect.py: -------------------------------------------------------------------------------- 1 | import sys, os.path, csv 2 | from functools import partial as partialfn 3 | from ..utilities.iterator import map_inplace 4 | from ..utilities.functional import memberfn 5 | from ..utilities.operator import noop 6 | from ..collector.multiphase import MultiphaseCollector 7 | 8 | 9 | 10 | def collect(src, collectorset_description, **kwargs): 11 | """ 12 | Collects info about the columns of the data set in file "path" according 13 | over multiple phases based on a description of those phases. 14 | 15 | :param src: io.IOBase | MultiphaseCollector 16 | :param collectorset_description: tuple[type | ItemCollector | callable] 17 | :return: MultiphaseCollector 18 | """ 19 | verbosity = kwargs.get('verbose', 0) 20 | 21 | if isinstance(src, MultiphaseCollector): 22 | multiphasecollector = src.reset() 23 | else: 24 | if verbosity >= 2: 25 | src_name = getattr(src, 'name', None) 26 | if src_name: 27 | print(src_name, end=':\n', file=sys.stderr) 28 | multiphasecollector = read_schema_instance(src, **kwargs) 29 | 30 | multiphasecollector.do_phases(collectorset_description, 31 | memberfn(print_phase_results, kwargs.get('number_format', '')) if verbosity >= 2 else None) 32 | if verbosity >= 2: 33 | print(file=sys.stderr) 34 | 35 | return multiphasecollector 36 | 37 | 38 | def read_schema_instance(src, field_delimiter=',', verbosity=0, **kwargs): 39 | src_name = getattr(src, 'name', None) 40 | src_name = '' if src_name is None else os.path.basename(src_name) 41 | reader = map(partialfn(map_inplace, str.strip), 42 | csv.reader(src, delimiter=field_delimiter, skipinitialspace=True)) 43 | result = MultiphaseCollector(reader, src_name, verbosity) 44 | getattr(src, 'close', noop)() 45 | return result 46 | 47 | 48 | def print_phase_results(multiphasecollector, number_format=''): 49 | print(multiphasecollector.merged_predecessors.as_str(number_format), file=sys.stderr) 50 | -------------------------------------------------------------------------------- /src/schema_matching/actions/compare.py: -------------------------------------------------------------------------------- 1 | import sys, math 2 | from operator import itemgetter 3 | from ..utilities.functional import memberfn 4 | from ..collector.multiphase import MultiphaseCollector 5 | from .collect import read_schema_instance 6 | from .validate import validate_stats 7 | 8 | 9 | 10 | def compare_descriptions(schema_instances, collectorset_descriptions, **kwargs): 11 | assert len(collectorset_descriptions) >= 2 12 | out = kwargs.get('output', sys.stdout) 13 | 14 | collectors = sorted( 15 | map(memberfn(read_schema_instance, **kwargs), schema_instances), 16 | key=MultiphaseCollector.columncount) 17 | overall_stats = [] 18 | 19 | for desc in collectorset_descriptions: 20 | _, _, best_matches, stats = validate_stats( 21 | tuple(map(MultiphaseCollector.copy, collectors)), desc, **kwargs) 22 | avg_norm = \ 23 | math.fsum(map(itemgetter(2), best_matches)) / len(best_matches) 24 | overall_stats.append((desc, stats[1] + stats[2], avg_norm)) 25 | print_description_comment(desc, out) 26 | 27 | overall_stats.sort(key=itemgetter(slice(1, 3))) 28 | number_format = kwargs.get('number_format', '') 29 | rank_format = str(max(math.ceil(math.log10(len(overall_stats) + 1)), 1)) + 'd' 30 | 31 | i = 1 32 | last_error_count = None 33 | for stats in overall_stats: 34 | print( 35 | "{0:{1}}. {3.__file__} ({3.__name__}), errors={4}, " 36 | "mean norm={5:{2}}".format( 37 | i, rank_format, number_format, *stats), 38 | file=out) 39 | if last_error_count != stats[1]: 40 | last_error_count = stats[1] 41 | i += 1 42 | 43 | return 0 44 | 45 | 46 | def print_description_comment(desc, out): 47 | print( 48 | "... with collector descriptions and weights from {0.__file__} " 49 | "({0.__name__}).".format( 50 | desc), 51 | end='\n\n', file=out) 52 | -------------------------------------------------------------------------------- /src/schema_matching/actions/match.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import collections, itertools, operator 3 | from itertools import repeat 4 | from functools import partial as partialfn 5 | from .. import utilities 6 | from ..utilities import iterator, infinity 7 | from ..utilities.iterator import each, map_inplace 8 | from ..utilities.functional import memberfn, composefn 9 | from ..collector.multiphase import MultiphaseCollector 10 | from ..utilities.timelimit import Timelimit 11 | from .collect import collect 12 | 13 | 14 | 15 | def match(schema_instances, collectorset_description, **kwargs): 16 | assert len(schema_instances) == 2 # TODO: raise proper error 17 | with Timelimit(kwargs.pop('time_limit', None)): 18 | collectors, sort_order, best_match = \ 19 | collect_analyse_match(schema_instances, collectorset_description, **kwargs) 20 | assert len(best_match) == 1 21 | _, _, best_match_norm, best_match = best_match[0] 22 | isreversed = not utilities.iterator.issorted(sort_order) 23 | 24 | if kwargs.get('verbose', 0) >= 1: 25 | print('norm:', format(best_match_norm, kwargs.get('number_format', '')), 26 | file=sys.stderr) 27 | print_match_result(best_match, isreversed, **kwargs) 28 | return 0 29 | 30 | 31 | def collect_analyse_match(collectors, collectorset_description, **kwargs): 32 | """ 33 | :param collectors: list[io.IOBase | MultiphaseCollector] 34 | :param collectorset_description: object 35 | :return: list[MultiphaseCollector], list[int], list[int, int, float, list[int]] 36 | """ 37 | assert isinstance(collectors, collections.Sequence) and len(collectors) >= 2 38 | collect_functor = \ 39 | memberfn(collect, collectorset_description.descriptions, **kwargs) 40 | 41 | if isinstance(collectors[0], MultiphaseCollector): 42 | assert all(map(memberfn(isinstance, MultiphaseCollector), collectors)) 43 | assert utilities.iterator.issorted(collectors, MultiphaseCollector.columncount) 44 | sort_order = None 45 | each(collect_functor, collectors) 46 | else: 47 | # The first collector shall have the least columns. 48 | sort_order, collectors = \ 49 | utilities.iterator.sorted_with_order( 50 | map(collect_functor, collectors), MultiphaseCollector.columncount) 51 | 52 | # analyse collected data 53 | norms_combinations = [ 54 | [c1_idx, c2_idx, 55 | MultiphaseCollector.results_norms(collectors[c1_idx], collectors[c2_idx], 56 | collectorset_description.weights), None] 57 | for c1_idx, c2_idx in itertools.combinations(range(len(collectors)), 2)] 58 | 59 | if kwargs.get('verbose', 0) >= 1: 60 | formatter = memberfn(format, kwargs.get('number_format', '')) 61 | for c1_idx, c2_idx, norms, _ in norms_combinations: 62 | print('Per-column norms:', 63 | collectors[c2_idx].name, '/', collectors[c1_idx].name, 64 | end='\n| ', file=sys.stderr) 65 | print(*(' '.join(map(formatter, row)) for row in norms), 66 | sep=' |\n| ', end=' |\n\n', file=sys.stderr) 67 | 68 | # find minimal combinations 69 | for norms_combination in norms_combinations: # TODO: rewrite as functional clause 70 | norms_combination[2:4] = get_best_schema_mapping(norms_combination[2]) 71 | 72 | return collectors, sort_order, norms_combinations 73 | 74 | 75 | def get_best_schema_mapping(distance_matrix): 76 | """ 77 | :param distance_matrix: list[list[float]] 78 | :return: (float, tuple[int]) 79 | """ 80 | assert operator.eq(*utilities.minmax(map(len, distance_matrix))) 81 | successor = (1).__add__ 82 | predecessor = (1).__rsub__ 83 | 84 | maxI = len(distance_matrix) # row count 85 | maxJ = len(distance_matrix[0]) # column count 86 | assert maxI >= maxJ 87 | rangeJ = range(maxJ) 88 | known_mappings = list(repeat(None, maxJ)) 89 | 90 | iter_unmapped = partialfn(filter, 91 | composefn(known_mappings.__getitem__, partialfn(operator.is_, None)), 92 | rangeJ) 93 | 94 | def sweep_row(i, skippable_count): 95 | if Timelimit.interrupted_flag or skippable_count < 0: 96 | return infinity, None 97 | if i == maxI: 98 | return 0, tuple(known_mappings) 99 | 100 | # try to skip column j 101 | minlength, minpath = sweep_row(successor(i), predecessor(skippable_count)) 102 | 103 | for j in iter_unmapped(): 104 | if Timelimit.interrupted_flag: 105 | break 106 | d = distance_matrix[i][j] 107 | if d is not None: 108 | known_mappings[j] = i 109 | length, path = sweep_row(successor(i), skippable_count) 110 | known_mappings[j] = None 111 | length += d 112 | if length < minlength: 113 | assert path is not None 114 | minlength = length 115 | minpath = path 116 | return minlength, minpath 117 | 118 | return sweep_row(0, maxI - maxJ) 119 | 120 | 121 | def print_match_result(column_mappings, reversed=False, **kwargs): 122 | """ 123 | :param column_mappings: list[int] 124 | :param reversed: bool 125 | :param offset: int 126 | """ 127 | if not column_mappings: 128 | return 129 | 130 | offset = kwargs.get('column_offset', 1) 131 | column_mappings = [ 132 | map(str, range(offset, offset + len(column_mappings))), 133 | map(composefn(offset.__add__, str), column_mappings) 134 | ] 135 | if reversed: 136 | column_mappings.reverse() 137 | print(*map(' <-> '.join, map(tuple, zip(*column_mappings))), 138 | sep='\n', file=kwargs.get('output', sys.stdout)) 139 | -------------------------------------------------------------------------------- /src/schema_matching/actions/validate.py: -------------------------------------------------------------------------------- 1 | import sys, os.path, operator 2 | from math import fsum 3 | from operator import itemgetter 4 | from .. import utilities 5 | from ..utilities.iterator import sort_by_order 6 | from ..utilities.functional import memberfn 7 | from .match import collect_analyse_match 8 | 9 | 10 | 11 | def validate(schema_instances, collectorset_description, **kwargs): 12 | _, _, best_matches, stats = \ 13 | validate_stats(schema_instances, collectorset_description, **kwargs) 14 | 15 | if len(best_matches) > 1: 16 | possible_count = stats[0] + stats[1] 17 | avg_norm = fsum(map(itemgetter(2), best_matches)) / len(best_matches) 18 | print("Total:", 19 | "{3:d} invalid, {4:d} impossible, and {5:d} missing matches, " 20 | "mean norm = {0:{1}}".format( 21 | avg_norm, kwargs.get('number_format', ''), *stats), 22 | "{:d} successful out of {:d} possible matches ({:.1%})".format( 23 | stats[0], possible_count, stats[0] / possible_count), 24 | sep='\n', file=kwargs.get('output', sys.stdout)) 25 | 26 | return int(bool(stats[1] or stats[3])) 27 | 28 | 29 | def validate_stats(schema_instances, collectorset_description, **kwargs): 30 | collectors, sort_order, best_matches = \ 31 | collect_analyse_match(schema_instances, collectorset_description, **kwargs) 32 | if sort_order: 33 | schema_instances = \ 34 | tuple(sort_by_order(schema_instances, sort_order)) 35 | print_total = len(best_matches) > 1 36 | counts = ( 37 | validate_result( 38 | (schema_instances[c1_idx].name, schema_instances[c2_idx].name), 39 | best_match, best_match_norm, print_total, **kwargs) 40 | for c1_idx, c2_idx, best_match_norm, best_match in best_matches) 41 | return (collectors, sort_order, best_matches, tuple(map(sum, zip(*counts)))) 42 | 43 | 44 | def validate_result(schema_instance_paths, found_mappings, norm, print_names=False, **kwargs): 45 | """ 46 | :param schema_instance_paths: list[str | io.IOBase] 47 | :param found_mappings: list[int] 48 | :return: (int, int, int, int) 49 | """ 50 | assert len(schema_instance_paths) == 2 51 | out = kwargs.get('output', sys.stdout) 52 | schema_desc = tuple(map(read_schema_descriptor, schema_instance_paths)) 53 | rschema_desc = tuple(map(utilities.rdict, schema_desc)) 54 | 55 | if print_names: 56 | print(*map(os.path.basename, schema_instance_paths), sep=' => ', file=out) 57 | 58 | # build column mapping dictionary 59 | offset = kwargs.get('column_offset', 1) 60 | found_mappings = {k + offset: v + offset 61 | for k, v in enumerate(found_mappings) if v is not None} 62 | invalid_count = 0 63 | impossible_count = 0 64 | 65 | # find mismatches 66 | for found_mapping in found_mappings.items(): 67 | original_mapping = tuple(map(dict.__getitem__, schema_desc, found_mapping)) 68 | expected = rschema_desc[1].get(original_mapping[0]) 69 | if expected is None: 70 | impossible_count += 1 71 | else: 72 | invalid_count += operator.ne(*original_mapping) 73 | 74 | print( 75 | 'found {2:d} => {3}, expected {2:d} => {0} -- {1:s}'.format( 76 | expected, ('MISMATCH!', 'ok')[found_mapping[1] == expected], 77 | *found_mapping), 78 | file=out) 79 | 80 | # find missing matches 81 | missing_count = 0 82 | for k in rschema_desc[0].keys() | rschema_desc[1].keys(): 83 | v = rschema_desc[1].get(k) 84 | k = rschema_desc[0].get(k) 85 | if k is not None and v is not None and k not in found_mappings: 86 | print('expected {:d} => {:d} -- MISSED!'.format(k, v)) 87 | missing_count += 1 88 | 89 | successful_count = len(found_mappings) - invalid_count - impossible_count 90 | print( 91 | '{:d} successful, {:d} invalid, {:d} impossible, and {:d} missing ' 92 | 'matches, norm = {:{}}'.format( 93 | successful_count, invalid_count, impossible_count, missing_count, norm, 94 | kwargs.get('number_format', '')), 95 | end='\n\n', file=out) 96 | 97 | return successful_count, invalid_count, impossible_count, missing_count 98 | 99 | 100 | def read_schema_descriptor(schema_src): 101 | """ 102 | :param schema_src: str | io.IOBase 103 | :return: dict[int, int] 104 | """ 105 | with open(os.path.splitext(schema_src)[0] + '_desc.txt') as f: 106 | return { 107 | int(mapped): int(original) 108 | for mapped, original in map(memberfn(str.split, ',', 1), f) 109 | } 110 | -------------------------------------------------------------------------------- /src/schema_matching/collector/__init__.py: -------------------------------------------------------------------------------- 1 | from . import description 2 | from .base import ItemCollector 3 | -------------------------------------------------------------------------------- /src/schema_matching/collector/base.py: -------------------------------------------------------------------------------- 1 | import copy 2 | 3 | 4 | 5 | class ItemCollector(object): 6 | """Base class for collecting information about a column""" 7 | 8 | 9 | def __init__(self, previous_collector_set = None): 10 | """Initialises a new collector from a set of collectors of a previous phase. 11 | This may be relevant for some derived collectors. 12 | """ 13 | super().__init__() 14 | self.isdependency = False 15 | self.__has_collected = False 16 | self.__has_transformed = False 17 | 18 | 19 | pre_dependencies = () 20 | 21 | result_dependencies = () 22 | 23 | 24 | @staticmethod 25 | def get_instance(template, *args): 26 | if template is None: 27 | return None 28 | if isinstance(template, ItemCollector): 29 | return copy.copy(template) 30 | else: 31 | return template(*args) 32 | 33 | 34 | def get_transformer(self): 35 | return None 36 | 37 | 38 | def collect(self, item, collector_set): 39 | """Called for every item in a column. 40 | 41 | Dependencies are guaranteed to have collected the same item before this collector. 42 | Override this in subclasses. 43 | """ 44 | pass 45 | 46 | 47 | def get_result(self, collector_set): 48 | """Returns the result of this collector after all items have been collected.""" 49 | raise NotImplementedError 50 | 51 | 52 | @property 53 | def has_collected(self): return self.__has_collected 54 | def set_collected(self): self.__has_collected = True 55 | 56 | @property 57 | def has_transformed(self): return self.__has_transformed 58 | def set_transformed(self): self.__has_transformed = True 59 | 60 | 61 | @staticmethod 62 | def result_norm(a, b, *args): 63 | return abs(a - b) 64 | 65 | 66 | @classmethod 67 | def get_type(cls, collector_set): 68 | return cls 69 | 70 | 71 | def as_str(self, collector_set, format_spec=''): 72 | return format(self.get_result(collector_set), format_spec) 73 | 74 | 75 | def __str__(self): 76 | return self.as_str(None) 77 | -------------------------------------------------------------------------------- /src/schema_matching/collector/columntype.py: -------------------------------------------------------------------------------- 1 | # coding=utf-8 2 | 3 | import re, itertools 4 | from numbers import Number 5 | from .. import utilities 6 | from ..utilities import functional, string, infinity 7 | from ..utilities.iterator import countif 8 | from .base import ItemCollector 9 | from .itemcount import ItemCountCollector 10 | 11 | 12 | __decimal_regex = re.compile(r"\s*([-+]?)(|\d[^,.]*?|[^,.]*\d|.*?([,.]).*?)\s*$") 13 | 14 | def decimal_info(item): 15 | m = re.match(__decimal_regex, item) 16 | if not m: 17 | return None 18 | 19 | start, end = m.span(2) 20 | if start != len(item) and not (item[start].isdigit() or item[end-1].isdigit()): 21 | return None 22 | 23 | if start == end: 24 | sign = m.group(1) 25 | return ('', len(sign), 0) if not sign or sign == '-' else None 26 | 27 | if start == m.start(3) and end == m.end(3): 28 | return None 29 | 30 | total_len = end - start 31 | potential_digits = itertools.islice(item, start, end) 32 | decimal_separator = m.group(3) if m.start(3) >= 0 else '' 33 | invalid_char_count = total_len - len(decimal_separator) - \ 34 | countif(type(item).isdigit, potential_digits) 35 | total_len += m.end(1) - m.start(1) 36 | return decimal_separator, total_len, invalid_char_count 37 | 38 | 39 | def tofloat(item): 40 | item = item.replace(',', '.', 1) 41 | try: 42 | return float(item) 43 | except ValueError: 44 | return None 45 | 46 | 47 | def toint(item): 48 | try: 49 | return int(item) 50 | except ValueError: 51 | return None 52 | 53 | 54 | 55 | def _make_type_distance_matrix(type_sequence): 56 | return [ 57 | [ 58 | float(a is not b) 59 | if isinstance(a, Number) is isinstance(b, Number) else 60 | infinity 61 | for a in type_sequence 62 | ] 63 | for b in type_sequence 64 | ] 65 | 66 | class ColumnTypeItemCollector(ItemCollector): 67 | 68 | result_dependencies = (ItemCountCollector,) 69 | 70 | __type_sequence = (int, float, str) 71 | __type_rdict = utilities.rdict(enumerate(__type_sequence)) 72 | __distance_matrix = _make_type_distance_matrix(__type_sequence) 73 | __transformers = (toint, tofloat, str) 74 | 75 | 76 | @staticmethod 77 | def __get_set_length(x): 78 | if isinstance(x, dict): 79 | icc = x.get(ItemCountCollector) 80 | if icc: 81 | return icc.get_result(x) 82 | return None 83 | 84 | 85 | def __init__(self, collector_set=None, max_invalid_absolute=2, max_invalid_relative=0.25, total_max_invalid=0.05): 86 | super().__init__() 87 | self.__type_index = -1 88 | self.__tolerance_exceeded_count = 0 89 | 90 | self.max_invalid_absolute = max_invalid_absolute 91 | self.max_invalid_relative = max_invalid_relative 92 | self.total_max_invalid = total_max_invalid 93 | set_length = self.__get_set_length(collector_set) 94 | self.__total_max_invalid_absolute = ( 95 | set_length and int(set_length * self.total_max_invalid)) 96 | 97 | 98 | def collect(self, item, collector_set = None): 99 | assert not self.has_collected 100 | if self.__type_index <= 0: # none or int 101 | if item == '-' or item.isdigit(): 102 | self.__type_index = 0 103 | return 104 | self.__type_index = 1 105 | 106 | if self.__type_index == 1: # float 107 | info = decimal_info(item) 108 | if info: 109 | if not info[2]: 110 | return 111 | if (info[2] <= self.max_invalid_absolute and 112 | info[2] <= info[1] * self.max_invalid_relative 113 | ): 114 | self.__tolerance_exceeded_count += 1 115 | if not self.__total_max_invalid_absolute < self.__tolerance_exceeded_count: 116 | return 117 | self.__type_index += 1 118 | 119 | 120 | def get_result(self, collector_set = None): 121 | assert self.has_collected 122 | if self.__type_index == 1 and self.__total_max_invalid_absolute is None: 123 | set_length = self.__get_set_length(collector_set) 124 | self.__total_max_invalid_absolute = \ 125 | 0 if set_length is None else int(set_length * self.total_max_invalid) 126 | if self.__total_max_invalid_absolute < self.__tolerance_exceeded_count: 127 | self.__type_index += 1 128 | 129 | return self.__type_sequence[self.__type_index] 130 | 131 | 132 | def get_transformer(self): 133 | return self.__transformers[self.__type_index] 134 | 135 | 136 | @staticmethod 137 | def result_norm(a, b): 138 | return ( 139 | ColumnTypeItemCollector.__distance_matrix 140 | [ColumnTypeItemCollector.__type_rdict[a]] 141 | [ColumnTypeItemCollector.__type_rdict[b]]) 142 | 143 | 144 | def as_str(self, collector_set = None, format_spec=None): 145 | return utilities.string.join('(', self.get_result(None).__name__, ':', 146 | str(self.__tolerance_exceeded_count), ')') 147 | 148 | 149 | def __format__(self, format_spec=None): return self.as_str() 150 | 151 | def __str__(self): return self.as_str() 152 | 153 | 154 | 155 | class factory(object): 156 | 157 | __pre_dependencies = (ColumnTypeItemCollector,) 158 | 159 | 160 | def __init__(self, string_collector, numeric_collector): 161 | super().__init__() 162 | self.string_collector = string_collector 163 | self.numeric_collector = numeric_collector 164 | self.pre_dependencies = frozenset(itertools.chain(self.__pre_dependencies, 165 | *_imap_attr('pre_dependencies', (), string_collector, 166 | numeric_collector))) 167 | self.result_dependencies = frozenset(itertools.chain( 168 | *_imap_attr('result_dependencies', (), string_collector, 169 | numeric_collector))) 170 | 171 | 172 | def __call__(self, type_or_predecessor): 173 | if isinstance(type_or_predecessor, dict): 174 | predecessor = type_or_predecessor 175 | type = predecessor[ColumnTypeItemCollector].get_result() 176 | else: 177 | predecessor = None 178 | type = type_or_predecessor 179 | return ItemCollector.get_instance(self.__for_type(type), predecessor) 180 | 181 | 182 | def get_type(self, collector_set): 183 | if collector_set: 184 | ctc = collector_set.get(ColumnTypeItemCollector) 185 | if ctc is not None: 186 | return self.__for_type(ctc.get_result()) 187 | return self 188 | 189 | 190 | def __for_type(self, type): 191 | return self.numeric_collector if issubclass(type, Number) else self.string_collector 192 | 193 | 194 | def __eq__(self, other): 195 | return (isinstance(other, factory) and 196 | self.string_collector == other.string_collector and 197 | self.numeric_collector == other.numeric_collector) 198 | 199 | 200 | def __ne__(self, other): 201 | return not self.__eq__(other) 202 | 203 | 204 | def __hash__(self): 205 | return 0x4a9fd98f ^ hash(self.string_collector) ^ hash(self.numeric_collector) 206 | 207 | 208 | 209 | def _imap_attr(attr, default, *objects): 210 | return map(utilities.functional.memberfn(getattr, attr, default), objects) 211 | -------------------------------------------------------------------------------- /src/schema_matching/collector/description/__init__.py: -------------------------------------------------------------------------------- 1 | from .normal import L1 as default 2 | from ._argparser import parse as argparser 3 | -------------------------------------------------------------------------------- /src/schema_matching/collector/description/_argparser.py: -------------------------------------------------------------------------------- 1 | import importlib 2 | 3 | 4 | def parse(src): 5 | try: 6 | if src == ':': 7 | from ..description import default as desc 8 | elif src.startswith(':'): 9 | desc = importlib.import_module(src[1:], __package__.partition('.')[0]) 10 | else: 11 | desc = importlib.machinery.SourceFileLoader(src, src).load_module() 12 | except: 13 | raise ImportError(src) 14 | 15 | if not getattr(desc, 'descriptions', None): 16 | raise NameError( 17 | "The collector description module doesn't contain any collector description.", 18 | desc, desc.__file__, 19 | "missing attribute 'descriptions'") 20 | 21 | return desc 22 | -------------------------------------------------------------------------------- /src/schema_matching/collector/description/normal/L1.py: -------------------------------------------------------------------------------- 1 | from ...weight import WeightDict, normalize_exp 2 | from ... import columntype 3 | from ...itemaverage import ItemAverageCollector 4 | from ...letteraverage import ItemLetterAverageCollector 5 | from ...variance import ItemVariationCoefficientCollector 6 | from ...lettervariance import LetterVariationCoefficient 7 | from ...itemprobability import ItemProbabilityCollector 8 | from ...letterprobability import LetterProbablilityCollector 9 | from ...letterentropy import NormalizedLetterEntropyCollector 10 | 11 | 12 | 13 | descriptions = ( 14 | columntype.ColumnTypeItemCollector, 15 | 16 | columntype.factory( 17 | ItemLetterAverageCollector, ItemAverageCollector), 18 | columntype.factory( 19 | LetterVariationCoefficient, ItemVariationCoefficientCollector), 20 | columntype.factory( 21 | LetterProbablilityCollector, ItemProbabilityCollector), 22 | columntype.factory( 23 | NormalizedLetterEntropyCollector, None) 24 | ) 25 | 26 | 27 | # Normalised distances and L1-normalised (Manhattan norm) collector sets 28 | weights = WeightDict(normalize_exp, tags={'normalized'}) 29 | -------------------------------------------------------------------------------- /src/schema_matching/collector/description/normal/L2.py: -------------------------------------------------------------------------------- 1 | import math 2 | from .... import utilities 3 | from ...weight import WeightDict, normalize_exp 4 | from ...description.normal.L1 import descriptions 5 | 6 | 7 | # Normalised distances and L2-normalised (Euclidean norm) collector sets 8 | weights = WeightDict( 9 | normalize_exp, (utilities.operator.square, math.sqrt), tags=('normalized')) 10 | -------------------------------------------------------------------------------- /src/schema_matching/collector/description/normal/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/davidfoerster/schema-matching/5edfde4d1962d35a3354fc12b13eb1205a1fec25/src/schema_matching/collector/description/normal/__init__.py -------------------------------------------------------------------------------- /src/schema_matching/collector/itemaverage.py: -------------------------------------------------------------------------------- 1 | from .base import ItemCollector 2 | from .itemsum import ItemSumCollector 3 | from .itemcount import ItemCountCollector 4 | 5 | 6 | 7 | class ItemAverageCollector(ItemCollector): 8 | 9 | result_dependencies = (ItemCountCollector, ItemSumCollector) 10 | 11 | 12 | def get_result(self, collector_set): 13 | sumcoll = collector_set[ItemSumCollector] 14 | return (sumcoll.get_result() / 15 | (collector_set[ItemCountCollector].get_result() - sumcoll.type_error_count)) 16 | -------------------------------------------------------------------------------- /src/schema_matching/collector/itemcount.py: -------------------------------------------------------------------------------- 1 | import numbers 2 | from .base import ItemCollector 3 | from .set import ItemCollectorSet 4 | 5 | 6 | 7 | class ItemCountCollector(ItemCollector): 8 | 9 | def __init__(self, previous_collector_set = None): 10 | super().__init__(previous_collector_set) 11 | if isinstance(previous_collector_set, numbers.Integral): 12 | self.count = previous_collector_set 13 | self.set_collected() 14 | else: 15 | self.count = 0 16 | assert previous_collector_set is None or \ 17 | isinstance(previous_collector_set, ItemCollectorSet) 18 | 19 | 20 | def collect(self, item, collector_set = None): 21 | assert not self.has_collected 22 | self.count += 1 23 | 24 | 25 | def get_result(self, collector_set = None): 26 | assert self.has_collected 27 | return self.count 28 | -------------------------------------------------------------------------------- /src/schema_matching/collector/itemfrequency.py: -------------------------------------------------------------------------------- 1 | import numbers, operator 2 | from .. import utilities 3 | from .base import ItemCollector 4 | from .columntype import ColumnTypeItemCollector 5 | from .itemcount import ItemCountCollector 6 | from .minitem import MinItemCollector 7 | from .maxitem import MaxItemCollector 8 | from .variance import ItemVarianceCollector 9 | from ..utilities.distribution import ( 10 | UniformBinDistributionTable, SparseDistributionTable) 11 | 12 | 13 | 14 | class ItemFrequencyCollector(ItemCollector): 15 | 16 | pre_dependencies = (ItemCountCollector, MinItemCollector, MaxItemCollector, ItemVarianceCollector) 17 | 18 | 19 | def __init__(self, previous_collector_set): 20 | super().__init__(previous_collector_set) 21 | 22 | if issubclass(previous_collector_set[ColumnTypeItemCollector].get_result(previous_collector_set), numbers.Real): 23 | prereqs = list(map(previous_collector_set.get, self.pre_dependencies)) 24 | if prereqs[-1] is None: 25 | del prereqs[-1] 26 | table_ctor = UniformBinDistributionTable.for_count 27 | else: 28 | table_ctor = UniformBinDistributionTable.for_variance 29 | assert all(prereqs) 30 | utilities.iterator.map_inplace(operator.methodcaller('get_result'), prereqs) 31 | prereqs.append('I') 32 | self.frequencies = table_ctor(*prereqs) 33 | else: 34 | self.frequencies = SparseDistributionTable(int) 35 | 36 | 37 | def collect(self, item, collector_set=None): 38 | if item is not None: 39 | self.frequencies.increase(item) 40 | 41 | 42 | def get_result(self, collector_set=None): 43 | return self.frequencies 44 | -------------------------------------------------------------------------------- /src/schema_matching/collector/itemprobability.py: -------------------------------------------------------------------------------- 1 | from .probability import BaseProbabilityCollector 2 | from .itemcount import ItemCountCollector 3 | from .itemfrequency import ItemFrequencyCollector 4 | 5 | 6 | class ItemProbabilityCollector(BaseProbabilityCollector): 7 | 8 | result_dependencies = (ItemCountCollector, ItemFrequencyCollector) 9 | -------------------------------------------------------------------------------- /src/schema_matching/collector/itemsum.py: -------------------------------------------------------------------------------- 1 | from math import isnan 2 | from .base import ItemCollector 3 | 4 | 5 | 6 | class ItemSumCollector(ItemCollector): 7 | 8 | def __init__(self, previous_collector_set = None): 9 | super().__init__(previous_collector_set) 10 | self.sum = 0 11 | self.type_error_count = 0 12 | 13 | 14 | def collect(self, item, collector_set = None): 15 | try: 16 | if not isnan(item): 17 | self.sum += item 18 | except TypeError: 19 | self.type_error_count += 1 20 | 21 | 22 | def get_result(self, collector_set = None): 23 | return self.sum 24 | -------------------------------------------------------------------------------- /src/schema_matching/collector/letteraverage.py: -------------------------------------------------------------------------------- 1 | from .base import ItemCollector 2 | from .itemcount import ItemCountCollector 3 | from .lettercount import ItemLetterCountCollector 4 | 5 | 6 | 7 | class ItemLetterAverageCollector(ItemCollector): 8 | 9 | result_dependencies = (ItemLetterCountCollector, ItemCountCollector) 10 | 11 | 12 | def get_result(self, collector_set): 13 | return ( 14 | collector_set[ItemLetterCountCollector].get_result() 15 | / collector_set[ItemCountCollector].get_result()) 16 | -------------------------------------------------------------------------------- /src/schema_matching/collector/lettercount.py: -------------------------------------------------------------------------------- 1 | from .base import ItemCollector 2 | 3 | if __debug__: 4 | from ..utilities.string import basestring 5 | 6 | 7 | 8 | class ItemLetterCountCollector(ItemCollector): 9 | 10 | def __init__(self, previous_collector_set = None): 11 | super().__init__(previous_collector_set) 12 | self.letter_count = 0 13 | 14 | 15 | def collect(self, item, collector_set = None): 16 | assert isinstance(item, basestring) 17 | self.letter_count += len(item) 18 | 19 | 20 | def get_result(self, collector_set = None): 21 | return self.letter_count 22 | -------------------------------------------------------------------------------- /src/schema_matching/collector/letterentropy.py: -------------------------------------------------------------------------------- 1 | from math import fsum, log 2 | from .base import ItemCollector 3 | from .letterprobability import LetterProbablilityCollector 4 | 5 | 6 | 7 | NORMALIZED = 'normalized' 8 | 9 | 10 | class LetterEntropyCollector(ItemCollector): 11 | 12 | result_dependencies = (LetterProbablilityCollector,) 13 | 14 | 15 | def __init__(self, collector_set=None, base=2): 16 | super().__init__(collector_set) 17 | self.base = base 18 | 19 | 20 | def get_result(self, collector_set): 21 | dist = collector_set[LetterProbablilityCollector].get_result(collector_set) 22 | base = len(dist) if self.base is NORMALIZED else self.base 23 | return -fsum(map(self.__event_entropy, filter(None, dist.values()))) / log(base) 24 | 25 | 26 | @staticmethod 27 | def __event_entropy(p): 28 | assert 0.0 < p <= 1.0 29 | return p * log(p) 30 | 31 | 32 | 33 | class NormalizedLetterEntropyCollector(LetterEntropyCollector): 34 | 35 | def __init__(self, collector_set=None): 36 | super().__init__(collector_set, NORMALIZED) 37 | -------------------------------------------------------------------------------- /src/schema_matching/collector/letterfrequency.py: -------------------------------------------------------------------------------- 1 | from .base import ItemCollector 2 | from ..utilities.distribution import SparseDistributionTable 3 | 4 | if __debug__: 5 | from ..utilities.string import basestring 6 | 7 | 8 | 9 | class LetterFrequencyCollector(ItemCollector): 10 | 11 | def __init__(self, previous_collector_set=None): 12 | super().__init__(previous_collector_set) 13 | self.frequencies = SparseDistributionTable(int) 14 | 15 | 16 | def collect(self, item, collector_set=None): 17 | assert isinstance(item, basestring) 18 | for c in item: 19 | self.frequencies[c] += 1 20 | 21 | 22 | def get_result(self, collector_set=None): 23 | return self.frequencies 24 | 25 | 26 | def as_str(self, collector_set=None, number_fmt=''): 27 | return format(self.get_result(collector_set), number_fmt) 28 | -------------------------------------------------------------------------------- /src/schema_matching/collector/letterprobability.py: -------------------------------------------------------------------------------- 1 | from .probability import BaseProbabilityCollector 2 | from .lettercount import ItemLetterCountCollector 3 | from .letterfrequency import LetterFrequencyCollector 4 | 5 | 6 | class LetterProbablilityCollector(BaseProbabilityCollector): 7 | 8 | result_dependencies = (ItemLetterCountCollector, LetterFrequencyCollector) 9 | -------------------------------------------------------------------------------- /src/schema_matching/collector/lettervariance.py: -------------------------------------------------------------------------------- 1 | from math import sqrt 2 | from ..utilities.operator import square 3 | from .base import ItemCollector 4 | from .lettercount import ItemLetterCountCollector 5 | from .letteraverage import ItemLetterAverageCollector 6 | 7 | 8 | 9 | class LetterVarianceCollector(ItemCollector): 10 | 11 | pre_dependencies = (ItemLetterAverageCollector,) 12 | 13 | result_dependencies = (ItemLetterCountCollector,) 14 | 15 | 16 | def __init__(self, previous_collector_set): 17 | super().__init__(previous_collector_set) 18 | self.sum_of_squares = 0 19 | self.letter_average = \ 20 | previous_collector_set[ItemLetterAverageCollector] \ 21 | .get_result(previous_collector_set) 22 | 23 | 24 | def collect(self, item, collector_set = None): 25 | self.sum_of_squares += square(len(item) - self.letter_average) 26 | 27 | 28 | def get_result(self, collector_set): 29 | return self.sum_of_squares / collector_set[ItemLetterCountCollector].get_result() 30 | 31 | 32 | 33 | class LetterStandardDeviationCollector(ItemCollector): 34 | 35 | result_dependencies = (LetterVarianceCollector,) 36 | 37 | def get_result(self, collector_set): 38 | return sqrt(collector_set[LetterVarianceCollector].get_result(collector_set)) 39 | 40 | 41 | 42 | class LetterVariationCoefficient(ItemCollector): 43 | 44 | result_dependencies = (LetterVarianceCollector,) 45 | 46 | def get_result(self, collector_set): 47 | varcoll = collector_set[LetterVarianceCollector] 48 | return sqrt(varcoll.get_result(collector_set)) / varcoll.letter_average 49 | -------------------------------------------------------------------------------- /src/schema_matching/collector/maxitem.py: -------------------------------------------------------------------------------- 1 | from .base import ItemCollector 2 | from ..utilities import infinity 3 | 4 | 5 | 6 | class MaxItemCollector(ItemCollector): 7 | 8 | def __init__(self, previous_collector_set = None): 9 | super().__init__(previous_collector_set) 10 | self.max = -infinity 11 | 12 | 13 | def collect(self, item, collector_set = None): 14 | if item is not None and item > self.max: 15 | self.max = item 16 | 17 | 18 | def get_result(self, collector_set = None): 19 | return self.max 20 | -------------------------------------------------------------------------------- /src/schema_matching/collector/minitem.py: -------------------------------------------------------------------------------- 1 | from .base import ItemCollector 2 | from ..utilities import infinity 3 | 4 | 5 | 6 | class MinItemCollector(ItemCollector): 7 | 8 | def __init__(self, previous_collector_set = None): 9 | super().__init__(previous_collector_set) 10 | self.min = infinity 11 | 12 | 13 | def collect(self, item, collector_set = None): 14 | if item is not None and item < self.min: 15 | self.min = item 16 | 17 | 18 | def get_result(self, collector_set = None): 19 | return self.min 20 | -------------------------------------------------------------------------------- /src/schema_matching/collector/multiphase.py: -------------------------------------------------------------------------------- 1 | import copy, collections 2 | from ..utilities import iterator as uiterator 3 | from itertools import filterfalse, zip_longest, islice, chain 4 | from functools import partial as partialfn 5 | from ..utilities.iterator import each, consume 6 | from ..utilities.functional import memberfn, composefn 7 | 8 | from .base import ItemCollector 9 | from .tag import TagCollector 10 | from .set import ItemCollectorSet 11 | from .rows import RowCollector 12 | from .itemcount import ItemCountCollector 13 | from .columntype import ColumnTypeItemCollector 14 | 15 | if __debug__: 16 | import operator 17 | 18 | 19 | 20 | class MultiphaseCollector(object): 21 | """Manages a sequence of collection phases""" 22 | 23 | def __init__(self, rowset, name=None, verbosity=0): 24 | self.name = name 25 | self.verbosity = verbosity 26 | self.rowset = rowset if isinstance(rowset, collections.Sequence) else tuple(rowset) 27 | #assert operator.eq(*utilities.minmax(map(len, self.rowset))) 28 | self.reset(None) 29 | 30 | 31 | def reset(self, keep=(ItemCountCollector, ColumnTypeItemCollector)): 32 | self.merged_predecessors = \ 33 | RowCollector(self.__emit_itemcollector_set(keep), self.verbosity) 34 | return self 35 | 36 | 37 | def __emit_itemcollector_set(self, keep): 38 | if keep and isinstance(self.merged_predecessors, RowCollector): 39 | keep = composefn(type, keep.__contains__) 40 | for predecessor in self.merged_predecessors: 41 | ics = ItemCollectorSet() 42 | 43 | def add_copy_and_dependencies(collector, isdependency): 44 | for dep in collector.result_dependencies: 45 | add_copy_and_dependencies(predecessor[dep], True) 46 | if isdependency is None: 47 | isdependency = collector.isdependency 48 | collector = ics.setdefault(type(collector), copy.copy(collector)) 49 | collector.isdependency &= isdependency 50 | 51 | each(memberfn(add_copy_and_dependencies, None), 52 | filter(keep, predecessor.values())) 53 | yield ics 54 | else: 55 | for _ in range(len(self.rowset[0])): 56 | ics = ItemCollectorSet() 57 | ics.add(ItemCountCollector(len(self.rowset)), True) 58 | yield ics 59 | 60 | 61 | def do_phases(self, collectorset_description, callback=None): 62 | phase_count = 0 63 | while True: 64 | phase_descriptions = self.get_phase_descriptions(collectorset_description) 65 | if __debug__: 66 | phase_descriptions = tuple(phase_descriptions) 67 | 68 | for phase_description in phase_descriptions: 69 | if self.__contains_factory(phase_description): 70 | assert phase_description is not phase_descriptions[0] 71 | break 72 | self.__do_phase_magic(self.__gen_itemcollector_sets(phase_description)) 73 | phase_count += 1 74 | if callback is not None: 75 | callback(self) 76 | else: 77 | break 78 | 79 | if __debug__: 80 | for coll_set in self.merged_predecessors: 81 | independent = frozenset((template.get_type(coll_set) for template in collectorset_description)) 82 | for ctype, coll in coll_set.items(): 83 | assert coll.isdependency is (ctype not in independent) 84 | 85 | return phase_count 86 | 87 | 88 | def __gen_itemcollector_sets(self, phase_desc): 89 | return ( 90 | pred if desc is None else ItemCollectorSet(desc.values(), pred) 91 | for desc, pred in zip(phase_desc, self.merged_predecessors)) 92 | 93 | 94 | @staticmethod 95 | def __contains_factory(phase_desc): 96 | return not all(( 97 | isinstance(ctype, ItemCollector) or 98 | (type(ctype) is type and issubclass(ctype, ItemCollector)) 99 | for ctype in chain(*filter(None, phase_desc)))) 100 | 101 | 102 | def get_phase_descriptions(self, collectorset_description): 103 | # column-first ordering 104 | phase_descriptions = map( 105 | partialfn(self.__get_dependency_chain, collectorset_description), 106 | self.merged_predecessors) 107 | # transpose to phase-first ordering 108 | phase_descriptions = zip_longest(*phase_descriptions) 109 | return phase_descriptions 110 | 111 | 112 | def __get_dependency_chain(self, collectorset_description, predecessors=None): 113 | """ 114 | Returns a list of phase-wise collector descriptions for a single column. 115 | 116 | :param collectorset_description: iterable 117 | :param predecessors: ItemCollectorSet 118 | :return: list[dict] 119 | """ 120 | phase = dict(filterfalse( 121 | lambda item: item[0] is None or item[0] in predecessors, 122 | ((template.get_type(predecessors), template) 123 | for template in collectorset_description))) 124 | independent = TagCollector('independent', frozenset(phase.keys()), True) 125 | 126 | phases = [] 127 | collector_min_phases = dict() 128 | phase_pre_dependencies = None 129 | phase_result_dependencies = set() 130 | 131 | def must_add_dependency(dep): 132 | return (dep not in phase and 133 | dep not in phase_result_dependencies and 134 | dep not in phase_pre_dependencies) 135 | 136 | def add_dependencies(template): 137 | if template.pre_dependencies: 138 | for dep in filterfalse(predecessors.__contains__, template.pre_dependencies): 139 | phase_pre_dependencies.setdefault(dep, dep) 140 | collector_min_phases[dep] = len(phases) - 1 141 | else: 142 | for dep in filter(must_add_dependency, template.result_dependencies): 143 | add_dependencies(dep) 144 | phase_result_dependencies.add(dep) 145 | 146 | # resolve dependencies and push them to an earlier phase 147 | while phase: 148 | phase_pre_dependencies = dict() 149 | phase_result_dependencies.clear() 150 | each(add_dependencies, phase.keys()) 151 | phases.append(phase) 152 | phase = phase_pre_dependencies 153 | 154 | # remove later duplicates 155 | consume(( 156 | each(memberfn(dict.pop, ctype, None), islice(phases, 0, -min_phase_idx)) 157 | for ctype, min_phase_idx in collector_min_phases.items())) 158 | 159 | if predecessors is not None: 160 | predecessors[independent] = independent 161 | elif phases: 162 | phases[-1][independent] = independent 163 | 164 | return uiterator.filter(None, reversed(phases)) 165 | 166 | 167 | def do_phase(self, phase_description): 168 | self.__do_phase_magic((ItemCollectorSet(phase_description, pred) 169 | for pred in self.merged_predecessors)) 170 | 171 | 172 | def __do_phase_magic(self, itemcollector_sets): 173 | phase = RowCollector(itemcollector_sets, self.verbosity) 174 | phase.collect_all(self.rowset) 175 | phase.transform_all(self.rowset) 176 | self.merged_predecessors = phase 177 | 178 | 179 | __call__ = do_phase 180 | 181 | 182 | def columncount(self): 183 | return len(self.merged_predecessors) 184 | 185 | 186 | def results_norms(a, b, weights=None): 187 | """ 188 | :param a: self 189 | :param b: MultiphaseCollector 190 | :return: list[list[float]] 191 | """ 192 | return a.merged_predecessors.results_norms(b.merged_predecessors, weights) 193 | 194 | 195 | def copy(self): 196 | return MultiphaseCollector( 197 | copy.deepcopy(self.rowset), self.name, self.verbosity) 198 | -------------------------------------------------------------------------------- /src/schema_matching/collector/probability.py: -------------------------------------------------------------------------------- 1 | from .base import ItemCollector 2 | 3 | 4 | 5 | class BaseProbabilityCollector(ItemCollector): 6 | 7 | # result_dependencies = (*CountCollector, *FrequencyCollector) 8 | 9 | 10 | def __init__(self, previous_collector_set): 11 | super().__init__(previous_collector_set) 12 | self.__cached_result = None 13 | 14 | 15 | def get_result(self, collector_set): 16 | if self.__cached_result is None: 17 | self.__cached_result = \ 18 | collector_set[self.result_dependencies[1]].get_result(collector_set) \ 19 | .normalize(collector_set[self.result_dependencies[0]] \ 20 | .get_result(collector_set)) 21 | return self.__cached_result 22 | 23 | 24 | def as_str(self, collector_set, number_fmt=''): 25 | return format(self.get_result(collector_set), number_fmt) 26 | 27 | 28 | @staticmethod 29 | def result_norm(a, b): 30 | return a.distance_to(b) 31 | -------------------------------------------------------------------------------- /src/schema_matching/collector/rows.py: -------------------------------------------------------------------------------- 1 | from ..utilities import operator as uoperator 2 | from operator import methodcaller 3 | from ..utilities.iterator import each 4 | from ..utilities.string import join 5 | 6 | 7 | 8 | class RowCollector(list): 9 | """Manages collectors for a set of rows""" 10 | 11 | def __init__(self, initialiser, verbosity=0): 12 | list.__init__(self, initialiser) 13 | 14 | self.__rowcount = 0 15 | if verbosity >= 2: 16 | import sys 17 | self.__stderr = sys.stderr 18 | else: 19 | self.__stderr = None 20 | 21 | 22 | def reset(self, collectors): 23 | self[:] = collectors 24 | self.__rowcount = 0 25 | 26 | 27 | def collect(self, items): 28 | """Collects the data of all columns of a row""" 29 | if self.__stderr is not None and len(self) != len(items): 30 | self.__rowcount += 1 31 | print( 32 | 'Row {} has {} columns, expected {}: {}'.format( 33 | self.__rowcount, len(items), len(self), items), 34 | file=self.__stderr) 35 | 36 | assert len(self) <= len(items) 37 | each(self.__collect_column, self, items) 38 | 39 | 40 | @staticmethod 41 | def __collect_column(collector, item): 42 | collector.collect(item, collector) 43 | 44 | 45 | def collect_all(self, rows): 46 | each(self.collect, rows) 47 | each(methodcaller('set_collected'), self) 48 | 49 | 50 | class __transformer(tuple): 51 | 52 | def __call__(self, items): 53 | for i, t in self: 54 | items[i] = t(items[i]) 55 | 56 | 57 | def get_transformer(self): 58 | column_transformers = tuple( 59 | filter(uoperator.second, 60 | enumerate(map(methodcaller('get_transformer'), self)))) 61 | 62 | if column_transformers: 63 | def row_transformer(items): 64 | for column_idx, column_transformer in column_transformers: 65 | items[column_idx] = column_transformer(items[column_idx]) 66 | else: 67 | row_transformer = None 68 | 69 | return row_transformer 70 | 71 | 72 | def transform_all(self, rows): 73 | transformer = self.get_transformer() 74 | if transformer is not None: 75 | each(transformer, rows) 76 | each(methodcaller('set_transformed'), self) 77 | 78 | 79 | def results_norms(a, b, weights=None): 80 | get_result = methodcaller('get_result') 81 | # Materialise results of inner loop because they'll be scanned multiple times. 82 | resultsA = tuple(map(get_result, a)) 83 | resultsB = map(get_result, b) 84 | return [ 85 | [collB.result_norm(resultA, resultB, weights) for resultA in resultsA] 86 | for collB, resultB in zip(b, resultsB) 87 | ] 88 | 89 | 90 | def as_str(self, format_spec=''): 91 | return join('(', ', '.join(map(methodcaller('as_str', None, format_spec), self)), ')') 92 | 93 | 94 | def __str__(self): return self.as_str() 95 | 96 | __format__ = as_str 97 | -------------------------------------------------------------------------------- /src/schema_matching/collector/set.py: -------------------------------------------------------------------------------- 1 | import collections, inspect 2 | from operator import methodcaller, attrgetter 3 | from .base import ItemCollector 4 | from .weight import WeightDict 5 | from .. import utilities 6 | from ..utilities import operator as uoperator 7 | from itertools import filterfalse 8 | from ..utilities.iterator import each 9 | from ..utilities.functional import composefn 10 | from ..utilities.string import join 11 | 12 | 13 | 14 | class ItemCollectorSet(ItemCollector, collections.OrderedDict): 15 | """Manages a set of collectors for a single column""" 16 | 17 | def __init__(self, collectors = (), predecessor = None): 18 | ItemCollector.__init__(self) 19 | collections.OrderedDict.__init__(self) 20 | 21 | self.predecessor = predecessor 22 | if predecessor: 23 | assert all(map(attrgetter('has_collected'), predecessor.values())) 24 | self.update(predecessor) 25 | each(self.add, collectors) 26 | 27 | 28 | def collect(self, item, collector_set = None): 29 | assert collector_set is self 30 | collect = ItemCollector.collect 31 | collect(self, item, self) 32 | each(methodcaller('collect', item, self), 33 | filterfalse(attrgetter('has_collected'), 34 | self.values())) 35 | 36 | 37 | class __result_type(object): 38 | 39 | def __init__(self, collector_set): 40 | super().__init__() 41 | self.__collector_set = collector_set 42 | 43 | def __iter__(self): 44 | collector_set = self.__collector_set 45 | return map(methodcaller('get_result', collector_set), collector_set.values()) 46 | 47 | def __cmp__(self, other, weights = WeightDict()): 48 | assert isinstance(other, type(self)) 49 | a = self.__collector_set 50 | b = other.__collector_set 51 | if not utilities.issubset(a.keys(), b): 52 | return weights[ItemCollectorSet].coefficient 53 | 54 | def distance_of_unweighted(a_coll): 55 | assert a[type(a_coll)] is a_coll and type(b[type(a_coll)]) is type(a_coll) 56 | return a_coll.result_norm( 57 | a_coll.get_result(a), b[type(a_coll)].get_result(b)) 58 | 59 | weight_sum = utilities.NonLocal(0) 60 | if weights is None: 61 | def distance_of(a_coll): 62 | weight_sum.value += 1 63 | return distance_of_unweighted(a_coll) 64 | else: 65 | def distance_of(a_coll): 66 | weight = weights[type(a_coll)] 67 | weight_sum.value += weight.coefficient 68 | return weight(distance_of_unweighted(a_coll)) 69 | 70 | value_sum = weights.sum(map(distance_of, 71 | filterfalse(attrgetter('isdependency'), a.values()))) 72 | if value_sum: 73 | assert weight_sum.value > 0 74 | assert not 'normalized' in weights.tags or abs(value_sum / weight_sum.value) <= 1 75 | return value_sum / weight_sum.value 76 | else: 77 | return utilities.NaN 78 | 79 | 80 | def set_collected(self): self.__forward_call() 81 | 82 | def set_transformed(self): self.__forward_call() 83 | 84 | 85 | def __forward_call(self, fn_name=None, *args): 86 | if fn_name is None: 87 | fn_name = inspect.stack()[1][3] 88 | each(methodcaller(fn_name, *args), self.values()) 89 | getattr(super(ItemCollectorSet, self), fn_name)(*args) 90 | 91 | 92 | def get_result(self, collector_set = None): 93 | assert collector_set is None 94 | return ItemCollectorSet.__result_type(self) 95 | 96 | 97 | @staticmethod 98 | def result_norm(a, b, *args): 99 | return ItemCollectorSet.__result_type.__cmp__(a, b, *args) 100 | 101 | 102 | def get_transformer(self): 103 | transformer = composefn(*filter(None, 104 | map(methodcaller('get_transformer'), 105 | filterfalse(attrgetter('has_transformed'), 106 | self.values())))) 107 | return None if transformer is uoperator.identity else transformer 108 | 109 | 110 | def as_str(self, collector_set=None, format_spec=''): 111 | assert collector_set is None 112 | return join('{', ', '.join(( 113 | join(type(collector).__name__, ': ', collector.as_str(self, format_spec)) 114 | for collector in self.values() if not collector.isdependency)), 115 | '}') 116 | 117 | 118 | def __format__(self, format_spec=''): return self.as_str(None, format_spec) 119 | 120 | 121 | def __str__(self): return self.as_str() 122 | 123 | 124 | def add(self, template, isdependency=None): 125 | """Adds an item collector and all its result_dependencies to this set with its type a key, 126 | if one of the same type isn't in the set already. 127 | 128 | Returns the collector the same type from this set, possibly the one just added. 129 | """ 130 | collector_type = template.get_type(self.predecessor) 131 | collector = self.get(collector_type) 132 | 133 | if isdependency is None: 134 | isdependency = self.__isdependency(collector_type, False) 135 | 136 | if collector is None: 137 | collector = ItemCollector.get_instance(template, self.predecessor) 138 | if not isinstance(collector, ItemCollector): 139 | assert collector is None 140 | return None 141 | collector.isdependency = isdependency 142 | each(self.__add_dependency, collector.result_dependencies) 143 | collector = self.setdefault(collector_type, collector) 144 | 145 | collector.isdependency &= isdependency 146 | return collector 147 | 148 | 149 | def __add_dependency(self, collector_type): 150 | return self.add(collector_type, self.__isdependency(collector_type, True)) 151 | 152 | 153 | def __isdependency(self, collector_type, default): 154 | independent_tag = self.get('independent') 155 | return ( 156 | default 157 | if independent_tag is None else 158 | collector_type not in independent_tag.data) 159 | -------------------------------------------------------------------------------- /src/schema_matching/collector/tag.py: -------------------------------------------------------------------------------- 1 | from .base import ItemCollector 2 | from ..utilities.string import join 3 | 4 | 5 | 6 | class TagCollector(ItemCollector): 7 | 8 | def __init__(self, id, data=None, isdependency=False): 9 | super().__init__() 10 | self.set_collected() 11 | self.set_transformed() 12 | self.isdependency = isdependency 13 | self.__id = id 14 | self.data = data 15 | 16 | 17 | @property 18 | def id(self): 19 | return self.__id 20 | 21 | 22 | def as_str(self, collector_set, format_spec=None): 23 | return join(str(self.__id), ': ', str(self.data)) 24 | 25 | 26 | def __eq__(self, other): 27 | return (self.__id == other or 28 | (isinstance(other, TagCollector) and self.__id == other.__id)) 29 | 30 | 31 | def __ne__(self, other): return not self.__eq__(other) 32 | 33 | def __hash__(self): return hash(self.__id) 34 | 35 | def get_result(self, collector_set): return None 36 | 37 | def get_type(self, collector_set): return self 38 | -------------------------------------------------------------------------------- /src/schema_matching/collector/variance.py: -------------------------------------------------------------------------------- 1 | from math import isnan, sqrt 2 | from ..utilities.operator import square 3 | from .base import ItemCollector 4 | from .itemaverage import ItemAverageCollector 5 | 6 | 7 | 8 | class ItemVarianceCollector(ItemCollector): 9 | 10 | pre_dependencies = (ItemAverageCollector,) 11 | 12 | def __init__(self, previous_collector_set): 13 | super().__init__(previous_collector_set) 14 | self.average = \ 15 | previous_collector_set[ItemAverageCollector]. \ 16 | get_result(previous_collector_set) 17 | self.sum_of_squares = 0 18 | self.sum_of_squares_count = 0 19 | 20 | 21 | def collect(self, item, collector_set=None): 22 | try: 23 | if not isnan(item): 24 | self.sum_of_squares += square(item - self.average) 25 | self.sum_of_squares_count += 1 26 | except TypeError: 27 | pass 28 | 29 | 30 | def get_result(self, collector_set = None): 31 | return self.sum_of_squares / self.sum_of_squares_count 32 | 33 | 34 | 35 | class ItemStandardDeviationCollector(ItemCollector): 36 | 37 | result_dependencies = (ItemVarianceCollector,) 38 | 39 | def get_result(self, collector_set): 40 | return sqrt(collector_set[ItemVarianceCollector].get_result(collector_set)) 41 | 42 | 43 | 44 | class ItemVariationCoefficientCollector(ItemCollector): 45 | 46 | result_dependencies = (ItemVarianceCollector,) 47 | 48 | def get_result(self, collector_set = None): 49 | varcoll = collector_set[ItemVarianceCollector] 50 | return sqrt(varcoll.get_result()) / varcoll.average 51 | -------------------------------------------------------------------------------- /src/schema_matching/collector/weight.py: -------------------------------------------------------------------------------- 1 | import itertools 2 | from ..utilities import iterator as uiterator, operator as uoperator 3 | from math import expm1, fsum 4 | 5 | 6 | 7 | class WeightDict(dict): 8 | 9 | class WeightFunctor(object): 10 | 11 | __cache = dict() 12 | 13 | def __new__(cls, weight): 14 | return ( 15 | weight 16 | if type(weight) is cls else ( 17 | cls.__cache.get(weight) or 18 | super(WeightDict.WeightFunctor, cls).__new__(cls))) 19 | 20 | def __init__(self, weight): 21 | super().__init__() 22 | if callable(weight): 23 | self.weightfn = weight 24 | self.coefficient = 1 25 | else: 26 | self.weightfn = weight.__mul__ 27 | self.coefficient = weight 28 | self.__cache.setdefault(weight, self) 29 | 30 | def __call__(self, x): 31 | return self.weightfn(x) 32 | 33 | 34 | def __new__(cls, *args, **kwargs): 35 | return super(WeightDict, cls).__new__(cls) 36 | 37 | 38 | def __init__(self, default=uoperator.identity, sum=(abs, uoperator.identity), *args, **kwargs): 39 | super().__init__() 40 | self.default = WeightDict.WeightFunctor(default) 41 | self.sum_data = sum 42 | self.tags = kwargs.pop('tags', frozenset()) 43 | uiterator.stareach(self.__setitem__, itertools.chain(args, kwargs.items())) 44 | 45 | 46 | def __missing__(self, key): 47 | return self.default 48 | 49 | 50 | def __setitem__(self, key, value): 51 | dict.__setitem__(self, key, WeightDict.WeightFunctor(value)) 52 | 53 | 54 | def setdefault(self, k, d=uoperator.identity): 55 | dict.setdefault(self, k, WeightDict(d)) 56 | 57 | 58 | def sum(self, iterable): 59 | return self.sum_data[1](fsum(map(self.sum_data[0], iterable))) 60 | 61 | 62 | 63 | def normalize_exp(x): 64 | """ 65 | Returns 66 | -(exp(-x) - 1) 67 | = -(exp(-x) - 1) 68 | = 1 - exp(-x) 69 | 70 | This gives us a nicely normalised distance measure that penalises large 71 | values subproportionally. 72 | """ 73 | return -expm1(-x) 74 | -------------------------------------------------------------------------------- /src/schema_matching/utilities/__init__.py: -------------------------------------------------------------------------------- 1 | from . import ( 2 | argparse, distribution, functional, iterator, misc, operator, string, 3 | timelimit, 4 | ) 5 | from .misc import ( 6 | infinity, NaN, minmax, sliceout, starmap, issubset, rdict, 7 | min_index, NonLocal, setattr_default, minmax2, 8 | ) 9 | -------------------------------------------------------------------------------- /src/schema_matching/utilities/argparse.py: -------------------------------------------------------------------------------- 1 | import builtins, sys, argparse, itertools 2 | 3 | 4 | 5 | class NargsRangeAction(argparse.Action): 6 | 7 | def __init__(self, option_strings, dest, nargs, 8 | default=None, type=None, choices=None, required=False, help=None, 9 | metavar=None 10 | ): 11 | assert builtins.type(nargs) is range and len(nargs) > 1 12 | assert nargs[0] >= 0 and nargs[1] > nargs[0] 13 | self.nargs_range = nargs 14 | 15 | nargs = argparse.ZERO_OR_MORE if self.nargs_range[0] == 0 else argparse.ONE_OR_MORE 16 | super().__init__(option_strings, dest, nargs, None, default, 17 | type, choices, required, help, metavar) 18 | 19 | 20 | def __call__(self, parser, namespace, values, option_string=None): 21 | if len(values) not in self.nargs_range: 22 | raise argparse.ArgumentError(self.metavar or self.dest, 23 | "needs {} to {} (multiple of {}) arguments".format( 24 | self.nargs_range[0], self.nargs_range[-1], 25 | self.nargs_range[1] - self.nargs_range[0])) 26 | 27 | setattr(namespace, self.dest, values) 28 | 29 | 30 | 31 | class ChoicesRangeHelpFormatter(argparse.HelpFormatter): 32 | 33 | def _expand_help(self, action): 34 | params = { 35 | k: getattr(v, '__name__', v) 36 | for k, v in vars(action).items() 37 | if v is not argparse.SUPPRESS 38 | } 39 | if self._prog is not argparse.SUPPRESS: 40 | params['prog'] = getattr(self._prog, '__name__', self._prog) 41 | 42 | choices = params.get('choices') 43 | if choices is not None: 44 | if type(choices) is range: 45 | if choices[-1] == sys.maxsize - 1: 46 | choices_str = '≥' + str(choices[0]) 47 | else: 48 | choices_str = str(choices[0]) + '-' + str(choices[-1]) 49 | step = choices[1] - choices[0] 50 | if abs(step) != 1: 51 | choices_str += ' step: ' + str(step) 52 | else: 53 | choices_str = ', '.join((str(c) for c in choices)) 54 | params['choices'] = choices_str 55 | return self._get_help_string(action) % params 56 | 57 | 58 | 59 | class NargsRangeHelpFormatter(argparse.HelpFormatter): 60 | 61 | def _format_args(self, action, default_metavar): 62 | if not isinstance(action, NargsRangeAction): 63 | return super()._format_args(action, default_metavar) 64 | 65 | nargs = action.nargs_range 66 | assert type(nargs) is range 67 | if len(nargs) <= 1 or nargs[-1] != sys.maxsize - 1: 68 | return NotImplemented 69 | 70 | assert nargs[0] >= 0 71 | assert nargs[1] - nargs[0] > 0 72 | metavar = self._metavar_formatter(action, default_metavar)(1)[0] 73 | return '{} [{} ...]'.format( 74 | ' '.join(itertools.repeat(metavar, nargs[0])), 75 | ' '.join(itertools.repeat(metavar, nargs[1] - nargs[0]))) 76 | 77 | 78 | 79 | class CombinedCustomHelpFormatter(ChoicesRangeHelpFormatter, NargsRangeHelpFormatter): 80 | 81 | _expand_help = ChoicesRangeHelpFormatter._expand_help 82 | 83 | _format_args = NargsRangeHelpFormatter._format_args 84 | -------------------------------------------------------------------------------- /src/schema_matching/utilities/distribution.py: -------------------------------------------------------------------------------- 1 | import numbers, array, itertools, operator, math 2 | from collections import defaultdict 3 | from math import fsum 4 | from .misc import minmax2 5 | from .string import join, format_char 6 | 7 | 8 | 9 | default_number_format = '.3g' 10 | 11 | 12 | 13 | class DistributionTable(object): 14 | 15 | def count(self): 16 | return NotImplemented 17 | 18 | 19 | def __truediv__(self, divisor): 20 | return NotImplemented 21 | 22 | 23 | def __str__(self): 24 | return self.__format__(default_number_format) 25 | 26 | 27 | def normalize(self, count=None): 28 | if count is None: 29 | count = self.count() 30 | return self / count 31 | 32 | 33 | 34 | class SparseDistributionTable(DistributionTable, defaultdict): 35 | """"Holds a probability distribution and can compute the distance to other dists""" 36 | 37 | def __init__(self, type=int, *args): 38 | """ 39 | :param type: type 40 | :param args: * 41 | :return: 42 | """ 43 | assert issubclass(type, numbers.Real) 44 | DistributionTable.__init__(self) 45 | defaultdict.__init__(self, type, *args) 46 | 47 | 48 | def distance_to(self, other): 49 | return fsum((abs(p - other[bin]) for bin, p in self.items())) + \ 50 | fsum(p for bin, p in other.items() if bin not in self) 51 | 52 | 53 | def count(self): 54 | return sum(self.values()) 55 | 56 | 57 | def increase(self, item, value=1): 58 | self[item] += value 59 | 60 | 61 | def __truediv__(self, divisor): 62 | """ 63 | :param divisor: numbers.Real 64 | :return: SparseDistributionTable 65 | """ 66 | divisor = float(divisor) 67 | return SparseDistributionTable(float, 68 | ((k, v / divisor) for k, v in self.items())) 69 | 70 | 71 | def __format__(self, number_format_spec=''): 72 | return join('(', 73 | ', '.join(( 74 | '{}: {:{}}'.format(format_char(event), frequency, number_format_spec) 75 | for event, frequency in self.items())), 76 | ')') 77 | 78 | 79 | 80 | class UniformBinDistributionTable(DistributionTable): 81 | 82 | def __init__(self, start, stop, bincount=None, datatype=None, initializer=None): 83 | super().__init__() 84 | 85 | assert stop > start 86 | if bincount is None: 87 | bincount = int(math.ceil(stop - start)) 88 | assert isinstance(bincount, numbers.Integral) and bincount >= 1 89 | self.lower = start 90 | self.upper = stop 91 | self.step = (stop - start) / bincount 92 | if self.__step.is_integer(): 93 | self.__step = int(self.__step) 94 | 95 | if initializer is None: 96 | initializer = itertools.repeat(0, bincount) 97 | self.data = list(initializer) if datatype is None else array.array(datatype, initializer) 98 | excess = len(self.data) - bincount 99 | if excess > 0: 100 | del self.data[bincount:] 101 | elif excess < 0: 102 | self.data.extend(itertools.repeat(0, -excess)) 103 | 104 | 105 | @property 106 | def step(self): 107 | return self.__step 108 | 109 | 110 | @step.setter 111 | def step(self, value): 112 | self.__step = value 113 | self.__invstep = 1. / value 114 | 115 | 116 | @property 117 | def invstep(self): 118 | return self.__invstep 119 | 120 | 121 | def datatype(self): 122 | return self.data.typecode if isinstance(self.data, array.array) else None 123 | 124 | 125 | def getbinlower(self, binidx): 126 | return binidx * self.__step + self.lower 127 | 128 | 129 | def getbinupper(self, binidx): 130 | return self.getbinlower(binidx + 1) 131 | 132 | 133 | def getbinlimits(self, binidx): 134 | return self.getbinlower(binidx), self.getbinupper(binidx) 135 | 136 | 137 | def getbinidx(self, key): 138 | if key <= self.lower: 139 | return 0 140 | if key >= self.upper: 141 | return len(self.data) - 1 142 | else: 143 | return self.__getbinidx_raw(key) 144 | 145 | 146 | def __getbinidx_raw(self, key): 147 | return int((key - self.lower) * self.__invstep) 148 | 149 | 150 | def __getitem__(self, key): 151 | return self.data[self.getbinidx(key)] 152 | 153 | 154 | def __setitem__(self, key, value): 155 | self.data[self.getbinidx(key)] = value 156 | 157 | 158 | def increase(self, key, value=1): 159 | self.data[self.getbinidx(key)] += value 160 | 161 | 162 | def __len__(self): 163 | return len(self.data) 164 | 165 | 166 | def __iter__(self): 167 | return iter(self.data) 168 | 169 | 170 | def count(self): 171 | return sum(self) 172 | 173 | 174 | def __truediv__(self, divisor): 175 | return UniformBinDistributionTable(self.lower, self.upper, len(self.data), 'd', 176 | map(float(divisor).__rtruediv__, self.data)) 177 | 178 | 179 | def distance_to(self, other): 180 | """ 181 | :param other: UniformBinDistributionTable 182 | :return: float 183 | """ 184 | if isinstance(other, UniformBinDistributionTable): 185 | if self.lower == other.lower and self.upper == other.upper and self.__step == other.__step: 186 | other = other.data 187 | else: 188 | return self.__distance_to2(other) 189 | 190 | assert not hasattr(other, '__len__') or len(self.data) == len(other) 191 | return fsum(map(abs, map(operator.sub, self.data, other))) 192 | 193 | 194 | def __distance_to2(self, other): 195 | return ( 196 | UniformBinDistributionTable.__distance_to2_lower( 197 | *minmax2(self, other, 'lower')) + 198 | UniformBinDistributionTable.__distance_to2_upper( 199 | *minmax2(self, other, 'upper', True)) + 200 | fsum(UniformBinDistributionTable.__distance_to2_middle_parts( 201 | *minmax2(self, other, 'step')))) 202 | 203 | 204 | def __distance_to2_middle_parts(self, other): 205 | assert self.__step <= other.__step 206 | assert self.lower < self.upper and other.lower < other.upper 207 | 208 | lower = max(self.lower, other.lower) 209 | self_binidx = self.__getbinidx_raw(lower) 210 | self_binlimits_next = self.getbinlimits(self_binidx) 211 | other_binidx = other.__getbinidx_raw(lower) 212 | other_binlimits = other.getbinlimits(other_binidx) 213 | 214 | while self_binidx < len(self.data) and other_binidx < len(other.data): 215 | self_binlimits = self_binlimits_next 216 | yield abs((self.data[self_binidx] * self.__invstep) - (other.data[other_binidx] * other.__invstep)) * \ 217 | (min(self_binlimits[1], other_binlimits[1]) - max(self_binlimits[0], other_binlimits[0])) 218 | 219 | if self_binlimits[1] <= other_binlimits[1]: 220 | self_binidx += 1 221 | self_binlimits_next = self.getbinlimits(self_binidx) 222 | if self_binlimits[1] >= other_binlimits[1]: 223 | other_binidx += 1 224 | other_binlimits = other.getbinlimits(other_binidx) 225 | 226 | 227 | def __distance_to2_lower(self, other): 228 | """ 229 | :param other: UniformBinDistributionTable 230 | :return: float 231 | """ 232 | assert self.lower <= other.lower 233 | lower_bin_end = ( 234 | self.__getbinidx_raw(other.lower) 235 | if self.upper > other.lower else 236 | len(self.data)) 237 | lower = fsum(itertools.islice(self.data, 0, lower_bin_end)) 238 | if lower_bin_end < len(self.data): 239 | lower += self.data[lower_bin_end] * self.__invstep * \ 240 | (other.lower - self.getbinlower(lower_bin_end)) 241 | return lower 242 | 243 | 244 | def __distance_to2_upper(self, other): 245 | """ 246 | :param other: UniformBinDistributionTable 247 | :return: float 248 | """ 249 | assert self.upper >= other.upper 250 | upper_bin_start = ( 251 | self.__getbinidx_raw(other.upper) 252 | if self.lower < other.upper else 253 | 0) 254 | upper = fsum(itertools.islice(self.data, upper_bin_start + 1, len(self.data))) 255 | if upper_bin_start < len(self.data): 256 | upper += self.data[upper_bin_start] * self.__invstep * \ 257 | (self.getbinupper(upper_bin_start) - other.upper) 258 | return upper 259 | 260 | 261 | def __format__(self, number_format_spec=''): 262 | return join('[', 263 | ', '.join(( 264 | '[{2:{0}}-{3:{0}}): {1:{0}}'.format( 265 | number_format_spec, frequency, *self.getbinlimits(bin_idx)) 266 | for bin_idx, frequency in enumerate(self))), 267 | ']') 268 | 269 | 270 | @staticmethod 271 | def for_count(count, lower, upper, *args): 272 | """ uses Sturge's rule: ceil(1 + log2(count)) """ 273 | return UniformBinDistributionTable( 274 | lower, upper, _sturges_rule(count), *args) 275 | 276 | 277 | @staticmethod 278 | def for_variance(count, lower, upper, variance, *args): 279 | """ uses Scott's rule, limited by the double of Sturge's """ 280 | h = int(math.ceil(3.49 * math.sqrt(variance) / _cubicroot(count))) 281 | return UniformBinDistributionTable( 282 | lower, upper, min(h, 2 * _sturges_rule(count)), *args) 283 | 284 | 285 | @staticmethod 286 | def for_quartiles(count, lower, upper, q1, q3, *args): 287 | """ uses Freedman's and Diaconis' rule """ 288 | h = int(math.ceil(2.0 * (q3 - q1) / _cubicroot(count))) 289 | return UniformBinDistributionTable( 290 | lower, upper, min(h, 2 * _sturges_rule(count)), *args) 291 | 292 | 293 | 294 | def _sturges_rule(n): 295 | assert isinstance(n, numbers.Integral) and n > 0 296 | return (n - 1).bit_length() + 1 297 | 298 | 299 | def _cubicroot(x): 300 | return x ** (1. / 3.) 301 | -------------------------------------------------------------------------------- /src/schema_matching/utilities/functional.py: -------------------------------------------------------------------------------- 1 | __all__ = ('memberfn', 'composefn', 'partialfn', 'reduce') 2 | 3 | from .operator import identity 4 | from operator import methodcaller 5 | from itertools import starmap 6 | from functools import reduce, partial as partialfn 7 | import inspect 8 | 9 | 10 | 11 | class memberfn: 12 | """Binds arguments for instance(-like) method calls. 13 | 14 | Instances of this class are callable and pass their single positional 15 | argument as the first positional argument to the wrapped function followed by 16 | the other arguments given during instantiation.""" 17 | 18 | __slots__ = ('func', 'args', 'kwargs') 19 | 20 | 21 | def __new__(cls, func, *args, **kwargs): 22 | if not callable(func): 23 | return methodcaller(func, *args, **kwargs) 24 | if not args and not kwargs: 25 | return func 26 | return super().__new__(cls) 27 | 28 | 29 | def __init__(self, func, *args, **kwargs): 30 | self.func = func 31 | self.args = args 32 | self.kwargs = kwargs 33 | 34 | 35 | def __call__(self, obj): 36 | return self.func(obj, *self.args, **self.kwargs) 37 | 38 | 39 | def __repr__(self): 40 | return '{:s}({:s})'.format( 41 | type(self).__qualname__, 42 | ', '.join(( 43 | func_repr(self.func), *map(repr, self.args), 44 | *starmap('{:s}={!r}'.format, self.kwargs.items())))) 45 | 46 | 47 | class composefn: 48 | """A function object that concatenates the passed functions from left to 49 | right. 50 | """ 51 | 52 | __slots__ = ('funcs',) 53 | 54 | 55 | def __new__(cls, *funcs): 56 | assert all(map(callable, funcs)) 57 | if len(funcs) > 1: 58 | return super().__new__(cls) 59 | if funcs: 60 | return funcs[0] 61 | return identity 62 | 63 | 64 | def __init__(self, *funcs): 65 | self.funcs = funcs 66 | 67 | 68 | def __call__(self, *args, **kwargs): 69 | funcs = iter(self.funcs) 70 | args = next(funcs, identity)(*args, **kwargs) 71 | del kwargs 72 | for f in funcs: 73 | args = f(args) 74 | return args 75 | 76 | 77 | def __repr__(self): 78 | return '{:s}({:s})'.format( 79 | type(self).__qualname__, ', '.join(tuple(map(func_repr, self.funcs)))) 80 | 81 | 82 | def func_repr(func): 83 | if isinstance(func, type) or inspect.isroutine(func): 84 | func_module = getattr( 85 | getattr(func, '__objclass__', func), '__module__', None) 86 | if func_module is not None: 87 | if func_module == 'builtins': 88 | return func.__qualname__ 89 | return '.'.join((func_module, func.__qualname__)) 90 | return repr(func) 91 | -------------------------------------------------------------------------------- /src/schema_matching/utilities/iterator.py: -------------------------------------------------------------------------------- 1 | import itertools, operator, collections.abc 2 | from . import functional as ufunctional 3 | 4 | 5 | if __debug__: 6 | import builtins 7 | 8 | def map(*args): 9 | return tuple(builtins.map(*args)) 10 | 11 | def zip(*args): 12 | return tuple(builtins.zip(*args)) 13 | 14 | def filter(function, iterable): 15 | return tuple(builtins.filter(function, iterable)) 16 | 17 | def filterfalse(function, iterable): 18 | return tuple(itertools.filterfalse(function, iterable)) 19 | 20 | else: 21 | from builtins import map, filter, zip 22 | from itertools import filterfalse 23 | 24 | 25 | 26 | __iterator_cookie = object() 27 | 28 | 29 | def each(function, *iterables): 30 | if not iterables: 31 | return 32 | elif len(iterables) == 1: 33 | for args in iterables[0]: 34 | function(args) 35 | else: 36 | stareach(function, zip(*iterables)) 37 | 38 | 39 | def stareach(function, iterable): 40 | for args in iterable: 41 | function(*args) 42 | 43 | 44 | def consume(iterable): 45 | iterator = iter(iterable) 46 | while next(iterator, __iterator_cookie) is not __iterator_cookie: 47 | pass 48 | 49 | 50 | def __slice_to_tuple(slice): 51 | return (slice.start, slice.stop, slice.step) 52 | 53 | 54 | def islice(iterable, *args): 55 | if not args: 56 | args = (None,) 57 | elif len(args) == 1 and isinstance(args[0], slice): 58 | args = __slice_to_tuple(args[0]) 59 | return itertools.islice(iterable, *args) 60 | 61 | 62 | def map_inplace(function, list, depth=0, slice=None): 63 | if depth <= 0: 64 | if slice is None: 65 | list[:] = map(function, list) 66 | else: 67 | list[slice] = map(function, 68 | itertools.islice(list, slice.start, slice.stop, slice.step)) 69 | else: 70 | for item in list: 71 | map_inplace(function, item, depth - 1, slice) 72 | return list 73 | 74 | 75 | def countif(function, *iterables): 76 | return sum(map(bool, itertools.starmap(function, *iterables))) 77 | 78 | 79 | def teemap(iterable, *functions): 80 | return map(lambda item: [item if f is None else f(item) for f in functions], iterable) 81 | 82 | 83 | def issorted(iterable, key=None, reverse=False): 84 | if key is not None: 85 | iterable = map(key, iterable) 86 | it = iter(iterable) 87 | last_item_key = next(it, __iterator_cookie) 88 | if last_item_key is not __iterator_cookie: 89 | not_in_order = operator.lt if reverse else operator.gt 90 | for item_key in it: 91 | if not_in_order(last_item_key, item_key): 92 | return False 93 | last_item_key = item_key 94 | return True 95 | 96 | 97 | def order(sequence, key=None, reverse=False): 98 | key2 = sequence.__getitem__ 99 | if key is not None: 100 | key2 = ufunctional.composefn(key2, key) 101 | return sorted(range(len(sequence)), key=key2, reverse=reverse) 102 | 103 | 104 | def sorted_with_order(iterable, key=None, reverse=False, inplace=False): 105 | if not inplace: 106 | iterable = list(iterable) 107 | else: 108 | assert callable(getattr(iterable, '__setitem__', None)) 109 | _order = order(iterable, key, reverse) 110 | iterable[:] = sort_by_order(iterable, _order) 111 | return _order, iterable 112 | 113 | 114 | def sort_by_order(sequence, order): 115 | if __debug__: 116 | if not isinstance(order, collections.abc.Sized): 117 | order = tuple(order) 118 | assert \ 119 | all(map((0).__le__, order)) and all(map(len(sequence).__gt__, order)) 120 | 121 | return map(sequence.__getitem__, order) 122 | -------------------------------------------------------------------------------- /src/schema_matching/utilities/misc.py: -------------------------------------------------------------------------------- 1 | import operator 2 | from . import operator as uoperator 3 | 4 | 5 | infinity = float('inf') 6 | NaN = float('NaN') 7 | 8 | 9 | def minmax(*args, **kwargs): 10 | keyfn = kwargs.get('key') 11 | if isinstance(keyfn, str): 12 | keyfn = operator.attrgetter(keyfn) 13 | 14 | iterator = iter(args if len(args) > 1 else args[0]) 15 | min_item = next(iterator) 16 | max_item = min_item 17 | if keyfn is None: 18 | for item in iterator: 19 | if max_item < item: 20 | max_item = item 21 | elif item < min_item: 22 | min_item = item 23 | else: 24 | min_value = keyfn(min_item) 25 | max_value = min_value 26 | for item in iterator: 27 | value = keyfn(item) 28 | if max_value < value: 29 | max_value = value 30 | max_item = item 31 | elif value < min_value: 32 | min_value = value 33 | min_item = item 34 | return min_item, max_item 35 | 36 | 37 | def minmax2(a, b, key=uoperator.identity, reverse=False): 38 | """Guarantees the return of two distinct values iff a is not b.""" 39 | if isinstance(key, str): 40 | key = operator.attrgetter(key) 41 | return (a, b) if (key(a) <= key(b)) is not reverse else (b, a) 42 | 43 | 44 | def sliceout(sequence, start, end=None): 45 | if end is None: 46 | end = start + 1 47 | return sequence[:start] + sequence[end:] 48 | 49 | 50 | def starmap(function, iterable): 51 | return [function(*item) for item in iterable] 52 | 53 | 54 | def issubset(iterable, set): 55 | return all(map(set.__contains__, iterable)) 56 | 57 | 58 | def rdict(d): 59 | if isinstance(d, dict): 60 | d = d.items() 61 | if __debug__: 62 | d = frozenset(d) 63 | rdict = {v: k for k, v in d} 64 | assert len(rdict) == len(d) # future keys should be unique 65 | return rdict 66 | 67 | 68 | def min_index(*args, **kwargs): 69 | key = kwargs.get('key') 70 | kwargs['key'] = args.__getitem__ if key is None else lambda idx: key(args[idx]) 71 | return min(*range(len(args)), **kwargs) 72 | 73 | 74 | class NonLocal: 75 | 76 | def __init__(self, value=None): 77 | self.value = value 78 | 79 | 80 | def setattr_default(obj, attr, value): 81 | try: 82 | value = getattr(obj, attr) 83 | except AttributeError: 84 | setattr(obj, attr, value) 85 | return value 86 | -------------------------------------------------------------------------------- /src/schema_matching/utilities/operator.py: -------------------------------------------------------------------------------- 1 | def first(sequence): 2 | return sequence[0] 3 | 4 | 5 | def second(sequence): 6 | return sequence[1] 7 | 8 | 9 | def isnone(x): 10 | return x is None 11 | 12 | 13 | def identity(x): 14 | return x 15 | 16 | 17 | def noop(): 18 | pass 19 | 20 | 21 | def square(x): 22 | return x * x 23 | -------------------------------------------------------------------------------- /src/schema_matching/utilities/string.py: -------------------------------------------------------------------------------- 1 | import unicodedata 2 | 3 | 4 | 5 | basestring = (str, bytes) 6 | 7 | 8 | def isprint(c): 9 | return unicodedata.category(c)[0] not in 'CZ' 10 | 11 | 12 | _char_replacement_sequences = { 13 | ' ': '', 14 | '\n': r'\n', 15 | '\r': r'\r', 16 | '\t': r'\t', 17 | '\v': r'\v', 18 | '\0': r'\0', 19 | '\a': r'\a', 20 | '\b': r'\b', 21 | '\f': r'\f' 22 | } 23 | 24 | def format_char(item): 25 | if isinstance(item, basestring): 26 | assert len(item) == 1 27 | rs = _char_replacement_sequences.get(item) 28 | if rs is not None: 29 | return rs 30 | if isprint(item): 31 | assert len(format(item, '')) 32 | return item 33 | else: 34 | code = ord(item) 35 | return \ 36 | ('\\u{:04x}' if code >= 0x80 and isinstance(item, str) else '\\x{:02x}') \ 37 | .format(code) 38 | else: 39 | return item 40 | 41 | 42 | def join(*args): 43 | return ''.join(args) 44 | -------------------------------------------------------------------------------- /src/schema_matching/utilities/timelimit.py: -------------------------------------------------------------------------------- 1 | import sys, signal 2 | 3 | if __debug__: 4 | from timeit import default_timer as _timer 5 | else: 6 | _timer = None 7 | 8 | 9 | 10 | class Timelimit(object): 11 | 12 | interrupted_flag = None 13 | 14 | 15 | def __init__(self, seconds): 16 | super().__init__() 17 | self.seconds = seconds 18 | 19 | 20 | def __enter__(self): 21 | if self.seconds > 0: 22 | if self.interrupted_flag is not None: 23 | raise RuntimeError("Multiple time limits aren't supported") 24 | self.interrupted_flag = False 25 | signal.signal(signal.SIGALRM, self.__timeout_handler) 26 | if signal.alarm(self.seconds): 27 | raise RuntimeError('Who set the alarm before us?!!') 28 | return self 29 | 30 | 31 | def __exit__(self, exc_type, exc_val, exc_tb): 32 | if self.interrupted_flag: 33 | print( 34 | 'The time limit of {} seconds was reached. The results may be ' 35 | 'incomplete or inaccurate.'.format(self.seconds), 36 | file=sys.stderr) 37 | if _timer: 38 | print('INFO:', _timer() - self.interrupted_flag, 39 | 'seconds between interruption and program termination.', 40 | file=sys.stderr) 41 | 42 | assert self.interrupted_flag is not None or not self.seconds 43 | self.interrupted_flag = None 44 | 45 | 46 | @classmethod 47 | def __timeout_handler(cls, signum, frame): 48 | if signum == signal.SIGALRM: 49 | if _timer: 50 | cls.interrupted_flag = _timer() 51 | else: 52 | cls.interrupted_flag = True 53 | -------------------------------------------------------------------------------- /tests/utilities/test_distribution.py: -------------------------------------------------------------------------------- 1 | import unittest, copy 2 | from utilities.distribution import UniformBinDistributionTable 3 | 4 | 5 | 6 | class UniformBinDistributionTableDistanceTestCase(unittest.TestCase): 7 | 8 | def setUp(self): 9 | self.data1 = (1, 0, 5, 1, 3) 10 | self.dist1 = UniformBinDistributionTable( 11 | 0, len(self.data1), None, None, self.data1) 12 | assert len(self.dist1) == len(self.data1) 13 | 14 | self.data2 = (2, 1, 0, 4, 3, 2, 1, 0, 5) 15 | lower2 = 0.8 16 | step2 = 0.4 17 | self.dist2 = UniformBinDistributionTable( 18 | lower2, lower2 + step2 * len(self.data2), len(self.data2), None, self.data2) 19 | assert len(self.dist2) == len(self.data2) 20 | assert abs(self.dist2.step - step2) < 1e-7 21 | self.dist2.step = step2 22 | 23 | 24 | def __do_test(self, a, b, expected): 25 | self.assertAlmostEqual(a.distance_to(b), expected) 26 | 27 | 28 | def test_to_self(self): 29 | self.__do_test(self.dist1, self.dist1, 0) 30 | 31 | 32 | def test_isomorph(self): 33 | dist3 = copy.copy(self.dist1) 34 | dist3.data = list(map((1).__add__, self.dist1.data)) 35 | self.__do_test(self.dist1, dist3, len(self.dist1)) 36 | 37 | 38 | def test_disjoint1(self): 39 | dist3 = copy.copy(self.dist1) 40 | dist3.lower = self.dist1.upper 41 | dist3.upper = dist3.lower + (self.dist1.upper - self.dist1.lower) 42 | self.__do_test(self.dist1, dist3, 2 * sum(self.data1)) 43 | 44 | 45 | def test_disjoint2(self): 46 | dist3 = copy.copy(self.dist1) 47 | dist3.upper = self.dist1.lower 48 | dist3.lower = -self.dist1.upper 49 | self.__do_test(self.dist1, dist3, 2 * sum(self.data1)) 50 | 51 | 52 | def test_intersecting1(self): 53 | dist3 = copy.copy(self.dist1) 54 | dist3.lower += 2 55 | dist3.upper += 2 56 | # 1: 1, 0, 5, 1, 3 57 | # 2: 1, 0, 5, 1, 3 58 | self.__do_test(self.dist1, dist3, 1 + 0 + 4 + 1 + 2 + 1 + 3) 59 | 60 | 61 | def test_intersecting2(self): 62 | dist3 = copy.copy(self.dist1) 63 | dist3.lower -= 1 64 | dist3.upper -= 1 65 | # 1: 1, 0, 5, 1, 3 66 | # 2: 1, 0, 5, 1, 3 67 | self.__do_test(self.dist1, dist3, 1 + 1 + 5 + 4 + 2 + 3) 68 | 69 | 70 | def test_contained(self): 71 | dist3 = copy.copy(self.dist1) 72 | dist3.lower += 1 73 | dist3.step /= 2 74 | dist3.upper = dist3.lower + len(dist3) * dist3.step 75 | self.__do_test(self.dist1, dist3, 12) 76 | 77 | 78 | def test_asynchronous_bins1(self): 79 | dist3 = copy.copy(self.dist1) 80 | dist3.lower += 0.5 81 | dist3.upper += 0.5 82 | # 1: 1, 0, 5, 1, 3 83 | # 2: 1, 0, 5, 1, 3 84 | expected = .5*1 + (.5*1-.5*1) + (.5*1-.5*0) + (.5*0-.5*0) + (.5*5-.5*0) + (.5*5-.5*5) + (.5*5-.5*1) + (.5*1-.5*1) + (.5*3-.5*1) + (.5*3-.5*3) + .5*3 85 | self.__do_test(self.dist1, dist3, expected) 86 | 87 | 88 | def test_asynchronous_bins2(self): 89 | dist3 = copy.copy(self.dist1) 90 | dist3.lower += 0.4 91 | dist3.upper += 0.4 92 | self.__do_test(self.dist1, dist3, 6.4) 93 | 94 | 95 | def test_asynchronous_steps(self): 96 | self.__do_test(self.dist1, self.dist2, 14) 97 | 98 | 99 | 100 | if __name__ == '__main__': 101 | unittest.main() 102 | --------------------------------------------------------------------------------