pychemstation 0.10.0__tar.gz → 0.10.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- pychemstation-0.10.2/.gitignore +7 -0
- pychemstation-0.10.2/.gitlab-ci.yml +16 -0
- pychemstation-0.10.2/CHANGELOG.md +5 -0
- pychemstation-0.10.2/CONTRIBUTING.md +98 -0
- {pychemstation-0.10.0/pychemstation.egg-info → pychemstation-0.10.2}/PKG-INFO +11 -9
- pychemstation-0.10.2/build/lib/pychemstation/analysis/spec_utils.py +304 -0
- pychemstation-0.10.2/build/lib/pychemstation/analysis/utils.py +63 -0
- pychemstation-0.10.2/build/lib/pychemstation/control/comm.py +206 -0
- pychemstation-0.10.2/build/lib/pychemstation/control/controllers/devices/column.py +12 -0
- pychemstation-0.10.2/build/lib/pychemstation/control/controllers/devices/pump.py +43 -0
- pychemstation-0.10.2/build/lib/pychemstation/control/controllers/method.py +338 -0
- pychemstation-0.10.2/build/lib/pychemstation/control/controllers/sequence.py +190 -0
- pychemstation-0.10.2/build/lib/pychemstation/control/controllers/table_controller.py +266 -0
- pychemstation-0.10.2/build/lib/pychemstation/control/table/__init__.py +3 -0
- pychemstation-0.10.2/build/lib/pychemstation/control/table/method.py +274 -0
- pychemstation-0.10.2/build/lib/pychemstation/control/table/sequence.py +210 -0
- pychemstation-0.10.2/build/lib/pychemstation/control/table/table_controller.py +201 -0
- pychemstation-0.10.2/build/lib/tests/__init__.py +0 -0
- pychemstation-0.10.2/build/lib/tests/test_comb.py +136 -0
- pychemstation-0.10.2/build/lib/tests/test_comm.py +65 -0
- pychemstation-0.10.2/build/lib/tests/test_inj.py +39 -0
- pychemstation-0.10.2/build/lib/tests/test_method.py +99 -0
- pychemstation-0.10.2/build/lib/tests/test_nightly.py +80 -0
- pychemstation-0.10.2/build/lib/tests/test_proc_rep.py +52 -0
- pychemstation-0.10.2/build/lib/tests/test_sequence.py +125 -0
- pychemstation-0.10.2/build/lib/tests/test_stable.py +276 -0
- pychemstation-0.10.2/doc/index.html +7 -0
- pychemstation-0.10.2/doc/pychemstation/analysis/base_spectrum.html +2216 -0
- pychemstation-0.10.2/doc/pychemstation/analysis/spec_utils.html +1073 -0
- pychemstation-0.10.2/doc/pychemstation/analysis/utils.html +443 -0
- pychemstation-0.10.2/doc/pychemstation/analysis.html +244 -0
- pychemstation-0.10.2/doc/pychemstation/control/chromatogram.html +863 -0
- pychemstation-0.10.2/doc/pychemstation/control/hplc.html +2987 -0
- pychemstation-0.10.2/doc/pychemstation/control.html +334 -0
- pychemstation-0.10.2/doc/pychemstation/generated.html +3358 -0
- pychemstation-0.10.2/doc/pychemstation/utils/chemstation.html +1165 -0
- pychemstation-0.10.2/doc/pychemstation/utils/constants.html +301 -0
- pychemstation-0.10.2/doc/pychemstation/utils/hplc_param_types.html +2741 -0
- pychemstation-0.10.2/doc/pychemstation/utils.html +245 -0
- pychemstation-0.10.2/doc/pychemstation.html +356 -0
- pychemstation-0.10.2/doc/search.js +46 -0
- pychemstation-0.10.2/pychemstation/__init__.py +3 -0
- pychemstation-0.10.2/pychemstation/analysis/__init__.py +5 -0
- pychemstation-0.10.2/pychemstation/analysis/base_spectrum.py +506 -0
- pychemstation-0.10.2/pychemstation/analysis/process_report.py +283 -0
- pychemstation-0.10.2/pychemstation/control/README.md +132 -0
- pychemstation-0.10.2/pychemstation/control/__init__.py +8 -0
- pychemstation-0.10.2/pychemstation/control/controllers/README.md +1 -0
- pychemstation-0.10.2/pychemstation/control/controllers/__init__.py +13 -0
- pychemstation-0.10.2/pychemstation/control/controllers/comm.py +222 -0
- pychemstation-0.10.2/pychemstation/control/controllers/devices/__init__.py +0 -0
- pychemstation-0.10.2/pychemstation/control/controllers/devices/device.py +39 -0
- pychemstation-0.10.2/pychemstation/control/controllers/devices/injector.py +51 -0
- pychemstation-0.10.2/pychemstation/control/controllers/tables/__init__.py +0 -0
- pychemstation-0.10.2/pychemstation/control/controllers/tables/method.py +405 -0
- pychemstation-0.10.2/pychemstation/control/controllers/tables/ms.py +21 -0
- pychemstation-0.10.2/pychemstation/control/controllers/tables/sequence.py +290 -0
- pychemstation-0.10.2/pychemstation/control/controllers/tables/table.py +315 -0
- pychemstation-0.10.2/pychemstation/control/hplc.py +299 -0
- pychemstation-0.10.2/pychemstation/generated/__init__.py +56 -0
- pychemstation-0.10.2/pychemstation/generated/dad_method.py +367 -0
- pychemstation-0.10.2/pychemstation/generated/pump_method.py +519 -0
- pychemstation-0.10.2/pychemstation/utils/__init__.py +0 -0
- pychemstation-0.10.2/pychemstation/utils/chromatogram.py +116 -0
- pychemstation-0.10.2/pychemstation/utils/injector_types.py +52 -0
- pychemstation-0.10.2/pychemstation/utils/macro.py +100 -0
- pychemstation-0.10.2/pychemstation/utils/method_types.py +56 -0
- pychemstation-0.10.2/pychemstation/utils/num_utils.py +65 -0
- pychemstation-0.10.2/pychemstation/utils/parsing.py +291 -0
- pychemstation-0.10.2/pychemstation/utils/pump_types.py +7 -0
- pychemstation-0.10.2/pychemstation/utils/sequence_types.py +54 -0
- pychemstation-0.10.2/pychemstation/utils/spec_utils.py +304 -0
- pychemstation-0.10.2/pychemstation/utils/table_types.py +95 -0
- pychemstation-0.10.2/pychemstation/utils/tray_types.py +183 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2}/pyproject.toml +12 -1
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/0_2025-03-15 19-14-35.PDF +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/ACQRES.REG +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/CSlbk.ini +5 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DA.M/DAMETHOD.REG +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DA.M/INFO.MTH +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DA.M/RECALIB.MTH +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DA.M/rpthead.txt +63 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1.UV +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1A.ch +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1A.npz +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1B.ch +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1B.npz +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1C.ch +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1C.npz +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1D.ch +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1D.npz +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1E.ch +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DAD1E.npz +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/DiagResults.REG +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/PMP1.AnalyticalResults.drvml +15 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/REPORT01.CSV +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/REPORT02.CSV +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/REPORT03.CSV +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/REPORT04.CSV +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/REPORT05.CSV +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/RUN.LOG +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/Report.TXT +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/Report00.CSV +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/Report01.xls +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/SAMPLE.XML +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/SAMPLE.XML.bak +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/WLS1.Sampler.scml +22 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/acq.macaml +957 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/acq.txt +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/acq_MethHist.txt +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/acq_damethod.reg +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/da.macaml +1113 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/lcdiag.reg +0 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/sample.acaml +5324 -0
- pychemstation-0.10.2/tests/0_2025-03-15 19-14-35.D/single.B +0 -0
- pychemstation-0.10.2/tests/__init__.py +0 -0
- pychemstation-0.10.2/tests/constants.py +134 -0
- pychemstation-0.10.2/tests/hplc_talk.mac +81 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/CSlbk.ini +5 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/ACQ.MS +311 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/Agilent1200erDadDriver1.RapidControl.ConfigXML.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/Agilent1200erDadDriver1.RapidControl.MethodMetaData.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/Agilent1200erDadDriver1.RapidControl.MethodXML.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/AgilentColumnCompDriver1.RapidControl.ConfigXML.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/AgilentColumnCompDriver1.RapidControl.MethodMetaData.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/AgilentColumnCompDriver1.RapidControl.MethodXML.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/AgilentPumpDriver1.RapidControl.ConfigXML.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/AgilentPumpDriver1.RapidControl.MethodMetaData.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/AgilentPumpDriver1.RapidControl.MethodXML.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/AgilentSamplerDriver1.RapidControl.ConfigXML.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/AgilentSamplerDriver1.RapidControl.MethodMetaData.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/AgilentSamplerDriver1.RapidControl.MethodXML.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/AgilentSamplerDriver1.RapidControl.PretreatXML.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/DAMETHOD.REG +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/FIA.REG +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/INFO.MTH +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/INJECTOR.MTH +3 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/MassHunterIntegration.ini +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/RECALIB.MTH +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/RapidControl.InstrumentConfig.xml +65 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/rpthead.txt +63 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/GENERAL-POROSHELL-OPT.M/smpl_pur.mth +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/Methods.Reg +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/hplc_testing.B +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/hplc_testing.LOG +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/hplc_testing.S +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/hplc_testing.Start +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/ACQRES.REG +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/CSlbk.ini +5 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DA.M/DAMETHOD.REG +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DA.M/INFO.MTH +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DA.M/RECALIB.MTH +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DA.M/rpthead.txt +63 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1.UV +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1A.ch +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1A.npz +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1B.ch +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1B.npz +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1C.ch +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1C.npz +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1D.ch +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1D.npz +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1E.ch +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DAD1E.npz +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/DiagResults.REG +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/Limsinf.xml +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/PMP1.AnalyticalResults.drvml +15 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/REPORT01.CSV +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/REPORT02.CSV +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/REPORT03.CSV +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/REPORT04.CSV +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/REPORT05.CSV +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/RUN.LOG +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/Report.TXT +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/Report00.CSV +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/Report01.xls +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/SAMPLE.XML +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/SAMPLE.XML.bak +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/WLS1.Sampler.scml +22 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/acq.macaml +921 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/acq.txt +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/acq_MethHist.txt +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/acq_damethod.reg +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/da.macaml +1113 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/hplc_testing 2025-03-27 17-13-47_run seq with new method.PDF +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/lcdiag.reg +0 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/run seq with new method.D/sequence.acam_ +4404 -0
- pychemstation-0.10.2/tests/hplc_testing 2025-03-27 17-13-47/sequence.acaml +4422 -0
- pychemstation-0.10.2/tests/out.txt +17822 -0
- pychemstation-0.10.2/tests/test_offline_stable.py +69 -0
- pychemstation-0.10.2/tests/test_online_stable.py +275 -0
- pychemstation-0.10.2/tests/test_runs_stable.py +225 -0
- pychemstation-0.10.2/update-lib.sh +6 -0
- pychemstation-0.10.2/uv.lock +2062 -0
- pychemstation-0.10.0/setup.cfg +0 -4
- pychemstation-0.10.0/setup.py +0 -31
- {pychemstation-0.10.0 → pychemstation-0.10.2}/LICENSE +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2}/README.md +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/__init__.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/analysis/__init__.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/analysis/base_spectrum.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/analysis/process_report.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/__init__.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/controllers/__init__.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/controllers/comm.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/controllers/devices/__init__.py +0 -0
- /pychemstation-0.10.0/pychemstation/control/controllers/tables/__init__.py → /pychemstation-0.10.2/build/lib/pychemstation/control/controllers/devices/dad.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/controllers/devices/device.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/controllers/devices/injector.py +0 -0
- {pychemstation-0.10.0/pychemstation/utils → pychemstation-0.10.2/build/lib/pychemstation/control/controllers/tables}/__init__.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/controllers/tables/method.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/controllers/tables/ms.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/controllers/tables/sequence.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/controllers/tables/table.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/control/hplc.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/generated/__init__.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/generated/dad_method.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/generated/pump_method.py +0 -0
- {pychemstation-0.10.0/tests → pychemstation-0.10.2/build/lib/pychemstation/utils}/__init__.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/chromatogram.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/injector_types.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/macro.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/method_types.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/num_utils.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/parsing.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/pump_types.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/sequence_types.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/spec_utils.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/table_types.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/pychemstation/utils/tray_types.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/tests/constants.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/tests/test_offline_stable.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/tests/test_online_stable.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/build/lib}/tests/test_runs_stable.py +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2/pychemstation.egg-info}/PKG-INFO +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2}/pychemstation.egg-info/SOURCES.txt +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2}/pychemstation.egg-info/dependency_links.txt +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2}/pychemstation.egg-info/requires.txt +0 -0
- {pychemstation-0.10.0 → pychemstation-0.10.2}/pychemstation.egg-info/top_level.txt +0 -0
@@ -0,0 +1,16 @@
|
|
1
|
+
stages:
|
2
|
+
- deploy
|
3
|
+
|
4
|
+
pages:
|
5
|
+
stage: deploy
|
6
|
+
image: python:3.12-slim
|
7
|
+
before_script:
|
8
|
+
- apt-get update && apt-get install make --no-install-recommends -y
|
9
|
+
- python -m pip install -e .
|
10
|
+
script:
|
11
|
+
- pdoc -o doc pychemstation
|
12
|
+
after_script:
|
13
|
+
- mv doc/ ./public/
|
14
|
+
artifacts:
|
15
|
+
paths:
|
16
|
+
- public
|
@@ -0,0 +1,98 @@
|
|
1
|
+
# Contributing Guide
|
2
|
+
|
3
|
+
Modified from [here](https://github.com/cncf/project-template/blob/main/CONTRIBUTING.md#contributing-guide).
|
4
|
+
|
5
|
+
* [Ways to Contribute](#ways-to-contribute)
|
6
|
+
* [Find an Issue](#find-an-issue)
|
7
|
+
* [Ask for Help](#ask-for-help)
|
8
|
+
* [Pull Request Lifecycle](#pull-request-lifecycle)
|
9
|
+
* [Development Environment Setup](#development-environment-setup)
|
10
|
+
* [Sign Your Commits](#sign-your-commits)
|
11
|
+
* [Pull Request Checklist](#pull-request-checklist)
|
12
|
+
|
13
|
+
Welcome! We are glad that you want to contribute to Hein Analytical Control! 💖
|
14
|
+
|
15
|
+
As you get started, you are in the best position to give us feedback on areas of
|
16
|
+
our project that we need help with including:
|
17
|
+
|
18
|
+
* Problems found during setting up a new developer environment
|
19
|
+
* Gaps in our Quickstart Guide or documentation
|
20
|
+
* Bugs in our Python scripts
|
21
|
+
|
22
|
+
If anything doesn't make sense, or doesn't work when you run it, please open a
|
23
|
+
bug report and let us know!
|
24
|
+
|
25
|
+
## Ways to Contribute
|
26
|
+
|
27
|
+
We welcome many different types of contributions including:
|
28
|
+
|
29
|
+
* New features
|
30
|
+
* Bug fixes
|
31
|
+
* Documentation
|
32
|
+
|
33
|
+
## Find an Issue
|
34
|
+
|
35
|
+
If there are currently issues present, please feel free to take one!
|
36
|
+
Comment with something like "I would like to take this issue",
|
37
|
+
and our team will communicate further with you in that issue.
|
38
|
+
|
39
|
+
## Ask for Help
|
40
|
+
|
41
|
+
The best way to reach us with a question when contributing is to ask on:
|
42
|
+
|
43
|
+
* The original GitLab issue
|
44
|
+
* Via email at: hao.lucyy@gmail.com (only inquiries sent to this email regarding this library will be answered)
|
45
|
+
|
46
|
+
## Pull Request Lifecycle
|
47
|
+
|
48
|
+
⚠️ **Explain your pull request process**
|
49
|
+
|
50
|
+
## Development Environment Setup
|
51
|
+
|
52
|
+
First, clone this repo. All required packages are specified in `pyproject.toml`.
|
53
|
+
We use [poetry](https://python-poetry.org/), but you can adjust the `pyproject.toml` to
|
54
|
+
work with your Python package manager. Activate your environment via your package manager's instructions
|
55
|
+
and this should be all you need to start development.
|
56
|
+
|
57
|
+
To update documentation, we use [Sphinx](https://www.sphinx-doc.org/en/master/). Install via instructions on
|
58
|
+
Sphinx's website. If you want a local version of the documentation website, then `cd docs`, `make clean`, `make html`.
|
59
|
+
Then within `docs/build`, open `index.html` in your browser.
|
60
|
+
|
61
|
+
## Sign Your Commits
|
62
|
+
|
63
|
+
### DCO
|
64
|
+
Licensing is important to open source projects. It provides some assurances that
|
65
|
+
the software will continue to be available based under the terms that the
|
66
|
+
author(s) desired. We require that contributors sign off on commits submitted to
|
67
|
+
our project's repositories. The [Developer Certificate of Origin
|
68
|
+
(DCO)](https://probot.github.io/apps/dco/) is a way to certify that you wrote and
|
69
|
+
have the right to contribute the code you are submitting to the project.
|
70
|
+
|
71
|
+
You sign-off by adding the following to your commit messages. Your sign-off must
|
72
|
+
match the git user and email associated with the commit.
|
73
|
+
|
74
|
+
This is my commit message
|
75
|
+
|
76
|
+
Signed-off-by: Your Name <your.name@example.com>
|
77
|
+
|
78
|
+
Git has a `-s` command line option to do this automatically:
|
79
|
+
|
80
|
+
git commit -s -m 'This is my commit message'
|
81
|
+
|
82
|
+
If you forgot to do this and have not yet pushed your changes to the remote
|
83
|
+
repository, you can amend your commit with the sign-off by running
|
84
|
+
|
85
|
+
git commit --amend -s
|
86
|
+
|
87
|
+
## Pull Request Checklist
|
88
|
+
|
89
|
+
When you submit your pull request, or you push new commits to it, our automated
|
90
|
+
systems will run some checks on your new code. We require that your pull request
|
91
|
+
passes these checks, but we also have more criteria than just that before we can
|
92
|
+
accept and merge it. We recommend that you check the following things locally
|
93
|
+
before you submit your code:
|
94
|
+
|
95
|
+
- have you provided a doc string for new functionality OR if you have extended an existing function,
|
96
|
+
ensure the doc string is still valid
|
97
|
+
- are you using type annotations?
|
98
|
+
- are your commit messages following the mentioned conventions?
|
@@ -1,13 +1,17 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: pychemstation
|
3
|
-
Version: 0.10.
|
3
|
+
Version: 0.10.2
|
4
4
|
Summary: Library to interact with Chemstation software, primarily used in Hein lagit branch -mb
|
5
|
-
|
6
|
-
|
5
|
+
Project-URL: Documentation, https://pychemstation-e5a086.gitlab.io/pychemstation.html
|
6
|
+
Project-URL: Repository, https://gitlab.com/heingroup/device-api/pychemstation
|
7
7
|
Author-email: lucyhao <hao.lucyy@gmail.com>
|
8
|
-
Requires-Python: >=3.10
|
9
|
-
Description-Content-Type: text/markdown
|
10
8
|
License-File: LICENSE
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
10
|
+
Classifier: Operating System :: OS Independent
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
14
|
+
Requires-Python: >=3.10
|
11
15
|
Requires-Dist: aghplctools>=4.8.8
|
12
16
|
Requires-Dist: coverage>=7.6.1
|
13
17
|
Requires-Dist: matplotlib>=3.7.5
|
@@ -22,9 +26,7 @@ Requires-Dist: seabreeze>=2.9.2
|
|
22
26
|
Requires-Dist: setuptools>=75.3.2
|
23
27
|
Requires-Dist: twine>=6.1.0
|
24
28
|
Requires-Dist: xsdata>=24.9
|
25
|
-
|
26
|
-
Dynamic: home-page
|
27
|
-
Dynamic: license-file
|
29
|
+
Description-Content-Type: text/markdown
|
28
30
|
|
29
31
|
# Agilent HPLC Macro Control
|
30
32
|
|
@@ -123,4 +125,4 @@ Lucy Hao, Maria Politi
|
|
123
125
|
automated method development guided by Bayesian optimization
|
124
126
|
**](https://pubs.rsc.org/en/content/articlelanding/2024/dd/d4dd00062e),
|
125
127
|
created by members in the Bourne Group. Copyright © Bourne Group, used under
|
126
|
-
the [MIT](https://opensource.org/license/mit) license.
|
128
|
+
the [MIT](https://opensource.org/license/mit) license.
|
@@ -0,0 +1,304 @@
|
|
1
|
+
"""
|
2
|
+
Module contains various utility function for spectral data processing and
|
3
|
+
analysis.
|
4
|
+
"""
|
5
|
+
|
6
|
+
import numpy as np
|
7
|
+
import scipy
|
8
|
+
|
9
|
+
from .utils import find_nearest_value_index
|
10
|
+
|
11
|
+
|
12
|
+
def create_binary_peak_map(data):
|
13
|
+
"""Return binary map of the peaks within data points.
|
14
|
+
|
15
|
+
True values are assigned to potential peak points, False - to baseline.
|
16
|
+
|
17
|
+
Args:
|
18
|
+
data (:obj:np.array): 1D array with data points.
|
19
|
+
|
20
|
+
Returns:
|
21
|
+
:obj:np.array, dtype=bool: Mapping of data points, where True is
|
22
|
+
potential peak region point, False - baseline.
|
23
|
+
"""
|
24
|
+
# copying array
|
25
|
+
data_c = np.copy(data)
|
26
|
+
|
27
|
+
# placeholder for the peak mapping
|
28
|
+
peak_map = np.full_like(data_c, False, dtype=bool)
|
29
|
+
|
30
|
+
for _ in range(100500): # shouldn't take more iterations
|
31
|
+
|
32
|
+
# looking for peaks
|
33
|
+
peaks_found = np.logical_or(
|
34
|
+
data_c > np.mean(data_c) + np.std(data_c) * 3,
|
35
|
+
data_c < np.mean(data_c) - np.std(data_c) * 3,
|
36
|
+
)
|
37
|
+
|
38
|
+
# merging with peak mapping
|
39
|
+
np.logical_or(peak_map, peaks_found, out=peak_map)
|
40
|
+
|
41
|
+
# if no peaks found - break
|
42
|
+
if not peaks_found.any():
|
43
|
+
break
|
44
|
+
|
45
|
+
# setting values to 0 and iterating again
|
46
|
+
data_c[peaks_found] = 0
|
47
|
+
|
48
|
+
return peak_map
|
49
|
+
|
50
|
+
|
51
|
+
def combine_map_to_regions(mapping):
|
52
|
+
"""Combine True values into their indexes arrays.
|
53
|
+
|
54
|
+
Args:
|
55
|
+
mapping (:obj:np.array): Boolean mapping array to extract the indexes
|
56
|
+
from.
|
57
|
+
|
58
|
+
Returns:
|
59
|
+
:obj:np.array: 2D array with left and right borders of regions, where
|
60
|
+
mapping is True.
|
61
|
+
|
62
|
+
Example:
|
63
|
+
>>> combine_map_to_regions(np.array([True, True, False, True, False]))
|
64
|
+
array([[0, 1],
|
65
|
+
[3, 3]])
|
66
|
+
"""
|
67
|
+
|
68
|
+
# No peaks identified, i.e. mapping is all False
|
69
|
+
if not mapping.any():
|
70
|
+
return np.array([], dtype="int64")
|
71
|
+
|
72
|
+
# region borders
|
73
|
+
region_borders = np.diff(mapping)
|
74
|
+
|
75
|
+
# corresponding indexes
|
76
|
+
border_indexes = np.argwhere(region_borders)
|
77
|
+
|
78
|
+
lefts = border_indexes[::2] + 1 # because diff was used to get the index
|
79
|
+
|
80
|
+
# edge case, where first peak doesn't have left border
|
81
|
+
if mapping[border_indexes][0]:
|
82
|
+
# just preppend 0 as first left border
|
83
|
+
# mind the vstack, as np.argwhere produces a vector array
|
84
|
+
lefts = np.vstack((0, lefts))
|
85
|
+
|
86
|
+
rights = border_indexes[1::2]
|
87
|
+
|
88
|
+
# another edge case, where last peak doesn't have a right border
|
89
|
+
if mapping[-1]: # True if last point identified as potential peak
|
90
|
+
# just append -1 as last peak right border
|
91
|
+
rights = np.vstack((rights, -1))
|
92
|
+
|
93
|
+
# columns as borders, rows as regions, i.e.
|
94
|
+
# :output:[0] -> first peak region
|
95
|
+
return np.hstack((lefts, rights))
|
96
|
+
|
97
|
+
|
98
|
+
def filter_regions(x_data, peaks_regions):
|
99
|
+
"""Filter peak regions.
|
100
|
+
|
101
|
+
Peak regions are filtered to remove potential false positives (e.g. noise
|
102
|
+
spikes).
|
103
|
+
|
104
|
+
Args:
|
105
|
+
x_data (:obj:np.array): X data points, needed to pick up the data
|
106
|
+
resolution and map the region indexes to the corresponding data
|
107
|
+
points.
|
108
|
+
y_data (:obj:np.array): Y data points, needed to validate if the peaks
|
109
|
+
are actually present in the region and remove invalid regions.
|
110
|
+
peaks_regions (:obj:np.array): 2D Nx2 array with peak regions indexes
|
111
|
+
(rows) as left and right borders (columns).
|
112
|
+
|
113
|
+
Returns:
|
114
|
+
:obj:np.array: 2D Mx2 array with filtered peak regions indexes(rows) as
|
115
|
+
left and right borders (columns).
|
116
|
+
"""
|
117
|
+
|
118
|
+
# filter peaks where region is smaller than spectrum resolution
|
119
|
+
# like single spikes, e.g. noise
|
120
|
+
# compute the regions first
|
121
|
+
x_data_regions = np.copy(x_data[peaks_regions])
|
122
|
+
|
123
|
+
# get arguments where absolute difference is greater than data resolution
|
124
|
+
resolution = np.absolute(np.mean(np.diff(x_data)))
|
125
|
+
|
126
|
+
# (N, 1) array!
|
127
|
+
valid_regions_map = np.absolute(np.diff(x_data_regions)) > resolution
|
128
|
+
|
129
|
+
# get their indexes, mind the flattening of all arrays!
|
130
|
+
valid_regions_indexes = np.argwhere(valid_regions_map.flatten()).flatten()
|
131
|
+
|
132
|
+
# filtering!
|
133
|
+
peaks_regions = peaks_regions[valid_regions_indexes]
|
134
|
+
|
135
|
+
return peaks_regions
|
136
|
+
|
137
|
+
|
138
|
+
def filter_noisy_regions(y_data, peaks_regions):
|
139
|
+
"""Remove noisy regions from given regions array.
|
140
|
+
|
141
|
+
Peak regions are filtered to remove false positive noise regions, e.g.
|
142
|
+
incorrectly assigned due to curvy baseline. Filtering is performed by
|
143
|
+
computing average peak points/data points ratio.
|
144
|
+
|
145
|
+
Args:
|
146
|
+
y_data (:obj:np.array): Y data points, needed to validate if the peaks
|
147
|
+
are actually present in the region and remove invalid regions.
|
148
|
+
peaks_regions (:obj:np.array): 2D Nx2 array with peak regions indexes
|
149
|
+
(rows) as left and right borders (columns).
|
150
|
+
|
151
|
+
Returns:
|
152
|
+
:obj:np.array: 2D Mx2 array with filtered peak regions indexes(rows) as
|
153
|
+
left and right borders (columns).
|
154
|
+
"""
|
155
|
+
|
156
|
+
# compute the actual regions data points
|
157
|
+
y_data_regions = []
|
158
|
+
for region in peaks_regions:
|
159
|
+
y_data_regions.append(y_data[region[0] : region[-1]])
|
160
|
+
|
161
|
+
# compute noise data regions, i.e. in between peak regions
|
162
|
+
noise_data_regions = []
|
163
|
+
for row, _ in enumerate(peaks_regions):
|
164
|
+
try:
|
165
|
+
noise_data_regions.append(
|
166
|
+
y_data[peaks_regions[row][1] : peaks_regions[row + 1][0]]
|
167
|
+
)
|
168
|
+
except IndexError:
|
169
|
+
# exception for the last row -> discard
|
170
|
+
pass
|
171
|
+
|
172
|
+
# compute average peaks/data points ratio for noisy regions
|
173
|
+
noise_peaks_ratio = []
|
174
|
+
for region in noise_data_regions:
|
175
|
+
# protection from empty regions
|
176
|
+
if region.size != 0:
|
177
|
+
# minimum height is pretty low to ensure enough noise is picked
|
178
|
+
peaks, _ = scipy.signal.find_peaks(region, height=region.max() * 0.2)
|
179
|
+
noise_peaks_ratio.append(peaks.size / region.size)
|
180
|
+
|
181
|
+
# compute average with weights equal to the region length
|
182
|
+
noise_peaks_ratio = np.average(
|
183
|
+
noise_peaks_ratio, weights=[region.size for region in noise_data_regions]
|
184
|
+
)
|
185
|
+
|
186
|
+
# filtering!
|
187
|
+
valid_regions_indexes = []
|
188
|
+
for row, region in enumerate(y_data_regions):
|
189
|
+
peaks, _ = scipy.signal.find_peaks(region, height=region.max() * 0.2)
|
190
|
+
if peaks.size != 0 and peaks.size / region.size < noise_peaks_ratio:
|
191
|
+
valid_regions_indexes.append(row)
|
192
|
+
|
193
|
+
# protecting from complete cleaning
|
194
|
+
if not valid_regions_indexes:
|
195
|
+
return peaks_regions
|
196
|
+
|
197
|
+
peaks_regions = peaks_regions[np.array(valid_regions_indexes)]
|
198
|
+
|
199
|
+
return peaks_regions
|
200
|
+
|
201
|
+
|
202
|
+
def merge_regions(x_data, peaks_regions, d_merge, recursively=True):
|
203
|
+
"""Merge peak regions if distance between is less than delta.
|
204
|
+
|
205
|
+
Args:
|
206
|
+
x_data (:obj:np.array): X data points.
|
207
|
+
peaks_regions (:obj:np.array): 2D Nx2 array with peak regions indexes
|
208
|
+
(rows) as left and right borders (columns).
|
209
|
+
d_merge (float): Minimum distance in X data points to merge two or more
|
210
|
+
regions together.
|
211
|
+
recursively (bool, optional): If True - will repeat the procedure until
|
212
|
+
all regions with distance < than d_merge will merge.
|
213
|
+
|
214
|
+
Returns:
|
215
|
+
:obj:np.array: 2D Mx2 array with peak regions indexes (rows) as left and
|
216
|
+
right borders (columns), merged according to predefined minimal
|
217
|
+
distance.
|
218
|
+
|
219
|
+
Example:
|
220
|
+
>>> regions = np.array([
|
221
|
+
[1, 10],
|
222
|
+
[11, 20],
|
223
|
+
[25, 45],
|
224
|
+
[50, 75],
|
225
|
+
[100, 120],
|
226
|
+
[122, 134]
|
227
|
+
])
|
228
|
+
>>> data = np.ones_like(regions) # ones as example
|
229
|
+
>>> merge_regions(data, regions, 1)
|
230
|
+
array([[ 1, 20],
|
231
|
+
[ 25, 45],
|
232
|
+
[ 50, 75],
|
233
|
+
[100, 120],
|
234
|
+
[122, 134]])
|
235
|
+
>>> merge_regions(data, regions, 20, True)
|
236
|
+
array([[ 1, 75],
|
237
|
+
[100, 134]])
|
238
|
+
"""
|
239
|
+
# the code is pretty ugly but works
|
240
|
+
merged_regions = []
|
241
|
+
|
242
|
+
# converting to list to drop the data of the fly
|
243
|
+
regions = peaks_regions.tolist()
|
244
|
+
|
245
|
+
for i, _ in enumerate(regions):
|
246
|
+
try:
|
247
|
+
# check left border of i regions with right of i+1
|
248
|
+
if abs(x_data[regions[i][-1]] - x_data[regions[i + 1][0]]) <= d_merge:
|
249
|
+
# if lower append merge the regions
|
250
|
+
merged_regions.append([regions[i][0], regions[i + 1][-1]])
|
251
|
+
# drop the merged one
|
252
|
+
regions.pop(i + 1)
|
253
|
+
else:
|
254
|
+
# if nothing to merge, just append the current region
|
255
|
+
merged_regions.append(regions[i])
|
256
|
+
except IndexError:
|
257
|
+
# last row
|
258
|
+
merged_regions.append(regions[i])
|
259
|
+
|
260
|
+
merged_regions = np.array(merged_regions)
|
261
|
+
|
262
|
+
if not recursively:
|
263
|
+
return merged_regions
|
264
|
+
|
265
|
+
# if recursively, check for the difference
|
266
|
+
if (merged_regions == regions).all():
|
267
|
+
# done
|
268
|
+
return merged_regions
|
269
|
+
|
270
|
+
return merge_regions(x_data, merged_regions, d_merge, recursively=True)
|
271
|
+
|
272
|
+
|
273
|
+
def expand_regions(x_data, peaks_regions, d_expand):
|
274
|
+
"""Expand the peak regions by the desired value.
|
275
|
+
|
276
|
+
Args:
|
277
|
+
x_data (:obj:np.array): X data points.
|
278
|
+
peaks_regions (:obj:np.array): 2D Nx2 array with peak regions indexes
|
279
|
+
(rows) as left and right borders (columns).
|
280
|
+
d_expand (float): Value to expand borders to (in X data scale).
|
281
|
+
|
282
|
+
Returns:
|
283
|
+
:obj:np.array: 2D Nx2 array with expanded peak regions indexes (rows) as
|
284
|
+
left and right borders (columns).
|
285
|
+
"""
|
286
|
+
|
287
|
+
data_regions = np.copy(x_data[peaks_regions])
|
288
|
+
|
289
|
+
# determine scale orientation, i.e. decreasing (e.g. ppm on NMR spectrum)
|
290
|
+
# or increasing (e.g. wavelength on UV spectrum)
|
291
|
+
if (data_regions[:, 0] - data_regions[:, 1]).mean() > 0:
|
292
|
+
# ppm-like scale
|
293
|
+
data_regions[:, 0] += d_expand
|
294
|
+
data_regions[:, -1] -= d_expand
|
295
|
+
else:
|
296
|
+
# wavelength-like scale
|
297
|
+
data_regions[:, 0] -= d_expand
|
298
|
+
data_regions[:, -1] += d_expand
|
299
|
+
|
300
|
+
# converting new values to new indexes
|
301
|
+
for index_, value in np.ndenumerate(data_regions):
|
302
|
+
data_regions[index_] = find_nearest_value_index(x_data, value)[1]
|
303
|
+
|
304
|
+
return data_regions.astype(int)
|
@@ -0,0 +1,63 @@
|
|
1
|
+
import numpy as np
|
2
|
+
|
3
|
+
|
4
|
+
def find_nearest_value_index(array, value) -> tuple[float, int]:
|
5
|
+
"""Returns closest value and its index in a given array.
|
6
|
+
|
7
|
+
:param array: An array to search in.
|
8
|
+
:type array: np.array(float)
|
9
|
+
:param value: Target value.
|
10
|
+
:type value: float
|
11
|
+
|
12
|
+
:returns: Nearest value in array and its index.
|
13
|
+
"""
|
14
|
+
|
15
|
+
index_ = np.argmin(np.abs(array - value))
|
16
|
+
return array[index_], index_
|
17
|
+
|
18
|
+
|
19
|
+
def interpolate_to_index(array, ids, precision: int = 100) -> np.array:
|
20
|
+
"""Find value in between arrays elements.
|
21
|
+
|
22
|
+
Constructs linspace of size "precision" between index+1 and index to
|
23
|
+
find approximate value for array[index], where index is float number.
|
24
|
+
Used for 2D data, where default scipy analysis occurs along one axis only,
|
25
|
+
e.g. signal.peak_width.
|
26
|
+
|
27
|
+
Rough equivalent of array[index], where index is float number.
|
28
|
+
|
29
|
+
:param array: Target array.
|
30
|
+
:type array: np.array(float)
|
31
|
+
:param ids: An array with "intermediate" indexes to interpolate to.
|
32
|
+
:type ids: np.array[float]
|
33
|
+
:param precision: Desired presion.
|
34
|
+
|
35
|
+
:returns: New array with interpolated values according to provided indexes "ids".
|
36
|
+
|
37
|
+
Example:
|
38
|
+
>>> interpolate_to_index(np.array([1.5]), np.array([1,2,3], 100))
|
39
|
+
array([2.50505051])
|
40
|
+
"""
|
41
|
+
|
42
|
+
# breaking ids into fractional and integral parts
|
43
|
+
prec, ids = np.modf(ids)
|
44
|
+
|
45
|
+
# rounding and switching type to int
|
46
|
+
prec = np.around(prec * precision).astype("int32")
|
47
|
+
ids = ids.astype("int32")
|
48
|
+
|
49
|
+
# linear interpolation for each data point
|
50
|
+
# as (n x m) matrix where n is precision and m is number of indexes
|
51
|
+
space = np.linspace(array[ids], array[ids + 1], precision)
|
52
|
+
|
53
|
+
# due to rounding error the index may become 100 in (100, ) array
|
54
|
+
# as a consequence raising IndexError when such array is indexed
|
55
|
+
# therefore index 100 will become the last (-1)
|
56
|
+
prec[prec == 100] = -1
|
57
|
+
|
58
|
+
# precise slicing
|
59
|
+
true_values = np.array(
|
60
|
+
[space[:, index[0]][value] for index, value in np.ndenumerate(prec)]
|
61
|
+
)
|
62
|
+
|
63
|
+
return true_values
|