OSCR

Real-time vectorcardiography simulator system.

Code ↔ Paper

3 matches between paragraphs of the paper and lines of its authors' code, computed by the harvester (lexical-v1). Click a colored paragraph or line to see its counterpart.

The 3 matches
  1. [1] § Results › Technical validation ↔ Supporting_Jupyter_Info/DTW_ECG_Reproducibility_V1.ipynb, lines 75 to 192 · score 0.90 · accumulated cost matrix, normalized DTW distance, optimal warping, raw signals, 1500 ms, map · Report a mismatch
  2. [2] § Results › Technical validation ↔ Supporting_Jupyter_Info/DTW_ECG_Reproducibility_V1.ipynb, lines 75 to 192 · score 0.74 · Accumulated cost matrix, optimal warping, Normalized DTW, clarity, alignment, metrics · Report a mismatch
  3. [3] § Materials and methods › Hardware design and implementation › Technical validation. ↔ Supporting_Jupyter_Info/DTW_ECG_Reproducibility_V1.ipynb, lines 31 to 73 · score 0.65 · Norwegian endurance athlete, physical signal, ECG database, v1, Physionet, waveforms · Report a mismatch

Paper

Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC

The paper is loaded when this pane is shown.

The authors' code

Jupyter notebook · 341 lines · 13 KB · MIT · 3 matches

  1. # %% [markdown]
  2. # # Supporting DTW_ECG Reproducibility
  3. # #### DTW analysis and figures, No additional analyses are introduced.
  4. # #### This program compares a synthetically generated signal and a real ECG signal for academic demonstration only. Not for clinical use.
  5. # ## Load simulated data
  6. # %%
  7. import numpy as np
  8. import matplotlib.pyplot as plt
  9. from scipy.signal import resample
  10. # 1. Load the data acquired from the graphic program (shape must be (n_samples, 3) LI, LII, LIII)
  11. sym_raw_data = np.load('mimic_ath16.npy')
  12. # 2. Resample data if is necessary. The shape of the array must be the same of the reference data array
  13. #single_wave_data = sym_raw_data[915:1220]
  14. #sym_data = resample(sym_raw_data, 360, axis=0)
  15. sym_data = sym_raw_data #Comment this line if a resaple was necessary
  16. # 3. test loaded data
  17. plt.figure(figsize=(7,2))
  18. plt.plot(sym_data[:, 0], linewidth=2)
  19. plt.grid(True, linestyle='--', alpha=0.7)
  20. plt.show()
  21. # 4. Check the shape to confirm
  22. print(f"Data shape: {sym_data.shape}")
  23. print(f"Data type: {sym_data.dtype}")
  24. print("This plot must show a single ECG wave")
  25. # %% [markdown]
  26. # ## Load reference data
  27. #
  28. # ##### ECG wave from Physionet (ath_016 snap from 850 to 2000 record) need (ath_016.hea, ath_016.dat files)
  29. # ##### SSingstad BJ. PhysioNet. 2022 [cited 2025 Mar 17]. Norwegian Endurance Athlete ECG Database v1.0.0. Available from: https://www.physionet.org/content/norwegian-athlete-ecg/1.0.0/
  30. # %%
  31. import wfdb
  32. from scipy.signal import butter, filtfilt
  33. # 1. Read the record
  34. # Note: 'record_name' should not include the extension (.hea or .dat) in the same jupyter nottebook folder
  35. record = wfdb.rdrecord('ath_016', sampfrom=850, sampto=2000, channels=[0, 1, 2])
  36. # 2. Extract the physical signal (the mV values)
  37. raw_data = record.p_signal
  38. ecg_data_b = raw_data[280:640] #sellect a single ECG wave
  39. # 3. remove the zero offsets if exist
  40. ### The ECG isoelectric line provides a zero-level reference that improves waveform comparison.
  41. ecg_data_b[:, 0] = ecg_data_b[:, 0]+0.02
  42. ecg_data_b[:, 1] = ecg_data_b[:, 1]+0.42
  43. ecg_data_b[:, 2] = ecg_data_b[:, 2]+0.33
  44. # 4. Filter the data
  45. sampling_rate = 500 #sampling_rate = 500.0 # Assume a sample rate of 1Hz, modify as needed
  46. num_samples = 300
  47. cutoff_frequency = 60 # Adjust as needed for desired cutoff frequency
  48. order = 4
  49. scale_factor = sampling_rate
  50. b, a = butter(order, cutoff_frequency, btype='low', fs=sampling_rate)
  51. filt_ref_data = filtfilt(b, a, ecg_data_b[:], axis=0) # Apply for denoising and improve the shape of the P signal
  52. # 5. test loaded data
  53. plt.figure(figsize=(7,2))
  54. plt.plot(filt_ref_data[:, 0], linewidth=2)
  55. plt.grid(True, linestyle='--', alpha=0.7)
  56. plt.show()
  57. # 6. Check the shape to confirm
  58. print(f"Data shape: {filt_ref_data.shape}")
  59. print(f"Data type: {filt_ref_data.dtype}")
  60. print("The reference data and the simulated data must match in dimensionality.")
  61. # %%
  62. import matplotlib.pyplot as plt
  63. import numpy as np
  64. from scipy import signal
  65. from scipy.spatial.distance import cdist
  66. # 1. Data Selection
  67. # Assuming lead index 1 (Lead II) for both
  68. s1 = filt_ref_data[:, 0] # Reference (Database)
  69. s2 = sym_data[:, 0] # User Generated
  70. # 2. Calculate Local Distance Matrix (Euclidean)
  71. # Compares every point in s1 with every point in s2
  72. cost_matrix = cdist(s1.reshape(-1, 1), s2.reshape(-1, 1), metric='euclidean')
  73. # 3. Compute Accumulated Cost Matrix
  74. # This is the core DTW logic to find the path of least resistance
  75. acc_cost_matrix = np.zeros(cost_matrix.shape)
  76. acc_cost_matrix[0, 0] = cost_matrix[0, 0]
  77. # Initialize first row and column
  78. for i in range(1, cost_matrix.shape[0]):
  79. acc_cost_matrix[i, 0] = cost_matrix[i, 0] + acc_cost_matrix[i-1, 0]
  80. for j in range(1, cost_matrix.shape[1]):
  81. acc_cost_matrix[0, j] = cost_matrix[0, j] + acc_cost_matrix[0, j-1]
  82. # Fill the matrix using the recursive rule
  83. for i in range(1, cost_matrix.shape[0]):
  84. for j in range(1, cost_matrix.shape[1]):
  85. acc_cost_matrix[i, j] = cost_matrix[i, j] + np.min([
  86. acc_cost_matrix[i-1, j], # Insertion
  87. acc_cost_matrix[i, j-1], # Deletion
  88. acc_cost_matrix[i-1, j-1] # Match
  89. ])
  90. # 4. Backtracking: Find the Optimal Warping Path
  91. path = []
  92. i, j = acc_cost_matrix.shape[0] - 1, acc_cost_matrix.shape[1] - 1
  93. path.append((i, j))
  94. while i > 0 or j > 0:
  95. options = []
  96. if i > 0: options.append((acc_cost_matrix[i-1, j], (i-1, j)))
  97. if j > 0: options.append((acc_cost_matrix[i, j-1], (i, j-1)))
  98. if i > 0 and j > 0: options.append((acc_cost_matrix[i-1, j-1], (i-1, j-1)))
  99. # Choose the neighbor with the lowest accumulated cost
  100. min_val, (i, j) = min(options, key=lambda x: x[0])
  101. path.append((i, j))
  102. path = np.array(path[::-1]) # Reverse to start from (0,0)
  103. # 5. Statistical Similarity Metrics
  104. # Calculate Cross-Correlation to find natural shift
  105. correlation = signal.correlate(s1 - np.mean(s1), s2 - np.mean(s2), mode='full')
  106. lags = signal.correlation_lags(len(s1), len(s2), mode='full')
  107. found_lag = lags[np.argmax(correlation)]
  108. # Calculate Similarity Percentage (Pearson Correlation) at Lag 0
  109. similarity_pct = np.corrcoef(s1, s2)[0, 1] * 100
  110. # Calculate DTW Metrics
  111. dtw_distance = acc_cost_matrix[-1, -1]
  112. norm_dtw = dtw_distance / (len(s1) + len(s2))
  113. # --- Visualization ---
  114. # --- Global font Settings ---
  115. plt.rcParams.update({
  116. 'font.size': 18, # Base font size
  117. 'axes.titlesize': 18, # Subplot titles
  118. 'axes.labelsize': 18, # X and Y labels
  119. 'xtick.labelsize': 14, # X-axis tick numbers
  120. 'ytick.labelsize': 14, # Y-axis tick numbers
  121. 'legend.fontsize': 14, # Legend text
  122. 'figure.titlesize': 24 # Main figure title
  123. })
  124. %config InlineBackend.figure_format = 'retina'
  125. plt.figure(figsize=(17, 5))
  126. # Plot A: Raw Signals
  127. plt.subplot(1, 3, 1)
  128. plt.plot(s1, label='Database (Ref)', color='blue', linewidth=1.5)
  129. plt.plot(s2, label='User (Query)', color='black', linewidth=1.5, alpha=0.8)
  130. plt.title("a. Raw Signals (Natural State)")
  131. plt.xlabel("Samples")
  132. plt.ylabel("Amplitude (mV)")
  133. plt.legend()
  134. plt.grid(alpha=0.2)
  135. # Plot B: Alignment
  136. plt.subplot(1, 3, 2)
  137. for (map_x, map_y) in path[::15]: # Sample every 15 for visual clarity
  138. plt.plot([map_x, map_y], [s1[map_x], s2[map_y] + 1.5], color='gray', alpha=0.3)
  139. plt.plot(s1, label='Database', color='blue')
  140. plt.plot(s2 + 1.5, label='User (+1.5)', color='black')
  141. plt.title("b. Dynamic Time Warping Alignment")
  142. plt.xlabel("Samples")
  143. plt.legend(loc='lower right')
  144. # Plot C: Cost Matrix & Summary
  145. plt.subplot(1, 3, 3)
  146. plt.imshow(acc_cost_matrix.T, origin='lower', cmap='viridis', aspect='auto')
  147. plt.plot(path[:, 0], path[:, 1], 'w-', linewidth=2, label='Optimal Path')
  148. plt.title(f"c. Accumulated Cost\nSimilarity: {similarity_pct:.2f}% | Norm DTW: {norm_dtw:.4f}")
  149. plt.colorbar(label='Cost Value')
  150. plt.xlabel('Database Index')
  151. plt.ylabel('User Index')
  152. plt.tight_layout()
  153. #plt.savefig('ecg_similarity.svg', dpi=300, bbox_inches='tight') #This save an image of the plot
  154. plt.show()
  155. print(f"Summary Report:")
  156. print(f"----------------")
  157. print(f"Pearson Similarity: {similarity_pct:.2f}%")
  158. print(f"Natural Lag: {found_lag} samples")
  159. print(f"Normalized DTW: {norm_dtw:.4f}")
  160. # %% [markdown]
  161. # ## Original Vs Warped Alignment and Similarity
  162. # %% [markdown]
  163. # ##### This ensures the correlation measures morphology (the shape of the wave) rather than just timing, since the ECG signals often have slight phase shifts in the timing of the P, QRS, and T waves.
  164. # ##### (V. Tuzcu and S. Nas, 'Dynamic time warping as a novel tool in pattern recognition of ECG changes in heart rhythm disturbances,' 2005 IEEE International Conference on Systems, Man and Cybernetics, Waikoloa, HI, USA, 2005, pp. 182-186 Vol. 1, doi: 10.1109/ICSMC.2005.1571142.
  165. # %%
  166. %config InlineBackend.figure_format = 'retina'
  167. from fastdtw import fastdtw
  168. from scipy.stats import pearsonr
  169. from matplotlib.ticker import MultipleLocator, FuncFormatter
  170. threshold = 0.9 # Similarity threshold, a warped correlation > 0.85 is typically considered a "high fidelity"
  171. plt.rcParams.update({
  172. 'font.size': 14, # Base font size
  173. 'axes.titlesize': 14, # Subplot titles
  174. 'axes.labelsize': 10, # X and Y labels
  175. 'xtick.labelsize': 8, # X-axis tick numbers
  176. 'ytick.labelsize': 8, # Y-axis tick numbers
  177. 'legend.fontsize': 8, # Legend text
  178. 'figure.titlesize': 12 # Main figure title
  179. })
  180. fig, axs = plt.subplots(3, 2, figsize=(10, 7), sharex=True, sharey=True)
  181. summary_data = []
  182. leads = ['Lead I', 'Lead II', 'Lead III']
  183. colors = ['teal', 'darkorange', 'crimson']
  184. for i in range(3):
  185. # 1. Plot - Side-by-Side Comparison
  186. # --- Column 0: Synthetic Data (symu_data) ---
  187. axs[i, 0].plot(sym_data[:, i], label='Synthetic Data', color=colors[i], linewidth=1)
  188. axs[i, 0].plot(filt_ref_data[:, i], label='Real Data', color='black', linewidth=1)
  189. axs[i, 0].set_ylabel(f'{leads[i]}\n(mV)')
  190. axs[i, 0].grid(True, linestyle='--', alpha=0.6)
  191. axs[i, 0].legend(loc='lower right')
  192. # 2. Prepare data
  193. ref = filt_ref_data[:, i]
  194. query = sym_data[:, i]
  195. # 3. Compute DTW Alignment
  196. distance, path = fastdtw(ref, query, dist=lambda x, y: np.abs(x - y))
  197. # 4. "Warp" the signals using the path to align them in time
  198. ref_aligned = np.array([ref[p[0]] for p in path])
  199. query_aligned = np.array([query[p[1]] for p in path])
  200. # 5. Calculate Warped Correlation
  201. #Pearson correlation is inherently invariant to amplitude scaling.
  202. correlation, _ = pearsonr(ref_aligned, query_aligned)
  203. is_correlated = "Yes" if correlation >= threshold else "No"
  204. summary_data.append([leads[i], distance, correlation, is_correlated])
  205. # 6. Plotting
  206. # We plot against a generic index because the path changes the 'time' scale
  207. axs[i, 1].plot(ref_aligned, label=f'Real {leads[i]} (Aligned)', color='black', alpha=0.5)
  208. axs[i, 1].plot(query_aligned, label=f'Sym {leads[i]} (Aligned)', color=colors[i], linestyle='--')
  209. axs[i, 1].set_title(f"{leads[i]}: Warped Correlation = {correlation:.3f} ({is_correlated})")
  210. axs[i, 0].xaxis.set_major_locator(MultipleLocator(100)) # Major ticks every 100 points
  211. axs[i, 0].xaxis.set_minor_locator(MultipleLocator(20)) # Minor ticks every 20 points
  212. axs[i, 0].yaxis.set_major_locator(MultipleLocator(0.6)) # Major ticks every 5 units
  213. axs[i, 0].yaxis.set_minor_locator(MultipleLocator(0.15)) # Minor ticks every 1 unit
  214. axs[i, 0].grid(which='major', color='black', linestyle='--')
  215. axs[i, 0].grid(which='minor', color='#CCCCCC', linestyle=':')
  216. axs[i, 0].grid(True, which='both')
  217. axs[i, 1].legend(loc='lower right')
  218. #axs[i, 1].grid(True, alpha=0.3)
  219. # Set titles for the columns
  220. axs[0, 0].set_title('Original Signals')
  221. #axs[0, 1].set_title('Real Filtered Signal', fontweight='bold')
  222. # Set shared X-axis label
  223. axs[2, 0].set_xlabel('Samples')
  224. axs[2, 1].set_xlabel('Elastic time shifting, to compare P, QRS and T waves')
  225. plt.style.use('seaborn-v0_8-whitegrid')
  226. plt.savefig('ecg_plot_three_leads.svg', dpi=300, bbox_inches='tight')
  227. plt.tight_layout()
  228. plt.show()
  229. # 7. --- Print Final Analysis ---
  230. print(f"{'Lead':<10} | {'DTW Dist':<12} | {'Warped Corr':<12} | {'Status'}")
  231. print("-" * 55)
  232. correlated_count = 0
  233. for row in summary_data:
  234. print(f"{row[0]:<10} | {row[1]:<12.2f} | {row[2]:<12.4f} | {row[3]}")
  235. if row[3] == "Yes":
  236. correlated_count += 1
  237. print(f"\nResult: {correlated_count} out of 3 leads are highly correlated.")
  238. # %% [markdown]
  239. # ## Dynamic Time Warping Alignment of LI, LII, LII
  240. # #### Visualisation of the three leads using fastdtw 'Python' library
  241. # %%
  242. fig, axs = plt.subplots(1, 3, figsize=(15, 4.5), sharex=True, sharey=True)
  243. summary_data = []
  244. leads = ['Lead I', 'Lead II', 'Lead III']
  245. colors = ['teal', 'darkorange', 'crimson']
  246. for i in range(3):
  247. # 2. Prepare data
  248. ref = filt_ref_data[:, i]
  249. query = sym_data[:, i]
  250. # 3. Compute DTW Alignment
  251. distance, path = fastdtw(ref, query, dist=lambda x, y: np.abs(x - y))
  252. # 4. "Warp" the signals using the path to align them in time
  253. ref_aligned = np.array([ref[p[0]] for p in path])
  254. query_aligned = np.array([query[p[1]] for p in path])
  255. # Assuming you already ran: distance, path = fastdtw(ref_lead, made_lead)
  256. # Extract the path indices
  257. path_x = [p[0] for p in path]
  258. path_y = [p[1] for p in path]
  259. # 1. Plot the Warping Path
  260. axs[i].plot(path_x, path_y, color='blue', linewidth=2, label='Warping Path')
  261. # 2. Plot a Reference Diagonal (Perfect match line)
  262. axs[i].plot([0, 320], [0, 320], color='red', linestyle='--', alpha=0.5, label='Ideal Diagonal')
  263. # Labeling for your paper
  264. axs[i].set_title(f"{leads[i]}")
  265. axs[i].legend(loc='lower right')
  266. #axs[i].set_title("DTW Warping Path: Natural vs. Synthetic ECG")
  267. axs[i].set_xlabel("Reference Signal Index (PhysioNet)")
  268. axs[i].grid(True, alpha=0.3)
  269. axs[i].legend()
  270. axs[0].set_ylabel("Synthetic Signal Index")
  271. plt.show()

DTW_ECG_Reproducibility_V1.ipynb at commit 369ddbe, under MIT · at the source

Overview

Authors: William R Rodriguez1, Hernan A Bernal2, Diana Patricia Amador-Munoz3
  1. Department of Electronic Engineering, Faculty of Engineering, Pontificia Universidad Javeriana, Bogota, Colombia
  2. School of Medicine and Health Sciences, biomedical engineering. Universidad del Rosario, Bogota, Colombia
  3. School of Medicine and Health Sciences, Neurovitae research Center, Universidad del Rosario, Bogota, Colombia
Institutions: Pontificia Universidad Javeriana (Colombia); Universidad del Rosario (Colombia)
Journal: PloS one, volume 21, issue 3, article e0345612
Dates: received 22 October 2025; accepted 6 March 2026; published online 31 March 2026
Type: Research article · Language: English
License: CC BY
Identifiers: DOI 10.1371/journal.pone.0345612 · PMID 41915705 · PMCID PMC13037978 · OpenAlex W7147582804
Open access: gold, a free copy (OpenAlex)
Status: code verified (how the code is found and verified)
Categories: other (modality), human (organism), methods / tools (subfield)
Methods: Smoothing, state filtering, decompositions, Evoked potentials
MeSH: Computer Simulation*, Vectorcardiography*, Electrocardiography, Humans, Pilot Projects, Signal Processing, Computer-Assisted, Software (* major topic)
Topic: ECG Monitoring and Analysis (Cardiology and Cardiovascular Medicine, Medicine), according to OpenAlex
Citations: not cited yet (Europe PMC); 46 references in the paper

Abstract

Vectorcardiography provides a spatial orientation and magnitude of the electrical activity of the heart, but its complexity and lack of interactive resources have limited its application in medical and bioengineering education. To bridge this pedagogical gap, we developed a low-cost, real-time vectorcardiography simulator integrating a physical wet-lab interface and digital signal processing. The hardware setup consists of a conductive medium and electrodes, enabling users to manually simulate a cardiac vector and observe the resultant electrophysiological signal consequences in real time. The system was validated through three complementary methods: theoretical conformity analysis, emulation of real ECG data from database, and user-driven waveform generation tests. A pilot study with medical students and instructors provided empirical evidence of the educational value of the device, indicating that the active, hands-on nature of the system might foster deeper cognitive engagement and facilitates the integration of complex electrophysiological concepts. By providing open-source software and cost-effective hardware, this simulator offers a scalable solution to enhance cardiac electrophysiology education and promote the broader adoption of VCG in clinical practice.

Reproduced under the paper's license (CC BY), from the paper cited above.

Repositories

Its files are read in the Code ↔ Paper reader above, with 3 matches between paragraphs and lines of code.

Zenodo 18486986

License: MIT
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: DataCite
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Matplotlib (1 file), NumPy (1 file)
Availability: 1 check, the latest on 30 September 2026: the link answers (HTTP 200)
  • 30 September 2026: the link answers (HTTP 200)
5 files

hbprojects/vectorial-plot-rpi-pico

License: MIT
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Commit: 369ddbe2412ce6beae17c29c457368a174ea957b, 23 March 2026
Languages: Python (3), Jupyter (1)
Size: 19 files, 4 scripts
Software Heritage: not archived
Found in: DataCite
Holds: README, license file, 1 notebook
Not found: CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Matplotlib (2 files), NumPy (2 files), SciPy (1 file), WFDB Python (1 file)
Availability: 1 check, the latest on 30 September 2026: the link answers
  • 30 September 2026: the link answers
6 files

Zenodo 18445797

License: MIT
State: the link answers, verified on 30 September 2026
Evidence: files inventoried
Size: 1 file
Software Heritage: not checked
Found in: DataCite
Not found: README, license file, CITATION.cff, environment file, tests, continuous integration, documentation
Tools: Matplotlib (1 file), NumPy (1 file)
Availability: 1 check, the latest on 30 September 2026: the link answers (HTTP 200)
  • 30 September 2026: the link answers (HTTP 200)
5 files

Tracing map

Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.

What the map holds:

  • 3 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
  • 10 scripts, each with its path and the digest of its content;
  • 3 matches between paragraphs of the paper and lines of the code (method lexical-v1);
  • neither the text of the paper nor the code itself.

Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.

Data

Datasets cited

Data Availability

All relevant data are within the manuscript and its Supporting Information files.

Reproduced under the paper's license (CC BY), from the paper cited above.

Versions

The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.

Version 1, 30 September 2026: the first record

Recorded: type, language, journal, volume, issue, pages, dates, 3 authors, 7 MeSH terms, 2 funders, 34 references.

Cite

This paper

Rodriguez, W. R., Bernal, H. A., & Amador-Munoz, D. P. (2026). Real-time vectorcardiography simulator system. PloS one, 21(3), e0345612. https://doi.org/10.1371/journal.pone.0345612

BibTeX

@article{rodriguez2026real,
author = {Rodriguez, William R and Bernal, Hernan A and Amador-Munoz, Diana Patricia},
title = {{Real-time vectorcardiography simulator system}},
journal = {PloS one},
year = {2026},
month = mar,
volume = {21},
number = {3},
pages = {e0345612},
publisher = {PLOS},
issn = {1932-6203},
doi = {10.1371/journal.pone.0345612},
url = {https://doi.org/10.1371/journal.pone.0345612},
pmid = {41915705},
pmcid = {PMC13037978}
}

RIS

TY - JOUR
AU - Rodriguez, William R
AU - Bernal, Hernan A
AU - Amador-Munoz, Diana Patricia
TI - Real-time vectorcardiography simulator system
T2 - PloS one
J2 - PLoS One
PY - 2026
DA - 2026/03/31
VL - 21
IS - 3
SP - e0345612
SN - 1932-6203
PB - PLOS
DO - 10.1371/journal.pone.0345612
UR - https://doi.org/10.1371/journal.pone.0345612
LA - en
ER -

CSL-JSON

{
"id": "10.1371/journal.pone.0345612",
"type": "article-journal",
"title": "Real-time vectorcardiography simulator system",
"container-title": "PloS one",
"author": [
{
"family": "Rodriguez",
"given": "William R"
},
{
"family": "Bernal",
"given": "Hernan A"
},
{
"family": "Amador-Munoz",
"given": "Diana Patricia"
}
],
"container-title-short": "PLoS One",
"volume": "21",
"issue": "3",
"page": "e0345612",
"DOI": "10.1371/journal.pone.0345612",
"PMID": "41915705",
"PMCID": "PMC13037978",
"ISSN": "1932-6203",
"publisher": "PLOS",
"URL": "https://doi.org/10.1371/journal.pone.0345612",
"language": "en",
"issued": {
"date-parts": [
[
2026,
3,
31
]
]
}
}

The tracing map gets a citation of its own once an author has validated it and it has a DOI.

Similar papers

The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.

[1] doi:10.7554/elife.100605 [code]
Age-related changes in ‘cortical’ 1/f dynamics are linked to cardiac activity
Journal: n/a
In common: WFDB Python, SciPy, Matplotlib, 1 other tool, other, 1 reference
[2] doi:10.1007/s41666-025-00209-5 [code]
A Hybrid Bidirectional Deep Learning Model Using HRV for Prediction of ICU Mortality Risk in TBI Patients.
Journal: Journal of healthcare informatics research
In common: WFDB Python, SciPy, Matplotlib, 1 other tool, other, 1 reference
[3] doi:10.1038/s41746-025-02237-2 [code]
SLEEPYLAND: trust begins with fair evaluation of automatic sleep staging models.
Journal: NPJ digital medicine
In common: WFDB Python, SciPy, Matplotlib, 1 other tool, methods / tools, 1 reference
[4] doi:10.1038/s41467-026-75134-1 [code]
Body surface potential mapping of the cortico-muscular axis using smart textile electrode arrays.
Journal: Nature communications
In common: WFDB Python, SciPy, Matplotlib, 1 other tool, other
[5] doi:10.1186/s40001-025-03540-0 [code]
The association between white blood cell-to-hemoglobin ratio and mortality risk in critical traumatic brain injury: insights from MIMIC-IV retrospective analysis.
Journal: European journal of medical research
In common: WFDB Python, SciPy, Matplotlib, 1 other tool, other
[6] doi:10.1097/js9.0000000000003143 [code]
Multimodal deep learning to predict postoperative major adverse cardiac and cerebrovascular events after noncardiac surgery.
Journal: International journal of surgery (London, England)
In common: WFDB Python, SciPy, Matplotlib, 1 other tool, other
[7] doi:10.1038/s41598-025-11175-8 [code]
Impact of mannitol on mortality in patients with non-traumatic intracerebral haemorrhage and acute kidney injury: a retrospective study.
Journal: Scientific reports
In common: WFDB Python, SciPy, Matplotlib, 1 other tool, other
[8] doi:10.3389/fneur.2023.1271391 [code]
Association between lactate/albumin ratio and 28-day all-cause mortality in ischemic stroke patients without reperfusion therapy: a retrospective analysis of the MIMIC-IV database.
Journal: Frontiers in neurology
In common: WFDB Python, SciPy, Matplotlib, 1 other tool, other
[9] doi:10.1038/s41598-025-18479-9 [code]
Epileptic seizure detection from electroencephalogram signals based on 1D CNN-LSTM deep learning model using discrete wavelet transform.
Journal: Scientific reports
In common: WFDB Python, SciPy, Matplotlib, 1 other tool, methods / tools
[10] doi:10.1038/s42003-026-10957-8 [code]
Brain defence by the extracellular matrix protein Cochlin.
Journal: Communications biology
In common: WFDB Python, SciPy, Matplotlib, 1 other tool

Contribute

The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.

Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.

Add the badge to the code's README

OSCR: the badge of this paper

If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.

Markdown
<!-- oscr-badge:start -->
[![OSCR](https://openscicode.org/badge/doi/10.1371/journal.pone.0345612.svg)](https://openscicode.org/badge/doi/10.1371/journal.pone.0345612)
<!-- oscr-badge:end -->
reStructuredText
.. oscr-badge:start

.. image:: https://openscicode.org/badge/doi/10.1371/journal.pone.0345612.svg
   :target: https://openscicode.org/badge/doi/10.1371/journal.pone.0345612
   :alt: OSCR

.. oscr-badge:end
HTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/doi/10.1371/journal.pone.0345612"><img src="https://openscicode.org/badge/doi/10.1371/journal.pone.0345612.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->

On GitHub, open the README, choose Edit (the pencil), paste the snippet under the title, then "Commit changes".

If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge page.

Request its removal

To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).

Discussion, reproductions, activity

Discussion: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.

Report a mismatch between the code and the paper · Report a code error (signed in)

Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.

Report a reproduction failure (signed in)

Versions of its code: the releases of its code tied to a version of this paper (the preprint, the accepted manuscript, the version of record…), each with the tracing map versioned with it.

Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.