├── .github ├── CODEOWNERS ├── PULL_REQUEST_TEMPLATE └── workflows │ ├── codeql-analysis.yml │ ├── python-publish.yml │ └── python-test.yml ├── .gitignore ├── .pep8speaks.yml ├── .pre-commit-config.yaml ├── .readthedocs.yml ├── .zenodo.json ├── CHANGELOG.md ├── CONTRIBUTORS ├── LICENSE.txt ├── MANIFEST.in ├── README.rst ├── WrightTools ├── CITATION ├── VERSION ├── WT5_VERSION ├── __citation__.py ├── __init__.py ├── __version__.py ├── __wt5_version__.py ├── _close.py ├── _dataset.py ├── _group.py ├── _open.py ├── artists │ ├── __init__.py │ ├── _base.py │ ├── _colors.py │ ├── _helpers.py │ ├── _interact.py │ └── _quick.py ├── cli │ ├── __init__.py │ ├── _units.py │ └── _wt5.py ├── collection │ ├── .gitignore │ ├── __init__.py │ ├── _cary.py │ ├── _collection.py │ └── _directory.py ├── data │ ├── __init__.py │ ├── _aramis.py │ ├── _axis.py │ ├── _brunold.py │ ├── _channel.py │ ├── _colors.py │ ├── _constant.py │ ├── _data.py │ ├── _databroker.py │ ├── _jasco.py │ ├── _join.py │ ├── _kent.py │ ├── _labram.py │ ├── _ocean_optics.py │ ├── _pycmds.py │ ├── _shimadzu.py │ ├── _solis.py │ ├── _spcm.py │ ├── _tensor27.py │ └── _variable.py ├── datasets │ ├── .gitignore │ ├── BrunoldrRaman │ │ └── LDS821_514nm_80mW.txt │ ├── COLORS │ │ ├── .gitignore │ │ ├── v0.0 │ │ │ └── .gitignore │ │ ├── v0.1 │ │ │ └── .gitignore │ │ ├── v0.2 │ │ │ └── d1_d2 diagonal.dat │ │ ├── v1.0 │ │ │ └── .gitignore │ │ ├── v2.0 │ │ │ └── .gitignore │ │ ├── v2.1 │ │ │ └── .gitignore │ │ └── v2.2 │ │ │ └── WL_wigner.dat │ ├── Cary │ │ ├── CuPCtS_H2O_vis.csv │ │ └── filters.csv │ ├── JASCO │ │ ├── PbSe batch 1.txt │ │ ├── PbSe batch 4 2012-02-21.txt │ │ └── PbSe batch 4 2012-03-15.txt │ ├── KENT │ │ ├── .gitignore │ │ ├── LDS821 DOVE │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_1 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_10 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_11 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_12 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_13 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_14 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_15 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_16 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_17 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_18 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_19 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_2 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_20 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_21 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_22 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_23 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_24 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_25 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_26 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_27 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_28 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_29 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_3 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_30 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_31 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_32 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_33 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_34 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_35 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_36 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_37 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_38 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_39 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_4 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_40 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_41 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_42 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_43 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_44 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_45 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_46 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_47 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_48 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_49 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_5 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_50 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_51 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_52 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_53 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_54 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_55 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_56 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_57 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_58 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_59 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_6 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_60 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_7 │ │ │ ├── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_8 │ │ │ └── w1w2wm_d1eff_3_d2eff_1_LDS_DOVE_Largescan_9 │ │ ├── LDS821 TRSF │ │ │ ├── 001 │ │ │ ├── 002 │ │ │ ├── 003 │ │ │ ├── 004 │ │ │ ├── 005 │ │ │ ├── 006 │ │ │ ├── 007 │ │ │ ├── 008 │ │ │ ├── 009 │ │ │ ├── 010 │ │ │ ├── 011 │ │ │ ├── 012 │ │ │ ├── 013 │ │ │ ├── 014 │ │ │ ├── 015 │ │ │ ├── 016 │ │ │ ├── 017 │ │ │ ├── 018 │ │ │ ├── 019 │ │ │ ├── 020 │ │ │ ├── 021 │ │ │ ├── 022 │ │ │ ├── 023 │ │ │ ├── 024 │ │ │ ├── 025 │ │ │ ├── 026 │ │ │ ├── 027 │ │ │ ├── 028 │ │ │ ├── 029 │ │ │ ├── 030 │ │ │ ├── 031 │ │ │ ├── 032 │ │ │ ├── 033 │ │ │ ├── 034 │ │ │ ├── 035 │ │ │ ├── 036 │ │ │ ├── 037 │ │ │ ├── 038 │ │ │ ├── 039 │ │ │ ├── 040 │ │ │ ├── 041 │ │ │ ├── 042 │ │ │ ├── 043 │ │ │ ├── 044 │ │ │ ├── 045 │ │ │ ├── 046 │ │ │ ├── 047 │ │ │ ├── 048 │ │ │ ├── 049 │ │ │ ├── 050 │ │ │ ├── 051 │ │ │ ├── 052 │ │ │ ├── 053 │ │ │ ├── 054 │ │ │ ├── 055 │ │ │ ├── 056 │ │ │ ├── 057 │ │ │ ├── 058 │ │ │ ├── 059 │ │ │ ├── 060 │ │ │ ├── 061 │ │ │ ├── 062 │ │ │ ├── 063 │ │ │ ├── 064 │ │ │ ├── 065 │ │ │ ├── 066 │ │ │ ├── 067 │ │ │ ├── 068 │ │ │ ├── 069 │ │ │ ├── 070 │ │ │ └── 071 │ │ └── PbSe 2D delay B │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_1 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_10 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_100 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_101 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_11 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_12 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_13 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_14 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_15 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_16 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_17 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_18 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_19 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_2 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_20 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_21 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_22 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_23 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_24 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_25 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_26 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_27 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_28 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_29 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_3 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_30 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_31 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_32 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_33 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_34 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_35 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_36 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_37 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_38 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_39 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_4 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_40 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_41 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_42 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_43 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_44 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_45 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_46 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_47 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_48 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_49 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_5 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_50 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_51 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_52 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_53 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_54 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_55 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_56 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_57 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_58 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_59 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_6 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_60 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_61 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_62 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_63 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_64 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_65 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_66 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_67 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_68 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_69 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_7 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_70 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_71 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_72 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_73 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_74 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_75 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_76 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_77 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_78 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_79 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_8 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_80 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_81 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_82 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_83 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_84 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_85 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_86 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_87 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_88 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_89 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_9 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_90 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_91 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_92 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_93 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_94 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_95 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_96 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_97 │ │ │ ├── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_98 │ │ │ └── D1_D2__w1w2wm_7000_2VL_1V_versmallstep_200shots_99 │ ├── LabRAM │ │ ├── map_nm.txt.gz │ │ ├── raman_linescan.txt.gz │ │ ├── spectrum_nm.txt.gz │ │ ├── spectrum_wn.txt.gz │ │ └── survey_nm.txt.gz │ ├── PyCMDS │ │ ├── d1 d2 000.data │ │ ├── d1 d2 001.data │ │ ├── w1 000.data │ │ ├── w1 wa 000.data │ │ ├── w2 w1 000.data │ │ ├── wm w2 w1 000.data │ │ └── wm w2 w1 001.data │ ├── Shimadzu │ │ └── MoS2_fromCzech2015.txt │ ├── Solis │ │ ├── kinetic.asc.gz │ │ ├── wm ypos fluorescence with filter.asc.gz │ │ └── xpos ypos fluorescence.asc.gz │ ├── Tensor27 │ │ └── CuPCtS_powder_ATR.dpt │ ├── __init__.py │ ├── ocean_optics │ │ └── tsunami.scope │ ├── spcm │ │ ├── test_data.asc │ │ └── test_data_full_metadata.asc │ └── wt5 │ │ ├── v1.0.0 │ │ └── perovskite_TA.wt5 │ │ └── v1.0.1 │ │ └── MoS2_TrEE_movie.wt5 ├── diagrams │ ├── WMEL.py │ ├── __init__.py │ └── delay.py ├── exceptions.py ├── kit │ ├── __init__.py │ ├── _array.py │ ├── _calculate.py │ ├── _discover_dimensions.py │ ├── _glob.py │ ├── _ini.py │ ├── _interpolate.py │ ├── _leastsq.py │ ├── _lineshapes.py │ ├── _list.py │ ├── _path.py │ ├── _timestamp.py │ ├── _unicode.py │ └── _utilities.py └── units.py ├── docs ├── .gitignore ├── Makefile ├── _static │ ├── .gitignore │ ├── v2p1_MoS2_TrEE_movie.gif │ ├── v2p1_MoS2_TrEE_movie.py │ └── v2p1_MoS2_TrEE_movie │ │ ├── MoS2 000.png │ │ ├── MoS2 001.png │ │ ├── MoS2 002.png │ │ ├── MoS2 003.png │ │ ├── MoS2 004.png │ │ ├── MoS2 005.png │ │ ├── MoS2 006.png │ │ ├── MoS2 007.png │ │ ├── MoS2 008.png │ │ ├── MoS2 009.png │ │ ├── MoS2 010.png │ │ ├── MoS2 011.png │ │ ├── MoS2 012.png │ │ ├── MoS2 013.png │ │ ├── MoS2 014.png │ │ ├── MoS2 015.png │ │ ├── MoS2 016.png │ │ ├── MoS2 017.png │ │ ├── MoS2 018.png │ │ ├── MoS2 019.png │ │ ├── MoS2 020.png │ │ ├── MoS2 021.png │ │ └── MoS2 022.png ├── alternatives.rst ├── api │ ├── .gitignore │ ├── WrightTools.artists.Axes.rst │ ├── WrightTools.artists.Figure.rst │ ├── WrightTools.artists.GridSpec.rst │ ├── WrightTools.artists.rst │ ├── WrightTools.collection.Collection.rst │ ├── WrightTools.collection.rst │ ├── WrightTools.data.Axis.rst │ ├── WrightTools.data.Channel.rst │ ├── WrightTools.data.Constant.rst │ ├── WrightTools.data.Data.rst │ ├── WrightTools.data.Variable.rst │ ├── WrightTools.data.rst │ ├── WrightTools.datasets.rst │ ├── WrightTools.diagrams.WMEL.rst │ ├── WrightTools.diagrams.delay.rst │ ├── WrightTools.diagrams.rst │ ├── WrightTools.exceptions.rst │ ├── WrightTools.kit.INI.rst │ ├── WrightTools.kit.Spline.rst │ ├── WrightTools.kit.TimeStamp.rst │ ├── WrightTools.kit.Timer.rst │ ├── WrightTools.kit.rst │ ├── WrightTools.open.rst │ ├── WrightTools.units.rst │ └── modules.rst ├── artists.rst ├── citation.rst ├── cli.rst ├── collection.rst ├── conf.py ├── contributing.rst ├── data.rst ├── datasets.rst ├── index.rst ├── install.rst ├── make.bat ├── quickstart.rst ├── units.rst ├── write_from_function.rst └── wt5.rst ├── examples ├── DOVE_transform.py ├── README.txt ├── colormaps.py ├── custom_fig.py ├── fill_types.py ├── filters.py ├── fringes_transform.py ├── gradient.py ├── heal.py ├── join.py ├── label_delay_space.py ├── level.py ├── lineshapes.py ├── map-variable.py ├── moment_sideplot.py ├── plot_colormap_components.py ├── quick1D.py ├── quick2D.py ├── quick2D_signed.py ├── rRaman.py ├── split.py ├── tune_test.py ├── wmels_trive_off_diagonal.py ├── wmels_trive_on_diagonal.py ├── wmels_trive_population_transfer.py └── wt for np users.ipynb ├── logo ├── .gitignore ├── logo.png ├── logo.py └── peak.h5 ├── paper ├── .gitignore ├── build.sh ├── paper.bib └── paper.md ├── requirements.txt ├── scripts ├── .gitignore └── checklists.org ├── setup.cfg ├── setup.py └── tests ├── .gitignore ├── __init__.py ├── artists ├── test_contour.py ├── test_imshow.py ├── test_interact2D.py ├── test_pcolor.py ├── test_plot.py ├── test_quick1D.py ├── test_quick2D.py └── test_scatter.py ├── base.py ├── citation.py ├── collection ├── collection.py ├── convert.py ├── from_cary.py └── from_directory.py ├── data ├── __init__.py ├── at.py ├── axis │ ├── convert_axis.py │ └── expressions.py ├── bluesky_data │ └── 3dbdd402-434b-4aac-b004-447a2f026d73.msgpack ├── bring_to_front.py ├── channel │ ├── normalize.py │ └── null.py ├── chop.py ├── collapse.py ├── constants.py ├── convert_data.py ├── created.py ├── dataset_creation.py ├── from_Aramis.py ├── from_BrunoldrRaman.py ├── from_COLORS.py ├── from_JASCO.py ├── from_KENT.py ├── from_LabRAM.py ├── from_PyCMDS.py ├── from_Solis.py ├── from_Tensor27.py ├── from_databroker.py ├── from_ocean_optics.py ├── from_shimadzu.py ├── from_spcm.py ├── get_nadir.py ├── get_zenith.py ├── gradient.py ├── heal.py ├── ichop.py ├── init.py ├── join.py ├── labels.py ├── level.py ├── map_variable.py ├── moment.py ├── prune.py ├── remove_channel.py ├── remove_variable.py ├── rename_channels.py ├── rename_variables.py ├── share_nans.py ├── smooth.py ├── split.py ├── squeeze.py ├── test_data │ ├── COLORS │ │ └── v2.1 │ │ │ └── MoS2 TrEE movie │ │ │ ├── 001.dat │ │ │ ├── 002.dat │ │ │ ├── 003.dat │ │ │ ├── 004.dat │ │ │ ├── 005.dat │ │ │ ├── 006.dat │ │ │ ├── 007.dat │ │ │ ├── 008.dat │ │ │ ├── 009.dat │ │ │ ├── 010.dat │ │ │ ├── 011.dat │ │ │ ├── 012.dat │ │ │ ├── 013.dat │ │ │ ├── 014.dat │ │ │ ├── 015.dat │ │ │ ├── 016.dat │ │ │ ├── 017.dat │ │ │ ├── 018.dat │ │ │ ├── 019.dat │ │ │ ├── 020.dat │ │ │ ├── 021.dat │ │ │ ├── 022.dat │ │ │ ├── 023.dat │ │ │ ├── 024.dat │ │ │ ├── 025.dat │ │ │ ├── 026.dat │ │ │ ├── 027.dat │ │ │ ├── 028.dat │ │ │ ├── 029.dat │ │ │ ├── 030.dat │ │ │ ├── 031.dat │ │ │ ├── 032.dat │ │ │ ├── 033.dat │ │ │ ├── 034.dat │ │ │ ├── 035.dat │ │ │ ├── 036.dat │ │ │ ├── 037.dat │ │ │ ├── 038.dat │ │ │ ├── 039.dat │ │ │ ├── 040.dat │ │ │ └── 041.dat │ ├── autotune.data │ ├── centers_tolerance.data │ ├── circular_map.ngc │ ├── duplicate_name.csv │ ├── ellipsoidal_map.ngc │ ├── incomplete.data │ ├── irregular_map.ngc │ ├── ps_delay.data │ ├── ps_delay_together.data │ ├── rectangular_map.ngc │ ├── skew_line.ngc │ ├── square_map.ngc │ ├── tolerance.data │ ├── two_centers.data │ └── vertical_linescan.ngc ├── transform.py ├── translate_to_txt.py └── trim.py ├── dataset ├── argmax.py ├── argmin.py ├── clip.py ├── convert_dataset.py ├── iadd.py ├── imul.py ├── ipow.py ├── isub.py ├── itruediv.py ├── log.py ├── max.py ├── max_cached.wt5 ├── min.py └── symmetric_root.py ├── docs └── _sphinx.py ├── entry_points └── wt_tree.py ├── group ├── attributes.py └── save.py ├── kit ├── .gitignore ├── __init__.py ├── closest_pair.py ├── diff.py ├── fft.py ├── flatten_list.py ├── fluence.py ├── get_index.py ├── get_path_matching.py ├── glob_handler.py ├── ini.py ├── intersperse.py ├── joint_shape.py ├── leastsqfitter.py ├── lineshapes.py ├── nm_width.py ├── remove_nans_1D.py ├── share_nans.py ├── signed.py ├── smooth_1D.py ├── string2identifier.py ├── svd.py ├── symmetric_sqrt.py ├── timer.py ├── timestamp.py ├── unicode.py ├── unique.py ├── valid_index.py └── zoom2D.py └── units.py /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | # Require review from one maintainer for pushes to Development and Master 2 | 3 | * @untzag @ksunden @ddkohler @darienmorrow @kameyer226 4 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE: -------------------------------------------------------------------------------- 1 | ## Changes 2 | 3 | please describe your changes here :smiley: 4 | 5 | ## Checklist 6 | 7 | - [ ] added tests, if applicable 8 | - [ ] updated documentation, if applicable 9 | - [ ] updated CHANGELOG.md 10 | - [ ] tests pass 11 | 12 | -------------------------------------------------------------------------------- /.github/workflows/python-publish.yml: -------------------------------------------------------------------------------- 1 | # This workflows will upload a Python Package using flit when a release is created 2 | # For more information see: https://help.github.com/en/actions/language-and-framework-guides/using-python-with-github-actions#publishing-to-package-registries 3 | 4 | name: Upload Python Package 5 | 6 | on: 7 | release: 8 | types: [created] 9 | 10 | jobs: 11 | deploy: 12 | 13 | runs-on: ubuntu-latest 14 | 15 | steps: 16 | - uses: actions/checkout@v4 17 | - name: Set up Python 18 | uses: actions/setup-python@v5 19 | with: 20 | python-version: '3.x' 21 | - name: Install dependencies 22 | run: | 23 | python -m pip install --upgrade pip 24 | pip install twine build setuptools 25 | - name: Build and publish 26 | env: 27 | TWINE_USERNAME: ${{ secrets.PYPI_USERNAME }} 28 | TWINE_PASSWORD: ${{ secrets.PYPI_PASSWORD }} 29 | run: | 30 | python -m build 31 | twine check dist/* 32 | twine upload dist/* 33 | -------------------------------------------------------------------------------- /.github/workflows/python-test.yml: -------------------------------------------------------------------------------- 1 | name: test python 2 | 3 | on: 4 | pull_request: 5 | types: [opened, reopened] 6 | push: 7 | 8 | jobs: 9 | build: 10 | 11 | runs-on: ${{ matrix.os }} 12 | strategy: 13 | matrix: 14 | os: [ubuntu-latest, windows-latest] 15 | python-version: [3.11, 3.12, 3.13] 16 | 17 | steps: 18 | - uses: actions/checkout@v4 19 | - name: Set up Python ${{ matrix.python-version }} 20 | uses: actions/setup-python@v5 21 | with: 22 | python-version: ${{ matrix.python-version }} 23 | - name: Install dependencies 24 | run: | 25 | python -m pip install --upgrade pip wheel setuptools 26 | python -m pip install --upgrade .[dev] 27 | - name: Test with pytest 28 | run: | 29 | pytest --color=yes 30 | 31 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # byte-compiled 2 | __pycache__/ 3 | *.py[cod] 4 | 5 | # direnv 6 | *.envrc 7 | 8 | # distribution / packaging 9 | .Python 10 | env/ 11 | build/ 12 | develop-eggs/ 13 | dist/ 14 | downloads/ 15 | eggs/ 16 | .eggs/ 17 | lib/ 18 | lib64/ 19 | parts/ 20 | sdist/ 21 | var/ 22 | temp/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | *.p 27 | 28 | # emacs 29 | flycheck_*.el 30 | .projectile 31 | *.#* 32 | 33 | # images 34 | *.jpg 35 | *.gif 36 | *.png 37 | !logo/logo.png 38 | *.svg 39 | *.ico 40 | 41 | # tests / coverage reports 42 | .coverage 43 | .coverage.* 44 | .cache 45 | coverage.xml 46 | *,cover 47 | .pytest_cache/* 48 | 49 | # vim 50 | *.sw? 51 | -------------------------------------------------------------------------------- /.pep8speaks.yml: -------------------------------------------------------------------------------- 1 | pycodestyle: 2 | max-line-length: 99 3 | count: True 4 | -------------------------------------------------------------------------------- /.pre-commit-config.yaml: -------------------------------------------------------------------------------- 1 | repos: 2 | - repo: https://github.com/psf/black 3 | rev: 24.10.0 # Replace by any tag/version: https://github.com/psf/black/tags 4 | hooks: 5 | - id: black 6 | language_version: python3 # Should be a command that runs python3.6+ 7 | args: ["--line-length", "99"] 8 | 9 | - repo: https://github.com/pre-commit/pre-commit-hooks 10 | rev: v5.0.0 11 | hooks: 12 | - id: trailing-whitespace 13 | exclude: datasets|.data$ 14 | - id: no-commit-to-branch 15 | args: [-b master] 16 | 17 | default_language_version: 18 | python: python3 19 | -------------------------------------------------------------------------------- /.readthedocs.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | 3 | build: 4 | os: ubuntu-22.04 5 | tools: 6 | python: "3.9" 7 | 8 | python: 9 | install: 10 | - method: pip 11 | path: . 12 | extra_requirements: 13 | - docs 14 | 15 | # Build documentation in the docs/ directory with Sphinx 16 | sphinx: 17 | configuration: docs/conf.py 18 | 19 | formats: 20 | - epub 21 | -------------------------------------------------------------------------------- /.zenodo.json: -------------------------------------------------------------------------------- 1 | { 2 | "license": {"id": "MIT"}, 3 | "title": "WrightTools", 4 | "upload_type": "software", 5 | "creators": [ 6 | { 7 | "orcid": "0000-0002-3845-824X", 8 | "affiliation": "University of Wisconsin–Madison", 9 | "name": "Blaise J. Thompson" 10 | }, 11 | { 12 | "orcid": "0000-0001-6167-8059", 13 | "affiliation": "University of Wisconsin–Madison", 14 | "name": "Kyle F. Sunden" 15 | }, 16 | { 17 | "orcid": "0000-0002-8922-8049", 18 | "affiliation": "University of Wisconsin–Madison", 19 | "name": "Darien J. Morrow" 20 | }, 21 | { 22 | "orcid": "0000-0003-4602-2961", 23 | "affiliation": "University of Wisconsin–Madison", 24 | "name": "Daniel D. Kohler" 25 | }, 26 | { 27 | "orcid": "0000-0002-9453-3590", 28 | "affiliation": "University of Wisconsin–Madison", 29 | "name": "Nathan Andrew Neff-Mallon" 30 | }, 31 | { 32 | "affiliation": "University of Wisconsin–Madison", 33 | "name": "Kyle J. Czech" 34 | }, 35 | { 36 | "orcid": "0000-0001-6718-8341", 37 | "affiliation": "University of Wisconsin–Madison", 38 | "name": "Emily M. Kaufman" 39 | }, 40 | { 41 | "name": "Thomas Parker" 42 | }, 43 | { 44 | "name": "Rachel Swedin" 45 | } 46 | ], 47 | "access_right": "open" 48 | } 49 | -------------------------------------------------------------------------------- /CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | For more information on how to contribute to WrightTools see: 2 | http://wright.tools/en/stable/contributing.html 3 | 4 | Maintainers (alphabetical by last name) 5 | Daniel Kohler (@ddkohler) 6 | Darien Morrow (@darienmorrow) 7 | Kyle Sunden (@ksunden) 8 | Blaise Thompson (@untzag) 9 | 10 | Contributors (alphabetical by last name) 11 | Kyle Czech (@kjczech) 12 | Nathan Neff-Mallon (@neffmallon) 13 | Thomas Parker (@parkertomf) 14 | Rachel Swedin (@RachelSwedin) 15 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016-2018 WrightTools Developers. 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 | -------------------------------------------------------------------------------- /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include LICENSE.txt 2 | include README.rst 3 | include CHANGELOG.md 4 | -------------------------------------------------------------------------------- /README.rst: -------------------------------------------------------------------------------- 1 | WrightTools 2 | ----------- 3 | 4 | ``WrightTools`` loads, processes, and plots multidimensional spectroscopy data. 5 | 6 | "Multidimensional spectroscopy" (MDS) is a family of diverse analytical techniques that record the response of a material to multiple stimuli---typically multiple ultrafast pulses of light. 7 | Due to its diversity and dimensionality, MDS data is challenging to process and visualize. 8 | ``WrightTools`` is a freely available and openly licensed Python package that is made specifically for multidimensional spectroscopy. 9 | It aims to be a core toolkit that is general enough to handle all MDS datasets and processing workloads. 10 | Being built for and by MDS practitioners, ``WrightTools`` has an intuitive, high-level, object-oriented interface for spectroscopists. 11 | 12 | Documentation at `wright.tools `_. 13 | 14 | .. image:: https://anaconda.org/conda-forge/wrighttools/badges/version.svg 15 | :target: https://anaconda.org/conda-forge/wrighttools 16 | 17 | .. image:: https://badge.fury.io/py/WrightTools.svg 18 | :target: https://badge.fury.io/py/WrightTools 19 | 20 | .. image:: https://readthedocs.org/projects/wrighttools/badge/?version=stable 21 | :target: http://wright.tools/en/stable/?badge=stable 22 | 23 | .. image:: https://readthedocs.org/projects/wrighttools/badge/?version=latest 24 | :target: http://wright.tools/en/latest/?badge=latest 25 | 26 | .. image:: https://img.shields.io/badge/code%20style-black-000000.svg 27 | :target: https://github.com/psf/black 28 | 29 | .. image:: http://joss.theoj.org/papers/10.21105/joss.01141/status.svg 30 | :target: https://doi.org/10.21105/joss.01141 31 | 32 | .. image:: https://raw.githubusercontent.com/wright-group/WrightTools/master/logo/logo.png 33 | :width: 400 34 | :alt: WrightTools 35 | :align: center 36 | -------------------------------------------------------------------------------- /WrightTools/CITATION: -------------------------------------------------------------------------------- 1 | @article{Thompson2019, 2 | doi = {10.21105/joss.01141}, 3 | url = {https://doi.org/10.21105/joss.01141}, 4 | year = {2019}, 5 | month = {jan}, 6 | publisher = {The Open Journal}, 7 | volume = {4}, 8 | number = {33}, 9 | pages = {1141}, 10 | author = {Blaise Thompson and Kyle Sunden and Darien Morrow and Daniel Kohler and John Wright}, 11 | title = {{WrightTools}: a Python package for multidimensional spectroscopy}, 12 | journal = {Journal of Open Source Software} 13 | } -------------------------------------------------------------------------------- /WrightTools/VERSION: -------------------------------------------------------------------------------- 1 | 3.5.5 2 | -------------------------------------------------------------------------------- /WrightTools/WT5_VERSION: -------------------------------------------------------------------------------- 1 | 1.0.3 2 | -------------------------------------------------------------------------------- /WrightTools/__citation__.py: -------------------------------------------------------------------------------- 1 | """Define WrightTools citation.""" 2 | 3 | import pathlib 4 | 5 | __all__ = ["__citation__"] 6 | 7 | here = pathlib.Path(__file__).parent 8 | 9 | with open(str(here / "CITATION")) as f: 10 | # remove extra whitespace 11 | __citation__ = " ".join(f.read().split()) 12 | -------------------------------------------------------------------------------- /WrightTools/__init__.py: -------------------------------------------------------------------------------- 1 | """WrightTools init.""" 2 | 3 | # flake8: noqa 4 | 5 | 6 | # --- import -------------------------------------------------------------------------------------- 7 | 8 | 9 | from .__citation__ import * 10 | from .__version__ import * 11 | from .__wt5_version__ import * 12 | from . import artists 13 | from . import collection 14 | from . import data 15 | from . import diagrams 16 | from . import kit 17 | from . import units 18 | from . import exceptions 19 | 20 | from ._open import * 21 | from ._close import * 22 | from .collection._collection import * 23 | from .data._data import * 24 | 25 | 26 | # --- rcparams ------------------------------------------------------------------------------------ 27 | 28 | artists.apply_rcparams("fast") 29 | -------------------------------------------------------------------------------- /WrightTools/__version__.py: -------------------------------------------------------------------------------- 1 | """Define WrightTools version.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import pathlib 7 | 8 | 9 | # ---- define ------------------------------------------------------------------------------------- 10 | 11 | 12 | here = pathlib.Path(__file__).resolve().parent 13 | 14 | 15 | __all__ = ["__version__", "__branch__"] 16 | 17 | 18 | # --- version ------------------------------------------------------------------------------------- 19 | 20 | 21 | # read from VERSION file 22 | with open(str(here / "VERSION")) as f: 23 | __version__ = f.read().strip() 24 | 25 | 26 | # add git branch, if appropriate 27 | p = here.parent / ".git" 28 | if p.is_file(): 29 | with open(str(p)) as f: 30 | p = p.parent / f.readline()[8:].strip() # Strip "gitdir: " 31 | p = p / "HEAD" 32 | if p.exists(): 33 | with open(str(p)) as f: 34 | __branch__ = f.readline().rstrip().split(r"/")[-1] 35 | __version__ += "+" + __branch__ 36 | else: 37 | __branch__ = None 38 | -------------------------------------------------------------------------------- /WrightTools/__wt5_version__.py: -------------------------------------------------------------------------------- 1 | """Define wt5 version.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import os 7 | 8 | 9 | # ---- define ------------------------------------------------------------------------------------- 10 | 11 | 12 | here = os.path.abspath(os.path.dirname(__file__)) 13 | 14 | 15 | __all__ = ["__wt5_version__"] 16 | 17 | 18 | # --- version ------------------------------------------------------------------------------------- 19 | 20 | 21 | # read from VERSION file 22 | with open(os.path.join(here, "WT5_VERSION")) as f: 23 | __wt5_version__ = f.read().strip() 24 | -------------------------------------------------------------------------------- /WrightTools/_close.py: -------------------------------------------------------------------------------- 1 | """Function to close all open wt5 files.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | from . import _group as wt_group 7 | 8 | 9 | # --- define ------------------------------------------------------------------------------------- 10 | 11 | 12 | __all__ = ["close"] 13 | 14 | 15 | # --- functions ---------------------------------------------------------------------------------- 16 | 17 | 18 | def close(): 19 | """Close all open wt5 files. 20 | 21 | Warning 22 | ------- 23 | This will make any open objects unusable and delete unsaved temporary files. 24 | """ 25 | while len(wt_group.Group._instances) > 0: 26 | wt_group.Group._instances.popitem()[1].close() 27 | -------------------------------------------------------------------------------- /WrightTools/_open.py: -------------------------------------------------------------------------------- 1 | """Generic open method for wt5 files.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import os 7 | import tempfile 8 | import weakref 9 | 10 | import h5py 11 | import numpy as np 12 | 13 | from . import collection as wt_collection 14 | from . import data as wt_data 15 | from . import _group as wt_group 16 | from numpy.lib.npyio import DataSource 17 | 18 | 19 | # --- define ------------------------------------------------------------------------------------- 20 | 21 | 22 | __all__ = ["open"] 23 | 24 | 25 | # --- functions ---------------------------------------------------------------------------------- 26 | 27 | _open = open 28 | 29 | 30 | def open(filepath, edit_local=False): 31 | """Open any wt5 file, returning the top-level object (data or collection). 32 | 33 | Parameters 34 | ---------- 35 | filepath : path-like 36 | Path to file. 37 | Can be either a local or remote file (http/ftp). 38 | Can be compressed with gz/bz2, decompression based on file name. 39 | edit_local : boolean (optional) 40 | If True, the file itself will be opened for editing. Otherwise, a 41 | copy will be created. Default is False. 42 | 43 | Returns 44 | ------- 45 | WrightTools Collection or Data 46 | Root-level object in file. 47 | """ 48 | filepath = os.fspath(filepath) 49 | ds = DataSource(None) 50 | if edit_local is False: 51 | tf = tempfile.mkstemp(prefix="", suffix=".wt5") 52 | with _open(tf[1], "w+b") as tff: 53 | with ds.open(str(filepath), "rb") as f: 54 | tff.write(f.read()) 55 | filepath = tf[1] 56 | f = h5py.File(filepath, "r") 57 | class_name = f["/"].attrs["class"] 58 | name = f["/"].attrs["name"] 59 | f.close() 60 | if class_name == "Data": 61 | obj = wt_data.Data(filepath=str(filepath), name=name, edit_local=True) 62 | elif class_name == "Collection": 63 | obj = wt_collection.Collection(filepath=str(filepath), name=name, edit_local=True) 64 | else: 65 | obj = wt_group.Group(filepath=str(filepath), name=name, edit_local=True) 66 | 67 | if edit_local is False: 68 | setattr(obj, "_tmpfile", tf) 69 | weakref.finalize(obj, obj.close) 70 | return obj 71 | -------------------------------------------------------------------------------- /WrightTools/artists/__init__.py: -------------------------------------------------------------------------------- 1 | """Artists.""" 2 | 3 | # flake8: noqa 4 | 5 | 6 | from ._base import * 7 | from ._colors import * 8 | from ._helpers import * 9 | from ._quick import * 10 | from ._interact import * 11 | -------------------------------------------------------------------------------- /WrightTools/cli/__init__.py: -------------------------------------------------------------------------------- 1 | from . import _units 2 | from . import _wt5 3 | -------------------------------------------------------------------------------- /WrightTools/cli/_units.py: -------------------------------------------------------------------------------- 1 | # --- import -------------------------------------------------------------------------------------- 2 | 3 | 4 | import click 5 | from WrightTools import __version__ as __wt_version__ 6 | from WrightTools.units import is_valid_conversion, get_valid_conversions, convert 7 | from WrightTools.exceptions import UnitsError 8 | 9 | 10 | # --- define -------------------------------------------------------------------------------------- 11 | 12 | 13 | @click.command(name="convert", help="convert numbers to different units.") 14 | @click.version_option(__wt_version__, prog_name="WrightTools") 15 | @click.argument("number", type=float, nargs=1) 16 | @click.argument("unit", nargs=1) 17 | @click.argument("destination_unit", default=None, nargs=-1) 18 | def cli(number, unit, destination_unit=None): 19 | """Convert numbers to different units.""" 20 | 21 | if int(number) == number: 22 | number = int(number) 23 | sig_figs = len(str(number)) 24 | sig_figs -= 1 if "." in str(number) else 0 25 | 26 | def fmt(new): 27 | exponent = int(f"{new:e}".split("e")[1]) 28 | if exponent > 6 or exponent < -3: 29 | return f"{new:{sig_figs}e}" 30 | else: # if a "normal" size number 31 | if sig_figs - exponent <= 0: 32 | return f"{int(round(new, sig_figs-exponent))}" 33 | else: 34 | return f"{round(new, sig_figs-exponent)}" 35 | 36 | if len(destination_unit): # units provided 37 | destination_unit = destination_unit[0] 38 | if not is_valid_conversion(unit, destination_unit): 39 | raise UnitsError(get_valid_conversions(unit), destination_unit) 40 | new = convert(number, unit, destination_unit) 41 | print(f"{number} {unit} = {fmt(new)} {destination_unit}") 42 | else: 43 | valid_units = get_valid_conversions(unit) 44 | for d_unit in valid_units: 45 | new = convert(number, unit, d_unit) 46 | print(f"{fmt(new)} {d_unit}") 47 | 48 | 49 | if __name__ == "__main__": 50 | cli() 51 | -------------------------------------------------------------------------------- /WrightTools/collection/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/collection/.gitignore -------------------------------------------------------------------------------- /WrightTools/collection/__init__.py: -------------------------------------------------------------------------------- 1 | """Collection class and associated.""" 2 | 3 | # flake8: noqa 4 | 5 | 6 | from ._collection import * 7 | from ._cary import * 8 | from ._directory import * 9 | 10 | 11 | __all__ = ["Collection", "from_Cary", "from_directory"] 12 | -------------------------------------------------------------------------------- /WrightTools/data/__init__.py: -------------------------------------------------------------------------------- 1 | """Data class and associated.""" 2 | 3 | # flake8: noqa 4 | 5 | 6 | from ._axis import * 7 | from ._channel import * 8 | from ._constant import * 9 | from ._join import * 10 | from ._variable import * 11 | 12 | from ._solis import * 13 | from ._brunold import * 14 | from ._colors import * 15 | from ._data import * 16 | from ._databroker import * 17 | from ._jasco import * 18 | from ._labram import * 19 | from ._kent import * 20 | from ._aramis import * 21 | from ._ocean_optics import * 22 | from ._pycmds import * 23 | from ._shimadzu import * 24 | from ._spcm import * 25 | from ._tensor27 import * 26 | 27 | 28 | __all__ = [ 29 | "Data", 30 | "join", 31 | "Axis", 32 | "Channel", 33 | "Constant", 34 | "Variable", 35 | # From methods in alphabetic order 36 | "from_BrunoldrRaman", 37 | "from_COLORS", 38 | "from_databroker", 39 | "from_JASCO", 40 | "from_KENT", 41 | "from_LabRAM", 42 | "from_Aramis", 43 | "from_ocean_optics", 44 | "from_PyCMDS", 45 | "from_shimadzu", 46 | "from_Solis", 47 | "from_spcm", 48 | "from_Tensor27", 49 | ] 50 | -------------------------------------------------------------------------------- /WrightTools/data/_databroker.py: -------------------------------------------------------------------------------- 1 | __all__ = ["from_databroker"] 2 | 3 | from ._data import Data 4 | 5 | 6 | def from_databroker(run, dataset="primary"): 7 | """Import a dataset from a bluesky run into the WrightTools Data format. 8 | 9 | Parameters 10 | ---------- 11 | run: BlueskyRun 12 | The bluesky run as returned by e.g. catalog[""] 13 | dataset: str 14 | The string identifier of the stream to import from the bluesky run. 15 | By default "primary" is used, but e.g. "baseline" is also common 16 | """ 17 | describe = run.describe() 18 | md = describe["metadata"] 19 | start = md["start"] 20 | ds = run[dataset].read() 21 | shape = start.get("shape", (len(ds.time),)) 22 | 23 | detectors = start.get("detectors", []) 24 | 25 | data = Data(name=start["uid"]) 26 | for var in ds: 27 | if var == "uid": 28 | continue 29 | if var.endswith("_busy"): 30 | continue 31 | if any(var.startswith(d) for d in detectors): 32 | data.create_channel(var, values=ds[var].data.reshape(shape)) 33 | else: 34 | # TODO units, once they are in the dataset metadata 35 | data.create_variable(var, values=ds[var].data.reshape(shape)) 36 | 37 | transform = [x[0] for x, ds_name in start["hints"]["dimensions"] if ds_name == dataset] 38 | data.transform(*transform) 39 | return data 40 | -------------------------------------------------------------------------------- /WrightTools/data/_jasco.py: -------------------------------------------------------------------------------- 1 | """JASCO.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import os 7 | import pathlib 8 | 9 | import numpy as np 10 | 11 | from ._data import Data 12 | from .. import exceptions as wt_exceptions 13 | from numpy.lib.npyio import DataSource 14 | 15 | 16 | # --- define -------------------------------------------------------------------------------------- 17 | 18 | 19 | __all__ = ["from_JASCO"] 20 | 21 | 22 | # --- from function ------------------------------------------------------------------------------- 23 | 24 | 25 | def from_JASCO(filepath, name=None, parent=None, verbose=True) -> Data: 26 | """Create a data object from JASCO UV-Vis spectrometers. 27 | 28 | Parameters 29 | ---------- 30 | filepath : path-like 31 | Path to .txt file. 32 | Can be either a local or remote file (http/ftp). 33 | Can be compressed with gz/bz2, decompression based on file name. 34 | name : string (optional) 35 | Name to give to the created data object. If None, filename is used. 36 | Default is None. 37 | parent : WrightTools.Collection (optional) 38 | Collection to place new data object within. Default is None. 39 | verbose : boolean (optional) 40 | Toggle talkback. Default is True. 41 | 42 | Returns 43 | ------- 44 | data 45 | New data object(s). 46 | """ 47 | # parse filepath 48 | filestr = os.fspath(filepath) 49 | filepath = pathlib.Path(filepath) 50 | 51 | if not ".txt" in filepath.suffixes: 52 | wt_exceptions.WrongFileTypeWarning.warn(filepath, ".txt") 53 | # parse name 54 | if not name: 55 | name = filepath.name.split(".")[0] 56 | # create data 57 | kwargs = {"name": name, "kind": "JASCO", "source": filestr} 58 | if parent is None: 59 | data = Data(**kwargs) 60 | else: 61 | data = parent.create_data(**kwargs) 62 | # array 63 | ds = DataSource(None) 64 | f = ds.open(filestr, "rt") 65 | arr = np.genfromtxt(f, skip_header=18).T 66 | f.close() 67 | 68 | # chew through all scans 69 | data.create_variable(name="energy", values=arr[0], units="nm") 70 | data.create_channel(name="signal", values=arr[1]) 71 | data.transform("energy") 72 | # finish 73 | if verbose: 74 | print("data created at {0}".format(data.fullpath)) 75 | print(" range: {0} to {1} (nm)".format(data.energy[0], data.energy[-1])) 76 | print(" size: {0}".format(data.size)) 77 | return data 78 | -------------------------------------------------------------------------------- /WrightTools/data/_shimadzu.py: -------------------------------------------------------------------------------- 1 | """Shimadzu.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import os 7 | import pathlib 8 | 9 | import numpy as np 10 | 11 | from ._data import Data 12 | from .. import exceptions as wt_exceptions 13 | from numpy.lib.npyio import DataSource 14 | 15 | 16 | # --- define -------------------------------------------------------------------------------------- 17 | 18 | 19 | __all__ = ["from_shimadzu"] 20 | 21 | 22 | # --- from function ------------------------------------------------------------------------------- 23 | 24 | 25 | def from_shimadzu(filepath, name=None, parent=None, verbose=True) -> Data: 26 | """Create a data object from Shimadzu .txt file. 27 | 28 | Parameters 29 | ---------- 30 | filepath : path-like 31 | Path to .txt file. 32 | Can be either a local or remote file (http/ftp). 33 | Can be compressed with gz/bz2, decompression based on file name. 34 | name : string (optional) 35 | Name to give to the created data object. If None, filename is used. 36 | Default is None. 37 | parent : WrightTools.Collection (optional) 38 | Collection to place new data object within. Default is None. 39 | verbose : boolean (optional) 40 | Toggle talkback. Default is True. 41 | 42 | Returns 43 | ------- 44 | data 45 | New data object. 46 | """ 47 | # parse filepath 48 | filestr = os.fspath(filepath) 49 | filepath = pathlib.Path(filepath) 50 | 51 | if not ".txt" in filepath.suffixes: 52 | wt_exceptions.WrongFileTypeWarning.warn(filepath, ".txt") 53 | # parse name 54 | if not name: 55 | name = filepath.name.split(".")[0] 56 | # create data 57 | kwargs = {"name": name, "kind": "Shimadzu", "source": filestr} 58 | if parent is None: 59 | data = Data(**kwargs) 60 | else: 61 | data = parent.create_data(**kwargs) 62 | # array 63 | ds = DataSource(None) 64 | f = ds.open(filestr, "rt") 65 | arr = np.genfromtxt(f, skip_header=2, delimiter=",").T 66 | f.close() 67 | # chew through all scans 68 | data.create_variable(name="energy", values=arr[0], units="nm") 69 | data.create_channel(name="signal", values=arr[1]) 70 | data.transform("energy") 71 | # finish 72 | if verbose: 73 | print("data created at {0}".format(data.fullpath)) 74 | print(" range: {0} to {1} (nm)".format(data.energy[0], data.energy[-1])) 75 | print(" size: {0}".format(data.size)) 76 | return data 77 | -------------------------------------------------------------------------------- /WrightTools/data/_variable.py: -------------------------------------------------------------------------------- 1 | """Variable class and associated.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import h5py 7 | 8 | from .._dataset import Dataset 9 | 10 | __all__ = ["Variable"] 11 | 12 | 13 | # --- class --------------------------------------------------------------------------------------- 14 | 15 | 16 | class Variable(Dataset): 17 | """Variable.""" 18 | 19 | class_name = "Variable" 20 | 21 | def __init__(self, parent, id, units=None, **kwargs): 22 | """Variable. 23 | 24 | Parameters 25 | ---------- 26 | parent : WrightTools.Data 27 | Parent data object. 28 | id : h5py DatasetID 29 | Dataset ID. 30 | units : string (optional) 31 | Variable units. Default is None. 32 | kwargs 33 | Additional keys and values to be written into dataset attrs. 34 | """ 35 | self._parent = parent 36 | super().__init__(id) 37 | if units is not None: 38 | self.units = units 39 | # attrs 40 | if self._parent.file.mode is not None and self._parent.file.mode != "r": 41 | self.attrs.update(kwargs) 42 | self.attrs["name"] = h5py.h5i.get_name(self.id).decode().split("/")[-1] 43 | self.attrs["class"] = self.class_name 44 | 45 | @property 46 | def label(self) -> str: 47 | return self.attrs.get("label", "") 48 | 49 | @label.setter 50 | def label(self, label): 51 | self.attrs["label"] = label 52 | 53 | def _to_dict(self): 54 | out = {} 55 | out["name"] = self.natural_name 56 | out["values"] = self[:] 57 | out["units"] = self.units 58 | out["label"] = self.label 59 | out.update(self.attrs) 60 | return out 61 | -------------------------------------------------------------------------------- /WrightTools/datasets/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/.gitignore -------------------------------------------------------------------------------- /WrightTools/datasets/COLORS/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/COLORS/.gitignore -------------------------------------------------------------------------------- /WrightTools/datasets/COLORS/v0.0/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/COLORS/v0.0/.gitignore -------------------------------------------------------------------------------- /WrightTools/datasets/COLORS/v0.1/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/COLORS/v0.1/.gitignore -------------------------------------------------------------------------------- /WrightTools/datasets/COLORS/v1.0/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/COLORS/v1.0/.gitignore -------------------------------------------------------------------------------- /WrightTools/datasets/COLORS/v2.0/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/COLORS/v2.0/.gitignore -------------------------------------------------------------------------------- /WrightTools/datasets/COLORS/v2.1/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/COLORS/v2.1/.gitignore -------------------------------------------------------------------------------- /WrightTools/datasets/KENT/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/KENT/.gitignore -------------------------------------------------------------------------------- /WrightTools/datasets/LabRAM/map_nm.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/LabRAM/map_nm.txt.gz -------------------------------------------------------------------------------- /WrightTools/datasets/LabRAM/raman_linescan.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/LabRAM/raman_linescan.txt.gz -------------------------------------------------------------------------------- /WrightTools/datasets/LabRAM/spectrum_nm.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/LabRAM/spectrum_nm.txt.gz -------------------------------------------------------------------------------- /WrightTools/datasets/LabRAM/spectrum_wn.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/LabRAM/spectrum_wn.txt.gz -------------------------------------------------------------------------------- /WrightTools/datasets/LabRAM/survey_nm.txt.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/LabRAM/survey_nm.txt.gz -------------------------------------------------------------------------------- /WrightTools/datasets/Solis/kinetic.asc.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/Solis/kinetic.asc.gz -------------------------------------------------------------------------------- /WrightTools/datasets/Solis/wm ypos fluorescence with filter.asc.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/Solis/wm ypos fluorescence with filter.asc.gz -------------------------------------------------------------------------------- /WrightTools/datasets/Solis/xpos ypos fluorescence.asc.gz: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/Solis/xpos ypos fluorescence.asc.gz -------------------------------------------------------------------------------- /WrightTools/datasets/wt5/v1.0.0/perovskite_TA.wt5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/wt5/v1.0.0/perovskite_TA.wt5 -------------------------------------------------------------------------------- /WrightTools/datasets/wt5/v1.0.1/MoS2_TrEE_movie.wt5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/WrightTools/datasets/wt5/v1.0.1/MoS2_TrEE_movie.wt5 -------------------------------------------------------------------------------- /WrightTools/diagrams/__init__.py: -------------------------------------------------------------------------------- 1 | """Diagrams.""" 2 | 3 | # flake8: noqa 4 | 5 | from . import delay 6 | from . import WMEL 7 | -------------------------------------------------------------------------------- /WrightTools/kit/__init__.py: -------------------------------------------------------------------------------- 1 | """General-purpose tool kit.""" 2 | 3 | # flake8: noqa 4 | 5 | from ._array import * 6 | from ._calculate import * 7 | from ._discover_dimensions import * 8 | from ._ini import * 9 | from ._interpolate import * 10 | from ._leastsq import * 11 | from ._lineshapes import * 12 | from ._list import * 13 | from ._path import * 14 | from ._timestamp import * 15 | from ._unicode import * 16 | from ._utilities import * 17 | from ._glob import * 18 | -------------------------------------------------------------------------------- /WrightTools/kit/_path.py: -------------------------------------------------------------------------------- 1 | """Filepath functions.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import pathlib 7 | 8 | 9 | # --- define -------------------------------------------------------------------------------------- 10 | 11 | 12 | __all__ = ["get_path_matching"] 13 | 14 | 15 | # --- functions ----------------------------------------------------------------------------------- 16 | 17 | 18 | def get_path_matching(name: str) -> pathlib.Path: 19 | """ 20 | Non-recursive search for path to the folder "name". 21 | Searches the user directory, then looks up the cwd for a parent folder that matches. 22 | 23 | Parameters 24 | ---------- 25 | name : string 26 | name of directory to search for. 27 | 28 | Returns 29 | ------- 30 | pathlib.Path 31 | Full filepath to directory name. 32 | 33 | """ 34 | # first try looking in the user folder 35 | p = pathlib.Path.home() / name 36 | # then try expanding upwards from cwd 37 | if not p.is_dir(): 38 | p = None 39 | drive, *folders = pathlib.Path.cwd().parts 40 | if name in folders: 41 | p = pathlib.Path(drive).joinpath(*folders[: folders.index(name) + 1]) 42 | # TODO: something more robust to catch the rest of the cases? 43 | return p 44 | -------------------------------------------------------------------------------- /WrightTools/kit/_unicode.py: -------------------------------------------------------------------------------- 1 | """Unicode.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import collections 7 | 8 | 9 | # --- define -------------------------------------------------------------------------------------- 10 | 11 | 12 | __all__ = ["unicode_dictionary"] 13 | 14 | 15 | unicode_dictionary = collections.OrderedDict() 16 | unicode_dictionary["Alpha"] = "\u0391" 17 | unicode_dictionary["Beta"] = "\u0392" 18 | unicode_dictionary["Gamma"] = "\u0392" 19 | unicode_dictionary["Delta"] = "\u0394" 20 | unicode_dictionary["Epsilon"] = "\u0395" 21 | unicode_dictionary["Zeta"] = "\u0396" 22 | unicode_dictionary["Eta"] = "\u0397" 23 | unicode_dictionary["Theta"] = "\u0398" 24 | unicode_dictionary["Iota"] = "\u0399" 25 | unicode_dictionary["Kappa"] = "\u039A" 26 | unicode_dictionary["Lamda"] = "\u039B" 27 | unicode_dictionary["Mu"] = "\u039C" 28 | unicode_dictionary["Nu"] = "\u039D" 29 | unicode_dictionary["Xi"] = "\u039E" 30 | unicode_dictionary["Omicron"] = "\u039F" 31 | unicode_dictionary["Pi"] = "\u03A0" 32 | unicode_dictionary["Rho"] = "\u03A1" 33 | unicode_dictionary["Sigma"] = "\u03A3" 34 | unicode_dictionary["Tau"] = "\u03A4" 35 | unicode_dictionary["Upsilon"] = "\u03A5" 36 | unicode_dictionary["Phi"] = "\u03A6" 37 | unicode_dictionary["Chi"] = "\u03A7" 38 | unicode_dictionary["Psi"] = "\u03A8" 39 | unicode_dictionary["Omega"] = "\u03A9" 40 | unicode_dictionary["alpha"] = "\u03B1" 41 | unicode_dictionary["beta"] = "\u03B2" 42 | unicode_dictionary["gamma"] = "\u03B3" 43 | unicode_dictionary["delta"] = "\u03B4" 44 | unicode_dictionary["epsilon"] = "\u03B5" 45 | unicode_dictionary["zeta"] = "\u03B6" 46 | unicode_dictionary["eta"] = "\u03B7" 47 | unicode_dictionary["theta"] = "\u03B8" 48 | unicode_dictionary["iota"] = "\u03B9" 49 | unicode_dictionary["kappa"] = "\u03BA" 50 | unicode_dictionary["lamda"] = "\u03BB" 51 | unicode_dictionary["mu"] = "\u03BC" 52 | unicode_dictionary["nu"] = "\u03BD" 53 | unicode_dictionary["xi"] = "\u03BE" 54 | unicode_dictionary["omicron"] = "\u03BF" 55 | unicode_dictionary["pi"] = "\u03C0" 56 | unicode_dictionary["rho"] = "\u03C1" 57 | unicode_dictionary["sigma"] = "\u03C3" 58 | unicode_dictionary["tau"] = "\u03C4" 59 | unicode_dictionary["upsilon"] = "\u03C5" 60 | unicode_dictionary["phi"] = "\u03C6" 61 | unicode_dictionary["chi"] = "\u03C7" 62 | unicode_dictionary["psi"] = "\u03C8" 63 | unicode_dictionary["omega"] = "\u03C9" 64 | -------------------------------------------------------------------------------- /WrightTools/kit/_utilities.py: -------------------------------------------------------------------------------- 1 | """Utilities.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import time 7 | import string 8 | 9 | 10 | # --- define -------------------------------------------------------------------------------------- 11 | 12 | 13 | __all__ = ["string2identifier", "Timer"] 14 | 15 | 16 | # --- functions ----------------------------------------------------------------------------------- 17 | 18 | 19 | def string2identifier(s, replace=None): 20 | """Turn a string into a valid python identifier. 21 | 22 | This method restricts identifier characters to ASCII letters, numbers, and 23 | underscore. The characters are slightly more restrictive than python 3 24 | itself, and may be refactored in future (see PEP 3131). 25 | 26 | For non-valid characters, the default replacement is "_". Replacement 27 | assignments can be customized with the replace kwarg. 28 | 29 | Parameters 30 | ---------- 31 | s : string 32 | string to convert 33 | replace: dictionary[str, str] (optional) 34 | dictionary of characters (keys) and their replacements (values). Values 35 | should be ASCII or underscore. Unspecified non-ascii characters are 36 | converted to underscore. 37 | 38 | Returns 39 | ------- 40 | str 41 | valid python identifier. 42 | """ 43 | if len(s) == 0: 44 | return "_" 45 | if s[0] not in string.ascii_letters: 46 | s = "_" + s 47 | valids = string.ascii_letters + string.digits + "_" 48 | out = "" 49 | for i, char in enumerate(s): 50 | if replace and (char in replace.keys()): 51 | out += replace[char] 52 | elif char in valids: 53 | out += char 54 | else: 55 | out += "_" 56 | return out 57 | 58 | 59 | # --- classes ------------------------------------------------------------------------------------- 60 | 61 | 62 | class Timer: 63 | """Context manager for timing code. 64 | 65 | >>> with Timer(): 66 | ... your_code() 67 | """ 68 | 69 | def __init__(self, verbose=True): 70 | self.verbose = verbose 71 | 72 | def __enter__(self, progress=None): 73 | self.start = time.time() 74 | 75 | def __exit__(self, type, value, traceback): 76 | self.end = time.time() 77 | self.interval = self.end - self.start 78 | if self.verbose: 79 | print("elapsed time: {0} sec".format(self.interval)) 80 | -------------------------------------------------------------------------------- /docs/.gitignore: -------------------------------------------------------------------------------- 1 | auto_examples/ 2 | _build/ 3 | gen_modules/ 4 | modules/ 5 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Minimal makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = python3 -msphinx 7 | SPHINXPROJ = WrightTools 8 | SOURCEDIR = . 9 | BUILDDIR = _build 10 | 11 | # Put it first so that "make" without argument is like "make help". 12 | help: 13 | @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 14 | 15 | .PHONY: help Makefile 16 | 17 | # Catch-all target: route all unknown targets to Sphinx using the new 18 | # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). 19 | %: Makefile 20 | @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) 21 | -------------------------------------------------------------------------------- /docs/_static/.gitignore: -------------------------------------------------------------------------------- 1 | !* -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie.gif -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie.py: -------------------------------------------------------------------------------- 1 | # import 2 | import WrightTools as wt 3 | from WrightTools import datasets 4 | 5 | # create 6 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 7 | data = wt.open(p) 8 | # cleanup 9 | data.level("ai0", "d2", -3) 10 | data.scale() 11 | data.convert("eV") 12 | data.name = "MoS2" 13 | data.flip("d2") 14 | # plot 15 | artist = wt.artists.mpl_2D(data, "w1", "w2") 16 | ps = artist.plot(fname="MoS2", output_folder="v2p1_MoS2_TrEE_movie", autosave=True) 17 | # stitch 18 | wt.artists.stitch_to_animation(ps, outpath="v2p1_MoS2_TrEE_movie.gif") 19 | -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 000.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 000.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 001.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 001.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 002.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 002.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 003.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 003.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 004.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 004.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 005.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 005.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 006.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 006.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 007.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 007.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 008.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 008.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 009.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 009.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 010.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 010.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 011.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 011.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 012.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 012.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 013.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 013.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 014.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 014.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 015.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 015.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 016.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 016.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 017.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 017.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 018.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 018.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 019.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 019.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 020.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 020.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 021.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 021.png -------------------------------------------------------------------------------- /docs/_static/v2p1_MoS2_TrEE_movie/MoS2 022.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/docs/_static/v2p1_MoS2_TrEE_movie/MoS2 022.png -------------------------------------------------------------------------------- /docs/alternatives.rst: -------------------------------------------------------------------------------- 1 | .. _alternatives: 2 | 3 | Alternatives 4 | ============ 5 | 6 | There are several packages with similar goals as WrightTools. 7 | None of them replace everything WrightTools does, but each of them overlaps with one of WrightTools' main features: 8 | 9 | - focus on spectroscopy 10 | - multidimensional 11 | - self-describing data formats 12 | - openly licensed & freely available 13 | 14 | Some of these packages are focused on adjacent analytical techniques that have different conventions than multidimensional spectroscopy. 15 | Others are focused on spectroscopy, but with a different approach than WrightTools. 16 | Others are more generic, and don't have the conventions of any particular experimental strategy built in. 17 | All of them are really cool! 18 | Your project may be better served by one of them: 19 | 20 | - glue_ 21 | - gridded_ 22 | - Gwyddion_ 23 | - hyperspy_ 24 | - nmrglue_ 25 | - PyTrA_ 26 | - scikit-spectra_ 27 | - specutils_ 28 | - xarray_ 29 | 30 | Of course there are also the "default" python data-science structures: 31 | 32 | - numpy ndarray_ 33 | - pandas DataFrame_ 34 | 35 | Those with general interest in array-oriented scientific data should be aware of hdf5_ and netcdf_. 36 | 37 | .. _DataFrame: https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.html 38 | .. _glue: http://www.glueviz.org 39 | .. _gridded: https://noaa-orr-erd.github.io/gridded/ 40 | .. _Gwyddion: http://gwyddion.net/ 41 | .. _hyperspy: http://hyperspy.org/ 42 | .. _ndarray: https://docs.scipy.org/doc/numpy/reference/generated/numpy.ndarray.html 43 | .. _hdf5: https://portal.hdfgroup.org/display/HDF5/HDF5 44 | .. _netcdf: https://www.unidata.ucar.edu/software/netcdf/ 45 | .. _nmrglue: http://www.nmrglue.com/ 46 | .. _PyTrA: http://nznano.blogspot.com/2012/06/pytra-femtosecond-transient-absorption.html 47 | .. _scikit-spectra: http://hugadams.github.io/scikit-spectra/ 48 | .. _specutils: http://specutils.readthedocs.io/en/latest/ 49 | .. _xarray: http://xarray.pydata.org/ 50 | -------------------------------------------------------------------------------- /docs/api/.gitignore: -------------------------------------------------------------------------------- 1 | *.rst 2 | !modules.rst 3 | !WrightTools.artists.rst 4 | !WrightTools.artists.Axes.rst 5 | !WrightTools.artists.Figure.rst 6 | !WrightTools.kit.rst 7 | !WrightTools.kit.Timer.rst 8 | !WrightTools.kit.INI.rst 9 | !WrightTools.kit.Spline.rst 10 | !WrightTools.kit.TimeStamp.rst 11 | !WrightTools.collection.rst 12 | !WrightTools.collection.Collection.rst 13 | !WrightTools.data.rst 14 | !WrightTools.data.Data.rst 15 | !WrightTools.data.Axis.rst 16 | !WrightTools.data.Constant.rst 17 | !WrightTools.data.Channel.rst 18 | !WrightTools.data.Variable.rst 19 | !WrightTools.units.rst 20 | !WrightTools.exceptions.rst 21 | !WrightTools.diagrams.delay.rst 22 | !WrightTools.diagrams.rst 23 | !WrightTools.diagrams.WMEL.rst 24 | !WrightTools.datasets.rst 25 | !WrightTools.open.rst 26 | -------------------------------------------------------------------------------- /docs/api/WrightTools.artists.Axes.rst: -------------------------------------------------------------------------------- 1 | WrightTools.artists.Axes 2 | ======================== 3 | 4 | .. currentmodule:: WrightTools.artists 5 | 6 | .. autoclass:: Axes 7 | :show-inheritance: 8 | 9 | 10 | .. rubric:: Methods 11 | 12 | .. autosummary:: 13 | :toctree: WrightTools.artists.Axes 14 | 15 | ~Axes.add_sideplot 16 | ~Axes.contour 17 | ~Axes.contourf 18 | ~Axes.legend 19 | ~Axes.pcolor 20 | ~Axes.pcolormesh 21 | ~Axes.plot 22 | -------------------------------------------------------------------------------- /docs/api/WrightTools.artists.Figure.rst: -------------------------------------------------------------------------------- 1 | WrightTools.artists.Figure 2 | ========================== 3 | 4 | .. currentmodule:: WrightTools.artists 5 | 6 | .. autoclass:: Figure 7 | :show-inheritance: 8 | 9 | -------------------------------------------------------------------------------- /docs/api/WrightTools.artists.GridSpec.rst: -------------------------------------------------------------------------------- 1 | WrightTools.artists.GridSpec 2 | ============================ 3 | 4 | .. currentmodule:: WrightTools.artists 5 | 6 | .. autoclass:: GridSpec 7 | :show-inheritance: 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /docs/api/WrightTools.artists.rst: -------------------------------------------------------------------------------- 1 | WrightTools\.artists module 2 | =========================== 3 | 4 | .. currentmodule:: WrightTools.artists 5 | 6 | .. automodule:: WrightTools.artists 7 | 8 | .. autosummary:: 9 | :toctree: ../api 10 | 11 | Axes 12 | Figure 13 | GridSpec 14 | add_sideplot 15 | apply_rcparams 16 | colormaps 17 | corner_text 18 | create_figure 19 | diagonal_line 20 | get_color_cycle 21 | get_scaled_bounds 22 | grayify_cmap 23 | interact2D 24 | overline_colors 25 | pcolor_helper 26 | plot_colorbar 27 | plot_colormap_components 28 | plot_gridlines 29 | plot_margins 30 | quick1D 31 | quick2D 32 | savefig 33 | set_ax_labels 34 | set_ax_spines 35 | set_fig_labels 36 | stitch_to_animation 37 | subplots_adjust 38 | -------------------------------------------------------------------------------- /docs/api/WrightTools.collection.Collection.rst: -------------------------------------------------------------------------------- 1 | WrightTools.collection.Collection 2 | ================================= 3 | 4 | .. currentmodule:: WrightTools.collection 5 | 6 | .. autoclass:: Collection 7 | :show-inheritance: 8 | 9 | 10 | .. automethod:: __init__ 11 | 12 | 13 | .. rubric:: Methods 14 | 15 | .. autosummary:: 16 | :toctree: WrightTools.collection.Collection 17 | 18 | ~Collection.close 19 | ~Collection.copy 20 | ~Collection.create_collection 21 | ~Collection.create_data 22 | ~Collection.flush 23 | ~Collection.print_tree 24 | ~Collection.save 25 | 26 | 27 | 28 | 29 | .. rubric:: Attributes 30 | 31 | .. autosummary:: 32 | :toctree: WrightTools.collection.Collection 33 | 34 | ~Collection.attrs 35 | ~Collection.class_name 36 | ~Collection.created 37 | ~Collection.file 38 | ~Collection.fullpath 39 | ~Collection.item_names 40 | ~Collection.name 41 | ~Collection.natural_name 42 | ~Collection.parent 43 | 44 | 45 | -------------------------------------------------------------------------------- /docs/api/WrightTools.collection.rst: -------------------------------------------------------------------------------- 1 | WrightTools\.collection package 2 | =============================== 3 | 4 | .. currentmodule:: WrightTools.collection 5 | 6 | .. automodule:: WrightTools.collection 7 | 8 | .. autosummary:: 9 | :toctree: ../api 10 | 11 | Collection 12 | from_Cary 13 | from_directory 14 | -------------------------------------------------------------------------------- /docs/api/WrightTools.data.Axis.rst: -------------------------------------------------------------------------------- 1 | WrightTools.data.Axis 2 | ===================== 3 | 4 | .. currentmodule:: WrightTools.data 5 | 6 | .. autoclass:: Axis 7 | :show-inheritance: 8 | 9 | 10 | .. automethod:: __init__ 11 | 12 | 13 | .. rubric:: Methods 14 | 15 | .. autosummary:: 16 | :toctree: WrightTools.data.Axis 17 | 18 | ~Axis.convert 19 | ~Axis.max 20 | ~Axis.min 21 | 22 | 23 | 24 | 25 | 26 | .. rubric:: Attributes 27 | 28 | .. autosummary:: 29 | :toctree: WrightTools.data.Axis 30 | 31 | ~Axis.full 32 | ~Axis.identity 33 | ~Axis.label 34 | ~Axis.masked 35 | ~Axis.natural_name 36 | ~Axis.ndim 37 | ~Axis.points 38 | ~Axis.shape 39 | ~Axis.size 40 | ~Axis.units_kind 41 | ~Axis.variables 42 | 43 | 44 | -------------------------------------------------------------------------------- /docs/api/WrightTools.data.Channel.rst: -------------------------------------------------------------------------------- 1 | WrightTools.data.Channel 2 | ======================== 3 | 4 | .. currentmodule:: WrightTools.data 5 | 6 | .. autoclass:: Channel 7 | :show-inheritance: 8 | 9 | 10 | .. automethod:: __init__ 11 | 12 | 13 | .. rubric:: Methods 14 | 15 | .. autosummary:: 16 | :toctree: WrightTools.data.Channel 17 | 18 | ~Channel.argmax 19 | ~Channel.argmin 20 | ~Channel.chunkwise 21 | ~Channel.clip 22 | ~Channel.convert 23 | ~Channel.log 24 | ~Channel.log10 25 | ~Channel.log2 26 | ~Channel.mag 27 | ~Channel.max 28 | ~Channel.min 29 | ~Channel.normalize 30 | ~Channel.slices 31 | ~Channel.symmetric_root 32 | ~Channel.trim 33 | 34 | 35 | 36 | 37 | 38 | .. rubric:: Attributes 39 | 40 | .. autosummary:: 41 | :toctree: WrightTools.data.Channel 42 | 43 | ~Channel.attrs 44 | ~Channel.class_name 45 | ~Channel.dtype 46 | ~Channel.file 47 | ~Channel.fillvalue 48 | ~Channel.flush 49 | ~Channel.full 50 | ~Channel.fullpath 51 | ~Channel.major_extent 52 | ~Channel.minor_extent 53 | ~Channel.name 54 | ~Channel.natural_name 55 | ~Channel.ndim 56 | ~Channel.null 57 | ~Channel.parent 58 | ~Channel.points 59 | ~Channel.shape 60 | ~Channel.signed 61 | ~Channel.size 62 | ~Channel.units 63 | ~Channel.value 64 | 65 | 66 | -------------------------------------------------------------------------------- /docs/api/WrightTools.data.Constant.rst: -------------------------------------------------------------------------------- 1 | WrightTools.data.Constant 2 | ========================= 3 | 4 | .. currentmodule:: WrightTools.data 5 | 6 | .. autoclass:: Constant 7 | :show-inheritance: 8 | 9 | 10 | .. automethod:: __init__ 11 | 12 | 13 | .. rubric:: Methods 14 | 15 | .. autosummary:: 16 | :toctree: WrightTools.data.Constant 17 | 18 | ~Constant.convert 19 | ~Constant.max 20 | ~Constant.min 21 | 22 | 23 | 24 | 25 | 26 | .. rubric:: Attributes 27 | 28 | .. autosummary:: 29 | :toctree: WrightTools.data.Constant 30 | 31 | ~Constant.full 32 | ~Constant.identity 33 | ~Constant.label 34 | ~Constant.masked 35 | ~Constant.natural_name 36 | ~Constant.ndim 37 | ~Constant.points 38 | ~Constant.shape 39 | ~Constant.size 40 | ~Constant.std 41 | ~Constant.units_kind 42 | ~Constant.value 43 | ~Constant.variables 44 | 45 | 46 | -------------------------------------------------------------------------------- /docs/api/WrightTools.data.Data.rst: -------------------------------------------------------------------------------- 1 | WrightTools.data.Data 2 | ===================== 3 | 4 | .. currentmodule:: WrightTools.data 5 | 6 | .. autoclass:: Data 7 | :show-inheritance: 8 | 9 | 10 | .. automethod:: __init__ 11 | 12 | 13 | .. rubric:: Methods 14 | 15 | .. autosummary:: 16 | :toctree: WrightTools.data.Data 17 | 18 | ~Data.bring_to_front 19 | ~Data.chop 20 | ~Data.clear 21 | ~Data.close 22 | ~Data.collapse 23 | ~Data.convert 24 | ~Data.copy 25 | ~Data.create_channel 26 | ~Data.create_constant 27 | ~Data.create_dataset 28 | ~Data.create_group 29 | ~Data.create_variable 30 | ~Data.flush 31 | ~Data.get 32 | ~Data.get_nadir 33 | ~Data.get_zenith 34 | ~Data.gradient 35 | ~Data.heal 36 | ~Data.level 37 | ~Data.map_variable 38 | ~Data.moment 39 | ~Data.offset 40 | ~Data.print_tree 41 | ~Data.prune 42 | ~Data.remove_channel 43 | ~Data.remove_constant 44 | ~Data.remove_variable 45 | ~Data.rename_channels 46 | ~Data.rename_variables 47 | ~Data.save 48 | ~Data.set_constants 49 | ~Data.share_nans 50 | ~Data.smooth 51 | ~Data.split 52 | ~Data.transform 53 | ~Data.update 54 | ~Data.zoom 55 | 56 | 57 | 58 | 59 | 60 | .. rubric:: Attributes 61 | 62 | .. autosummary:: 63 | :toctree: WrightTools.data.Data 64 | 65 | ~Data.attrs 66 | ~Data.axes 67 | ~Data.axis_expressions 68 | ~Data.axis_names 69 | ~Data.channel_names 70 | ~Data.channels 71 | ~Data.class_name 72 | ~Data.constant_expressions 73 | ~Data.constant_names 74 | ~Data.constant_units 75 | ~Data.constants 76 | ~Data.created 77 | ~Data.datasets 78 | ~Data.file 79 | ~Data.fullpath 80 | ~Data.id 81 | ~Data.item_names 82 | ~Data.kind 83 | ~Data.name 84 | ~Data.natural_name 85 | ~Data.ndim 86 | ~Data.parent 87 | ~Data.ref 88 | ~Data.regionref 89 | ~Data.shape 90 | ~Data.size 91 | ~Data.source 92 | ~Data.units 93 | ~Data.variable_names 94 | ~Data.variables 95 | 96 | 97 | -------------------------------------------------------------------------------- /docs/api/WrightTools.data.Variable.rst: -------------------------------------------------------------------------------- 1 | WrightTools.data.Variable 2 | ========================= 3 | 4 | .. currentmodule:: WrightTools.data 5 | 6 | .. autoclass:: Variable 7 | :show-inheritance: 8 | 9 | 10 | .. automethod:: __init__ 11 | 12 | 13 | .. rubric:: Methods 14 | 15 | .. autosummary:: 16 | :toctree: WrightTools.data.Variable 17 | 18 | ~Variable.argmax 19 | ~Variable.argmin 20 | ~Variable.chunkwise 21 | ~Variable.clip 22 | ~Variable.convert 23 | ~Variable.log 24 | ~Variable.log10 25 | ~Variable.log2 26 | ~Variable.max 27 | ~Variable.min 28 | ~Variable.slices 29 | ~Variable.symmetric_root 30 | ~Variable.write_direct 31 | 32 | 33 | 34 | 35 | 36 | .. rubric:: Attributes 37 | 38 | .. autosummary:: 39 | :toctree: WrightTools.data.Variable 40 | 41 | ~Variable.attrs 42 | ~Variable.class_name 43 | ~Variable.dtype 44 | ~Variable.file 45 | ~Variable.fillvalue 46 | ~Variable.flush 47 | ~Variable.full 48 | ~Variable.fullpath 49 | ~Variable.label 50 | ~Variable.name 51 | ~Variable.natural_name 52 | ~Variable.ndim 53 | ~Variable.parent 54 | ~Variable.points 55 | ~Variable.shape 56 | ~Variable.size 57 | ~Variable.units 58 | 59 | 60 | -------------------------------------------------------------------------------- /docs/api/WrightTools.data.rst: -------------------------------------------------------------------------------- 1 | WrightTools\.data package 2 | ========================= 3 | 4 | .. currentmodule:: WrightTools.data 5 | 6 | .. automodule:: WrightTools.data 7 | 8 | .. autosummary:: 9 | :toctree: ../api 10 | 11 | Data 12 | Axis 13 | Channel 14 | Constant 15 | Variable 16 | join 17 | from_BrunoldrRaman 18 | from_COLORS 19 | from_databroker 20 | from_JASCO 21 | from_KENT 22 | from_Aramis 23 | from_ocean_optics 24 | from_PyCMDS 25 | from_shimadzu 26 | from_Solis 27 | from_spcm 28 | from_Tensor27 29 | -------------------------------------------------------------------------------- /docs/api/WrightTools.datasets.rst: -------------------------------------------------------------------------------- 1 | WrightTools\.datasets package 2 | ============================= 3 | 4 | .. automodule:: WrightTools.datasets 5 | :members: 6 | :special-members: __init__ 7 | :undoc-members: 8 | :show-inheritance: 9 | 10 | -------------------------------------------------------------------------------- /docs/api/WrightTools.diagrams.WMEL.rst: -------------------------------------------------------------------------------- 1 | WrightTools\.diagrams\.WMEL module 2 | ================================== 3 | 4 | .. automodule:: WrightTools.diagrams.WMEL 5 | :members: 6 | :special-members: __init__ 7 | :undoc-members: 8 | :show-inheritance: 9 | -------------------------------------------------------------------------------- /docs/api/WrightTools.diagrams.delay.rst: -------------------------------------------------------------------------------- 1 | WrightTools\.diagrams\.delay module 2 | =================================== 3 | 4 | .. automodule:: WrightTools.diagrams.delay 5 | :members: 6 | :special-members: __init__ 7 | :undoc-members: 8 | :show-inheritance: 9 | -------------------------------------------------------------------------------- /docs/api/WrightTools.diagrams.rst: -------------------------------------------------------------------------------- 1 | WrightTools\.diagrams package 2 | ============================= 3 | 4 | .. automodule:: WrightTools.diagrams 5 | :members: 6 | :special-members: __init__ 7 | :undoc-members: 8 | :show-inheritance: 9 | 10 | .. toctree:: 11 | 12 | WrightTools.diagrams.WMEL 13 | WrightTools.diagrams.delay 14 | 15 | -------------------------------------------------------------------------------- /docs/api/WrightTools.exceptions.rst: -------------------------------------------------------------------------------- 1 | WrightTools\.exceptions module 2 | ============================== 3 | 4 | .. currentmodule:: WrightTools.exceptions 5 | 6 | .. automodule:: WrightTools.exceptions 7 | 8 | .. autosummary:: 9 | :toctree: ../api 10 | 11 | DimensionalityError 12 | EntireDatasetInMemoryWarning 13 | FileExistsError 14 | MultidimensionalAxisError 15 | NameNotUniqueError 16 | ObjectExistsWarning 17 | TypeError 18 | UnitsError 19 | ValueError 20 | VisibleDeprecationWarning 21 | WrightToolsException 22 | WrightToolsWarning 23 | WrongFileTypeWarning 24 | -------------------------------------------------------------------------------- /docs/api/WrightTools.kit.INI.rst: -------------------------------------------------------------------------------- 1 | WrightTools.kit.INI 2 | =================== 3 | 4 | .. autoclass:: WrightTools.kit.INI 5 | :members: 6 | :special-members: __init__ 7 | :show-inheritance: 8 | 9 | -------------------------------------------------------------------------------- /docs/api/WrightTools.kit.Spline.rst: -------------------------------------------------------------------------------- 1 | WrightTools.kit.Spline 2 | ====================== 3 | 4 | .. autoclass:: WrightTools.kit.Spline 5 | :members: 6 | :special-members: __init__, __call__ 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/api/WrightTools.kit.TimeStamp.rst: -------------------------------------------------------------------------------- 1 | WrightTools.kit.TimeStamp 2 | ========================= 3 | 4 | .. autoclass:: WrightTools.kit.TimeStamp 5 | :members: 6 | :special-members: __init__ 7 | :show-inheritance: 8 | -------------------------------------------------------------------------------- /docs/api/WrightTools.kit.Timer.rst: -------------------------------------------------------------------------------- 1 | WrightTools.kit.Timer 2 | ===================== 3 | 4 | 5 | .. autoclass:: WrightTools.kit.Timer 6 | :members: 7 | :undoc-members: 8 | :special-members: __init__, __enter__, __exit__ 9 | :show-inheritance: 10 | 11 | .. attribute:: start 12 | 13 | Timestamp for start in seconds. 14 | 15 | .. attribute:: end 16 | 17 | Timestamp for end in seconds. 18 | 19 | .. attribute:: interval 20 | 21 | Timedelta for end - start in seconds. 22 | -------------------------------------------------------------------------------- /docs/api/WrightTools.kit.rst: -------------------------------------------------------------------------------- 1 | WrightTools\.kit module 2 | ======================= 3 | 4 | .. currentmodule:: WrightTools.kit 5 | 6 | .. automodule:: WrightTools.kit 7 | 8 | .. autosummary:: 9 | :toctree: ../api 10 | 11 | INI 12 | Spline 13 | TimeStamp 14 | Timer 15 | closest_pair 16 | diff 17 | discover_dimensions 18 | enforce_mask_shape 19 | fft 20 | flatten_list 21 | fluence 22 | get_index 23 | get_path_matching 24 | glob_handler 25 | intersperse 26 | joint_shape 27 | leastsqfitter 28 | mask_reduce 29 | mono_resolution 30 | nm_width 31 | orthogonal 32 | pairwise 33 | remove_nans_1D 34 | share_nans 35 | smooth_1D 36 | string2identifier 37 | svd 38 | symmetric_sqrt 39 | timestamp_from_RFC3339 40 | unique 41 | valid_index 42 | zoom2D 43 | -------------------------------------------------------------------------------- /docs/api/WrightTools.open.rst: -------------------------------------------------------------------------------- 1 | WrightTools.open 2 | ================ 3 | 4 | .. currentmodule:: WrightTools 5 | 6 | .. autofunction:: open 7 | -------------------------------------------------------------------------------- /docs/api/WrightTools.units.rst: -------------------------------------------------------------------------------- 1 | WrightTools\.units module 2 | ========================= 3 | 4 | .. currentmodule:: WrightTools.units 5 | 6 | .. automodule:: WrightTools.units 7 | 8 | .. autosummary:: 9 | :toctree: ../api 10 | 11 | convert 12 | get_symbol 13 | get_valid_conversions 14 | is_valid_conversion 15 | kind 16 | ureg 17 | -------------------------------------------------------------------------------- /docs/api/modules.rst: -------------------------------------------------------------------------------- 1 | WrightTools API 2 | =============== 3 | 4 | .. toctree:: 5 | :maxdepth: 6 6 | 7 | WrightTools.artists 8 | WrightTools.collection 9 | WrightTools.data 10 | WrightTools.diagrams 11 | WrightTools.exceptions 12 | WrightTools.kit 13 | WrightTools.open 14 | WrightTools.units 15 | -------------------------------------------------------------------------------- /docs/install.rst: -------------------------------------------------------------------------------- 1 | .. _install: 2 | 3 | Installation 4 | ============ 5 | 6 | WrightTools requires Python 3.6 or newer. 7 | 8 | conda-forge 9 | ----------- 10 | 11 | Conda_ is a multilingual package/environment manager. 12 | It seamlessly handles non-Python library dependencies which many scientific Python tools rely upon. 13 | Conda is recommended, especially for Windows users. 14 | If you don't have Python yet, start by `installing Anaconda`_ or `miniconda`_. 15 | 16 | `conda-forge`_ is a community-driven conda channel. `conda-forge contains a WrightTools feedstock`_. 17 | 18 | .. code-block:: bash 19 | 20 | conda config --add channels conda-forge 21 | conda install wrighttools 22 | 23 | To upgrade: 24 | 25 | .. code-block:: bash 26 | 27 | conda update wrighttools 28 | 29 | pip 30 | --- 31 | 32 | pip_ is Python's official package manager. `WrightTools is hosted on PyPI`_. 33 | 34 | 35 | .. code-block:: bash 36 | 37 | pip install wrighttools 38 | 39 | To upgrade: 40 | 41 | .. code-block:: bash 42 | 43 | pip install wrighttools --upgrade 44 | 45 | .. _Conda: https://conda.io/docs/intro.html 46 | .. _installing Anaconda: https://www.anaconda.com/products/individual#Downloads 47 | .. _conda-forge: https://conda-forge.org/ 48 | .. _conda-forge contains a WrightTools feedstock: https://github.com/conda-forge/wrighttools-feedstock 49 | .. _miniconda: https://conda.io/miniconda.html 50 | .. _pip: https://pypi.python.org/pypi/pip 51 | .. _WrightTools is hosted on PyPI: https://pypi.org/project/WrightTools/ 52 | -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | pushd %~dp0 4 | 5 | REM Command file for Sphinx documentation 6 | 7 | if "%SPHINXBUILD%" == "" ( 8 | set SPHINXBUILD=python -msphinx 9 | ) 10 | set SOURCEDIR=. 11 | set BUILDDIR=_build 12 | set SPHINXPROJ=WrightTools 13 | 14 | if "%1" == "" goto help 15 | 16 | %SPHINXBUILD% >NUL 2>NUL 17 | if errorlevel 9009 ( 18 | echo. 19 | echo.The Sphinx module was not found. Make sure you have Sphinx installed, 20 | echo.then set the SPHINXBUILD environment variable to point to the full 21 | echo.path of the 'sphinx-build' executable. Alternatively you may add the 22 | echo.Sphinx directory to PATH. 23 | echo. 24 | echo.If you don't have Sphinx installed, grab it from 25 | echo.http://sphinx-doc.org/ 26 | exit /b 1 27 | ) 28 | 29 | %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 30 | goto end 31 | 32 | :help 33 | %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% 34 | 35 | :end 36 | popd 37 | -------------------------------------------------------------------------------- /examples/DOVE_transform.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | DOVE transform 4 | ================= 5 | 6 | An example of transform on a dataset from a DOVE experiment. 7 | """ 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | import WrightTools as wt 12 | from WrightTools import datasets 13 | 14 | p = datasets.KENT.LDS821_DOVE 15 | data = wt.data.from_KENT(p, ignore=["d1", "d2", "wm"], verbose=False) 16 | 17 | fig, gs = wt.artists.create_figure(width="double", cols=[1, 1, "cbar"], wspace=0.7) 18 | 19 | # as taken 20 | ax = plt.subplot(gs[0, 0]) 21 | data.transform("w2", "w1") 22 | ax.pcolor(data) 23 | wt.artists.set_ax_labels(xlabel=data.w2.label, ylabel=data.w1.label) 24 | ax.grid() 25 | ax.set_title("as taken", fontsize=20) 26 | 27 | # transformed 28 | ax = plt.subplot(gs[0, 1]) 29 | data.transform("w2", "w1-w2") 30 | ax.pcolor(data) 31 | wt.artists.set_ax_labels(xlabel=data.w2.label) 32 | ax.grid() 33 | ax.set_title("transformed", fontsize=20) 34 | 35 | # colorbar 36 | cax = plt.subplot(gs[0, -1]) 37 | wt.artists.plot_colorbar(cax, label="Intensity") 38 | -------------------------------------------------------------------------------- /examples/README.txt: -------------------------------------------------------------------------------- 1 | .. _auto_examples-index: 2 | 3 | Gallery 4 | ======= 5 | -------------------------------------------------------------------------------- /examples/colormaps.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Colormaps 4 | ========= 5 | 6 | Different colormaps. 7 | """ 8 | 9 | import matplotlib.pyplot as plt 10 | from matplotlib import cm 11 | 12 | import WrightTools as wt 13 | from WrightTools import datasets 14 | 15 | fig, gs = wt.artists.create_figure(width="double", cols=[1, 1, "cbar"], nrows=3) 16 | 17 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 18 | data = wt.open(p) 19 | data.level(0, 2, -3) 20 | data.convert("eV") 21 | data.ai0.symmetric_root(2) 22 | data = data.chop("w1=wm", "w2", at={"d2": [-600, "fs"]})[0] 23 | data.ai0.normalize() 24 | data.ai0.clip(min=0, replace="value") 25 | 26 | 27 | def fill_row(row, cmap): 28 | # greyscale 29 | ax = plt.subplot(gs[row, 0]) 30 | ax.pcolor(data, cmap=wt.artists.grayify_cmap(cmap)) 31 | # color 32 | ax = plt.subplot(gs[row, 1]) 33 | ax.pcolor(data, cmap=cmap) 34 | # cbar 35 | cax = plt.subplot(gs[row, 2]) 36 | wt.artists.plot_colorbar(cax=cax, label=cmap.name, cmap=cmap) 37 | wt.artists.set_ax_labels(cax, yticks=False) 38 | 39 | 40 | cmap = wt.artists.colormaps["default"] 41 | fill_row(0, cmap) 42 | cmap = wt.artists.colormaps["wright"] 43 | fill_row(1, cmap) 44 | cmap = cm.viridis 45 | fill_row(2, cmap) 46 | 47 | # label 48 | wt.artists.set_fig_labels(xlabel=data.w1__e__wm.label, ylabel=data.w2.label, col=slice(0, 1)) 49 | -------------------------------------------------------------------------------- /examples/filters.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | # -*- coding: utf-8 -*- 3 | """ 4 | Plotting Multiple Lines 5 | ======================= 6 | 7 | A quick demonstration of how to plot multiple lines on the same 8 | set of axes, using :meth:`create_figure` to have a set of axes 9 | which can plot data objects directly. 10 | 11 | The dataset is a set of optical filters transmission spectra. 12 | """ 13 | 14 | import WrightTools as wt 15 | from WrightTools import datasets 16 | from matplotlib import pyplot as plt 17 | 18 | p = datasets.Cary.filters 19 | col = wt.collection.from_Cary(p) 20 | 21 | fig, gs = wt.artists.create_figure(width="double", default_aspect=0.5) 22 | ax = plt.subplot(gs[0]) 23 | 24 | for data in col.values(): 25 | if data.natural_name in ("600LP", "550LP2"): 26 | continue 27 | data.convert("wn", verbose=False) 28 | ax.plot(data, label=data.natural_name) 29 | 30 | 31 | ax.set_ylabel("%T") 32 | ax.set_xlabel("Frequency (cm$^{-1}$)") 33 | ax.legend() 34 | -------------------------------------------------------------------------------- /examples/fringes_transform.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Fringes transform 4 | ================= 5 | 6 | An example of transform on a dataset containing fringes. 7 | """ 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | import WrightTools as wt 12 | from WrightTools import datasets 13 | 14 | p = datasets.PyCMDS.w2_w1_000 15 | data = wt.data.from_PyCMDS(p) 16 | 17 | data.signal_mean.symmetric_root(2) # to amplitude level 18 | data.convert("wn") 19 | 20 | fig, gs = wt.artists.create_figure(width="double", cols=[1, 1, "cbar"]) 21 | 22 | # as taken 23 | ax = plt.subplot(gs[0, 0]) 24 | ax.pcolor(data) 25 | wt.artists.set_ax_labels(xlabel=data.w2.label, ylabel=data.w1.label) 26 | ax.grid() 27 | ax.set_title("as taken", fontsize=20) 28 | 29 | # transformed 30 | ax = plt.subplot(gs[0, 1]) 31 | data.transform("wm", "w1") 32 | data.convert("wn") 33 | ax.pcolor(data) 34 | wt.artists.set_ax_labels(xlabel=data.wm.label, yticks=False) 35 | ax.grid() 36 | ax.set_title("transformed", fontsize=20) 37 | 38 | # colorbar 39 | cax = plt.subplot(gs[0, -1]) 40 | wt.artists.plot_colorbar(cax, label="amplitude") 41 | -------------------------------------------------------------------------------- /examples/gradient.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Gradient 4 | ======== 5 | 6 | Demonstration of the gradient method. 7 | """ 8 | 9 | import numpy as np 10 | import WrightTools as wt 11 | 12 | data = wt.data.Data() 13 | data.create_variable("w1", np.linspace(-10, 10, 100)) 14 | data.create_channel("sig", 1 / (np.pi * (1 + (data.w1[:] - 1) ** 2))) 15 | data.transform("w1") 16 | data.gradient("w1") 17 | 18 | wt.artists.quick1D(data) 19 | wt.artists.quick1D(data, channel="sig_w1_gradient") 20 | -------------------------------------------------------------------------------- /examples/heal.py: -------------------------------------------------------------------------------- 1 | """ 2 | Heal 3 | ==== 4 | 5 | An example of how heal works. 6 | """ 7 | 8 | import numpy as np 9 | from matplotlib import pyplot as plt 10 | import WrightTools as wt 11 | 12 | # create original arrays 13 | x = np.linspace(-3, 3, 31)[:, None] 14 | y = np.linspace(-3, 3, 31)[None, :] 15 | arr = np.exp(-1 * (x**2 + y**2)) 16 | # create damaged array 17 | arr2 = arr.copy() 18 | np.random.seed(11) # set seed for reproducibility 19 | arr2[np.random.random(arr2.shape) < 0.2] = np.nan 20 | # create data object 21 | d = wt.data.Data() 22 | d.create_variable("x", values=x) 23 | d.create_variable("y", values=y) 24 | d.create_channel("original", arr) 25 | d.create_channel("damaged", arr2) 26 | d.create_channel("healed", arr2) 27 | d.transform("x", "y") 28 | # heal 29 | d.heal(channel="healed") 30 | # create figure 31 | fig, gs = wt.artists.create_figure(cols=[1, 1, 1]) 32 | for i in range(3): 33 | ax = plt.subplot(gs[i]) 34 | ax.pcolor(d, channel=i) 35 | ax.set_title(d.channel_names[i]) 36 | ticks = [-2, 0, 2] 37 | wt.artists.set_fig_labels( 38 | xlabel=d.axes[0].label, ylabel=d.axes[1].label, xticks=ticks, yticks=ticks 39 | ) 40 | -------------------------------------------------------------------------------- /examples/join.py: -------------------------------------------------------------------------------- 1 | """ 2 | Join 3 | ===== 4 | 5 | Some examples of how joining works. 6 | """ 7 | 8 | import numpy as np 9 | from matplotlib import pyplot as plt 10 | import WrightTools as wt 11 | 12 | a = wt.data.Data(name="a") 13 | b = wt.data.Data(name="b") 14 | a.create_variable("x", np.linspace(0, 10, 51)[:, None]) 15 | b.create_variable("x", np.linspace(5, 15, 51)[:, None]) 16 | a.create_variable("y", np.linspace(0, 10, 51)[None, :]) 17 | b.create_variable("y", np.linspace(0, 10, 51)[None, :]) 18 | 19 | a.create_channel("z", np.sin(a.x[:]) * np.cos(a.y[:]) + 1) 20 | b.create_channel("z", 5 * np.exp(-((b.x[:] - 10) ** 2)) * np.exp(-((b.y[:] - 5) ** 2)) + 1) 21 | a.transform("x", "y") 22 | b.transform("x", "y") 23 | 24 | 25 | first = wt.data.join([a, b], name="first") 26 | last = wt.data.join([a, b], method="last", name="last") 27 | min = wt.data.join([a, b], method="min", name="min") 28 | max = wt.data.join([a, b], method="max", name="max") 29 | mean = wt.data.join([a, b], method="mean", name="mean") 30 | 31 | # Plot the splits in columns 32 | fig, gs = wt.artists.create_figure(nrows=4, cols=[1, 1]) 33 | for i, da in enumerate([a, b, first, last, min, max, mean]): 34 | ax = plt.subplot(gs[i]) 35 | ax.pcolor(da, vmin=0, vmax=6) 36 | wt.artists.corner_text(da.natural_name, ax=ax) 37 | ax.set_xlim(first.axes[0].min(), first.axes[0].max()) 38 | ax.set_ylim(first.axes[1].min(), first.axes[1].max()) 39 | 40 | wt.artists.set_fig_labels(xlabel=a.axes[0].label, ylabel=a.axes[1].label) 41 | -------------------------------------------------------------------------------- /examples/label_delay_space.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Label delay space 4 | ================= 5 | 6 | Using WrightTools to label delay space. 7 | """ 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | import WrightTools as wt 12 | from WrightTools import datasets 13 | 14 | fig, gs = wt.artists.create_figure(width="double", cols=[1, 1, "cbar"]) 15 | 16 | 17 | def set_lim(ax): 18 | ax.set_xlim(-175, 175) 19 | ax.set_ylim(-175, 175) 20 | 21 | 22 | # traditional delay space 23 | ax = plt.subplot(gs[0, 0]) 24 | p = datasets.PyCMDS.d1_d2_000 25 | data = wt.data.from_PyCMDS(p) 26 | data.convert("fs") 27 | data.channels[0].symmetric_root(2) 28 | data.channels[0].normalize() 29 | data.channels[0].clip(min=0, replace="value") 30 | ax.pcolor(data) 31 | wt.diagrams.delay.label_sectors(ax=ax) # using default labels 32 | set_lim(ax) 33 | ax.set_title(r"$\mathsf{\vec{k}_1 - \vec{k}_2 + \vec{k}_{2^\prime}}$", fontsize=20) 34 | 35 | # conjugate delay space 36 | ax = plt.subplot(gs[0, 1]) 37 | p = datasets.PyCMDS.d1_d2_001 38 | data = wt.data.from_PyCMDS(p) 39 | data.convert("fs") 40 | data.channels[0].symmetric_root(2) 41 | data.channels[0].normalize() 42 | data.channels[0].clip(min=0, replace="value") 43 | ax.pcolor(data) 44 | labels = ["II", "I", "III", "V", "VI", "IV"] 45 | wt.diagrams.delay.label_sectors(ax=ax, labels=labels) 46 | set_lim(ax) 47 | ax.set_title(r"$\mathsf{\vec{k}_1 + \vec{k}_2 - \vec{k}_{2^\prime}}$", fontsize=20) 48 | 49 | # label 50 | wt.artists.set_fig_labels(xlabel=data.d1.label, ylabel=data.d2.label) 51 | 52 | # colorbar 53 | cax = plt.subplot(gs[:, -1]) 54 | wt.artists.plot_colorbar(cax=cax, label="amplitude") 55 | -------------------------------------------------------------------------------- /examples/level.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Level 4 | ===== 5 | 6 | Leveling a dataset. 7 | """ 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | import WrightTools as wt 12 | from WrightTools import datasets 13 | 14 | fig, gs = wt.artists.create_figure(width="double", cols=[1, 1, "cbar"]) 15 | 16 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 17 | data = wt.open(p) 18 | data.convert("eV") 19 | data.ai0.symmetric_root(2) 20 | 21 | # as taken 22 | ax = plt.subplot(gs[0, 0]) 23 | chop = data.chop("w1=wm", "d2", at={"w2": [1.7, "eV"]})[0] 24 | chop.ai0.null = chop.ai0.min() # only for example 25 | ax.pcolor(chop) 26 | ax.contour(chop) 27 | 28 | # leveled 29 | ax = plt.subplot(gs[0, 1]) 30 | data.level(0, 2, -3) 31 | chop = data.chop("w1=wm", "d2", at={"w2": [1.7, "eV"]})[0] 32 | chop.ai0.clip(min=0, replace="value") 33 | ax.pcolor(chop, vmin=0) 34 | ax.contour(chop) 35 | 36 | # label 37 | wt.artists.set_fig_labels(xlabel=data.w1__e__wm.label, ylabel=data.d2.label) 38 | 39 | # colorbar 40 | cax = plt.subplot(gs[0, -1]) 41 | wt.artists.plot_colorbar(cax=cax, label="amplitude") 42 | wt.artists.set_ax_labels(cax, yticks=False) 43 | -------------------------------------------------------------------------------- /examples/lineshapes.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Lineshapes 4 | ========== 5 | 6 | Common lineshapes included in kit 7 | """ 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | import WrightTools as wt 12 | 13 | import numpy as np 14 | 15 | 16 | # initiate figure 17 | fig, gs = wt.artists.create_figure(nrows=2, default_aspect=0.6) 18 | axs = [plt.subplot(gs[i]) for i in range(2)] 19 | 20 | # initial parameters 21 | x = np.linspace(-2, 2, 1001) 22 | x0 = 0 23 | FWHM = 1 24 | G = 0.5 25 | # plot all of the real versions 26 | ax = axs[0] 27 | y = wt.kit.gaussian(x, x0, FWHM, norm="height") 28 | ax.plot(x, y, label="Gaussian, height") 29 | y = wt.kit.gaussian(x, x0, FWHM, norm="area") 30 | ax.plot(x, y, label="Gaussian, area") 31 | y = wt.kit.lorentzian_real(x, x0, G, norm="height") 32 | ax.plot(x, y, label="Lorentzian, height") 33 | y = wt.kit.lorentzian_real(x, x0, G, norm="area") 34 | ax.plot(x, y, label="Lorentzian, area") 35 | y = wt.kit.voigt(x, x0, FWHM, G) 36 | ax.plot(x, y / y.max(), label="Voigt") 37 | # plot the complex variants 38 | ax = axs[1] 39 | y = wt.kit.lorentzian_complex(x, x0, G, norm="height_imag") 40 | ax.plot(x, y.real, label="Re[L], height_imag") 41 | ax.plot(x, y.imag, label="Im[L], height_imag") 42 | y = wt.kit.lorentzian_complex(x, x0, G, norm="area_int") 43 | ax.plot(x, y.real, label="Re[L], area_int") 44 | ax.plot(x, y.imag, label="Im[L], area_int") 45 | # finish 46 | for ax in axs: 47 | ax.legend( 48 | bbox_to_anchor=(1.04, 0.5), 49 | loc="center left", 50 | borderaxespad=0, 51 | title="Lineshape, normalization", 52 | ) 53 | ax.grid() 54 | ax.set_xlim(-2, 2) 55 | wt.artists.set_fig_labels(fig, "X", "Y") 56 | -------------------------------------------------------------------------------- /examples/map-variable.py: -------------------------------------------------------------------------------- 1 | """ 2 | Map-Variable 3 | ============ 4 | 5 | An example of how map-variable works. 6 | """ 7 | 8 | import numpy as np 9 | from matplotlib import pyplot as plt 10 | import WrightTools as wt 11 | 12 | # create original arrays 13 | x = np.linspace(1, 5, 11)[:, None] 14 | y = np.linspace(1, 5, 11)[None, :] 15 | arr = np.exp(-1 * (((x - 3) / 0.6) ** 2 + ((y - 3) / 0.6) ** 2)) 16 | # create data object 17 | d = wt.data.Data(name="original") 18 | d.create_variable("x", values=x) 19 | d.create_variable("y", values=y) 20 | d.create_channel("z", arr) 21 | d.transform("x", "y") 22 | # create new data objects 23 | pointsx = np.linspace(x.min(), x.max(), 31) # linear spacing 24 | pointsy = points = np.logspace(0, 0.7, 11) # log spacing 25 | dx = d.map_variable("x", points=pointsx) # just linear along x 26 | dy = d.map_variable("y", points=pointsy) # just log along y 27 | dxy = dx.map_variable("y", points=pointsy) # linear along x and log along y 28 | ds = [d, dx, dy, dxy] 29 | # create figure 30 | fig, gs = wt.artists.create_figure(width="double", cols=[1, 1, 1, 1]) 31 | for i, d in enumerate(ds): 32 | ax = plt.subplot(gs[i]) 33 | ax.pcolor(d) 34 | ax.set_title(d.natural_name) 35 | ax.set_xlim(1, 5) 36 | ax.set_ylim(1, 5) 37 | ticks = [1, 3, 5] 38 | wt.artists.set_fig_labels( 39 | xlabel=d.axes[0].label, ylabel=d.axes[1].label, xticks=ticks, yticks=ticks 40 | ) 41 | -------------------------------------------------------------------------------- /examples/moment_sideplot.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Sideplots and Moments 4 | ===================== 5 | An example showing how to use moments and sideplots. 6 | """ 7 | 8 | import WrightTools as wt 9 | import numpy as np 10 | import matplotlib.pyplot as plt 11 | 12 | 13 | def S(x): 14 | return (1 + np.exp(-1 * x)) ** -1 15 | 16 | 17 | # instantiate data object 18 | d1 = np.linspace(-1, 3, 101)[:, None] 19 | d2 = np.linspace(-1, 3, 102)[None, :] 20 | arr = S(10 * (d1 + 0.5)) * S(10 * d2) * S(-2 * d1) + 0.1 * S(5 * d1) * S(5 * (d2 - 1)) 21 | d = wt.Data(name="test") 22 | d.create_variable("d1", values=d1, units="ps", label="1") 23 | d.create_variable("d2", values=d2, units="ps", label="2") 24 | d.create_channel("z", values=arr) 25 | d.transform("d1", "d2") 26 | 27 | # calculate moments 28 | d.moment(axis="d1", channel=0, moment=0) # integral 29 | d["z_d1_moment_0"].normalize() 30 | d.moment(axis="d1", channel=0, moment=1) # center of mass 31 | d.moment(axis="d2", channel=0, moment=0) # integral 32 | d["z_d2_moment_0"].normalize() 33 | d.moment(axis="d2", channel=0, moment=1) # center of mass 34 | # create figure 35 | fig, gs = wt.artists.create_figure(cols=[1, "cbar"]) 36 | ax = plt.subplot(gs[0]) 37 | # instantiate sideplots 38 | axcorrx = ax.add_sideplot(along="x", pad=0.1, ymin=-0.1, ymax=1.1) 39 | axcorry = ax.add_sideplot(along="y", pad=0.1, ymin=-0.1, ymax=1.1) 40 | # plot data 41 | ax.pcolor(d, autolabel="both") 42 | # plot integral moments in sideplot 43 | axcorrx.plot(d, channel="z_d2_moment_0", color="k", linewidth=3) 44 | # this sideplot is uncouth. 45 | # the independent axis is 'y' and the dependent is 'x' 46 | y_ = d.d2.points 47 | x_ = d["z_d1_moment_0"].points 48 | axcorry.plot(x_, y_, color="k", linewidth=3) 49 | # plot center of mass for each slice 50 | ax.plot(d["z_d1_moment_1"].points, d.d2.points, label="COM along y") 51 | ax.plot(d.d1.points, d["z_d2_moment_1"].points, label="COM along x") 52 | ax.legend(fontsize=12, loc=4) 53 | # grids 54 | for ax_ in [ax, axcorrx, axcorry]: 55 | ax_.grid() 56 | # plot colorbar 57 | cax = plt.subplot(gs[-1]) 58 | wt.artists.plot_colorbar(cax=cax, label="amplitude") 59 | -------------------------------------------------------------------------------- /examples/plot_colormap_components.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Plot colormap components 4 | ======================== 5 | 6 | Quickly plot the RGB components of a colormap. 7 | """ 8 | 9 | import WrightTools as wt 10 | 11 | cmap = wt.artists.colormaps["default"] 12 | wt.artists.plot_colormap_components(cmap) 13 | -------------------------------------------------------------------------------- /examples/quick1D.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Quick 1D 4 | ======== 5 | 6 | A quick 1D plot. 7 | """ 8 | 9 | import WrightTools as wt 10 | from WrightTools import datasets 11 | 12 | ps = datasets.KENT.LDS821_TRSF 13 | data = wt.data.from_KENT(ps, ignore=["d1", "d2", "wm"], verbose=False) 14 | wt.artists.quick1D(data, "w1", at={"w2": [1520, "wn"]}, verbose=False) 15 | -------------------------------------------------------------------------------- /examples/quick2D.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Quick 2D 4 | ======== 5 | 6 | A quick 2D plot. 7 | """ 8 | 9 | import WrightTools as wt 10 | from WrightTools import datasets 11 | 12 | ps = datasets.KENT.LDS821_TRSF 13 | data = wt.data.from_KENT(ps, ignore=["d1", "d2", "wm"], verbose=False) 14 | wt.artists.quick2D(data, verbose=False) 15 | -------------------------------------------------------------------------------- /examples/quick2D_signed.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Quick 2D Signed 4 | =============== 5 | 6 | A quick 2D plot of a signed channel. 7 | """ 8 | 9 | import WrightTools as wt 10 | from WrightTools import datasets 11 | 12 | p = datasets.wt5.v1p0p0_perovskite_TA 13 | data = wt.open(p) 14 | wt.artists.quick2D(data, "w1=wm", "w2", at={"d2": [0, "fs"]}, verbose=False) 15 | -------------------------------------------------------------------------------- /examples/rRaman.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Resonance Raman 4 | =============== 5 | 6 | A Resonance Raman plot. 7 | """ 8 | 9 | import WrightTools as wt 10 | from WrightTools import datasets 11 | 12 | p = datasets.BrunoldrRaman.LDS821_514nm_80mW 13 | data = wt.data.from_BrunoldrRaman(p) 14 | 15 | data.convert("wn", verbose=False) 16 | 17 | wt.artists.quick1D(data) 18 | -------------------------------------------------------------------------------- /examples/split.py: -------------------------------------------------------------------------------- 1 | """ 2 | Split 3 | ===== 4 | 5 | Some examples of how splitting works. 6 | """ 7 | 8 | from matplotlib import pyplot as plt 9 | import WrightTools as wt 10 | from WrightTools import datasets 11 | 12 | d = wt.data.from_PyCMDS(datasets.PyCMDS.w2_w1_000) 13 | 14 | d.convert("wn", convert_variables=True) 15 | 16 | # A simple split along an axis 17 | a = d.split("w2", [7000, 8000]) 18 | # A more complicated split along some diagonal 19 | b = d.split("w1+w2+7000", [20400, 23000], units="wn") 20 | # A particularly strange split 21 | d.create_variable("strange", values=d.channels[0].points / d.channels[0].max()) 22 | c = d.split("strange", [0.2, 0.4]) 23 | 24 | # Plot the splits in columns 25 | fig, gs = wt.artists.create_figure(nrows=len(c), cols=[1, 1, 1]) 26 | for j, (col, title) in enumerate(zip([a, b, c], ["Simple", "Medium", "Advanced"])): 27 | for i, da in enumerate(col.values()): 28 | ax = plt.subplot(gs[i, j]) 29 | if i == 0: 30 | ax.set_title(title) 31 | ax.pcolor(da) 32 | ax.set_xlim(d.axes[0].min(), d.axes[0].max()) 33 | ax.set_ylim(d.axes[1].min(), d.axes[1].max()) 34 | 35 | wt.artists.set_fig_labels(xlabel=d.axes[0].label, ylabel=d.axes[1].label) 36 | -------------------------------------------------------------------------------- /examples/tune_test.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | """ 3 | Tune test 4 | ========= 5 | 6 | An example of transform on a tune test. 7 | """ 8 | 9 | import matplotlib.pyplot as plt 10 | 11 | import WrightTools as wt 12 | from WrightTools import datasets 13 | 14 | p = datasets.PyCMDS.w1_wa_000 15 | data = wt.data.from_PyCMDS(p) 16 | 17 | fig, gs = wt.artists.create_figure(width="double", cols=[1, 0.25, 1, "cbar"]) 18 | 19 | # as taken 20 | ax = plt.subplot(gs[0, 0]) 21 | ax.pcolor(data) 22 | wt.artists.set_ax_labels(xlabel=data.w1__e__wm.label, ylabel=data.wa.label) 23 | ax.grid() 24 | ax.set_title("as taken", fontsize=20) 25 | 26 | # transformed 27 | ax = plt.subplot(gs[0, 2]) 28 | data.transform("w1", "wa-w1") 29 | ax.pcolor(data) 30 | wt.artists.set_ax_labels(xlabel=data.w1.label, ylabel=data.wa__m__w1.label) 31 | ax.grid() 32 | ax.set_title("transformed", fontsize=20) 33 | 34 | # colorbar 35 | cax = plt.subplot(gs[0, -1]) 36 | wt.artists.plot_colorbar(cax, label="intensity") 37 | -------------------------------------------------------------------------------- /logo/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/logo/.gitignore -------------------------------------------------------------------------------- /logo/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/logo/logo.png -------------------------------------------------------------------------------- /logo/peak.h5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/logo/peak.h5 -------------------------------------------------------------------------------- /paper/.gitignore: -------------------------------------------------------------------------------- 1 | # built paper 2 | *paper.pdf 3 | -------------------------------------------------------------------------------- /paper/build.sh: -------------------------------------------------------------------------------- 1 | pandoc paper.md --filter pandoc-citeproc -o paper.pdf 2 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | . -------------------------------------------------------------------------------- /scripts/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/scripts/.gitignore -------------------------------------------------------------------------------- /scripts/checklists.org: -------------------------------------------------------------------------------- 1 | * distribution 2 | ** make a new release on GitHub 3 | ** release to PyPI (if not done by Travis) 4 | *** checkout master on your machine 5 | *** ensure twine is installed / setup on your machine 6 | *** run scripts/upload.sh 7 | *** takes a few minutes before it appears on pip (?) 8 | ** release on conda-forge (If not done by regro-cf-autotick-bot) 9 | *** grab tar.gz SHA from https://pypi.org/project/WrightTools/ (under Download Files) 10 | *** update meta.yaml https://github.com/wright-group/wrighttools-feedstock/blob/master/recipe/meta.yaml 11 | **** version 12 | **** SHA256 13 | **** build number (should be 0 for version bump) 14 | **** dependencies 15 | *** make a PR to conda-forge master 16 | *** wait for checks to complete 17 | *** merge 18 | ** update master VERSION 19 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [aliases] 2 | test=pytest 3 | 4 | [bdist_wheel] 5 | universal=0 6 | 7 | [flake8] 8 | max-line-length = 99 9 | exclude = 10 | .git, 11 | __pycache__, 12 | data, 13 | temp, 14 | *.egg* 15 | docs 16 | count = True 17 | ignore = D105, E203, W503 18 | 19 | [pydocstyle] 20 | convention = numpy 21 | add-ignore = D105 22 | 23 | [metadata] 24 | description_file = README.rst 25 | license_file = LICENSE.txt 26 | 27 | [tool:pytest] 28 | addopts = --durations=10 --cov=WrightTools --verbose --cov-report term:skip-covered 29 | python_files = tests/*.py 30 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/.gitignore -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/__init__.py -------------------------------------------------------------------------------- /tests/artists/test_contour.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | 4 | import WrightTools as wt 5 | from WrightTools import datasets 6 | from matplotlib import pyplot as plt 7 | import shutil 8 | import os 9 | 10 | 11 | def test_contour(): 12 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 13 | p = shutil.copy(p, "./test_contour.wt5") 14 | data = wt.open(p) 15 | os.unlink(p) 16 | data.level(0, 2, -3) 17 | data.convert("eV") 18 | data.ai0.symmetric_root(2) 19 | chop = data.chop("w1=wm", "w2", at={"d2": [-600, "fs"]})[0] 20 | 21 | fig, gs = wt.artists.create_figure() 22 | ax = plt.subplot(gs[0]) 23 | ax.contourf(chop) 24 | ax.contour(chop) 25 | 26 | data.close() 27 | chop.close() 28 | 29 | 30 | def test_contour_lower_rank(): 31 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 32 | p = shutil.copy(p, "./test_contour_lower_rank.wt5") 33 | data = wt.open(p) 34 | os.unlink(p) 35 | data.level(0, 2, -3) 36 | data.convert("eV") 37 | data.ai0.symmetric_root(2) 38 | data.collapse("d2", method="sum") 39 | 40 | fig, gs = wt.artists.create_figure() 41 | ax = plt.subplot(gs[0]) 42 | ax.contourf(data, channel="ai0_d2_sum") 43 | ax.contour(data, channel="ai0_d2_sum") 44 | 45 | data.close() 46 | 47 | 48 | if __name__ == "__main__": 49 | test_contour() 50 | test_contour_lower_rank() 51 | plt.show() 52 | -------------------------------------------------------------------------------- /tests/artists/test_imshow.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | 4 | import WrightTools as wt 5 | from WrightTools import datasets 6 | from matplotlib import pyplot as plt 7 | import numpy as np 8 | 9 | 10 | def test_imshow_transform(): 11 | p = datasets.PyCMDS.d1_d2_000 12 | data = wt.data.from_PyCMDS(p) 13 | 14 | fig, gs = wt.artists.create_figure(cols=[1, 1]) 15 | ax0 = plt.subplot(gs[0]) 16 | data.transform("d1", "d2") 17 | im1 = ax0.imshow(data) 18 | 19 | ax1 = plt.subplot(gs[1]) 20 | data.transform("d2", "d1") 21 | im2 = ax1.imshow(data) 22 | 23 | assert np.all(im1.get_array() == im2.get_array().T) 24 | 25 | data.close() 26 | 27 | 28 | def test_imshow_approx_pcolormesh(): 29 | p = datasets.PyCMDS.w2_w1_000 30 | data = wt.data.from_PyCMDS(p) 31 | 32 | fig, gs = wt.artists.create_figure(cols=[1, 1]) 33 | ax0 = plt.subplot(gs[0]) 34 | mesh = ax0.pcolormesh(data) 35 | ax1 = plt.subplot(gs[1]) 36 | image = ax1.imshow(data) 37 | 38 | lim0 = ax0.get_xlim() + ax0.get_ylim() 39 | lim1 = ax1.get_xlim() + ax1.get_ylim() 40 | assert np.allclose(lim0, lim1, atol=1e-3, rtol=1), f"unequal axis limits: {lim0}, {lim1}" 41 | 42 | bbox = mesh.get_datalim(ax0.transData) 43 | meshbox = [bbox.x0, bbox.x1, bbox.y0, bbox.y1] 44 | imagebox = image.get_extent() 45 | imagebox = [*sorted(imagebox[:2]), *sorted(imagebox[2:])] 46 | assert np.allclose( 47 | meshbox, imagebox, atol=1e-3, rtol=1e-3 48 | ), f"unequal limits: mesh {meshbox} image {imagebox}" 49 | 50 | assert np.isclose(mesh.norm.vmin, image.norm.vmin), "unequal norm.vmin" 51 | assert np.isclose(mesh.norm.vmax, image.norm.vmax), "unequal norm.vmax" 52 | 53 | data.close() 54 | 55 | 56 | if __name__ == "__main__": 57 | test_imshow_transform() 58 | test_imshow_approx_pcolormesh() 59 | -------------------------------------------------------------------------------- /tests/artists/test_pcolor.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | 4 | import WrightTools as wt 5 | from WrightTools import datasets 6 | from matplotlib import pyplot as plt 7 | import shutil 8 | import os 9 | 10 | 11 | def test_pcolor(): 12 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 13 | p = shutil.copy(p, "./test_pcolor.wt5") 14 | data = wt.open(p) 15 | os.unlink(p) 16 | data.level(0, 2, -3) 17 | data.convert("eV") 18 | data.ai0.symmetric_root(2) 19 | chop = data.chop("w1=wm", "w2", at={"d2": [-600, "fs"]})[0] 20 | 21 | fig, gs = wt.artists.create_figure() 22 | ax = plt.subplot(gs[0]) 23 | ax.pcolor(chop) 24 | ax.pcolormesh(chop) 25 | 26 | data.close() 27 | chop.close() 28 | 29 | 30 | def test_pcolor_lower_rank(): 31 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 32 | p = shutil.copy(p, "./test_pcolor_lower_rank.wt5") 33 | data = wt.open(p) 34 | os.unlink(p) 35 | data.level(0, 2, -3) 36 | data.convert("eV") 37 | data.ai0.symmetric_root(2) 38 | data.collapse("d2", method="sum") 39 | 40 | fig, gs = wt.artists.create_figure() 41 | ax = plt.subplot(gs[0]) 42 | ax.pcolor(data, channel="ai0_d2_sum") 43 | ax.pcolormesh(data, channel="ai0_d2_sum") 44 | 45 | data.close() 46 | 47 | 48 | if __name__ == "__main__": 49 | test_pcolor() 50 | test_pcolor_lower_rank() 51 | plt.show() 52 | -------------------------------------------------------------------------------- /tests/artists/test_plot.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | 4 | import WrightTools as wt 5 | from WrightTools import datasets 6 | from matplotlib import pyplot as plt 7 | import shutil 8 | import os 9 | 10 | 11 | def test_plot(): 12 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 13 | p = shutil.copy(p, "./test_plot.wt5") 14 | data = wt.open(p) 15 | os.unlink(p) 16 | data.level(0, 2, -3) 17 | data.convert("eV") 18 | data.ai0.symmetric_root(2) 19 | chop = data.chop("w1=wm", at={"d2": [-600, "fs"], "w2": [2.0, "eV"]})[0] 20 | 21 | fig, gs = wt.artists.create_figure() 22 | ax = plt.subplot(gs[0]) 23 | ax.plot(chop) 24 | 25 | data.close() 26 | chop.close() 27 | 28 | 29 | def test_plot_lower_rank(): 30 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 31 | p = shutil.copy(p, "./test_plot_lower_rank.wt5") 32 | data = wt.open(p) 33 | os.unlink(p) 34 | data.transform("w1", "w2", "d2") 35 | data.level(0, 2, -3) 36 | data.convert("eV") 37 | data.ai0.symmetric_root(2) 38 | data.collapse("d2", method="sum") 39 | data.collapse("w2", method="sum") 40 | 41 | fig, gs = wt.artists.create_figure() 42 | ax = plt.subplot(gs[0]) 43 | ax.plot(data, channel="ai0_d2_sum_w2_sum") 44 | 45 | data.close() 46 | 47 | 48 | if __name__ == "__main__": 49 | test_plot() 50 | test_plot_lower_rank() 51 | plt.show() 52 | -------------------------------------------------------------------------------- /tests/artists/test_quick1D.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | import numpy as np 4 | import WrightTools as wt 5 | from WrightTools import datasets 6 | 7 | 8 | def test_perovskite(): 9 | p = datasets.wt5.v1p0p0_perovskite_TA # axes w1=wm, w2, d2 10 | # A race condition exists where multiple tests access the same file in short order 11 | # this loop will open the file when it becomes available. 12 | while True: 13 | try: 14 | data = wt.open(p) 15 | break 16 | except: 17 | pass 18 | wt.artists.quick1D(data, axis=0, at={"w2": [1.7, "eV"], "d2": [0, "fs"]}) 19 | 20 | 21 | def test_2D(): 22 | w1 = np.linspace(-3, 3, 51) 23 | w2 = np.linspace(-1, 1, 3) 24 | signal = w1[:, None] + w2[None, :] 25 | data = wt.data.Data(name="data") 26 | data.create_channel("signal", values=signal, signed=True) 27 | data.create_variable("w1", values=w1[:, None], units="wn", label="1") 28 | data.create_variable("w2", values=w2[None, :], units="wn", label="2") 29 | data.transform("w1", "w2") 30 | wt.artists.quick1D(data) 31 | 32 | 33 | def test_moment_channel(): 34 | w1 = np.linspace(-2, 2, 51) 35 | w2 = np.linspace(-1, 1, 3) 36 | w3 = np.linspace(1, 3, 5) 37 | signal = np.cos(w1[:, None, None] + w2[None, :, None] + w3[None, None, :]) 38 | data = wt.data.Data(name="data") 39 | data.create_channel("signal", values=signal, signed=True) 40 | data.create_variable("w1", values=w1[:, None, None], units="wn", label="1") 41 | data.create_variable("w2", values=w2[None, :, None], units="wn", label="2") 42 | data.create_variable("w3", values=w3[None, None, :], units="wn", label="3") 43 | data.transform("w1", "w2", "w3") 44 | data.moment(2, 0, 0) 45 | wt.artists.quick1D(data, channel=-1) 46 | 47 | 48 | if __name__ == "__main__": 49 | import matplotlib.pyplot as plt 50 | 51 | plt.close("all") 52 | test_perovskite() 53 | test_2D() 54 | test_moment_channel() 55 | plt.show() 56 | -------------------------------------------------------------------------------- /tests/artists/test_scatter.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import WrightTools as wt 3 | import matplotlib.pyplot as plt 4 | 5 | 6 | def test_scatter_broadcast_vars(): 7 | rng = np.random.default_rng(seed=42) 8 | data = wt.data.Data(name="data") 9 | a = rng.random((50, 1)) 10 | b = rng.random((1, 50)) 11 | data.create_variable("x", values=2 * a - 1) 12 | data.create_variable("y", values=2 * b - 1) 13 | data.create_channel("z", values=np.exp(-(data.x[:] ** 2 + data.y[:] ** 2))) 14 | fig, gs = wt.artists.create_figure() 15 | ax = plt.subplot(gs[0]) 16 | ax.scatter(data, x="x", y="y", channel="z", s=20, alpha=0.5) 17 | data.close() 18 | 19 | 20 | def test_scatter_signed_channel(): 21 | rng = np.random.default_rng(seed=42) 22 | data = wt.data.Data(name="data") 23 | a = rng.random((10**3)) 24 | b = rng.random((10**3)) 25 | data.create_variable("x", values=4 * np.pi * (a - 0.5)) 26 | data.create_variable("y", values=4 * np.pi * (b - 0.5)) 27 | data.create_channel("z", values=np.sin((data.x[:] ** 2 + data.y[:] ** 2) ** 0.5), signed=True) 28 | fig, gs = wt.artists.create_figure() 29 | ax = plt.subplot(gs[0]) 30 | ax.scatter(data, x="x", y="y", channel="z", s=20, alpha=0.5) 31 | data.close() 32 | 33 | 34 | if __name__ == "__main__": 35 | test_scatter_broadcast_vars() 36 | test_scatter_signed_channel() 37 | -------------------------------------------------------------------------------- /tests/citation.py: -------------------------------------------------------------------------------- 1 | """Test citation.""" 2 | 3 | import WrightTools as wt 4 | 5 | 6 | def test_existence(): 7 | assert wt.__citation__ 8 | -------------------------------------------------------------------------------- /tests/collection/collection.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | import WrightTools as wt 3 | import pytest 4 | 5 | 6 | def test_create_collection(): 7 | col = wt.Collection() 8 | child1 = col.create_collection() 9 | with pytest.warns(wt.exceptions.ObjectExistsWarning): 10 | child2 = col.create_collection() 11 | child3 = col.create_collection("path/to/collection") 12 | assert child3.natural_name == "collection" 13 | assert child3.parent.natural_name == "to" 14 | assert "path" in col.item_names 15 | assert isinstance(child3.parent, wt.Collection) 16 | assert child1 == child2 17 | assert child1.natural_name == "collection" 18 | 19 | 20 | def test_create_data(): 21 | col = wt.Collection() 22 | child1 = col.create_data() 23 | with pytest.warns(wt.exceptions.ObjectExistsWarning): 24 | child2 = col.create_data() 25 | child3 = col.create_data("path/to/data") 26 | assert child3.natural_name == "data" 27 | assert child3.parent.natural_name == "to" 28 | assert "path" in col.item_names 29 | assert isinstance(child3.parent, wt.Collection) 30 | assert child1 == child2 31 | assert child1.natural_name == "data" 32 | 33 | 34 | if __name__ == "__main__": 35 | test_create_collection() 36 | test_create_data() 37 | -------------------------------------------------------------------------------- /tests/collection/from_cary.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | import WrightTools as wt 4 | from WrightTools import datasets 5 | 6 | import pathlib 7 | 8 | here = pathlib.Path(__file__).parent.resolve() 9 | 10 | 11 | def test_CuPCtS_H2O_vis(): 12 | p = datasets.Cary.CuPCtS_H2O_vis 13 | col = wt.collection.from_Cary(p) 14 | data = col.sample1 15 | assert col.natural_name == "cary" 16 | assert data.axis_names == ("wavelength",) 17 | assert data.units == ("nm",) 18 | assert data.shape == (141,) 19 | col.close() 20 | 21 | 22 | def test_filters(): 23 | p = datasets.Cary.filters 24 | col = wt.collection.from_Cary(p) 25 | assert len(col) == 11 26 | for d, sh in zip(col.values(), (121, 196, 301, 301, 301, 301, 301, 301, 301, 401, 101)): 27 | assert d.axis_names == ("wavelength",) 28 | assert d.channels[0].natural_name in ("abs", "%t") 29 | assert d.shape == (sh,) 30 | 31 | 32 | def test_duplicate_name(): 33 | p = here.parent / "data" / "test_data" / "duplicate_name.csv" 34 | col = wt.collection.from_Cary(p) 35 | assert len(col) == 2 36 | assert col.item_names == ("sample1_000", "sample1_001") 37 | col.close() 38 | 39 | 40 | if __name__ == "__main__": 41 | test_CuPCtS_H2O_vis() 42 | test_filters() 43 | test_duplicate_name() 44 | -------------------------------------------------------------------------------- /tests/collection/from_directory.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | import os 4 | import WrightTools as wt 5 | from WrightTools import datasets 6 | 7 | 8 | def test_from_directory(): 9 | from_dict = { 10 | "*.data": wt.data.from_PyCMDS, 11 | "*.csv": wt.collection.from_Cary, 12 | "KENT": None, 13 | "COLORS": None, 14 | } 15 | p = datasets.PyCMDS.w1_000 16 | p = os.path.dirname(p) 17 | p = os.path.dirname(p) 18 | col = wt.collection.from_directory(p, from_dict) 19 | # Print the tree in case tests fail, also will catch errors in printing 20 | col.print_tree() 21 | assert col.natural_name == "datasets" 22 | assert col.PyCMDS["w1 000"] 23 | assert col.Cary["CuPCtS_H2O_vis"] 24 | assert "KENT" not in col.item_names 25 | col.close() 26 | 27 | 28 | if __name__ == "__main__": 29 | test_from_directory() 30 | -------------------------------------------------------------------------------- /tests/data/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/data/__init__.py -------------------------------------------------------------------------------- /tests/data/at.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test at.""" 3 | 4 | 5 | # --- import ------------------------------------------------------------------------------------- 6 | 7 | 8 | import WrightTools as wt 9 | from WrightTools import datasets 10 | 11 | 12 | # --- tests -------------------------------------------------------------------------------------- 13 | 14 | 15 | def test_3D_to_1D(): 16 | data = wt.open(datasets.wt5.v1p0p1_MoS2_TrEE_movie) 17 | sliced = data.at(d2=[-50, "fs"], w2=[700, "nm"]) 18 | assert sliced.axis_expressions == ("w1=wm",) 19 | sliced = data.at(w1__e__wm=[605, "nm"], w2=[700, "nm"]) 20 | assert sliced.axis_expressions == ("d2",) 21 | data.close() 22 | sliced.close() 23 | 24 | 25 | def test_chop_equivalence(): 26 | data = wt.open(datasets.wt5.v1p0p1_MoS2_TrEE_movie) 27 | at_data = data.at(d2=[-50, "fs"], w2=[700, "nm"]) 28 | chop_data = data.chop("w1=wm", at={"d2": [-50, "fs"], "w2": [700, "nm"]})[0] 29 | assert at_data.shape == chop_data.shape 30 | assert at_data.axis_expressions == chop_data.axis_expressions 31 | 32 | 33 | if __name__ == "__main__": 34 | test_3D_to_1D() 35 | test_chop_equivalence() 36 | -------------------------------------------------------------------------------- /tests/data/axis/convert_axis.py: -------------------------------------------------------------------------------- 1 | """Test axis unit conversion.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | from WrightTools import datasets 10 | 11 | 12 | # --- define -------------------------------------------------------------------------------------- 13 | 14 | 15 | def test_convert_variables(): 16 | p = datasets.KENT.LDS821_TRSF 17 | ignore = ["d1", "d2", "wm"] 18 | data = wt.data.from_KENT(p, ignore=ignore) 19 | data.w2.convert("meV", convert_variables=True) 20 | assert data.w2.units == "meV" 21 | assert data["w2"].units == "meV" 22 | data.close() 23 | 24 | 25 | def test_units_preserved_on_copy(): 26 | d1 = wt.Data() 27 | d1.create_variable(name="color", values=np.array([1]), units="nm") 28 | d1.create_variable(name="length", values=np.array([1]), units="nm") 29 | d1.transform("color", "length") 30 | 31 | d1.color.convert("wn") 32 | d2 = d1.copy() 33 | assert d2.units == d1.units 34 | assert d2.units == ("wn", "nm") 35 | d2.close() 36 | d1.close() 37 | 38 | 39 | def test_exception(): 40 | p = datasets.PyCMDS.w1_000 41 | data = wt.data.from_PyCMDS(p) 42 | try: 43 | data.w1.convert("fs") 44 | except wt.exceptions.UnitsError: 45 | assert True 46 | else: 47 | assert False 48 | assert data.w1.units == "wn" 49 | assert data["w1"].units == "nm" 50 | data.close() 51 | 52 | 53 | def test_w1_wa(): 54 | p = datasets.PyCMDS.w1_wa_000 55 | data = wt.data.from_PyCMDS(p) 56 | assert data.wa.units == "wn" 57 | data.wa.convert("eV") 58 | assert data.wa.units == "eV" 59 | assert np.isclose(data.wa.max(), 1.5800551001941774) 60 | assert np.isclose(data.wa.min(), 0.6725528801867734) 61 | assert data["wa"].units == "nm" 62 | data.close() 63 | 64 | 65 | def test_wigner(): 66 | p = datasets.COLORS.v2p2_WL_wigner 67 | data = wt.data.from_COLORS(p) 68 | data.d1.convert("ns") 69 | assert data.d1.units == "ns" 70 | assert data["d1"].units == "fs" 71 | data.close() 72 | 73 | 74 | # --- run ----------------------------------------------------------------------------------------- 75 | 76 | 77 | if __name__ == "__main__": 78 | test_convert_variables() 79 | test_units_preserved_on_copy() 80 | test_exception() 81 | test_w1_wa() 82 | test_wigner() 83 | -------------------------------------------------------------------------------- /tests/data/axis/expressions.py: -------------------------------------------------------------------------------- 1 | import WrightTools as wt 2 | 3 | 4 | def test_space_character(): 5 | d = wt.Data() 6 | d.create_variable("w1") 7 | d.create_variable("w2") 8 | d.transform("w1 + w2") 9 | assert d.axis_names == ("w1__p__w2",) 10 | assert d.axis_expressions == ("w1+w2",) 11 | 12 | 13 | if __name__ == "__main__": 14 | test_space_character() 15 | -------------------------------------------------------------------------------- /tests/data/bluesky_data/3dbdd402-434b-4aac-b004-447a2f026d73.msgpack: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/data/bluesky_data/3dbdd402-434b-4aac-b004-447a2f026d73.msgpack -------------------------------------------------------------------------------- /tests/data/bring_to_front.py: -------------------------------------------------------------------------------- 1 | """Test data bring_to_front.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_integer(): 14 | p = datasets.PyCMDS.wm_w2_w1_000 15 | data = wt.data.from_PyCMDS(p) 16 | assert data.channel_names[0] == "signal_diff" 17 | data.bring_to_front(1) 18 | assert data.channel_names[0] == "signal_mean" 19 | data.bring_to_front(1) 20 | assert data.channel_names[0] == "signal_diff" 21 | data.close() 22 | 23 | 24 | def test_name(): 25 | p = datasets.COLORS.v2p2_WL_wigner 26 | data = wt.data.from_COLORS(p) 27 | assert data.channel_names[0] == "ai0" 28 | data.bring_to_front("ai3") 29 | assert data.channel_names[0] == "ai3" 30 | data.close() 31 | -------------------------------------------------------------------------------- /tests/data/channel/normalize.py: -------------------------------------------------------------------------------- 1 | """Test channel normalize.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | from WrightTools import datasets 10 | 11 | 12 | # --- test ---------------------------------------------------------------------------------------- 13 | 14 | 15 | def test_LDS821(): 16 | p = datasets.BrunoldrRaman.LDS821_514nm_80mW 17 | data = wt.data.from_BrunoldrRaman(p) 18 | data.signal.normalize() 19 | assert data.signal.null == 0.0 20 | assert data.signal.max() == 1.0 21 | data.close() 22 | 23 | 24 | def test_LDS821_mag_0p5(): 25 | p = datasets.BrunoldrRaman.LDS821_514nm_80mW 26 | data = wt.data.from_BrunoldrRaman(p) 27 | mag = 0.5 28 | data.signal.normalize(mag) 29 | assert np.isclose(data.signal.null, 0.0) 30 | assert np.isclose(data.signal.max(), mag) 31 | assert np.isclose(data.signal.mag(), mag) 32 | data.close() 33 | 34 | 35 | def test_wigner(): 36 | p = datasets.COLORS.v2p2_WL_wigner 37 | data = wt.data.from_COLORS(p) 38 | data.ai0.normalize() 39 | assert np.isclose(data.ai0.null, 0.0) 40 | assert np.isclose(data.ai0.max(), 1.0) 41 | data.close() 42 | 43 | 44 | def test_negative_wigner(): 45 | p = datasets.COLORS.v2p2_WL_wigner 46 | data = wt.data.from_COLORS(p) 47 | data.ai0 *= -1 48 | data.ai0.signed = True 49 | data.ai0.normalize() 50 | assert np.isclose(data.ai0.null, 0.0) 51 | assert np.isclose(data.ai0.min(), -1.0) 52 | assert np.isclose(data.ai0.mag(), 1.0) 53 | data.close() 54 | 55 | 56 | def test_negative_wigner_mag_1p1(): 57 | p = datasets.COLORS.v2p2_WL_wigner 58 | data = wt.data.from_COLORS(p) 59 | data.ai0 *= -1 60 | data.ai0.signed = True 61 | data.ai0.normalize(1.1) 62 | assert np.isclose(data.ai0.null, 0.0) 63 | assert np.isclose(data.ai0.min(), -1.1) 64 | assert np.isclose(data.ai0.mag(), 1.1) 65 | data.close() 66 | 67 | 68 | # --- run ----------------------------------------------------------------------------------------- 69 | 70 | 71 | if __name__ == "__main__": 72 | test_LDS821() 73 | test_LDS821_mag_0p5() 74 | test_wigner() 75 | test_negative_wigner() 76 | test_negative_wigner_mag_1p1() 77 | -------------------------------------------------------------------------------- /tests/data/channel/null.py: -------------------------------------------------------------------------------- 1 | """Tests to do with null.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | 8 | from WrightTools import datasets 9 | 10 | 11 | # --- test ---------------------------------------------------------------------------------------- 12 | 13 | 14 | def test_setter(): 15 | p = datasets.BrunoldrRaman.LDS821_514nm_80mW 16 | data = wt.data.from_BrunoldrRaman(p) 17 | assert data.signal.null == 0 18 | data.signal.null = 5 19 | assert data.signal.null == 5 20 | data.close() 21 | 22 | 23 | # --- run ----------------------------------------------------------------------------------------- 24 | 25 | 26 | if __name__ == "__main__": 27 | test_setter() 28 | -------------------------------------------------------------------------------- /tests/data/constants.py: -------------------------------------------------------------------------------- 1 | """Tests relating to constants.""" 2 | 3 | import WrightTools as wt 4 | import numpy as np 5 | import re 6 | 7 | 8 | def test_set_remove(): 9 | data = wt.Data() 10 | data.create_variable("x", np.linspace(0, 10)) 11 | data.create_variable("y", np.linspace(0, 10)) 12 | data.create_variable("z", np.zeros(50)) 13 | data.set_constants("x-y", "z") 14 | assert data.constant_names == ("x__m__y", "z") 15 | data.remove_constant("z") 16 | assert data.constant_names == ("x__m__y",) 17 | data.remove_constant(0) 18 | assert data.constant_names == () 19 | 20 | 21 | def test_label(): 22 | data = wt.Data() 23 | data.create_variable("x", np.linspace(0, 10)) 24 | data.create_variable("y", np.linspace(0, 10)) 25 | data.create_variable("z", np.full(50, 2.3), units="fs") 26 | data.z.label = "z" 27 | data.set_constants("x-y", "z") 28 | assert data.constants[1].label == r"$\mathsf{\tau_{z}\,=\,2.3\,fs}$" 29 | 30 | 31 | def test_repr(): 32 | data = wt.Data() 33 | data.create_variable("x", np.linspace(0, 10)) 34 | data.create_variable("y", np.linspace(0, 10)) 35 | data.create_variable("z", np.full(50, 2.3), units="fs") 36 | data.z.label = "z" 37 | data.set_constants("x-y", "z") 38 | assert ( 39 | re.match(r"\", repr(data.constants[0])) 40 | is not None 41 | ) 42 | -------------------------------------------------------------------------------- /tests/data/convert_data.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test data unit conversion.""" 3 | 4 | 5 | # --- import -------------------------------------------------------------------------------------- 6 | 7 | 8 | import numpy as np 9 | 10 | import WrightTools as wt 11 | from WrightTools import datasets 12 | 13 | 14 | # --- define -------------------------------------------------------------------------------------- 15 | 16 | 17 | def test_convert_variables(): 18 | p = datasets.KENT.LDS821_TRSF 19 | ignore = ["d1", "d2"] 20 | data = wt.data.from_KENT(p, ignore=ignore) 21 | data.convert("meV", convert_variables=True) 22 | assert data.w1.units == "meV" 23 | assert data.w2.units == "meV" 24 | assert data["w2"].units == "meV" 25 | assert data["w2"].units == "meV" 26 | # tests that 'inactive' variable is converted 27 | assert data["wm"].units == "meV" 28 | data.close() 29 | 30 | 31 | def test_w1_wa(): 32 | p = datasets.PyCMDS.w1_wa_000 33 | data = wt.data.from_PyCMDS(p) 34 | data.create_constant("w2") 35 | assert data.wa.units == "wn" 36 | assert data.constants[0].units == "nm" 37 | data.convert("eV") 38 | assert data.wa.units == "eV" 39 | assert data.constants[0].units == "eV" 40 | assert np.isclose(data.wa.max(), 1.5800551001941774) 41 | assert np.isclose(data.wa.min(), 0.6725528801867734) 42 | assert data["wa"].units == "nm" 43 | data.close() 44 | 45 | 46 | def test_wigner(): 47 | p = datasets.COLORS.v2p2_WL_wigner 48 | data = wt.data.from_COLORS(p) 49 | data.convert("ns") 50 | assert data.d1.units == "ns" 51 | assert data["d1"].units == "fs" 52 | assert data.wm.units == "nm" 53 | assert data["wm"].units == "nm" 54 | data.close() 55 | 56 | 57 | # --- run ----------------------------------------------------------------------------------------- 58 | 59 | 60 | if __name__ == "__main__": 61 | test_convert_variables() 62 | test_w1_wa() 63 | test_wigner() 64 | -------------------------------------------------------------------------------- /tests/data/created.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | 4 | import WrightTools as wt 5 | from WrightTools import datasets 6 | 7 | 8 | def test_created(): 9 | p = datasets.PyCMDS.w2_w1_000 10 | data = wt.data.from_PyCMDS(p) 11 | 12 | assert int(data.created.unix) == 1487860880 13 | 14 | copy = data.copy() 15 | assert int(copy.created.unix) == 1487860880 16 | 17 | 18 | if __name__ == "__main__": 19 | test_created() 20 | -------------------------------------------------------------------------------- /tests/data/dataset_creation.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | import WrightTools as wt 4 | import numpy as np 5 | import pytest 6 | 7 | import os 8 | 9 | 10 | def test_create_variable(): 11 | data = wt.Data() 12 | child1 = data.create_variable("hi", shape=(10, 10)) 13 | with pytest.warns(wt.exceptions.ObjectExistsWarning): 14 | child2 = data.create_variable("hi", shape=(10, 1)) 15 | assert child1 == child2 16 | assert child2.shape == (10, 10) 17 | 18 | 19 | def test_create_channel(): 20 | data = wt.Data() 21 | child1 = data.create_channel("hi", shape=(10, 10)) 22 | with pytest.warns(wt.exceptions.ObjectExistsWarning): 23 | child2 = data.create_channel("hi", shape=(10, 1)) 24 | assert child1 == child2 25 | assert child2.shape == (10, 10) 26 | 27 | 28 | def test_exception(): 29 | d = wt.Data() 30 | points = np.linspace(0, 1, 51) 31 | d.create_variable(name="w1", points=points, units="eV") 32 | with pytest.raises(wt.exceptions.NameNotUniqueError): 33 | d.create_channel(name="w1") 34 | 35 | 36 | def test_create_compressed_channel(): 37 | data = wt.Data() 38 | child1 = data.create_channel("hi", shape=(1024, 1024), compression="gzip") 39 | data["hi"][:] = 0 40 | assert os.path.getsize(data.filepath) < 1e6 41 | 42 | 43 | if __name__ == "__main__": 44 | test_create_variable() 45 | test_create_channel() 46 | test_exception() 47 | -------------------------------------------------------------------------------- /tests/data/from_BrunoldrRaman.py: -------------------------------------------------------------------------------- 1 | """test from_BrunoldrRaman""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_LDS821_514nm_80mW(): 14 | p = datasets.BrunoldrRaman.LDS821_514nm_80mW 15 | data = wt.data.from_BrunoldrRaman(p) 16 | assert data.shape == (1340,) 17 | assert data.axis_expressions == ("energy",) 18 | assert data.units == ("wn",) 19 | data.close() 20 | -------------------------------------------------------------------------------- /tests/data/from_COLORS.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """test from_COLORS""" 3 | 4 | 5 | # --- import -------------------------------------------------------------------------------------- 6 | 7 | 8 | import numpy as np 9 | import glob 10 | import os 11 | 12 | import WrightTools as wt 13 | from WrightTools import datasets 14 | 15 | 16 | # --- helper functions ---------------------------------------------------------------------------- 17 | 18 | 19 | def isclose(p, data, **kwargs): 20 | if isinstance(p, list): 21 | for i, f in enumerate(p): 22 | dat = np.genfromtxt(f).T 23 | if i == 0: 24 | arr = dat 25 | else: 26 | arr = np.append(arr, dat, axis=1) 27 | else: 28 | arr = np.genfromtxt(p).T 29 | for key, index in kwargs.items(): 30 | raw = arr[index] 31 | raw.shape = data.shape 32 | assert np.isclose(raw.all(), data[key].full.all()) 33 | 34 | 35 | __here__ = os.path.abspath(os.path.dirname(__file__)) 36 | 37 | # --- test ---------------------------------------------------------------------------------------- 38 | 39 | 40 | def test_v0p2_d1_d2_diagonal(): 41 | p = datasets.COLORS.v0p2_d1_d2_diagonal 42 | data = wt.data.from_COLORS(p) 43 | assert data.shape == (21, 21) 44 | assert data.axis_expressions == ("d1", "d2") 45 | assert data.units == ("fs", "fs") 46 | isclose(p, data, d1=6, d2=8, ai0=10, ai1=11, ai2=12) 47 | data.close() 48 | 49 | 50 | def test_v2p1_MoS2_TrEE_movie(): 51 | ps = sorted( 52 | glob.glob( 53 | os.path.join(__here__, "test_data", "COLORS", "v2.1", "MoS2 TrEE movie", "*.dat") 54 | ) 55 | ) 56 | data = wt.data.from_COLORS(ps) 57 | assert data.shape == (41, 41, 23) 58 | assert data.axis_expressions == ("w2", "w1=wm", "d2") 59 | assert data.units == ("nm", "nm", "fs") 60 | isclose(ps, data, wm=7) 61 | data.close() 62 | 63 | 64 | def test_v2p2_WL_wigner(): 65 | p = datasets.COLORS.v2p2_WL_wigner 66 | data = wt.data.from_COLORS(p) 67 | assert data.shape == (241, 51) 68 | assert data.axis_expressions == ("wm", "d1") 69 | assert data.units == ("nm", "fs") 70 | isclose(p, data, wm=7, d1=12, ai0=16, ai1=17, ai2=18) 71 | data.close() 72 | 73 | 74 | # --- run ----------------------------------------------------------------------------------------- 75 | 76 | 77 | if __name__ == "__main__": 78 | test_v0p2_d1_d2_diagonal() 79 | test_v2p1_MoS2_TrEE_movie() 80 | test_v2p2_WL_wigner() 81 | -------------------------------------------------------------------------------- /tests/data/from_JASCO.py: -------------------------------------------------------------------------------- 1 | """test from_JASCO""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import pathlib 7 | 8 | import WrightTools as wt 9 | from WrightTools import datasets 10 | 11 | 12 | # --- test ---------------------------------------------------------------------------------------- 13 | 14 | 15 | def test_PbSe_batch_1(): 16 | p = datasets.JASCO.PbSe_batch_1 17 | data = wt.data.from_JASCO(p) 18 | assert data.shape == (1801,) 19 | assert data.axis_expressions == ("energy",) 20 | assert data.units == ("nm",) 21 | data.close() 22 | 23 | 24 | def test_PbSe_batch_4_2012_02_21(): 25 | p = datasets.JASCO.PbSe_batch_4_2012_02_21 26 | data = wt.data.from_JASCO(p) 27 | assert data.shape == (1251,) 28 | assert data.axis_expressions == ("energy",) 29 | assert data.units == ("nm",) 30 | data.close() 31 | 32 | 33 | def test_PbSe_batch_4_2012_03_15(): 34 | p = datasets.JASCO.PbSe_batch_4_2012_03_15 35 | p = pathlib.Path(p) 36 | data = wt.data.from_JASCO(p) 37 | assert data.shape == (1251,) 38 | assert data.axis_expressions == ("energy",) 39 | assert data.units == ("nm",) 40 | data.close() 41 | 42 | 43 | def test_remote(): 44 | p = "https://osf.io/download/hzsjp/" 45 | data = wt.data.from_JASCO(p) 46 | assert data.shape == (851,) 47 | assert data.axis_expressions == ("energy",) 48 | assert data.units == ("nm",) 49 | -------------------------------------------------------------------------------- /tests/data/from_KENT.py: -------------------------------------------------------------------------------- 1 | """test from_KENT""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | from WrightTools import datasets 10 | 11 | 12 | # --- helper functions ---------------------------------------------------------------------------- 13 | 14 | 15 | def isclose(p, data, ignore=[], ss=(slice(None))): 16 | if isinstance(p, list): 17 | for i, f in enumerate(p): 18 | dat = np.genfromtxt(f).T 19 | if i == 0: 20 | arr = dat 21 | else: 22 | arr = np.append(arr, dat, axis=1) 23 | else: 24 | arr = np.genfromtxt(p).T 25 | for i, key in enumerate(["w1", "w2", "wm", "d1", "d2", "signal", "OPA1", "OPA2"]): 26 | if key in ignore: 27 | continue 28 | raw = arr[i] 29 | raw.shape = data.shape 30 | assert np.isclose(raw.all(), data[key].full[ss].all()) 31 | 32 | 33 | # --- test ---------------------------------------------------------------------------------------- 34 | 35 | 36 | def test_LDS821_TRSF(): 37 | p = datasets.KENT.LDS821_TRSF 38 | ignore = ["wm", "d1", "d2"] 39 | data = wt.data.from_KENT(p, ignore=ignore) 40 | assert data.shape == (71, 71) 41 | assert data.axis_names == ("w2", "w1") 42 | assert data.units == ("wn", "wn") 43 | ss = (slice(None, None, -1), slice(None, None, None)) 44 | isclose(p, data, ignore=ignore, ss=ss) 45 | data.close() 46 | 47 | 48 | def test_PbSe_2D_delay_B(): 49 | p = datasets.KENT.PbSe_2D_delay_B 50 | data = wt.data.from_KENT(p, delay_tolerance=0.01) 51 | assert data.shape == (101, 101) 52 | assert data.axis_names == ("d2", "d1") 53 | assert data.units == ("ps", "ps") 54 | ss = (slice(None, None, None), slice(None, None, -1)) 55 | isclose(p, data, ss=ss, ignore=["d1", "d2"]) 56 | data.close() 57 | 58 | 59 | # --- run ----------------------------------------------------------------------------------------- 60 | 61 | 62 | if __name__ == "__main__": 63 | test_LDS821_TRSF() 64 | test_PbSe_2D_delay_B() 65 | -------------------------------------------------------------------------------- /tests/data/from_LabRAM.py: -------------------------------------------------------------------------------- 1 | import WrightTools as wt 2 | from WrightTools.datasets import LabRAM 3 | 4 | 5 | def test_spectral_units(): 6 | d = wt.data.from_LabRAM(LabRAM.spectrum_nm) 7 | assert d.wm.units == "nm" 8 | d.close() 9 | d = wt.data.from_LabRAM(LabRAM.spectrum_wn) 10 | assert d.wm.units == "wn" 11 | d.close() 12 | 13 | 14 | def test_import_1D(): 15 | d = wt.data.from_LabRAM(LabRAM.spectrum_nm) 16 | d.close() 17 | 18 | 19 | def test_import_2D(): 20 | d = wt.data.from_LabRAM(LabRAM.raman_linescan) 21 | d.close() 22 | 23 | 24 | def test_import_2D_survey(): 25 | d = wt.data.from_LabRAM(LabRAM.survey_nm) 26 | d.close() 27 | 28 | 29 | def test_import_3D(): 30 | d = wt.data.from_LabRAM(LabRAM.map_nm) 31 | d.close() 32 | 33 | 34 | if __name__ == "__main__": 35 | test_spectral_units() 36 | test_import_1D() 37 | test_import_2D() 38 | test_import_2D_survey() 39 | test_import_3D() 40 | -------------------------------------------------------------------------------- /tests/data/from_Solis.py: -------------------------------------------------------------------------------- 1 | """test from_JASCO""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_wm_ypos_fluorescence_with_filter(): 14 | p = datasets.Solis.wm_ypos_fluorescence_with_filter 15 | data = wt.data.from_Solis(p) 16 | assert data.shape == (2560, 2160) 17 | assert data.axis_expressions == ("wm", "yindex") 18 | assert data.units == ("nm", None) 19 | data.close() 20 | 21 | 22 | def test_xpos_ypos_fluorescence(): 23 | p = datasets.Solis.xpos_ypos_fluorescence 24 | data = wt.data.from_Solis(p) 25 | assert data.shape == (2560, 2160) 26 | assert data.axis_expressions == ("xindex", "yindex") 27 | assert data.units == (None, None) 28 | data.close() 29 | 30 | 31 | def test_kinetic(): 32 | p = datasets.Solis.kinetic 33 | data = wt.data.from_Solis(p) 34 | assert data.shape == (10, 20, 20) 35 | assert data.axis_expressions == ("frame", "xindex", "yindex") 36 | assert data.units == (None, None, None) 37 | data.close() 38 | 39 | 40 | if __name__ == "__main__": 41 | test_wm_ypos_fluorescence_with_filter() 42 | test_xpos_ypos_fluorescence() 43 | test_kinetic() 44 | -------------------------------------------------------------------------------- /tests/data/from_Tensor27.py: -------------------------------------------------------------------------------- 1 | """test from_Tensor27""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_CuPCtS_powder_ATR(): 14 | p = datasets.Tensor27.CuPCtS_powder_ATR 15 | data = wt.data.from_Tensor27(p) 16 | assert data.shape == (7259,) 17 | assert data.axis_names == ("energy",) 18 | data.close() 19 | 20 | 21 | # --- run ----------------------------------------------------------------------------------------- 22 | 23 | 24 | if __name__ == "__main__": 25 | test_CuPCtS_powder_ATR() 26 | -------------------------------------------------------------------------------- /tests/data/from_databroker.py: -------------------------------------------------------------------------------- 1 | import pathlib 2 | 3 | from databroker.v2 import temp 4 | import msgpack 5 | 6 | import WrightTools as wt 7 | 8 | catalog = temp() 9 | 10 | __here__ = pathlib.Path(__file__).parent 11 | 12 | for child in (__here__ / "bluesky_data").iterdir(): 13 | with child.open("rb") as f: 14 | unpack = msgpack.Unpacker(f) 15 | for item in unpack: 16 | catalog.v1.insert(*item) 17 | 18 | 19 | def test_2d_data(): 20 | run = catalog["3dbdd402-434b-4aac-b004-447a2f026d73"] 21 | data = wt.data.from_databroker(run) 22 | assert data.shape == (10, 11) 23 | assert "d1_readback" in data 24 | assert "d1_setpoint" in data 25 | assert data.channel_names == ("daq_random_walk",) 26 | assert data.d1_readback.min() == 0 27 | assert data.d1_readback.max() == 1 28 | -------------------------------------------------------------------------------- /tests/data/from_ocean_optics.py: -------------------------------------------------------------------------------- 1 | """Test from_ocean_optics.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_tsunami_scope(): 14 | p = datasets.ocean_optics.tsunami 15 | data = wt.data.from_ocean_optics(p) 16 | assert data.axis_names == ("energy",) 17 | assert data.shape == (2048,) 18 | data.close() 19 | 20 | 21 | # --- run ----------------------------------------------------------------------------------------- 22 | 23 | 24 | if __name__ == "__main__": 25 | test_tsunami_scope() 26 | -------------------------------------------------------------------------------- /tests/data/from_shimadzu.py: -------------------------------------------------------------------------------- 1 | """test from_shimadzu""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_MoS2_fromCzech2015(): 14 | p = datasets.Shimadzu.MoS2_fromCzech2015 15 | data = wt.data.from_shimadzu(p) 16 | assert data.shape == (819,) 17 | assert data.axis_expressions == ("energy",) 18 | assert data.units == ("nm",) 19 | data.close() 20 | -------------------------------------------------------------------------------- /tests/data/from_spcm.py: -------------------------------------------------------------------------------- 1 | """Test from_spcm.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_test_data(): 14 | p = datasets.spcm.test_data 15 | data = wt.data.from_spcm(p) 16 | assert data.shape == (1024,) 17 | assert data.axis_names == ("time",) 18 | data.close() 19 | 20 | 21 | def test_test_data_full_metadata(): 22 | p = datasets.spcm.test_data_full_metadata 23 | data = wt.data.from_spcm(p) 24 | assert data.size == data.attrs["SP_ADC_RE"] 25 | data.close() 26 | 27 | 28 | # --- run ----------------------------------------------------------------------------------------- 29 | 30 | 31 | if __name__ == "__main__": 32 | test_test_data() 33 | test_test_data_full_metadata() 34 | -------------------------------------------------------------------------------- /tests/data/get_nadir.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test get_nadir.""" 3 | 4 | import WrightTools as wt 5 | import numpy as np 6 | from WrightTools import datasets 7 | 8 | 9 | def test_nadir(): 10 | p = wt.datasets.PyCMDS.wm_w2_w1_000 11 | data = wt.data.from_PyCMDS(p) 12 | data.wm.convert("nm") 13 | assert np.allclose(list(data.get_nadir()), [483.0833, 1590.0, 1600.0]) 14 | 15 | 16 | if __name__ == "__main__": 17 | test_nadir() 18 | -------------------------------------------------------------------------------- /tests/data/get_zenith.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test get_zenith.""" 3 | 4 | import WrightTools as wt 5 | import numpy as np 6 | from WrightTools import datasets 7 | 8 | 9 | def test_zenith(): 10 | p = wt.datasets.PyCMDS.wm_w2_w1_000 11 | data = wt.data.from_PyCMDS(p) 12 | data.wm.convert("nm") 13 | data.w1.convert("nm") 14 | assert np.allclose(list(data.get_zenith()), [495.0566, 1560.0, 6369.426752]) 15 | 16 | 17 | if __name__ == "__main__": 18 | test_zenith() 19 | -------------------------------------------------------------------------------- /tests/data/gradient.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test collapse.""" 3 | 4 | 5 | # --- import ------------------------------------------------------------------------------------- 6 | 7 | 8 | import WrightTools as wt 9 | import numpy as np 10 | 11 | 12 | # --- tests -------------------------------------------------------------------------------------- 13 | 14 | 15 | def test_gradient(): 16 | data = wt.Data() 17 | data.create_variable("v1", np.arange(0, 6)) 18 | data.create_variable("v2", np.arange(0, 6) * 2) 19 | data.create_channel("ch", np.array([1, 2, 4, 7, 11, 16])) 20 | data.transform("v1") 21 | data.gradient("v1") 22 | data.transform("v2") 23 | data.gradient("v2") 24 | 25 | assert data.ch_v1_gradient.shape == (6,) 26 | assert np.allclose(data.ch_v1_gradient.points, np.array([1.0, 1.5, 2.5, 3.5, 4.5, 5.0])) 27 | assert data.ch_v2_gradient.shape == (6,) 28 | assert np.allclose(data.ch_v2_gradient.points, np.array([0.5, 0.75, 1.25, 1.75, 2.25, 2.5])) 29 | 30 | 31 | # --- run ----------------------------------------------------------------------------------------- 32 | 33 | 34 | if __name__ == "__main__": 35 | test_gradient() 36 | -------------------------------------------------------------------------------- /tests/data/heal.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test data.heal.""" 3 | 4 | 5 | # --- import -------------------------------------------------------------------------------------- 6 | 7 | 8 | import numpy as np 9 | 10 | import WrightTools as wt 11 | 12 | 13 | # --- test ---------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_heal_gauss(): 17 | # create original arrays 18 | x = np.linspace(-3, 3, 31)[:, None] 19 | y = np.linspace(-3, 3, 31)[None, :] 20 | arr = np.exp(-1 * (x**2 + y**2)) 21 | # create damaged array 22 | arr2 = arr.copy() 23 | np.random.seed(11) # set seed for reproducibility 24 | arr2[np.random.random(arr2.shape) < 0.2] = np.nan 25 | # create data object 26 | d = wt.data.Data() 27 | d.create_variable("x", values=x) 28 | d.create_variable("y", values=y) 29 | d.create_channel("original", arr) 30 | d.create_channel("damaged", arr2) 31 | d.create_channel("healed_linear", arr2) 32 | d.create_channel("healed_nearest", arr2) 33 | d.create_channel("healed_cubic", arr2) 34 | d.transform("x", "y") 35 | # heal 36 | d.heal(channel="healed_linear", fill_value=0, method="linear") 37 | d.heal(channel="healed_nearest", fill_value=0, method="nearest") 38 | d.heal(channel="healed_cubic", fill_value=0, method="cubic") 39 | # check 40 | assert np.allclose(d.original[:], d.healed_linear[:], rtol=1e-1, atol=1e-1) 41 | assert np.allclose(d.original[:], d.healed_nearest[:], rtol=5e-1, atol=5e-1) 42 | assert np.allclose(d.original[:], d.healed_cubic[:], rtol=1e-1, atol=1e-1) 43 | 44 | 45 | if __name__ == "__main__": 46 | test_heal_gauss() 47 | -------------------------------------------------------------------------------- /tests/data/init.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test data __init__""" 3 | 4 | # --- import -------------------------------------------------------------------------------------- 5 | 6 | 7 | import WrightTools as wt 8 | import numpy as np 9 | 10 | 11 | # --- test ---------------------------------------------------------------------------------------- 12 | 13 | 14 | def test_axes_NoneType_units(): 15 | a = wt.Data() 16 | a.create_variable("x", np.array([0]), units=None) 17 | a.transform("x") 18 | a = a.copy() 19 | assert a.x.units is None 20 | a.close() 21 | -------------------------------------------------------------------------------- /tests/data/labels.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | 3 | import WrightTools as wt 4 | import numpy as np 5 | 6 | 7 | def test_short(): 8 | data = wt.Data() 9 | data.create_variable("t", np.linspace(0, 10, 10), units="fs") 10 | data.transform("t") 11 | assert data.axes[0].label == r"$\mathsf{\tau\,\left(fs\right)}$" 12 | 13 | 14 | if __name__ == "__main__": 15 | test_short() 16 | -------------------------------------------------------------------------------- /tests/data/level.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test level.""" 3 | 4 | 5 | # --- import -------------------------------------------------------------------------------------- 6 | 7 | 8 | import WrightTools as wt 9 | from WrightTools import datasets 10 | 11 | import numpy as np 12 | 13 | 14 | # --- test ---------------------------------------------------------------------------------------- 15 | 16 | 17 | def test_1D(): 18 | p = datasets.Cary.CuPCtS_H2O_vis 19 | data = wt.collection.from_Cary(p)[0] 20 | data.level(0, 0, 5) 21 | assert np.isclose(data.abs[:5].mean(), 0.0) 22 | data.close() 23 | 24 | 25 | def test_2D(): 26 | p = datasets.COLORS.v2p2_WL_wigner 27 | data = wt.data.from_COLORS(p) 28 | data.level("ai0", 1, -3) 29 | print(data.ai0[:, -3:].max()) 30 | assert np.allclose(data.ai0[:, -3:], [0.0], atol=5) # very noisy data 31 | data.close() 32 | 33 | 34 | def test_3D(): 35 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 36 | data = wt.open(p) 37 | data.level("ai0", 1, 1) 38 | assert np.allclose(data.ai0[:, :1], [0.0], atol=1e-3) 39 | data.close() 40 | 41 | 42 | def test_channels(): 43 | p = datasets.PyCMDS.wm_w2_w1_001 44 | data = wt.data.from_PyCMDS(p) 45 | data_copy = data.copy() 46 | data.bring_to_front(1) 47 | data.level(0, 0, 4) 48 | data_copy.level(1, 0, 4) 49 | a = data.channels[0][:] 50 | b = data_copy.channels[1][:] 51 | assert np.allclose(a, b) 52 | data.close() 53 | data_copy.close() 54 | 55 | 56 | # --- run ----------------------------------------------------------------------------------------- 57 | 58 | 59 | if __name__ == "__main__": 60 | test_1D() 61 | test_2D() 62 | test_3D() 63 | test_channels() 64 | -------------------------------------------------------------------------------- /tests/data/map_variable.py: -------------------------------------------------------------------------------- 1 | """Test map_variable.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | import pytest 8 | 9 | import WrightTools as wt 10 | from WrightTools import datasets 11 | 12 | 13 | # --- test ---------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_array(): 17 | p = datasets.JASCO.PbSe_batch_1 18 | data = wt.data.from_JASCO(p) 19 | assert data.shape == (1801,) 20 | new = np.linspace(6000, 8000, 55) 21 | mapped = data.map_variable("energy", new, "wn") 22 | assert np.allclose(mapped.axes[0][:], 1e7 / new) 23 | data.close() 24 | 25 | 26 | def test_int(): 27 | p = datasets.PyCMDS.wm_w2_w1_000 28 | data = wt.data.from_PyCMDS(p) 29 | assert data.shape == (35, 11, 11) 30 | mapped = data.map_variable("w2", 5) 31 | assert mapped.shape == (35, 5, 11) 32 | mapped = data.map_variable("w1", 25) 33 | assert mapped.shape == (35, 11, 25) 34 | data.close() 35 | 36 | 37 | def test_excess_data_kwarg_1D(): 38 | p = datasets.wt5.v1p0p0_perovskite_TA 39 | data = wt.open(p).chop("w2", at={"w1=wm": [1.6, "eV"], "d2": [0, "fs"]})[0] 40 | mapped = data.map_variable("w2", 11) 41 | assert mapped.w2.size == 11 42 | data.close() 43 | 44 | 45 | @pytest.mark.skip("It's a long test") 46 | def test_v1p0p0(): 47 | p = datasets.wt5.v1p0p0_perovskite_TA 48 | data = wt.open(p) 49 | mapped = data.map_variable("w2", 2) 50 | assert mapped.w2.size == 2 51 | data.close() 52 | 53 | 54 | # --- run ----------------------------------------------------------------------------------------- 55 | 56 | 57 | if __name__ == "__main__": 58 | test_array() 59 | test_int() 60 | test_excess_data_kwarg_1D() 61 | test_v1p0p0() 62 | -------------------------------------------------------------------------------- /tests/data/moment.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | import numpy as np 3 | import WrightTools as wt 4 | from WrightTools import datasets 5 | 6 | 7 | def test_moment_lognormal(): 8 | data = wt.Data() 9 | data.create_variable("x", np.linspace(0, 1000, 100000)) 10 | data.transform("x") 11 | x = data.x[:] 12 | data.create_channel("y", 1 / (x * np.sqrt(2 * np.pi)) * np.exp(-np.log(x) ** 2 / 2)) 13 | 14 | data.moment(0, moment=(0, 1, 2, 3, 4)) 15 | 16 | vals = [ 17 | 1, 18 | np.exp(1 / 2), 19 | (np.exp(1) - 1) * np.exp(1), 20 | (np.exp(1) + 2) * np.sqrt(np.exp(1) - 1), 21 | np.exp(4) + 2 * np.exp(3) + 3 * np.exp(2) - 6, 22 | ] 23 | 24 | for i, val in zip(range(5), vals): 25 | assert np.isclose(data[f"y_0_moment_{i}"][0], val, rtol=10 ** (-4 + i)) 26 | 27 | 28 | def test_moment_nd(): 29 | p = datasets.PyCMDS.w1_wa_000 30 | data = wt.data.from_PyCMDS(p) 31 | data.convert("nm") 32 | data.create_variable("x", (data.wa[:] - data.w1[:]).mean(axis=0, keepdims=True), units="nm") 33 | 34 | data.transform("w1", "x") 35 | 36 | data.level(0, 1, -10) 37 | data.moment(1, moment=0) 38 | assert data.channels[-1][10, 0] > 0 # check sign is as expected 39 | assert data.channels[-1].shape == (25, 1) 40 | data.moment(1, moment=1) 41 | assert data.channels[-1].shape == (25, 1) 42 | data.moment(1, moment=2) 43 | assert data.channels[-1].shape == (25, 1) 44 | data.close() 45 | 46 | 47 | def test_moment_resultant(): 48 | p = datasets.PyCMDS.w1_wa_000 49 | data = wt.data.from_PyCMDS(p) 50 | data.convert("nm") 51 | 52 | data.level(0, 1, -10) 53 | data.moment("wa", moment=0, resultant=data.w1.shape) 54 | assert data.channels[-1][10, 0] > 0 # check sign is as expected 55 | assert data.channels[-1].shape == (25, 1) 56 | data.moment("wa", moment=1, resultant=data.w1.shape) 57 | assert data.channels[-1].shape == (25, 1) 58 | data.moment("wa", moment=2, resultant=data.w1.shape) 59 | assert data.channels[-1].shape == (25, 1) 60 | data.close() 61 | 62 | 63 | if __name__ == "__main__": 64 | test_moment_nd() 65 | test_moment_lognormal() 66 | -------------------------------------------------------------------------------- /tests/data/prune.py: -------------------------------------------------------------------------------- 1 | """Test remove channel.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_prune_default(): 14 | p = datasets.PyCMDS.wm_w2_w1_000 15 | data = wt.data.from_PyCMDS(p) 16 | data.create_constant("d1") 17 | num_channels = len(data.channels) 18 | data.prune() 19 | assert len(data.variables) == 4 20 | assert set(data.variable_names) == {"wm", "w2", "w1", "d1"} 21 | assert len(data.channels) == num_channels 22 | data.close() 23 | 24 | 25 | def test_prune_false(): 26 | p = datasets.PyCMDS.wm_w2_w1_000 27 | data = wt.data.from_PyCMDS(p) 28 | data.create_constant("d1") 29 | data.prune(False) 30 | assert len(data.variables) == 4 31 | assert set(data.variable_names) == {"wm", "w2", "w1", "d1"} 32 | assert len(data.channels) == 1 33 | assert data.channel_names[0] == "signal_diff" 34 | data.close() 35 | 36 | 37 | def test_prune_number(): 38 | p = datasets.PyCMDS.wm_w2_w1_000 39 | data = wt.data.from_PyCMDS(p) 40 | data.create_constant("d1") 41 | data.prune(2) 42 | assert len(data.variables) == 4 43 | assert set(data.variable_names) == {"wm", "w2", "w1", "d1"} 44 | assert len(data.channels) == 1 45 | assert data.channel_names[0] == "pyro1" 46 | data.close() 47 | 48 | 49 | def test_prune_string(): 50 | p = datasets.PyCMDS.wm_w2_w1_000 51 | data = wt.data.from_PyCMDS(p) 52 | data.create_constant("d1") 53 | data.prune("pyro1") 54 | assert len(data.variables) == 4 55 | assert set(data.variable_names) == {"wm", "w2", "w1", "d1"} 56 | assert len(data.channels) == 1 57 | assert data.channel_names[0] == "pyro1" 58 | data.close() 59 | 60 | 61 | def test_prune_tuple(): 62 | p = datasets.PyCMDS.wm_w2_w1_000 63 | data = wt.data.from_PyCMDS(p) 64 | data.prune(("pyro1", 3, 4), verbose=False) 65 | assert len(data.variables) == 3 66 | assert set(data.variable_names) == {"wm", "w2", "w1"} 67 | assert len(data.channels) == 3 68 | assert set(data.channel_names) == {"pyro1", "pyro2", "pyro3"} 69 | data.close() 70 | 71 | 72 | if __name__ == "__main__": 73 | test_prune_default() 74 | test_prune_false() 75 | test_prune_number() 76 | test_prune_string() 77 | test_prune_tuple() 78 | -------------------------------------------------------------------------------- /tests/data/remove_channel.py: -------------------------------------------------------------------------------- 1 | """Test remove channel.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_remove_first_channel(): 14 | p = datasets.PyCMDS.wm_w2_w1_000 15 | data = wt.data.from_PyCMDS(p) 16 | data.remove_channel("signal_diff") 17 | assert data.channel_names[0] == "signal_mean" 18 | data.close() 19 | 20 | 21 | def test_remove_trailing_channels(): 22 | p = datasets.COLORS.v2p2_WL_wigner 23 | data = wt.data.from_COLORS(p) 24 | while len(data.channel_names) > 1: 25 | data.remove_channel(-1) 26 | assert data.channel_names == ("ai0",) 27 | data.close() 28 | -------------------------------------------------------------------------------- /tests/data/remove_variable.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test remove_variable.""" 3 | 4 | 5 | # --- import -------------------------------------------------------------------------------------- 6 | 7 | 8 | import warnings 9 | 10 | import WrightTools as wt 11 | from WrightTools import datasets 12 | 13 | 14 | # --- test ---------------------------------------------------------------------------------------- 15 | 16 | 17 | def test_exception(): 18 | p = datasets.COLORS.v2p2_WL_wigner 19 | data = wt.data.from_COLORS(p) 20 | try: 21 | data.remove_variable("d1") 22 | except RuntimeError: 23 | assert True 24 | else: 25 | assert False 26 | data.close() 27 | 28 | 29 | def test_constant_warning(): 30 | p = datasets.PyCMDS.w2_w1_000 31 | data = wt.data.from_PyCMDS(p) 32 | data.create_constant("d1") 33 | with warnings.catch_warnings(record=True) as w: 34 | data.remove_variable("d1") 35 | assert len(w) == 1 36 | assert issubclass(w[-1].category, wt.exceptions.WrightToolsWarning) 37 | data.close() 38 | 39 | 40 | def test_implied(): 41 | p = datasets.PyCMDS.w2_w1_000 42 | data = wt.data.from_PyCMDS(p) 43 | names = data.variable_names 44 | data.remove_variable("d0") 45 | for n in names: 46 | if n.startswith("d0"): 47 | assert n not in data.variable_names 48 | data.close() 49 | 50 | 51 | def test_not_implied(): 52 | p = datasets.PyCMDS.w2_w1_000 53 | data = wt.data.from_PyCMDS(p) 54 | names = data.variable_names 55 | data.remove_variable("d0", implied=False) 56 | for n in names: 57 | if n != "d0": 58 | assert n in data.variable_names 59 | else: 60 | assert n not in data.variable_names 61 | data.close() 62 | 63 | 64 | def test_index(): 65 | p = datasets.KENT.LDS821_TRSF 66 | ignore = ["wm", "d1", "d2"] 67 | data = wt.data.from_KENT(p, ignore=ignore) 68 | assert data.variable_names == ("w2", "w1", "wm", "d1", "d2") 69 | data.remove_variable(-2) 70 | assert data.variable_names == ("w2", "w1", "wm", "d2") 71 | data.close() 72 | 73 | 74 | if __name__ == "__main__": 75 | test_exception() 76 | test_implied() 77 | test_not_implied() 78 | test_index() 79 | -------------------------------------------------------------------------------- /tests/data/rename_channels.py: -------------------------------------------------------------------------------- 1 | """Test rename_channel.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_rename(): 14 | p = datasets.PyCMDS.wm_w2_w1_000 15 | data = wt.data.from_PyCMDS(p) 16 | assert data.channel_names[1] == "signal_mean" 17 | data.rename_channels(signal_mean="sig") 18 | assert data.channel_names[1] == "sig" 19 | assert data.channels[1].natural_name == "sig" 20 | assert "sig" in data.channels[1].name 21 | data.close() 22 | 23 | 24 | def test_error(): 25 | p = datasets.PyCMDS.wm_w2_w1_000 26 | data = wt.data.from_PyCMDS(p) 27 | try: 28 | data.rename_channels(pyro1="pyro2") 29 | except wt.exceptions.NameNotUniqueError: 30 | assert True 31 | else: 32 | assert False 33 | data.close() 34 | -------------------------------------------------------------------------------- /tests/data/rename_variables.py: -------------------------------------------------------------------------------- 1 | """Test rename_variable.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_simple(): 14 | p = datasets.BrunoldrRaman.LDS821_514nm_80mW 15 | data = wt.data.from_BrunoldrRaman(p) 16 | data.rename_variables(energy="blaise") 17 | assert data.variable_names == ("blaise",) 18 | assert data.variables[0].natural_name == "blaise" 19 | assert "blaise" in data.variables[0].name 20 | data.close() 21 | 22 | 23 | def test_implied(): 24 | p = datasets.PyCMDS.w2_w1_000 25 | data = wt.data.from_PyCMDS(p) 26 | names = data.variable_names 27 | data.rename_variables(w1="w2", w2="w1") 28 | for old, new in zip(names, data.variable_names): 29 | if old.startswith("w1"): 30 | assert new.startswith("w2") 31 | elif old.startswith("w2"): 32 | assert new.startswith("w1") 33 | else: 34 | pass 35 | data.close() 36 | 37 | 38 | def test_propagate_units(): 39 | p = datasets.PyCMDS.wm_w2_w1_001 40 | data = wt.data.from_PyCMDS(p) 41 | data.convert("meV") 42 | data.rename_variables(wm="mono") 43 | assert data.units == ("meV", "meV", "meV") 44 | data.close() 45 | 46 | 47 | def test_updated_axes(): 48 | p = datasets.COLORS.v2p2_WL_wigner 49 | data = wt.data.from_COLORS(p) 50 | data.create_constant("wm") 51 | assert data.constant_expressions == ("wm",) 52 | assert data.axis_expressions == ("wm", "d1") 53 | data.rename_variables(wm="mono") 54 | assert data.axis_expressions == ("mono", "d1") 55 | assert data.constant_expressions == ("mono",) 56 | data.close() 57 | -------------------------------------------------------------------------------- /tests/data/share_nans.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test share_nans.""" 3 | 4 | import WrightTools as wt 5 | import numpy as np 6 | from WrightTools import datasets 7 | 8 | 9 | def test_share_nans(): 10 | p = wt.datasets.PyCMDS.wm_w2_w1_000 11 | data = wt.data.from_PyCMDS(p) 12 | data.channels[0][3] = np.nan 13 | data.share_nans() 14 | for ch in data.channels: 15 | assert np.all(np.isnan(ch[3])) 16 | 17 | 18 | if __name__ == "__main__": 19 | test_share_nans() 20 | -------------------------------------------------------------------------------- /tests/data/smooth.py: -------------------------------------------------------------------------------- 1 | """Test data.smooth.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- test ---------------------------------------------------------------------------------------- 12 | 13 | 14 | def test_1(): 15 | # create collection 16 | root = wt.Collection(name="root_coll") 17 | kwargs = {"name": "test1"} 18 | data = root.create_data(**kwargs) 19 | # create test arrays 20 | x = np.linspace(0, 1, 1000) 21 | y = 1 * x 22 | # create channels and variables 23 | data.create_variable(name="x", values=x, units=None) 24 | data.create_channel(name="y", values=y) 25 | data.create_channel(name="z", values=y) 26 | data.transform("x") 27 | # smooth 28 | data.smooth(5, channel="y") 29 | check_arr = data.y[:] - data.z[:] 30 | assert np.isclose(check_arr.all(), 0, rtol=1e-4, atol=1e-4) 31 | 32 | 33 | def test_2(): 34 | # create collection 35 | root = wt.Collection(name="root_coll") 36 | kwargs = {"name": "test2"} 37 | data = root.create_data(**kwargs) 38 | # create test arrays 39 | x = np.linspace(0, 1, 100) 40 | z = np.random.rand(100, 100) 41 | # create channels and variables 42 | data.create_variable(name="x1", values=x, units=None) 43 | data.create_variable(name="x2", values=x, units=None) 44 | data.create_channel(name="z", values=z) 45 | data.transform("x1", "x2") 46 | # smooth 47 | data.smooth(90, channel="z") 48 | assert np.allclose(data.z[:], 0.5, rtol=0.1, atol=0.4) 49 | 50 | 51 | def test_3(): 52 | # create collection 53 | root = wt.Collection(name="root_coll") 54 | kwargs = {"name": "test3"} 55 | data = root.create_data(**kwargs) 56 | # create test arrays 57 | x = np.linspace(0, 4 * np.pi, 1000) 58 | z_big = np.sin(x) 59 | z_small = np.sin(x * 50) 60 | z_comb = z_big + 0.1 * z_small 61 | # create channels and variables 62 | data.create_variable(name="x", values=x, units=None) 63 | data.create_channel(name="z_comb", values=z_comb) 64 | data.transform("x") 65 | # smooth 66 | data.smooth(10, channel="z_comb") 67 | assert np.allclose(data.z_comb[:], z_big, rtol=0.1, atol=0.05) 68 | -------------------------------------------------------------------------------- /tests/data/squeeze.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test squeeze.""" 3 | 4 | 5 | # --- import ------------------------------------------------------------------------------------- 6 | 7 | 8 | import numpy as np 9 | import WrightTools as wt 10 | from WrightTools import datasets 11 | 12 | 13 | # --- tests -------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_squeeze(): 17 | d = wt.Data(name="test") 18 | d.create_variable("x", values=np.arange(5)[:, None, None]) 19 | d.create_variable("y", values=np.arange(4)[None, :, None]) 20 | d.create_variable("redundant_array", values=np.tile(np.arange(3), (5, 4, 1))) 21 | 22 | d.create_channel("keep", values=d.x[:] + d.y[:]) 23 | d.create_channel("throw_away", values=np.zeros((5, 4, 3))) 24 | 25 | d.transform("x", "y") 26 | d = d.squeeze() # make sure it runs error free 27 | assert d.ndim == 2 28 | assert d.shape == (5, 4) 29 | 30 | 31 | def test_constants(): 32 | d = wt.Data(name="test") 33 | d.create_variable("x", values=np.array([1]).reshape(1, 1)) 34 | d.create_constant("x") 35 | d.create_variable("y", values=np.linspace(3, 5, 4).reshape(-1, 1)) 36 | d.create_variable("z", values=np.linspace(0, 1, 6).reshape(1, -1)) 37 | d.transform("y") 38 | ds = d.squeeze() 39 | assert "x" in ds.constant_expressions 40 | d.print_tree() 41 | ds.print_tree() 42 | 43 | 44 | if __name__ == "__main__": 45 | test_squeeze() 46 | test_constants() 47 | -------------------------------------------------------------------------------- /tests/data/test_data/circular_map.ngc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/data/test_data/circular_map.ngc -------------------------------------------------------------------------------- /tests/data/test_data/ellipsoidal_map.ngc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/data/test_data/ellipsoidal_map.ngc -------------------------------------------------------------------------------- /tests/data/test_data/irregular_map.ngc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/data/test_data/irregular_map.ngc -------------------------------------------------------------------------------- /tests/data/test_data/rectangular_map.ngc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/data/test_data/rectangular_map.ngc -------------------------------------------------------------------------------- /tests/data/test_data/skew_line.ngc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/data/test_data/skew_line.ngc -------------------------------------------------------------------------------- /tests/data/test_data/square_map.ngc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/data/test_data/square_map.ngc -------------------------------------------------------------------------------- /tests/data/test_data/vertical_linescan.ngc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/data/test_data/vertical_linescan.ngc -------------------------------------------------------------------------------- /tests/data/transform.py: -------------------------------------------------------------------------------- 1 | """Test transform.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | from WrightTools import datasets 10 | 11 | 12 | # --- tests --------------------------------------------------------------------------------------- 13 | 14 | 15 | def test_add(): 16 | p = datasets.PyCMDS.w2_w1_000 17 | data = wt.data.from_PyCMDS(p) 18 | data.transform("w1+w2", "wm") 19 | assert data.axis_names == ("w1__p__w2", "wm") 20 | assert data.w1__p__w2.shape == (81, 81) 21 | assert data.wm.shape == (81, 81) 22 | data.close() 23 | 24 | 25 | def test_multiply_by_constant(): 26 | p = datasets.PyCMDS.w2_w1_000 27 | data = wt.data.from_PyCMDS(p) 28 | data.transform("3*w2", "0.5*wm") 29 | assert data.axis_names == ("_3__t__w2", "_0_5__t__wm") 30 | assert np.allclose(data._3__t__w2[:], data["w2"][:] * 3) 31 | assert np.allclose(data._0_5__t__wm[:], data["wm"][:] * 0.5) 32 | data.close() 33 | 34 | 35 | def test_simple(): 36 | p = datasets.PyCMDS.w2_w1_000 37 | data = wt.data.from_PyCMDS(p) 38 | data.transform("w2", "wm") 39 | assert data.axis_names == ("w2", "wm") 40 | assert data.w2.shape == (81, 1) 41 | assert data.wm.shape == (81, 81) 42 | data.close() 43 | 44 | 45 | def test_subtract(): 46 | p = datasets.PyCMDS.w2_w1_000 47 | data = wt.data.from_PyCMDS(p) 48 | data.transform("w1-w2", "wm") 49 | assert data.axis_names == ("w1__m__w2", "wm") 50 | assert np.allclose(data.w1__m__w2[:], data["w1"][:] - data["w2"][:]) 51 | assert np.allclose(data.wm[:], data["wm"][:]) 52 | data.close() 53 | 54 | 55 | def test_subtract_constant(): 56 | p = datasets.PyCMDS.w2_w1_000 57 | data = wt.data.from_PyCMDS(p) 58 | data.transform("w2-7000", "wm") 59 | assert data.axis_names == ("w2__m__7000", "wm") 60 | assert np.allclose(data.w2__m__7000[:], data["w2"][:] - 7000.0) 61 | assert np.allclose(data.wm[:], data["wm"][:]) 62 | data.close() 63 | 64 | 65 | def test_copy_decimal(): 66 | d = wt.Data() 67 | d.create_variable("a", np.array([10.0])) 68 | d.transform("a/2.0") 69 | assert d.a__d__2_0[0] == 5.0 70 | d2 = d.copy() 71 | assert d2.a__d__2_0[0] == 5.0 72 | d.close() 73 | d2.close() 74 | 75 | 76 | # --- run ----------------------------------------------------------------------------------------- 77 | 78 | 79 | if __name__ == "__main__": 80 | test_add() 81 | test_multiply_by_constant() 82 | test_simple() 83 | test_subtract() 84 | test_subtract_constant() 85 | -------------------------------------------------------------------------------- /tests/data/translate_to_txt.py: -------------------------------------------------------------------------------- 1 | """Test transform.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import pathlib 7 | import WrightTools as wt 8 | 9 | from WrightTools import datasets 10 | from tempfile import NamedTemporaryFile 11 | 12 | 13 | # --- tests --------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_datasets_mos2(): 17 | d = wt.open(datasets.wt5.v1p0p1_MoS2_TrEE_movie).at(w2=[18000, "wn"])[:5] 18 | 19 | with NamedTemporaryFile(delete=False) as tmp: 20 | d.translate_to_txt(tmp.name, verbose=True) 21 | 22 | with open(tmp.name, "r") as f: 23 | for i in range(100): 24 | f.readline() 25 | datum_txt = f.readline().split("|") 26 | id1, id2 = [_ for _ in map(int, datum_txt[0].split())] 27 | values = [_ for _ in map(float, datum_txt[1].split())] 28 | datum_wt5 = d[int(id1), int(id2)] 29 | for i, vari in enumerate(d.variable_names): 30 | # print(vari, values[i], datum_wt5[vari][:]) 31 | assert (values[i] - datum_wt5[vari][:]) ** 2 <= (1e-4 * values[i]) ** 2 32 | 33 | d.close() 34 | 35 | 36 | # --- run ----------------------------------------------------------------------------------------- 37 | 38 | 39 | if __name__ == "__main__": 40 | test_datasets_mos2() 41 | -------------------------------------------------------------------------------- /tests/dataset/argmax.py: -------------------------------------------------------------------------------- 1 | """Test dataset argmax method.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_JASCO_PbSe_batch_4_2012_02_21(): 14 | p = datasets.JASCO.PbSe_batch_4_2012_02_21 15 | data = wt.data.from_JASCO(p) 16 | assert data.signal.argmax() == (1250,) 17 | assert data["energy"].argmax() == (0,) 18 | data.close() 19 | 20 | 21 | def test_PyCMDS_wm_w2_w1_000(): 22 | p = datasets.PyCMDS.wm_w2_w1_000 23 | data = wt.data.from_PyCMDS(p) 24 | assert data["wm"].argmax() == (34, 0, 0) 25 | assert data["w2"].argmax() == (0, 0, 0) 26 | assert data["w1"].argmax() == (0, 0, 10) 27 | assert data.signal_diff.argmax() == (10, 8, 6) 28 | assert data.signal_mean.argmax() == (14, 7, 4) 29 | data.close() 30 | -------------------------------------------------------------------------------- /tests/dataset/argmin.py: -------------------------------------------------------------------------------- 1 | """Test dataset min method.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_JASCO_PbSe_batch_4_2012_02_21(): 14 | p = datasets.JASCO.PbSe_batch_4_2012_02_21 15 | data = wt.data.from_JASCO(p) 16 | assert data.signal.argmin() == (11,) 17 | assert data["energy"].argmin() == (1250,) 18 | data.close() 19 | 20 | 21 | def test_PyCMDS_wm_w2_w1_000(): 22 | p = datasets.PyCMDS.wm_w2_w1_000 23 | data = wt.data.from_PyCMDS(p) 24 | assert data["wm"].argmin() == (0, 0, 0) 25 | assert data["w2"].argmin() == (0, 10, 0) 26 | assert data["w1"].argmin() == (0, 0, 0) 27 | assert data.signal_diff.argmin() == (0, 2, 0) 28 | assert data.signal_mean.argmin() == (30, 1, 9) 29 | data.close() 30 | -------------------------------------------------------------------------------- /tests/dataset/clip.py: -------------------------------------------------------------------------------- 1 | """Test clipping.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | import WrightTools as wt 6 | from WrightTools import datasets 7 | 8 | 9 | # --- test ---------------------------------------------------------------------------------------- 10 | 11 | 12 | def test_w1_wa(): 13 | p = datasets.PyCMDS.w1_wa_000 14 | data = wt.data.from_PyCMDS(p) 15 | new_max = 0.5 * data.array_signal.max() + data.array_signal.min() 16 | data.array_signal.clip(max=new_max) 17 | assert data.array_signal.max() <= new_max 18 | data.close() 19 | 20 | 21 | # --- run ----------------------------------------------------------------------------------------- 22 | 23 | 24 | if __name__ == "__main__": 25 | test_w1_wa() 26 | -------------------------------------------------------------------------------- /tests/dataset/convert_dataset.py: -------------------------------------------------------------------------------- 1 | """Test dataset unit conversion.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | from WrightTools import datasets 10 | 11 | 12 | # --- define -------------------------------------------------------------------------------------- 13 | 14 | 15 | def test_exception(): 16 | p = datasets.PyCMDS.w1_000 17 | data = wt.data.from_PyCMDS(p) 18 | try: 19 | data["w1"].convert("fs") 20 | except wt.exceptions.UnitsError: 21 | assert True 22 | else: 23 | assert False 24 | assert data["w1"].units == "nm" 25 | data.close() 26 | 27 | 28 | def test_w1_wa(): 29 | p = datasets.PyCMDS.w1_wa_000 30 | data = wt.data.from_PyCMDS(p) 31 | assert data["wa"].units == "nm" 32 | data["wa"].convert("eV") 33 | assert np.isclose(data["wa"].max(), 1.5800551001941774) 34 | assert np.isclose(data["wa"].min(), 0.6725528801867734) 35 | data.close() 36 | 37 | 38 | def test_wigner(): 39 | p = datasets.COLORS.v2p2_WL_wigner 40 | data = wt.data.from_COLORS(p) 41 | data["d1"].convert("ns") 42 | assert data["d1"].units == "ns" 43 | data.close() 44 | 45 | 46 | # --- run ----------------------------------------------------------------------------------------- 47 | 48 | 49 | if __name__ == "__main__": 50 | test_exception() 51 | test_w1_wa() 52 | test_wigner() 53 | -------------------------------------------------------------------------------- /tests/dataset/ipow.py: -------------------------------------------------------------------------------- 1 | """Test in place power.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import random 7 | 8 | import numpy as np 9 | 10 | import WrightTools as wt 11 | from WrightTools import datasets 12 | 13 | 14 | # --- test ---------------------------------------------------------------------------------------- 15 | 16 | 17 | def test_d1_d2(): 18 | p = datasets.COLORS.v0p2_d1_d2_diagonal 19 | data = wt.data.from_COLORS(p) 20 | value = random.randint(0, 5) 21 | original_max = data.ai0.max() 22 | data.ai0 **= value 23 | assert np.isclose(data.ai0.max(), original_max**value) 24 | data.close() 25 | 26 | 27 | def test_d1_d2_array(): 28 | p = datasets.COLORS.v0p2_d1_d2_diagonal 29 | data = wt.data.from_COLORS(p) 30 | value = np.random.randint(0, 5, data.shape) 31 | original = data.ai0[:] 32 | data.ai0 **= value 33 | assert np.array_equal(data.ai0, original**value) 34 | data.close() 35 | 36 | 37 | def test_w1(): 38 | p = datasets.PyCMDS.w1_000 39 | data = wt.data.from_PyCMDS(p) 40 | value = random.randint(0, 5) 41 | original_max = data.signal.max() 42 | data.signal **= value 43 | assert np.isclose(data.signal.max(), original_max**value) 44 | data.close() 45 | 46 | 47 | def test_w1_array(): 48 | p = datasets.PyCMDS.w1_000 49 | data = wt.data.from_PyCMDS(p) 50 | value = np.random.randint(0, 5, data.shape) 51 | original = data.signal[:] 52 | data.signal **= value 53 | assert np.array_equal(data.signal, original**value) 54 | data.close() 55 | 56 | 57 | def test_w1_wa(): 58 | p = datasets.PyCMDS.w1_wa_000 59 | data = wt.data.from_PyCMDS(p) 60 | value = random.randint(0, 5) 61 | original_max = data.array_signal.max() 62 | data.array_signal **= value 63 | assert np.isclose(data.array_signal.max(), original_max**value) 64 | data.close() 65 | 66 | 67 | def test_w1_wa_array(): 68 | p = datasets.PyCMDS.w1_wa_000 69 | data = wt.data.from_PyCMDS(p) 70 | value = np.random.randint(0, 5, data.shape) 71 | original = data.array_signal[:] 72 | data.array_signal **= value 73 | assert np.array_equal(data.array_signal, original**value) 74 | data.close() 75 | 76 | 77 | # --- run ----------------------------------------------------------------------------------------- 78 | 79 | 80 | if __name__ == "__main__": 81 | test_d1_d2() 82 | test_d1_d2_array() 83 | test_w1() 84 | test_w1_array() 85 | test_w1_wa() 86 | test_w1_wa_array() 87 | -------------------------------------------------------------------------------- /tests/dataset/max.py: -------------------------------------------------------------------------------- 1 | """Test dataset max method.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import h5py 7 | import numpy as np 8 | 9 | import WrightTools as wt 10 | from WrightTools import datasets 11 | 12 | 13 | # --- test ---------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_COLORS_v2p2_WL_wigner(): 17 | p = datasets.COLORS.v2p2_WL_wigner 18 | data = wt.data.from_COLORS(p) 19 | arr = np.genfromtxt(p).T 20 | assert np.isclose(data["wm"].max(), arr[7].max()) 21 | assert np.isclose(data["d1"].max(), arr[12].max(), rtol=0.1) 22 | assert np.isclose(data.ai0.max(), arr[16].max(), rtol=0.1) 23 | data.close() 24 | 25 | 26 | def test_JASCO_PbSe_batch_4_2012_02_21(): 27 | p = datasets.JASCO.PbSe_batch_4_2012_02_21 28 | data = wt.data.from_JASCO(p) 29 | assert np.isclose(data.signal.max(), 0.78552) 30 | assert np.isclose(data["energy"].max(), 2000.0) 31 | data.close() 32 | 33 | 34 | def test_PyCMDS_wm_w2_w1_000(): 35 | p = datasets.PyCMDS.wm_w2_w1_000 36 | data = wt.data.from_PyCMDS(p) 37 | assert np.isclose(data["wm"].max(), 526.3259) 38 | assert np.isclose(data["w2"].max(), 1600.0) 39 | assert np.isclose(data["w1"].max(), 6451.612903) 40 | assert np.isclose(data.signal_diff.max(), 0.264612) 41 | assert np.isclose(data.signal_mean.max(), 0.07345) 42 | data.close() 43 | 44 | 45 | def test_read_only(): 46 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 47 | f = h5py.File(p, "r") 48 | d = wt.Data(f) 49 | assert np.isclose(d.w2.max(), 763.3587731728356) 50 | assert "max" not in d.ai0.attrs 51 | assert np.isclose(d.ai0.max(), 0.2560301283785622) 52 | assert "max" not in d.ai0.attrs 53 | d.close() 54 | 55 | 56 | # --- run ----------------------------------------------------------------------------------------- 57 | 58 | 59 | if __name__ == "__main__": 60 | test_COLORS_v2p2_WL_wigner() 61 | test_JASCO_PbSe_batch_4_2012_02_21() 62 | test_PyCMDS_wm_w2_w1_000() 63 | test_read_only() 64 | -------------------------------------------------------------------------------- /tests/dataset/max_cached.wt5: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/dataset/max_cached.wt5 -------------------------------------------------------------------------------- /tests/dataset/min.py: -------------------------------------------------------------------------------- 1 | """Test dataset min method.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | import pathlib 6 | 7 | import h5py 8 | import numpy as np 9 | 10 | import WrightTools as wt 11 | from WrightTools import datasets 12 | 13 | 14 | # --- test ---------------------------------------------------------------------------------------- 15 | 16 | 17 | def test_COLORS_v2p2_WL_wigner(): 18 | p = datasets.COLORS.v2p2_WL_wigner 19 | data = wt.data.from_COLORS(p) 20 | arr = np.genfromtxt(p).T 21 | assert np.isclose(data["wm"].min(), arr[7].min()) 22 | assert np.isclose(data["d1"].min(), arr[12].min(), rtol=0.1) 23 | assert np.isclose(data.ai0.min(), arr[16].min(), rtol=0.1) 24 | data.close() 25 | 26 | 27 | def test_JASCO_PbSe_batch_4_2012_02_21(): 28 | p = datasets.JASCO.PbSe_batch_4_2012_02_21 29 | data = wt.data.from_JASCO(p) 30 | assert np.isclose(data.signal.min(), 0.02875) 31 | assert np.isclose(data["energy"].min(), 750.0) 32 | data.close() 33 | 34 | 35 | def test_PyCMDS_wm_w2_w1_000(): 36 | p = datasets.PyCMDS.wm_w2_w1_000 37 | data = wt.data.from_PyCMDS(p) 38 | assert np.isclose(data["wm"].min(), 483.0833) 39 | assert np.isclose(data["w2"].min(), 1550.0) 40 | assert np.isclose(data["w1"].min(), 6250.0) 41 | assert np.isclose(data.signal_diff.min(), 0.000773) 42 | assert np.isclose(data.signal_mean.min(), 0.000563) 43 | data.close() 44 | 45 | 46 | def test_read_only(): 47 | p = datasets.wt5.v1p0p1_MoS2_TrEE_movie 48 | f = h5py.File(p, "r") 49 | d = wt.Data(f) 50 | assert np.isclose(d.w2.min(), 584.7953254198521) 51 | assert "min" not in d.ai0.attrs 52 | assert np.isclose(d.ai0.min(), -0.008888) 53 | assert "min" not in d.ai0.attrs 54 | d.close() 55 | 56 | 57 | def test_read_only_with_max_cached(): 58 | p = pathlib.Path(__file__).parent / "max_cached.wt5" 59 | f = h5py.File(p, "r") 60 | d = wt.Data(f) 61 | assert "max" in d.x.attrs 62 | assert np.isclose(d.x.min(), -1) 63 | assert "min" not in d.x.attrs 64 | d.close() 65 | 66 | 67 | # --- run ----------------------------------------------------------------------------------------- 68 | 69 | 70 | if __name__ == "__main__": 71 | test_COLORS_v2p2_WL_wigner() 72 | test_JASCO_PbSe_batch_4_2012_02_21() 73 | test_PyCMDS_wm_w2_w1_000() 74 | test_read_only() 75 | -------------------------------------------------------------------------------- /tests/dataset/symmetric_root.py: -------------------------------------------------------------------------------- 1 | """Test symmetric root.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import random 7 | 8 | import numpy as np 9 | 10 | import WrightTools as wt 11 | from WrightTools import datasets 12 | 13 | 14 | # --- test ---------------------------------------------------------------------------------------- 15 | 16 | 17 | def test_d1_d2(): 18 | p = datasets.COLORS.v0p2_d1_d2_diagonal 19 | data = wt.data.from_COLORS(p) 20 | root = random.randint(1, 10) 21 | original = data.ai0[:] 22 | data.ai0.symmetric_root(root) 23 | assert np.array_equal(np.sign(data.ai0[:]), np.sign(original)) 24 | assert np.isclose(original.max() ** (1 / root), data.ai0.max()) 25 | data.close() 26 | 27 | 28 | def test_w1(): 29 | p = datasets.PyCMDS.w1_000 30 | data = wt.data.from_PyCMDS(p) 31 | root = random.randint(1, 10) 32 | original = data.signal[:] 33 | data.signal.symmetric_root(root) 34 | assert np.array_equal(np.sign(data.signal[:]), np.sign(original)) 35 | assert np.isclose(original.max() ** (1 / root), data.signal.max()) 36 | data.close() 37 | 38 | 39 | def test_w1_wa(): 40 | p = datasets.PyCMDS.w1_wa_000 41 | data = wt.data.from_PyCMDS(p) 42 | root = random.randint(1, 10) 43 | original = data.array_signal[:] 44 | data.array_signal.symmetric_root(root) 45 | assert np.array_equal(np.sign(data.array_signal[:]), np.sign(original)) 46 | assert np.isclose(original.max() ** (1 / root), data.array_signal.max()) 47 | data.close() 48 | 49 | 50 | # --- run ----------------------------------------------------------------------------------------- 51 | 52 | 53 | if __name__ == "__main__": 54 | test_d1_d2() 55 | test_w1() 56 | test_w1_wa() 57 | -------------------------------------------------------------------------------- /tests/docs/_sphinx.py: -------------------------------------------------------------------------------- 1 | """Test building the documentation.""" 2 | 3 | from sphinx.cmd import build 4 | import os 5 | import shutil 6 | 7 | 8 | def test_build_docs(): 9 | docsdir = os.path.abspath(os.path.dirname(__file__)) + "/../../docs" 10 | exitCode = build.build_main([docsdir, docsdir + "/__testbuild"]) 11 | # The following code works in sphinx >= 1.7.0 12 | # exitCode = sphinx.build([docsdir, docsdir + '/__testbuild']) 13 | assert exitCode == 0 14 | shutil.rmtree(docsdir + "/__testbuild") 15 | 16 | 17 | if __name__ == "__main__": 18 | test_build_docs() 19 | -------------------------------------------------------------------------------- /tests/entry_points/wt_tree.py: -------------------------------------------------------------------------------- 1 | import hashlib 2 | import WrightTools as wt 3 | import subprocess 4 | import os 5 | 6 | 7 | def test_no_change(): 8 | d = wt.Data() 9 | d.save("test_no_change", overwrite=True) 10 | d.close() 11 | before = hashlib.sha1() 12 | with open("test_no_change.wt5", "rb") as f: 13 | before.update(f.read()) 14 | subprocess.call(["wt5", "tree", "test_no_change.wt5"]) 15 | after = hashlib.sha1() 16 | with open("test_no_change.wt5", "rb") as f: 17 | after.update(f.read()) 18 | os.remove("test_no_change.wt5") 19 | assert before.digest() == after.digest() 20 | -------------------------------------------------------------------------------- /tests/group/attributes.py: -------------------------------------------------------------------------------- 1 | """Test getattr and associated.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | from WrightTools import datasets 8 | 9 | 10 | # --- test ---------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_axis_variable_namespace_collision(): 14 | root = wt.Collection() 15 | p = datasets.PyCMDS.wm_w2_w1_001 16 | data = wt.data.from_PyCMDS(p, parent=root, name="data") 17 | assert isinstance(data.wm, wt.data._axis.Axis) 18 | assert isinstance(data.w2, wt.data._axis.Axis) 19 | assert isinstance(data.w1, wt.data._axis.Axis) 20 | assert isinstance(data.d1, wt.data._variable.Variable) 21 | assert isinstance(data.d2, wt.data._variable.Variable) 22 | data.close() 23 | 24 | 25 | def test_transform(): 26 | root = wt.Collection() 27 | p = datasets.PyCMDS.wm_w2_w1_001 28 | data = wt.data.from_PyCMDS(p, parent=root, name="data") 29 | data.transform("wm-w1", "w1", "w2") 30 | assert hasattr(data, "wm__m__w1") 31 | assert hasattr(data, "w1") 32 | assert hasattr(data, "w2") 33 | data.close() 34 | 35 | 36 | # --- run ----------------------------------------------------------------------------------------- 37 | 38 | 39 | if __name__ == "__main__": 40 | test_axis_variable_namespace_collision() 41 | test_transform() 42 | -------------------------------------------------------------------------------- /tests/kit/.gitignore: -------------------------------------------------------------------------------- 1 | test.ini 2 | -------------------------------------------------------------------------------- /tests/kit/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/wright-group/WrightTools/86851fd023cafba69700149dae726cb7294db385/tests/kit/__init__.py -------------------------------------------------------------------------------- /tests/kit/closest_pair.py: -------------------------------------------------------------------------------- 1 | """Test closest pair.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- test --------------------------------------------------------------------------------------- 12 | 13 | 14 | def test_5(): 15 | arr = np.array([1, 3, 4, 6, 12]) 16 | assert wt.kit.closest_pair(arr) == [[(1,), (2,)]] 17 | assert wt.kit.closest_pair(arr, "distance") == 1 18 | 19 | 20 | def test_5_multiple(): 21 | arr = np.array([1, 3, 4, 11, 12]) 22 | assert wt.kit.closest_pair(arr) == [[(1,), (2,)], [(3,), (4,)]] 23 | assert wt.kit.closest_pair(arr, "distance") == 1 24 | 25 | 26 | def test_example(): 27 | arr = np.array([0, 1, 2, 3, 3, 4, 5, 6, 1]) 28 | assert wt.kit.closest_pair(arr) == [[(1,), (8,)], [(3,), (4,)]] 29 | 30 | 31 | def test_2x3(): 32 | arr = np.array([[0, 1, 2], [3, 4, 4.5]]) 33 | assert wt.kit.closest_pair(arr) == [[(1, 1), (1, 2)]] 34 | assert wt.kit.closest_pair(arr, "distance") == 0.5 35 | -------------------------------------------------------------------------------- /tests/kit/diff.py: -------------------------------------------------------------------------------- 1 | """Test diff.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- test --------------------------------------------------------------------------------------- 12 | 13 | 14 | def test_ascending_1(): 15 | x = np.linspace(0, 10, 1000) 16 | y = np.sin(x) 17 | d = wt.kit.diff(x, y) 18 | assert np.all((np.abs(d - np.cos(x)) < 0.0001)[:-1]) 19 | 20 | 21 | def test_ascending_2(): 22 | x = np.linspace(0, 10, 1000) 23 | y = np.sin(x) 24 | d = wt.kit.diff(x, y, 2) 25 | assert np.all((np.abs(d + np.sin(x)) < 0.0001)[1:-2]) 26 | 27 | 28 | def test_ascending_3(): 29 | x = np.linspace(0, 10, 1000) 30 | y = np.sin(x) 31 | d = wt.kit.diff(x, y, 3) 32 | assert np.all((np.abs(d + np.cos(x)) < 0.0001)[2:-3]) 33 | 34 | 35 | def test_ascending_4(): 36 | x = np.linspace(0, 10, 1000) 37 | y = np.sin(x) 38 | d = wt.kit.diff(x, y, 4) 39 | assert np.all((np.abs(d - np.sin(x)) < 0.0001)[3:-4]) 40 | 41 | 42 | def test_descending_1(): 43 | x = np.linspace(10, 0, 1000) 44 | y = np.sin(x) 45 | d = wt.kit.diff(x, y) 46 | assert np.all((np.abs(d - np.cos(x)) < 0.0001)[1:-1]) 47 | 48 | 49 | def test_descending_3(): 50 | x = np.linspace(10, 0, 1000) 51 | y = np.sin(x) 52 | d = wt.kit.diff(x, y, 3) 53 | assert np.all((np.abs(d + np.cos(x)) < 0.0001)[3:-3]) 54 | -------------------------------------------------------------------------------- /tests/kit/fft.py: -------------------------------------------------------------------------------- 1 | """Test fft.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import pytest 7 | 8 | import numpy as np 9 | 10 | import WrightTools as wt 11 | 12 | 13 | # --- test ---------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_analytic_fft(): 17 | a = 1 - 1j 18 | t = np.linspace(0, 10, 10000) 19 | z = np.heaviside(t, 0.5) * np.exp(-a * t) 20 | wi, zi = wt.kit.fft(t, z) 21 | zi_analytical = 1 / (a + 1j * 2 * np.pi * wi) 22 | assert np.allclose(zi.real, zi_analytical.real, atol=1e-3) 23 | assert np.allclose(zi.imag, zi_analytical.imag, atol=1e-3) 24 | 25 | 26 | def test_plancherel(): 27 | t = np.linspace(-10, 10, 10000) 28 | z = np.sin(2 * np.pi * t) 29 | wi, zi = wt.kit.fft(t, z) 30 | intensity_time = (z**2).sum() * (t[1] - t[0]) 31 | intensity_freq = (zi * zi.conjugate()).real.sum() * (wi[1] - wi[0]) 32 | rel_error = np.abs(intensity_time - intensity_freq) / (intensity_time + intensity_freq) 33 | assert rel_error < 1e-12 34 | 35 | 36 | def test_5_sines(): 37 | t = np.linspace(-20, 20, 10000) 38 | freqs = np.linspace(1, 5, 5) 39 | z = np.sin(2 * np.pi * freqs[None, :] * t[:, None]) 40 | wi, zi = wt.kit.fft(t, z, axis=0) 41 | freq = np.abs(wi[np.argmax(zi, axis=0)]) 42 | assert np.allclose(freq, freqs, rtol=1e-3, atol=1e-3) 43 | 44 | 45 | def test_dimensionality_error(): 46 | with pytest.raises(wt.exceptions.DimensionalityError): 47 | t = np.linspace(-20, 20, 10000) 48 | freqs = np.linspace(1, 5, 5) 49 | z = np.sin(2 * np.pi * freqs[None, :] * t[:, None]) 50 | t = t[:, None] 51 | wt.kit.fft(t, z, axis=0) 52 | 53 | 54 | def test_even_spacing_error(): 55 | with pytest.raises(RuntimeError): 56 | xi = np.logspace(0, 2, 50) 57 | yi = 0 58 | wt.kit.fft(xi, yi) 59 | -------------------------------------------------------------------------------- /tests/kit/flatten_list.py: -------------------------------------------------------------------------------- 1 | """test flatten_list""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | 8 | 9 | # --- test ---------------------------------------------------------------------------------------- 10 | 11 | 12 | def test_list(): 13 | input = [[[1, 2, 3], [4, 5]], 6] 14 | output = wt.kit.flatten_list(input) 15 | assert output == [1, 2, 3, 4, 5, 6] 16 | -------------------------------------------------------------------------------- /tests/kit/fluence.py: -------------------------------------------------------------------------------- 1 | """Test fluence.""" 2 | 3 | # --- import ------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- test --------------------------------------------------------------- 12 | 13 | 14 | def test_even(): 15 | out = wt.kit.fluence(1, 2, 0.1, 1000, 1, "eV", "cm", "ps_t") 16 | checks = (31.83098, 99336493460095.2, 0.03183098) 17 | assert np.isclose(checks[0], out[0], rtol=1e-3) 18 | assert np.isclose(checks[1], out[1], rtol=1e-3) 19 | assert np.isclose(checks[2], out[2], rtol=1e-3) 20 | 21 | 22 | def test_average(): 23 | out = wt.kit.fluence(1, 2, 0.1, 1000, 1, "eV", "cm", "ps_t", "average") 24 | checks = (22.95969209043682, 71651412732766.67, 0.02295969209043682) 25 | assert np.isclose(checks[0], out[0], rtol=1e-3) 26 | assert np.isclose(checks[1], out[1], rtol=1e-3) 27 | assert np.isclose(checks[2], out[2], rtol=1e-3) 28 | 29 | 30 | if __name__ == "__main__": 31 | test_even() 32 | test_average() 33 | -------------------------------------------------------------------------------- /tests/kit/get_index.py: -------------------------------------------------------------------------------- 1 | """Test get_index.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | 8 | 9 | # --- test --------------------------------------------------------------------------------------- 10 | 11 | 12 | def test_string(): 13 | assert wt.kit.get_index(["w1", "d1", "d2"], "d2") == 2 14 | 15 | 16 | def test_int(): 17 | assert wt.kit.get_index(["w1", "w2", "w3"], 1) == 1 18 | -------------------------------------------------------------------------------- /tests/kit/get_path_matching.py: -------------------------------------------------------------------------------- 1 | """Test get_path_matching.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import os 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- define ------------------------------------------------------------------------------------- 12 | 13 | 14 | here = os.path.abspath(os.path.dirname(__file__)) 15 | 16 | 17 | # --- test --------------------------------------------------------------------------------------- 18 | 19 | 20 | def test_WrightTools(): 21 | wt.kit.get_path_matching("WrightTools") # exception will be raised if broken 22 | -------------------------------------------------------------------------------- /tests/kit/glob_handler.py: -------------------------------------------------------------------------------- 1 | """Test glob_handler.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import os 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- define ------------------------------------------------------------------------------------- 12 | 13 | 14 | here = os.path.abspath(os.path.dirname(__file__)) 15 | 16 | 17 | # --- test --------------------------------------------------------------------------------------- 18 | 19 | 20 | def test_here(): 21 | wt.kit.glob_handler(".py", here) # exception will be raised if broken 22 | -------------------------------------------------------------------------------- /tests/kit/intersperse.py: -------------------------------------------------------------------------------- 1 | """Test intersperse.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | 8 | 9 | # --- test --------------------------------------------------------------------------------------- 10 | 11 | 12 | def test_abcd(): 13 | lis = ["a", "b", "c", "d"] 14 | assert wt.kit.intersperse(lis, "blaise") == [ 15 | "a", 16 | "blaise", 17 | "b", 18 | "blaise", 19 | "c", 20 | "blaise", 21 | "d", 22 | ] 23 | 24 | 25 | def test_empty(): 26 | assert wt.kit.intersperse([], "blaise") == [] 27 | 28 | 29 | def test_1(): 30 | assert wt.kit.intersperse(["sprout"], "potato") == ["sprout"] 31 | -------------------------------------------------------------------------------- /tests/kit/joint_shape.py: -------------------------------------------------------------------------------- 1 | """Test joint_shape.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- test ---------------------------------------------------------------------------------------- 12 | 13 | 14 | def test_5x7(): 15 | arr1 = np.empty((5, 1)) 16 | arr2 = np.empty((1, 7)) 17 | assert wt.kit.joint_shape(arr1, arr2) == (5, 7) 18 | 19 | 20 | def test_3x4x5(): 21 | arr1 = np.empty((1, 4, 1)) 22 | arr2 = np.empty((3, 1, 5)) 23 | arr3 = np.empty((1, 1, 1)) 24 | assert wt.kit.joint_shape(arr1, arr2, arr3) == (3, 4, 5) 25 | -------------------------------------------------------------------------------- /tests/kit/leastsqfitter.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import WrightTools as wt 3 | 4 | 5 | def test_leastsq(): 6 | x = np.linspace(0, 10) 7 | y = np.linspace(10, 0) 8 | fit, cov = wt.kit.leastsqfitter([0, 0], x, y, lambda p, x: p[0] * x + p[1]) 9 | assert np.allclose(fit, [-1, 10]) 10 | assert np.allclose(cov, [0, 0]) 11 | 12 | 13 | def test_leastsq_no_corr(): 14 | x = np.linspace(0, 10) 15 | y = np.linspace(10, 0) 16 | # The third parameter does not determine output, this caused an exception in wt <= 3.2.1 17 | fit, cov = wt.kit.leastsqfitter([0, 0, 0], x, y, lambda p, x: p[0] * x + p[1]) 18 | assert np.allclose(fit, [-1, 10, 0]) 19 | assert np.allclose(cov, [0, 0, 0]) 20 | -------------------------------------------------------------------------------- /tests/kit/lineshapes.py: -------------------------------------------------------------------------------- 1 | """Test lineshapes.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | 10 | # numpy 2.0 compatibility 11 | trapezoid = np.trapezoid if int(np.__version__.split(".")[0]) > 1 else np.trapz 12 | 13 | # --- test ---------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_gaussian(): 17 | x = np.linspace(-2, 2, 1001) 18 | x0 = 0 19 | FWHM = 1 20 | y = wt.kit.gaussian(x, x0, FWHM, norm="area") 21 | assert np.isclose(trapezoid(y, x), 1, rtol=1e-3, atol=1e-3) 22 | y = wt.kit.gaussian(x, x0, FWHM, norm="height") 23 | assert np.isclose(y.max(), 1, rtol=1e-3, atol=1e-3) 24 | 25 | 26 | def test_lorentzian_complex(): 27 | x = np.linspace(-50, 50, 100001) 28 | x0 = 0 29 | G = 0.1 30 | y = wt.kit.lorentzian_complex(x, x0, G, norm="area_int") 31 | assert np.isclose(trapezoid(np.abs(y) ** 2, x), 1, rtol=1e-3, atol=1e-3) 32 | y = wt.kit.lorentzian_complex(x, x0, G, norm="height_imag") 33 | assert np.isclose(y.imag.max(), 1, rtol=1e-3, atol=1e-3) 34 | 35 | 36 | def test_lorentzian_real(): 37 | x = np.linspace(-50, 50, 100001) 38 | x0 = 0 39 | G = 0.1 40 | y = wt.kit.lorentzian_real(x, x0, G, norm="area") 41 | assert np.isclose(trapezoid(y, x), 1, rtol=1e-3, atol=1e-3) 42 | y = wt.kit.lorentzian_real(x, x0, G, norm="height") 43 | assert np.isclose(y.max(), 1, rtol=1e-3, atol=1e-3) 44 | 45 | 46 | def test_voigt(): 47 | x = np.linspace(-2, 2, 1001) 48 | x0 = 0 49 | G = 0.5 50 | FWHM = 1 51 | gauss = wt.kit.gaussian(x, x0, FWHM, norm="height") 52 | lor = wt.kit.lorentzian_real(x, x0, G, norm="height") 53 | y = wt.kit.voigt(x, x0, FWHM, 0) 54 | assert np.all(np.isclose(y / y.max(), gauss, rtol=1e-3, atol=1e-3)) 55 | y = wt.kit.voigt(x, x0, 1e-6, G) 56 | assert np.all(np.isclose(y / y.max(), lor, rtol=1e-3, atol=1e-3)) 57 | -------------------------------------------------------------------------------- /tests/kit/nm_width.py: -------------------------------------------------------------------------------- 1 | """Test nm_width.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- test --------------------------------------------------------------------------------------- 12 | 13 | 14 | def test_float(): 15 | assert np.isclose(wt.kit.nm_width(1300, 100), 592.593, atol=0.1) 16 | -------------------------------------------------------------------------------- /tests/kit/remove_nans_1D.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test remove_nans_1D.""" 3 | 4 | 5 | # --- import ------------------------------------------------------------------------------------- 6 | 7 | 8 | import numpy as np 9 | 10 | import WrightTools as wt 11 | 12 | 13 | # --- test --------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_simple(): 17 | arr = np.arange(-4, 6, dtype=float) 18 | arr[arr < 0] = np.nan 19 | assert wt.kit.remove_nans_1D(arr)[0].all() == np.arange(0, 6, dtype=float).all() 20 | 21 | 22 | def test_multiple(): 23 | arrs = [np.random.random(21) for _ in range(5)] 24 | arrs[0][0] = np.nan 25 | arrs[1][-1] = np.nan 26 | arrs = wt.kit.remove_nans_1D(*arrs) 27 | for arr in arrs: 28 | assert arr.size == 19 29 | 30 | 31 | def test_list(): 32 | assert np.all(wt.kit.remove_nans_1D([np.nan, 1, 2, 3])[0] == np.array([1, 2, 3])) 33 | 34 | 35 | if __name__ == "__main__": 36 | test_simple() 37 | test_multiple() 38 | test_list() 39 | -------------------------------------------------------------------------------- /tests/kit/share_nans.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test share_nans.""" 3 | 4 | 5 | # --- import ------------------------------------------------------------------------------------- 6 | 7 | 8 | import numpy as np 9 | 10 | import WrightTools as wt 11 | 12 | 13 | # --- test --------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_5(): 17 | arrs = [np.random.random(5) for _ in range(12)] 18 | arrs[2][2] = np.nan 19 | arrs = wt.kit.share_nans(*arrs) 20 | for arr in arrs: 21 | assert np.isnan(arr[2]) 22 | 23 | 24 | def test_broadcast(): 25 | a = np.array([[1, 2], [3, 4]]) 26 | b = np.array([[5, np.nan]]) 27 | 28 | ao, bo = wt.kit.share_nans(a, b) 29 | 30 | assert np.allclose(ao, np.array([[1, np.nan], [3, np.nan]]), equal_nan=True) 31 | assert np.allclose(bo, np.array([[5, np.nan], [5, np.nan]]), equal_nan=True) 32 | 33 | bo, ao = wt.kit.share_nans(b, a) 34 | 35 | assert np.allclose(ao, np.array([[1, np.nan], [3, np.nan]]), equal_nan=True) 36 | assert np.allclose(bo, np.array([[5, np.nan], [5, np.nan]]), equal_nan=True) 37 | 38 | 39 | # --- run ----------------------------------------------------------------------------------------- 40 | 41 | 42 | if __name__ == "__main__": 43 | test_5() 44 | test_broadcast() 45 | -------------------------------------------------------------------------------- /tests/kit/signed.py: -------------------------------------------------------------------------------- 1 | """Test guess_signed""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | import WrightTools as wt 8 | 9 | 10 | # --- test --------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_many_ranges(): 14 | for minmax, signed in [ 15 | ([-0.05, 1], False), 16 | ([-1, 0.05], False), 17 | ([-1, 1], True), 18 | ([0, 0], True), 19 | ([0, -1], False), 20 | ([-1, 0.5], True), 21 | ]: 22 | assert wt.kit.guess_signed(np.array(minmax)) == signed 23 | 24 | 25 | def test_channel(): 26 | d = wt.Data() 27 | chan = d.create_channel("chan", values=np.linspace(3, 4, 16).reshape(4, 4)) 28 | assert wt.kit.guess_signed(chan) == False 29 | chan.null = 3.5 30 | assert wt.kit.guess_signed(chan) 31 | -------------------------------------------------------------------------------- /tests/kit/smooth_1D.py: -------------------------------------------------------------------------------- 1 | """Test kit.smooth_1D.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- test ---------------------------------------------------------------------------------------- 12 | 13 | 14 | def test_basic_smoothing_functionality(): 15 | # create arrays 16 | x = np.linspace(0, 10, 1000) 17 | y = np.sin(x) 18 | np.random.seed(seed=12) 19 | r = np.random.rand(1000) - 0.5 20 | yr = y + r 21 | # iterate through window types 22 | windows = ["flat", "hanning", "hamming", "bartlett", "blackman"] 23 | for w in windows: 24 | out = wt.kit.smooth_1D(yr, n=101, smooth_type=w) 25 | check_arr = out - y 26 | check_arr = check_arr[50:-50] # get rid of edge effects 27 | assert np.allclose(check_arr, 0, rtol=0.2, atol=0.2) 28 | 29 | 30 | # --- run ----------------------------------------------------------------------------------------- 31 | 32 | 33 | if __name__ == "__main__": 34 | test_basic_smoothing_functionality() 35 | -------------------------------------------------------------------------------- /tests/kit/string2identifier.py: -------------------------------------------------------------------------------- 1 | """Test string2identifier.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | 8 | 9 | # --- test --------------------------------------------------------------------------------------- 10 | 11 | 12 | def test_ω(): 13 | assert wt.kit.string2identifier("blaiseω") == "blaise_" 14 | 15 | 16 | def test_numstart(): 17 | assert wt.kit.string2identifier("2blaise") == "_2blaise" 18 | 19 | 20 | def test_space(): 21 | assert wt.kit.string2identifier("blaise thompson") == "blaise_thompson" 22 | -------------------------------------------------------------------------------- /tests/kit/svd.py: -------------------------------------------------------------------------------- 1 | """Test svd.""" 2 | 3 | import numpy as np 4 | import WrightTools as wt 5 | 6 | 7 | def test_int(): 8 | arr1 = np.linspace(0, 1, 20) 9 | arr2 = np.linspace(0, 1, 21) 10 | arr = arr1[:, None] * arr2[None, :] 11 | u, v, s = wt.kit.svd(arr, i=0) 12 | assert u.shape == (20,) 13 | assert v.shape == (21,) 14 | assert s.shape == () 15 | 16 | 17 | def test_reconstruction(): 18 | arr1 = np.linspace(0, 1, 20) 19 | arr2 = np.linspace(0, 1, 21) 20 | arr = arr1[:, None] * arr2[None, :] 21 | U, V, s = wt.kit.svd(arr, i=None) 22 | U = U.T 23 | S = np.diag(s) 24 | assert np.allclose(arr, np.dot(U, np.dot(S, V))) 25 | 26 | 27 | def test_slice(): 28 | arr1 = np.linspace(0, 1, 20) 29 | arr2 = np.linspace(0, 1, 21) 30 | arr = arr1[:, None] * arr2[None, :] 31 | u, v, s = wt.kit.svd(arr, i=slice(1, 5)) 32 | assert u.shape == (4, 20) 33 | assert v.shape == (4, 21) 34 | assert s.shape == (4,) 35 | 36 | 37 | if __name__ == "__main__": 38 | test_int() 39 | test_reconstruction() 40 | test_slice() 41 | -------------------------------------------------------------------------------- /tests/kit/symmetric_sqrt.py: -------------------------------------------------------------------------------- 1 | """test symmetric_sqrt""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- test ---------------------------------------------------------------------------------------- 12 | 13 | 14 | def test_numbers(): 15 | numbers = np.random.normal(size=100) 16 | for number in numbers: 17 | answer = wt.kit.symmetric_sqrt(number) 18 | assert answer == np.sign(number) * np.sqrt(np.abs(number)) 19 | 20 | 21 | def test_no_reallocation(): 22 | a = np.linspace(-9, 9, 3) 23 | out = np.empty_like(a) 24 | ret = wt.kit.symmetric_sqrt(a, out=out) 25 | assert out is ret 26 | assert np.allclose(ret, [-3, 0, 3]) 27 | -------------------------------------------------------------------------------- /tests/kit/timer.py: -------------------------------------------------------------------------------- 1 | """Test timer.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import time 7 | 8 | import numpy as np 9 | 10 | import WrightTools as wt 11 | 12 | 13 | # --- test --------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_wait(): 17 | with wt.kit.Timer(): 18 | time.sleep(1) 19 | 20 | 21 | def test_instance(): 22 | t = wt.kit.Timer(verbose=False) 23 | with t: 24 | time.sleep(1) 25 | assert np.isclose(t.interval, 1, atol=1) 26 | -------------------------------------------------------------------------------- /tests/kit/timestamp.py: -------------------------------------------------------------------------------- 1 | """Test timestamp.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | 8 | 9 | # --- test --------------------------------------------------------------------------------------- 10 | 11 | 12 | def test_now(): 13 | wt.kit.TimeStamp() # exception will be raised upon failure 14 | 15 | 16 | def test_utc(): 17 | wt.kit.timestamp_from_RFC3339("2017-11-13 16:09:17Z") # exception will be raised upon failure 18 | 19 | 20 | def test_date(): 21 | ts = wt.kit.timestamp_from_RFC3339("2017-11-13 16:09:17-6") 22 | assert len(ts.date) == 10 23 | 24 | 25 | def test_hms(): 26 | ts = wt.kit.timestamp_from_RFC3339("2017-11-13 16:33:44-6") 27 | assert len(ts.hms) == 8 28 | 29 | 30 | def test_human(): 31 | ts = wt.kit.TimeStamp() 32 | assert len(ts.human) == 19 33 | 34 | 35 | def test_RFC3339(): 36 | ts = wt.kit.TimeStamp() 37 | assert ts.RFC3339 38 | assert wt.kit.timestamp_from_RFC3339(ts.RFC3339) == ts 39 | 40 | 41 | def test_RFC5322(): 42 | ts = wt.kit.TimeStamp() 43 | assert ts.RFC5322 44 | 45 | 46 | def test_path(): 47 | ts = wt.kit.TimeStamp() 48 | assert ts.path 49 | -------------------------------------------------------------------------------- /tests/kit/unicode.py: -------------------------------------------------------------------------------- 1 | """Test unicode dictionary.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | 8 | 9 | # --- test --------------------------------------------------------------------------------------- 10 | 11 | 12 | def test_print(): 13 | for key, value in wt.kit.unicode_dictionary.items(): 14 | print(key, value) 15 | -------------------------------------------------------------------------------- /tests/kit/unique.py: -------------------------------------------------------------------------------- 1 | """Test unique.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | 6 | import numpy as np 7 | 8 | import WrightTools as wt 9 | 10 | 11 | # --- test --------------------------------------------------------------------------------------- 12 | 13 | 14 | def test_5(): 15 | arr = np.array([0, 1, 2, 3, 3 + 1e-7]) 16 | assert np.isclose(wt.kit.unique(arr).all(), np.array([0, 1, 2, 3.000005]).all()) 17 | 18 | 19 | def test_5_tolerance(): 20 | arr = np.array([0, 1, 2, 3, 3 + 1e-7]) 21 | assert wt.kit.unique(arr, tolerance=1e-8).all() == arr.all() 22 | -------------------------------------------------------------------------------- /tests/kit/valid_index.py: -------------------------------------------------------------------------------- 1 | """Test valid index function.""" 2 | 3 | # --- import -------------------------------------------------------------------------------------- 4 | 5 | 6 | import WrightTools as wt 7 | 8 | 9 | # --- test ---------------------------------------------------------------------------------------- 10 | 11 | 12 | def test__1_5__7(): 13 | index = (1, 5) 14 | shape = (7,) 15 | assert wt.kit.valid_index(index, shape) == (5,) 16 | 17 | 18 | def test__4_2_12__1_25_1(): 19 | index = (4, 2, 12) 20 | shape = (1, 25, 1) 21 | assert wt.kit.valid_index(index, shape) == (0, 2, 0) 22 | 23 | 24 | def test__s__23(): 25 | index = (slice(None),) 26 | shape = (23,) 27 | assert wt.kit.valid_index(index, shape) == (slice(None),) 28 | 29 | 30 | def test__s__1_25(): 31 | index = (slice(None),) 32 | shape = (1, 25) 33 | assert wt.kit.valid_index(index, shape) == (slice(None), slice(None)) 34 | 35 | 36 | def test__ss_ss__1_25(): 37 | index = (slice(20, None, 1), slice(20, None, 1)) 38 | shape = (1, 25) 39 | assert wt.kit.valid_index(index, shape) == (slice(None), slice(20, None, 1)) 40 | 41 | 42 | def test__s__13_25_99(): 43 | index = (slice(None),) 44 | shape = (13, 25, 99) 45 | assert wt.kit.valid_index(index, shape) == (slice(None), slice(None), slice(None)) 46 | 47 | 48 | def test__s_s__51(): 49 | index = (slice(None), slice(None)) 50 | shape = (51,) 51 | assert wt.kit.valid_index(index, shape) == (slice(None),) 52 | 53 | 54 | # --- run ----------------------------------------------------------------------------------------- 55 | 56 | 57 | if __name__ == "__main__": 58 | test__1_5__7() 59 | test__4_2_12__1_25_1() 60 | test__s__23() 61 | test__s__1_25() 62 | test__ss_ss__1_25() 63 | test__s__13_25_99() 64 | test__s_s__51() 65 | -------------------------------------------------------------------------------- /tests/kit/zoom2D.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | """Test smooth2D function.""" 3 | 4 | # --- import -------------------------------------------------------------------------------------- 5 | 6 | import WrightTools as wt 7 | import numpy as np 8 | 9 | 10 | # --- tests --------------------------------------------------------------------------------------- 11 | 12 | 13 | def test_default(): 14 | xi = np.linspace(-10, 10, 100) 15 | yi = np.linspace(-10, 10, 100) 16 | 17 | zi = np.sin(xi[:, None]) * np.cos(yi[None, :]) 18 | 19 | xo, yo, zo = wt.kit.zoom2D(xi, yi, zi) 20 | 21 | zcheck = np.sin(xo[:, None]) * np.cos(yo[None, :]) 22 | 23 | assert xo.shape == (300,) 24 | assert yo.shape == (300,) 25 | assert zo.shape == (300, 300) 26 | 27 | assert np.all(np.isclose(zo, zcheck, 0.01)) # all values within 1 percent of "actual" 28 | 29 | 30 | def test_non_default(): 31 | xi = np.linspace(-10, 10, 100) 32 | yi = np.linspace(-10, 10, 100) 33 | 34 | zi = np.sin(xi[:, None]) * np.cos(yi[None, :]) 35 | 36 | xo, yo, zo = wt.kit.zoom2D(xi, yi, zi, 2, 4) 37 | 38 | zcheck = np.sin(xo[:, None]) * np.cos(yo[None, :]) 39 | 40 | assert xo.shape == (200,) 41 | assert yo.shape == (400,) 42 | assert zo.shape == (200, 400) 43 | 44 | assert np.all(np.isclose(zo, zcheck, 0.01)) # all values within 1 percent of "actual" 45 | 46 | 47 | # --- run ----------------------------------------------------------------------------------------- 48 | 49 | 50 | if __name__ == "__main__": 51 | test_default() 52 | test_non_default() 53 | -------------------------------------------------------------------------------- /tests/units.py: -------------------------------------------------------------------------------- 1 | """Test units.""" 2 | 3 | # --- import ------------------------------------------------------------------------------------- 4 | 5 | import numpy as np 6 | import pytest 7 | import pint 8 | 9 | import WrightTools as wt 10 | from WrightTools import datasets 11 | 12 | 13 | # --- test --------------------------------------------------------------------------------------- 14 | 15 | 16 | def test_axis_convert_exception(): 17 | p = datasets.PyCMDS.w2_w1_000 18 | data = wt.data.from_PyCMDS(p) 19 | try: 20 | data.w2.convert("fs") 21 | except wt.exceptions.UnitsError: 22 | assert True 23 | else: 24 | assert False 25 | 26 | 27 | def test_in_mm_conversion(): 28 | assert np.isclose(wt.units.convert(25.4, "mm", "in"), 1.0) 29 | assert np.isclose(wt.units.convert(1.0, "in", "mm"), 25.4) 30 | 31 | 32 | def test_unit_registry(): 33 | values = np.linspace(-1, 1, 51) 34 | d = wt.Data(name="test") 35 | d.create_variable("Bgood", values=values, units="tesla") 36 | d.transform("Bgood") 37 | 38 | 39 | def test_bad_unit_registry(): 40 | values = np.linspace(-1, 1, 51) 41 | d = wt.Data(name="test") 42 | with pytest.raises(ValueError): 43 | d.create_variable("Bbad", values=values, units="Tesla") 44 | d.transform("Bbad") 45 | 46 | 47 | def test_0_inf(): 48 | assert wt.units.convert(0, "wn", "nm") == np.inf 49 | assert wt.units.convert(0, "nm", "wn") == np.inf 50 | 51 | 52 | def test_round_trip(): 53 | start = 12500.0 54 | halftrip = wt.units.convert(start, "wn", "eV") 55 | fulltrip = wt.units.convert(halftrip, "eV", "wn") 56 | assert np.isclose(start, fulltrip) 57 | 58 | 59 | def test_return_input_noerror(): 60 | val = 12500 61 | out = wt.units.convert(val, current_unit=None, destination_unit=None) 62 | assert val == out 63 | 64 | 65 | def test_return_input_warning(): 66 | val = 12500 67 | with pytest.warns(UserWarning): 68 | out = wt.units.convert(val, None, "eV") 69 | assert val == out 70 | with pytest.warns(UserWarning): 71 | out = wt.units.convert(val, "wn", None) 72 | assert val == out 73 | 74 | 75 | def test_error(): 76 | val = 12500 77 | with pytest.raises(pint.errors.DimensionalityError): 78 | wt.units.convert(val, "wn", "W") 79 | with pytest.raises(pint.errors.DimensionalityError): 80 | wt.units.convert(val, "W", "wn") 81 | --------------------------------------------------------------------------------