edf2csv 0.9.27 → 0.9.29

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.
@@ -250,7 +250,7 @@ export declare function convertedChannels(plan: ConversionPlan): Set<number>;
250
250
  *
251
251
  * `writesSignals` rather than the option, because the plan is what settles it.
252
252
  */
253
- export declare function withSignalTableUnwritten(diagnostics: readonly Diagnostic[], writesSignals: boolean, gzip: boolean, converted?: ReadonlySet<number>): Diagnostic[];
253
+ export declare function withSignalTableUnwritten(diagnostics: readonly Diagnostic[], writesSignals: boolean, gzip: boolean, converted?: ReadonlySet<number>, toStdout?: boolean): Diagnostic[];
254
254
  /**
255
255
  * The sidecar files a `--stdout` run does not write, taken out of the sentences about them.
256
256
  *
@@ -107,7 +107,7 @@ export async function convert(inputPath, options = {}) {
107
107
  diagnostics: withSidecarsNamed(withSignalTableUnwritten([
108
108
  ...withTimingPromiseKept(withoutFileRateWarning(file.diagnostics), timing.starts !== null),
109
109
  ...plan.diagnostics,
110
- ], plan.writeSignals, plan.gzip, convertedChannels(plan)), { toStdout: true, gzip: plan.gzip }),
110
+ ], plan.writeSignals, plan.gzip, convertedChannels(plan), true), { toStdout: true, gzip: plan.gzip }),
111
111
  plan,
112
112
  file,
113
113
  elapsedMs: Date.now() - startedAt,
@@ -1659,7 +1659,27 @@ export function withSignalTableUnwritten(diagnostics, writesSignals, gzip,
1659
1659
  touch. The rewrites are the same rewrites, so the set of them is the argument rather than
1660
1660
  a second copy: empty means no signal table at all, which is what `writesSignals` said.
1661
1661
  */
1662
- converted = new Set()) {
1662
+ converted = new Set(),
1663
+ /*
1664
+ And whether this run writes the file those rewrites send the reader to.
1665
+
1666
+ Every sentence below that takes a cell away offers channels.csv in its place — "channels.csv
1667
+ still records the digital range the header gives", "it is named `signal_1` in channels.csv's
1668
+ column cell". `--stdout` writes no sidecar at all, and it can be given `--channels`:
1669
+
1670
+ $ edf2csv rec.edf --stdout --channels ECG > rows.csv
1671
+ warning: Signal 0 ("flat") has digital minimum equal to digital maximum (0), so its
1672
+ values cannot be scaled.
1673
+ No samples are converted for a channel --channels left out, so there are no
1674
+ cells to leave empty. channels.csv still records the digital range the
1675
+ header gives.
1676
+
1677
+ It does not. The run writes one CSV to the stream and nothing else, so the file offered
1678
+ as the place the channel is still described is not written either — which is the same
1679
+ thing `withSidecarsNamed` says one pass later about the sentences it knows. These are the
1680
+ ones it has never been shown: they do not exist until this pass writes them.
1681
+ */
1682
+ toStdout = false) {
1663
1683
  const skipped = (diagnostic) => {
1664
1684
  if (!writesSignals)
1665
1685
  return true;
@@ -1677,8 +1697,24 @@ converted = new Set()) {
1677
1697
  had already taught to say `channels.csv.gz`. So a single run named both spellings, and only
1678
1698
  the second one existed.
1679
1699
  */
1680
- const channelsFile = outputCsvName('channels', gzip);
1700
+ /*
1701
+ Named plainly under `--stdout`, where no compressed sidecar is written either.
1702
+
1703
+ `--stdout --gzip` compresses the stream and nothing else, so `channels.csv.gz` is as
1704
+ absent as `channels.csv` — and it is the spelling `withSidecarsNamed` already uses one
1705
+ pass later when it says none is written.
1706
+ */
1707
+ const channelsFile = outputCsvName('channels', gzip && !toStdout);
1681
1708
  const annotationsFile = outputCsvName('annotations', gzip);
1709
+ /*
1710
+ What channels.csv still holds about the channel, or that there is no channels.csv.
1711
+
1712
+ Worded the way the sidecar pass words the hints it rewrites — the file is named, so the
1713
+ reader knows what they are missing, and the command that produces it is named too.
1714
+ */
1715
+ const records = (what) => toStdout
1716
+ ? `--stdout writes no ${channelsFile}; a conversion to a directory records ${what}.`
1717
+ : `${channelsFile} still records ${what}.`;
1682
1718
  return diagnostics.map((diagnostic) => {
1683
1719
  if (!skipped(diagnostic))
1684
1720
  return diagnostic;
@@ -1726,11 +1762,18 @@ converted = new Set()) {
1726
1762
  return {
1727
1763
  ...diagnostic,
1728
1764
  message: diagnostic.message
1729
- .replace("as the channel's name in signals.csv", `as the channel's name in ${channelsFile}'s column cell`)
1765
+ /*
1766
+ The hedge goes where the file goes, so it is taken off wherever the header put it
1767
+ and folded into the clause below. A run writing into a directory does write
1768
+ channels.csv, and the qualification is noise there; a `--stdout` run writes none,
1769
+ which is the case the header's own sentence has been qualified for since 0.8.52.
1770
+ */
1771
+ .replace(' in any conversion that writes one', '')
1772
+ .replace("as the channel's name in signals.csv", `as the channel's name in ${channelsFile}'s column cell` +
1773
+ `${toStdout ? ' in any conversion that writes one' : ''}`)
1730
1774
  // Matched on the name the header diagnostic used, which the line above has not
1731
1775
  // touched: it renames the first mention, and this collapses the second.
1732
- .replace("column cell and in channels.csv's", 'column cell and in its')
1733
- .replace(' in any conversion that writes one', ''),
1776
+ .replace("and in channels.csv's", 'and in its'),
1734
1777
  };
1735
1778
  }
1736
1779
  /*
@@ -1745,7 +1788,8 @@ converted = new Set()) {
1745
1788
  if (diagnostic.code === 'DUPLICATE_LABEL' && / so its column is "/u.test(diagnostic.message)) {
1746
1789
  return {
1747
1790
  ...diagnostic,
1748
- message: diagnostic.message.replace(/ so its column is ("[^"]*")\.$/u, ` so it is named $1 in ${channelsFile}'s column cell.`),
1791
+ message: diagnostic.message.replace(/ so its column is ("[^"]*")\.$/u, ` so it is named $1 in ${channelsFile}'s column cell` +
1792
+ `${toStdout ? ' in any conversion that writes one' : ''}.`),
1749
1793
  };
1750
1794
  }
1751
1795
  if (diagnostic.code === 'DUPLICATE_LABEL' &&
@@ -1754,8 +1798,11 @@ converted = new Set()) {
1754
1798
  ...diagnostic,
1755
1799
  hint: 'Their names are suffixed with the signal number so they stay distinguishable. ' +
1756
1800
  (writesSignals
1757
- ? `--channels left this channel out, so its suffixed name appears in ` +
1758
- `${channelsFile}'s column cell and nowhere else.`
1801
+ ? toStdout
1802
+ ? `--channels left this channel out, and --stdout writes no ${channelsFile} for ` +
1803
+ `its suffixed name to appear in — convert to a directory for that.`
1804
+ : `--channels left this channel out, so its suffixed name appears in ` +
1805
+ `${channelsFile}'s column cell and nowhere else.`
1759
1806
  : '--annotations-only writes no signal table, so the suffixed names appear only ' +
1760
1807
  `in ${channelsFile}'s column cells.`),
1761
1808
  };
@@ -1770,11 +1817,19 @@ converted = new Set()) {
1770
1817
  rewrites above already name.
1771
1818
  */
1772
1819
  if (diagnostic.code === 'EMPTY_LABEL') {
1820
+ // Hedged under `--stdout`, where the cell is in a file that run does not write — the
1821
+ // wording 0.8.52 gave the same clause in NONPRINTABLE_LABEL, for the same reason.
1822
+ // Spelled out as its own string rather than by appending an s to the singular, which
1823
+ // reads as a number of seconds to the check that keeps those going through
1824
+ // `plainSeconds` — and does so whether it is in code or in a comment about it.
1825
+ const hedge = toStdout ? ' in any conversion that writes one' : '';
1826
+ const cell = `${channelsFile}'s column cell${hedge}`;
1827
+ const cells = `${channelsFile}'s column cells${hedge}`;
1773
1828
  return {
1774
1829
  ...diagnostic,
1775
1830
  message: diagnostic.message
1776
- .replace(/ It will appear as ("[^"]*")\.$/u, ` It is named $1 in ${channelsFile}'s column cell.`)
1777
- .replace('so both columns are suffixed with their position instead.', `so both are suffixed with their position in ${channelsFile}'s column cells instead.`),
1831
+ .replace(/ It will appear as ("[^"]*")\.$/u, ` It is named $1 in ${cell}.`)
1832
+ .replace('so both columns are suffixed with their position instead.', `so both are suffixed with their position in ${cells} instead.`),
1778
1833
  };
1779
1834
  }
1780
1835
  /*
@@ -1788,30 +1843,29 @@ converted = new Set()) {
1788
1843
  if (diagnostic.code === 'UNUSABLE_PHYSICAL_RANGE') {
1789
1844
  return {
1790
1845
  ...diagnostic,
1791
- hint: `No samples are converted ${because}, so there are no cells to leave ` +
1792
- `empty. ${channelsFile} still records the physical range the header gives.`,
1846
+ hint: `No samples are converted ${because}, so there are no cells to leave empty. ` +
1847
+ `${records('the physical range the header gives')}`,
1793
1848
  };
1794
1849
  }
1795
1850
  if (diagnostic.code === 'DEGENERATE_DIGITAL_RANGE') {
1796
1851
  return {
1797
1852
  ...diagnostic,
1798
- hint: `No samples are converted ${because}, so there are no cells to leave ` +
1799
- `empty. ${channelsFile} still records the digital range the header gives.`,
1853
+ hint: `No samples are converted ${because}, so there are no cells to leave empty. ` +
1854
+ `${records('the digital range the header gives')}`,
1800
1855
  };
1801
1856
  }
1802
1857
  if (diagnostic.code === 'DEGENERATE_PHYSICAL_RANGE') {
1803
1858
  return {
1804
1859
  ...diagnostic,
1805
1860
  message: diagnostic.message.replace('so every sample converts to the same value.', 'so every sample would convert to the same value.'),
1806
- hint: `No samples are converted ${because}. ${channelsFile} still records ` +
1807
- 'the calibration, one point wide.',
1861
+ hint: `No samples are converted ${because}. ${records('the calibration, one point wide')}`,
1808
1862
  };
1809
1863
  }
1810
1864
  if (diagnostic.code === 'INVERTED_PHYSICAL_RANGE') {
1811
1865
  return {
1812
1866
  ...diagnostic,
1813
- hint: `No samples are converted ${because}. ${channelsFile} records the ` +
1814
- 'physical minimum and maximum in the order the header gives them, inversion included.',
1867
+ hint: `No samples are converted ${because}. ` +
1868
+ `${records('the physical minimum and maximum in the order the header gives them, inversion included')}`,
1815
1869
  };
1816
1870
  }
1817
1871
  /*