chromConverter 0.10.0
Breaking changes
- 2D chromatograms from ‘Shimadzu’
.lcdfiles are now scaled by the calibration factor as well as the value factor, so the intensities match those reported by ‘Lab Solutions’. The calibration factor converts the encoded integers into the base unit of the detector, and is stored alongside the raw data in theChromatogram Statusstream. The parser was instead taking it from the copy of the2D Data ItemunderLSS Data Processing, where it is always1. Channels where it is not1were off by a constant factor, such as ~42x for an SPD-20A UV detector and ~310x for an RID-10A refractive index detector, so any factor applied by hand to match ‘Lab Solutions’ should now be removed. Older files, written by ‘LCsolution’ rather than ‘Lab Solutions’, have no2D Data Itemat all, so neither factor reached them; both are now read from the status record, changing the scale of those chromatograms by up to ~5000x.scale = FALSEstill returns the unscaled integers. - Fixed a loss of precision in long-format data. The conversion from wide to long format finished by coercing the assembled table with
apply(x, 2, as.numeric). Because retention times entered that table as character (from the rownames), the coercion routed every column through a character matrix, formatting each intensity withgetOption("digits")and so rounding it to 7 significant figures. Long-format intensities now match the wide-format values exactly. Exported files were affected too, sincewrite_mzmlandwrite_andi_msreshape to long format before encoding. - Mass spectra are no longer coerced to a matrix. With
format_out = "matrix", which is the default,read_shimadzu_qgd,read_chemstation_msandread_cdfreturned MS1 as a matrix, andread_varian_smsreturned a data.frame but recordedformat_outasmatrix. Long spectral data has no useful matrix representation: the coercion promotedscanandrtto double alongside the intensities and gave up$. All four now return adata.tablefor this value offormat_out, and record it.data.frameanddata.tableare returned as requested, and the two-dimensional streams (TIC,BPC) still honormatrix. - The names of several metadata fields have changed, and some functions and arguments have been deprecated or removed. See the “Metadata field changes” and “Deprecations and removals” sections below.
- A photodiode array trace from a ‘Shimadzu’
.lcdor.gcdfile now reports itsdetectorasDADrather thanPDA, matching the vocabulary used by every other parser.read_shimadzu_lcdalso returns the stream under the nameDADrather thanpda, so a result indexed asx$pdaneeds updating — though only where more than one stream was requested, orcollapse = FALSE, since a single-stream read returns the object itself, unnamed.whattakes either spelling, so the two are interchangeable throughout. - When
parseris not specified, reading a ‘Waters’.rawdirectory now requires therainbowPython module, and reports how to install it when it is missing. Auto-detection previously fell back on the internal parser, which reads only the analog_CHROtraces and reported nothing about the MS and PDA data it had skipped, so a file with three detectors could come back with one. The fallback also depended on a test that started Python for every file, including the formats that need no Python at all.rainbow-apiis requested automatically, so only hand-managed environments are affected;parser = "chromconverter"still selects the internal parser for files that hold analog traces alone.
New features
- Added
read_agilent_rsltfunction to read whole sequence of files from OpenLab and automatically attach corresponding metadata from theacamlfile. -
read_shimadzu_lcdcan now read mass spectra from.lcdfiles, withwhat = "MS1","MS2", or"MS"(to retrieve both levels). Two types of containers are supported:QTFL RawData(centroided quadrupole time-of-flight) andTLM Raw Data(triple quadrupole full scan, product-ion scan, MRM and SIM).what = "TIC"reads the total ion current from either container. QTOF m/z are computed from the TOF calibration stored in the file, with the mass correction ‘LabSolutions’ cached for the run folded in, which reproduces its mass axis exactly. Where a file carries no cached correction, the calibration is refit against the lock mass reference ions found in the data instead, which is good to a few tenths of a ppm. A newsparseargument controls whether zeros are dropped from triple quadrupole profile spectra. - Added
sort_byargument toread_chromsto control chromatogram order. Options are “none” (default), “acquisition_time” (usingrun_datetimefrom metadata), and “file_time” (using file modification time). The default will change to “acquisition_time” in a future release. - Added a
bin_widthargument tocall_rainbowas an alternative toprecision, for m/z grids that are not a power of ten (e.g.bin_width = 0.5).precisionis unchanged and remains the default. - Added a
summarymethod forchrom_listobjects, which returns whatprintdisplays as a table: one row per chromatogram, with the sample it belongs to, its dimensions and relevant metadata fields, such aswavelengthordetector_rangefor an optical detector,scan_type,polarity,precursor_mz,product_mzandmz_rangefor a mass spectrometer. - Added an
expandargument toextract_metadatafor the nested metadata fields, whose value is itself a list or table rather than a single value per chromatogram: thems_paramsinstrument settings, theacaml_metadatainjection recordread_agilent_rsltreads from the.acamlfile, or the whole vendor list whenmetadata_format = "raw". - Added a
collapseargument toextract_metadata, which renders a field holding more than one value as a single comma-separated string instead of spreading it over numbered columns (time_range1,time_range2). - Added a
detectorargument toextract_metadatato select which detectors to include (e.g.detector = "UV"ordetector = c("UV", "MS")), matched case-insensitively against each chromatogram’sdetectorattribute. This is useful for lists containing more than one detector per sample, such as those returned by therainbowparser. -
write_andi_msis now exported, likewrite_andi_chromandwrite_mzml. It was previously reachable only throughwrite_chroms(what = "MS1")orread_chroms(export_format = "cdf"), which write a whole list of chromatograms and offer no control over the file name or the instrument settings. -
write_chroms(export_format = "cdf")now forwards...to the underlying writer, as themzmlexporter already did. This makes thems_paramsargument ofwrite_andi_msand thelambdaargument ofwrite_andi_chromusable when writing a batch of files.
Improved handling of Python dependencies
- chromConverter is now more robust when you are offline. Python is only started when a parser that needs it (
rainbow,olefileorAston) is actually called, so the formats read by the internal parsers no longer require an internet connection. When Python is needed and the package index can’t be reached, chromConverter now falls back on a previously cached environment instead of failing. - Python packages are now requested only for the parser you actually call, so using the
rainboworolefileparsers no longer installs the ‘Aston’ requirements or constrains which version ofscipyyou can have. - chromConverter no longer creates Python module objects in your global environment when the package is loaded.
- Fixed
configure_python_environmentso it accepts theparserargument it is called with, and removed its interactive prompts, which failed in non-interactive sessions.
Performance
- Refactored internal ‘Agilent’ parsers for increased speed through vectorization of byte operations (~3.5-30x for the delta-encoded formats). For example, a 10.8 MB ‘ChemStation’ version 31
.uvfile went from ~9 s to ~0.57 s. - Refactored ‘Shimadzu’ binary parsers for increased speed (7-55x) through vectorization of byte operations. Reading MS1 scans from a 40 MB
.qgdfile went from ~56 s to ~1 s, and reading a PDA stream from an.lcdfile went from ~7 s to ~1 s. - Refactored
read_varian_smsfor increased speed (~8x) through vectorization. ReadingSTRD15.SMS(2.4 MB, 935k MS1 rows) drops from ~13 s to ~1.7 s. The stream is also bounded by the end of theMSDatasection rather than the end of the file, which reduced peak memory requirements for files carrying a large tail of peak tables and results. - Refactored
write_mzmlfor increased speed (~1.4x) and lower memory use. The spectra are now sliced out of the long-format table in place instead of being copied into a list of per-scan tables, and the byte offsets for the index are accumulated as the file is written rather than probed withseek()once per scan. Writing 3432 scans (935k points) drops from ~1.24 s to ~0.87 s, with peak memory falling from ~384 MB to ~339 MB. - Refactored conversion to long format for increased speed (~150x). The reshaping step now assembles the three columns directly instead of pivoting the table and then coercing it, which also avoids the rounding described below. Reshaping a 4689 x 328 PDA matrix drops from ~2.0 s to ~0.012 s, with peak memory falling from ~455 MB to ~227 MB. This affects every parser called with
data_format = "long"(orformat_out = "data.table", which implies long format), as well as the mzML and ANDI MS writers, which reshape to long format internally. - The temporary files that are extracted from ‘Shimadzu’ OLE containers are now deleted once they have been read, instead of accumulating in the session’s temporary directory until R exits. This matters most when converting many files at once.
- The SHA-1 of the source file, recorded as the
source_sha1metadata attribute, is now computed once per file instead of once per chromatogram. Formats that return several chromatograms from one file hashed it again for each of them, which dominated the read for large files: a 40 MB.qgddrops from ~2.2 s to ~1.3 s.
Metadata field changes
- The metadata field names are now defined in one place, so the names the readers attach and the names
extract_metadatareports cannot drift apart. Five fields had drifted and are renamed:software_nameis nowsoftware(‘Shimadzu’, ‘Varian’ SMS andread_agilent_rslt);run_dateis nowrun_datetimeandinjection_volumeis nowsample_injection_volume(‘Thermo’ RAW);time_startandtime_end(orend_time) are now the two ends oftime_range(ANDI, ‘Lumex’ MDF and ‘Varian’ SMS); and the two formats that record a scan count, ‘Varian’ SMS and ANDI MS, now both report it asn_scans, matching then_prefix used for counts throughout the package, rather thanno_scansin one andms_params$n_scansin the other.extract_metadataaccepts the old names and maps them to the new ones. - The
parserattribute is now always spelledchromconverter. Withmetadata_format = "raw", some readers reportedchromConverterinstead. -
sample_amountis no longer copied from the injection volume (‘Shimadzu’ ASCII, ‘ChemStation’.ch,.uvand.msfiles, ‘ChemStation’ report files, and ‘MassHunter’). None of these records a sample amount, so it is nowNA. ‘Lumex’ MDF likewise no longer reports an injection volume and amount of1, which the file does not record. -
detector_idis renamed asdetector_model. Every format that fills the field supplies a module or a model number, and says as much internally:detector_modelfor ‘ChemStation’, ‘OpenLab’ and ‘Chromatotec’ (G1315B,HP G1530A),detector_model_numberfor ASM,detector_namefor ANDI (9065 UV-DAD) andDetector Namefor the ‘Shimadzu’ ascii exports. None supplies a serial number or any other identifier of a particular unit, so the old name was misleading.extract_metadataacceptsdetector_idand maps it to the new name.
‘Agilent’
-
detector_rangeis now reserved for the numeric wavelength range recorded by.uvfiles. For ‘ChemStation’ versions 30 and 130 the signal descriptor was previously reported in this field, and is now reported assignal_descriptor. - The
detectorfield is nowNAfor ‘ChemStation’.chfiles. These files do not record a detector type; the field previously reported the detector module, duplicatingdetector_id. -
read_acamlnow also returns the injection volume (InjectionVolume,InjectionVolume_unit) and the acquisition software name and version (Software,SoftwareVersion).
‘Shimadzu’
- The
wavelengthattribute of a ‘Shimadzu’ 2D chromatogram is nowNArather than an empty string when the channel records none, as a refractive index or FID trace does. An empty string printed as a blank cell instead of as a missing value. - ‘Shimadzu’
.lcd,.gcdand.qgdfiles now reportfile_version, the version of the container format (5.01for files written by ‘Lab Solutions’; absent in the older files, which report only asoftware_versionof1.x). - ‘Shimadzu’
.lcdand.gcdfiles now report the instrument the file was acquired on, rather than the detector module of whichever trace you are looking at: one run on one HPLC previously came back asSPD-20Aon two channels andRID-10Aon a third.instrumentis taken from theSystemInformationstream (Instrument2,HPLC RID,GC-2014), the same string the ascii exports report asInstrument Name, so a run exported both ways now agrees. The module is now reported asdetector_model. A mass spectrometry trace has no module of its own, so it reports whatever unitSystemInformationlists for the mass spectrometer instead. That is a model number on newer software (LCMS-9030), but older versions list the generic platform name (e.g.,LCMS-3030for every triple quadrupole). - The channel a ‘Shimadzu’
.lcdor.gcdtrace was read from (LC.1.1.DET.1.CH#1,PDA.1.1.PDA.1.3D) is now reported aschannel_id, (replacingdetector_id). This field is used to name the peak table belonging to a trace (PT-LC.1.1.DET.1.CH#1), so the two can still be matched up.
Deprecations and removals
- The
astonparser is deprecated and will be removed in a future release. ‘Aston’ has been unmaintained since 2020. It is now used only bysp_converterto read ‘Agilent MassHunter’.spfiles (format_in = "masshunter_dad"), andread_chromsselects it automatically only as a last resort, when no other parser can read the file. Please use the internal chromConverter parsers or theentabparser (by the same author as ‘Aston’) instead. -
uv_converteris now defunct; useread_chemstation_uvor theentabparser instead. Theastonbinding forformat_in = "other"has also been removed; this format is still handled by theentabparser. Both relied on an ‘Aston’ reader that requiresscipy < 1.14, which would otherwise constrain the Python environment for every user. - Deprecated
datargument inread_chroms. Instead, chrom_lists can be combined withc(). - Renamed the
data_formatargument ofread_peaklistandread_chemstation_reportstopeaktable_format. This argument selectschromatographrororiginalpeak table layout, so it had nothing to do with thedata_formatargument of the chromatogram readers, which selectswideorlongformat.peaktable_formatis the name already used for this option byread_shimadzu. The old name still works but warns, and will be removed in a future release. -
read_sz_lcd_2dandread_sz_lcd_3dare no longer exported. Each reads a single stream of an.lcdfile and neither has to be called directly:read_shimadzu_lcd(what = ...)picks the reader a stream needs. Their documentation remains, since each records the layout of the stream it reads, but is marked internal and no longer appears in the reference index.
Bug fixes and other minor changes
- Fixed a bug causing data to be discarded when metadata could not be interpreted. The data is now returned with a warning, and with its source file and parser recorded.
- Fixed
format_out = "data.frame", which returned adata.tablefor any parser that assembles its result as one. The conversion tested the object withinherits, and a data.table inherits from data.frame, so the conversion was skipped. - Fixed the
rainbowparser, which raisedread() no longer takes precisionon every call oncerainbow-apiv1.5.0 was released. v1.5.0 splitprecisionintobin_width(the m/z grid, in daltons) anddisplay_precision(label rounding, in decimals); chromConverter now derives both fromprecision, so the argument and the data it returns are unchanged. v1.5.0 is now the minimum required version. - String metadata read from ‘Agilent ChemStation’ and ‘Shimadzu’ files is now decoded as Latin-1 and stripped of control characters. Previously these fields could contain bytes that made the resulting string invalid in the session encoding, so
nchar()andtoupper()failed on them andgrepl()could not match them. Accented characters in a path or sample name are now preserved rather than mangled. - Fixed error (
input string 1 is invalid UTF-8) when printing achrom_listread from a ‘Shimadzu’.lcdwritten in a non-Latin locale. The hex-encoded@StoX@fields, which hold themethodandbatchpaths, skipped the Latin-1 decoding applied to the rest of the file’s strings. Undecodable bytes are now replaced with?, andprint.chrom_listrepairs whatever it is handed, so one mangled path cannot take down the summary. - Fixed a bug where the
thermoraw,openchrom,agilent_dxandagilent_amxparsers deleted the whole session temporary directory on exit, instead of just the files they created. This behavior could potentially create conflicts with other packages. Each call now gets its own directory inside the session temp directory which is cleaned up on exit. - ‘Shimadzu’ OLE containers are now closed as soon as they have been read. Previously the contents of the last stream read were also kept in memory until R exited, and file handles were released only when garbage collection got around to them.
- Fixed a bug on ‘Windows’ causing paths with backslashes to be rejected on Windows by the ‘Shimadzu’ binary parsers.
- The ‘OpenChrom’ batch file is now deleted after the conversion, instead of accumulating in the export directory.
- The error reported when a required Python module is missing now names the distribution the module is installed from rather than the name it is imported under. It previously suggested
reticulate::py_install("rainbow"), which installs an unrelated package; the ‘rainbow’ module comes fromrainbow-api.
‘Agilent’
- Fixed missing
detector_idfor ‘ChemStation’ version 130 files. - Added
sample_positionmetadata field for ‘ChemStation’ 179 files (.chand.it). - The acquisition time of ‘Agilent MassHunter’ files is now converted to
POSIXctinstead of being attached as an unparsed string, whichextract_metadatareported asNA. - Fixed a bug causing
read_agilent_dx,read_agilent_amxandread_agilent_rsltto fail whenpath_outwas supplied. - Fixed the documentation of the peak table format argument to
read_chemstation_reports, which listed the accepted values aschromatographrorchemstation. The second value has always beenoriginal, so following the documentation raised an error.
‘Shimadzu’
- Fixed the acquisition time reported for ‘Shimadzu’ ASCII files, which was
NAfor every export not written by a machine using a 12-hour month-first date format. Note that the times in an ASCII export are local to that machine, which does not record its time zone, whereas.lcdfiles record the acquisition instant in UTC. - Fixed the metadata of ‘Shimadzu’ PDA ascii exports, which were read through the field map for the 2D exports. A PDA export reported no
detectorand nodetector_range; it now reportsDADand the wavelength range the detector covered. - Fixed
read_shimadzu_lcdfor.lcdfiles that do not contain a2D Data Item, which failed with'names' attribute [4] must be the same length as the vector [2]. This bug seems to affect older files, which store their chromatograms underLC Raw Datarather thanLSS Raw Data. - Fixed
read_shimadzu_lcdso it can return PDA data in long format.read_shimadzu_lcd(what = "PDA", data_format = "long")previously failed with an error about a missinglambdacolumn, because the reshaping step was called with the wrong target format. -
format_outnow reaches the peak tables of ‘Shimadzu’.lcdand.gcdfiles.read_shimadzu_lcd(what = "peak_table")andread_shimadzu_gcd(what = "peak_table")accepted the argument and then dropped it, so a table always came back as adata.frame.data.tableis now returned when asked for —matrix, which has no useful representation for a peak table, resolves todata.tableas it does for mass spectra. - Fixed export of OLE streams to a path containing
~, which is not expanded by Python. - Fixed the number of points per record in
.lcddata streams, which was read as a signed 2-byte field rather than the 4-byte field it is. A 2D chromatogram with 32,768 to 65,535 points failed withinvalid 'length' argument, and one with more than 65,535 points was truncated to the remainder. Files below that threshold, such as the 30,000-point chromatograms in the test suite, were read correctly.
‘Varian’ SMS
- Fixed the acquisition timestamps for ‘Varian SMS’ files. The corrected start matches the timestamp written by ‘OpenChrom’ for the same sample, and the interval between the start and end times matches the span of the chromatogram.
- The
run_datetimefor ‘Varian SMS’ files is now the acquisition start time, as a single value rather than a start/end pair. - Fixed
read_varian_smsforformat_out = "data.table", which failed previously with an error. TheTICandBPCreturned by this parser also had their intensity column namedtic/bpcinstead ofintensityfor this value offormat_out. - Added support for reading
instrumentandmethodmetadata from Varian SMS files (read from theInjectionLogsection).
ANDI (netCDF)
- Fixed the MS1 scans returned by
read_cdffor ‘ANDI MS’ files in which every scan holds the same number of points (common when the instrument scans a fixed mass range). The retention times arrived as a matrix and were split into one column per scan, so a 20-scan file returned a table withrt.1,rt.2, …rt.20columns instead of a singlertcolumn. Withms_format = "list"the same files returned a list of individual numbers rather than a list of spectra. Files with a varying number of points per scan were unaffected, and their output is unchanged. -
read_cdfno longer opens the netCDF file twice, and the peak table returned for ‘ANDI chrom’ files is no longer transposed when it holds a single peak. -
read_cdf(what = "peak_table")on an ‘ANDI chrom’ file that holds no peak table now warns and returns the other streams that were asked for, rather than failing withvalue for 'peak_table' not found.
mzML export
-
write_mzmlnow warns that MS2 spectra are skipped rather than counting them in thespectrumListheader and writing none of them. Writing MS2 is not supported yet. - Fixed
write_chroms(export_format = "mzml"), which failed for every file unlesswhatwas given explicitly. The streams to write are now inferred from the data, as they are whenwrite_mzmlis called directly. -
write_mzmlno longer writes a one-dimensional chromatogram as DAD spectra, and points towrite_andi_chrominstead. mzML stores scans of (m/z or wavelength, intensity), so a single trace has no axis to put in one: it was written as a single-point spectrum per retention time, which for a 66,000-point trace meant 66,000 scans, as many warnings about empty ranges, and a 128 MB file. The trace is skipped with a warning if other streams were requested, and reported as an error if it was the only one, since skipping it would leave an empty file.TICandBPCare unaffected, since the format has terms for those MS-derived summaries and they are written to the chromatogram list rather than as spectra. -
write_mzmlnow throws a more informative error when handed a single chromatogram whosedetectorattribute is missing,NA, or names a detector it has no mzML stream for, rather than failing withEXPR must be a length 1 vectoror quietly writing an unnamed stream. - Fixed the
fileChecksumwritten into indexed mzML files, which was the SHA-1 of the first line of the file (<?xml version="1.0" encoding="UTF-8"?>) rather than of the file itself, because the digest was taken over a multi-element character vector. Files are now checksummed as required by the mzML specification, over the bytes up to and including the opening<fileChecksum>tag, and the file no longer has to be read back into memory to do it. - Fixed the offsets in the
indexListof mzML files.<indexListOffset>pointed one byte before<indexList>, and every offset in the DAD spectrum index pointed at the newline preceding its<spectrum>element rather than at the element. Offsets are now counted as the file is written instead of being probed withseek(), which is unreliable on a connection opened in text mode and ignores the write buffer. - Fixed the chromatogram index of mzML files. Each
<offset>pointed four bytes before its<chromatogram>element, and itsidRefnamed the element’sindexrather than itsid, so no entry in the index resolved to the chromatogram it was meant to locate. - Fixed the spectrum-type term written into mzML files, which was always
MS:1000580(“MSn spectrum”) even thoughms levelwas1. - Fixed
write_mzml(compress = FALSE), which was ignored for spectra (though not for chromatograms), since the argument was never passed on. - Fixed the
countattribute of<spectrumList>, which was always written as1for data read as adata.table. - Fixed malformed mzML files written from data with missing
sample_name,source_fileorsource_sha1attributes: a missing field collapsed thesprintfthat builds the header, dropping the<mzML>element itself. The header read its metadata fromMS1, or fromDADwhenMS1was not requested, without checking the stream was still there — aDADtrace skipped earlier leaves nothing to read from. It now reads from a stream that is actually being written, and a missingsample_nameis an error naming the argument that supplies one. - Fixed the
countattribute of<spectrumList>when the TIC starts before the first MS1 scan. Those leading retention times are written as empty spectra, so the file holds one spectrum per TIC point, but the count was taken from the MS1 table and fell short by the number of padded scans. - Fixed the
indexattribute of the DAD spectra, which withindexed = FALSErestarted at zero and repeated the numbers the MS1 spectra already used. The starting value was parsed from the id of the last spectrum-index entry, and those entries carry an id only when the file is indexed; it is now the count of spectra already written. - mzML files are now written as binary, so their line endings are
LFon all platforms.
Metadata and printing
- Refactored the attachment of metadata. A registry of per-format field maps replaces a twenty-branch
switch, and attributes likesource_file,source_sha1andparserare no longer repeated in each one. The change is internal, but it resolves several problems listed below. - Fixed
metadata_format, which several readers mishandled.metadata_format = "raw"errored for ‘Chromeleon’ files and returnedNULLinstead of a chromatogram for therainbowparser; theentabparser andread_shimadzuignored the argument altogether; andparser = "entab"withformat_in = "other"returnedNULL. The argument is now resolved in one place instead of separately by each reader. - Metadata from ‘Agilent ChemStation’ report files is now attached to the peak lists that
read_peaklistreturns, soextract_metadatacan see it. - Fixed
detector_rangefor ‘Chromeleon’ 3D files, which reported only the lower end of the scan range. For 2D files, which record no scan range, it was a zero-length value that disappeared fromextract_metadatainstead of readingNA. - Fixed errors reading ‘Chromeleon’ files that record no injection volume, or more than one field matching “Volume”, and ‘MassHunter’ directories with no
sample_info.xml. - The file-level properties that
read_mzmlrecovers are now attached as attributes, soextract_metadataandprint.chrom_listcan see them, and themetadataelement carrying them is no longer counted as a chromatogram. Therun_datetime,time_range,time_unitanddetector_rangefields previously came back asNAfor mzML files even though ‘RaMS’ had parsed them, which also meantread_chroms(sort_by = "acquisition_time")could not order them. Themetadataelement is still returned in full, since it carries several fields with no attribute equivalent. - Some metadata attributes that were previously left unset are now recorded, so
extract_metadatanow reports them as empty instead of dropping them altogether.scaledwas accepted by every reader that takes ascaleargument and then dropped by thirteen of the twenty field maps, so it was missing for most formats;metadata_format = "raw"recordedsource_fileandsource_sha1but notformat_outorsource_file_format; and ‘Thermo’ RAW files lost any field that the mzML conversion recorded but the converter’s own metadata output did not. - The
source_file_formatattribute is now set correctly for every format. It was previously missing for some formats, and named the parser or an intermediate file for others. -
extract_metadatanow reports the injection volume for every format that records one, and the acquisition software for ‘Shimadzu’ and ‘Varian’ files. These were previously ignored, because the formats did not agree on what to call them. -
extract_metadatanow returns a row for every chromatogram, however deeply nested, and reads sample-level attributes from the list enclosing a sample’s traces as well as from the traces themselves. Previously only the top level of the list was examined, so nested traces, and any metadata held on the list grouping them, were left out of the table. A field that varies from trace to trace, such asdetectorin a multichannel file, stays with the trace; where the traces agree, the value on the enclosing list is used, since it describes the sample as a whole. -
extract_metadatano longer reports a multi-valued field as missing. The check tested the requested names against the columns of the assembled table, where a field holding several values appears asproduct_mz1,product_mz2, … and so never under the name that was asked for. -
extract_metadatanow matches attribute names exactly. Previously a requested element could be filled in from a different attribute that merely started with the same characters, so a chromatogram with nodetectorattribute could report itsdetector_y_unitas its detector. -
extract_metadatanow returnsNAinstead of a metadata frame with only anamecolumn when none of the requested metadata elements are found. - Fixed the intensity units and scan count written to ANDI MS files, which were always empty previously because the writer was trying to read them from the wrong attributes.
-
print.chrom_listnow handles lists holding more than one trace per sample, such as a multichannel ‘Shimadzu’ file or an ‘Agilent’.dxread withwhat = c("chroms", "dad"). Traces are grouped under the sample they belong to, however deeply nested, and attributes shared by all of a sample’s traces are shown in that sample’s block header instead of being repeated on every row. Previously only the top-level elements were counted, so the chromatogram count was wrong and only the first trace of each sample was shown. - Improved
print.chrom_listformatting: datetimes print as timestamps rather than raw epoch seconds; the header wraps to the width of the console, breaking between fields; long values, such as a ‘Windows’methodpath, are shortened from the middle; and a field that is empty for every chromatogram is dropped.printno longer errors when none of the requestedcolsare present or whennis negative, andnnow defaults to10, as documented.
read_chroms
- Refactored the dispatch in
read_chroms. A single internal table now records which formats it can read and, for each one, the file extension, and the reader each parser uses. These facts were previously spread across the argument list, anif/elsechain, and several utility functions (check_parserandformat_to_extension). The change is internal, but it resolves several problems listed below. - Arguments passed through
...are now matched against the arguments the selected parser actually accepts. An unrecognized argument previously made every file fail, surfacing from insidetry()as a warning with an unreadable message; such arguments are now ignored with a warning naming them. - When
format_inis not supplied and the type of a file cannot be recognized,read_chromsnow says so and asks for a format, rather than failing withargument is of length zero. -
read_chromsnow gives an informative error when no parser is available for a format, instead of failing withmissing value where TRUE/FALSE needed. - When a file cannot be interpreted,
read_chromsnow names it instead of reporting its position in the list. - A file that cannot be interpreted now produces a single warning naming it, rather than a warning followed by a separate message. The message could not be silenced with
suppressWarningsand was invisible to callers handling the warning. - Some formats can now be named in more than one way.
format_inaccepts an alias as readily as the format’s own name, and the two behave identically:rsltandsirsltforagilent_rslt,openlab_dxforagilent_dx,chemstation_fidforchemstation_ch,andiforcdf, andallotropeforasm. - The
shimadzu_ascii,csv,asm,openlab_131andchemstationformats are now matched to the correct file extension, instead of falling through to a pattern matching any file containing a.. - The
metadata_formatargument now reaches theagilent_dx,agilent_rslt,shimadzu_lcd,shimadzu_qgd,cdfandentabparsers. Previously,metadata_format = "raw"had no effect for these formats. - For formats that return more than one chromatogram per sample,
sample_names = "sample_name"named every sample with the literal string"NULL"and then warned about duplicate names. This was because thesample_nameattribute is attached to the individual chromatograms rather than to the list grouping them, so the lookup came up empty and the resultingNULLwas coerced to a string. Samples with no recorded sample name now fall back to the file name, with a warning naming them. A name that is recorded but empty counts as no name, since a parser that finds the field but reads nothing out of it leaves an empty string behind. The traces making up a sample are now also checked against each other: if they disagree about the sample name there is no basis for preferring one over another, so the file name is used instead, again with a warning.
chromConverter 0.9.1
New features
- Added a
[.chrom_listmethod so that subsetting achrom_listpreserves its class instead of dropping it to a plainlist. - Added a
c.chrom_listmethod so that combiningchrom_listobjects withc()preserves the class instead of dropping it to a plainlist.
Bug fixes and other minor changes
- Fixed encoding bug when parsing XML metadata in
read_shimadzu_lcd: (bytes are now read explicitly as ISO-8859-1 rather than relying on system locale viareadLines()). - Updated for compatibility with rainbow v1.3.0, which renamed the
precargument toprecision; chromConverter now requires rainbow >= 1.3.0. - Fixed vignette example for
varian_smsso the example file is downloaded in binary mode (mode = "wb"), preventing file corruption on Windows. - Added
sample_positionfield toextract_metadata.
chromConverter 0.9.0
CRAN release: 2026-05-31
Breaking changes
- Consolidated
sample_idandvialmetadata fields into newsample_positionfield. - Added
sparseargument forrainbowparser (now enabled by default) to remove zeros form long-format MS data. - Changed order of
whatarguments inread_agilent_dto prioritize DAD data (instead of 2D chromatograms). - Fixed bug so that Varian long-format MS data is returned as a data.frame by default (rather than a matrix).
- Added
chrom_listclass andprint.chrom_listmethod. Instead of dumping the full contents of every chromatogram, prints a compact metadata summary with configurable columns (cols) and row limit (n).
New features
- Added support for reading Agilent Common Analytical Markup Language (ACAML) files.
- Added support for reading Agilent OpenLab method files (
.amx). - Added preliminary support for reading “Chromatotec”
.Chromfiles through theread_chromatotecfunction. - Added support for reading regular utf8-encoded
csvfiles. - Pass source file through when reading
agilent_dxfiles so that the original source file is stored in metadata instead of a temp file. - Added warning in
read_chromsfor duplicated names as they may silently interfere with downstream analyses.
Improved support for exporting files
- Added option to write ARW files in
write_chroms. This format seems to be the simplest way to get DAD data intoOpenChrom. - Added support for writing standard utf8-encoded
csvfiles and fixed a bug causing column names to be prepended with “X”. - Modified
write_chromsso it invisibly returns file names of the exported chromatograms. - Improved error handling within
write_chroms.
CDF
- Fixed bug causing failure to write chromatograms with missing attributes to
.cdf(thanks to @pbulsink for PR #37). - Fixed bug causing failure to write existing timestamp data to
.cdffiles. - Fixed bug causing failure to write ANDI chrom files on Windows due to failure to coerce numeric metadata to text.
- Added additional metadata fields to exported CDF files.
- Added additional test for writing CDF files with missing attributes.
- Fixed CDF time range metadata bug.
Other bug fixes and minor changes
- Fixed entab parser so it translates
.chfiles to wide format when specified. - Fixed bug in
read_agilent_dwhen subsetting data with thewhatargument. - Fixed Waters ARW parser so it can read files with missing metadata.
- Added assumption that time units for data generated by
rainbowparser are in minutes. - Rainbow parser now returns sparse MS data by default (excluding zeros) when long format is requested to match format returned by other parsers.
- Fixed problems with Aston converters due to changes in reticulate behavior.
- Fixed bug so that data from ANDI MS netCDF files can be returned as
data.tableobject when specified by user. - Fixed ‘Shimadzu’ QGD bug affecting large values. Resolves (#44).
- Fixed bug causing sample_position/vial metadata to be dropped when reading Agilent files.
- Fixed bug so that temp directories created by certain file parsers (e.g.,
read_agilent_dxandread_themoraw) are actually deleted on completion. - Refactored
extract_metadatafunction for simplicity.
chromConverter 0.8.0
- Improved support for ‘Agilent OpenLab’
.dxfiles: extraction of DAD and auxiliary instrumental data (stored in.ITfiles). - Refactored
read_shimadzu_qgdfor a 1.4x speedup in the parsing of Shimadzu.qgdfiles, cutting execution time by 30%. - Refactored
read_shimadzu_lcdfor a 2.4x speedup in the parsing of Shimadzu.lcdfiles, cutting execution time by 60%. - Refactored
write_mzmlfor massive speed-up when writing mzML files, especially for large MS data. - Fixed ‘Shimadzu’ metadata time zone offsets.
- Fixed misplaced parentheses in
read_agilent_dthat were causing possible bug. - Fixed bug in
read_chemstation_uvcausing error for long format data. - Added more informative error messages for
read_agilent_d. - Added additional tests for retention times and
data_formatattribute. - Added
data_formatandread_metadataarguments forread_chemstation_csv. - Fixed incorrect
data_formatattributes for MS data to reflect that they are always returned in long format. - Fixed documentation to accurately reflect the fact that MS data is always returned in long format.
- Automatically return long format when
data.tableoutput is selected since data.tables do not have rownames. - Fixed error due to fractional timezones in Shimadzu metadata (e.g., India +05:30).
- Fixed bug in
write_mzmlcausing retention time shifts for BPC and TIC. - Rewrote
configure_python_environmentfunction to facilitate configuration of a chromConverter virtual environment or conda environment, though a dedicated environment is no longer required (as of chromConverter v0.7.4). - Fixed bug in
collapseargument causing functions to return vector whenformat_outisdata.frame. - Fixed bug causing elimination of retention times when
format_outisdata.table. - Enabled
data.tableformat inread_shimadzu_ascii. - Enabled automatic recognition of ‘Agilent OpenLab’
.dxfile byread_chroms. - Fixed long format output for
read_shimadzu(‘Shimadzu’ ASCII files). - Fixed timezone issue in some ‘Agilent ChemStation’ files.
chromConverter 0.7.5
CRAN release: 2025-03-31
-
Changes to
sample_namesargument inread_chroms: This argument can no longer be supplied with a vector of names. Instead,sample_namescan be provided with one of two arguments:basenameorsample_name. The default setting (basename) will use the basename of the file, whilesample_namewill instead use the sample name encoded in the file’s metadata. - Fixed bug in
extract_metadatawhen sub-setting metadata elements. - Added more informative error and warning messages to
extract_metadata. - Added
data.tableformat option toextract_metadata. - Fixed path issue in
call_openchrom. - Updated documentation in README and
call_openchrommanual concerning OpenChrom installation.
chromConverter 0.7.4
- Use updated syntax for reticulate (hopefully this will solve some of the issues with python configuration failure).
- Invisibly return paths to exported CDF files.
- Small updates to documentation (e.g., addition of functional families, standardization of function titles and descriptions).
- Fixed Windows path issue when R is installed locally.
- Fixed error reading Shimadzu metadata on Windows (due to “Extra content at end of document”).
chromConverter 0.7.3
- Updated
read_shimadzu_lcdto infer retention times in Shimadzu 3D Data fromMax Plotstream since it is always (?) present. - Updated
read_shimadzu_lcdto skip parsing of metadata from 3D Data Item when it is not present. - Updated
read_shimadzu_lcdto includeMax Plotstream when parsing 2D chromatograms. - Fixed bug in
read_chromeleonrelated to inference of decimal separators. - Added
decimal_markargument toread_chromeleonto manually set decimal separator.
chromConverter 0.7.2
- Added preliminary support for extraction of peak tables from ‘Shimadzu’
.lcdfiles. - Added support for inference of retention times from ‘Shimadzu’
.lcdfiles lackingData Itemstreams. - Added support for raw format File Properties stream in ‘Shimadzu’
.lcdfiles. - Added support for parsing 3D data field from ‘Chromeleon’ ascii files.
chromConverter 0.7.1
- Fixed automatic file detection for directories (e.g., Waters
.rawand Agilent.D) - Fixed bug preventing extraction of
Waterschromatograms with lowercase filenames. - Added support for extracting metadata from ‘Waters’
.rawheader files. - Added support for extraction of detector units from ‘Waters’ chromatograms.
chromConverter 0.7.0
Major features
- Added preliminary support for ‘Varian Worktation’ (
.sms) format throughread_varian_smsfunction. - Added preliminary support for ‘Shimadzu QGD’ GC-MS files through the
read_shimadzu_qgdfunction. - Added preliminary support for ‘Allotrope Simple Model’ (ASM) 2D chromatography date files.
- Added support for reading multiple files from ‘Agilent’
.Ddirectories throughread_agilent_dfunction. - Added internal parser for ‘Agilent ChemStation’ MS files through
read_agilent_ms. - Added option to write mzML files (MS1 and DAD).
- Added option to write ANDI MS netCDF files.
UI changes
- Changed order of arguments in
read_chromsso thatformat_incomes second afterpath. - Removed extraneous
exportargument fromread_chroms. To export files, you now only need to provide an argument toexport_format. - Updated handling of multiple chromatograms by
read_shimadzu_lcd. The function now returns a list of named chromatograms ifdata_format == "wide"and returns multiple chromatograms in a singledata.frameifdata_format == "long". - Added
scaleargument toread_chemstation_uvandread_shimadzu_asciito toggle scaling of chromatograms. - Harmonized file path arguments across parser functions by changing
filearguments topath. - Harmonized column names in output across parsers.
- Small changes in
read_cdfUI:whatnow defaults toNULLand defaults are coded into downstreamread_andi_chromandread_andi_msfunctions. - Added extra verbosity in
read_chromswhenverboseisTRUE.
Other improvements
- Fixed bug causing reticulate to attempt reinstallation of Aston every time the package is loaded (due to case sensitivity of packages names in
reticulate::configure_environment). - Added
data.tableas an option forformat_out. - Improved speed of
read_shimadzu_lcdby dealing with twos-complements more sensibly. - Start ‘Shimadzu LCD’ chromatogram retention times at dwell time (DLT).
- Give temp files generated from Shimadzu OLE files informative names.
- Use ‘Output Date’ field instead of ‘Type’ to find ‘Shimadzu’ ASCII delimiter. (This seems to be a more generalizable solution since some files do not contain the ‘Type’ field).
- Allow relative paths for
path_outwhen using ‘ThermoRawFileParser’ and ‘OpenChrom’ parsers. - Allow creation of new directories by
read_chromsifpath_outdoes not exist. - Fixed bug affecting some
mdffiles lacking null bytes after the file header. - Eliminated ‘magrittr’ dependency by using xpath to parse XML in a more straightforward fashion.
- Fixed bug causing truncation of sample names at the first period by
read_chroms. - Modified
export_csvfunction to label first column for wide-format chromatograms. - Improved handling of metadata from rainbow parsers.
- Fixed error when providing single chromatogram to .
- Added metadata field for source checksum (SHA1) and source file format.
- Other minor changes to metadata fields.
- Return all times in Coordinated Univeral Time (UTC) for consistency across systems.
chromConverter 0.6.4
- Added support for ‘Agilent ChemStation’ version 8 (
.ch) files throughread_chemstation_ch. - Fixed failure to return units in some
Agilent Chemstationfiles due to typo. - Fixed bug causing “spill-over” of Agilent metadata fields.
- Fixed bug causing failure to read
ChemStationCSV files on (some) mac machines by specifying little-endian format in call toread.csv.
chromConverter 0.6.3
- Added parser for total ion chromatogram (TIC) stream in ‘Shimadzu’ LCD files.
- Added additional support for extraction of metadata from ‘Shimadzu’ LCD and GCD files.
- Updated docs for
read_shimadzu_lcd_2dto more accurately reflect file structure. - Added
scaleargument toread_chemstation_chandread_shimadzu_lcdto toggle scaling of chromatograms resolving (#30).
chromConverter 0.6.2
- Updated
read_shimadzu_lcdfunction to correctly determine the number of blocks in the “Shimadzu” LCD PDA stream (thanks to kco-hereon). - Added preliminary support for 2D data streams from “Shimadzu LCD” files.
- Added parser for ‘Shimadzu GCD’ files (from GC-FID).
chromConverter 0.6.1
- Added support for ‘Shimadzu’ ASCII files with ‘[LC Chromatogram…]’ sub-header.
- Correct ‘Shimadzu’ ASCII chromatograms by ‘Intensity Multiplier’ if it is provided.
- Fixed bug in logic in
export_cdfsfunction to permit conversion of files lacking metadata. - Minor, cosmetic changes to documentation.
chromConverter 0.6.0
- Added parser for reading ANDI MS (
.cdf) files. - Fixed parsing of Agilent MS files with ‘entab’ reader.
- Fixed
read_chemstation_chparser to correctly read “Mustang Chemstation” 179 files with 8-byte encoding. - Re-factored
read_shimadzufunction and added support for new types of chromatograms (e.g. status, uv and total ion chromatograms). Added support for reading multiple types of chromatograms at once. - Added support for reading MS spectra from ‘Shimadzu’ ascii files using
read_shimadzu. - Exported
write_cdfand added additional arguments (lambdaandforce) for greater control by users. - Added internal parser for 1D ‘Waters RAW’ chromatograms (
read_waters_raw). - Added
collapseargument tocall_rainbowand to collapse superfluous lists. - Added
...argument toread_chromsfor supplying additional arguments to parsers. - Added alias to
read_chromsfor readingmzxmlfiles withRaMS. - Added
precisionargument tocall_rainbowto control number of digits “mz” values are rounded to. (Also changed default behavior so values are rounded to one decimal by default). - Fixed bug in
read_shimadzu_lcdon Windows due to issue with passing escaped paths to Python. - Updated documentation of various functions.
chromConverter 0.5.0
New features
- Added support for parallel processing through
pbapplypackage. (Note: Thepbapplypackage must be manually installed to enable parallel processing). - Added internal parser for ‘Agilent ChemStation’ version 31 files (through
read_chemstation_uvfunction). - Added support for ‘Agilent OpenLab’ version 131 files through internal parser.
- Added preliminary support for reading ‘Agilent’ (
.dx) files (throughread_agilentdxfunction). - Added support for reading ‘ChemStation’ REPORT files.
- Added parser for Shimadzu
.lcdfiles through theread_shimadzu_lcdfunction. Only the PDA stream (not MS) is currently supported. - Added
read_peaklistfunction for reading peak lists. Currently ‘Agilent ChemStation’ and ‘Shimadzu ASCII’ formats are supported. - Added
verboseargument to control console output for external parsers (‘OpenChrom’ and ‘ThermoRawFileParser’).
Other Improvements
- Improved automatic file type detection by
read_chroms. - Refactored
read_thermorawfunction to simplify paths. - The
thermorawandopenchromparsers now use a proper temp directory if an export directory is not specified through thepath_outargument. - Re-factored
reshape_chroms, speeding up conversion from wide to long format. - Added additional tests, attaining 82% test coverage.
- Changed default
openchromexport format tomzml. - Minor changes to some metadata fields to better standardize results across different file formats and parsers.
Bug fixes
- Corrected ‘Shimadzu’ DAD parser so it reads wavelengths from the file instead of inferring them.
- Fixed bug causing failure of ‘Shimadzu’ ascii parser (when
what == "peak_table"andread_metadata == TRUE). - Fixed bug causing ‘MDF’ files to export as data.frames when
format_out == "matrix". - Fixed misleading
data_formatattributes in ‘Waters ARW’ and ‘Chromeleon’ parsers.
chromConverter 0.4.3
- Fixed bug in
chemstation_chparser (version 130) (#17)
chromConverter 0.4.1
chromConverter 0.4.0
New features
- Added parser for ANDI chrom
cdffiles through theread_cdffunction. - Added parser for ‘Lumex’
.mdffiles through theread_mdffunction. - Added additional options for file exports. New options for writing
chemstation_csv(utf-16) and ANDI chromcdffiles throughread_chroms. - Added preliminary support for automatic filetype detection by
read_chromswhen providing direct paths to files (i.e. whenfind_files == FALSE). - Added
read_varian_peaklistfunction for reading peak lists from ‘Varian MS Workstation’.
Other improvements and bug fixes:
- Added
wideandlongdata_formatoptions for 2D data, such that thewideformat option writes retention times as rownames of the matrix or data.frame. while thelongformat writes retention times as the first column of the object. - Updated
configure_openchromfor better discovery of ‘OpenChrom’ path and addedpathargument for directly specifying the path to ‘OpenChrom’. - Slightly restructured metadata fields. Added
source_filefield to track data origin. - Standardized datetime stamps so they are always converted to POSIXct format.
- Now use
fspackage for parsing paths, eliminating buggycheck_pathsfunction. - Fixed bug causing sloppy ‘ChemStation’ FID metadata.
- Fixed bug that caused padding of ‘ChemStation 130’ files with extra zeros.
- Added additional tests.
chromConverter 0.3.3
- Added R-based parser for “ChemStation” UV (
.uv) files (version 131) through theread_chemstation_uvfunction. - Added
extract_metadatafunction for extracting metadata from a list of chromatograms and returning it as adata.frameortibble. - Added
progress_baroption inread_chroms. - Updated
reshape_chromsandreshape_chromto allow switching between “wide” and “long” formats. - Added wide format option in
read_mzml. - Added automatic detection of file formats by
read_chroms. - Minor changes to storage of metadata in attributes for the purpose of simplification.
- Fixed bug preventing removal of file extensions for ‘Agilent’ data when using
read_chroms. - Standardized run date/time in metadata to
POSIXctformat. - Minor updates to documentation.
chromConverter 0.3.2
- Fix ‘Shimadzu’ ascii parser so it can cope with variable entries in PDA header.
chromConverter 0.3.1
- Added support for “ChemStation” UV (
.ch) files (version 130). - Added provisional support for “ChemStation” FID (version 8).
- Changed name of
read_chemstation_fidfunction toread_chemstation_ch. - Ignore case when matching file extensions in
read_chroms. - Added note to README about configuring RStudio correctly for accessing python parsers.
chromConverter 0.3.0
- Fixed bug causing “Chromeleon” metadata parser to fail.
- Fixed bug in “ChemStation” metadata parser.
- Changed
format_dataargument todata_formatto select wide or long format. - Added support for parsing
mzMLfiles withRaMS. - Added support for parsing “Agilent” (
.D) and “Waters” (.raw) files with rainbow. - Made
data_formatoption available consistently for choosingwideorlongformat. - Added parser in R for “ChemStation” FID (
.ch) data (versions 81, 179 & 181). - Improved error handling when loading python modules.
- Improved error-handling for parsing metadata so small problems no longer error out the whole program.
chromConverter 0.2.2
- Fixed bug in
call_openchromso that it can actually find ‘OpenChrom’ path. - Fixed bug in
call_openchromto allow ‘animl’ as validexport_format. - Allow ‘Thermo RAW’ files to be parsed using ‘Entab’.
chromConverter 0.2.1
CRAN release: 2022-07-11
- Added
configure_astonfunction for configuration of Aston parsers and fixed issues with configuration of Aston.
chromConverter 0.2.0
New features and formats
- Added
read_shimadzufunction for parsing ‘Shimadzu’ ascii files. - Added
read_chromeleonfunction for parsing ‘Chromeleon’ ascii files. - Added
read_thermorawfunction to convert ‘Thermo Raw’ files by calling the ‘ThermoRawFileParser’. - Added
read_mzmlfunction to extract UV data from mzML files using mzR. - Added
call_entabfunction for calling Entab parsers. - Added
call_openchromto call OpenChrom parsers through the command-line interface.
(All of the new functions described above can be called from the read_chroms function by setting the format_in and parser arguments).
- New option to read and attach instrumental metadata to chromatograms by setting
read_metadata = TRUEinread_chroms.
Simplification of read_chroms syntax
-
read_chromswill now automatically assign a parser if the parser isn’t specified. -
read_chromswill throw more informative errors for mismatch betweenformat_inandparserarguments. -
read_chromswill try to automatically determine if files or directories are being provided.
Other changes to read_chroms syntax:
Dots were replaced with underscores in all arguments to read_chroms for internal syntactical consistency across the package. Thus:
- The argument to specify the format of R objects was changed from
R.formattoformat_out. - The argument to specify the format for exported files was changed from
format.outtoexport_format.
