masster 0.4.0__py3-none-any.whl → 0.4.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (54) hide show
  1. masster/__init__.py +8 -8
  2. masster/_version.py +1 -1
  3. masster/chromatogram.py +3 -9
  4. masster/data/libs/README.md +1 -1
  5. masster/data/libs/ccm.csv +120 -120
  6. masster/data/libs/ccm.py +116 -62
  7. masster/data/libs/central_carbon_README.md +1 -1
  8. masster/data/libs/urine.py +161 -65
  9. masster/data/libs/urine_metabolites.csv +4693 -4693
  10. masster/data/wiff/2025_01_14_VW_7600_LpMx_DBS_CID_2min_TOP15_030msecMS1_005msecReac_CE35_DBS-ON_3.mzML +2 -2
  11. masster/logger.py +43 -78
  12. masster/sample/__init__.py +1 -1
  13. masster/sample/adducts.py +264 -338
  14. masster/sample/defaults/find_adducts_def.py +8 -21
  15. masster/sample/defaults/find_features_def.py +1 -6
  16. masster/sample/defaults/get_spectrum_def.py +1 -5
  17. masster/sample/defaults/sample_def.py +1 -5
  18. masster/sample/h5.py +282 -561
  19. masster/sample/helpers.py +75 -131
  20. masster/sample/lib.py +17 -42
  21. masster/sample/load.py +17 -31
  22. masster/sample/parameters.py +2 -6
  23. masster/sample/plot.py +27 -88
  24. masster/sample/processing.py +87 -117
  25. masster/sample/quant.py +51 -57
  26. masster/sample/sample.py +90 -103
  27. masster/sample/sample5_schema.json +44 -44
  28. masster/sample/save.py +12 -35
  29. masster/sample/sciex.py +19 -66
  30. masster/spectrum.py +20 -58
  31. masster/study/__init__.py +1 -1
  32. masster/study/defaults/align_def.py +1 -5
  33. masster/study/defaults/fill_chrom_def.py +1 -5
  34. masster/study/defaults/fill_def.py +1 -5
  35. masster/study/defaults/integrate_chrom_def.py +1 -5
  36. masster/study/defaults/integrate_def.py +1 -5
  37. masster/study/defaults/study_def.py +25 -58
  38. masster/study/export.py +207 -233
  39. masster/study/h5.py +136 -470
  40. masster/study/helpers.py +202 -495
  41. masster/study/helpers_optimized.py +13 -40
  42. masster/study/id.py +110 -213
  43. masster/study/load.py +143 -230
  44. masster/study/plot.py +257 -518
  45. masster/study/processing.py +257 -469
  46. masster/study/save.py +5 -15
  47. masster/study/study.py +276 -379
  48. masster/study/study5_schema.json +96 -96
  49. {masster-0.4.0.dist-info → masster-0.4.1.dist-info}/METADATA +1 -1
  50. masster-0.4.1.dist-info/RECORD +67 -0
  51. masster-0.4.0.dist-info/RECORD +0 -67
  52. {masster-0.4.0.dist-info → masster-0.4.1.dist-info}/WHEEL +0 -0
  53. {masster-0.4.0.dist-info → masster-0.4.1.dist-info}/entry_points.txt +0 -0
  54. {masster-0.4.0.dist-info → masster-0.4.1.dist-info}/licenses/LICENSE +0 -0
@@ -8,14 +8,13 @@ import pyopenms as oms
8
8
 
9
9
  from tqdm import tqdm
10
10
 
11
- from master.spectrum import Spectrum
11
+ from masster.spectrum import Spectrum
12
12
  from .defaults.find_features_def import find_features_defaults
13
13
  from .defaults.find_ms2_def import find_ms2_defaults
14
14
  from .defaults.get_spectrum_def import get_spectrum_defaults
15
15
 
16
16
 
17
- from master.chromatogram import Chromatogram
18
-
17
+ from masster.chromatogram import Chromatogram
19
18
 
20
19
  def get_spectrum(self, scan, **kwargs):
21
20
  """Retrieve a single spectrum and optionally post-process it.
@@ -253,8 +252,7 @@ def get_spectrum(self, scan, **kwargs):
253
252
  spec=spect,
254
253
  scan_uid=scan_uid,
255
254
  feature_uid=scan_info["feature_uid"][0]
256
- if "feature_uid" in scan_info
257
- and scan_info["feature_uid"][0] is not None
255
+ if "feature_uid" in scan_info and scan_info["feature_uid"][0] is not None
258
256
  else feature_uid,
259
257
  q1_step=2,
260
258
  deisotope=deisotope,
@@ -447,9 +445,7 @@ def _spec_to_mat(
447
445
  closest_index = np.argmin(np.abs(ar2 - val1))
448
446
  closest_indices.append((i, closest_index))
449
447
  # filter out pairs that are not within the specified tolerance
450
- closest_indices = [
451
- (i, j) for i, j in closest_indices if np.abs(ar1[i] - ar2[j]) <= tol
452
- ]
448
+ closest_indices = [(i, j) for i, j in closest_indices if np.abs(ar1[i] - ar2[j]) <= tol]
453
449
  # remove duplicates from the list of indices
454
450
  closest_indices = list(set(closest_indices))
455
451
  # sort the list of indices by the first element (i) in ascending order
@@ -568,13 +564,9 @@ def find_features(self, **kwargs):
568
564
  import os
569
565
 
570
566
  os.environ["OMP_NUM_THREADS"] = str(params.threads)
571
- self.logger.debug(
572
- f"Set thread count to {params.threads} via OMP_NUM_THREADS",
573
- )
567
+ self.logger.debug(f"Set thread count to {params.threads} via OMP_NUM_THREADS")
574
568
  except Exception:
575
- self.logger.warning(
576
- f"Could not set thread count to {params.threads} - using default",
577
- )
569
+ self.logger.warning(f"Could not set thread count to {params.threads} - using default")
578
570
 
579
571
  # Set debug mode if enabled
580
572
  if hasattr(params, "debug") and params.debug:
@@ -615,8 +607,7 @@ def find_features(self, **kwargs):
615
607
  mtd_par.setValue("noise_threshold_int", float(params.get("noise")))
616
608
  mtd_par.setValue(
617
609
  "min_trace_length",
618
- float(params.get("min_trace_length_multiplier"))
619
- * float(params.get("chrom_fwhm_min")),
610
+ float(params.get("min_trace_length_multiplier")) * float(params.get("chrom_fwhm_min")),
620
611
  )
621
612
  mtd_par.setValue(
622
613
  "trace_termination_outliers",
@@ -627,14 +618,8 @@ def find_features(self, **kwargs):
627
618
  # Additional MTD parameters
628
619
  mtd_par.setValue("min_sample_rate", float(params.get("min_sample_rate")))
629
620
  mtd_par.setValue("min_trace_length", float(params.get("min_trace_length")))
630
- mtd_par.setValue(
631
- "trace_termination_criterion",
632
- params.get("trace_termination_criterion"),
633
- )
634
- mtd_par.setValue(
635
- "reestimate_mt_sd",
636
- "true" if params.get("reestimate_mt_sd") else "false",
637
- )
621
+ mtd_par.setValue("trace_termination_criterion", params.get("trace_termination_criterion"))
622
+ mtd_par.setValue("reestimate_mt_sd", "true" if params.get("reestimate_mt_sd") else "false")
638
623
  mtd_par.setValue("quant_method", params.get("quant_method"))
639
624
 
640
625
  mtd.setParameters(mtd_par) # set the new parameters
@@ -703,7 +688,7 @@ def find_features(self, **kwargs):
703
688
  df = feature_map.get_df(export_peptide_identifications=False) # type: ignore[attr-defined]
704
689
  # Sets the file path to the primary MS run (usually the mzML file)
705
690
  feature_map.setPrimaryMSRunPath([self.file_path.encode()])
706
-
691
+
707
692
  # Store feature map in both attributes for compatibility
708
693
  self.features = feature_map
709
694
  self._oms_features_map = feature_map
@@ -784,15 +769,13 @@ def find_features(self, **kwargs):
784
769
  height_scaleds.append(None)
785
770
 
786
771
  # Add the computed columns to the dataframe
787
- df = df.with_columns(
788
- [
789
- pl.Series("chrom", chroms, dtype=pl.Object),
790
- pl.Series("chrom_coherence", coherences, dtype=pl.Float64),
791
- pl.Series("chrom_prominence", prominences, dtype=pl.Float64),
792
- pl.Series("chrom_prominence_scaled", prominence_scaleds, dtype=pl.Float64),
793
- pl.Series("chrom_height_scaled", height_scaleds, dtype=pl.Float64),
794
- ],
795
- )
772
+ df = df.with_columns([
773
+ pl.Series("chrom", chroms, dtype=pl.Object),
774
+ pl.Series("chrom_coherence", coherences, dtype=pl.Float64),
775
+ pl.Series("chrom_prominence", prominences, dtype=pl.Float64),
776
+ pl.Series("chrom_prominence_scaled", prominence_scaleds, dtype=pl.Float64),
777
+ pl.Series("chrom_height_scaled", height_scaleds, dtype=pl.Float64),
778
+ ])
796
779
 
797
780
  self.features_df = df
798
781
  self._features_sync()
@@ -813,10 +796,10 @@ def find_features(self, **kwargs):
813
796
  def _clean_features_df(self, df):
814
797
  """Clean and standardize features DataFrame."""
815
798
  # Convert pandas DataFrame to polars if needed
816
- if hasattr(df, "index"): # pandas DataFrame
799
+ if hasattr(df, 'index'): # pandas DataFrame
817
800
  df = df.copy()
818
801
  df["feature_id"] = df.index
819
-
802
+
820
803
  if hasattr(df, "columns") and not isinstance(df, pl.DataFrame):
821
804
  df_pl = pl.from_pandas(df)
822
805
  else:
@@ -826,37 +809,35 @@ def _clean_features_df(self, df):
826
809
  df2 = df_pl.filter(pl.col("quality") != 0)
827
810
 
828
811
  # Create new dataframe with required columns and transformations
829
- df_result = df2.select(
830
- [
831
- pl.int_range(pl.len()).alias("feature_uid"),
832
- pl.col("feature_id").cast(pl.String).alias("feature_id"),
833
- pl.col("mz").round(5),
834
- pl.col("RT").round(3).alias("rt"),
835
- pl.col("RT").round(3).alias("rt_original"),
836
- pl.col("RTstart").round(3).alias("rt_start"),
837
- pl.col("RTend").round(3).alias("rt_end"),
838
- (pl.col("RTend") - pl.col("RTstart")).round(3).alias("rt_delta"),
839
- pl.col("MZstart").round(5).alias("mz_start"),
840
- pl.col("MZend").round(5).alias("mz_end"),
841
- pl.col("intensity").alias("inty"),
842
- pl.col("quality"),
843
- pl.col("charge"),
844
- pl.lit(0).alias("iso"),
845
- pl.lit(None, dtype=pl.Int64).alias("iso_of"),
846
- pl.lit(None, dtype=pl.Utf8).alias("adduct"),
847
- pl.lit(None, dtype=pl.Float64).alias("adduct_charge"),
848
- pl.lit(None, dtype=pl.Float64).alias("adduct_mass_shift"),
849
- pl.lit(None, dtype=pl.Float64).alias("adduct_mass_neutral"),
850
- pl.lit(None, dtype=pl.Int64).alias("adduct_group"),
851
- pl.lit(None, dtype=pl.Object).alias("chrom"),
852
- pl.lit(None, dtype=pl.Float64).alias("chrom_coherence"),
853
- pl.lit(None, dtype=pl.Float64).alias("chrom_prominence"),
854
- pl.lit(None, dtype=pl.Float64).alias("chrom_prominence_scaled"),
855
- pl.lit(None, dtype=pl.Float64).alias("chrom_height_scaled"),
856
- pl.lit(None, dtype=pl.Object).alias("ms2_scans"),
857
- pl.lit(None, dtype=pl.Object).alias("ms2_specs"),
858
- ],
859
- )
812
+ df_result = df2.select([
813
+ pl.int_range(pl.len()).alias("feature_uid"),
814
+ pl.col("feature_id").cast(pl.String).alias("feature_id"),
815
+ pl.col("mz").round(5),
816
+ pl.col("RT").round(3).alias("rt"),
817
+ pl.col("RT").round(3).alias("rt_original"),
818
+ pl.col("RTstart").round(3).alias("rt_start"),
819
+ pl.col("RTend").round(3).alias("rt_end"),
820
+ (pl.col("RTend") - pl.col("RTstart")).round(3).alias("rt_delta"),
821
+ pl.col("MZstart").round(5).alias("mz_start"),
822
+ pl.col("MZend").round(5).alias("mz_end"),
823
+ pl.col("intensity").alias("inty"),
824
+ pl.col("quality"),
825
+ pl.col("charge"),
826
+ pl.lit(0).alias("iso"),
827
+ pl.lit(None, dtype=pl.Int64).alias("iso_of"),
828
+ pl.lit(None, dtype=pl.Utf8).alias("adduct"),
829
+ pl.lit(None, dtype=pl.Float64).alias("adduct_charge"),
830
+ pl.lit(None, dtype=pl.Float64).alias("adduct_mass_shift"),
831
+ pl.lit(None, dtype=pl.Float64).alias("adduct_mass_neutral"),
832
+ pl.lit(None, dtype=pl.Int64).alias("adduct_group"),
833
+ pl.lit(None, dtype=pl.Object).alias("chrom"),
834
+ pl.lit(None, dtype=pl.Float64).alias("chrom_coherence"),
835
+ pl.lit(None, dtype=pl.Float64).alias("chrom_prominence"),
836
+ pl.lit(None, dtype=pl.Float64).alias("chrom_prominence_scaled"),
837
+ pl.lit(None, dtype=pl.Float64).alias("chrom_height_scaled"),
838
+ pl.lit(None, dtype=pl.Object).alias("ms2_scans"),
839
+ pl.lit(None, dtype=pl.Object).alias("ms2_specs"),
840
+ ])
860
841
 
861
842
  return df_result
862
843
 
@@ -878,12 +859,10 @@ def _features_deisotope(
878
859
  df = pl.from_pandas(df)
879
860
 
880
861
  # Initialize new columns
881
- df = df.with_columns(
882
- [
883
- pl.lit(0).alias("iso"),
884
- pl.col("feature_uid").alias("iso_of"),
885
- ],
886
- )
862
+ df = df.with_columns([
863
+ pl.lit(0).alias("iso"),
864
+ pl.col("feature_uid").alias("iso_of"),
865
+ ])
887
866
 
888
867
  # Sort by 'mz'
889
868
  df = df.sort("mz")
@@ -910,13 +889,13 @@ def _features_deisotope(
910
889
  for isotope_offset in [1, 2, 3]:
911
890
  offset_mz = isotope_offset * mz_diff
912
891
  tolerance_factor = 1.0 if isotope_offset == 1 else 1.5
913
-
892
+
914
893
  t_lower = base_mz + offset_mz - tolerance_factor * mz_tol
915
894
  t_upper = base_mz + offset_mz + tolerance_factor * mz_tol
916
-
895
+
917
896
  li = np.searchsorted(mz_arr, t_lower, side="left")
918
897
  ri = np.searchsorted(mz_arr, t_upper, side="right")
919
-
898
+
920
899
  if li < ri:
921
900
  cand_idx = np.arange(li, ri)
922
901
  mask = (
@@ -925,23 +904,22 @@ def _features_deisotope(
925
904
  & (intensity_arr[cand_idx] < 2 * base_int)
926
905
  )
927
906
  valid_cand = cand_idx[mask]
928
-
907
+
929
908
  for cand in valid_cand:
930
909
  if cand != i and iso_of_arr[cand] == feature_uid_arr[cand]:
931
910
  iso_arr[cand] = iso_arr[i] + isotope_offset
932
911
  iso_of_arr[cand] = base_feature_uid
933
912
 
934
913
  # Update the dataframe with isotope assignments
935
- df = df.with_columns(
936
- [
937
- pl.Series("iso", iso_arr),
938
- pl.Series("iso_of", iso_of_arr),
939
- ],
940
- )
914
+ df = df.with_columns([
915
+ pl.Series("iso", iso_arr),
916
+ pl.Series("iso_of", iso_of_arr),
917
+ ])
941
918
 
942
919
  return df
943
920
 
944
921
 
922
+
945
923
  def analyze_dda(self):
946
924
  # Preallocate variables
947
925
  cycle_records = []
@@ -1128,9 +1106,7 @@ def find_ms2(self, **kwargs):
1128
1106
  feature_rt_start = features_subset.select("rt_start").to_numpy().flatten()
1129
1107
  feature_rt_end = features_subset.select("rt_end").to_numpy().flatten()
1130
1108
  feature_uids = features_subset.select("feature_uid").to_numpy().flatten()
1131
- feature_indices = (
1132
- features_subset.with_row_index().select("index").to_numpy().flatten()
1133
- )
1109
+ feature_indices = features_subset.with_row_index().select("index").to_numpy().flatten()
1134
1110
 
1135
1111
  # Pre-compute RT radius for all features
1136
1112
  rt_radius = np.minimum(feature_rt - feature_rt_start, feature_rt_end - feature_rt)
@@ -1183,17 +1159,15 @@ def find_ms2(self, **kwargs):
1183
1159
 
1184
1160
  scan_uids = ms2_index_arr[final_indices].tolist()
1185
1161
  scan_uid_lists.append(scan_uids)
1186
- spec_lists.append(
1187
- [
1188
- self.get_spectrum(
1189
- scan_uids[0],
1190
- centroid=centroid,
1191
- deisotope=deisotope,
1192
- dia_stats=dia_stats,
1193
- feature_uid=feature_uid,
1194
- ),
1195
- ],
1196
- )
1162
+ spec_lists.append([
1163
+ self.get_spectrum(
1164
+ scan_uids[0],
1165
+ centroid=centroid,
1166
+ deisotope=deisotope,
1167
+ dia_stats=dia_stats,
1168
+ feature_uid=feature_uid,
1169
+ ),
1170
+ ])
1197
1171
 
1198
1172
  # Collect updates for batch processing
1199
1173
  updated_feature_uids.extend([feature_uid] * len(final_indices))
@@ -1207,13 +1181,11 @@ def find_ms2(self, **kwargs):
1207
1181
  features_df = pl.from_pandas(features_df)
1208
1182
 
1209
1183
  # Update the features_df
1210
- update_df = pl.DataFrame(
1211
- {
1212
- "temp_idx": feature_indices,
1213
- "ms2_scans": pl.Series("ms2_scans", scan_uid_lists, dtype=pl.Object),
1214
- "ms2_specs": pl.Series("ms2_specs", spec_lists, dtype=pl.Object),
1215
- },
1216
- )
1184
+ update_df = pl.DataFrame({
1185
+ "temp_idx": feature_indices,
1186
+ "ms2_scans": pl.Series("ms2_scans", scan_uid_lists, dtype=pl.Object),
1187
+ "ms2_specs": pl.Series("ms2_specs", spec_lists, dtype=pl.Object),
1188
+ })
1217
1189
 
1218
1190
  # Join and update
1219
1191
  features_df = (
@@ -1224,18 +1196,16 @@ def find_ms2(self, **kwargs):
1224
1196
  how="left",
1225
1197
  suffix="_new",
1226
1198
  )
1227
- .with_columns(
1228
- [
1229
- pl.when(pl.col("ms2_scans_new").is_not_null())
1230
- .then(pl.col("ms2_scans_new"))
1231
- .otherwise(pl.col("ms2_scans"))
1232
- .alias("ms2_scans"),
1233
- pl.when(pl.col("ms2_specs_new").is_not_null())
1234
- .then(pl.col("ms2_specs_new"))
1235
- .otherwise(pl.col("ms2_specs"))
1236
- .alias("ms2_specs"),
1237
- ],
1238
- )
1199
+ .with_columns([
1200
+ pl.when(pl.col("ms2_scans_new").is_not_null())
1201
+ .then(pl.col("ms2_scans_new"))
1202
+ .otherwise(pl.col("ms2_scans"))
1203
+ .alias("ms2_scans"),
1204
+ pl.when(pl.col("ms2_specs_new").is_not_null())
1205
+ .then(pl.col("ms2_specs_new"))
1206
+ .otherwise(pl.col("ms2_specs"))
1207
+ .alias("ms2_specs"),
1208
+ ])
1239
1209
  .drop(["temp_idx", "ms2_scans_new", "ms2_specs_new"])
1240
1210
  )
1241
1211
 
@@ -1272,4 +1242,4 @@ def find_ms2(self, **kwargs):
1272
1242
  self.store_history(["find_ms2"], params.to_dict())
1273
1243
  self.logger.debug(
1274
1244
  "Parameters stored to find_ms2",
1275
- )
1245
+ )
masster/sample/quant.py CHANGED
@@ -53,25 +53,23 @@ def chrom_from_csv(
53
53
 
54
54
  traces = []
55
55
  for _, row in df.iterrows():
56
- traces.append(
57
- {
58
- "chid": row[col_qid],
59
- "type": "mrm",
60
- "name": row["name"],
61
- "group": row[col_group],
62
- "prec_mz": row[col_q1],
63
- "prod_mz": row[col_q3] if col_q3 else None,
64
- "rt": row[col_rt],
65
- "rt_start": None,
66
- "rt_end": None,
67
- "istd": row[col_istd] if col_istd else None,
68
- "adduct": row[col_adduct] if col_adduct else None,
69
- "class": row[col_class] if col_class else None,
70
- "formula": row[col_formula] if col_formula else None,
71
- "inchikey": row[col_inchikey] if col_inchikey else None,
72
- "smiles": row[col_smiles] if col_smiles else None,
73
- },
74
- )
56
+ traces.append({
57
+ "chid": row[col_qid],
58
+ "type": "mrm",
59
+ "name": row["name"],
60
+ "group": row[col_group],
61
+ "prec_mz": row[col_q1],
62
+ "prod_mz": row[col_q3] if col_q3 else None,
63
+ "rt": row[col_rt],
64
+ "rt_start": None,
65
+ "rt_end": None,
66
+ "istd": row[col_istd] if col_istd else None,
67
+ "adduct": row[col_adduct] if col_adduct else None,
68
+ "class": row[col_class] if col_class else None,
69
+ "formula": row[col_formula] if col_formula else None,
70
+ "inchikey": row[col_inchikey] if col_inchikey else None,
71
+ "smiles": row[col_smiles] if col_smiles else None,
72
+ })
75
73
  self.chrom_df = pd.DataFrame(traces)
76
74
  return
77
75
 
@@ -143,25 +141,23 @@ def chrom_from_oracle(
143
141
  oracle_data.at[i, "lib_frags"] = frags
144
142
  for _key, value in frags.items():
145
143
  # add the fragment to the row
146
- traces.append(
147
- {
148
- "chid": qid,
149
- "type": "mrm",
150
- "name": row["name"] + " " + row["ion"],
151
- "group": row["name"] + " " + row["ion"],
152
- "prec_mz": row["mz"],
153
- "prod_mz": value,
154
- "rt": row["rt"],
155
- "rt_start": None,
156
- "rt_end": None,
157
- "istd": None,
158
- "adduct": row["ion"],
159
- "class": row["hg"],
160
- "formula": row["formula"],
161
- "inchikey": None,
162
- "smiles": None,
163
- },
164
- )
144
+ traces.append({
145
+ "chid": qid,
146
+ "type": "mrm",
147
+ "name": row["name"] + " " + row["ion"],
148
+ "group": row["name"] + " " + row["ion"],
149
+ "prec_mz": row["mz"],
150
+ "prod_mz": value,
151
+ "rt": row["rt"],
152
+ "rt_start": None,
153
+ "rt_end": None,
154
+ "istd": None,
155
+ "adduct": row["ion"],
156
+ "class": row["hg"],
157
+ "formula": row["formula"],
158
+ "inchikey": None,
159
+ "smiles": None,
160
+ })
165
161
  qid += 1
166
162
  self.chrom_df = pd.DataFrame(traces)
167
163
  return
@@ -190,25 +186,23 @@ def chrom_from_features(
190
186
  if row["feature_uid"] not in feature_uid:
191
187
  continue
192
188
 
193
- traces.append(
194
- {
195
- "chid": chid,
196
- "type": "ms1",
197
- "name": f"MS1 fid:{row['feature_uid']} ({row['mz']:.4f})",
198
- "group": f"fid:{row['feature_uid']}",
199
- "prec_mz": row["mz"],
200
- "prod_mz": None,
201
- "rt": row["rt"],
202
- "rt_start": row["rt_start"],
203
- "rt_end": row["rt_end"],
204
- "istd": None,
205
- "adduct": None,
206
- "class": None,
207
- "formula": None,
208
- "inchikey": None,
209
- "smiles": None,
210
- },
211
- )
189
+ traces.append({
190
+ "chid": chid,
191
+ "type": "ms1",
192
+ "name": f"MS1 fid:{row['feature_uid']} ({row['mz']:.4f})",
193
+ "group": f"fid:{row['feature_uid']}",
194
+ "prec_mz": row["mz"],
195
+ "prod_mz": None,
196
+ "rt": row["rt"],
197
+ "rt_start": row["rt_start"],
198
+ "rt_end": row["rt_end"],
199
+ "istd": None,
200
+ "adduct": None,
201
+ "class": None,
202
+ "formula": None,
203
+ "inchikey": None,
204
+ "smiles": None,
205
+ })
212
206
  chid += 1
213
207
 
214
208
  self.chrom_df = pd.DataFrame(traces)