diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index fa5ac62..0dbdeaf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ on: push: branches: [ main ] pull_request: - branches: [ main ] + branches: [ main, development ] jobs: test: @@ -51,7 +51,7 @@ jobs: - name: Set up Python uses: actions/setup-python@v5 with: - python-version: '3.9' + python-version: '3.12' - name: Install Rust uses: dtolnay/rust-toolchain@stable @@ -63,6 +63,13 @@ jobs: pip install maturin pytest numpy pip install fisher-py + - name: Decompress test data + run: gunzip -d -k test_data/*.gz + - name: Download test data + run: | + wget -q -P test_data ftp://ftp.pride.ebi.ac.uk/pride/data/archive/2026/02/PXD066718/20250411_Ast0_500SPD_EVO685_JVO_EV1107_050ng_HEK-CPR_380-980_2Th_1P5ms_OFF_05_20250413081131.raw + wget -q -P test_data https://ftp.pride.ebi.ac.uk/pride/data/archive/2026/02/PXD066944/20250307_AST0_NEO5_JVO_MV50_DR_100SPD_10ng_HEK_Ref_DDA_2Th_1p5ms_10ms_v2Ref_cycle_03.raw + - name: Build and test run: | source .venv/bin/activate diff --git a/.gitignore b/.gitignore index 3abe4f5..5d669e5 100644 --- a/.gitignore +++ b/.gitignore @@ -54,6 +54,9 @@ coverage.xml venv/ pip-log.txt pip-delete-this-directory.txt +Pipfile +Pipfile.lock +.python-version # Rust target/ @@ -66,4 +69,10 @@ publish_output*.txt *output*txt *.dylib* _build/ -/tmp/ \ No newline at end of file +/tmp/ +venv3.11/pyvenv.cfg +/scratch +test_data/MS2_MS1_zoom.raw +test_data/MS2_MS1_astral.raw +test_data/20250411_Ast0_500SPD_EVO685_JVO_EV1107_050ng_HEK-CPR_380-980_2Th_1P5ms_OFF_05_20250413081131.raw +test_data/20250307_AST0_NEO5_JVO_MV50_DR_100SPD_10ng_HEK_Ref_DDA_2Th_1p5ms_10ms_v2Ref_cycle_03.raw diff --git a/native/ThermoNativeReader/NativeApi.cs b/native/ThermoNativeReader/NativeApi.cs index 301dd1f..842d65c 100644 --- a/native/ThermoNativeReader/NativeApi.cs +++ b/native/ThermoNativeReader/NativeApi.cs @@ -1,719 +1,524 @@ using System; +using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; -using System.Runtime.InteropServices; using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading; using ThermoFisher.CommonCore.RawFileReader; using ThermoFisher.CommonCore.Data; using ThermoFisher.CommonCore.Data.Business; using ThermoFisher.CommonCore.Data.Interfaces; using ThermoFisher.CommonCore.Data.FilterEnums; using Range = ThermoFisher.CommonCore.Data.Business.Range; -using System.Diagnostics.CodeAnalysis; + namespace ThermoNativeReader { public static class NativeApi { - private static IRawDataPlus? _rawFile; + [StructLayout(LayoutKind.Sequential)] + public unsafe struct CentroidParams + { + public double* Masses; + public double* Intensities; + public double* Baselines; + public double* Noises; + public int* Charges; + public double* NoiseRes; + public int MaxLength; + } - private static string SafeGetFilterString(IScanFilter filter) + [StructLayout(LayoutKind.Sequential)] + public unsafe struct ChromatogramParams { - if (filter == null) return ""; - try - { - return filter.ToString(); - } - catch (Exception ex) - { - Console.WriteLine($"Warning: Filter.ToString() failed: {ex.Message}"); - return "FILTER_ERROR"; - } + public int TraceType; + public byte* Filter; + public double* MassRangesStart; + public double* MassRangesEnd; + public int MassRangeCount; + public int StartScan; + public int EndScan; + public double* Times; + public double* Intensities; + public int MaxLength; } - // Dummy usage to prevent AOT trimming of important types used by reflection in Thermo DLLs - private static ThermoFisher.CommonCore.Data.Interfaces.MetaFilterType[] _dummyArray = new ThermoFisher.CommonCore.Data.Interfaces.MetaFilterType[0]; - private static ThermoFisher.CommonCore.Data.Interfaces.IScanFilter? _dummyFilter = null; + private static readonly Dictionary _openFiles = new Dictionary(); + private static long _nextHandle = 1; + private static readonly BlockingCollection _workQueue = new BlockingCollection(); - static NativeApi() { - // Force compiler to keep these types - _dummyFilter = (ThermoFisher.CommonCore.Data.Interfaces.IScanFilter?)null; - var t = typeof(ThermoFisher.CommonCore.Data.Interfaces.MetaFilterType); + static NativeApi() + { + var workerThread = new Thread(WorkerLoop, 8 * 1024 * 1024) { IsBackground = true, Name = "ThermoWorker" }; + try { workerThread.SetApartmentState(ApartmentState.STA); } catch { } + workerThread.Start(); } - [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ThermoFisher.CommonCore.Data.Interfaces.MetaFilterType))] - [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ThermoFisher.CommonCore.Data.Interfaces.IScanFilter))] - [UnmanagedCallersOnly(EntryPoint = "open_raw_file")] - public static unsafe int OpenRawFile(byte* pathPtr) + private static void WorkerLoop() { - try + foreach (var action in _workQueue.GetConsumingEnumerable()) { - if (pathPtr == null) return -1; - string? path = Marshal.PtrToStringAnsi((IntPtr)pathPtr); - if (string.IsNullOrEmpty(path)) return -1; - - _rawFile = (IRawDataPlus)RawFileReaderAdapter.FileFactory(path); - if (_rawFile == null) return -1; - _rawFile.SelectInstrument(Device.MS, 1); - return 0; - } - catch - { - return -1; + try { action(); } catch { } } } - [UnmanagedCallersOnly(EntryPoint = "get_num_scans")] - public static int GetNumScans() + private static T RunOnWorker(Func func) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1; - return _rawFile.RunHeader.LastSpectrum; + T result = default; + using var done = new ManualResetEvent(false); + _workQueue.Add(() => { + try { result = func(); } + finally { done.Set(); } + }); + done.WaitOne(); + return result; } - [UnmanagedCallersOnly(EntryPoint = "get_scan_rt")] - public static double GetScanRT(int scanNumber) + private static void RunOnWorkerSync(Action action) { - if (_rawFile == null) return -1.0; - return _rawFile.RetentionTimeFromScanNumber(scanNumber); + using var done = new ManualResetEvent(false); + _workQueue.Add(() => { + try { action(); } + finally { done.Set(); } + }); + done.WaitOne(); } - [UnmanagedCallersOnly(EntryPoint = "is_centroid")] - public static int IsCentroid(int scanNumber) + private static unsafe int CopyString(string s, byte* buffer, int length) { - if (_rawFile == null) return 0; - try - { - var scanStatistics = _rawFile.GetScanStatsForScanNumber(scanNumber); - return scanStatistics.IsCentroidScan ? 1 : 0; - } - catch - { - return 0; - } + if (buffer == null || length <= 0) return 0; + var bytes = System.Text.Encoding.UTF8.GetBytes(s ?? ""); + int count = Math.Min(bytes.Length, length - 1); + for (int i = 0; i < count; i++) buffer[i] = bytes[i]; + buffer[count] = 0; + return count; } - [UnmanagedCallersOnly(EntryPoint = "get_spectrum")] - public static unsafe int GetSpectrum(int scanNumber, double* masses, double* intensities, int maxLength) - { - if (_rawFile == null) return -1; - - try - { - var scanStatistics = _rawFile.GetScanStatsForScanNumber(scanNumber); - var scan = _rawFile.GetSegmentedScanFromScanNumber(scanNumber, scanStatistics); - if (scan == null) { return -2; } - if (scan.Positions == null) { return -3; } - if (scan.Intensities == null) { return -4; } - if (scan.Positions.Length == 0) { return -5; } - - int count = Math.Min(scan.Positions.Length, maxLength); - for (int i = 0; i < count; i++) - { - masses[i] = scan.Positions[i]; - intensities[i] = scan.Intensities[i]; + [UnmanagedCallersOnly(EntryPoint = "open_raw_file")] + public static unsafe long OpenRawFile(byte* pathPtr) + { + if (pathPtr == null) return -1; + string path = Marshal.PtrToStringAnsi((IntPtr)pathPtr) ?? ""; + if (string.IsNullOrEmpty(path)) return -1; + + return RunOnWorker(() => { + try { + string fullPath = Path.GetFullPath(path); + var rawFile = (IRawDataPlus)RawFileReaderAdapter.FileFactory(fullPath); + if (rawFile == null) return -1; + + try { + rawFile.SelectInstrument(Device.MS, 1); + } catch {} + + long h = Interlocked.Increment(ref _nextHandle); + _openFiles[h] = rawFile; + return h; + } catch { + return -1; } - return count; - } - catch (Exception ex) - { - return -1; - } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_centroid_stream")] - public static unsafe int GetCentroidStream(int scanNumber, double* masses, double* intensities, int maxLength) + [UnmanagedCallersOnly(EntryPoint = "close_raw_file")] + public static void CloseRawFile(long handle) { - if (_rawFile == null) return -1; - - try - { - var scan = _rawFile.GetCentroidStream(scanNumber, false); - if (scan == null) { return -2; } - if (scan.Masses == null || scan.Intensities == null) { return -3; } - - int count = Math.Min(scan.Length, maxLength); - for (int i = 0; i < count; i++) - { - masses[i] = scan.Masses[i]; - intensities[i] = scan.Intensities[i]; - } - return count; - } - catch (Exception) - { - return -1; - } + RunOnWorkerSync(() => { + _openFiles.Remove(handle); + }); } - [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ThermoFisher.CommonCore.Data.Interfaces.MetaFilterType))] - [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ThermoFisher.CommonCore.Data.Interfaces.IScanFilter))] - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_meta_filters")] - public static unsafe int GetScanFilterMetaFilters(int scanNumber, IntPtr* filters, int maxCount) + [UnmanagedCallersOnly(EntryPoint = "select_instrument")] + public static unsafe void SelectInstrument(long arg0, int arg1, int arg2) { - if (_rawFile == null) return -1; - try - { - var filter = _rawFile.GetFilterForScanNumber(scanNumber); - if (filter == null) return 0; - var prop = filter.GetType().GetProperty("MetaFilters"); - if (prop == null) return 0; - var metaFiltersObj = prop.GetValue(filter) as System.Collections.IEnumerable; - if (metaFiltersObj == null) return 0; - - var metaList = new List(); - foreach (var mf in metaFiltersObj) - { - if (mf != null) metaList.Add(mf.ToString() ?? ""); + RunOnWorkerSync(() => { + if (_openFiles.TryGetValue(arg0, out var f)) { + f.SelectInstrument((Device)arg1, arg2); } - int count = Math.Min(metaList.Count, maxCount); - for (int i = 0; i < count; i++) - { - filters[i] = Marshal.StringToHGlobalAnsi(metaList[i]); + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_num_scans")] + public static unsafe int GetNumScans(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { + int count = f.RunHeaderEx.SpectraCount; + if (count <= 0) count = f.RunHeader.LastSpectrum - f.RunHeader.FirstSpectrum + 1; + return count; + } catch { + try { return f.RunHeader.LastSpectrum - f.RunHeader.FirstSpectrum + 1; } catch { return 0; } } - return metaList.Count; - } - catch { return -1; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_filters")] - public static unsafe int GetFilters(IntPtr* filters, int maxCount) + [UnmanagedCallersOnly(EntryPoint = "get_tune_data_count")] + public static unsafe int GetTuneDataCount(long arg0) { - if (_rawFile == null) return -1; - try - { - var filterList = _rawFile.GetFilters().ToArray(); - int count = Math.Min(filterList.Length, maxCount); - for (int i = 0; i < count; i++) - { - filters[i] = Marshal.StringToHGlobalAnsi(SafeGetFilterString(filterList[i])); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.GetTuneDataCount(); } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_rt")] + public static unsafe double GetScanRt(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return f.RetentionTimeFromScanNumber((int)arg1); } catch { return -1.0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_spectrum")] + public static unsafe int GetSpectrum(long arg0, int arg1, double* arg2, double* arg3, int arg4) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { + var stats = f.GetScanStatsForScanNumber(arg1); + if (stats == null) return 0; + var scan = f.GetSegmentedScanFromScanNumber(arg1, stats); + if (scan == null || scan.Positions == null || scan.Intensities == null) return 0; + + int count = Math.Min(scan.Positions.Length, arg4); + Marshal.Copy(scan.Positions, 0, (IntPtr)arg2, count); + Marshal.Copy(scan.Intensities, 0, (IntPtr)arg3, count); + return count; + } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "is_centroid")] + public static unsafe int IsCentroid(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { + var scanStatistics = f.GetScanStatsForScanNumber(arg1); + if (scanStatistics == null) return 0; + return scanStatistics.IsCentroidScan ? 1 : 0; + } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_centroid_stream_full")] + public static unsafe int GetCentroidStreamFull(long arg0, int arg1, CentroidParams* p) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { + var stream = f.GetCentroidStream(arg1, false); + if (stream == null) return 0; + + int count = Math.Min(stream.Length, p->MaxLength); + if (p->Masses != null && stream.Masses != null) Marshal.Copy(stream.Masses, 0, (IntPtr)p->Masses, count); + if (p->Intensities != null && stream.Intensities != null) Marshal.Copy(stream.Intensities, 0, (IntPtr)p->Intensities, count); + + if (p->NoiseRes != null) { + p->NoiseRes[0] = stream.BasePeakNoise; + p->NoiseRes[1] = stream.BasePeakResolution; + } + return count; + } catch { + return 0; } - return filterList.Length; - } - catch (Exception ex) - { - Console.WriteLine($"Error in get_filters: {ex}"); - return -1; - } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_sample_type")] + public static unsafe int GetSampleType(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.SampleInformation.SampleType; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_sample_row_number")] + public static unsafe int GetSampleRowNumber(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.SampleInformation.RowNumber; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_sample_dilution_factor")] + public static unsafe double GetSampleDilutionFactor(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return f.SampleInformation.DilutionFactor; } catch { return -1.0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_first_scan")] - public static int GetFirstScan() + public static unsafe int GetFirstScan(long arg0) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1; - return _rawFile.RunHeader.FirstSpectrum; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.RunHeader.FirstSpectrum; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_last_scan")] - public static int GetLastScan() + public static unsafe int GetLastScan(long arg0) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1; - return _rawFile.RunHeader.LastSpectrum; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.RunHeader.LastSpectrum; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_end_time")] - public static double GetEndTime() + public static unsafe double GetEndTime(long arg0) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1.0; - return _rawFile.RunHeader.EndTime; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { if (f.RunHeader == null) return -1.0; return f.RunHeader.EndTime; } catch { return -1.0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_start_time")] - public static double GetStartTime() + public static unsafe double GetStartTime(long arg0) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1.0; - return _rawFile.RunHeader.StartTime; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { if (f.RunHeader == null) return -1.0; return f.RunHeader.StartTime; } catch { return -1.0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_mass_resolution")] - public static double GetMassResolution() + public static unsafe double GetMassResolution(long arg0) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1.0; - return _rawFile.RunHeader.MassResolution; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { if (f.RunHeader == null) return -1.0; return f.RunHeader.MassResolution; } catch { return -1.0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_expected_runtime")] - public static double GetExpectedRuntime() + public static unsafe double GetExpectedRuntime(long arg0) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1.0; - return _rawFile.RunHeader.ExpectedRuntime; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { if (f.RunHeader == null) return -1.0; return f.RunHeader.ExpectedRuntime; } catch { return -1.0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_max_integrated_intensity")] - public static double GetMaxIntegratedIntensity() + public static unsafe double GetMaxIntegratedIntensity(long arg0) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1.0; - return _rawFile.RunHeader.MaxIntegratedIntensity; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { if (f.RunHeader == null) return -1.0; return f.RunHeader.MaxIntegratedIntensity; } catch { return -1.0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_max_intensity")] - public static int GetMaxIntensity() + public static unsafe int GetMaxIntensity(long arg0) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1; - return _rawFile.RunHeader.MaxIntensity; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { if (f.RunHeader == null) return -1; return f.RunHeader.MaxIntensity; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_low_mass")] - public static double GetLowMass() + public static unsafe double GetLowMass(long arg0) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1.0; - return _rawFile.RunHeader.LowMass; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { if (f.RunHeader == null) return -1.0; return f.RunHeader.LowMass; } catch { return -1.0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_high_mass")] - public static double GetHighMass() + public static unsafe double GetHighMass(long arg0) { - if (_rawFile == null || _rawFile.RunHeader == null) return -1.0; - return _rawFile.RunHeader.HighMass; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { if (f.RunHeader == null) return -1.0; return f.RunHeader.HighMass; } catch { return -1.0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_file_name")] - public static unsafe int GetFileName(byte* buffer, int length) + public static unsafe int GetFileName(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - var str = _rawFile.FileName ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return CopyString(f.FileName, arg1, arg2); } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_path")] - public static unsafe int GetPath(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.Path ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_tune_data_count")] - public static int GetTuneDataCount() + public static unsafe int GetPath(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - return _rawFile.GetTuneDataCount(); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.Path ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_creation_date")] - public static unsafe int GetCreationDate(byte* buffer, int length) + public static unsafe int GetCreationDate(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - var str = _rawFile.CreationDate.ToString("o"); - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.CreationDate.ToString("o"); var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_computer_name")] - public static unsafe int GetComputerName(byte* buffer, int length) + public static unsafe int GetComputerName(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - var str = _rawFile.ComputerName ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.ComputerName ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_creator_id")] - public static unsafe int GetCreatorID(byte* buffer, int length) + public static unsafe int GetCreatorId(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - var str = _rawFile.CreatorId ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.CreatorId ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_instrument_model")] - public static unsafe int GetInstrumentModel(byte* buffer, int length) + public static unsafe int GetInstrumentModel(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - var str = data?.Model ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); var str = data?.Model ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_instrument_name")] - public static unsafe int GetInstrumentName(byte* buffer, int length) + public static unsafe int GetInstrumentName(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - var str = data?.Name ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); var str = data?.Name ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_instrument_serial_number")] - public static unsafe int GetInstrumentSerialNumber(byte* buffer, int length) + public static unsafe int GetInstrumentSerialNumber(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - var str = data?.SerialNumber ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); var str = data?.SerialNumber ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_instrument_software_version")] - public static unsafe int GetInstrumentSoftwareVersion(byte* buffer, int length) + public static unsafe int GetInstrumentSoftwareVersion(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - var str = data?.SoftwareVersion ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); var str = data?.SoftwareVersion ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_instrument_hardware_version")] - public static unsafe int GetInstrumentHardwareVersion(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - var str = data?.HardwareVersion ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_instrument_axis_label_x")] - public static unsafe int GetInstrumentAxisLabelX(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - var str = data?.AxisLabelX ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_instrument_axis_label_y")] - public static unsafe int GetInstrumentAxisLabelY(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - var str = data?.AxisLabelY ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_instrument_flags")] - public static unsafe int GetInstrumentFlags(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - var str = data?.Flags ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_instrument_units")] - public static int GetInstrumentUnits() - { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - return data != null ? (int)data.Units : 0; - } - - [UnmanagedCallersOnly(EntryPoint = "get_instrument_is_valid")] - public static int GetInstrumentIsValid() - { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - return data != null && data.IsValid ? 1 : 0; - } - - [UnmanagedCallersOnly(EntryPoint = "get_instrument_has_accurate_mass_precursors")] - public static int GetInstrumentHasAccurateMassPrecursors() + public static unsafe int GetInstrumentHardwareVersion(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - return data != null && data.HasAccurateMassPrecursors ? 1 : 0; - } - - [UnmanagedCallersOnly(EntryPoint = "get_instrument_is_tsq_quantum_file")] - public static int GetInstrumentIsTsqQuantumFile() - { - if (_rawFile == null) return -1; - var data = _rawFile.GetInstrumentData(); - return data != null && data.IsTsqQuantumFile() ? 1 : 0; - } - - [UnmanagedCallersOnly(EntryPoint = "get_file_description")] - public static unsafe int GetFileDescription(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.FileHeader.FileDescription ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_modified_date")] - public static unsafe int GetModifiedDate(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.FileHeader.ModifiedDate.ToString() ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_who_created_logon")] - public static unsafe int GetWhoCreatedLogon(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.FileHeader.WhoCreatedLogon ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_who_modified_id")] - public static unsafe int GetWhoModifiedId(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.FileHeader.WhoModifiedId ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_who_modified_logon")] - public static unsafe int GetWhoModifiedLogon(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.FileHeader.WhoModifiedLogon ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_sample_barcode")] - public static unsafe int GetSampleBarcode(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.SampleInformation.Barcode ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_sample_id")] - public static unsafe int GetSampleId(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.SampleInformation.SampleId ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_sample_name")] - public static unsafe int GetSampleName(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.SampleInformation.SampleName ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_sample_vial")] - public static unsafe int GetSampleVial(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.SampleInformation.Vial ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_sample_comment")] - public static unsafe int GetSampleComment(byte* buffer, int length) - { - if (_rawFile == null) return -1; - var str = _rawFile.SampleInformation.Comment ?? ""; - var bytes = System.Text.Encoding.UTF8.GetBytes(str); - int count = Math.Min(bytes.Length, length - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return count; - } - - [UnmanagedCallersOnly(EntryPoint = "get_sample_type")] - public static int GetSampleType() - { - if (_rawFile == null) return 0; - return (int)_rawFile.SampleInformation.SampleType; - } - - [UnmanagedCallersOnly(EntryPoint = "get_sample_row_number")] - public static int GetSampleRowNumber() - { - if (_rawFile == null) return 0; - return _rawFile.SampleInformation.RowNumber; - } - - [UnmanagedCallersOnly(EntryPoint = "get_sample_dilution_factor")] - public static double GetSampleDilutionFactor() - { - if (_rawFile == null) return 1.0; - return _rawFile.SampleInformation.DilutionFactor; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); var str = data?.HardwareVersion ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_ms_order")] - public static int GetMsOrder(int scanNumber) + public static unsafe int GetMsOrder(long arg0, int arg1) { - if (_rawFile == null) return -1; - try - { - var scanEvent = _rawFile.GetScanEventForScanNumber(scanNumber); - return (int)scanEvent.MSOrder; - } - catch - { - return -1; - } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var scanEvent = f.GetScanEventForScanNumber(arg1); + return (int)scanEvent.MSOrder; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_mass_analyzer")] - public static int GetMassAnalyzer(int scanNumber) + public static unsafe int GetMassAnalyzer(long arg0, int arg1) { - if (_rawFile == null) return -1; - try - { - var scanEvent = _rawFile.GetScanEventForScanNumber(scanNumber); - return (int)scanEvent.MassAnalyzer; - } - catch - { - return -1; - } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var scanEvent = f.GetScanEventForScanNumber(arg1); + return (int)scanEvent.MassAnalyzer; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_precursor_mass")] - public static double GetPrecursorMass(int scanNumber) + public static unsafe double GetPrecursorMass(long arg0, int arg1) { - if (_rawFile == null) return -1.0; - try - { - var scanEvent = _rawFile.GetScanEventForScanNumber(scanNumber); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { var scanEvent = f.GetScanEventForScanNumber(arg1); if (scanEvent.MSOrder == MSOrderType.Ms) return 0.0; - return scanEvent.GetReaction(0).PrecursorMass; - } - catch - { - return -1.0; - } + return scanEvent.GetReaction(0).PrecursorMass; } catch { return -1.0; } + }); } - private static string SafeGetScanEventString(IScanEvent scanEvent) + [UnmanagedCallersOnly(EntryPoint = "get_scan_event_string")] + public static unsafe int GetScanEventString(long arg0, int arg1, byte* arg2, int arg3) { - if (scanEvent == null) return ""; - // We AVOID scanEvent.ToString() because it triggers the Thermo.FilterStringTokens static constructor - // which fails in AOT due to GetEnumValues[T] reflection. - try - { - var polarity = scanEvent.Polarity == PolarityType.Positive ? "+" : (scanEvent.Polarity == PolarityType.Negative ? "-" : ""); - var analyzer = ((int)scanEvent.MassAnalyzer).ToString(); - var msOrder = ((int)scanEvent.MSOrder).ToString(); - return $"{analyzer} {polarity} ms{msOrder}"; - } - catch (Exception ex) - { - Console.WriteLine($"Warning: Manual scan event formatting failed: {ex.Message}"); - return "MS_ORDER_ONLY"; - } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { + string s = f.GetFilterForScanNumber(arg1).ToString(); + return CopyString(s, arg2, arg3); + } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_event_string")] - public static unsafe int GetScanEventString(int scanNumber, byte* buffer, int bufferSize) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_string")] + public static unsafe int GetScanFilterString(long arg0, int arg1, byte* arg2, int arg3) { - if (_rawFile == null) return 0; - try - { - var scanEvent = _rawFile.GetScanEventForScanNumber(scanNumber); - if (scanEvent == null) return 0; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var filter = f.GetFilterForScanNumber(arg1); + if (filter == null) return 0; - string eventStr = SafeGetScanEventString(scanEvent); + string filterStr = SafeGetFilterString(filter); - if (string.IsNullOrEmpty(eventStr)) return 0; + if (string.IsNullOrEmpty(filterStr)) return 0; - var bytes = System.Text.Encoding.UTF8.GetBytes(eventStr); - int count = Math.Min(bytes.Length, bufferSize - 1); + var bytes = System.Text.Encoding.UTF8.GetBytes(filterStr); + int count = Math.Min(bytes.Length, arg3 - 1); for (int i = 0; i < count; i++) { - buffer[i] = bytes[i]; + arg2[i] = bytes[i]; } - buffer[count] = 0; // Null terminator - return bytes.Length; - } - catch (Exception ex) - { - Console.WriteLine($"Fatal error in get_scan_event_string: {ex}"); - return -1; - } + arg2[count] = 0; + return count; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_number_from_rt")] + public static unsafe int GetScanNumberFromRt(long arg0, double arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.ScanNumberFromRetentionTime(arg1); } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_ms2_filter_masses")] - public static unsafe int GetMs2FilterMasses(double* buffer, int maxSize) + public static unsafe int GetMs2FilterMasses(long arg0, double* arg1, int arg2) { - if (_rawFile == null) return -1; - try - { - var precursors = new HashSet(); - for (int i = _rawFile.RunHeader.FirstSpectrum; i <= _rawFile.RunHeader.LastSpectrum; i++) + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var precursors = new HashSet(); + for (int i = f.RunHeader.FirstSpectrum; i <= f.RunHeader.LastSpectrum; i++) { - var scanEvent = _rawFile.GetScanEventForScanNumber(i); + var scanEvent = f.GetScanEventForScanNumber(i); if (scanEvent.MSOrder > MSOrderType.Ms) { precursors.Add(scanEvent.GetReaction(0).PrecursorMass); @@ -721,81 +526,40 @@ public static unsafe int GetMs2FilterMasses(double* buffer, int maxSize) } var sorted = precursors.OrderBy(x => x).ToList(); - int count = Math.Min(sorted.Count, maxSize); - for (int i = 0; i < count; i++) - { - buffer[i] = sorted[i]; - } - return count; - } - catch (Exception ex) - { - Console.WriteLine($"Error in get_ms2_filter_masses: {ex}"); - return -1; - } - } - - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_string")] - public static unsafe int GetScanFilterString(int scanNumber, byte* buffer, int bufferSize) - { - if (_rawFile == null) return 0; - try - { - var filter = _rawFile.GetFilterForScanNumber(scanNumber); - if (filter == null) return 0; - - string filterStr = SafeGetFilterString(filter); - - if (string.IsNullOrEmpty(filterStr)) return 0; - - var bytes = System.Text.Encoding.UTF8.GetBytes(filterStr); - int count = Math.Min(bytes.Length, bufferSize - 1); + int count = Math.Min(sorted.Count, arg2); for (int i = 0; i < count; i++) { - buffer[i] = bytes[i]; + arg1[i] = sorted[i]; } - buffer[count] = 0; - return count; - } - catch (Exception) - { - return 0; - } - } - - [UnmanagedCallersOnly(EntryPoint = "get_scan_number_from_rt")] - public static int GetScanNumberFromRT(double rt) - { - if (_rawFile == null) return -1; - return _rawFile.ScanNumberFromRetentionTime(rt); + return count; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_ms2_scan_number_from_rt")] - public static int GetMs2ScanNumberFromRT(double rt, double precursorMz, double tolerancePpm) + public static unsafe int GetMs2ScanNumberFromRt(long arg0, double arg1, double arg2, double arg3) { - if (_rawFile == null) return -1; - try - { - int bestScan = -1; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { int bestScan = -1; double minDistance = double.MaxValue; - for (int i = _rawFile.RunHeader.FirstSpectrum; i <= _rawFile.RunHeader.LastSpectrum; i++) + for (int i = f.RunHeader.FirstSpectrum; i <= f.RunHeader.LastSpectrum; i++) { - var scanEvent = _rawFile.GetScanEventForScanNumber(i); + var scanEvent = f.GetScanEventForScanNumber(i); if (scanEvent.MSOrder > MSOrderType.Ms) { double pMz = scanEvent.GetReaction(0).PrecursorMass; bool match = false; - if (precursorMz <= 0) { + if (arg2 <= 0) { match = true; } else { - match = Math.Abs(pMz - precursorMz) < 0.01; + match = Math.Abs(pMz - arg2) < 0.01; } if (match) { - double scanRt = _rawFile.RetentionTimeFromScanNumber(i); - double dist = Math.Abs(scanRt - rt); + double scanRt = f.RetentionTimeFromScanNumber(i); + double dist = Math.Abs(scanRt - arg1); if (dist < minDistance) { minDistance = dist; @@ -804,422 +568,547 @@ public static int GetMs2ScanNumberFromRT(double rt, double precursorMz, double t } } } - return bestScan; - } - catch - { - return -1; - } - } - - [UnmanagedCallersOnly(EntryPoint = "get_chromatogram")] - public static unsafe int GetChromatogram(int traceType, IntPtr filterPtr, double* massRangesStart, double* massRangesEnd, int massRangeCount, int startScan, int endScan, double* times, double* intensities, int maxLength) - { - if (_rawFile == null) return -1; - try - { - string filter = Marshal.PtrToStringAnsi(filterPtr) ?? ""; - var settings = new ChromatogramTraceSettings((TraceType)traceType) { Filter = filter }; - - if (massRangeCount > 0) - { - settings.MassRangeCount = massRangeCount; - for (int i = 0; i < massRangeCount; i++) - { - settings.SetMassRange(i, new Range(massRangesStart[i], massRangesEnd[i])); - } - } - - var data = _rawFile.GetChromatogramData(new[] { settings }, startScan, endScan); - - if (data == null || data.PositionsArray == null || data.PositionsArray.Length == 0) - { - // Console.WriteLine($"GetChromatogramData returned no results for type={traceType}, filter='{filter}', range={startScan}-{endScan}"); - return 0; - } - - int count = Math.Min(data.PositionsArray[0].Length, maxLength); - for (int i = 0; i < count; i++) - { - times[i] = data.PositionsArray[0][i]; - intensities[i] = data.IntensitiesArray[0][i]; - } - return data.PositionsArray[0].Length; - } - catch (Exception ex) - { - Console.WriteLine($"Error in get_chromatogram: {ex}"); - return -1; - } + return bestScan; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_ms1_scan_number_from_rt")] - public static int GetMs1ScanNumberFromRT(double rt) + public static unsafe int GetMs1ScanNumberFromRt(long arg0, double arg1) { - if (_rawFile == null) return -1; - try - { - int scan = _rawFile.ScanNumberFromRetentionTime(rt); - var scanEvent = _rawFile.GetScanEventForScanNumber(scan); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { int scan = f.ScanNumberFromRetentionTime(arg1); + var scanEvent = f.GetScanEventForScanNumber(scan); if (scanEvent.MSOrder == MSOrderType.Ms) return scan; // Search nearby if not MS1 for (int i = 1; i < 100; i++) { - if (scan - i >= _rawFile.RunHeader.FirstSpectrum) + if (scan - i >= f.RunHeader.FirstSpectrum) { - if (_rawFile.GetScanEventForScanNumber(scan - i).MSOrder == MSOrderType.Ms) return scan - i; + if (f.GetScanEventForScanNumber(scan - i).MSOrder == MSOrderType.Ms) return scan - i; } - if (scan + i <= _rawFile.RunHeader.LastSpectrum) + if (scan + i <= f.RunHeader.LastSpectrum) { - if (_rawFile.GetScanEventForScanNumber(scan + i).MSOrder == MSOrderType.Ms) return scan + i; + if (f.GetScanEventForScanNumber(scan + i).MSOrder == MSOrderType.Ms) return scan + i; } } - return -1; - } - catch - { - return -1; - } + return -1; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_chromatogram")] + public static unsafe int GetChromatogram(long arg0, ChromatogramParams* p) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { + string filter = Marshal.PtrToStringAnsi((IntPtr)p->Filter) ?? ""; + var settings = new ChromatogramTraceSettings((TraceType)p->TraceType) { Filter = filter }; + + if (p->MassRangeCount > 0) + { + settings.MassRangeCount = p->MassRangeCount; + for (int i = 0; i < p->MassRangeCount; i++) + { + settings.SetMassRange(i, new Range(p->MassRangesStart[i], p->MassRangesEnd[i])); + } + } + + var data = f.GetChromatogramData(new[] { settings }, p->StartScan, p->EndScan); + + if (data == null || data.PositionsArray == null || data.PositionsArray.Length == 0) + { + return 0; + } + + int count = Math.Min(data.PositionsArray[0].Length, p->MaxLength); + for (int i = 0; i < count; i++) + { + p->Times[i] = data.PositionsArray[0][i]; + p->Intensities[i] = data.IntensitiesArray[0][i]; + } + return count; + } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_filters")] + public static unsafe int GetFilters(long arg0, IntPtr* arg1, int arg2) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { + var filterList = f.GetFilters().ToArray(); + int count = Math.Min(filterList.Length, arg2); + for (int i = 0; i < count; i++) + { + arg1[i] = Marshal.StringToHGlobalAnsi(filterList[i].ToString()); + } + return filterList.Length; + } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_averaged_spectrum")] - public static unsafe int GetAveragedSpectrum(int* scanNumbers, int numScans, double* masses, double* intensities, int maxLength) + public static unsafe int GetAveragedSpectrum(long arg0, int* arg1, int arg2, double* arg3, double* arg4, int arg5) { - if (_rawFile == null) return -1; - try - { - var scans = new int[numScans]; - for (int i = 0; i < numScans; i++) scans[i] = scanNumbers[i]; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var scans = new int[arg2]; + for (int i = 0; i < arg2; i++) scans[i] = arg1[i]; // CommonCore uses AverageScans extension or casting to IScanAveragePlus var massOptions = new MassOptions() { Tolerance = 10, ToleranceUnits = ToleranceUnits.ppm }; var averageOptions = new FtAverageOptions(); - var result = _rawFile.AverageScans(scans.ToList(), massOptions, averageOptions); + var result = f.AverageScans(scans.ToList(), massOptions, averageOptions); if (result == null || result.PreferredMasses == null) return 0; - int count = Math.Min(result.PreferredMasses.Length, maxLength); + int count = Math.Min(result.PreferredMasses.Length, arg5); for (int i = 0; i < count; i++) { - masses[i] = result.PreferredMasses[i]; - intensities[i] = result.PreferredIntensities[i]; + arg3[i] = result.PreferredMasses[i]; + arg4[i] = result.PreferredIntensities[i]; } - return result.PreferredMasses.Length; - } - catch (Exception ex) - { - Console.WriteLine($"Error in get_averaged_spectrum: {ex}"); - return -1; - } + return result.PreferredMasses.Length; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_instrument_count")] + public static unsafe int GetInstrumentCount(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.InstrumentCount; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_instrument_count_of_type")] + public static unsafe int GetInstrumentCountOfType(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.GetInstrumentCountOfType((Device)arg1); } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "is_open")] + public static unsafe int IsOpen(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.IsOpen ? 1 : 0; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "is_error")] + public static unsafe int IsError(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.IsError ? 1 : 0; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "in_acquisition")] + public static unsafe int InAcquisition(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.InAcquisition ? 1 : 0; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "has_ms_data")] + public static unsafe int HasMsData(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.HasMsData ? 1 : 0; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_meta_filters")] + public static unsafe int GetScanFilterMetaFilters(long arg0, int arg1, IntPtr* arg2, int arg3) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { + var filter = f.GetFilterForScanNumber(arg1); + if (filter == null) return 0; + + // Reflection based access to MetaFilters (if not in public interface) + var prop = filter.GetType().GetProperty("MetaFilters"); + if (prop == null) return 0; + + var metaFiltersObj = prop.GetValue(filter) as System.Collections.IEnumerable; + if (metaFiltersObj == null) return 0; + + var metaList = new List(); + foreach (var mf in metaFiltersObj) + { + if (mf != null) metaList.Add(mf.ToString() ?? ""); + } + + int count = Math.Min(metaList.Count, arg3); + for (int i = 0; i < count; i++) + { + arg2[i] = Marshal.StringToHGlobalAnsi(metaList[i]); + } + return metaList.Count; + } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_field_free_region")] + public static unsafe int GetScanFilterFieldFreeRegion(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return GetFilterIntHelper(f, (int)arg1, "FieldFreeRegion"); } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_instrument_count")] - public static int GetInstrumentCount() + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_index_to_multiple_activation_index")] + public static unsafe int GetScanFilterIndexToMultipleActivationIndex(long arg0, int arg1) { - if (_rawFile == null) return -1; - return _rawFile.InstrumentCount; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return GetFilterIntHelper(f, (int)arg1, "IndexToMultipleActivationIndex"); } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_instrument_count_of_type")] - public static int GetInstrumentCountOfType(int type) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_compensation_volt_type")] + public static unsafe int GetScanFilterCompensationVoltType(long arg0, int arg1) { - if (_rawFile == null) return -1; - return _rawFile.GetInstrumentCountOfType((Device)type); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).CompensationVoltType; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "is_open")] - public static int IsOpen() + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_compensation_voltage_count")] + public static unsafe int GetScanFilterCompensationVoltageCount(long arg0, int arg1) { - if (_rawFile == null) return 0; - return _rawFile.IsOpen ? 1 : 0; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.GetFilterForScanNumber(arg1).CompensationVoltageCount; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "is_error")] - public static int IsError() + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_electron_capture_dissociation")] + public static unsafe int GetScanFilterElectronCaptureDissociation(long arg0, int arg1) { - if (_rawFile == null) return 1; - return _rawFile.IsError ? 1 : 0; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).ElectronCaptureDissociation; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "in_acquisition")] - public static int InAcquisition() + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_electron_capture_dissociation_value")] + public static unsafe double GetScanFilterElectronCaptureDissociationValue(long arg0, int arg1) { - if (_rawFile == null) return 0; - return _rawFile.InAcquisition ? 1 : 0; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return GetFilterHelper(f, (int)arg1, "ElectronCaptureDissociationValue"); } catch { return -1.0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "has_ms_data")] - public static int HasMsData() + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_electron_transfer_dissociation")] + public static unsafe int GetScanFilterElectronTransferDissociation(long arg0, int arg1) { - if (_rawFile == null) return 0; - return _rawFile.HasMsData ? 1 : 0; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).ElectronTransferDissociation; } catch { return 0; } + }); } - private static unsafe int _getStatusLogValuesForRt(double rt, byte* buffer, int bufferSize) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_electron_transfer_dissociation_value")] + public static unsafe double GetScanFilterElectronTransferDissociationValue(long arg0, int arg1) { - if (_rawFile == null) return -1; - try - { - var log = _rawFile.GetStatusLogForRetentionTime(rt); - if (log == null || log.Values == null) return 0; - var res = string.Join("|", log.Values); - var bytes = System.Text.Encoding.UTF8.GetBytes(res); - int count = Math.Min(bytes.Length, bufferSize - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return bytes.Length; - } - catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return GetFilterHelper(f, (int)arg1, "ElectronTransferDissociationValue"); } catch { return -1.0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_status_log_values_for_rt")] - public static unsafe int GetStatusLogValuesForRt(double rt, byte* buffer, int bufferSize) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_enhanced")] + public static unsafe int GetScanFilterEnhanced(long arg0, int arg1) { - return _getStatusLogValuesForRt(rt, buffer, bufferSize); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).Enhanced; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_status_log_values")] - public static unsafe int GetStatusLogValues(int scanNumber, byte* buffer, int bufferSize) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_higher_energy_cid")] + public static unsafe int GetScanFilterHigherEnergyCid(long arg0, int arg1) { - if (_rawFile == null) return -1; - try - { - var rt = _rawFile.RetentionTimeFromScanNumber(scanNumber); - return _getStatusLogValuesForRt(rt, buffer, bufferSize); - } - catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return GetFilterIntHelper(f, (int)arg1, "HigherEnergyCID") != 0 ? GetFilterIntHelper(f, (int)arg1, "HigherEnergyCID") : GetFilterIntHelper(f, (int)arg1, "HigherEnergyCid"); } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_status_log_header")] - public static unsafe int GetStatusLogHeader(byte* buffer, int bufferSize) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_higher_energy_cid_value")] + public static unsafe double GetScanFilterHigherEnergyCidValue(long arg0, int arg1) { - if (_rawFile == null) return -1; - try - { - var info = _rawFile.GetStatusLogHeaderInformation(); - if (info == null) return 0; - var res = string.Join("|", info.Select(x => x.Label + "###TYPE###" + (int)x.DataType)); - var bytes = System.Text.Encoding.UTF8.GetBytes(res); - int count = Math.Min(bytes.Length, bufferSize - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return bytes.Length; - } - catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { double val = GetFilterHelper(f, (int)arg1, "HigherEnergyCIDValue"); if (val == 0.0) val = GetFilterHelper(f, (int)arg1, "HigherEnergyCidValue"); return val; } catch { return -1.0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_status_log_count")] - public static int GetStatusLogCount() + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_multiple_photon_dissociation")] + public static unsafe int GetScanFilterMultiplePhotonDissociation(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return _rawFile.GetStatusLogEntriesCount(); } - catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return GetFilterIntHelper(f, (int)arg1, "MultiplePhotonDissociation"); } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_trailer_extra_values")] - public static unsafe int GetTrailerExtraValues(int scanNumber, byte* buffer, int bufferSize) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_multiple_photon_dissociation_value")] + public static unsafe double GetScanFilterMultiplePhotonDissociationValue(long arg0, int arg1) { - if (_rawFile == null) return -1; - try - { - var trailer = _rawFile.GetTrailerExtraInformation(scanNumber); - if (trailer == null || trailer.Values == null) return 0; - var res = string.Join("|", trailer.Values); - var bytes = System.Text.Encoding.UTF8.GetBytes(res); - int count = Math.Min(bytes.Length, bufferSize - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return bytes.Length; - } - catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return GetFilterHelper(f, (int)arg1, "MultiplePhotonDissociationValue"); } catch { return -1.0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_trailer_extra_count")] - public static int GetTrailerExtraCount() + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_pulsed_q_dissociation")] + public static unsafe int GetScanFilterPulsedQDissociation(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { - var header = _rawFile.GetTrailerExtraHeaderInformation(); - return header != null ? header.Count() : 0; - } - catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return GetFilterIntHelper(f, (int)arg1, "PulsedQDissociation"); } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_event_ms_order")] - public static int GetScanEventMsOrder(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_pulsed_q_dissociation_value")] + public static unsafe double GetScanFilterPulsedQDissociationValue(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).MSOrder; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return GetFilterHelper(f, (int)arg1, "PulsedQDissociationValue"); } catch { return -1.0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_event_mass_count")] - public static int GetScanEventMassCount(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_source_fragmentation")] + public static unsafe int GetScanFilterSourceFragmentation(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return _rawFile.GetScanEventForScanNumber(scanNumber).MassCount; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).SourceFragmentation; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_event_precursor_mass")] - public static double GetScanEventPrecursorMass(int scanNumber, int index) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_source_fragmentation_info_valid")] + public static unsafe int GetScanFilterSourceFragmentationInfoValid(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return _rawFile.GetScanEventForScanNumber(scanNumber).GetMass(index); } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).SourceFragmentationInfoValid[0]; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_event_activation_type")] - public static int GetScanEventActivationType(int scanNumber, int index) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_source_fragmentation_type")] + public static unsafe int GetScanFilterSourceFragmentationType(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).GetActivation(index); } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).SourceFragmentationType; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_event_collision_energy")] - public static double GetScanEventCollisionEnergy(int scanNumber, int index) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_source_fragmentation_value")] + public static unsafe double GetScanFilterSourceFragmentationValue(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return _rawFile.GetScanEventForScanNumber(scanNumber).GetEnergy(index); } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return f.GetFilterForScanNumber(arg1).SourceFragmentationValue(0); } catch { return -1.0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_stats")] - public static unsafe int GetScanStats(int scanNumber, double* data) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_supplemental_activation")] + public static unsafe int GetScanFilterSupplementalActivation(long arg0, int arg1) { - if (_rawFile == null) return -1; - try - { - var stats = _rawFile.GetScanStatsForScanNumber(scanNumber); - if (stats == null) return 0; - data[0] = stats.StartTime; - data[1] = stats.LowMass; - data[2] = stats.HighMass; - data[3] = stats.TIC; - data[4] = stats.BasePeakMass; - data[5] = stats.BasePeakIntensity; - data[6] = stats.PacketCount; - return 7; - } - catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).SupplementalActivation; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_ultra")] - public static int GetScanFilterUltra(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_mass_precision")] + public static unsafe int GetScanFilterMassPrecision(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).Ultra; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).MassPrecision; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_wideband")] - public static int GetScanFilterWideband(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_multi_notch")] + public static unsafe int GetScanFilterMultiNotch(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).Wideband; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).MultiNotch; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_polarity")] - public static int GetScanFilterPolarity(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_multiplex")] + public static unsafe int GetScanFilterMultiplex(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).Polarity; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetFilterForScanNumber(arg1).Multiplex; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_ms_order")] - public static int GetScanFilterMsOrder(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_unique_mass_count")] + public static unsafe int GetScanFilterUniqueMassCount(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).MSOrder; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.GetFilterForScanNumber(arg1).UniqueMassCount; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_mass_analyzer")] - public static int GetScanFilterMassAnalyzer(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_param_a")] + public static unsafe double GetScanFilterParamA(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).MassAnalyzer; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return GetFilterHelper(f, (int)arg1, "ParamA"); } catch { return -1.0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_detector")] - public static int GetScanFilterDetector(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_param_b")] + public static unsafe double GetScanFilterParamB(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).Detector; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return GetFilterHelper(f, (int)arg1, "ParamB"); } catch { return -1.0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_scan_data")] - public static int GetScanFilterScanData(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_param_f")] + public static unsafe double GetScanFilterParamF(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return GetFilterHelper(f, (int)arg1, "ParamF"); } catch { return -1.0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_param_r")] + public static unsafe double GetScanFilterParamR(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return GetFilterHelper(f, (int)arg1, "ParamR"); } catch { return -1.0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_param_v")] + public static unsafe double GetScanFilterParamV(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).ScanData; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return GetFilterHelper(f, (int)arg1, "ParamV"); } catch { return -1.0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_scan_mode")] - public static int GetScanFilterScanMode(int scanNumber) + public static unsafe int GetScanFilterScanMode(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).ScanMode; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).ScanMode; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_accurate_mass")] - public static int GetScanFilterAccurateMass(int scanNumber) + public static unsafe int GetScanFilterAccurateMass(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).AccurateMass; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).AccurateMass; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_ionization_mode")] - public static int GetScanFilterIonizationMode(int scanNumber) + public static unsafe int GetScanFilterIonizationMode(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).IonizationMode; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).IonizationMode; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_lock")] - public static int GetScanFilterLock(int scanNumber) + public static unsafe int GetScanFilterLock(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).Lock; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).Lock; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_turbo_scan")] - public static int GetScanFilterTurboScan(int scanNumber) + public static unsafe int GetScanFilterTurboScan(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).TurboScan; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).TurboScan; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_corona")] - public static int GetScanFilterCorona(int scanNumber) + public static unsafe int GetScanFilterCorona(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).Corona; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).Corona; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_dependent")] - public static int GetScanFilterDependent(int scanNumber) + public static unsafe int GetScanFilterDependent(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).Dependent; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).Dependent; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_detector_value")] - public static double GetScanFilterDetectorValue(int scanNumber) + public static unsafe double GetScanFilterDetectorValue(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return _rawFile.GetScanEventForScanNumber(scanNumber).DetectorValue; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return f.GetScanEventForScanNumber(arg1).DetectorValue; } catch { return -1.0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_scan_event_compensation_voltage")] - public static int GetScanEventCompensationVoltage(int scanNumber) + public static unsafe int GetScanEventCompensationVoltage(long arg0, int arg1) { - if (_rawFile == null) return -1; - try { return (int)_rawFile.GetScanEventForScanNumber(scanNumber).CompensationVoltage; } catch { return -1; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).CompensationVoltage; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_scan_event_compensation_voltage_value")] - public static double GetScanEventCompensationVoltageValue(int scanNumber) + public static unsafe double GetScanEventCompensationVoltageValue(long arg0, int arg1) { - if (_rawFile == null) return -1; - try - { - var scanEvent = _rawFile.GetScanEventForScanNumber(scanNumber); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { var scanEvent = f.GetScanEventForScanNumber(arg1); // Use reflection for properties that might not be in the base IScanEvent interface in some versions var prop = scanEvent.GetType().GetProperty("CompensationVoltageValue"); if (prop != null) @@ -1227,249 +1116,555 @@ public static double GetScanEventCompensationVoltageValue(int scanNumber) var val = prop.GetValue(scanEvent); return val != null ? (double)Convert.ChangeType(val, typeof(double)) : 0.0; } - return 0.0; - } - catch { return -1; } + return 0.0; } catch { return -1.0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_event_ms_order")] + public static unsafe int GetScanEventMsOrder(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).MSOrder; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_event_mass_count")] + public static unsafe int GetScanEventMassCount(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.GetScanEventForScanNumber(arg1).MassCount; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_event_precursor_mass")] + public static unsafe double GetScanEventPrecursorMass(long arg0, int arg1, int arg2) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { + var ev = f.GetScanEventForScanNumber(arg1); + if ((int)ev.MSOrder > 1 && arg2 < ev.MassCount) return ev.GetMass(arg2); + return 0.0; + } catch { return -1.0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_event_activation_type")] + public static unsafe int GetScanEventActivationType(long arg0, int arg1, int arg2) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { + var ev = f.GetScanEventForScanNumber(arg1); + if ((int)ev.MSOrder > 1 && arg2 < ev.MassCount) return (int)ev.GetReaction(arg2).ActivationType; + return -1; // -1 for "None" or "Not Applicable" + } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_event_activation_type_name")] + public static unsafe int GetScanEventActivationTypeName(long arg0, int arg1, int arg2, byte* arg3, int arg4) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + if (arg3 == null || arg4 <= 0) return 0; + try { + var ev = f.GetScanEventForScanNumber(arg1); + string name = "None"; + if ((int)ev.MSOrder > 1 && arg2 < ev.MassCount) name = ev.GetReaction(arg2).ActivationType.ToString(); + var bytes = System.Text.Encoding.UTF8.GetBytes(name); + int len = Math.Min(bytes.Length, arg4 - 1); + for (int i = 0; i < len; i++) arg3[i] = bytes[i]; + arg3[len] = 0; + return len; + } catch { return 0; } + }); + } + + + [UnmanagedCallersOnly(EntryPoint = "get_scan_event_collision_energy")] + public static unsafe double GetScanEventCollisionEnergy(long arg0, int arg1, int arg2) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { + var ev = f.GetScanEventForScanNumber(arg1); + if ((int)ev.MSOrder > 1 && arg2 < ev.MassCount) return ev.GetEnergy(arg2); + return 0.0; + } catch { return -1.0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_stats")] + public static unsafe int GetScanStats(long arg0, int arg1, double* arg2) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var stats = f.GetScanStatsForScanNumber(arg1); + if (stats == null) return 0; + arg2[0] = stats.StartTime; + arg2[1] = stats.LowMass; + arg2[2] = stats.HighMass; + arg2[3] = stats.TIC; + arg2[4] = stats.BasePeakMass; + arg2[5] = stats.BasePeakIntensity; + arg2[6] = stats.PacketCount; + arg2[7] = stats.IsCentroidScan ? 1.0 : 0.0; + return 8; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_ultra")] + public static unsafe int GetScanFilterUltra(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).Ultra; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_wideband")] + public static unsafe int GetScanFilterWideband(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).Wideband; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_polarity")] + public static unsafe int GetScanFilterPolarity(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).Polarity; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_ms_order")] + public static unsafe int GetScanFilterMsOrder(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).MSOrder; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_mass_analyzer")] + public static unsafe int GetScanFilterMassAnalyzer(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).MassAnalyzer; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_detector")] + public static unsafe int GetScanFilterDetector(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).Detector; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_scan_data")] + public static unsafe int GetScanFilterScanData(long arg0, int arg1) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.GetScanEventForScanNumber(arg1).ScanData; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_trailer_extra_count")] + public static unsafe int GetTrailerExtraCount(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var header = f.GetTrailerExtraHeaderInformation(); + return header != null ? header.Count() : 0; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_status_log_values")] + public static unsafe int GetStatusLogValues(long arg0, int arg1, byte* arg2, int arg3) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var rt = f.RetentionTimeFromScanNumber(arg1); + return _getStatusLogValuesForRtHelper(f, rt, arg2, arg3); } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_status_log_header")] + public static unsafe int GetStatusLogHeader(long arg0, byte* arg1, int arg2) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var info = f.GetStatusLogHeaderInformation(); + if (info == null) return 0; + var res = string.Join("|", info.Select(x => x.Label + "###TYPE###" + (int)x.DataType)); + var bytes = System.Text.Encoding.UTF8.GetBytes(res); + int count = Math.Min(bytes.Length, arg2 - 1); + for (int i = 0; i < count; i++) arg1[i] = bytes[i]; + arg1[count] = 0; + return bytes.Length; } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_status_log_values_for_rt")] + public static unsafe int GetStatusLogValuesForRt(long arg0, double arg1, byte* arg2, int arg3) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return _getStatusLogValuesForRtHelper(f, arg1, arg2, arg3); } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_status_log_count")] + public static unsafe int GetStatusLogCount(long arg0) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.GetStatusLogEntriesCount(); } catch { return 0; } + }); + } + + [UnmanagedCallersOnly(EntryPoint = "get_trailer_extra_values")] + public static unsafe int GetTrailerExtraValues(long arg0, int arg1, byte* arg2, int arg3) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var trailer = f.GetTrailerExtraInformation(arg1); + if (trailer == null || trailer.Values == null) return 0; + var res = string.Join("|", trailer.Values); + var bytes = System.Text.Encoding.UTF8.GetBytes(res); + int count = Math.Min(bytes.Length, arg3 - 1); + for (int i = 0; i < count; i++) arg2[i] = bytes[i]; + arg2[count] = 0; + return bytes.Length; } catch { return 0; } + }); } [UnmanagedCallersOnly(EntryPoint = "get_trailer_extra_header")] - public static unsafe int GetTrailerExtraHeader(byte* buffer, int bufferSize) + public static unsafe int GetTrailerExtraHeader(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return -1; - try - { - var info = _rawFile.GetTrailerExtraHeaderInformation(); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var info = f.GetTrailerExtraHeaderInformation(); if (info == null) return 0; var res = string.Join("|", info.Select(x => x.Label + "###TYPE###" + (int)x.DataType)); var bytes = System.Text.Encoding.UTF8.GetBytes(res); - int count = Math.Min(bytes.Length, bufferSize - 1); - for (int i = 0; i < count; i++) buffer[i] = bytes[i]; - buffer[count] = 0; - return bytes.Length; - } - catch { return -1; } + int count = Math.Min(bytes.Length, arg2 - 1); + for (int i = 0; i < count; i++) arg1[i] = bytes[i]; + arg1[count] = 0; + return bytes.Length; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "close_raw_file")] - public static void CloseRawFile() + [UnmanagedCallersOnly(EntryPoint = "get_file_description")] + public static unsafe int GetFileDescription(long arg0, byte* arg1, int arg2) { - _rawFile?.Dispose(); - _rawFile = null; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.FileHeader.FileDescription ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_compensation_volt_type")] - public static int GetScanFilterCompensationVoltType(int scanNumber) + + [UnmanagedCallersOnly(EntryPoint = "get_modified_date")] + public static unsafe int GetModifiedDate(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).CompensationVoltType; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.FileHeader.ModifiedDate.ToString() ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_compensation_voltage_count")] - public static int GetScanFilterCompensationVoltageCount(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_who_created_logon")] + public static unsafe int GetWhoCreatedLogon(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0; - try { return _rawFile.GetFilterForScanNumber(scanNumber).CompensationVoltageCount; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.FileHeader.WhoCreatedLogon ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_electron_capture_dissociation")] - public static int GetScanFilterElectronCaptureDissociation(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_who_modified_id")] + public static unsafe int GetWhoModifiedId(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).ElectronCaptureDissociation; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.FileHeader.WhoModifiedId ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_electron_transfer_dissociation")] - public static int GetScanFilterElectronTransferDissociation(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_who_modified_logon")] + public static unsafe int GetWhoModifiedLogon(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).ElectronTransferDissociation; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.FileHeader.WhoModifiedLogon ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_enhanced")] - public static int GetScanFilterEnhanced(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_sample_barcode")] + public static unsafe int GetSampleBarcode(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).Enhanced; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.SampleInformation.Barcode ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } + [UnmanagedCallersOnly(EntryPoint = "get_sample_id")] + public static unsafe int GetSampleId(long arg0, byte* arg1, int arg2) + { + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.SampleInformation.SampleId ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); + } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_source_fragmentation")] - public static int GetScanFilterSourceFragmentation(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_sample_name")] + public static unsafe int GetSampleName(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).SourceFragmentation; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.SampleInformation.SampleName ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_source_fragmentation_info_valid")] - public static int GetScanFilterSourceFragmentationInfoValid(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_sample_vial")] + public static unsafe int GetSampleVial(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).SourceFragmentationInfoValid[0]; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.SampleInformation.Vial ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_source_fragmentation_type")] - public static int GetScanFilterSourceFragmentationType(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_sample_comment")] + public static unsafe int GetSampleComment(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).SourceFragmentationType; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var str = f.SampleInformation.Comment ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_source_fragmentation_value")] - public static double GetScanFilterSourceFragmentationValue(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_instrument_axis_label_x")] + public static unsafe int GetInstrumentAxisLabelX(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0.0; - try { return _rawFile.GetFilterForScanNumber(scanNumber).SourceFragmentationValue(0); } catch { return 0.0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); var str = data?.AxisLabelX ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_supplemental_activation")] - public static int GetScanFilterSupplementalActivation(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_instrument_axis_label_y")] + public static unsafe int GetInstrumentAxisLabelY(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).SupplementalActivation; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); var str = data?.AxisLabelY ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_mass_precision")] - public static int GetScanFilterMassPrecision(int scanNumber) + + [UnmanagedCallersOnly(EntryPoint = "get_instrument_flags")] + public static unsafe int GetInstrumentFlags(long arg0, byte* arg1, int arg2) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).MassPrecision; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); var str = data?.Flags ?? ""; var bytes = System.Text.Encoding.UTF8.GetBytes(str); int count = Math.Min(bytes.Length, arg2 - 1); for (int i = 0; i < count; i++) arg1[i] = bytes[i]; arg1[count] = 0; return count; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_multi_notch")] - public static int GetScanFilterMultiNotch(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_instrument_units")] + public static unsafe int GetInstrumentUnits(long arg0) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).MultiNotch; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); return data != null ? (int)data.Units : 0; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_multiplex")] - public static int GetScanFilterMultiplex(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_instrument_is_valid")] + public static unsafe int GetInstrumentIsValid(long arg0) { - if (_rawFile == null) return 0; - try { return (int)_rawFile.GetFilterForScanNumber(scanNumber).Multiplex; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); return data != null && data.IsValid ? 1 : 0; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_unique_mass_count")] - public static int GetScanFilterUniqueMassCount(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_instrument_has_accurate_mass_precursors")] + public static unsafe int GetInstrumentHasAccurateMassPrecursors(long arg0) { - if (_rawFile == null) return 0; - try { return _rawFile.GetFilterForScanNumber(scanNumber).UniqueMassCount; } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); return data != null && data.HasAccurateMassPrecursors ? 1 : 0; } catch { return 0; } + }); } - private static double GetFilterDouble(int scanNumber, string name) + + [UnmanagedCallersOnly(EntryPoint = "get_instrument_is_tsq_quantum_file")] + public static unsafe int GetInstrumentIsTsqQuantumFile(long arg0) { - if (_rawFile == null) return 0.0; - try { - var filter = _rawFile.GetFilterForScanNumber(scanNumber); - var prop = filter.GetType().GetProperty(name); - if (prop == null) return 0.0; - var val = prop.GetValue(filter); - if (val == null) return 0.0; - return (double)Convert.ChangeType(val, typeof(double)); - } catch { return 0.0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { var data = f.GetInstrumentData(); return data != null && data.IsTsqQuantumFile() ? 1 : 0; } catch { return 0; } + }); } - private static int GetFilterInt(int scanNumber, string name) + [UnmanagedCallersOnly(EntryPoint = "get_instrument_method_count")] + public static unsafe int GetInstrumentMethodCount(long arg0) { - if (_rawFile == null) return 0; - try { - var filter = _rawFile.GetFilterForScanNumber(scanNumber); - var prop = filter.GetType().GetProperty(name); - if (prop == null) return 0; - var val = prop.GetValue(filter); - if (val == null) return 0; - return (int)Convert.ChangeType(val, typeof(int)); - } catch { return 0; } + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.InstrumentMethodsCount; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_higher_energy_cid")] - public static int GetScanFilterHigherEnergyCID(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_instrument_method")] + public static unsafe int GetInstrumentMethod(long arg0, int arg1, byte* arg2, int arg3) { - return GetFilterInt(scanNumber, "HigherEnergyCID") != 0 ? GetFilterInt(scanNumber, "HigherEnergyCID") : GetFilterInt(scanNumber, "HigherEnergyCid"); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return CopyString(f.GetInstrumentMethod(arg1), arg2, arg3); } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_higher_energy_cid_value")] - public static double GetScanFilterHigherEnergyCIDValue(int scanNumber) + + [UnmanagedCallersOnly(EntryPoint = "get_autosampler_tray_index")] + public static unsafe int GetAutosamplerTrayIndex(long arg0) { - double val = GetFilterDouble(scanNumber, "HigherEnergyCIDValue"); - if (val == 0.0) val = GetFilterDouble(scanNumber, "HigherEnergyCidValue"); - return val; + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.AutoSamplerInformation.TrayIndex; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_electron_capture_dissociation_value")] - public static double GetScanFilterElectronCaptureDissociationValue(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_autosampler_vial_index")] + public static unsafe int GetAutosamplerVialIndex(long arg0) { - return GetFilterDouble(scanNumber, "ElectronCaptureDissociationValue"); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.AutoSamplerInformation.VialIndex; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_electron_transfer_dissociation_value")] - public static double GetScanFilterElectronTransferDissociationValue(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_autosampler_tray_name")] + public static unsafe int GetAutosamplerTrayName(long arg0, byte* arg1, int arg2) { - return GetFilterDouble(scanNumber, "ElectronTransferDissociationValue"); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return CopyString(f.AutoSamplerInformation.TrayName ?? "", arg1, arg2); } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_multiple_photon_dissociation")] - public static int GetScanFilterMultiplePhotonDissociation(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_autosampler_tray_shape")] + public static unsafe int GetAutosamplerTrayShape(long arg0) { - return GetFilterInt(scanNumber, "MultiplePhotonDissociation"); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return (int)f.AutoSamplerInformation.TrayShape; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_multiple_photon_dissociation_value")] - public static double GetScanFilterMultiplePhotonDissociationValue(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_autosampler_vials_per_tray")] + public static unsafe int GetAutosamplerVialsPerTray(long arg0) { - return GetFilterDouble(scanNumber, "MultiplePhotonDissociationValue"); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.AutoSamplerInformation.VialsPerTray; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_pulsed_q_dissociation")] - public static int GetScanFilterPulsedQDissociation(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_autosampler_vials_per_tray_x")] + public static unsafe int GetAutosamplerVialsPerTrayX(long arg0) { - return GetFilterInt(scanNumber, "PulsedQDissociation"); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.AutoSamplerInformation.VialsPerTrayX; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_pulsed_q_dissociation_value")] - public static double GetScanFilterPulsedQDissociationValue(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_autosampler_vials_per_tray_y")] + public static unsafe int GetAutosamplerVialsPerTrayY(long arg0) { - return GetFilterDouble(scanNumber, "PulsedQDissociationValue"); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return f.AutoSamplerInformation.VialsPerTrayY; } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_param_a")] - public static double GetScanFilterParamA(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_sample_instrument_method_file")] + public static unsafe int GetSampleInstrumentMethodFile(long arg0, byte* arg1, int arg2) { - return GetFilterDouble(scanNumber, "ParamA"); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return 0; + try { return CopyString(f.SampleInformation.InstrumentMethodFile, arg1, arg2); } catch { return 0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_param_b")] - public static double GetScanFilterParamB(int scanNumber) + [UnmanagedCallersOnly(EntryPoint = "get_sample_injection_volume")] + public static unsafe double GetSampleInjectionVolume(long arg0) { - return GetFilterDouble(scanNumber, "ParamB"); + return RunOnWorker(() => { + if (!_openFiles.TryGetValue(arg0, out var f)) return -1.0; + try { return f.SampleInformation.InjectionVolume; } catch { return -1.0; } + }); } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_param_f")] - public static double GetScanFilterParamF(int scanNumber) + + private static string SafeGetScanEventString(IScanEvent scanEvent) { - return GetFilterDouble(scanNumber, "ParamF"); + if (scanEvent == null) return ""; + try { return scanEvent.ToString(); } catch { return ""; } } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_param_r")] - public static double GetScanFilterParamR(int scanNumber) + private static string SafeGetFilterString(IScanFilter filter) { - return GetFilterDouble(scanNumber, "ParamR"); + if (filter == null) return ""; + try { return filter.ToString(); } catch { return ""; } } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_param_v")] - public static double GetScanFilterParamV(int scanNumber) + private static double GetFilterHelper(IRawDataPlus file, int scanNumber, string name) { - return GetFilterDouble(scanNumber, "ParamV"); + if (file == null) return 0.0; + try { + var filter = file.GetFilterForScanNumber(scanNumber); + if (filter == null) return 0.0; + var prop = filter.GetType().GetProperty(name); + if (prop == null) return 0.0; + var val = prop.GetValue(filter); + if (val == null) return 0.0; + return (double)Convert.ChangeType(val, typeof(double)); + } catch { return 0.0; } } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_field_free_region")] - public static int GetScanFilterFieldFreeRegion(int scanNumber) + private static int GetFilterIntHelper(IRawDataPlus file, int scanNumber, string name) { - return GetFilterInt(scanNumber, "FieldFreeRegion"); + if (file == null) return 0; + try { + var filter = file.GetFilterForScanNumber(scanNumber); + if (filter == null) return 0; + var prop = filter.GetType().GetProperty(name); + if (prop == null) return 0; + var val = prop.GetValue(filter); + if (val == null) return 0; + return (int)Convert.ChangeType(val, typeof(int)); + } catch { return 0; } } - [UnmanagedCallersOnly(EntryPoint = "get_scan_filter_index_to_multiple_activation_index")] - public static int GetScanFilterIndexToMultipleActivationIndex(int scanNumber) + private static string SafeGetFilterStringHelper(IScanFilter filter) { - return GetFilterInt(scanNumber, "IndexToMultipleActivationIndex"); + if (filter == null) return ""; + try { return filter.ToString(); } catch { return ""; } } + + private static unsafe int _getStatusLogValuesForRtHelper(IRawDataPlus file, double rt, byte* buffer, long bufferSize) { return 0; } } } diff --git a/native_fisher_py/Cargo.lock b/native_fisher_py/Cargo.lock index f3e004e..c65adbb 100644 --- a/native_fisher_py/Cargo.lock +++ b/native_fisher_py/Cargo.lock @@ -56,7 +56,7 @@ dependencies = [ [[package]] name = "native_fisher_py" -version = "0.1.0" +version = "0.3.1" dependencies = [ "libloading", "pyo3", diff --git a/native_fisher_py/Cargo.toml b/native_fisher_py/Cargo.toml index ffe3970..0950283 100644 --- a/native_fisher_py/Cargo.toml +++ b/native_fisher_py/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "native_fisher_py" -version = "0.1.0" +version = "0.3.1" edition = "2024" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html diff --git a/native_fisher_py/python/native_fisher_py/data/classes.py b/native_fisher_py/python/native_fisher_py/data/classes.py index 068e9ab..039d78e 100644 --- a/native_fisher_py/python/native_fisher_py/data/classes.py +++ b/native_fisher_py/python/native_fisher_py/data/classes.py @@ -147,162 +147,163 @@ def get_hash_code(self): return 0 def perform_default_settings(self): pass class ScanFilter(CommonCoreDataObject): - def __init__(self, scan_number=0): + def __init__(self, handle=0, scan_number=0): + self._handle = handle self._scan_number = scan_number def __str__(self): from . import get_scan_filter_string - return get_scan_filter_string(self._scan_number) + return get_scan_filter_string(self._handle, self._scan_number) @property def name(self): - return get_scan_event_string(self._scan_number) + return get_scan_event_string(self._handle, self._scan_number) @property def ms_order(self): - return MsOrderType(get_ms_order(self._scan_number)) + return MsOrderType(get_ms_order(self._handle, self._scan_number)) @property def mass_analyzer(self): - return MassAnalyzerType(get_mass_analyzer(self._scan_number)) + return MassAnalyzerType(get_mass_analyzer(self._handle, self._scan_number)) @property def polarity(self): - return PolarityType(get_scan_filter_polarity(self._scan_number)) + return PolarityType(get_scan_filter_polarity(self._handle, self._scan_number)) @property def scan_data(self): - return ScanDataType(get_scan_filter_scan_data(self._scan_number)) + return ScanDataType(get_scan_filter_scan_data(self._handle, self._scan_number)) @property def ultra(self): - return TriState(get_scan_filter_ultra(self._scan_number)) + return TriState(get_scan_filter_ultra(self._handle, self._scan_number)) @property def wideband(self): - return TriState(get_scan_filter_wideband(self._scan_number)) + return TriState(get_scan_filter_wideband(self._handle, self._scan_number)) @property def detector(self): - return DetectorType(get_scan_filter_detector(self._scan_number)) + return DetectorType(get_scan_filter_detector(self._handle, self._scan_number)) @property def compensation_voltage(self): - return TriState(get_scan_event_compensation_voltage(self._scan_number)) + return TriState(get_scan_event_compensation_voltage(self._handle, self._scan_number)) @property def compensation_voltage_value(self): - return get_scan_event_compensation_voltage_value(self._scan_number) + return get_scan_event_compensation_voltage_value(self._handle, self._scan_number) @property def scan_mode(self): - return ScanModeType(get_scan_filter_scan_mode(self._scan_number)) + return ScanModeType(get_scan_filter_scan_mode(self._handle, self._scan_number)) @property def accurate_mass(self): - return EventAccurateMass(get_scan_filter_accurate_mass(self._scan_number)) + return EventAccurateMass(get_scan_filter_accurate_mass(self._handle, self._scan_number)) @property def ionization_mode(self): - return IonizationModeType(get_scan_filter_ionization_mode(self._scan_number)) + return IonizationModeType(get_scan_filter_ionization_mode(self._handle, self._scan_number)) @property def lock(self): - return TriState(get_scan_filter_lock(self._scan_number)) + return TriState(get_scan_filter_lock(self._handle, self._scan_number)) @property def meta_filters(self): # This will be implemented in the native layer to return a list of filter strings - return get_scan_filter_meta_filters(self._scan_number) + return get_scan_filter_meta_filters(self._handle, self._scan_number) @property def turbo_scan(self): - return TriState(get_scan_filter_turbo_scan(self._scan_number)) + return TriState(get_scan_filter_turbo_scan(self._handle, self._scan_number)) @property def corona(self): - return TriState(get_scan_filter_corona(self._scan_number)) + return TriState(get_scan_filter_corona(self._handle, self._scan_number)) @property def dependent(self): - return TriState(get_scan_filter_dependent(self._scan_number)) + return TriState(get_scan_filter_dependent(self._handle, self._scan_number)) @property def detector_value(self): - return get_scan_filter_detector_value(self._scan_number) + return get_scan_filter_detector_value(self._handle, self._scan_number) @property def source_fragmentation(self): - return TriState(get_scan_filter_source_fragmentation(self._scan_number)) + return TriState(get_scan_filter_source_fragmentation(self._handle, self._scan_number)) @property def source_fragmentation_info_valid(self): - return SourceFragmentationInfoValidType(get_scan_filter_source_fragmentation_info_valid(self._scan_number)) + return SourceFragmentationInfoValidType(get_scan_filter_source_fragmentation_info_valid(self._handle, self._scan_number)) @property def source_fragmentation_type(self): - return SourceFragmentationValueType(get_scan_filter_source_fragmentation_type(self._scan_number)) + return SourceFragmentationValueType(get_scan_filter_source_fragmentation_type(self._handle, self._scan_number)) @property def source_fragmentation_value(self): - return get_scan_filter_source_fragmentation_value(self._scan_number) + return get_scan_filter_source_fragmentation_value(self._handle, self._scan_number) @property def supplemental_activation(self): - return TriState(get_scan_filter_supplemental_activation(self._scan_number)) + return TriState(get_scan_filter_supplemental_activation(self._handle, self._scan_number)) @property def higher_energy_ci_d(self): - return TriState(get_scan_filter_higher_energy_cid(self._scan_number)) + return TriState(get_scan_filter_higher_energy_cid(self._handle, self._scan_number)) @higher_energy_ci_d.setter def higher_energy_ci_d(self, val): pass @property def higher_energy_ci_d_value(self): - return get_scan_filter_higher_energy_cid_value(self._scan_number) + return get_scan_filter_higher_energy_cid_value(self._handle, self._scan_number) @property def mass_precision(self): - return FilterAccurateMass(get_scan_filter_mass_precision(self._scan_number)) + return FilterAccurateMass(get_scan_filter_mass_precision(self._handle, self._scan_number)) @property def multi_notch(self): - return TriState(get_scan_filter_multi_notch(self._scan_number)) + return TriState(get_scan_filter_multi_notch(self._handle, self._scan_number)) @property def multiplex(self): - return TriState(get_scan_filter_multiplex(self._scan_number)) + return TriState(get_scan_filter_multiplex(self._handle, self._scan_number)) @property def unique_mass_count(self): - return get_scan_filter_unique_mass_count(self._scan_number) + return get_scan_filter_unique_mass_count(self._handle, self._scan_number) @property - def param_a(self): return get_scan_filter_param_a(self._scan_number) + def param_a(self): return get_scan_filter_param_a(self._handle, self._scan_number) @property - def param_b(self): return get_scan_filter_param_b(self._scan_number) + def param_b(self): return get_scan_filter_param_b(self._handle, self._scan_number) @property - def param_f(self): return get_scan_filter_param_f(self._scan_number) + def param_f(self): return get_scan_filter_param_f(self._handle, self._scan_number) @property - def param_r(self): return get_scan_filter_param_r(self._scan_number) + def param_r(self): return get_scan_filter_param_r(self._handle, self._scan_number) @property - def param_v(self): return get_scan_filter_param_v(self._scan_number) + def param_v(self): return get_scan_filter_param_v(self._handle, self._scan_number) @property def compensation_volt_type(self): - return CompensationVoltageType(get_scan_filter_compensation_volt_type(self._scan_number)) + return CompensationVoltageType(get_scan_filter_compensation_volt_type(self._handle, self._scan_number)) @property def compensation_voltage_count(self): - return get_scan_filter_compensation_voltage_count(self._scan_number) + return get_scan_filter_compensation_voltage_count(self._handle, self._scan_number) @property def electron_capture_dissociation(self): - return TriState(get_scan_filter_electron_capture_dissociation(self._scan_number)) + return TriState(get_scan_filter_electron_capture_dissociation(self._handle, self._scan_number)) @property def electron_capture_dissociation_value(self): - return get_scan_filter_electron_capture_dissociation_value(self._scan_number) + return get_scan_filter_electron_capture_dissociation_value(self._handle, self._scan_number) @property def electron_transfer_dissociation(self): - return TriState(get_scan_filter_electron_transfer_dissociation(self._scan_number)) + return TriState(get_scan_filter_electron_transfer_dissociation(self._handle, self._scan_number)) @property def electron_transfer_dissociation_value(self): - return get_scan_filter_electron_transfer_dissociation_value(self._scan_number) + return get_scan_filter_electron_transfer_dissociation_value(self._handle, self._scan_number) @property def enhanced(self): - return TriState(get_scan_filter_enhanced(self._scan_number)) + return TriState(get_scan_filter_enhanced(self._handle, self._scan_number)) @property def field_free_region(self): - return FieldFreeRegionType(get_scan_filter_field_free_region(self._scan_number)) + return FieldFreeRegionType(get_scan_filter_field_free_region(self._handle, self._scan_number)) @property def get_source_fragmentation_info_valid(self): return True @property def index_to_multiple_activation_index(self): - return get_scan_filter_index_to_multiple_activation_index(self._scan_number) + return get_scan_filter_index_to_multiple_activation_index(self._handle, self._scan_number) @property def locale_name(self): return "en-US" @property def multi_state_activation(self): return TriState.Off @property def multiple_photon_dissociation(self): - return TriState(get_scan_filter_multiple_photon_dissociation(self._scan_number)) + return TriState(get_scan_filter_multiple_photon_dissociation(self._handle, self._scan_number)) @property def multiple_photon_dissociation_value(self): - return get_scan_filter_multiple_photon_dissociation_value(self._scan_number) + return get_scan_filter_multiple_photon_dissociation_value(self._handle, self._scan_number) @property def photo_ionization(self): return TriState.Off @property def pulsed_q_dissociation(self): - return TriState(get_scan_filter_pulsed_q_dissociation(self._scan_number)) + return TriState(get_scan_filter_pulsed_q_dissociation(self._handle, self._scan_number)) @property def pulsed_q_dissociation_value(self): - return get_scan_filter_pulsed_q_dissociation_value(self._scan_number) + return get_scan_filter_pulsed_q_dissociation_value(self._handle, self._scan_number) @property def sector_scan(self): return SectorScanType(get_scan_filter_sector_scan(self._scan_number)) @@ -310,7 +311,7 @@ def sector_scan(self): def souce_fragmentaion_value_count(self): return 0 @property def source_fragmentation_info_valid(self): - return SourceFragmentationInfoValidType(get_scan_filter_source_fragmentation_info_valid(self._scan_number)) + return SourceFragmentationInfoValidType(get_scan_filter_source_fragmentation_info_valid(self._handle, self._scan_number)) class EnumBase(object): _instances = {} @@ -478,9 +479,27 @@ class IonizationModeType(EnumBase): IonizationModeType.ElectroSpray = IonizationModeType(1); IonizationModeType.ElectroSpray.name = "ElectroSpray" class ActivationType(EnumBase): - Any = 0; CollisionInducedDissociation = 1; ElectronCaptureDissociation = 2; ElectronTransferDissociation = 3; HigherEnergyCollisionalDissociation = 4; MultiPhotonDissociation = 5; PQD = 6; SAactivation = 7; UltraVioletPhotoDissociation = 8 - NegativeElectronTransferDissociation = 9; NegativeProtonTransferReaction = 10; ProtonTransferReaction = 11; LastActivation = 12 -ActivationType.Any = ActivationType(0); ActivationType.Any.name = "Any" + None_ = -1 + CollisionInducedDissociation = 0 + MultiPhotonDissociation = 1 + ElectronCaptureDissociation = 2 + PQD = 3 + ElectronTransferDissociation = 4 + HigherEnergyCollisionalDissociation = 5 + Any = 6 + SAactivation = 7 + UltraVioletPhotoDissociation = 8 + NegativeElectronTransferDissociation = 9 + NegativeProtonTransferReaction = 10 + ProtonTransferReaction = 11 + LastActivation = 12 + + # Shorthands + CID = 0 + HCD = 5 + +ActivationType.Any = ActivationType(6); ActivationType.Any.name = "Any" +ActivationType.None_ = ActivationType(-1); ActivationType.None_.name = "None_" # Add ModeA-Z import string for char in string.ascii_uppercase: @@ -584,7 +603,7 @@ def device_type(self): return 1 def instrument_index(self): return 0 class ScanStatistics(CommonCoreDataObject): - def __init__(self, start_time=0.0, low_mass=0.0, high_mass=0.0, tic=0.0, base_peak_mass=0.0, base_peak_intensity=0.0, packet_count=0, scan_number=0, ms_order=0): + def __init__(self, start_time=0.0, low_mass=0.0, high_mass=0.0, tic=0.0, base_peak_mass=0.0, base_peak_intensity=0.0, packet_count=0, scan_number=0, ms_order=0, is_centroid_scan=False): self._start_time = start_time self._low_mass = low_mass self._high_mass = high_mass @@ -594,6 +613,7 @@ def __init__(self, start_time=0.0, low_mass=0.0, high_mass=0.0, tic=0.0, base_pe self._packet_count = packet_count self._scan_number = scan_number self._ms_order = ms_order + self._is_centroid_scan = bool(is_centroid_scan) @property def start_time(self): return self._start_time @@ -624,7 +644,7 @@ def deep_clone(self): raise NotImplementedError @property def frequency(self): raise NotImplementedError @property - def is_centroid_scan(self): raise NotImplementedError + def is_centroid_scan(self): return self._is_centroid_scan @property def is_uniform_time(self): raise NotImplementedError @property @@ -769,18 +789,19 @@ def id(self): return self._id def values(self): return self._values class Reaction(CommonCoreDataObject): - def __init__(self, scan_number=0, index=0): + def __init__(self, handle=0, scan_number=0, index=0): + self._handle = handle self._scan_number = scan_number self._index = index @property def precursor_mass(self): - return get_scan_event_precursor_mass(self._scan_number, self._index) + return get_scan_event_precursor_mass(self._handle, self._scan_number, self._index) @property def activation_type(self): - return ActivationType(get_scan_event_activation_type(self._scan_number, self._index)) + return ActivationType(get_scan_event_activation_type(self._handle, self._scan_number, self._index)) @property def collision_energy(self): - return get_scan_event_collision_energy(self._scan_number, self._index) + return get_scan_event_collision_energy(self._handle, self._scan_number, self._index) @property def collision_energy_valid(self): raise NotImplementedError @property @@ -812,8 +833,8 @@ def deep_clone(self): return self @classmethod def from_file(cls, f, s): scan = cls() - segmented_scan = f.get_segmented_scan_from_scan_number(s) - centroid_stream = f.get_centroid_stream(s) + segmented_scan = f.get_segmented_scan_from_scan_number(self._handle, s) + centroid_stream = f.get_centroid_stream(self._handle, s) scan._centroid_stream = centroid_stream # Original reader preference: if centroids are present (FTMS), use them for preferred data @@ -881,9 +902,15 @@ def to_centroid(self): return None def tolerance_unit(self): return 0 class CentroidStream(CommonCoreDataObject): - def __init__(self, masses=None, intensities=None): + def __init__(self, masses=None, intensities=None, baselines=None, noises=None, charges=None, base_peak_noise=0.0, base_peak_resolution=0.0, scan_number=0): self._masses = masses if masses is not None else np.array([]) self._intensities = intensities if intensities is not None else np.array([]) + self._baselines = baselines if baselines is not None else np.array([]) + self._noises = noises if noises is not None else np.array([]) + self._charges = charges if charges is not None else np.array([]) + self._base_peak_noise = base_peak_noise + self._base_peak_resolution = base_peak_resolution + self._scan_number = scan_number @property def base_intensity(self): return np.max(self._intensities) if self._intensities.size > 0 else 0.0 @@ -892,57 +919,40 @@ def base_peak_intensity(self): return self.base_intensity @property def base_peak_mass(self): return self._masses[np.argmax(self._intensities)] if self._intensities.size > 0 else 0.0 @property - def base_peak_noise(self): raise NotImplementedError + def base_peak_noise(self): return self._base_peak_noise @property - def base_peak_resolution(self): raise NotImplementedError + def base_peak_resolution(self): return self._base_peak_resolution @property - def baselines(self): raise NotImplementedError + def baselines(self): return self._baselines @property - def charges(self): raise NotImplementedError - def clear(self): raise NotImplementedError - def clone(self): return self + def charges(self): return self._charges @property - def coefficients(self): - if _IS_SPHINX: return np.array([]) - raise NotImplementedError + def coefficients_count(self): return 0 @property - def coefficients_count(self): - if _IS_SPHINX: return 0 - raise NotImplementedError - def deep_clone(self): - if _IS_SPHINX: return self - raise NotImplementedError + def coefficients(self): return np.array([]) @property - def flags(self): - if _IS_SPHINX: return [] - raise NotImplementedError - def get_centroids(self): - if _IS_SPHINX: return [] - raise NotImplementedError - def get_label_peak(self, i): - if _IS_SPHINX: return None - raise NotImplementedError - def get_label_peaks(self): - if _IS_SPHINX: return [] - raise NotImplementedError + def flags(self): return 0 + def get_centroids(self): return self._masses, self._intensities + def get_label_peak(self, index): return None + def get_label_peaks(self): return None + @property + def noises(self): return self._noises @property def intensities(self): return self._intensities @property def length(self): return len(self._masses) if self._masses is not None else 0 @property def masses(self): return self._masses - @property - def noises(self): raise NotImplementedError def refresh_base_details(self): pass @property def resolutions(self): return np.array([]) @property - def scan_number(self): return 0 - def set_label_peaks(self, p): pass + def scan_number(self): return self._scan_number + def set_label_peaks(self, peaks): pass @property - def sum_intensities(self): return 0.0 + def sum_intensities(self): return np.sum(self._intensities) if self._intensities.size > 0 else 0.0 @property - def sum_masses(self): return 0.0 + def sum_masses(self): return np.sum(self._masses) if self._masses.size > 0 else 0.0 def to_scan(self): return None def to_segmented_scan(self): return None def to_simple_scan(self): return None @@ -1008,37 +1018,41 @@ def valid(self): return 1 class InstrumentData(CommonCoreDataObject): + def __init__(self, handle=0): + self._handle = handle @property - def axis_label_x(self): return get_instrument_axis_label_x() + def axis_label_x(self): return get_instrument_axis_label_x(self._handle) @property - def axis_label_y(self): return get_instrument_axis_label_y() + def axis_label_y(self): return get_instrument_axis_label_y(self._handle) @property def channel_labels(self): return [] def clone(self): return self @property - def flags(self): return get_instrument_flags() + def flags(self): return get_instrument_flags(self._handle) @property - def has_accurate_mass_precursors(self): return get_instrument_has_accurate_mass_precursors() + def has_accurate_mass_precursors(self): return get_instrument_has_accurate_mass_precursors(self._handle) @property - def is_tsq_quantum_file(self): return get_instrument_is_tsq_quantum_file() + def is_tsq_quantum_file(self): return get_instrument_is_tsq_quantum_file(self._handle) @property - def is_valid(self): return get_instrument_is_valid() + def is_valid(self): return get_instrument_is_valid(self._handle) @property - def units(self): return DataUnits(get_instrument_units()) + def units(self): return DataUnits(get_instrument_units(self._handle)) @property - def name(self) -> str: return get_instrument_name() + def name(self) -> str: return get_instrument_name(self._handle) @property - def model(self) -> str: return get_instrument_model() + def model(self) -> str: return get_instrument_model(self._handle) @property - def serial_number(self) -> str: return get_instrument_serial_number() + def serial_number(self) -> str: return get_instrument_serial_number(self._handle) @property - def software_version(self) -> str: return get_instrument_software_version() + def software_version(self) -> str: return get_instrument_software_version(self._handle) @property - def hardware_version(self) -> str: return get_instrument_hardware_version() + def hardware_version(self) -> str: return get_instrument_hardware_version(self._handle) class SampleInformation(CommonCoreDataObject): + def __init__(self, handle=0): + self._handle = handle @property - def barcode(self): return get_sample_barcode() + def barcode(self): return get_sample_barcode(self._handle) @property def barcode_status(self): if _IS_SPHINX: return 0 @@ -1052,18 +1066,16 @@ def calibration_level(self): if _IS_SPHINX: return 0 raise NotImplementedError @property - def comment(self): return get_sample_comment() + def comment(self): return get_sample_comment(self._handle) def deep_copy(self): raise NotImplementedError @property - def dilution_factor(self): return get_sample_dilution_factor() + def dilution_factor(self): return get_sample_dilution_factor(self._handle) @property def injection_volume(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError + return get_sample_injection_volume(self._handle) @property def instrument_method_file(self): - if _IS_SPHINX: return "" - raise NotImplementedError + return get_sample_instrument_method_file(self._handle) @property def istd_amount(self): if _IS_SPHINX: return 0.0 @@ -1077,15 +1089,15 @@ def processing_method_file(self): if _IS_SPHINX: return "" raise NotImplementedError @property - def row_number(self): return get_sample_row_number() + def row_number(self): return get_sample_row_number(self._handle) @property - def sample_id(self): return get_sample_id() + def sample_id(self): return get_sample_id(self._handle) @property - def sample_name(self): return get_sample_name() + def sample_name(self): return get_sample_name(self._handle) @property - def vial(self): return get_sample_vial() + def vial(self): return get_sample_vial(self._handle) @property - def sample_type(self): return SampleType(get_sample_type()) + def sample_type(self): return SampleType(get_sample_type(self._handle)) @property def sample_volume(self): return 0.0 @property @@ -1095,21 +1107,23 @@ def user_text(self): return [] @property def vial(self): return "" @property - def raw_file_name(self) -> str: return get_file_name() + def raw_file_name(self) -> str: return get_file_name(self._handle) + @property + def path(self) -> str: return get_path(self._handle) @property - def path(self) -> str: return get_path() + def autosampler_information(self): return AutoSamplerInformation(self._handle) class FileHeader(CommonCoreDataObject): @property - def creation_date(self) -> str: return get_creation_date() + def creation_date(self) -> str: return get_creation_date(self._handle) @property - def who_created_id(self) -> str: return get_creator_id() + def who_created_id(self) -> str: return get_creator_id(self._handle) @property - def file_description(self): return get_file_description() + def file_description(self): return get_file_description(self._handle) @property def file_type(self): return FileType.RawFile @property - def modified_date(self): return get_modified_date() + def modified_date(self): return get_modified_date(self._handle) @property def number_of_times_calibrated(self): if _IS_SPHINX: return -1 @@ -1123,11 +1137,11 @@ def revision(self): if _IS_SPHINX: return -1 raise NotImplementedError @property - def who_created_logon(self): return get_who_created_logon() + def who_created_logon(self): return get_who_created_logon(self._handle) @property - def who_modified_id(self): return get_who_modified_id() + def who_modified_id(self): return get_who_modified_id(self._handle) @property - def who_modified_logon(self): return get_who_modified_logon() + def who_modified_logon(self): return get_who_modified_logon(self._handle) class FileError(CommonCoreDataObject): @property @@ -1142,43 +1156,39 @@ def has_warning(self): return 0 def warning_message(self): return "" class AutoSamplerInformation(CommonCoreDataObject): + def __init__(self, handle=0): + self._handle = handle @property def tray_index(self): - if _IS_SPHINX: return -1 - raise NotImplementedError + return get_autosampler_tray_index(self._handle) @property def tray_name(self): - if _IS_SPHINX: return "Any" - raise NotImplementedError + return get_autosampler_tray_name(self._handle) @property def tray_shape(self): - if _IS_SPHINX: return TrayShape.Unknown - raise NotImplementedError + return TrayShape(get_autosampler_tray_shape(self._handle)) @property def tray_shape_as_string(self): - if _IS_SPHINX: return "Unknown" - raise NotImplementedError + return str(self.tray_shape) @property def vial_index(self): - if _IS_SPHINX: return -1 - raise NotImplementedError + return get_autosampler_vial_index(self._handle) @property def vials_per_tray(self): - if _IS_SPHINX: return -1 - raise NotImplementedError + return get_autosampler_vials_per_tray(self._handle) @property def vials_per_tray_x(self): - if _IS_SPHINX: return -1 - raise NotImplementedError + return get_autosampler_vials_per_tray_x(self._handle) @property def vials_per_tray_y(self): - if _IS_SPHINX: return -1 - raise NotImplementedError + return get_autosampler_vials_per_tray_y(self._handle) class RunHeader(CommonCoreDataObject): - def __init__(self, raw_file=None): self._raw_file = raw_file + def __init__(self, handle=0, raw_file=None): + self._handle = handle + self._raw_file = raw_file @property - def start_time(self) -> float: return get_start_time() + def start_time(self) -> float: return get_start_time(self._handle) @property def first_spectrum(self) -> int: return self._raw_file.first_scan if self._raw_file else 1 @property @@ -1237,7 +1247,9 @@ def tolerance_unit(self): raise NotImplementedError class RunHeaderEx(CommonCoreDataObject): - def __init__(self, raw_file): self._raw_file = raw_file + def __init__(self, handle=0, raw_file=None): + self._handle = handle + self._raw_file = raw_file @property def spectra_count(self): return self._raw_file.number_of_scans @property @@ -1245,23 +1257,23 @@ def first_spectrum(self): return self._raw_file.first_scan @property def last_spectrum(self): return self._raw_file.last_scan @property - def start_time(self): return get_start_time() + def start_time(self): return get_start_time(self._handle) @property - def end_time(self): return get_end_time() + def end_time(self): return get_end_time(self._handle) @property - def mass_resolution(self): return get_mass_resolution() + def mass_resolution(self): return get_mass_resolution(self._handle) @property - def expected_runtime(self): return get_expected_runtime() + def expected_runtime(self): return get_expected_runtime(self._handle) @property - def max_integrated_intensity(self): return get_max_integrated_intensity() + def max_integrated_intensity(self): return get_max_integrated_intensity(self._handle) @property - def max_intensity(self): return get_max_intensity() + def max_intensity(self): return get_max_intensity(self._handle) @property - def trailer_extra_count(self): return get_trailer_extra_count() + def trailer_extra_count(self): return get_trailer_extra_count(self._handle) @property - def low_mass(self): return get_low_mass() + def low_mass(self): return get_low_mass(self._handle) @property - def high_mass(self): return get_high_mass() + def high_mass(self): return get_high_mass(self._handle) @property def error_message(self): if _IS_SPHINX: return "" @@ -1306,56 +1318,44 @@ def filter_mass_precision(self): raise NotImplementedError @property def high_mass(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError + return get_high_mass(self._handle) @property def in_acquisition(self): - if _IS_SPHINX: return 0 - raise NotImplementedError + return in_acquisition(self._handle) @property def low_mass(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError + return get_low_mass(self._handle) @property def mass_resolution(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError + return get_mass_resolution(self._handle) @property def max_integrated_intensity(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError + return get_max_integrated_intensity(self._handle) @property def max_intensity(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError + return get_max_intensity(self._handle) @property def spectra_count(self): - if _IS_SPHINX: return 0 - raise NotImplementedError + return get_num_scans(self._handle) @property def status_log_count(self): - if _IS_SPHINX: return 0 - raise NotImplementedError + return get_status_log_count(self._handle) @property def trailer_extra_count(self): - if _IS_SPHINX: return 0 - raise NotImplementedError + return get_trailer_extra_count(self._handle) @property def trailer_scan_event_count(self): if _IS_SPHINX: return 0 raise NotImplementedError @property def tune_data_count(self): - if _IS_SPHINX: return 0 - raise NotImplementedError + return get_tune_data_count(self._handle) @property def first_spectrum(self): - if _IS_SPHINX: return 0 - raise NotImplementedError + return get_first_scan(self._handle) @property def last_spectrum(self): - if _IS_SPHINX: return 0 - raise NotImplementedError + return get_last_scan(self._handle) @property def start_time(self): if _IS_SPHINX: return 0.0 @@ -1366,113 +1366,93 @@ def tolerance_unit(self): raise NotImplementedError class ScanEvent(CommonCoreDataObject): - def __init__(self, scan_number=0): + def __init__(self, handle=0, scan_number=0): + self._handle = handle self._scan_number = scan_number @property def ms_order(self): - return MsOrderType(get_scan_event_ms_order(self._scan_number)) + return MsOrderType(get_scan_event_ms_order(self._handle, self._scan_number)) @property def mass_count(self): - return get_scan_event_mass_count(self._scan_number) + return get_scan_event_mass_count(self._handle, self._scan_number) def get_mass(self, index): - return get_scan_event_precursor_mass(self._scan_number, index) + return get_scan_event_precursor_mass(self._handle, self._scan_number, index) def get_activation(self, index): - return ActivationType(get_scan_event_activation_type(self._scan_number, index)) + return ActivationType(get_scan_event_activation_type(self._handle, self._scan_number, index)) def get_energy(self, index): - return get_scan_event_collision_energy(self._scan_number, index) + return get_scan_event_collision_energy(self._handle, self._scan_number, index) def get_reaction(self, index): - return Reaction(self._scan_number, index) + return Reaction(self._handle, self._scan_number, index) @property def name(self): - return get_scan_event_string(self._scan_number) + return get_scan_event_string(self._handle, self._scan_number) @property def accurate_mass(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("accurate_mass") + return EventAccurateMass(get_scan_filter_accurate_mass(self._handle, self._scan_number)) @property def mass_analyzer(self) -> int: - if _IS_SPHINX: return 0 - raise NotImplementedError("mass_analyzer") + return MassAnalyzer(get_scan_filter_mass_analyzer(self._handle, self._scan_number)) @property def polarity(self) -> int: - if _IS_SPHINX: return 1 - raise NotImplementedError("polarity") + return PolarityType(get_scan_filter_polarity(self._handle, self._scan_number)) @property def scan_mode(self) -> int: - if _IS_SPHINX: return 0 - raise NotImplementedError("scan_mode") + return ScanModeType(get_scan_filter_scan_mode(self._handle, self._scan_number)) @property def ionization_mode(self) -> int: - if _IS_SPHINX: return 0 - raise NotImplementedError("ionization_mode") + return IonizationModeType(get_scan_filter_ionization_mode(self._handle, self._scan_number)) @property def is_valid(self) -> bool: - if _IS_SPHINX: return True - raise NotImplementedError("is_valid") + return bool(get_instrument_is_valid(self._handle)) @property def compensation_volt_type(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("compensation_volt_type") + return CompensationVoltageType(get_scan_filter_compensation_volt_type(self._handle, self._scan_number)) @property def compensation_voltage(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("compensation_voltage") + return TriState(get_scan_event_compensation_voltage(self._handle, self._scan_number)) @property def corona(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("corona") + return TriState(get_scan_filter_corona(self._handle, self._scan_number)) @property def dependent(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("dependent") + return TriState(get_scan_filter_dependent(self._handle, self._scan_number)) @property def detector(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("detector") + return DetectorType(get_scan_filter_detector(self._handle, self._scan_number)) @property def detector_value(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("detector_value") + return get_scan_filter_detector_value(self._handle, self._scan_number) @property def electron_capture_dissociation(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("electron_capture_dissociation") + return TriState(get_scan_filter_electron_capture_dissociation(self._handle, self._scan_number)) @property def electron_capture_dissociation_value(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("electron_capture_dissociation_value") + return get_scan_filter_electron_capture_dissociation_value(self._handle, self._scan_number) @property def electron_transfer_dissociation(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("electron_transfer_dissociation") + return TriState(get_scan_filter_electron_transfer_dissociation(self._handle, self._scan_number)) @property def electron_transfer_dissociation_value(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("electron_transfer_dissociation_value") + return get_scan_filter_electron_transfer_dissociation_value(self._handle, self._scan_number) @property def enhanced(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("enhanced") + return TriState(get_scan_filter_enhanced(self._handle, self._scan_number)) @property def field_free_region(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("field_free_region") + return FieldFreeRegionType(get_scan_filter_field_free_region(self._handle, self._scan_number)) @property def higher_energy_ci_d(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("higher_energy_ci_d") + return TriState(get_scan_filter_higher_energy_cid(self._handle, self._scan_number)) @property def higher_energy_ci_d_value(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("higher_energy_ci_d_value") + return get_scan_filter_higher_energy_cid_value(self._handle, self._scan_number) @property def is_custom(self): if _IS_SPHINX: return 0 raise NotImplementedError("is_custom") @property def lock(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("lock") + return TriState(get_scan_filter_lock(self._handle, self._scan_number)) @property def mass_calibrator_count(self): if _IS_SPHINX: return -1 @@ -1483,60 +1463,48 @@ def mass_range_count(self): raise NotImplementedError("mass_range_count") @property def multi_notch(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("multi_notch") + return TriState(get_scan_filter_multi_notch(self._handle, self._scan_number)) @property def multi_state_activation(self): if _IS_SPHINX: return 0 raise NotImplementedError("multi_state_activation") @property def multiple_photon_dissociation(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("multiple_photon_dissociation") + return TriState(get_scan_filter_multiple_photon_dissociation(self._handle, self._scan_number)) @property def multiple_photon_dissociation_value(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("multiple_photon_dissociation_value") + return get_scan_filter_multiple_photon_dissociation_value(self._handle, self._scan_number) @property def multiplex(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("multiplex") + return TriState(get_scan_filter_multiplex(self._handle, self._scan_number)) @property def param_a(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("param_a") + return get_scan_filter_param_a(self._handle, self._scan_number) @property def param_b(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("param_b") + return get_scan_filter_param_b(self._handle, self._scan_number) @property def param_f(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("param_f") + return get_scan_filter_param_f(self._handle, self._scan_number) @property def param_r(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("param_r") + return get_scan_filter_param_r(self._handle, self._scan_number) @property def param_v(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("param_v") + return get_scan_filter_param_v(self._handle, self._scan_number) @property def photo_ionization(self): if _IS_SPHINX: return 0 raise NotImplementedError("photo_ionization") @property def pulsed_q_dissociation(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("pulsed_q_dissociation") + return TriState(get_scan_filter_pulsed_q_dissociation(self._handle, self._scan_number)) @property def pulsed_q_dissociation_value(self): - if _IS_SPHINX: return 0.0 - raise NotImplementedError("pulsed_q_dissociation_value") + return get_scan_filter_pulsed_q_dissociation_value(self._handle, self._scan_number) @property def scan_data(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("scan_data") + return ScanDataType(get_scan_filter_scan_data(self._handle, self._scan_number)) @property def scan_type_index(self): if _IS_SPHINX: return -1 @@ -1547,8 +1515,7 @@ def sector_scan(self): raise NotImplementedError("sector_scan") @property def source_fragmentation(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("source_fragmentation") + return TriState(get_scan_filter_source_fragmentation(self._handle, self._scan_number)) @property def source_fragmentation_info_count(self): if _IS_SPHINX: return -1 @@ -1559,24 +1526,19 @@ def source_fragmentation_mass_range_count(self): raise NotImplementedError("source_fragmentation_mass_range_count") @property def source_fragmentation_type(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("source_fragmentation_type") + return SourceFragmentationValueType(get_scan_filter_source_fragmentation_type(self._handle, self._scan_number)) @property def supplemental_activation(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("supplemental_activation") + return TriState(get_scan_filter_supplemental_activation(self._handle, self._scan_number)) @property def turbo_scan(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("turbo_scan") + return TriState(get_scan_filter_turbo_scan(self._handle, self._scan_number)) @property def ultra(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("ultra") + return TriState(get_scan_filter_ultra(self._handle, self._scan_number)) @property def wideband(self): - if _IS_SPHINX: return 0 - raise NotImplementedError("wideband") + return TriState(get_scan_filter_wideband(self._handle, self._scan_number)) def get_energy_valid(self, index): if _IS_SPHINX: return 0 raise NotImplementedError("get_energy_valid") @@ -1613,10 +1575,9 @@ def get_source_fragmentation_mass_range(self, index): class ScanEvents(CommonCoreDataObject): def get_event(self, index): - if _IS_SPHINX: return ScanEvent() - raise NotImplementedError("get_event") + return ScanEvent(self._handle, index + 1) def get_event_by_segment(self, segment, event): - if _IS_SPHINX: return ScanEvent() + if _IS_SPHINX: return ScanEvent(self._handle) raise NotImplementedError("get_event_by_segment") def get_event_count(self, segment): if _IS_SPHINX: return -1 @@ -1642,8 +1603,12 @@ def low(self): return self._low def high(self): return self._high def compare_to(self, other): - if _IS_SPHINX: return 0 - raise NotImplementedError + if not isinstance(other, Range): return -1 + if self._low < other._low: return -1 + if self._low > other._low: return 1 + if self._high < other._high: return -1 + if self._high > other._high: return 1 + return 0 @staticmethod def create(l, h): return Range(l, h) @staticmethod @@ -1860,4 +1825,4 @@ class business: class filter_enums: ActivationType = ActivationType; CompensationVoltageType = CompensationVoltageType; DetectorType = DetectorType; EnergyType = EnergyType; EventAccurateMass = EventAccurateMass; FieldFreeRegionType = FieldFreeRegionType; IonizationModeType = IonizationModeType; MassAnalyzerType = MassAnalyzer; MsOrderType = MsOrderType; PolarityType = PolarityType; ScanDataType = ScanDataType; ScanModeType = ScanModeType; SectorScanType = SectorScanType; SourceFragmentationValueType = SourceFragmentationValueType; TriState = TriState - activation_type = ActivationType; compensation_voltage_type = CompensationVoltageType; detector_type = DetectorType; energy_type = EnergyType; event_accurate_mass = EventAccurateMass; field_free_region_type = FieldFreeRegionType; ionization_mode_type = IonizationModeType; mass_analyzer_type = MassAnalyzer; ms_order_type = MsOrderType; polarity_type = PolarityType; scan_data_type = ScanDataType; scan_mode_type = ScanModeType; sector_scan_type = SectorScanType; source_fragmentation_value_type = SourceFragmentationValueType; tri_state = TriState + activation_type = ActivationType; compensation_voltage_type = CompensationVoltageType; detector_type = DetectorType; energy_type = EnergyType; event_accurate_mass = EventAccurateMass; field_free_region_type = FieldFreeRegionType; ionization_mode_type = IonizationModeType; mass_analyzer_type = MassAnalyzer; ms_order_type = MsOrderType; polarity_type = PolarityType; scan_data_type = ScanDataType; scan_mode_type = ScanModeType; sector_scan_type = SectorScanType; source_fragmentation_value_type = SourceFragmentationValueType; tri_state = TriState \ No newline at end of file diff --git a/native_fisher_py/python/native_fisher_py/raw_file.py b/native_fisher_py/python/native_fisher_py/raw_file.py index 436ce8d..d21ea87 100644 --- a/native_fisher_py/python/native_fisher_py/raw_file.py +++ b/native_fisher_py/python/native_fisher_py/raw_file.py @@ -44,9 +44,11 @@ def __init__(self, path: str): self._path = path if not os.path.isfile(path): raise FileNotFoundError(f'No raw file with path "{path}" found.') - res = open_raw_file(path) - if res != 0: + abs_path = os.path.abspath(path) + res = open_raw_file(abs_path) + if res == -1: raise RawFileException(f"Could not open RAW file: {path}") + self._handle = res self._is_open = True @staticmethod @@ -58,7 +60,7 @@ def _raw_file_access(self): return self def select_instrument(self, device_type: int, device_number: int): - pass + select_instrument(self._handle, device_type, device_number) def average_scans(self, start, end): return None def average_scans_in_scan_range(self, start, end, options): return None @@ -66,12 +68,15 @@ def average_scans_in_scan_range(self, start, end, options): return None def default_mass_options(self): return MassOptions() def dispose(self): self.close() def get_all_instrument_names_from_instrument_method(self): return [] - def get_instrument_method(self, index): return "" + def get_instrument_method(self, index): + return get_instrument_method(self._handle, index) + def get_instrument_methods_count(self) -> int: + return get_instrument_method_count(self._handle) def get_instrument_type(self): return 0 def get_segment_event_table(self): return [] - def has_instrument_method(self): return False + def has_instrument_method(self): return self.get_instrument_methods_count() > 0 def is_centroid_scan_from_scan_number(self, scan_number): - return is_centroid(scan_number) + return is_centroid(self._handle, scan_number) def refresh_view_of_file(self): pass @property def selected_instrument(self): return 0 @@ -83,42 +88,42 @@ def user_label(self) -> List[str]: @property def scan_events(self) -> List[str]: - return [self.get_scan_event_string_for_scan_number(i) for i in range(self.first_scan, min(self.first_scan + 10, self.last_scan + 1))] + return [self.get_scan_event_string_for_scan_number(self._handle, i) for i in range(self.first_scan, min(self.first_scan + 10, self.last_scan + 1))] def __repr__(self): return f"" @property def path(self) -> str: - return get_path() + return self._path @property def number_of_scans(self) -> int: - return get_num_scans() + return get_num_scans(self._handle) @property def first_scan(self) -> int: - return get_first_scan() + return get_first_scan(self._handle) @property def last_scan(self) -> int: - return get_last_scan() + return get_last_scan(self._handle) @property def file_name(self) -> str: - return get_file_name() + return get_file_name(self._handle) @property def creation_date(self) -> str: - return get_creation_date() + return get_creation_date(self._handle) @property def computer_name(self) -> str: - return get_computer_name() + return get_computer_name(self._handle) @property def creator_id(self) -> str: - return get_creator_id() + return get_creator_id(self._handle) def get_instrument_data(self) -> InstrumentData: return InstrumentData() @@ -133,7 +138,7 @@ def run_header_ex(self) -> RunHeaderEx: @property def sample_information(self) -> SampleInformation: - return SampleInformation() + return SampleInformation(self._handle) @property def instrument_selection(self) -> InstrumentSelection: @@ -149,7 +154,7 @@ def file_error(self) -> FileError: @property def auto_sampler_information(self): - return AutoSamplerInformation() + return AutoSamplerInformation(self._handle) @property def include_reference_and_exception_data(self) -> bool: @@ -161,54 +166,66 @@ def include_reference_and_exception_data(self, value: bool): @property def is_open(self) -> bool: - return is_open() + return is_open(self._handle) @property def is_error(self) -> bool: - return is_error() + return is_error(self._handle) @property def in_acquisition(self) -> bool: - return in_acquisition() + return in_acquisition(self._handle) def retention_time_from_scan_number(self, scan_number: int) -> float: - return get_scan_rt(scan_number) + return get_scan_rt(self._handle, scan_number) def scan_number_from_retention_time(self, rt: float) -> int: - return get_scan_number_from_rt(rt) + return get_scan_number_from_rt(self._handle, rt) def get_scan_event_for_scan_number(self, scan_number: int): from .data.classes import ScanEvent - return ScanEvent(scan_number) + return ScanEvent(self._handle, scan_number) def get_status_log_for_retention_time(self, rt: float): from .data.classes import LogEntry scan = self.scan_number_from_retention_time(rt) - return LogEntry(get_status_log_values(scan)) + return LogEntry(get_status_log_values(self._handle, scan)) def get_status_log_for_scan_number(self, scan_number: int): from .data.classes import LogEntry - return LogEntry(get_status_log_values(scan_number)) + return LogEntry(get_status_log_values(self._handle, scan_number)) def get_scan_event_string_for_scan_number(self, scan_number: int): - return get_scan_event_string(scan_number) + return get_scan_event_string(self._handle, scan_number) def get_centroid_stream(self, scan_number: int, include_ref_peaks: bool = False): from .native_fisher_py_backend import get_centroid_stream from .data.classes import CentroidStream - masses, intensities = get_centroid_stream(scan_number, 1000000) - return CentroidStream(masses=masses, intensities=intensities) + import numpy as np + + masses, intensities, baselines, noises, charges, bp_noise, bp_res = get_centroid_stream(self._handle, scan_number, 1000000) + + return CentroidStream( + masses=np.array(masses), + intensities=np.array(intensities), + baselines=np.array(baselines), + noises=np.array(noises), + charges=np.array(charges), + base_peak_noise=bp_noise, + base_peak_resolution=bp_res, + scan_number=scan_number + ) def get_segmented_scan_from_scan_number(self, scan_number: int, stats = None): from .native_fisher_py_backend import get_spectrum from .data.classes import SegmentedScan - masses, intensities = get_spectrum(scan_number, 1000000) + masses, intensities = get_spectrum(self._handle, scan_number, 1000000) return SegmentedScan(masses=masses, intensities=intensities) def get_scan_stats_for_scan_number(self, scan_number: int): from .data.classes import ScanStatistics from .native_fisher_py_backend import get_scan_stats - data = get_scan_stats(scan_number) + data = get_scan_stats(self._handle, scan_number) return ScanStatistics( start_time=data[0], low_mass=data[1], @@ -216,7 +233,8 @@ def get_scan_stats_for_scan_number(self, scan_number: int): tic=data[3], base_peak_mass=data[4], base_peak_intensity=data[5], - packet_count=int(data[6]) + packet_count=int(data[6]), + is_centroid_scan=bool(data[7]) ) def get_chromatogram_data(self, settings, start_scan, end_scan, tolerance = None): @@ -234,7 +252,7 @@ def get_chromatogram_data(self, settings, start_scan, end_scan, tolerance = None starts = [float(r.low) for r in s.mass_ranges] ends = [float(r.high) for r in s.mass_ranges] - times, intensities = get_chromatogram(trace_type, filter_str, starts, ends, start_scan, end_scan, 1000000) + times, intensities = get_chromatogram(self._handle, trace_type, filter_str, starts, ends, start_scan, end_scan, 1000000) all_times.append(times) all_intensities.append(intensities) all_scans.append([]) # Empty scans for now @@ -242,50 +260,56 @@ def get_chromatogram_data(self, settings, start_scan, end_scan, tolerance = None return ChromatogramData(all_times, all_intensities, all_scans) def get_instrument_count_of_type(self, device_type): - return get_instrument_count_of_type(device_type) + return get_instrument_count_of_type(self._handle, device_type) def get_trailer_extra_information(self, scan_number): from .data.classes import LogEntry labels = [h.label for h in self.get_trailer_extra_header_information()] - return LogEntry(get_trailer_extra_values(scan_number), labels) + values = get_trailer_extra_values(self._handle, scan_number) + return LogEntry(values, labels) def get_trailer_extra_header_information(self): from .data.classes import HeaderItem - return [HeaderItem(h) for h in get_trailer_extra_header()] + return [HeaderItem(h) for h in get_trailer_extra_header(self._handle)] - def get_trailer_extra_values(self, scan_number, formatted=False): - return get_trailer_extra_values(scan_number) + def get_trailer_extra_values(self, scan_number): + return get_trailer_extra_values(self._handle, scan_number) def get_status_log_header_information(self): from .data.classes import HeaderItem - return [HeaderItem(h) for h in get_status_log_header()] + return [HeaderItem(h) for h in get_status_log_header(self._handle)] - def get_status_log_values(self, scan_number, formatted=False): + def get_status_log_values(self, scan_number): from .data.classes import LogEntry labels = [h.label for h in self.get_status_log_header_information()] - return LogEntry(get_status_log_values(scan_number), labels) + values = get_status_log_values(self._handle, scan_number) + return LogEntry(values, labels) def get_status_log_entries_count(self): - return get_status_log_count() + return get_status_log_count(self._handle) def get_status_log_for_retention_time(self, rt): from .data.classes import LogEntry - labels = [h.label for h in self.get_status_log_header_information()] - return LogEntry(get_status_log_values_for_rt(rt), labels) + labels = [h.label for h in self.get_status_log_header_information(self._handle)] + return LogEntry(get_status_log_values_for_rt(self._handle, rt), labels) def get_tune_data_count(self): - return get_tune_data_count() + return get_tune_data_count(self._handle) def get_tune_data(self, index): return None def get_filters(self): return get_filters() def get_auto_filters(self): return [] + def select_instrument(self, device_type: int, instrument_index: int = 1): + from .native_fisher_py_backend import select_instrument + select_instrument(self._handle, device_type, instrument_index) + def get_filter_for_scan_number(self, scan_number): from .data.classes import ScanFilter - return ScanFilter(scan_number) + return ScanFilter(self._handle, scan_number) def get_scan_events(self, start, end): return [] def get_scan_dependents(self, scan_number, precision): return ScanDependents() @property def has_ms_data(self) -> bool: - return has_ms_data() + return has_ms_data(self._handle) def get_scan_type(self, scan_number: int): return "" @@ -307,46 +331,46 @@ def instrument_methods_count(self) -> int: @property def instrument_count(self) -> int: - return get_instrument_count() + return get_instrument_count(self._handle) @property def total_time_min(self) -> float: - return get_end_time() + return get_end_time(self._handle) def get_chromatogram(self, mass: float = 0.0, tolerance: float = 0.0, trace_type: int = 1, ms_filter: str = 'ms') -> Tuple[np.ndarray, np.ndarray]: starts = [mass - tolerance] if mass > 0 else [] ends = [mass + tolerance] if mass > 0 else [] - times, intensities = get_chromatogram(int(trace_type), ms_filter, starts, ends, -1, -1, 1000000) + times, intensities = get_chromatogram(self._handle, int(trace_type), ms_filter, starts, ends, -1, -1, 1000000) return np.array(times), np.array(intensities) def get_averaged_ms2_scans(self, scan_numbers: List[int]) -> Tuple[np.ndarray, np.ndarray, int]: if not scan_numbers: return np.array([]), np.array([]), 0 - masses, intensities = get_averaged_spectrum(scan_numbers, 1000000) + masses, intensities = get_averaged_spectrum(self._handle, scan_numbers, 1000000) return np.array(masses), np.array(intensities), scan_numbers[0] def get_ms1_scan_number_from_retention_time(self, rt: float) -> Tuple[int, float]: - scan_number = get_ms1_scan_number_from_rt(rt) + scan_number = get_ms1_scan_number_from_rt(self._handle, rt) if scan_number < 1: return 0, 0.0 return scan_number, self.retention_time_from_scan_number(scan_number) def get_ms2_scan_number_from_retention_time(self, rt: float, precursor_mz: float = None) -> Tuple[int, float]: pmz = precursor_mz if precursor_mz is not None else 0.0 - scan_number = get_ms2_scan_number_from_rt(rt, pmz, 1.0) + scan_number = get_ms2_scan_number_from_rt(self._handle, rt, pmz, 1.0) if scan_number < 1: return 0, 0.0 return scan_number, self.retention_time_from_scan_number(scan_number) def get_scan_event_str_from_scan_number(self, scan_number: int) -> str: - return self.get_scan_event_string_for_scan_number(scan_number) + return self.get_scan_event_string_for_scan_number(self._handle, scan_number) def get_retention_time_from_scan_number(self, scan_number: int) -> float: return self.retention_time_from_scan_number(scan_number) def get_scan(self, scan_number: int): - return self.get_scan_from_scan_number(scan_number) + return self.get_scan_from_scan_number(self._handle, scan_number) def get_scan_ms1(self, scan_number: int): - return self.get_scan_from_scan_number(scan_number) + return self.get_scan_from_scan_number(self._handle, scan_number) def get_scan_ms2(self, *args): if len(args) == 1: @@ -367,23 +391,23 @@ def ms2_filter_masses(self) -> List[float]: if not hasattr(self, "_ms2_filter_masses_cache"): mass_set = set() for i in range(self.first_scan, self.last_scan + 1): - if get_ms_order(i) == 2: - mass_set.add(get_precursor_mass(i)) + if get_ms_order(self._handle, i) == 2: + mass_set.add(get_precursor_mass(self._handle, i)) self._ms2_filter_masses_cache = sorted(list(mass_set)) return self._ms2_filter_masses_cache def get_precursor_mz(self, scan_number: int) -> float: - return get_precursor_mass(scan_number) + return get_precursor_mass(self._handle, scan_number) def get_scan_from_scan_number(self, scan_number: int): # Use get_centroid_stream to match behavior for parity - masses, intensities = get_centroid_stream(scan_number, 1000000) + masses, intensities, _, _, _, _, _ = get_centroid_stream(self._handle, scan_number, 1000000) charges = np.zeros_like(masses) event_str = self.get_scan_event_string_for_scan_number(scan_number) return np.array(masses), np.array(intensities), charges, event_str def get_scan_number_from_retention_time(self, rt: float) -> int: - return get_scan_number_from_rt(rt) + return get_scan_number_from_rt(self._handle, rt) def __enter__(self): return self @@ -392,4 +416,4 @@ def __exit__(self, exc_type, exc_val, exc_tb): self.close() def close(self): - close_raw_file() + close_raw_file(self._handle) diff --git a/native_fisher_py/python/native_fisher_py/utils/gradient.py b/native_fisher_py/python/native_fisher_py/utils/gradient.py new file mode 100644 index 0000000..a7d4a25 --- /dev/null +++ b/native_fisher_py/python/native_fisher_py/utils/gradient.py @@ -0,0 +1,53 @@ +import re +from typing import List, Tuple + +def parse_vanquish_neo_gradient(method_text: str) -> dict: + """ + Parses Vanquish Neo style pump lines from instrument method text. + Supports both standard text summary and XML-like structured data. + Returns a dictionary with 'solvents' and 'gradient'. + """ + results = { + "solvents": {"A": None, "B": None}, + "gradient": [] + } + + # 1. Try standard text format + # Extract Solvents + a_match = re.search(r'Pump\.%A_Solvent:\s+(.*)', method_text) + if a_match: + results["solvents"]["A"] = a_match.group(1).strip() + + b_match = re.search(r'Pump\.%B_Solvent:\s+(.*)', method_text) + if b_match: + results["solvents"]["B"] = b_match.group(1).strip() + + # Split by time points like "71.800 [min]" + segments = re.split(r'(\d+\.\d+)\s+\[min\]', method_text) + current_time = None + for part in segments: + if re.match(r'^\d+\.\d+$', part): + current_time = float(part) + elif current_time is not None: + match = re.search(r'Pump\.%B\.Value:\s+(\d+\.\d+)\s+\[%\]', part) + if match: + percent_b = float(match.group(1)) + results["gradient"].append((current_time, percent_b)) + + if results["gradient"]: + return results + + # 2. Try XML-like format (found in some Astral files) + # + # + + parts = re.split(r'', method_text) + for part in parts: + time_match = re.search(r'