SCUBA implements a storage format-agnostic API for single-cell data access in R

preprint OA: closed
Full text JSON View at publisher

Abstract

While robust tools exist for the analysis of single-cell datasets in both Python and R, interoperability is limited, and analysis tools generally only accept one object class. Considerable programming expertise is required to integrate tools across package ecosystems into a comprehensive analysis, due to their differing languages and internal data structures. This complicates validation of results and leads to inconsistent visualizations between analysis suites. Conversion between object formats is the most common solution, but this is difficult and error-prone due to the rapid pace of development of the analysis suites and their underlying data structures. To address this, we created SCUBA (Single-Cell Unified Backend API), an R package that implements a unified data access API for all common R and Python single-cell object formats. SCUBA extends the data access approach from the widely used Seurat package to SingleCellExperiment and anndata objects. SCUBA also implements new data-specific access functions for all supported object types. Performance scales well across all SCUBA-supported formats. In addition to performance, SCUBA offers several advantages over object conversion for the visualization and further analysis of pre-processed single-cell data. First, SCUBA extracts only data required for the operation at hand, leaving the original object unmodified. This process is simpler, less error prone, and less memory intensive than object conversion, which operates on the entire dataset. Second, code written with SCUBA can use any supported object class as input, with simple and consistent syntax across object formats. This allows a single analysis script or package (like our interactive single-cell browser, scExploreR) to work seamlessly with multiple object types, reducing the complexity of the code and improving both readability and reproducibility. Adoption of SCUBA will ultimately improve collaboration and reproducible research in single-cell analysis by lowering the barriers between package ecosystems.
Full text 278,874 characters · extracted from preprint-html · click to expand
SCUBA implements a storage format-agnostic API... | F1000Research "use strict";function _typeof(t){return(_typeof="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(t){return typeof t}:function(t){return t&&"function"==typeof Symbol&&t.constructor===Symbol&&t!==Symbol.prototype?"symbol":typeof t})(t)}!function(){var t=function(){var t,e,o=[],n=window,r=n;for(;r;){try{if(r.frames.__tcfapiLocator){t=r;break}}catch(t){}if(r===n.top)break;r=r.parent}t||(!function t(){var e=n.document,o=!!n.frames.__tcfapiLocator;if(!o)if(e.body){var r=e.createElement("iframe");r.style.cssText="display:none",r.name="__tcfapiLocator",e.body.appendChild(r)}else setTimeout(t,5);return!o}(),n.__tcfapi=function(){for(var t=arguments.length,n=new Array(t),r=0;r 3&&2===parseInt(n[1],10)&&"boolean"==typeof n[3]&&(e=n[3],"function"==typeof n[2]&&n[2]("set",!0)):"ping"===n[0]?"function"==typeof n[2]&&n[2]({gdprApplies:e,cmpLoaded:!1,cmpStatus:"stub"}):o.push(n)},n.addEventListener("message",(function(t){var e="string"==typeof t.data,o={};if(e)try{o=JSON.parse(t.data)}catch(t){}else o=t.data;var n="object"===_typeof(o)&&null!==o?o.__tcfapiCall:null;n&&window.__tcfapi(n.command,n.version,(function(o,r){var a={__tcfapiReturn:{returnValue:o,success:r,callId:n.callId}};t&&t.source&&t.source.postMessage&&t.source.postMessage(e?JSON.stringify(a):a,"*")}),n.parameter)}),!1))};"undefined"!=typeof module?module.exports=t:t()}(); dataLayer = dataLayer || []; // Standard GTM initialization - Google Consent Mode handles consent automatically (function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl+ '>m_auth=hzk0Vc3qFsQYhCrIoHz68A>m_preview=env-1>m_cookies_win=x';f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-MWFK8L5J'); ;window.NREUM||(NREUM={});NREUM.init={distributed_tracing:{enabled:true},privacy:{cookies_enabled:true},ajax:{deny_list:["bam.nr-data.net"]}}; ;NREUM.loader_config={accountID:"438030",trustKey:"438030",agentID:"772317073",licenseKey:"97f8f67f26",applicationID:"772317073"} ;NREUM.info={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net",licenseKey:"97f8f67f26",applicationID:"772317073",sa:1} ;/*! For license information please see nr-loader-spa-1.236.0.min.js.LICENSE.txt */ (()=>{"use strict";var e,t,r={5763:(e,t,r)=>{r.d(t,{P_:()=>l,Mt:()=>g,C5:()=>s,DL:()=>v,OP:()=>T,lF:()=>D,Yu:()=>y,Dg:()=>h,CX:()=>c,GE:()=>b,sU:()=>_});var n=r(8632),i=r(9567);const o={beacon:n.ce.beacon,errorBeacon:n.ce.errorBeacon,licenseKey:void 0,applicationID:void 0,sa:void 0,queueTime:void 0,applicationTime:void 0,ttGuid:void 0,user:void 0,account:void 0,product:void 0,extra:void 0,jsAttributes:{},userAttributes:void 0,atts:void 0,transactionName:void 0,tNamePlain:void 0},a={};function s(e){if(!e)throw new Error("All info objects require an agent identifier!");if(!a[e])throw new Error("Info for ".concat(e," was never set"));return a[e]}function c(e,t){if(!e)throw new Error("All info objects require an agent identifier!");a[e]=(0,i.D)(t,o),(0,n.Qy)(e,a[e],"info")}var u=r(7056);const d=()=>{const e={blockSelector:"[data-nr-block]",maskInputOptions:{password:!0}};return{allow_bfcache:!0,privacy:{cookies_enabled:!0},ajax:{deny_list:void 0,enabled:!0,harvestTimeSeconds:10},distributed_tracing:{enabled:void 0,exclude_newrelic_header:void 0,cors_use_newrelic_header:void 0,cors_use_tracecontext_headers:void 0,allowed_origins:void 0},session:{domain:void 0,expiresMs:u.oD,inactiveMs:u.Hb},ssl:void 0,obfuscate:void 0,jserrors:{enabled:!0,harvestTimeSeconds:10},metrics:{enabled:!0},page_action:{enabled:!0,harvestTimeSeconds:30},page_view_event:{enabled:!0},page_view_timing:{enabled:!0,harvestTimeSeconds:30,long_task:!1},session_trace:{enabled:!0,harvestTimeSeconds:10},harvest:{tooManyRequestsDelay:60},session_replay:{enabled:!1,harvestTimeSeconds:60,sampleRate:.1,errorSampleRate:.1,maskTextSelector:"*",maskAllInputs:!0,get blockClass(){return"nr-block"},get ignoreClass(){return"nr-ignore"},get maskTextClass(){return"nr-mask"},get blockSelector(){return e.blockSelector},set blockSelector(t){e.blockSelector+=",".concat(t)},get maskInputOptions(){return e.maskInputOptions},set maskInputOptions(t){e.maskInputOptions={...t,password:!0}}},spa:{enabled:!0,harvestTimeSeconds:10}}},f={};function l(e){if(!e)throw new Error("All configuration objects require an agent identifier!");if(!f[e])throw new Error("Configuration for ".concat(e," was never set"));return f[e]}function h(e,t){if(!e)throw new Error("All configuration objects require an agent identifier!");f[e]=(0,i.D)(t,d()),(0,n.Qy)(e,f[e],"config")}function g(e,t){if(!e)throw new Error("All configuration objects require an agent identifier!");var r=l(e);if(r){for(var n=t.split("."),i=0;i {r.d(t,{D:()=>i});var n=r(50);function i(e,t){try{if(!e||"object"!=typeof e)return(0,n.Z)("Setting a Configurable requires an object as input");if(!t||"object"!=typeof t)return(0,n.Z)("Setting a Configurable requires a model to set its initial properties");const r=Object.create(Object.getPrototypeOf(t),Object.getOwnPropertyDescriptors(t)),o=0===Object.keys(r).length?e:r;for(let a in o)if(void 0!==e[a])try{"object"==typeof e[a]&&"object"==typeof t[a]?r[a]=i(e[a],t[a]):r[a]=e[a]}catch(e){(0,n.Z)("An error occurred while setting a property of a Configurable",e)}return r}catch(e){(0,n.Z)("An error occured while setting a Configurable",e)}}},6818:(e,t,r)=>{r.d(t,{Re:()=>i,gF:()=>o,q4:()=>n});const n="1.236.0",i="PROD",o="CDN"},385:(e,t,r)=>{r.d(t,{FN:()=>a,IF:()=>u,Nk:()=>f,Tt:()=>s,_A:()=>o,il:()=>n,pL:()=>c,v6:()=>i,w1:()=>d});const n="undefined"!=typeof window&&!!window.document,i="undefined"!=typeof WorkerGlobalScope&&("undefined"!=typeof self&&self instanceof WorkerGlobalScope&&self.navigator instanceof WorkerNavigator||"undefined"!=typeof globalThis&&globalThis instanceof WorkerGlobalScope&&globalThis.navigator instanceof WorkerNavigator),o=n?window:"undefined"!=typeof WorkerGlobalScope&&("undefined"!=typeof self&&self instanceof WorkerGlobalScope&&self||"undefined"!=typeof globalThis&&globalThis instanceof WorkerGlobalScope&&globalThis),a=""+o?.location,s=/iPad|iPhone|iPod/.test(navigator.userAgent),c=s&&"undefined"==typeof SharedWorker,u=(()=>{const e=navigator.userAgent.match(/Firefox[/\s](\d+\.\d+)/);return Array.isArray(e)&&e.length>=2?+e[1]:0})(),d=Boolean(n&&window.document.documentMode),f=!!navigator.sendBeacon},1117:(e,t,r)=>{r.d(t,{w:()=>o});var n=r(50);const i={agentIdentifier:"",ee:void 0};class o{constructor(e){try{if("object"!=typeof e)return(0,n.Z)("shared context requires an object as input");this.sharedContext={},Object.assign(this.sharedContext,i),Object.entries(e).forEach((e=>{let[t,r]=e;Object.keys(i).includes(t)&&(this.sharedContext[t]=r)}))}catch(e){(0,n.Z)("An error occured while setting SharedContext",e)}}}},8e3:(e,t,r)=>{r.d(t,{L:()=>d,R:()=>c});var n=r(2177),i=r(1284),o=r(4322),a=r(3325);const s={};function c(e,t){const r={staged:!1,priority:a.p[t]||0};u(e),s[e].get(t)||s[e].set(t,r)}function u(e){e&&(s[e]||(s[e]=new Map))}function d(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"feature";if(u(e),!e||!s[e].get(t))return a(t);s[e].get(t).staged=!0;const r=[...s[e]];function a(t){const r=e?n.ee.get(e):n.ee,a=o.X.handlers;if(r.backlog&&a){var s=r.backlog[t],c=a[t];if(c){for(var u=0;s&&u {let[t,r]=e;return r.staged}))&&(r.sort(((e,t)=>e[1].priority-t[1].priority)),r.forEach((e=>{let[t]=e;a(t)})))}function f(e,t){var r=e[1];(0,i.D)(t[r],(function(t,r){var n=e[0];if(r[0]===n){var i=r[1],o=e[3],a=e[2];i.apply(o,a)}}))}},2177:(e,t,r)=>{r.d(t,{c:()=>f,ee:()=>u});var n=r(8632),i=r(2210),o=r(1284),a=r(5763),s="nr@context";let c=(0,n.fP)();var u;function d(){}function f(e){return(0,i.X)(e,s,l)}function l(){return new d}function h(){u.aborted=!0,u.backlog={}}c.ee?u=c.ee:(u=function e(t,r){var n={},c={},f={},g=!1;try{g=16===r.length&&(0,a.OP)(r).isolatedBacklog}catch(e){}var p={on:b,addEventListener:b,removeEventListener:y,emit:v,get:x,listeners:w,context:m,buffer:A,abort:h,aborted:!1,isBuffering:E,debugId:r,backlog:g?{}:t&&"object"==typeof t.backlog?t.backlog:{}};return p;function m(e){return e&&e instanceof d?e:e?(0,i.X)(e,s,l):l()}function v(e,r,n,i,o){if(!1!==o&&(o=!0),!u.aborted||i){t&&o&&t.emit(e,r,n);for(var a=m(n),s=w(e),d=s.length,f=0;fn,p:()=>i});var n=r(2177).ee.get("handle");function i(e,t,r,i,o){o?(o.buffer([e],i),o.emit(e,t,r)):(n.buffer([e],i),n.emit(e,t,r))}},4322:(e,t,r)=>{r.d(t,{X:()=>o});var n=r(5546);o.on=a;var i=o.handlers={};function o(e,t,r,o){a(o||n.E,i,e,t,r)}function a(e,t,r,i,o){o||(o="feature"),e||(e=n.E);var a=t[o]=t[o]||{};(a[r]=a[r]||[]).push([e,i])}},3239:(e,t,r)=>{r.d(t,{bP:()=>s,iz:()=>c,m$:()=>a});var n=r(385);let i=!1,o=!1;try{const e={get passive(){return i=!0,!1},get signal(){return o=!0,!1}};n._A.addEventListener("test",null,e),n._A.removeEventListener("test",null,e)}catch(e){}function a(e,t){return i||o?{capture:!!e,passive:i,signal:t}:!!e}function s(e,t){let r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=arguments.length>3?arguments[3]:void 0;window.addEventListener(e,t,a(r,n))}function c(e,t){let r=arguments.length>2&&void 0!==arguments[2]&&arguments[2],n=arguments.length>3?arguments[3]:void 0;document.addEventListener(e,t,a(r,n))}},4402:(e,t,r)=>{r.d(t,{Ht:()=>u,M:()=>c,Rl:()=>a,ky:()=>s});var n=r(385);const i="xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";function o(e,t){return e?15&e[t]:16*Math.random()|0}function a(){const e=n._A?.crypto||n._A?.msCrypto;let t,r=0;return e&&e.getRandomValues&&(t=e.getRandomValues(new Uint8Array(31))),i.split("").map((e=>"x"===e?o(t,++r).toString(16):"y"===e?(3&o()|8).toString(16):e)).join("")}function s(e){const t=n._A?.crypto||n._A?.msCrypto;let r,i=0;t&&t.getRandomValues&&(r=t.getRandomValues(new Uint8Array(31)));const a=[];for(var s=0;s {r.d(t,{Bq:()=>n,Hb:()=>o,oD:()=>i});const n="NRBA",i=144e5,o=18e5},7894:(e,t,r)=>{function n(){return Math.round(performance.now())}r.d(t,{z:()=>n})},7243:(e,t,r)=>{r.d(t,{e:()=>o});var n=r(385),i={};function o(e){if(e in i)return i[e];if(0===(e||"").indexOf("data:"))return{protocol:"data"};let t;var r=n._A?.location,o={};if(n.il)t=document.createElement("a"),t.href=e;else try{t=new URL(e,r.href)}catch(e){return o}o.port=t.port;var a=t.href.split("://");!o.port&&a[1]&&(o.port=a[1].split("/")[0].split("@").pop().split(":")[1]),o.port&&"0"!==o.port||(o.port="https"===a[0]?"443":"80"),o.hostname=t.hostname||r.hostname,o.pathname=t.pathname,o.protocol=a[0],"/"!==o.pathname.charAt(0)&&(o.pathname="/"+o.pathname);var s=!t.protocol||":"===t.protocol||t.protocol===r.protocol,c=t.hostname===r.hostname&&t.port===r.port;return o.sameOrigin=s&&(!t.hostname||c),"/"===o.pathname&&(i[e]=o),o}},50:(e,t,r)=>{function n(e,t){"function"==typeof console.warn&&(console.warn("New Relic: ".concat(e)),t&&console.warn(t))}r.d(t,{Z:()=>n})},2587:(e,t,r)=>{r.d(t,{N:()=>c,T:()=>u});var n=r(2177),i=r(5546),o=r(8e3),a=r(3325);const s={stn:[a.D.sessionTrace],err:[a.D.jserrors,a.D.metrics],ins:[a.D.pageAction],spa:[a.D.spa],sr:[a.D.sessionReplay,a.D.sessionTrace]};function c(e,t){const r=n.ee.get(t);e&&"object"==typeof e&&(Object.entries(e).forEach((e=>{let[t,n]=e;void 0===u[t]&&(s[t]?s[t].forEach((e=>{n?(0,i.p)("feat-"+t,[],void 0,e,r):(0,i.p)("block-"+t,[],void 0,e,r),(0,i.p)("rumresp-"+t,[Boolean(n)],void 0,e,r)})):n&&(0,i.p)("feat-"+t,[],void 0,void 0,r),u[t]=Boolean(n))})),Object.keys(s).forEach((e=>{void 0===u[e]&&(s[e]?.forEach((t=>(0,i.p)("rumresp-"+e,[!1],void 0,t,r))),u[e]=!1)})),(0,o.L)(t,a.D.pageViewEvent))}const u={}},2210:(e,t,r)=>{r.d(t,{X:()=>i});var n=Object.prototype.hasOwnProperty;function i(e,t,r){if(n.call(e,t))return e[t];var i=r();if(Object.defineProperty&&Object.keys)try{return Object.defineProperty(e,t,{value:i,writable:!0,enumerable:!1}),i}catch(e){}return e[t]=i,i}},1284:(e,t,r)=>{r.d(t,{D:()=>n});const n=(e,t)=>Object.entries(e||{}).map((e=>{let[r,n]=e;return t(r,n)}))},4351:(e,t,r)=>{r.d(t,{P:()=>o});var n=r(2177);const i=()=>{const e=new WeakSet;return(t,r)=>{if("object"==typeof r&&null!==r){if(e.has(r))return;e.add(r)}return r}};function o(e){try{return JSON.stringify(e,i())}catch(e){try{n.ee.emit("internal-error",[e])}catch(e){}}}},3960:(e,t,r)=>{r.d(t,{K:()=>a,b:()=>o});var n=r(3239);function i(){return"undefined"==typeof document||"complete"===document.readyState}function o(e,t){if(i())return e();(0,n.bP)("load",e,t)}function a(e){if(i())return e();(0,n.iz)("DOMContentLoaded",e)}},8632:(e,t,r)=>{r.d(t,{EZ:()=>u,Qy:()=>c,ce:()=>o,fP:()=>a,gG:()=>d,mF:()=>s});var n=r(7894),i=r(385);const o={beacon:"bam.nr-data.net",errorBeacon:"bam.nr-data.net"};function a(){return i._A.NREUM||(i._A.NREUM={}),void 0===i._A.newrelic&&(i._A.newrelic=i._A.NREUM),i._A.NREUM}function s(){let e=a();return e.o||(e.o={ST:i._A.setTimeout,SI:i._A.setImmediate,CT:i._A.clearTimeout,XHR:i._A.XMLHttpRequest,REQ:i._A.Request,EV:i._A.Event,PR:i._A.Promise,MO:i._A.MutationObserver,FETCH:i._A.fetch}),e}function c(e,t,r){let i=a();const o=i.initializedAgents||{},s=o[e]||{};return Object.keys(s).length||(s.initializedAt={ms:(0,n.z)(),date:new Date}),i.initializedAgents={...o,[e]:{...s,[r]:t}},i}function u(e,t){a()[e]=t}function d(){return function(){let e=a();const t=e.info||{};e.info={beacon:o.beacon,errorBeacon:o.errorBeacon,...t}}(),function(){let e=a();const t=e.init||{};e.init={...t}}(),s(),function(){let e=a();const t=e.loader_config||{};e.loader_config={...t}}(),a()}},7956:(e,t,r)=>{r.d(t,{N:()=>i});var n=r(3239);function i(e){let t=arguments.length>1&&void 0!==arguments[1]&&arguments[1],r=arguments.length>2?arguments[2]:void 0,i=arguments.length>3?arguments[3]:void 0;return void(0,n.iz)("visibilitychange",(function(){if(t)return void("hidden"==document.visibilityState&&e());e(document.visibilityState)}),r,i)}},1214:(e,t,r)=>{r.d(t,{em:()=>v,u5:()=>N,QU:()=>S,_L:()=>I,Gm:()=>L,Lg:()=>M,gy:()=>U,BV:()=>Q,Kf:()=>ee});var n=r(2177);const i="nr@original";var o=Object.prototype.hasOwnProperty,a=!1;function s(e,t){return e||(e=n.ee),r.inPlace=function(e,t,n,i,o){n||(n="");var a,s,c,u="-"===n.charAt(0);for(c=0;c 2?n-2:0),o=2;o {r(A[T],e,w),r(E[T],e,w)})),r(l._A,"fetch",y),t.on(y+"end",(function(e,r){var n=this;if(r){var i=r.headers.get("content-length");null!==i&&(n.rxSize=i),t.emit(y+"done",[null,r],n)}else t.emit(y+"done",[e],n)})),t}const O={},j=["pushState","replaceState"];function S(e){const t=function(e){return(e||n.ee).get("history")}(e);return!l.il||O[t.debugId]++||(O[t.debugId]=1,s(t).inPlace(window.history,j,"-")),t}var P=r(3239);const C={},R=["appendChild","insertBefore","replaceChild"];function I(e){const t=function(e){return(e||n.ee).get("jsonp")}(e);if(!l.il||C[t.debugId])return t;C[t.debugId]=!0;var r=s(t),i=/[?&](?:callback|cb)=([^&#]+)/,o=/(.*)\.([^.]+)/,a=/^(\w+)(\.|$)(.*)$/;function c(e,t){var r=e.match(a),n=r[1],i=r[3];return i?c(i,t[n]):t[n]}return r.inPlace(Node.prototype,R,"dom-"),t.on("dom-start",(function(e){!function(e){if(!e||"string"!=typeof e.nodeName||"script"!==e.nodeName.toLowerCase())return;if("function"!=typeof e.addEventListener)return;var n=(a=e.src,s=a.match(i),s?s[1]:null);var a,s;if(!n)return;var u=function(e){var t=e.match(o);if(t&&t.length>=3)return{key:t[2],parent:c(t[1],window)};return{key:e,parent:window}}(n);if("function"!=typeof u.parent[u.key])return;var d={};function f(){t.emit("jsonp-end",[],d),e.removeEventListener("load",f,(0,P.m$)(!1)),e.removeEventListener("error",l,(0,P.m$)(!1))}function l(){t.emit("jsonp-error",[],d),t.emit("jsonp-end",[],d),e.removeEventListener("load",f,(0,P.m$)(!1)),e.removeEventListener("error",l,(0,P.m$)(!1))}r.inPlace(u.parent,[u.key],"cb-",d),e.addEventListener("load",f,(0,P.m$)(!1)),e.addEventListener("error",l,(0,P.m$)(!1)),t.emit("new-jsonp",[e.src],d)}(e[0])})),t}var k=r(5763);const H={};function L(e){const t=function(e){return(e||n.ee).get("mutation")}(e);if(!l.il||H[t.debugId])return t;H[t.debugId]=!0;var r=s(t),i=k.Yu.MO;return i&&(window.MutationObserver=function(e){return this instanceof i?new i(r(e,"fn-")):i.apply(this,arguments)},MutationObserver.prototype=i.prototype),t}const z={};function M(e){const t=function(e){return(e||n.ee).get("promise")}(e);if(z[t.debugId])return t;z[t.debugId]=!0;var r=n.c,o=s(t),a=k.Yu.PR;return a&&function(){function e(r){var n=t.context(),i=o(r,"executor-",n,null,!1);const s=Reflect.construct(a,[i],e);return t.context(s).getCtx=function(){return n},s}l._A.Promise=e,Object.defineProperty(e,"name",{value:"Promise"}),e.toString=function(){return a.toString()},Object.setPrototypeOf(e,a),["all","race"].forEach((function(r){const n=a[r];e[r]=function(e){let i=!1;[...e||[]].forEach((e=>{this.resolve(e).then(a("all"===r),a(!1))}));const o=n.apply(this,arguments);return o;function a(e){return function(){t.emit("propagate",[null,!i],o,!1,!1),i=i||!e}}}})),["resolve","reject"].forEach((function(r){const n=a[r];e[r]=function(e){const r=n.apply(this,arguments);return e!==r&&t.emit("propagate",[e,!0],r,!1,!1),r}})),e.prototype=a.prototype;const n=a.prototype.then;a.prototype.then=function(){var e=this,i=r(e);i.promise=e;for(var a=arguments.length,s=new Array(a),c=0;c e())),t};function m(e,t){i.inPlace(t,["onreadystatechange"],"fn-",E)}function b(){var e=this,t=r.context(e);e.readyState>3&&!t.resolved&&(t.resolved=!0,r.emit("xhr-resolved",[],e)),i.inPlace(e,f,"fn-",E)}if(function(e,t){for(var r in e)t[r]=e[r]}(o,p),p.prototype=o.prototype,i.inPlace(p.prototype,J,"-xhr-",E),r.on("send-xhr-start",(function(e,t){m(e,t),function(e){h.push(e),a&&(y?y.then(A):u?u(A):(w=-w,x.data=w))}(t)})),r.on("open-xhr-start",m),a){var y=c&&c.resolve();if(!u&&!c){var w=1,x=document.createTextNode(w);new a(A).observe(x,{characterData:!0})}}else t.on("fn-end",(function(e){e[0]&&e[0].type===d||A()}));function A(){for(var e=0;e {r.d(t,{t:()=>n});const n=r(3325).D.ajax},6660:(e,t,r)=>{r.d(t,{A:()=>i,t:()=>n});const n=r(3325).D.jserrors,i="nr@seenError"},3081:(e,t,r)=>{r.d(t,{gF:()=>o,mY:()=>i,t9:()=>n,vz:()=>s,xS:()=>a});const n=r(3325).D.metrics,i="sm",o="cm",a="storeSupportabilityMetrics",s="storeEventMetrics"},4649:(e,t,r)=>{r.d(t,{t:()=>n});const n=r(3325).D.pageAction},7633:(e,t,r)=>{r.d(t,{Dz:()=>i,OJ:()=>a,qw:()=>o,t9:()=>n});const n=r(3325).D.pageViewEvent,i="firstbyte",o="domcontent",a="windowload"},9251:(e,t,r)=>{r.d(t,{t:()=>n});const n=r(3325).D.pageViewTiming},3614:(e,t,r)=>{r.d(t,{BST_RESOURCE:()=>i,END:()=>s,FEATURE_NAME:()=>n,FN_END:()=>u,FN_START:()=>c,PUSH_STATE:()=>d,RESOURCE:()=>o,START:()=>a});const n=r(3325).D.sessionTrace,i="bstResource",o="resource",a="-start",s="-end",c="fn"+a,u="fn"+s,d="pushState"},7836:(e,t,r)=>{r.d(t,{BODY:()=>A,CB_END:()=>E,CB_START:()=>u,END:()=>x,FEATURE_NAME:()=>i,FETCH:()=>_,FETCH_BODY:()=>v,FETCH_DONE:()=>m,FETCH_START:()=>p,FN_END:()=>c,FN_START:()=>s,INTERACTION:()=>l,INTERACTION_API:()=>d,INTERACTION_EVENTS:()=>o,JSONP_END:()=>b,JSONP_NODE:()=>g,JS_TIME:()=>T,MAX_TIMER_BUDGET:()=>a,REMAINING:()=>f,SPA_NODE:()=>h,START:()=>w,originalSetTimeout:()=>y});var n=r(5763);const i=r(3325).D.spa,o=["click","submit","keypress","keydown","keyup","change"],a=999,s="fn-start",c="fn-end",u="cb-start",d="api-ixn-",f="remaining",l="interaction",h="spaNode",g="jsonpNode",p="fetch-start",m="fetch-done",v="fetch-body-",b="jsonp-end",y=n.Yu.ST,w="-start",x="-end",A="-body",E="cb"+x,T="jsTime",_="fetch"},5938:(e,t,r)=>{r.d(t,{W:()=>o});var n=r(5763),i=r(2177);class o{constructor(e,t,r){this.agentIdentifier=e,this.aggregator=t,this.ee=i.ee.get(e,(0,n.OP)(this.agentIdentifier).isolatedBacklog),this.featureName=r,this.blocked=!1}}},9144:(e,t,r)=>{r.d(t,{j:()=>m});var n=r(3325),i=r(5763),o=r(5546),a=r(2177),s=r(7894),c=r(8e3),u=r(3960),d=r(385),f=r(50),l=r(3081),h=r(8632);function g(){const e=(0,h.gG)();["setErrorHandler","finished","addToTrace","inlineHit","addRelease","addPageAction","setCurrentRouteName","setPageViewName","setCustomAttribute","interaction","noticeError","setUserId"].forEach((t=>{e[t]=function(){for(var r=arguments.length,n=new Array(r),i=0;i 1?r-1:0),i=1;i {e.exposed&&e.api[t]&&o.push(e.api[t](...n))})),o.length>1?o:o[0]}(t,...n)}}))}var p=r(2587);function m(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},m=arguments.length>2?arguments[2]:void 0,v=arguments.length>3?arguments[3]:void 0,{init:b,info:y,loader_config:w,runtime:x={loaderType:m},exposed:A=!0}=t;const E=(0,h.gG)();y||(b=E.init,y=E.info,w=E.loader_config),(0,i.Dg)(e,b||{}),(0,i.GE)(e,w||{}),(0,i.sU)(e,x),y.jsAttributes??={},d.v6&&(y.jsAttributes.isWorker=!0),(0,i.CX)(e,y),g();const T=function(e,t){t||(0,c.R)(e,"api");const h={};var g=a.ee.get(e),p=g.get("tracer"),m="api-",v=m+"ixn-";function b(t,r,n,o){const a=(0,i.C5)(e);return null===r?delete a.jsAttributes[t]:(0,i.CX)(e,{...a,jsAttributes:{...a.jsAttributes,[t]:r}}),x(m,n,!0,o||null===r?"session":void 0)(t,r)}function y(){}["setErrorHandler","finished","addToTrace","inlineHit","addRelease"].forEach((e=>h[e]=x(m,e,!0,"api"))),h.addPageAction=x(m,"addPageAction",!0,n.D.pageAction),h.setCurrentRouteName=x(m,"routeName",!0,n.D.spa),h.setPageViewName=function(t,r){if("string"==typeof t)return"/"!==t.charAt(0)&&(t="/"+t),(0,i.OP)(e).customTransaction=(r||"http://custom.transaction")+t,x(m,"setPageViewName",!0)()},h.setCustomAttribute=function(e,t){let r=arguments.length>2&&void 0!==arguments[2]&&arguments[2];if("string"==typeof e){if(["string","number"].includes(typeof t)||null===t)return b(e,t,"setCustomAttribute",r);(0,f.Z)("Failed to execute setCustomAttribute.\nNon-null value must be a string or number type, but a type of was provided."))}else(0,f.Z)("Failed to execute setCustomAttribute.\nName must be a string type, but a type of was provided."))},h.setUserId=function(e){if("string"==typeof e||null===e)return b("enduser.id",e,"setUserId",!0);(0,f.Z)("Failed to execute setUserId.\nNon-null value must be a string type, but a type of was provided."))},h.interaction=function(){return(new y).get()};var w=y.prototype={createTracer:function(e,t){var r={},i=this,a="function"==typeof t;return(0,o.p)(v+"tracer",[(0,s.z)(),e,r],i,n.D.spa,g),function(){if(p.emit((a?"":"no-")+"fn-start",[(0,s.z)(),i,a],r),a)try{return t.apply(this,arguments)}catch(e){throw p.emit("fn-err",[arguments,this,"string"==typeof e?new Error(e):e],r),e}finally{p.emit("fn-end",[(0,s.z)()],r)}}}};function x(e,t,r,i){return function(){return(0,o.p)(l.xS,["API/"+t+"/called"],void 0,n.D.metrics,g),i&&(0,o.p)(e+t,[(0,s.z)(),...arguments],r?null:this,i,g),r?void 0:this}}function A(){r.e(439).then(r.bind(r,7438)).then((t=>{let{setAPI:r}=t;r(e),(0,c.L)(e,"api")})).catch((()=>(0,f.Z)("Downloading runtime APIs failed...")))}return["actionText","setName","setAttribute","save","ignore","onEnd","getContext","end","get"].forEach((e=>{w[e]=x(v,e,void 0,n.D.spa)})),h.noticeError=function(e,t){"string"==typeof e&&(e=new Error(e)),(0,o.p)(l.xS,["API/noticeError/called"],void 0,n.D.metrics,g),(0,o.p)("err",[e,(0,s.z)(),!1,t],void 0,n.D.jserrors,g)},d.il?(0,u.b)((()=>A()),!0):A(),h}(e,v);return(0,h.Qy)(e,T,"api"),(0,h.Qy)(e,A,"exposed"),(0,h.EZ)("activatedFeatures",p.T),T}},3325:(e,t,r)=>{r.d(t,{D:()=>n,p:()=>i});const n={ajax:"ajax",jserrors:"jserrors",metrics:"metrics",pageAction:"page_action",pageViewEvent:"page_view_event",pageViewTiming:"page_view_timing",sessionReplay:"session_replay",sessionTrace:"session_trace",spa:"spa"},i={[n.pageViewEvent]:1,[n.pageViewTiming]:2,[n.metrics]:3,[n.jserrors]:4,[n.ajax]:5,[n.sessionTrace]:6,[n.pageAction]:7,[n.spa]:8,[n.sessionReplay]:9}}},n={};function i(e){var t=n[e];if(void 0!==t)return t.exports;var o=n[e]={exports:{}};return r[e](o,o.exports,i),o.exports}i.m=r,i.d=(e,t)=>{for(var r in t)i.o(t,r)&&!i.o(e,r)&&Object.defineProperty(e,r,{enumerable:!0,get:t[r]})},i.f={},i.e=e=>Promise.all(Object.keys(i.f).reduce(((t,r)=>(i.f[r](e,t),t)),[])),i.u=e=>(({78:"page_action-aggregate",147:"metrics-aggregate",242:"session-manager",317:"jserrors-aggregate",348:"page_view_timing-aggregate",412:"lazy-feature-loader",439:"async-api",538:"recorder",590:"session_replay-aggregate",675:"compressor",733:"session_trace-aggregate",786:"page_view_event-aggregate",873:"spa-aggregate",898:"ajax-aggregate"}[e]||e)+"."+{78:"ac76d497",147:"3dc53903",148:"1a20d5fe",242:"2a64278a",317:"49e41428",348:"bd6de33a",412:"2f55ce66",439:"30bd804e",538:"1b18459f",590:"cf0efb30",675:"ae9f91a8",733:"83105561",786:"06482edd",860:"03a8b7a5",873:"e6b09d52",898:"998ef92b"}[e]+"-1.236.0.min.js"),i.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),e={},t="NRBA:",i.l=(r,n,o,a)=>{if(e[r])e[r].push(n);else{var s,c;if(void 0!==o)for(var u=document.getElementsByTagName("script"),d=0;d {s.onerror=s.onload=null,clearTimeout(h);var i=e[r];if(delete e[r],s.parentNode&&s.parentNode.removeChild(s),i&&i.forEach((e=>e(n))),t)return t(n)},h=setTimeout(l.bind(null,void 0,{type:"timeout",target:s}),12e4);s.onerror=l.bind(null,s.onerror),s.onload=l.bind(null,s.onload),c&&document.head.appendChild(s)}},i.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.j=364,i.p="https://js-agent.newrelic.com/",(()=>{var e={364:0,953:0};i.f.j=(t,r)=>{var n=i.o(e,t)?e[t]:void 0;if(0!==n)if(n)r.push(n[2]);else{var o=new Promise(((r,i)=>n=e[t]=[r,i]));r.push(n[2]=o);var a=i.p+i.u(t),s=new Error;i.l(a,(r=>{if(i.o(e,t)&&(0!==(n=e[t])&&(e[t]=void 0),n)){var o=r&&("load"===r.type?"missing":r.type),a=r&&r.target&&r.target.src;s.message="Loading chunk "+t+" failed.\n("+o+": "+a+")",s.name="ChunkLoadError",s.type=o,s.request=a,n[1](s)}}),"chunk-"+t,t)}};var t=(t,r)=>{var n,o,[a,s,c]=r,u=0;if(a.some((t=>0!==e[t]))){for(n in s)i.o(s,n)&&(i.m[n]=s[n]);if(c)c(i)}for(t&&t(r);u {i.r(o);var e=i(3325),t=i(5763);const r=Object.values(e.D);function n(e){const n={};return r.forEach((r=>{n[r]=function(e,r){return!1!==(0,t.Mt)(r,"".concat(e,".enabled"))}(r,e)})),n}var a=i(9144);var s=i(5546),c=i(385),u=i(8e3),d=i(5938),f=i(3960),l=i(50);class h extends d.W{constructor(e,t,r){let n=!(arguments.length>3&&void 0!==arguments[3])||arguments[3];super(e,t,r),this.auto=n,this.abortHandler,this.featAggregate,this.onAggregateImported,n&&(0,u.R)(e,r)}importAggregator(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{};if(this.featAggregate||!this.auto)return;const r=c.il&&!0===(0,t.Mt)(this.agentIdentifier,"privacy.cookies_enabled");let n;this.onAggregateImported=new Promise((e=>{n=e}));const o=async()=>{let t;try{if(r){const{setupAgentSession:e}=await Promise.all([i.e(860),i.e(242)]).then(i.bind(i,3228));t=e(this.agentIdentifier)}}catch(e){(0,l.Z)("A problem occurred when starting up session manager. This page will not start or extend any session.",e)}try{if(!this.shouldImportAgg(this.featureName,t))return void(0,u.L)(this.agentIdentifier,this.featureName);const{lazyFeatureLoader:r}=await i.e(412).then(i.bind(i,8582)),{Aggregate:o}=await r(this.featureName,"aggregate");this.featAggregate=new o(this.agentIdentifier,this.aggregator,e),n(!0)}catch(e){(0,l.Z)("Downloading and initializing ".concat(this.featureName," failed..."),e),this.abortHandler?.(),n(!1)}};c.il?(0,f.b)((()=>o()),!0):o()}shouldImportAgg(r,n){return r!==e.D.sessionReplay||!1!==(0,t.Mt)(this.agentIdentifier,"session_trace.enabled")&&(!!n?.isNew||!!n?.state.sessionReplay)}}var g=i(7633),p=i(7894);class m extends h{static featureName=g.t9;constructor(r,n){let i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];if(super(r,n,g.t9,i),("undefined"==typeof PerformanceNavigationTiming||c.Tt)&&"undefined"!=typeof PerformanceTiming){const n=(0,t.OP)(r);n[g.Dz]=Math.max(Date.now()-n.offset,0),(0,f.K)((()=>n[g.qw]=Math.max((0,p.z)()-n[g.Dz],0))),(0,f.b)((()=>{const t=(0,p.z)();n[g.OJ]=Math.max(t-n[g.Dz],0),(0,s.p)("timing",["load",t],void 0,e.D.pageViewTiming,this.ee)}))}this.importAggregator()}}var v=i(1117),b=i(1284);class y extends v.w{constructor(e){super(e),this.aggregatedData={}}store(e,t,r,n,i){var o=this.getBucket(e,t,r,i);return o.metrics=function(e,t){t||(t={count:0});return t.count+=1,(0,b.D)(e,(function(e,r){t[e]=w(r,t[e])})),t}(n,o.metrics),o}merge(e,t,r,n,i){var o=this.getBucket(e,t,n,i);if(o.metrics){var a=o.metrics;a.count+=r.count,(0,b.D)(r,(function(e,t){if("count"!==e){var n=a[e],i=r[e];i&&!i.c?a[e]=w(i.t,n):a[e]=function(e,t){if(!t)return e;t.c||(t=x(t.t));return t.min=Math.min(e.min,t.min),t.max=Math.max(e.max,t.max),t.t+=e.t,t.sos+=e.sos,t.c+=e.c,t}(i,a[e])}}))}else o.metrics=r}storeMetric(e,t,r,n){var i=this.getBucket(e,t,r);return i.stats=w(n,i.stats),i}getBucket(e,t,r,n){this.aggregatedData[e]||(this.aggregatedData[e]={});var i=this.aggregatedData[e][t];return i||(i=this.aggregatedData[e][t]={params:r||{}},n&&(i.custom=n)),i}get(e,t){return t?this.aggregatedData[e]&&this.aggregatedData[e][t]:this.aggregatedData[e]}take(e){for(var t={},r="",n=!1,i=0;i t.max&&(t.max=e),e 2&&void 0!==arguments[2])||arguments[2];super(e,r,j.t,n),c.il&&((0,t.OP)(e).initHidden=Boolean("hidden"===document.visibilityState),(0,N.N)((()=>(0,s.p)("docHidden",[(0,p.z)()],void 0,j.t,this.ee)),!0),(0,O.bP)("pagehide",(()=>(0,s.p)("winPagehide",[(0,p.z)()],void 0,j.t,this.ee))),this.importAggregator())}}var P=i(3081);class C extends h{static featureName=P.t9;constructor(e,t){let r=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];super(e,t,P.t9,r),this.importAggregator()}}var R,I=i(2210),k=i(1214),H=i(2177),L={};try{R=localStorage.getItem("__nr_flags").split(","),console&&"function"==typeof console.log&&(L.console=!0,-1!==R.indexOf("dev")&&(L.dev=!0),-1!==R.indexOf("nr_dev")&&(L.nrDev=!0))}catch(e){}function z(e){try{L.console&&z(e)}catch(e){}}L.nrDev&&H.ee.on("internal-error",(function(e){z(e.stack)})),L.dev&&H.ee.on("fn-err",(function(e,t,r){z(r.stack)})),L.dev&&(z("NR AGENT IN DEVELOPMENT MODE"),z("flags: "+(0,b.D)(L,(function(e,t){return e})).join(", ")));var M=i(6660);class B extends h{static featureName=M.t;constructor(r,n){let i=!(arguments.length>2&&void 0!==arguments[2])||arguments[2];super(r,n,M.t,i),this.skipNext=0;try{this.removeOnAbort=new AbortController}catch(e){}const o=this;o.ee.on("fn-start",(function(e,t,r){o.abortHandler&&(o.skipNext+=1)})),o.ee.on("fn-err",(function(t,r,n){o.abortHandler&&!n[M.A]&&((0,I.X)(n,M.A,(function(){return!0})),this.thrown=!0,(0,s.p)("err",[n,(0,p.z)()],void 0,e.D.jserrors,o.ee))})),o.ee.on("fn-end",(function(){o.abortHandler&&!this.thrown&&o.skipNext>0&&(o.skipNext-=1)})),o.ee.on("internal-error",(function(t){(0,s.p)("ierr",[t,(0,p.z)(),!0],void 0,e.D.jserrors,o.ee)})),this.origOnerror=c._A.onerror,c._A.onerror=this.onerrorHandler.bind(this),c._A.addEventListener("unhandledrejection",(t=>{const r=function(e){let t="Unhandled Promise Rejection: ";if(e instanceof Error)try{return e.message=t+e.message,e}catch(t){return e}if(void 0===e)return new Error(t);try{return new Error(t+(0,D.P)(e))}catch(e){return new Error(t)}}(t.reason);(0,s.p)("err",[r,(0,p.z)(),!1,{unhandledPromiseRejection:1}],void 0,e.D.jserrors,this.ee)}),(0,O.m$)(!1,this.removeOnAbort?.signal)),(0,k.gy)(this.ee),(0,k.BV)(this.ee),(0,k.em)(this.ee),(0,t.OP)(r).xhrWrappable&&(0,k.Kf)(this.ee),this.abortHandler=this.#e,this.importAggregator()}#e(){this.removeOnAbort?.abort(),this.abortHandler=void 0}onerrorHandler(t,r,n,i,o){"function"==typeof this.origOnerror&&this.origOnerror(...arguments);try{this.skipNext?this.skipNext-=1:(0,s.p)("err",[o||new F(t,r,n),(0,p.z)()],void 0,e.D.jserrors,this.ee)}catch(t){try{(0,s.p)("ierr",[t,(0,p.z)(),!0],void 0,e.D.jserrors,this.ee)}catch(e){}}return!1}}function F(e,t,r){this.message=e||"Uncaught error with no additional information",this.sourceURL=t,this.line=r}let U=1;const q="nr@id";function G(e){const t=typeof e;return!e||"object"!==t&&"function"!==t?-1:e===c._A?0:(0,I.X)(e,q,(function(){return U++}))}function V(e){if("string"==typeof e&&e.length)return e.length;if("object"==typeof e){if("undefined"!=typeof ArrayBuffer&&e instanceof ArrayBuffer&&e.byteLength)return e.byteLength;if("undefined"!=typeof Blob&&e instanceof Blob&&e.size)return e.size;if(!("undefined"!=typeof FormData&&e instanceof FormData))try{return(0,D.P)(e).length}catch(e){return}}}var X=i(7243);class W{constructor(e){this.agentIdentifier=e,this.generateTracePayload=this.generateTracePayload.bind(this),this.shouldGenerateTrace=this.shouldGenerateTrace.bind(this)}generateTracePayload(e){if(!this.shouldGenerateTrace(e))return null;var r=(0,t.DL)(this.agentIdentifier);if(!r)return null;var n=(r.accountID||"").toString()||null,i=(r.agentID||"").toString()||null,o=(r.trustKey||"").toString()||null;if(!n||!i)return null;var a=(0,_.M)(),s=(0,_.Ht)(),c=Date.now(),u={spanId:a,traceId:s,timestamp:c};return(e.sameOrigin||this.isAllowedOrigin(e)&&this.useTraceContextHeadersForCors())&&(u.traceContextParentHeader=this.generateTraceContextParentHeader(a,s),u.traceContextStateHeader=this.generateTraceContextStateHeader(a,c,n,i,o)),(e.sameOrigin&&!this.excludeNewrelicHeader()||!e.sameOrigin&&this.isAllowedOrigin(e)&&this.useNewrelicHeaderForCors())&&(u.newrelicHeader=this.generateTraceHeader(a,s,c,n,i,o)),u}generateTraceContextParentHeader(e,t){return"00-"+t+"-"+e+"-01"}generateTraceContextStateHeader(e,t,r,n,i){return i+"@nr=0-1-"+r+"-"+n+"-"+e+"----"+t}generateTraceHeader(e,t,r,n,i,o){if(!("function"==typeof c._A?.btoa))return null;var a={v:[0,1],d:{ty:"Browser",ac:n,ap:i,id:e,tr:t,ti:r}};return o&&n!==o&&(a.d.tk=o),btoa((0,D.P)(a))}shouldGenerateTrace(e){return this.isDtEnabled()&&this.isAllowedOrigin(e)}isAllowedOrigin(e){var r=!1,n={};if((0,t.Mt)(this.agentIdentifier,"distributed_tracing")&&(n=(0,t.P_)(this.agentIdentifier).distributed_tracing),e.sameOrigin)r=!0;else if(n.allowed_origins instanceof Array)for(var i=0;i 2&&void 0!==arguments[2])||arguments[2];super(r,n,Z.t,i),(0,t.OP)(r).xhrWrappable&&(this.dt=new W(r),this.handler=(e,t,r,n)=>(0,s.p)(e,t,r,n,this.ee),(0,k.u5)(this.ee),(0,k.Kf)(this.ee),function(r,n,i,o){function a(e){var t=this;t.totalCbs=0,t.called=0,t.cbTime=0,t.end=E,t.ended=!1,t.xhrGuids={},t.lastSize=null,t.loadCaptureCalled=!1,t.params=this.params||{},t.metrics=this.metrics||{},e.addEventListener("load",(function(r){_(t,e)}),(0,O.m$)(!1)),c.IF||e.addEventListener("progress",(function(e){t.lastSize=e.loaded}),(0,O.m$)(!1))}function s(e){this.params={method:e[0]},T(this,e[1]),this.metrics={}}function u(e,n){var i=(0,t.DL)(r);i.xpid&&this.sameOrigin&&n.setRequestHeader("X-NewRelic-ID",i.xpid);var a=o.generateTracePayload(this.parsedOrigin);if(a){var s=!1;a.newrelicHeader&&(n.setRequestHeader("newrelic",a.newrelicHeader),s=!0),a.traceContextParentHeader&&(n.setRequestHeader("traceparent",a.traceContextParentHeader),a.traceContextStateHeader&&n.setRequestHeader("tracestate",a.traceContextStateHeader),s=!0),s&&(this.dt=a)}}function d(e,t){var r=this.metrics,i=e[0],o=this;if(r&&i){var a=V(i);a&&(r.txSize=a)}this.startTime=(0,p.z)(),this.listener=function(e){try{"abort"!==e.type||o.loadCaptureCalled||(o.params.aborted=!0),("load"!==e.type||o.called===o.totalCbs&&(o.onloadCalled||"function"!=typeof t.onload)&&"function"==typeof o.end)&&o.end(t)}catch(e){try{n.emit("internal-error",[e])}catch(e){}}};for(var s=0;s 1?e[1]=i:e.push(i)}else e[0]&&e[0].headers&&s(e[0].headers,n)&&(this.dt=n);function s(e,t){var r=!1;return t.newrelicHeader&&(e.set("newrelic",t.newrelicHeader),r=!0),t.traceContextParentHeader&&(e.set("traceparent",t.traceContextParentHeader),t.traceContextStateHeader&&e.set("tracestate",t.traceContextStateHeader),r=!0),r}}function x(e,t){this.params={},this.metrics={},this.startTime=(0,p.z)(),this.dt=t,e.length>=1&&(this.target=e[0]),e.length>=2&&(this.opts=e[1]);var r,n=this.opts||{},i=this.target;"string"==typeof i?r=i:"object"==typeof i&&i instanceof Y?r=i.url:c._A?.URL&&"object"==typeof i&&i instanceof URL&&(r=i.href),T(this,r);var o=(""+(i&&i instanceof Y&&i.method||n.method||"GET")).toUpperCase();this.params.method=o,this.txSize=V(n.body)||0}function A(t,r){var n;this.endTime=(0,p.z)(),this.params||(this.params={}),this.params.status=r?r.status:0,"string"==typeof this.rxSize&&this.rxSize.length>0&&(n=+this.rxSize);var o={txSize:this.txSize,rxSize:n,duration:(0,p.z)()-this.startTime};i("xhr",[this.params,o,this.startTime,this.endTime,"fetch"],this,e.D.ajax)}function E(t){var r=this.params,n=this.metrics;if(!this.ended){this.ended=!0;for(var o=0;o 2&&void 0!==arguments[2])||arguments[2];super(e,t,we.t,r),this.importAggregator()}}new class{constructor(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:(0,_.ky)(16);c._A?(this.agentIdentifier=t,this.sharedAggregator=new y({agentIdentifier:this.agentIdentifier}),this.features={},this.desiredFeatures=new Set(e.features||[]),this.desiredFeatures.add(m),Object.assign(this,(0,a.j)(this.agentIdentifier,e,e.loaderType||"agent")),this.start()):(0,l.Z)("Failed to initial the agent. Could not determine the runtime environment.")}get config(){return{info:(0,t.C5)(this.agentIdentifier),init:(0,t.P_)(this.agentIdentifier),loader_config:(0,t.DL)(this.agentIdentifier),runtime:(0,t.OP)(this.agentIdentifier)}}start(){const t="features";try{const r=n(this.agentIdentifier),i=[...this.desiredFeatures];i.sort(((t,r)=>e.p[t.featureName]-e.p[r.featureName])),i.forEach((t=>{if(r[t.featureName]||t.featureName===e.D.pageViewEvent){const n=function(t){switch(t){case e.D.ajax:return[e.D.jserrors];case e.D.sessionTrace:return[e.D.ajax,e.D.pageViewEvent];case e.D.sessionReplay:return[e.D.sessionTrace];case e.D.pageViewTiming:return[e.D.pageViewEvent];default:return[]}}(t.featureName);n.every((e=>r[e]))||(0,l.Z)("".concat(t.featureName," is enabled but one or more dependent features has been disabled (").concat((0,D.P)(n),"). This may cause unintended consequences or missing data...")),this.features[t.featureName]=new t(this.agentIdentifier,this.sharedAggregator)}})),(0,T.Qy)(this.agentIdentifier,this.features,t)}catch(e){(0,l.Z)("Failed to initialize all enabled instrument classes (agent aborted) -",e);for(const e in this.features)this.features[e].abortHandler?.();const r=(0,T.fP)();return delete r.initializedAgents[this.agentIdentifier]?.api,delete r.initializedAgents[this.agentIdentifier]?.[t],delete this.sharedAggregator,r.ee?.abort(),delete r.ee?.get(this.agentIdentifier),!1}}}({features:[J,m,S,class extends h{static featureName=oe;constructor(t,r){if(super(t,r,oe,!(arguments.length>2&&void 0!==arguments[2])||arguments[2]),!c.il)return;const n=this.ee;let i;(0,k.QU)(n),this.eventsEE=(0,k.em)(n),this.eventsEE.on(se,(function(e,t){this.bstStart=(0,p.z)()})),this.eventsEE.on(ae,(function(t,r){(0,s.p)("bst",[t[0],r,this.bstStart,(0,p.z)()],void 0,e.D.sessionTrace,n)})),n.on(ce+ne,(function(e){this.time=(0,p.z)(),this.startPath=location.pathname+location.hash})),n.on(ce+ie,(function(t){(0,s.p)("bstHist",[location.pathname+location.hash,this.startPath,this.time],void 0,e.D.sessionTrace,n)}));try{i=new PerformanceObserver((t=>{const r=t.getEntries();(0,s.p)(te,[r],void 0,e.D.sessionTrace,n)})),i.observe({type:re,buffered:!0})}catch(e){}this.importAggregator({resourceObserver:i})}},C,xe,B,class extends h{static featureName=de;constructor(e,r){if(super(e,r,de,!(arguments.length>2&&void 0!==arguments[2])||arguments[2]),!c.il)return;if(!(0,t.OP)(e).xhrWrappable)return;try{this.removeOnAbort=new AbortController}catch(e){}let n,i=0;const o=this.ee.get("tracer"),a=(0,k._L)(this.ee),s=(0,k.Lg)(this.ee),u=(0,k.BV)(this.ee),d=(0,k.Kf)(this.ee),f=this.ee.get("events"),l=(0,k.u5)(this.ee),h=(0,k.QU)(this.ee),g=(0,k.Gm)(this.ee);function m(e,t){h.emit("newURL",[""+window.location,t])}function v(){i++,n=window.location.hash,this[ve]=(0,p.z)()}function b(){i--,window.location.hash!==n&&m(0,!0);var e=(0,p.z)();this[pe]=~~this[pe]+e-this[ve],this[ye]=e}function y(e,t){e.on(t,(function(){this[t]=(0,p.z)()}))}this.ee.on(ve,v),s.on(be,v),a.on(be,v),this.ee.on(ye,b),s.on(ge,b),a.on(ge,b),this.ee.buffer([ve,ye,"xhr-resolved"],this.featureName),f.buffer([ve],this.featureName),u.buffer(["setTimeout"+le,"clearTimeout"+fe,ve],this.featureName),d.buffer([ve,"new-xhr","send-xhr"+fe],this.featureName),l.buffer([me+fe,me+"-done",me+he+fe,me+he+le],this.featureName),h.buffer(["newURL"],this.featureName),g.buffer([ve],this.featureName),s.buffer(["propagate",be,ge,"executor-err","resolve"+fe],this.featureName),o.buffer([ve,"no-"+ve],this.featureName),a.buffer(["new-jsonp","cb-start","jsonp-error","jsonp-end"],this.featureName),y(l,me+fe),y(l,me+"-done"),y(a,"new-jsonp"),y(a,"jsonp-end"),y(a,"cb-start"),h.on("pushState-end",m),h.on("replaceState-end",m),window.addEventListener("hashchange",m,(0,O.m$)(!0,this.removeOnAbort?.signal)),window.addEventListener("load",m,(0,O.m$)(!0,this.removeOnAbort?.signal)),window.addEventListener("popstate",(function(){m(0,i>1)}),(0,O.m$)(!0,this.removeOnAbort?.signal)),this.abortHandler=this.#e,this.importAggregator()}#e(){this.removeOnAbort?.abort(),this.abortHandler=void 0}}],loaderType:"spa"})})(),window.NRBA=o})(); window.jQuery || document.write(' ') CKEDITOR_BASEPATH='https://f1000research.com/js/vendor/ckeditor/' window.reactTheme = 'research'; window.MathJax = { CommonHTML: { linebreaks: { automatic: true } }, 'HTML-CSS': { linebreaks: { automatic: true } }, SVG: { linebreaks: { automatic: true } }, AuthorInit: function() { MathJax.Hub.Register.MessageHook('End Process', function () { let timeout = false; // holder for timeout id const delay = 250; // delay after event is "complete" to run callback const reflowMath = function() { const dispFormulas = document.querySelectorAll('.disp-formula.panel'); if (!dispFormulas) { return; } for (const dispFormula of dispFormulas) { const child = dispFormula.querySelector('.MathJax_Preview').nextSibling.firstChild; const isMultiline = MathJax.Hub.getAllJax(dispFormula)[0].root.isMultiline; if (dispFormula.offsetWidth < child.offsetWidth || isMultiline) { MathJax.Hub.Queue(['Rerender', MathJax.Hub, dispFormula]); } } }; window.addEventListener('resize', function() { clearTimeout(timeout); // clear the timeout timeout = setTimeout(reflowMath, delay); // start timing for event "completion" }); }); }, }; if (window.location.hash == '#_=_'){ window.location = window.location.href.split('#')[0] } !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function() {n.callMethod? n.callMethod.apply(n,arguments):n.queue.push(arguments)} ;if(!f._fbq)f._fbq=n; n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0; t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window, document,'script','https://connect.facebook.net/en_US/fbevents.js'); fbq('init', '1641728616063202'); fbq('track', "PixelInitialized", {}); (function(h,o,t,j,a,r){ h.hj=h.hj||function(){(h.hj.q=h.hj.q||[]).push(arguments)}; h._hjSettings={hjid:2318163,hjsv:6}; a=o.getElementsByTagName('head')[0]; r=o.createElement('script');r.async=1; r.src=t+h._hjSettings.hjid+j+h._hjSettings.hjsv; a.appendChild(r); })(window,document,'https://static.hotjar.com/c/hotjar-','.js?sv='); search file_upload Submit your research search menu close search Browse Gateways & Collections How to Publish Submit your Research My Submissions Article Guidelines Article Guidelines (New Versions) Open Data, Software and Code Guidelines Open Data and Accessible Source Materials Guidelines (HSS) Open Data, Software and Code Guidelines (PSE) Prepublication Checks Production Process Posters and Slides Guidelines Document Guidelines Article Processing Charges Peer Review Finding Article Reviewers About How it Works For Reviewers Our Advisors Policies Glossary FAQs For Developers Newsroom Contact My Research Submissions Content and Tracking Alerts My Details Sign In file_upload Submit your research { "@context": "https://schema.org", "@type": "ScholarlyArticle", "mainEntityOfPage": { "@type": "WebPage", "@id": "https://f1000research.com/articles/13-1256" }, "headline": "SCUBA implements a storage format-agnostic API for single-cell data access in R", "datePublished": "2024-10-21T12:14:20", "dateModified": "2025-06-02T15:18:11", "author": [ { "@type": "Person", "name": "William M. Showers" }, { "@type": "Person", "name": "Jairav Desai" }, { "@type": "Person", "name": "Krysta L. Engel" }, { "@type": "Person", "name": "Clayton Smith" }, { "@type": "Person", "name": "Craig T. Jordan" }, { "@type": "Person", "name": "Austin E. Gillen" } ], "publisher": { "@type": "Organization", "name": "F1000Research", "logo": { "@type": "ImageObject", "url": "https://f1000research.com/img/AMP/F1000Research_image.png", "height": 480, "width": 60 } }, "image": { "@type": "ImageObject", "url": "https://f1000research.com/img/AMP/F1000Research_image.png", "height": 1200, "width": 150 }, "description": "While robust tools exist for the analysis of single-cell datasets in both Python and R, interoperability is limited, and analysis tools generally only accept one object class. Considerable programming expertise is required to integrate tools across package ecosystems into a comprehensive analysis, due to their differing languages and internal data structures. This complicates validation of results and leads to inconsistent visualizations between analysis suites. Conversion between object formats is the most common solution, but this is difficult and error-prone due to the rapid pace of development of the analysis suites and their underlying data structures. To address this, we created SCUBA (Single-Cell Unified Backend API), an R package that implements a unified data access API for all common R and Python single-cell object formats. SCUBA extends the data access approach from the widely used Seurat package to SingleCellExperiment and anndata objects. SCUBA also implements new data-specific access functions for all supported object types. Performance scales well across all SCUBA-supported formats. In addition to performance, SCUBA offers several advantages over object conversion for the visualization and further analysis of pre-processed single-cell data. First, SCUBA extracts only data required for the operation at hand, leaving the original object unmodified. This process is simpler, less error prone, and less memory intensive than object conversion, which operates on the entire dataset. Second, code written with SCUBA can use any supported object class as input, with simple and consistent syntax across object formats. This allows a single analysis script or package (like our interactive single-cell browser, scExploreR) to work seamlessly with multiple object types, reducing the complexity of the code and improving both readability and reproducibility. Adoption of SCUBA will ultimately improve collaboration and reproducible research in single-cell analysis by lowering the barriers between package ecosystems." } { "@context": "http://schema.org", "@type": "BreadcrumbList", "itemListElement": [ { "@type": "ListItem", "position": "1", "item": { "@id": "https://f1000research.com/", "name": "Home" } }, { "@type": "ListItem", "position": "2", "item": { "@id": "https://f1000research.com/browse/articles", "name": "Browse" } }, { "@type": "ListItem", "position": "3", "item": { "@id": "https://f1000research.com/articles/13-1256/v2", "name": "SCUBA implements a storage format-agnostic API for single-cell data..." } } ] } Home Browse SCUBA implements a storage format-agnostic API for single-cell data... ALL Metrics - Views Downloads Get PDF Get XML Cite How to cite this article Showers WM, Desai J, Engel KL et al. SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.12688/f1000research.154675.2 ) NOTE: If applicable, it is important to ensure the information in square brackets after the title is included in all citations of this article. Close Copy Citation Details Export Export Citation Sciwheel EndNote Ref. Manager Bibtex ProCite Sente EXPORT Select a format first Track Share ▬ ✚ Software Tool Article Revised SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] William M. Showers 1,2 , Jairav Desai 1 , Krysta L. Engel 1,2 , Clayton Smith 1,2 , Craig T. Jordan 2 , Austin E. Gillen 2,3 William M. Showers 1,2 , Jairav Desai 1 , [...] Krysta L. Engel 1,2 , Clayton Smith 1,2 , Craig T. Jordan 2 , Austin E. Gillen 2,3 PUBLISHED 02 Jun 2025 Author details Author details 1 RefinedScience, Aurora, Colorado, USA 2 Division of Hematology, University of Colorado Anschutz Medical Campus School of Medicine, Aurora, Colorado, USA 3 Rocky Mountain Regional VA Medical Center, Aurora, Colorado, USA William M. Showers Roles: Conceptualization, Data Curation, Software, Writing – Original Draft Preparation, Writing – Review & Editing Jairav Desai Roles: Software, Writing – Review & Editing Krysta L. Engel Roles: Writing – Review & Editing Clayton Smith Roles: Funding Acquisition Craig T. Jordan Roles: Funding Acquisition Austin E. Gillen Roles: Conceptualization, Funding Acquisition, Software, Writing – Review & Editing OPEN PEER REVIEW DETAILS REVIEWER STATUS This article is included in the RPackage gateway. Abstract While robust tools exist for the analysis of single-cell datasets in both Python and R, interoperability is limited, and analysis tools generally only accept one object class. Considerable programming expertise is required to integrate tools across package ecosystems into a comprehensive analysis, due to their differing languages and internal data structures. This complicates validation of results and leads to inconsistent visualizations between analysis suites. Conversion between object formats is the most common solution, but this is difficult and error-prone due to the rapid pace of development of the analysis suites and their underlying data structures. To address this, we created SCUBA (Single-Cell Unified Backend API), an R package that implements a unified data access API for all common R and Python single-cell object formats. SCUBA extends the data access approach from the widely used Seurat package to SingleCellExperiment and anndata objects. SCUBA also implements new data-specific access functions for all supported object types. Performance scales well across all SCUBA-supported formats. In addition to performance, SCUBA offers several advantages over object conversion for the visualization and further analysis of pre-processed single-cell data. First, SCUBA extracts only data required for the operation at hand, leaving the original object unmodified. This process is simpler, less error prone, and less memory intensive than object conversion, which operates on the entire dataset. Second, code written with SCUBA can use any supported object class as input, with simple and consistent syntax across object formats. This allows a single analysis script or package (like our interactive single-cell browser, scExploreR) to work seamlessly with multiple object types, reducing the complexity of the code and improving both readability and reproducibility. Adoption of SCUBA will ultimately improve collaboration and reproducible research in single-cell analysis by lowering the barriers between package ecosystems. READ ALL READ LESS Keywords single-cell sequencing, multimodal, software tools, R package, Python, visualization Corresponding Author(s) Austin E. Gillen ( [email protected] ) Close Corresponding author: Austin E. Gillen Competing interests: A.E. Gillen and C.T. Jordan report other support from RefinedScience outside the submitted work. C.A. Smith is the Chief Innovation Officer of RefinedScience and the Chief Medical Officer of Oncoverity and receives financial support from both. No funding from Oncoverity was used in this work. No disclosures were reported by the other authors. The contents do not represent the views of the U.S. Department of Veterans Affairs or the United States Government. Grant information: This work received support from US VA IK2BX004952-01A1 to AEG and US NIH R35CA242376 to CTJ and The Leukemia & Lymphoma Society Discovery Grant Program 8052-25 to CTJ and AEG. The funders had no role in study design, data collection and analysis, decision to publish, or preparation of the manuscript. Copyright: © 2025 Showers WM et al . This is an open access article distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. How to cite: Showers WM, Desai J, Engel KL et al. SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.12688/f1000research.154675.2 ) First published: 21 Oct 2024, 13 :1256 ( https://doi.org/10.12688/f1000research.154675.1 ) Latest published: 02 Jun 2025, 13 :1256 ( https://doi.org/10.12688/f1000research.154675.2 ) Revised Amendments from Version 1 The new version of the manuscript highlights the addition of the `fetch_data` generic. This was added instead using the FetchData generic from SeuratObject and extending it to SingleCellExperiment and anndata objects. A website for SCUBA was added via pkgdown (https://amc-heme.github.io/SCUBA/) with improved documentation. A user guide vignette was added to the pkgdown website, and the Github README was updated with additional installation instructions. Modifications were made to the introduction section in response to reviewer feedback. Figures 1, 2, 4, 5, and 6 were modified. We corrected an error in the caption for figure 4, where the caption for figure 4A was intended to refer to figure 4C, and vice versa. The new version of the manuscript highlights the addition of the `fetch_data` generic. This was added instead using the FetchData generic from SeuratObject and extending it to SingleCellExperiment and anndata objects. A website for SCUBA was added via pkgdown (https://amc-heme.github.io/SCUBA/) with improved documentation. A user guide vignette was added to the pkgdown website, and the Github README was updated with additional installation instructions. Modifications were made to the introduction section in response to reviewer feedback. Figures 1, 2, 4, 5, and 6 were modified. We corrected an error in the caption for figure 4, where the caption for figure 4A was intended to refer to figure 4C, and vice versa. See the authors' detailed response to the review by Huamei Li See the authors' detailed response to the review by Damian Panas and Marcin Tabaka See the authors' detailed response to the review by Kristian Ullrich READ REVIEWER RESPONSES Introduction The rapidly evolving landscape of single-cell sequencing methods has led to the production of increasingly large and diverse single-cell datasets, greatly improving our knowledge of both inter- and intra-patient heterogeneity in a wide range of diseases and normal tissues. 1 , 2 While there are many excellent tools available for analyzing single-cell datasets in both the Python and R ecosystems, interoperability is hindered by the use of incompatible object classes ( Figure 1A ). Analysis tools generally only accept one object class, forcing users to commit to a suite of packages at the beginning of an analysis. This restriction limits access to tools outside that suite, creating “walled gardens” that pose several challenges for single-cell analysis. Single-cell analysis requires programming experience for full customization of analysis and visualization, and different object formats make it even more difficult for biologists to analyze data. The implementation of popular object formats in both Python and R requires users to be fluent in both programming languages, and it is difficult and time consuming to learn both without formal education in data structures and syntax in each language. The widespread use of multiple object formats also makes it difficult to validate results produced by one analysis suite with another, and visualizations produced with different analysis suites are not consistent. Additionally, the practical analysis of objects with large numbers of cells requires a way to interact with on-disk matrices rather than loading all data in memory. On-disk matrix implementations are analysis suite-specific, which introduces additional barriers to effective analysis. For example, anndata objects are natively stored in the memory-efficient HDF5 format, but anndata objects are not compatible with the Bioconductor’s single-cell tools or Seurat. If a user converts an anndata object to Seurat or SingleCellExperiment format, they must use a different on-disk matrix implementation specific to that format, which further restricts the analyses that can be performed. If single-cell object formats were interoperable, it would be easy for researchers to analyze data from any single-cell dataset, regardless of the object format used when the dataset was generated, but unfortunately this is not the case. Figure 1. SCUBA addresses challenges posed by multiple object formats in single-cell sequencing data. A) Raw single-cell sequencing data is stored in defined object classes, and processed downstream by packages that only accept one object class. This creates “walled garden” analysis suites of incompatible packages that complicate single-cell analysis. When a specific downstream package is desired, the user will need to convert between object formats prior to use. This is possible, but the process is difficult and error-prone. B) SCUBA returns feature expression data, metadata, and reduction coordinates from Seurat, SingleCellExperiment, and Anndata objects in a consistent output format. An overview of each object structure is shown, with rectangles indicating data matrices stored in each object. Dimensions of the matrices are labeled with “cells” or “genes” (features), and matrices placed adjacent to one another indicate requirements that matrices have the same number of values in the dimension indicated (i.e. for Seurat objects, the “reduction coordinates” and “gene expression” matrices must have the same number of cells, but may have varying number of genes (or in the case of reduction coordinates, dimensions). Next to the description of each matrix, object-specific code to retrieve the matrix is given. If additional modalities are supported by an object type, the structure of matrices specific to sequencing modalities are shown, along with code to retrieve data on alternate modalities. The output format for SCUBA is shown at the bottom of the panel. The output is a single R data.frame with values for each variable requested for each cell. The S3 methods added by SCUBA to yield the output format are shown in blue. The methods are based on the existing FetchData method from the MIT licensed, open-source Seurat package. The fetch_data method for Seruat objects is a wrapper for FetchData from Seurat, and the fetch_data methods for SingleCellExperiment and anndata objects apply the workflow from the Seurat FetchData method to these object classes. Currently, the most effective solution is to convert between object classes. All major single-cell analysis packages implement conversion functions, and third-party packages such as sceasy, 3 Zellconverter, 4 and scDIOR 5 are specifically designed for these conversions. Additionally, SeruatWrapper 6 implements conversion functions that allow several otherwise incompatible single-cell analysis packages to be used on Seurat objects. However, inconsistencies in approaches to object structure across implementations often result in data loss upon conversion, which is difficult to overcome. Additionally, the rapid development of packages implementing object formats means that conversion functions are difficult to maintain and frequently break due to changes in these packages. This is especially true when converting to and from the anndata format, since this format is implemented in the Python programming language, and the Seurat and SingleCellExperiment objects are implemented in the R programming language. Even if conversion is successfully achieved without loss of data quality, it has recently been demonstrated that results from Seurat differ from those of Scanpy, 7 despite the fact the two packages implement ostensibly identical processing steps. Addressing interoperability and consistency issues between analysis suites is crucial to ensuring the fidelity and reproducibility of single-cell analysis results, making consistent visualizations across suites essential. Rather than conversion between objects, we propose a more sustainable approach to the visualization and further analysis of pre-processed single-cell data by implementing a unified API for all common single-cell object formats. Here, we present Single-Cell Unified Backend API (SCUBA), an R package based on the data accession function in the widely used Seurat 8 package that returns data from Seurat, SingleCellExperiment, and annadata objects in a common format for downstream visualization and analysis ( Figure 1B ). SCUBA also implements new data-specific access functions for all supported object types. Data is returned in a single R data.frame, with requested variables as columns, and cells as rows. The functions in this package allow users to plot data in a consistent manner from these object types in R, without requiring conversion. SCUBA can also be used in functional programming applications as the basis for single-cell plotting packages, or in the development of Shiny apps. For objects with very large numbers of cells, it is now possible to choose the object class based on on-disk storage performance and produce visually consistent plots without having to downsample the object. Packages and scripts created with SCUBA are flexible with regard to input type, greatly improving the consistency of results between objects and increasing accessibility of these analyses for non-programmers. Methods Implementation SCUBA provides a unified framework for data access by leveraging R’s S3 object-oriented programming. 9 The workflow for data access in SCUBA is based on Seurat’s FetchData method. We implemented a new generic, fetch_data , which executes S3 methods based on the input object class. For Seurat objects, the fetch_data method is a wrapper for FetchData from Seurat. For SingleCellExperiment and anndata objects, SCUBA implements novel methods that replicate the behavior of Seurat FetchData in these objects. The Seurat method was chosen as a basis due to its ease of use, and its implementation in Seurat plotting functions, which are widely used. Access to anndata objects is accomplished using reticulate 10 and performing as many operations in python as possible before returning data to R. The workflow from the existing method for Seurat objects is largely unchanged upon re-implementation for these object formats. We used code from the Seurat package under the terms of the package’s MIT license. In addition to replicating the behavior of Seurat’s FetchData in SingleCellExperiment and anndata objects, SCUBA includes S3 generics and methods specific to the retrieval of metadata and reduction coordinates from each object format. These methods offer improvements in performance relative to retrieving the same data via fetch_data for large objects. Operation SCUBA can be installed as an R package via GitHub using the devtools 11 R package, and can be used on all common operating systems. To ensure compatibility across operating systems, SCUBA is maintained using Continuous Integration (CI), with Github Actions and the testthat 12 R package. The Github Actions workflow performs 100+ tests on recent Linux R and Python versions whenever a pull request is created. Tests are additionally run on Mac OS and Windows for releases. The dataset used for testing is a downsampled version of the acute myeloid leukemia reference dataset 13 from Triana et al. 2021. 14 If using SCUBA with Seurat or SingleCellExperiment objects, no further installation is necessary beyond the R dependencies. For anndata objects, the reticulate 10 R package and a Python installation are required. The following python packages must be manually installed: pandas, 15 numpy, 16 scipy, 17 and anndata. 18 We recommend installing these packages in an anaconda 19 environment and loading the environment in R with reticulate::use_condaenv() , but this is not required. Detailed installation instructions are available on the SCUBA GitHub Page. Use cases The features of SCUBA fall broadly into three categories; data access, data visualization, and data exploration. The functions provided in these categories can be used independently or in a stepwise pipeline. Generally speaking, SCUBA works best for objects that have been filtered and clustered, though SCUBA can work on objects in any state as long as the data being requested exists. Here we highlight independent use cases using a downsampled version of the acute myeloid leukemia reference dataset 13 generated by Triana et al. 14 Additional vignettes are provided on the SCUBA GitHub page. FetchData Methods for SingleCellExperiment and Anndata Objects Example usage of SCUBA’s fetch_data methods is given in Figure 2 . The existing Seurat method (first column) is compared to the methods added by SCUBA. There are only minor variations in input syntax across the three supported object types, and the required parameters are few, making the methods easy to use. All data requested is specified using the vars parameter. The methods infer whether the data requested is metadata, reduction coordinates, or feature expression by parsing the character vector passed to this parameter. To retrieve feature expression or reduction coordinates, the user adds a “key” with an underscore giving the name of the reduction, or the modality to pull feature expression data from. If using an object with only one modality, the modality key is not needed, and the key is also not needed to retrieve metadata. Minor variations in the key exist between object types, due to object-specific conventions for naming modalities (which are called “assays” in Seurat objects, and “Experiments” in SingleCellExperiment objects). Variations in the layer parameter are based on variations in conventions for naming layers (in SingleCellExperiment objects, “assays”, and in Seurat v4 and earlier, “slots”). The consistency in parameters between the three object types, and the presence of only minor differences in inputs to each parameter, facilitates the writing of scripts for any object type. Figure 2. The methods added by SCUBA simplify the retrieval of data from supported object classes. The existing Seurat method (first column), is compared to the methods added by SCUBA for SingleCellExperiment and anndata objects (second and third columns). The methods use consistent syntax across object classes and involve the use of only a few parameters. Pseudocode is used in the examples. object represents a single-cell object. features represents one or more features, from any modality in the object. metadata represents one or more metadata variables, for example, cell type classifications. reduction_dims represents a set of dimensions in a reduction included with the object, with the number of the dimension separated from the reduction with an underscore. For example, to fetch the first and second dimensions of the UMAP projection, reduction_dims would be c(“UMAP_1”, “UMAP_2”) . The output of fetch_data is identical across the three object classes. The output is an R data.frame with values for each requested feature in vars per cell. Columns represent each feature, and rows represent cells. Metadata, reduction-specific accession methods SCUBA also includes S3 generics and methods specific to the retrieval of metadata and reduction coordinates, which are faster than retrieving the same data via fetch_data for R object types. An overview of the fetch_metadata and fetch_reduction functions is given in Figure 3A . As with ‘fetch_data’, the output of fetch_metadata and fetch_reduction is an R data.frame with data for the requested metadata variables or reduction coordinates, respectively, as columns, and rows for each cell. Figure 3B compares the usage of fetch_reduction and fetch_metadata between supported object types. We implement these methods in anndata objects for consistency in syntax, but their performance is roughly equivalent to fetch_data . The functions are easy to use, and the inputs to each function do not vary based on object type. To set defaults for the reduction and cells parameters of fetch_reduction , SCUBA provides several utility methods. default_reduction will search for UMAP, t-SNE, and PCA reductions, and will return them in that order if they exist. get_all_cells will return the IDs of all cells in the object. Figure 3. SCUBA methods specific to the retrieval of metadata and reduction coordinates. A) Overview of outputs of fetch_metadata , for metadata variables, and fetch_reduction , for reduction coordinates. The output is an R data.frame with the metadata or reduction coordinates as columns, and the cells as rows. B) Comparison of the usage of fetch_metadata and fetch_reduction across each object type. For fetch_metadata , the metadata variable or variables to retrieve (which are represented as metadata in this pseudocode example) are specified via a character vector input to vars . For fetch_reduction , the dimensions to return from the reduction coordinate matrix is passed to dims , and the reduction to pull from is specified via reduction . The cells parameter allows the user to specify which cells to fetch reduction coordinates for. For ease of use and flexibility, there is no difference in inputs between object types; only the object itself varies. Figure 4A-B compares the performance of fetch_metadata and fetch_reduction with the performance of ‘ fetch_data ’ to pull one metadata variable, and the first and second dimensions of UMAP coordinates, respectively. Run time was tested for each function on random subsets of varying numbers of cells, with five subsets created for each size. The fetch_metadata and fetch_reduction methods were more performant than ‘ fetch_data ’ in Seurat and SingleCellExperiment objects for all subsets tested. In anndata objects, the runtime of these functions was comparable to that of FetchData . Performance testing for the fetch_data methods added by SCUBA was also performed ( Figure 4C ). Performance of the method for anndata objects exceeds the performance for the existing Seurat method in most cases, and the performance of the SingleCellExperiement method exceeds performance of the Seurat method for the largest subset tested (500k cells). Figure 4. Performance testing of SCUBA functions and methods. Five random subsets of the indicated numbers of cells were created from the Human Brain Atlas object downloaded from CellXGene. 24 The subsets were saved in the following object formats: Seurat, via saveRDS() , SingleCellExperiment, via HDF5Array::saveHDF5Summarized Experiment() , and anndata, via write_h5ad . For all tests, the indicated operations were run on each of the five subsets, and the run time was measured using sys.time . A) Performance of the FetchData methods developed for SingleCellExperiment and anndata objects, compared to the existing FetchData method for Seurat objects. The series “Seurat”, “SingleCellExperiment”, and “anndata” indicate the performance of fetch_data methods for Seurat, SingleCellExperiment, and anndata objects, respectively. A single feature was pulled via FetchData for each of the random subsets for the indicated object and number of cells. B) Comparison of fetch_data methods vs. fetch_metadata for the retrieval of data for a single metadata variable. In most cases, using fetch_metadata to pull metadata was more performant than using ‘ fetch_data ’. C) Comparison of ‘ fetch_data ’ methods vs. fetch_reduction for the retrieval of data for a pair of reduction coordinates. fetch_reduction was more performant than ‘ fetch_data ’ for the retrieval of reduction coordinates in most cases. Example scripts created with SCUBA Figure 5 gives an example usage of SCUBA methods to create plots with consistent visuals across object types. Figure 5A shows the scripts to create a density plot showing expression by cell type from each of the three supported object types, showing regions of the script that vary between object types, and regions that are conserved. Figure 5B shows the output of the example script. The script demonstrates the ease at which expression data can be visualized from each object format, and the ease at which plot visuals can be harmonized across object formats. Figure 5. SCUBA enables flexible plotting scripts harmonized across object types. A) Example script for visualizing expression of a gene by cluster in a density plot. The three boxes for fetch_data indicate slight variations in the script for each object type. All downstream code is the same across object formats. B) Output of the plotting script in (A). Output does not vary by object type. Any plot visualizing a combination expression data, metadata, and reduction coordinates can be created by generating a table from fetch_data , fetch_metadata , or fetch_reduction , and passing the output table to downstream plotting code. Plotting is performed via ggplot2 20 in this example, but any other plotting package that accepts a data.frame or a tibble as input may be used. If desired, it is also possible to convert to a pandas 15 dataframe via Reticulate, 10 and perform plotting operations in python. The flexibility of SCUBA’s data access methods facilitates the creation of a broad variety of plots from single-cell data. Figure 6 shows an example script that simplifies the printing of unique values of a metadata variable represented in an object, which is a commonly used basic operation in analysis. With SCUBA, this operation can simply be performed by calling fetch_metadata on the object and piping the results to unique() . The language used is the same for all supported object classes, which negates the need to memorize and use the most efficient function calls for each respective object type. Figure 6. SCUBA simplifies common object exploration operations. This figure compares the usage of SCUBA with the most efficient equivalent operations for viewing the unique values of a metadata variable represented in an object. The operation with SCUBA is shown in the first column, and the most efficient equivalents are shown in the second column. SCUBA simplifies this operation, allowing for the development of scripts that are generalized for multiple object types. Conclusions SCUBA addresses issues with interoperability between single-cell object formats by providing a flexible backend that returns data in a consistent format, via a consistent interface. The consistent output format of SCUBA facilitates downstream use in functional programming applications (plotting scripts, packages, etc.) and allows for consistent visualizations across object types. Packages and scripts using SCUBA will not require object conversion prior to use, conferring several advantages for end users. Users will not have to risk data loss upon object conversion, and analysis will be more straightforward without conversion, requiring less programming experience. Packages made with SCUBA will also allow users to choose object classes based on storage and performance characteristics that are best for the specific dataset, rather than being constrained to a class based on downstream packages. SCUBA does not allow users to use any analysis package with any object format, however. The aforementioned benefits only apply to packages and scripts created using SCUBA. SCUBA also only performs data access operations, and is not for object assembly, clustering, or filtering. Because of this, SCUBA is not a replacement for analysis packages such as Seurat and Scanpy. Instead, SCUBA allows users to visualize objects that have been prepared with these analysis packages in the same manner, regardless of object class. Support for MuData 21 , 22 will be added in the future, as this Python object class is especially useful for storing data from multimodal single-cell sequencing experiments. SCUBA is particularly well suited for interactive use, such as in Shiny apps, where multiple object formats may be used as inputs. We developed a single-cell browser, scExploreR, 23 that allows users to create consistent Seurat-style visualizations from either Seurat, SingleCellExperiment, or anndata objects. SCUBA can also be used to create a plotting package that produces visuals from any supported object class for reports and shiny apps, and a QC package reporting the results of preprocessing steps such as filtering, clustering, and batch correction could also be created using SCUBA. The flexibility of SCUBA is envisioned to facilitate analysis and visualization of preprocessed data, unifying disparate object-based package ecosystems. Ethics and consent Ethical approval and consent were not required. Data and software availability SCUBA uses two third-party datasets for performance benchmarking, testing, and demonstration in the manuscript. The datasets are described below. Figshare: Expression of 197 surface markers and 462 mRNAs in 15281 cells from blood and bone marrow from a young healthy donor. https://doi.org/10.6084/m9.figshare.13398065.v4 . 13 This project contains the following underlying data: • 200AB_projected.rds. (Seurat object with 15821 cells, showing the expression of 197 surface markers and 462 mRNAs in bone marrow from a young healthy donor). The dataset is available under the terms of the Creative Commons Attribution 4.0 International license (CC-BY 4.0). CELLxGENE: Human Brain Cell Atlas v1.0. https://cellxgene.cziscience.com/collections/283d65eb-dd53-496d-adb7-7570c7caa443 . This project contains the following underlying data: • cc9bfb86-96ed-4ecd-bcc9-464120fc8628.rds. (Seurat object with 800k non-neuronal cells used for performance benchmarking in the manuscript. The file is accessed by selecting “All non-neuronal cells” and then the.rds radio button). The dataset is available under the terms of the Creative Commons Attribution 4.0 International license (CC-BY 4.0). The Velten et al. dataset 13 was processed to yield a format suitable for testing and demonstration of SCUBA, downsampled, and stored in the inst/extdata/ and data/directories of the SCUBA repo. Scripts used in these operations and performance benchmarking are available at the manuscript GitHub repo: https://github.com/amc-heme/SCUBA_Manuscript . Working examples of code shown in figures 2, 3, 5, and 6 are also stored in this repo. Software, up to date source code, and tutorials are available from: https://github.com/amc-heme/scuba Archived source code at time of publication: https://zenodo.org/doi/10.5281/zenodo.13776167 License: MIT Acknowledgements The authors would like to acknowledge Monica Ransom, Sarah E. Staggs, Stephanie R. Gipson, Abbigayl Burtis, and Devin Burke for their thoughtful comments and suggestions during the development of this package and the writing of this manuscript. References 1. Schäfer PSL, Dimitrov D, Villablanca EJ, et al. : Integrating single-cell multi-omics and prior biological knowledge for a functional characterization of the immune system. Nat. Immunol. 2024; 25 : 405–417. PubMed Abstract | Publisher Full Text 2. Zeng AGX, et al. : A cellular hierarchy framework for understanding heterogeneity and predicting drug response in acute myeloid leukemia. Nat. Med. 2022; 28 : 1212–1223. PubMed Abstract | Publisher Full Text 3. Kiselev V, Huang N: sceasy.2022. 4. Zappia L, Lun A, Kamm J, et al. : Zellconverter. 2025. 5. Feng H, Lin L, Chen J: scDIOR: single cell RNA-seq data IO software. BMC Bioinformatics. 2022; 23 : 16. PubMed Abstract | Publisher Full Text | Free Full Text 6. Butler A, et al. : SeuratWrappers. New York Genome Center: Satija Lab; 2024. 7. Wolf FA, Angerer P, Theis FJ: SCANPY: large-scale single-cell gene expression data analysis. Genome Biol. 2018; 19 : 15. PubMed Abstract | Publisher Full Text | Free Full Text 8. Hao Y, et al. : Dictionary learning for integrative, multimodal and scalable single-cell analysis. Nat. Biotechnol. 2024; 42 : 293–304. PubMed Abstract | Publisher Full Text | Free Full Text 9. Wickham H: S3. Advanced R. Chapman and Hall/CRC; 2019. Publisher Full Text 10. Ushey K, Allaire J, Tang Y: reticulate: Interface to ‘Python’.2023. 11. Wickham H, Hester J, Chang W, et al. : devtools: Tools to Make Developing R Packages Easier.2022. 12. Wickham H: testthat: Get Started with Testing. The R Journal. 2011; 3 : 5. Publisher Full Text 13. Velten L, Triana S, Haas S, et al. : Expression of 197 surface markers and 462 mRNAs in 15281 cells from blood and bone marrow from a young healthy donor. [Dataset]. Figshare. 2021. Publisher Full Text 14. Triana S, et al. : Single-cell proteo-genomic reference maps of the hematopoietic system enable the purification and massive profiling of precisely defined cell states. Nat. Immunol. 2021; 22 : 1577–1589. PubMed Abstract | Publisher Full Text | Free Full Text 15. The pandas development team: Pandas.2023. Publisher Full Text 16. Harris CR, et al. : Array programming with NumPy. Nature. 2020; 585 : 357–362. PubMed Abstract | Publisher Full Text | Free Full Text 17. Virtanen P, et al. : Author Correction: SciPy 1.0: fundamental algorithms for scientific computing in Python (Nature Methods, (2020), 10.1038/s41592-019-0686-2). Nat. Methods. 2020; 17 : 352–352. PubMed Abstract | Publisher Full Text | Free Full Text 18. Virshup I, Rybakov S, Theis FJ, et al. : anndata: Annotated data.2021. 2021.12.16.473007. Publisher Full Text 19. Conda contributors: Conda: A system-level, binary package and environment manager running on all major operating systems and platforms.2024. 20. Wickham H: Ggplot2: Elegant Graphics for Data Analysis. Switzerland: Springer; 2016. Publisher Full Text 21. Bredikhin D, Kats I, Stegle O: MUON: multimodal omics analysis framework. Genome Biol. 2022; 23 : 42. PubMed Abstract | Publisher Full Text | Free Full Text 22. Virshup I, et al. : The scverse project provides a computational ecosystem for single-cell omics data analysis. Nat. Biotechnol. 2023; 41 : 604–606. PubMed Abstract | Publisher Full Text 23. Showers W, Desai J, Gipson S, et al. : scExploreR: a Flexible Shiny App for Democratized Analysis of Multimodal single-cell RNA-seq Data.2024. 24. Siletti K, et al. : Human Brain Cell Atlas v1.0. [Dataset]. CELLxGENE. 2023. Reference Source Comments on this article Comments (0) Version 2 VERSION 2 PUBLISHED 21 Oct 2024 ADD YOUR COMMENT Comment Author details Author details 1 RefinedScience, Aurora, Colorado, USA 2 Division of Hematology, University of Colorado Anschutz Medical Campus School of Medicine, Aurora, Colorado, USA 3 Rocky Mountain Regional VA Medical Center, Aurora, Colorado, USA William M. Showers Roles: Conceptualization, Data Curation, Software, Writing – Original Draft Preparation, Writing – Review & Editing Jairav Desai Roles: Software, Writing – Review & Editing Krysta L. Engel Roles: Writing – Review & Editing Clayton Smith Roles: Funding Acquisition Craig T. Jordan Roles: Funding Acquisition Austin E. Gillen Roles: Conceptualization, Funding Acquisition, Software, Writing – Review & Editing Competing interests A.E. Gillen and C.T. Jordan report other support from RefinedScience outside the submitted work. C.A. Smith is the Chief Innovation Officer of RefinedScience and the Chief Medical Officer of Oncoverity and receives financial support from both. No funding from Oncoverity was used in this work. No disclosures were reported by the other authors. The contents do not represent the views of the U.S. Department of Veterans Affairs or the United States Government. Grant information This work received support from US VA IK2BX004952-01A1 to AEG and US NIH R35CA242376 to CTJ and The Leukemia & Lymphoma Society Discovery Grant Program 8052-25 to CTJ and AEG. The funders had no role in study design, data collection and analysis, decision to publish, or preparation of the manuscript. Article Versions (2) version 2 Revised Published: 02 Jun 2025, 13:1256 https://doi.org/10.12688/f1000research.154675.2 version 1 Published: 21 Oct 2024, 13:1256 https://doi.org/10.12688/f1000research.154675.1 Copyright © 2025 Showers WM et al . This is an open access article distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. Download Export To Sciwheel Bibtex EndNote ProCite Ref. Manager (RIS) Sente metrics Views Downloads F1000Research - - PubMed Central info_outline Data from PMC are received and updated monthly. - - Citations open_in_new 0 open_in_new 0 open_in_new SEE MORE DETAILS CITE how to cite this article Showers WM, Desai J, Engel KL et al. SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.12688/f1000research.154675.2 ) NOTE: If applicable, it is important to ensure the information in square brackets after the title is included in all citations of this article. COPY CITATION DETAILS track receive updates on this article Track an article to receive email alerts on any updates to this article. TRACK THIS ARTICLE Share Open Peer Review Current Reviewer Status: ? Key to Reviewer Statuses VIEW HIDE Approved The paper is scientifically sound in its current form and only minor, if any, improvements are suggested Approved with reservations A number of small changes, sometimes more significant revisions are required to address specific details and improve the papers academic merit. Not approved Fundamental flaws in the paper seriously undermine the findings and conclusions Version 2 VERSION 2 PUBLISHED 02 Jun 2025 Revised Views 0 Cite How to cite this report: Obermayer B. Reviewer Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.182803.r396950 ) The direct URL for this report is: https://f1000research.com/articles/13-1256/v2#referee-response-396950 NOTE: it is important to ensure the information in square brackets after the title is included in this citation. Close Copy Citation Details Reviewer Report 19 Aug 2025 Benedikt Obermayer , Berlin Institute of Health at Charité – Universitätsmedizin Berlin, Berlin, Germany Approved VIEWS 0 https://doi.org/10.5256/f1000research.182803.r396950 This manuscript presents an R package for unified data access to single-cell genomics objects from different commonly used formats (Seurat, SingleCellExperiment, and anndata). In version 2, most issues raised by previous reviewers were satisfactorily addressed, and the paper has reached ... Continue reading READ ALL This manuscript presents an R package for unified data access to single-cell genomics objects from different commonly used formats (Seurat, SingleCellExperiment, and anndata). In version 2, most issues raised by previous reviewers were satisfactorily addressed, and the paper has reached a sufficiently sound stage. I have one more major issue and a few small corrections that could be incorporated. Major issue: I agree with Damian Panas and Marcin Tabaka in that this package does not really present a significant advancement or novel solution to comprehensively address the problem of interoperability. People who manage to successfully set up reticulate and conda environments to be used within their R installation would be expected to be able to get necessary data out of objects in different formats. People with less expertise for which a visualization / data exploration tool allowing for different input formats might be most useful will probably not be able to set this up in a reasonable time frame. In that case, I'd prefer a web-based or maybe Docker-based explorer that accepts R as well as python objects as input. Minor issues: - I don't really understand the advantage of SCUBA over the anndata R package for reading h5ad files and accessing their contents, apart from a unified syntax. (However, anndata specific data structures such as the ad$raw slot don't seem to be accessible using SCUBA). SCUBA appears to be somewhat faster than anndata in my hands, but that is probably of little concern to most users. This could be explained better. - I noticed two typos (Suerat instead of Seurat in Fig. 1 caption, and SueratWrapper instead of SeuratWrapper on p4 bottom). - When installing the package, my existing conda env with anndata did not have a sufficiently recent version (including anndata.abc, which I think was introduced in 0.10). Requirements don't specify this - the plot functions still use the deprecated FetchData method. Why is density plot not part of the package if it's used in the User Guide? Is the rationale for developing the new software tool clearly explained? Yes Is the description of the software tool technically sound? Yes Are sufficient details of the code, methods and analysis (if applicable) provided to allow replication of the software development and its use by others? Yes Is sufficient information provided to allow interpretation of the expected output datasets and any results generated using the tool? Yes Are the conclusions about the tool and its performance adequately supported by the findings presented in the article? Partly Competing Interests: No competing interests were disclosed. Reviewer Expertise: Bioinformatics, single-cell genomics, computational biology I confirm that I have read this submission and believe that I have an appropriate level of expertise to confirm that it is of an acceptable scientific standard. Close READ LESS CITE CITE HOW TO CITE THIS REPORT Obermayer B. Reviewer Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.182803.r396950 ) The direct URL for this report is: https://f1000research.com/articles/13-1256/v2#referee-response-396950 NOTE: it is important to ensure the information in square brackets after the title is included in all citations of this article. COPY CITATION DETAILS Report a concern Respond or Comment COMMENT ON THIS REPORT Views 0 Cite How to cite this report: Tabaka M and Panas D. Reviewer Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.182803.r389307 ) The direct URL for this report is: https://f1000research.com/articles/13-1256/v2#referee-response-389307 NOTE: it is important to ensure the information in square brackets after the title is included in this citation. Close Copy Citation Details Reviewer Report 13 Aug 2025 Marcin Tabaka , International Centre for Translaional Eye Research, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland Damian Panas , International Centre for Translational Eye Research, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Mazowieckie, Poland; ICTER, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland Approved VIEWS 0 https://doi.org/10.5256/f1000research.182803.r389307 The revised article comprises significant improvements on the initial submission. The comprehensive documentation, created using the pkgdown framework, is an essential addition. The documentation is now clearly structured, detailed, and supplemented by numerous examples. The authors have reformatted the manuscript ... Continue reading READ ALL The revised article comprises significant improvements on the initial submission. The comprehensive documentation, created using the pkgdown framework, is an essential addition. The documentation is now clearly structured, detailed, and supplemented by numerous examples. The authors have reformatted the manuscript to improve clarity and expanded the benchmarking section to provide a more informative performance comparison. Another significant addition is the new fetch_data() function, which resolves one of the most important issues raised in the initial submission. While a few minor problems presented earlier remain, the most critical concerns have been addressed and resolved. Overall, the current version of the SCUBA is a robust, high-quality tool that demonstrates thoughtful improvements in its usability. Competing Interests: No competing interests were disclosed. Reviewer Expertise: Single-cell Genomics, Bioinformatics We confirm that we have read this submission and believe that we have an appropriate level of expertise to confirm that it is of an acceptable scientific standard. Close READ LESS CITE CITE HOW TO CITE THIS REPORT Tabaka M and Panas D. Reviewer Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.182803.r389307 ) The direct URL for this report is: https://f1000research.com/articles/13-1256/v2#referee-response-389307 NOTE: it is important to ensure the information in square brackets after the title is included in all citations of this article. COPY CITATION DETAILS Report a concern Respond or Comment COMMENT ON THIS REPORT Version 1 VERSION 1 PUBLISHED 21 Oct 2024 Views 0 Cite How to cite this report: Panas D and Tabaka M. Reviewer Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.169727.r350233 ) The direct URL for this report is: https://f1000research.com/articles/13-1256/v1#referee-response-350233 NOTE: it is important to ensure the information in square brackets after the title is included in this citation. Close Copy Citation Details Reviewer Report 29 Jan 2025 Damian Panas , International Centre for Translational Eye Research, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Mazowieckie, Poland; ICTER, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland Marcin Tabaka , International Centre for Translaional Eye Research, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland Not Approved VIEWS 0 https://doi.org/10.5256/f1000research.169727.r350233 In this study, William M. Showers and colleagues developed SCUBA, an R package designed to facilitate the access to single-cell data stored in various formats commonly utilized by single-cell data analysis software in R (Seurat, Scran) or Python (Scanpy). These ... Continue reading READ ALL In this study, William M. Showers and colleagues developed SCUBA, an R package designed to facilitate the access to single-cell data stored in various formats commonly utilized by single-cell data analysis software in R (Seurat, Scran) or Python (Scanpy). These single-cell data storage formats include SeuratObject (Seurat), SingleCellExperiment (Scran, Bioconductor’s single-cell tools), Anndata (Scanpy). Interoperability between R-based and Python-based tools and data types is a real problem in bioinformatics. Several tools are typically used in this case, such as zellkonverter, anndataR, sceasy, or SeuratDisk. However, these tools rely on data type conversion, which can be computationally expensive. SCUBA implements a unified API for single-cell object formats to efficiently access data for exploratory analysis and visualization. It extracts from storage objects using FetchData methods a table with requested features, metadata, and reduction coordinates for each cell. The manuscript is clearly written, with a logical structure that effectively conveys the study's objective and organized in the following structure: 1) Introduction; 2) Methods including subsection Implementation and Operation; 3) Use cases; and 4) Conclusions. The “Use cases” section involve examples of Scuba usage: 1) application of FetchData function to retrieve features, metadata, and dimensionality reduction coordinates; 2) S3 generics and methods for similar tasks as in (1) including functions fetch_metadata and fetch_reduction; 3) speed tests of the functions for SeuratObjects stored in RDS format, SingleCellExperiment and Anndata in h5 formats; 3) presentation of example scripts for single-cell data exploration and visualization. While the issue of single-cell data interoperability is a well-recognized and pervasive challenge in the field, the manuscript in the current form does not appear to present a significant advancement or novel solution to address this problem comprehensively. It represents rather a set of functions that allows accessing data from various single-cell data objects needed for visualization purposes and should be a part of their scExploreR package rather than the standalone package. Other comments: 1) The authors justify the need for SCUBA development by the fact that conversion between different data storage formats results in data loss upon conversion or this process is error-prone. Additionally, the rapid development of single-cell packages means that conversion functions are difficult to maintain and frequently break due to changes in other packages. I don’t understand why data is lost during conversion or why it is error-prone and how their approach overcome these limitations. For me, Scuba has exactly the same problems. In case of mentioned updates in single-cell third-party software and storage formats, Authors’ SCUBA code will require updates in the same way. 2) Authors should explain how different visualization software like CellxGene and many others retrieve features or cell metadata and benchmark them against SCUBA. 3) One of the most common features of exploratory analysis is retrieval of feature values such as gene expression or chromatin accessibility from raw count or processed feature matrices. While this function is presented in Figure 2, it is omitted in the performance testing in Figure 4. Why? Can SCUBA extract, for example, gene expression values for a specified gene from huge matrices (500k cells) from SeuratObjects, SingleCellExperiments, Anndata objects in efficient manner? Authors show only retrieval of cell coordinates and cell metadata which are stored in smaller data structures. 4) It is not clear if Authors developed also a new faster version of FetchData for SeuratObject. 5) The speed tests in Figure 4 are confusing. It’s not clear when Authors use native “FetchData” functions from Seurat/Scanpy and when from SCUBA. For example, Figure 4: fetch_metadata is slower than “FetchData” from Scanpy for anndata? 6) All the differences in run times in A-C are of the order of 0.5-2 seconds, so negligible for users analyzing the single-cell data. 7) Authors state: “Analysis tools generally only accept one object class, forcing users to commit to a suite of packages at the beginning of an analysis. This restriction limits access to tools outside that suite, creating “walled gardens” that pose several challenges for single-cell analysis.” How Scuba overcomes this problem? 8) The package lacks robust and well-organized documentation, such as that provided by the aforementioned zellkoverter, anndataR, or SeuratDisk. The use of the FetchData function is also unclear. The name exceptionally follows the Pascal case naming convention, unlike all other functions which follow the Camel case. If this is done deliberately, e.g., to highlight the use of the Seurat or SeuratObject packages, please consider including a namespace so that the user is aware of the external packages being employed. Alternatively, consider adding the fetch_data function to make the SCUBA package appear more like a closed, independent toolkit. Is the rationale for developing the new software tool clearly explained? Partly Is the description of the software tool technically sound? Partly Are sufficient details of the code, methods and analysis (if applicable) provided to allow replication of the software development and its use by others? Partly Is sufficient information provided to allow interpretation of the expected output datasets and any results generated using the tool? Yes Are the conclusions about the tool and its performance adequately supported by the findings presented in the article? No Competing Interests: No competing interests were disclosed. Reviewer Expertise: Single-cell Genomics, Bioinformatics We confirm that we have read this submission and believe that we have an appropriate level of expertise to state that we do not consider it to be of an acceptable scientific standard, for reasons outlined above. Close READ LESS CITE CITE HOW TO CITE THIS REPORT Panas D and Tabaka M. Reviewer Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.169727.r350233 ) The direct URL for this report is: https://f1000research.com/articles/13-1256/v1#referee-response-350233 NOTE: it is important to ensure the information in square brackets after the title is included in all citations of this article. COPY CITATION DETAILS Report a concern Author Response 16 Jun 2025 William Showers , Division of Hematology, University of Colorado Anschutz Medical Campus, Aurora, USA 16 Jun 2025 Author Response Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see ... Continue reading Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. In this study, William M. Showers and colleagues developed SCUBA, an R package designed to facilitate the access to single-cell data stored in various formats commonly utilized by single-cell data analysis software in R (Seurat, Scran) or Python (Scanpy). These single-cell data storage formats include SeuratObject (Seurat), SingleCellExperiment (Scran, Bioconductor’s single-cell tools), Anndata (Scanpy). Interoperability between R-based and Python-based tools and data types is a real problem in bioinformatics. Several tools are typically used in this case, such as zellkonverter, anndataR, sceasy, or SeuratDisk. However, these tools rely on data type conversion, which can be computationally expensive. SCUBA implements a unified API for single-cell object formats to efficiently access data for exploratory analysis and visualization. It extracts from storage objects using FetchData methods a table with requested features, metadata, and reduction coordinates for each cell. The manuscript is clearly written, with a logical structure that effectively conveys the study's objective and organized in the following structure: 1) Introduction; 2) Methods including subsection Implementation and Operation; 3) Use cases; and 4) Conclusions. The “Use cases” section involve examples of Scuba usage: 1) application of FetchData function to retrieve features, metadata, and dimensionality reduction coordinates; 2) S3 generics and methods for similar tasks as in (1) including functions fetch_metadata and fetch_reduction; 3) speed tests of the functions for SeuratObjects stored in RDS format, SingleCellExperiment and Anndata in h5 formats; 3) presentation of example scripts for single-cell data exploration and visualization. While the issue of single-cell data interoperability is a well-recognized and pervasive challenge in the field, the manuscript in the current form does not appear to present a significant advancement or novel solution to address this problem comprehensively. It represents rather a set of functions that allows accessing data from various single-cell data objects needed for visualization purposes and should be a part of their scExploreR package rather than the standalone package. Thank you for this assessment. The observation that SCUBA is a set of functions for accessing data from single-cell objects is correct, but we disagree that SCUBA should not be a standalone package. The functions provided by SCUBA are useful both in fetching data for interactive report generation (the usage context for scExploreR), and for static report generation by bioinformaticians. The consistent usage of SCUBA across object formats facilitates, for example, re-running a specific visualization script on data from a group that uses a different object class. SCUBA is a tool for developers to work seamlessly across different object classes, and we envision it as the basis of an analysis suite of static visualization packages, as well as the basis of scExploreR. We improved our documentation with examples of how users would integrate SCUBA into their analysis scripts. Other comments: 1) The authors justify the need for SCUBA development by the fact that conversion between different data storage formats results in data loss upon conversion or this process is error-prone. Additionally, the rapid development of single-cell packages means that conversion functions are difficult to maintain and frequently break due to changes in other packages. I don’t understand why data is lost during conversion or why it is error-prone and how their approach overcome these limitations. For me, Scuba has exactly the same problems. In case of mentioned updates in single-cell third-party software and storage formats, Authors’ SCUBA code will require updates in the same way. While it is true that SCUBA is vulnerable to changes in underlying object class implementation and must be maintained, we see this vulnerability as being less severe than with conversion packages. Conversion methods such as those mentioned aim to convert the entirety of each object class to another class, while SCUBA functions each extract small subsets of data. While still requiring active maintenance to track upstream changes, we believe this atomic approach is substantially less vulnerable to breaking changes that affect the entire package. 2) Authors should explain how different visualization software like CellxGene and many others retrieve features or cell metadata and benchmark them against SCUBA. Thank you for the suggestion. We don’t feel this is in scope, as the API for data access in CELLxGENE and other visualization software is not exposed to end users in the way that Seurat’s FetchData is. 3) One of the most common features of exploratory analysis is retrieval of feature values such as gene expression or chromatin accessibility from raw count or processed feature matrices. While this function is presented in Figure 2, it is omitted in the performance testing in Figure 4. Why? Can SCUBA extract, for example, gene expression values for a specified gene from huge matrices (500k cells) from SeuratObjects, SingleCellExperiments, Anndata objects in efficient manner? Authors show only retrieval of cell coordinates and cell metadata which are stored in smaller data structures. Thank you for pointing this out. The function mentioned for retrieval of gene expression data was benchmarked in figure 4A. The captions for figure 4C and figure 4A were switched, which incorrectly suggested that figure 4A was benchmarking fetch_reduction. We regret the confusion caused by this error and have corrected it in the revised version. Figure 4A has also been changed to more clearly reflect that the performance of the original Seruat FetchData is being compared to the methods added in SCUBA. 4) It is not clear if Authors developed also a new faster version of FetchData for SeuratObject. We did not. Figure 4A has been updated to make this clear. In addition, we created a snake case fetch_data generic in response to comment 8, below. `fetch_data.Seurat` is simply a wrapper for Seurat’s FetchData, while `fetch_data.SingleCellExperiment` and `fetch_data.AnnDataR6` are added by SCUBA. This has been made clear in the manuscript and the updated documentation. 5) The speed tests in Figure 4 are confusing. It’s not clear when Authors use native “FetchData” functions from Seurat/Scanpy and when from SCUBA. For example, Figure 4: fetch_metadata is slower than “FetchData” from Scanpy for anndata? As mentioned above, we feel that the new generic fetch_data makes this clear. Figure 4B and figure 4C compare the `fetch_data` method in SCUBA to `fetch_metadata` and `fetch_reduction`, respectively. 6) All the differences in run times in A-C are of the order of 0.5-2 seconds, so negligible for users analyzing the single-cell data. Thanks for this observation. We agree in the context of interactive analysis in an R session, but disagree in the context of interactive web apps that plot data from single-cell objects with many cells. Regardless, while this is a valid point, we feel the main benefit of SCUBA is the consistency in syntax across object formats. 7) Authors state: “Analysis tools generally only accept one object class, forcing users to commit to a suite of packages at the beginning of an analysis. This restriction limits access to tools outside that suite, creating “walled gardens” that pose several challenges for single-cell analysis.” How Scuba overcomes this problem? While SCUBA does not fully overcome this problem, we see SCUBA as being a dependency of packages that would do so. We envision an analysis suite with packages for analyses such as differential gene expression and gene set enrichment analysis, as well as static and interactive visualizations. Packages built on SCUBA access functions will be flexible by default to input object class, and should be easier for end users to use compared to running a function from a conversion package, and then running an existing function from an analysis package. We also expect packages based on SCUBA to be easier to develop, since the access functions are easier to use than running class-specific access code, and have consistent syntax. 8) The package lacks robust and well-organized documentation, such as that provided by the aforementioned zellkoverter, anndataR, or SeuratDisk. The use of the FetchData function is also unclear. The name exceptionally follows the Pascal case naming convention, unlike all other functions which follow the Camel case. If this is done deliberately, e.g., to highlight the use of the Seurat or SeuratObject packages, please consider including a namespace so that the user is aware of the external packages being employed. Alternatively, consider adding the fetch_data function to make the SCUBA package appear more like a closed, independent toolkit. We appreciate these observations. In addition to overhauling the function documentation for clarity, we added a pkgdown site at https://amc-heme.github.io/SCUBA/ . In the site, we have added the “User Guide” vignette to the “Articles” tab, which contains a walkthrough of key functions in the SCUBA package for the access, exploration, and visualization of single-cell datasets. As suggested, we created a new generic fetch_data, and moved the pascal case FetchData methods added by SCUBA to this generic. The fetch_data method for Seurat is a wrapper for Seurat’s FetchData method, and the fetch_data methods for SingleCellExperiment and anndata are added by SCUBA. In addition to improving clarity, the fetch_data generic removes the need for a dependency on Seurat. Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. In this study, William M. Showers and colleagues developed SCUBA, an R package designed to facilitate the access to single-cell data stored in various formats commonly utilized by single-cell data analysis software in R (Seurat, Scran) or Python (Scanpy). These single-cell data storage formats include SeuratObject (Seurat), SingleCellExperiment (Scran, Bioconductor’s single-cell tools), Anndata (Scanpy). Interoperability between R-based and Python-based tools and data types is a real problem in bioinformatics. Several tools are typically used in this case, such as zellkonverter, anndataR, sceasy, or SeuratDisk. However, these tools rely on data type conversion, which can be computationally expensive. SCUBA implements a unified API for single-cell object formats to efficiently access data for exploratory analysis and visualization. It extracts from storage objects using FetchData methods a table with requested features, metadata, and reduction coordinates for each cell. The manuscript is clearly written, with a logical structure that effectively conveys the study's objective and organized in the following structure: 1) Introduction; 2) Methods including subsection Implementation and Operation; 3) Use cases; and 4) Conclusions. The “Use cases” section involve examples of Scuba usage: 1) application of FetchData function to retrieve features, metadata, and dimensionality reduction coordinates; 2) S3 generics and methods for similar tasks as in (1) including functions fetch_metadata and fetch_reduction; 3) speed tests of the functions for SeuratObjects stored in RDS format, SingleCellExperiment and Anndata in h5 formats; 3) presentation of example scripts for single-cell data exploration and visualization. While the issue of single-cell data interoperability is a well-recognized and pervasive challenge in the field, the manuscript in the current form does not appear to present a significant advancement or novel solution to address this problem comprehensively. It represents rather a set of functions that allows accessing data from various single-cell data objects needed for visualization purposes and should be a part of their scExploreR package rather than the standalone package. Thank you for this assessment. The observation that SCUBA is a set of functions for accessing data from single-cell objects is correct, but we disagree that SCUBA should not be a standalone package. The functions provided by SCUBA are useful both in fetching data for interactive report generation (the usage context for scExploreR), and for static report generation by bioinformaticians. The consistent usage of SCUBA across object formats facilitates, for example, re-running a specific visualization script on data from a group that uses a different object class. SCUBA is a tool for developers to work seamlessly across different object classes, and we envision it as the basis of an analysis suite of static visualization packages, as well as the basis of scExploreR. We improved our documentation with examples of how users would integrate SCUBA into their analysis scripts. Other comments: 1) The authors justify the need for SCUBA development by the fact that conversion between different data storage formats results in data loss upon conversion or this process is error-prone. Additionally, the rapid development of single-cell packages means that conversion functions are difficult to maintain and frequently break due to changes in other packages. I don’t understand why data is lost during conversion or why it is error-prone and how their approach overcome these limitations. For me, Scuba has exactly the same problems. In case of mentioned updates in single-cell third-party software and storage formats, Authors’ SCUBA code will require updates in the same way. While it is true that SCUBA is vulnerable to changes in underlying object class implementation and must be maintained, we see this vulnerability as being less severe than with conversion packages. Conversion methods such as those mentioned aim to convert the entirety of each object class to another class, while SCUBA functions each extract small subsets of data. While still requiring active maintenance to track upstream changes, we believe this atomic approach is substantially less vulnerable to breaking changes that affect the entire package. 2) Authors should explain how different visualization software like CellxGene and many others retrieve features or cell metadata and benchmark them against SCUBA. Thank you for the suggestion. We don’t feel this is in scope, as the API for data access in CELLxGENE and other visualization software is not exposed to end users in the way that Seurat’s FetchData is. 3) One of the most common features of exploratory analysis is retrieval of feature values such as gene expression or chromatin accessibility from raw count or processed feature matrices. While this function is presented in Figure 2, it is omitted in the performance testing in Figure 4. Why? Can SCUBA extract, for example, gene expression values for a specified gene from huge matrices (500k cells) from SeuratObjects, SingleCellExperiments, Anndata objects in efficient manner? Authors show only retrieval of cell coordinates and cell metadata which are stored in smaller data structures. Thank you for pointing this out. The function mentioned for retrieval of gene expression data was benchmarked in figure 4A. The captions for figure 4C and figure 4A were switched, which incorrectly suggested that figure 4A was benchmarking fetch_reduction. We regret the confusion caused by this error and have corrected it in the revised version. Figure 4A has also been changed to more clearly reflect that the performance of the original Seruat FetchData is being compared to the methods added in SCUBA. 4) It is not clear if Authors developed also a new faster version of FetchData for SeuratObject. We did not. Figure 4A has been updated to make this clear. In addition, we created a snake case fetch_data generic in response to comment 8, below. `fetch_data.Seurat` is simply a wrapper for Seurat’s FetchData, while `fetch_data.SingleCellExperiment` and `fetch_data.AnnDataR6` are added by SCUBA. This has been made clear in the manuscript and the updated documentation. 5) The speed tests in Figure 4 are confusing. It’s not clear when Authors use native “FetchData” functions from Seurat/Scanpy and when from SCUBA. For example, Figure 4: fetch_metadata is slower than “FetchData” from Scanpy for anndata? As mentioned above, we feel that the new generic fetch_data makes this clear. Figure 4B and figure 4C compare the `fetch_data` method in SCUBA to `fetch_metadata` and `fetch_reduction`, respectively. 6) All the differences in run times in A-C are of the order of 0.5-2 seconds, so negligible for users analyzing the single-cell data. Thanks for this observation. We agree in the context of interactive analysis in an R session, but disagree in the context of interactive web apps that plot data from single-cell objects with many cells. Regardless, while this is a valid point, we feel the main benefit of SCUBA is the consistency in syntax across object formats. 7) Authors state: “Analysis tools generally only accept one object class, forcing users to commit to a suite of packages at the beginning of an analysis. This restriction limits access to tools outside that suite, creating “walled gardens” that pose several challenges for single-cell analysis.” How Scuba overcomes this problem? While SCUBA does not fully overcome this problem, we see SCUBA as being a dependency of packages that would do so. We envision an analysis suite with packages for analyses such as differential gene expression and gene set enrichment analysis, as well as static and interactive visualizations. Packages built on SCUBA access functions will be flexible by default to input object class, and should be easier for end users to use compared to running a function from a conversion package, and then running an existing function from an analysis package. We also expect packages based on SCUBA to be easier to develop, since the access functions are easier to use than running class-specific access code, and have consistent syntax. 8) The package lacks robust and well-organized documentation, such as that provided by the aforementioned zellkoverter, anndataR, or SeuratDisk. The use of the FetchData function is also unclear. The name exceptionally follows the Pascal case naming convention, unlike all other functions which follow the Camel case. If this is done deliberately, e.g., to highlight the use of the Seurat or SeuratObject packages, please consider including a namespace so that the user is aware of the external packages being employed. Alternatively, consider adding the fetch_data function to make the SCUBA package appear more like a closed, independent toolkit. We appreciate these observations. In addition to overhauling the function documentation for clarity, we added a pkgdown site at https://amc-heme.github.io/SCUBA/ . In the site, we have added the “User Guide” vignette to the “Articles” tab, which contains a walkthrough of key functions in the SCUBA package for the access, exploration, and visualization of single-cell datasets. As suggested, we created a new generic fetch_data, and moved the pascal case FetchData methods added by SCUBA to this generic. The fetch_data method for Seurat is a wrapper for Seurat’s FetchData method, and the fetch_data methods for SingleCellExperiment and anndata are added by SCUBA. In addition to improving clarity, the fetch_data generic removes the need for a dependency on Seurat. Competing Interests: No competing interests were disclosed. Close Report a concern Respond or Comment COMMENTS ON THIS REPORT Author Response 16 Jun 2025 William Showers , Division of Hematology, University of Colorado Anschutz Medical Campus, Aurora, USA 16 Jun 2025 Author Response Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see ... Continue reading Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. In this study, William M. Showers and colleagues developed SCUBA, an R package designed to facilitate the access to single-cell data stored in various formats commonly utilized by single-cell data analysis software in R (Seurat, Scran) or Python (Scanpy). These single-cell data storage formats include SeuratObject (Seurat), SingleCellExperiment (Scran, Bioconductor’s single-cell tools), Anndata (Scanpy). Interoperability between R-based and Python-based tools and data types is a real problem in bioinformatics. Several tools are typically used in this case, such as zellkonverter, anndataR, sceasy, or SeuratDisk. However, these tools rely on data type conversion, which can be computationally expensive. SCUBA implements a unified API for single-cell object formats to efficiently access data for exploratory analysis and visualization. It extracts from storage objects using FetchData methods a table with requested features, metadata, and reduction coordinates for each cell. The manuscript is clearly written, with a logical structure that effectively conveys the study's objective and organized in the following structure: 1) Introduction; 2) Methods including subsection Implementation and Operation; 3) Use cases; and 4) Conclusions. The “Use cases” section involve examples of Scuba usage: 1) application of FetchData function to retrieve features, metadata, and dimensionality reduction coordinates; 2) S3 generics and methods for similar tasks as in (1) including functions fetch_metadata and fetch_reduction; 3) speed tests of the functions for SeuratObjects stored in RDS format, SingleCellExperiment and Anndata in h5 formats; 3) presentation of example scripts for single-cell data exploration and visualization. While the issue of single-cell data interoperability is a well-recognized and pervasive challenge in the field, the manuscript in the current form does not appear to present a significant advancement or novel solution to address this problem comprehensively. It represents rather a set of functions that allows accessing data from various single-cell data objects needed for visualization purposes and should be a part of their scExploreR package rather than the standalone package. Thank you for this assessment. The observation that SCUBA is a set of functions for accessing data from single-cell objects is correct, but we disagree that SCUBA should not be a standalone package. The functions provided by SCUBA are useful both in fetching data for interactive report generation (the usage context for scExploreR), and for static report generation by bioinformaticians. The consistent usage of SCUBA across object formats facilitates, for example, re-running a specific visualization script on data from a group that uses a different object class. SCUBA is a tool for developers to work seamlessly across different object classes, and we envision it as the basis of an analysis suite of static visualization packages, as well as the basis of scExploreR. We improved our documentation with examples of how users would integrate SCUBA into their analysis scripts. Other comments: 1) The authors justify the need for SCUBA development by the fact that conversion between different data storage formats results in data loss upon conversion or this process is error-prone. Additionally, the rapid development of single-cell packages means that conversion functions are difficult to maintain and frequently break due to changes in other packages. I don’t understand why data is lost during conversion or why it is error-prone and how their approach overcome these limitations. For me, Scuba has exactly the same problems. In case of mentioned updates in single-cell third-party software and storage formats, Authors’ SCUBA code will require updates in the same way. While it is true that SCUBA is vulnerable to changes in underlying object class implementation and must be maintained, we see this vulnerability as being less severe than with conversion packages. Conversion methods such as those mentioned aim to convert the entirety of each object class to another class, while SCUBA functions each extract small subsets of data. While still requiring active maintenance to track upstream changes, we believe this atomic approach is substantially less vulnerable to breaking changes that affect the entire package. 2) Authors should explain how different visualization software like CellxGene and many others retrieve features or cell metadata and benchmark them against SCUBA. Thank you for the suggestion. We don’t feel this is in scope, as the API for data access in CELLxGENE and other visualization software is not exposed to end users in the way that Seurat’s FetchData is. 3) One of the most common features of exploratory analysis is retrieval of feature values such as gene expression or chromatin accessibility from raw count or processed feature matrices. While this function is presented in Figure 2, it is omitted in the performance testing in Figure 4. Why? Can SCUBA extract, for example, gene expression values for a specified gene from huge matrices (500k cells) from SeuratObjects, SingleCellExperiments, Anndata objects in efficient manner? Authors show only retrieval of cell coordinates and cell metadata which are stored in smaller data structures. Thank you for pointing this out. The function mentioned for retrieval of gene expression data was benchmarked in figure 4A. The captions for figure 4C and figure 4A were switched, which incorrectly suggested that figure 4A was benchmarking fetch_reduction. We regret the confusion caused by this error and have corrected it in the revised version. Figure 4A has also been changed to more clearly reflect that the performance of the original Seruat FetchData is being compared to the methods added in SCUBA. 4) It is not clear if Authors developed also a new faster version of FetchData for SeuratObject. We did not. Figure 4A has been updated to make this clear. In addition, we created a snake case fetch_data generic in response to comment 8, below. `fetch_data.Seurat` is simply a wrapper for Seurat’s FetchData, while `fetch_data.SingleCellExperiment` and `fetch_data.AnnDataR6` are added by SCUBA. This has been made clear in the manuscript and the updated documentation. 5) The speed tests in Figure 4 are confusing. It’s not clear when Authors use native “FetchData” functions from Seurat/Scanpy and when from SCUBA. For example, Figure 4: fetch_metadata is slower than “FetchData” from Scanpy for anndata? As mentioned above, we feel that the new generic fetch_data makes this clear. Figure 4B and figure 4C compare the `fetch_data` method in SCUBA to `fetch_metadata` and `fetch_reduction`, respectively. 6) All the differences in run times in A-C are of the order of 0.5-2 seconds, so negligible for users analyzing the single-cell data. Thanks for this observation. We agree in the context of interactive analysis in an R session, but disagree in the context of interactive web apps that plot data from single-cell objects with many cells. Regardless, while this is a valid point, we feel the main benefit of SCUBA is the consistency in syntax across object formats. 7) Authors state: “Analysis tools generally only accept one object class, forcing users to commit to a suite of packages at the beginning of an analysis. This restriction limits access to tools outside that suite, creating “walled gardens” that pose several challenges for single-cell analysis.” How Scuba overcomes this problem? While SCUBA does not fully overcome this problem, we see SCUBA as being a dependency of packages that would do so. We envision an analysis suite with packages for analyses such as differential gene expression and gene set enrichment analysis, as well as static and interactive visualizations. Packages built on SCUBA access functions will be flexible by default to input object class, and should be easier for end users to use compared to running a function from a conversion package, and then running an existing function from an analysis package. We also expect packages based on SCUBA to be easier to develop, since the access functions are easier to use than running class-specific access code, and have consistent syntax. 8) The package lacks robust and well-organized documentation, such as that provided by the aforementioned zellkoverter, anndataR, or SeuratDisk. The use of the FetchData function is also unclear. The name exceptionally follows the Pascal case naming convention, unlike all other functions which follow the Camel case. If this is done deliberately, e.g., to highlight the use of the Seurat or SeuratObject packages, please consider including a namespace so that the user is aware of the external packages being employed. Alternatively, consider adding the fetch_data function to make the SCUBA package appear more like a closed, independent toolkit. We appreciate these observations. In addition to overhauling the function documentation for clarity, we added a pkgdown site at https://amc-heme.github.io/SCUBA/ . In the site, we have added the “User Guide” vignette to the “Articles” tab, which contains a walkthrough of key functions in the SCUBA package for the access, exploration, and visualization of single-cell datasets. As suggested, we created a new generic fetch_data, and moved the pascal case FetchData methods added by SCUBA to this generic. The fetch_data method for Seurat is a wrapper for Seurat’s FetchData method, and the fetch_data methods for SingleCellExperiment and anndata are added by SCUBA. In addition to improving clarity, the fetch_data generic removes the need for a dependency on Seurat. Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. In this study, William M. Showers and colleagues developed SCUBA, an R package designed to facilitate the access to single-cell data stored in various formats commonly utilized by single-cell data analysis software in R (Seurat, Scran) or Python (Scanpy). These single-cell data storage formats include SeuratObject (Seurat), SingleCellExperiment (Scran, Bioconductor’s single-cell tools), Anndata (Scanpy). Interoperability between R-based and Python-based tools and data types is a real problem in bioinformatics. Several tools are typically used in this case, such as zellkonverter, anndataR, sceasy, or SeuratDisk. However, these tools rely on data type conversion, which can be computationally expensive. SCUBA implements a unified API for single-cell object formats to efficiently access data for exploratory analysis and visualization. It extracts from storage objects using FetchData methods a table with requested features, metadata, and reduction coordinates for each cell. The manuscript is clearly written, with a logical structure that effectively conveys the study's objective and organized in the following structure: 1) Introduction; 2) Methods including subsection Implementation and Operation; 3) Use cases; and 4) Conclusions. The “Use cases” section involve examples of Scuba usage: 1) application of FetchData function to retrieve features, metadata, and dimensionality reduction coordinates; 2) S3 generics and methods for similar tasks as in (1) including functions fetch_metadata and fetch_reduction; 3) speed tests of the functions for SeuratObjects stored in RDS format, SingleCellExperiment and Anndata in h5 formats; 3) presentation of example scripts for single-cell data exploration and visualization. While the issue of single-cell data interoperability is a well-recognized and pervasive challenge in the field, the manuscript in the current form does not appear to present a significant advancement or novel solution to address this problem comprehensively. It represents rather a set of functions that allows accessing data from various single-cell data objects needed for visualization purposes and should be a part of their scExploreR package rather than the standalone package. Thank you for this assessment. The observation that SCUBA is a set of functions for accessing data from single-cell objects is correct, but we disagree that SCUBA should not be a standalone package. The functions provided by SCUBA are useful both in fetching data for interactive report generation (the usage context for scExploreR), and for static report generation by bioinformaticians. The consistent usage of SCUBA across object formats facilitates, for example, re-running a specific visualization script on data from a group that uses a different object class. SCUBA is a tool for developers to work seamlessly across different object classes, and we envision it as the basis of an analysis suite of static visualization packages, as well as the basis of scExploreR. We improved our documentation with examples of how users would integrate SCUBA into their analysis scripts. Other comments: 1) The authors justify the need for SCUBA development by the fact that conversion between different data storage formats results in data loss upon conversion or this process is error-prone. Additionally, the rapid development of single-cell packages means that conversion functions are difficult to maintain and frequently break due to changes in other packages. I don’t understand why data is lost during conversion or why it is error-prone and how their approach overcome these limitations. For me, Scuba has exactly the same problems. In case of mentioned updates in single-cell third-party software and storage formats, Authors’ SCUBA code will require updates in the same way. While it is true that SCUBA is vulnerable to changes in underlying object class implementation and must be maintained, we see this vulnerability as being less severe than with conversion packages. Conversion methods such as those mentioned aim to convert the entirety of each object class to another class, while SCUBA functions each extract small subsets of data. While still requiring active maintenance to track upstream changes, we believe this atomic approach is substantially less vulnerable to breaking changes that affect the entire package. 2) Authors should explain how different visualization software like CellxGene and many others retrieve features or cell metadata and benchmark them against SCUBA. Thank you for the suggestion. We don’t feel this is in scope, as the API for data access in CELLxGENE and other visualization software is not exposed to end users in the way that Seurat’s FetchData is. 3) One of the most common features of exploratory analysis is retrieval of feature values such as gene expression or chromatin accessibility from raw count or processed feature matrices. While this function is presented in Figure 2, it is omitted in the performance testing in Figure 4. Why? Can SCUBA extract, for example, gene expression values for a specified gene from huge matrices (500k cells) from SeuratObjects, SingleCellExperiments, Anndata objects in efficient manner? Authors show only retrieval of cell coordinates and cell metadata which are stored in smaller data structures. Thank you for pointing this out. The function mentioned for retrieval of gene expression data was benchmarked in figure 4A. The captions for figure 4C and figure 4A were switched, which incorrectly suggested that figure 4A was benchmarking fetch_reduction. We regret the confusion caused by this error and have corrected it in the revised version. Figure 4A has also been changed to more clearly reflect that the performance of the original Seruat FetchData is being compared to the methods added in SCUBA. 4) It is not clear if Authors developed also a new faster version of FetchData for SeuratObject. We did not. Figure 4A has been updated to make this clear. In addition, we created a snake case fetch_data generic in response to comment 8, below. `fetch_data.Seurat` is simply a wrapper for Seurat’s FetchData, while `fetch_data.SingleCellExperiment` and `fetch_data.AnnDataR6` are added by SCUBA. This has been made clear in the manuscript and the updated documentation. 5) The speed tests in Figure 4 are confusing. It’s not clear when Authors use native “FetchData” functions from Seurat/Scanpy and when from SCUBA. For example, Figure 4: fetch_metadata is slower than “FetchData” from Scanpy for anndata? As mentioned above, we feel that the new generic fetch_data makes this clear. Figure 4B and figure 4C compare the `fetch_data` method in SCUBA to `fetch_metadata` and `fetch_reduction`, respectively. 6) All the differences in run times in A-C are of the order of 0.5-2 seconds, so negligible for users analyzing the single-cell data. Thanks for this observation. We agree in the context of interactive analysis in an R session, but disagree in the context of interactive web apps that plot data from single-cell objects with many cells. Regardless, while this is a valid point, we feel the main benefit of SCUBA is the consistency in syntax across object formats. 7) Authors state: “Analysis tools generally only accept one object class, forcing users to commit to a suite of packages at the beginning of an analysis. This restriction limits access to tools outside that suite, creating “walled gardens” that pose several challenges for single-cell analysis.” How Scuba overcomes this problem? While SCUBA does not fully overcome this problem, we see SCUBA as being a dependency of packages that would do so. We envision an analysis suite with packages for analyses such as differential gene expression and gene set enrichment analysis, as well as static and interactive visualizations. Packages built on SCUBA access functions will be flexible by default to input object class, and should be easier for end users to use compared to running a function from a conversion package, and then running an existing function from an analysis package. We also expect packages based on SCUBA to be easier to develop, since the access functions are easier to use than running class-specific access code, and have consistent syntax. 8) The package lacks robust and well-organized documentation, such as that provided by the aforementioned zellkoverter, anndataR, or SeuratDisk. The use of the FetchData function is also unclear. The name exceptionally follows the Pascal case naming convention, unlike all other functions which follow the Camel case. If this is done deliberately, e.g., to highlight the use of the Seurat or SeuratObject packages, please consider including a namespace so that the user is aware of the external packages being employed. Alternatively, consider adding the fetch_data function to make the SCUBA package appear more like a closed, independent toolkit. We appreciate these observations. In addition to overhauling the function documentation for clarity, we added a pkgdown site at https://amc-heme.github.io/SCUBA/ . In the site, we have added the “User Guide” vignette to the “Articles” tab, which contains a walkthrough of key functions in the SCUBA package for the access, exploration, and visualization of single-cell datasets. As suggested, we created a new generic fetch_data, and moved the pascal case FetchData methods added by SCUBA to this generic. The fetch_data method for Seurat is a wrapper for Seurat’s FetchData method, and the fetch_data methods for SingleCellExperiment and anndata are added by SCUBA. In addition to improving clarity, the fetch_data generic removes the need for a dependency on Seurat. Competing Interests: No competing interests were disclosed. Close Report a concern COMMENT ON THIS REPORT Views 0 Cite How to cite this report: Ullrich K. Reviewer Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.169727.r334007 ) The direct URL for this report is: https://f1000research.com/articles/13-1256/v1#referee-response-334007 NOTE: it is important to ensure the information in square brackets after the title is included in this citation. Close Copy Citation Details Reviewer Report 15 Jan 2025 Kristian Ullrich , Scientific IT group, Max Planck Institute for Evolutionary Biology, Plon, Germany Approved with Reservations VIEWS 0 https://doi.org/10.5256/f1000research.169727.r334007 In this article the authors provide a valuable R package that implements a unified data access API for single-cell object formats like `anndata` objects (Python) and `Seurat/SingleCellExperiment` objects (R). The SCUBA API (implemented in R) keeps the original single-cell objects ... Continue reading READ ALL In this article the authors provide a valuable R package that implements a unified data access API for single-cell object formats like `anndata` objects (Python) and `Seurat/SingleCellExperiment` objects (R). The SCUBA API (implemented in R) keeps the original single-cell objects unmodified and use three data accession methods, namely `FetchData`, `fetch_metdata` and `fetch_reduction`. To more easily compare pre-processed data stored in common single-cell data formats, like `AnnData`, `SingleCellExperiment` (SCE) and `Seurat`, the authors fetch metadata from cells and genes from the original object and create a `data.frame` R object with the requested features. Using the `data.frame` object, downstream plotting function are provided to create plots in the `ggplot2` R package grammar. Code review Given the dependency issues related to R-base version and Python version, I would encourage the authors to submit their package to either CRAN or Bioconductor R repository so that R package community standards are tested in a continious integration setup. The authors should try to alter their code to pass at least the R-CMD-check without warnings and errors. In the "Use cases" section, the authors claim that "Additional vignettes are provided on the SCUBA GitHub page", which is not true time of writing this review. Please add the mentioned vignettes to the GitHub page. The provided R functions should contain runnable examples. Building a vignette would help the community to present the basic functions from the R package and provide more background information, if needed. I would suggest the authors to include a github workflow to create the R package documentation, vignettes and convert it into a website e.g. with the `pkgdown` package or similar workflow. Software I was able to install the software and run the examples given on the main github page, despite the need to pre-load the `Seurat` R package. As indicated in the Minor comments part, the three functions `reduction_names()`, `assay_names()` and `features_in_assay()` have been removed from the repository and the given example code block should be also removed from the github page. The Rmarkdown files on the github page https://github.com/amc-heme/SCUBA_Manuscript has been inspected and partially run. I have not re-created the subset data sets, however the code base seems to be fine. Major comments If many genes are requested by the `FetchData` function, creating a single `data.frame` has the offsite to not benefit from sparse data structures leading to high memory footprints. Please implement some checks to prevent a user given the local resources to request too many gene features. Please remove "manually" from the sentence: "Currently, the most efective solution is to manually convert between object classes." Here, manually implies a programatically high efford to do so, which in my opinion is not true, given the existing converting tools like `SeuratWrapper`, `zellkonverter`, `SCEasy Converter` `scDIOR`. Please add the corresponding literature for the mentioned tools. In your R DESCRIPTION file you set the `reticulate` and `anndata` R packages as suggests, however for your API to be fully functional these packages needs to be imported. Please change accordingly. Minor comments Please change the DESCRIPTION and add the corresponding author/creators in the github repository. Please alter the examples from your initial github page so that they work as expected. E.g. the `FetchData` function for Seurat objects is not pre-loaded, one need to first import Seurat `library(Seurat)`. Please remove the following example part from your github pages, sicne the functions have been removed and are not working anymore `reduction_names()`, `assay_names()` and `features_in_assay()`. Please update the corresponding `fetch_...` function main description and param field about what object types are supported, since the `AnnDataR6` class in most cases is supported but not mentioned. Please rephrase "Single-cell analysis can be inaccessible to bench scientists due to programming experience required, ...", in my opinion this sentence is formulated too harshly, as it is possible e.g. to convert and analyze single-cell objects with GUI-based solutions such as usegalaxy.eu and the SCEasy Converter plugin. Please provide a working example for a default user without admin priviliges how to setup and use `reticulate` in R for the usecase described here to access an `AnnData` object and how to install the prerequisite Python packages. The authors refer to the main `reticulate` documentation, however, showing a working code snippet example would be beneficial for scientists not fluent in both programming languages. Please remove "for all three object types" from Figure 5A "Common plotting script for all three object types", since the plotting function applies on the constructed intermediate `data.frame` object. Figure 6, please change the code example to use the R default pipe operator `|>` instead of the `magrittr` pipe operator `%>%` so that one would not need to pre-load the corresponding libraries. Is the rationale for developing the new software tool clearly explained? Yes Is the description of the software tool technically sound? Partly Are sufficient details of the code, methods and analysis (if applicable) provided to allow replication of the software development and its use by others? Yes Is sufficient information provided to allow interpretation of the expected output datasets and any results generated using the tool? Yes Are the conclusions about the tool and its performance adequately supported by the findings presented in the article? Partly References 1. Cakir B, Prete M, Huang N, van Dongen S, et al.: Comparison of visualization tools for single-cell RNAseq data. NAR Genom Bioinform . 2020; 2 (3): lqaa052 PubMed Abstract | Publisher Full Text 2. Feng H, Lin L, Chen J: scDIOR: single cell RNA-seq data IO software. BMC Bioinformatics . 2022; 23 (1): 16 PubMed Abstract | Publisher Full Text Competing Interests: No competing interests were disclosed. Reviewer Expertise: Comparative Genomics, Bioinformatics, R Programming I confirm that I have read this submission and believe that I have an appropriate level of expertise to confirm that it is of an acceptable scientific standard, however I have significant reservations, as outlined above. Close READ LESS CITE CITE HOW TO CITE THIS REPORT Ullrich K. Reviewer Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.169727.r334007 ) The direct URL for this report is: https://f1000research.com/articles/13-1256/v1#referee-response-334007 NOTE: it is important to ensure the information in square brackets after the title is included in all citations of this article. COPY CITATION DETAILS Report a concern Author Response 16 Jun 2025 William Showers , Division of Hematology, University of Colorado Anschutz Medical Campus, Aurora, USA 16 Jun 2025 Author Response Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see ... Continue reading Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. In this article the authors provide a valuable R package that implements a unified data access API for single-cell object formats like `anndata` objects (Python) and `Seurat/SingleCellExperiment` objects (R). The SCUBA API (implemented in R) keeps the original single-cell objects unmodified and use three data accession methods, namely `FetchData`, `fetch_metdata` and `fetch_reduction`. To more easily compare pre-processed data stored in common single-cell data formats, like `AnnData`, `SingleCellExperiment` (SCE) and `Seurat`, the authors fetch metadata from cells and genes from the original object and create a `data.frame` R object with the requested features. Using the `data.frame` object, downstream plotting function are provided to create plots in the `ggplot2` R package grammar. Code review Given the dependency issues related to R-base version and Python version, I would encourage the authors to submit their package to either CRAN or Bioconductor R repository so that R package community standards are tested in a continious integration setup. The authors should try to alter their code to pass at least the R-CMD-check without warnings and errors. Thank you for this valuable feedback. While we do not intend to submit this package to CRAN or Bioconductor, we recognize the value of continuous integration and have ensured that the code now passes the R-CMD-check without warnings or errors. In the "Use cases" section, the authors claim that "Additional vignettes are provided on the SCUBA GitHub page", which is not true time of writing this review. Please add the mentioned vignettes to the GitHub page. We have added a vignette with examples of all major SCUBA functions (see the comment below). The provided R functions should contain runnable examples. Building a vignette would help the community to present the basic functions from the R package and provide more background information, if needed. I would suggest the authors to include a github workflow to create the R package documentation, vignettes and convert it into a website e.g. with the `pkgdown` package or similar workflow. We appreciate this feedback, and have improved our documentation to address these important observations. Specifically, we have added a pkgdown site at https://amc-heme.github.io/SCUBA/ . Here, we have added the “User Guide” vignette to the “Articles” tab, which contains a walkthrough of key functions in the SCUBA package for the access, exploration, and visualization of single-cell datasets. The vignette shows usage examples for all three object types currently supported by SCUBA. In addition to adding the vignette, we updated the function documentation to improve clarity and provide usage examples. Software I was able to install the software and run the examples given on the main github page, despite the need to pre-load the `Seurat` R package. As indicated in the Minor comments part, the three functions `reduction_names()`, `assay_names()` and `features_in_assay()` have been removed from the repository and the given example code block should be also removed from the github page. Thanks for letting us know about this. We have removed reduction_names() and assay_names() from the documentation to avoid this confusion. Features_in_assay() was added back to the package, and documentation on usage of this function is now on our pkgdown site, in the “User Guide” article. The Rmarkdown files on the github page https://github.com/amc-heme/SCUBA_Manuscript have been inspected and partially run. I have not re-created the subset data sets, however the code base seems to be fine. We have double-checked the code in amc-heme/SCUBA_Manuscript internally for consistent outputs. Please let us know if you notice further issues with the code in the manuscript repo. Major comments If many genes are requested by the `FetchData` function, creating a single `data.frame` has the offsite to not benefit from sparse data structures leading to high memory footprints. Please implement some checks to prevent a user given the local resources to request too many gene features. Thank you for this observation. We don’t feel that it is necessary to prevent users from doing this, but we have added a warning to users (shown below) in this scenario. The warning appears when 1000 or more genes are requested. "A very large number of features was requested (<> features). fetch_data is not intended to be used with feature queries of this length. Data is returned in a dense format, so the memory usage of the output may be very large. Also, this query may take a while to complete." Please remove "manually" from the sentence: "Currently, the most efective solution is to manually convert between object classes." Here, manually implies a programatically high efford to do so, which in my opinion is not true, given the existing converting tools like `SeuratWrapper`, `zellkonverter`, `SCEasy Converter` `scDIOR`. Please add the corresponding literature for the mentioned tools. Thank you for pointing this out. The sentence was changed as follows in the updated manuscript: "All major single-cell analysis packages implement conversion functions, and third-party packages such as sceasy, Zellconverter, and scDIOR are specifically designed for these conversions. Additionally, SeruatWrapper implements conversion functions that allow several otherwise-incompatible single-cell analysis packages to be used on Seurat objects." Citations for the corresponding literature have also been added to the revised manuscript. In your R DESCRIPTION file you set the `reticulate` and `anndata` R packages as suggests, however for your API to be fully functional these packages needs to be imported. Please change accordingly. We appreciate this observation. While we prefer not to require users to install anndata and reticulate if they are not using anndata objects, we have added a conditional statement in all exported AnnDataR6 methods to check if these packages are installed, and throw an error directing users to install these packages if they are not. Minor comments Please change the DESCRIPTION and add the corresponding author/creators in the github repository. This change was made. Please alter the examples from your initial github page so that they work as expected. E.g. the `FetchData` function for Seurat objects is not pre-loaded, one need to first import Seurat `library(Seurat)`. To keep users from having to import Seurat to use our FetchData methods, we moved them to a new generic defined within our package (fetch_data). Please remove the following example part from your github pages, since the functions have been removed and are not working anymore `reduction_names()`, `assay_names()` and `features_in_assay()`. All three functions have been removed from the README on our GitHub page. We added `features_in_assay()` back to SCUBA, and have added documentation for the function in our user guide vignette. Please update the corresponding `fetch_...` function main description and param field about what object types are supported, since the `AnnDataR6` class in most cases is supported but not mentioned. This has been corrected. All fetch_* functions and all functions that take an object as a parameter now mention all object types corrected. The description text for the `object` parameter is now also consistent across all functions. Please rephrase "Single-cell analysis can be inaccessible to bench scientists due to programming experience required, ...", in my opinion this sentence is formulated too harshly, as it is possible e.g. to convert and analyze single-cell objects with GUI-based solutions such as usegalaxy.eu and the SCEasy Converter plugin. We have modified this sentence to the following: “Single-cell analysis requires programming experience for full customization of analysis and visualization, and different object formats make it even more difficult for biologists to analyze data”. Please provide a working example for a default user without admin privileges how to setup and use `reticulate` in R for the usecase described here to access an `AnnData` object and how to install the prerequisite Python packages. The authors refer to the main `reticulate` documentation, however, showing a working code snippet example would be beneficial for scientists not fluent in both programming languages. Thanks for this suggestion. We have added this to the README, under the section “Additional Installation for anndata Objects”. Please remove "for all three object types" from Figure 5A "Common plotting script for all three object types", since the plotting function applies on the constructed intermediate `data.frame` object. This has been changed. The sentence now reads “Example script for visualizing expression of a gene by cluster in a density plot.” Figure 6, please change the code example to use the R default pipe operator `|>` instead of the `magrittr` pipe operator `%>%` so that one would not need to pre-load the corresponding libraries. This change has been made. Please see figure 6 in the revised submission. Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. In this article the authors provide a valuable R package that implements a unified data access API for single-cell object formats like `anndata` objects (Python) and `Seurat/SingleCellExperiment` objects (R). The SCUBA API (implemented in R) keeps the original single-cell objects unmodified and use three data accession methods, namely `FetchData`, `fetch_metdata` and `fetch_reduction`. To more easily compare pre-processed data stored in common single-cell data formats, like `AnnData`, `SingleCellExperiment` (SCE) and `Seurat`, the authors fetch metadata from cells and genes from the original object and create a `data.frame` R object with the requested features. Using the `data.frame` object, downstream plotting function are provided to create plots in the `ggplot2` R package grammar. Code review Given the dependency issues related to R-base version and Python version, I would encourage the authors to submit their package to either CRAN or Bioconductor R repository so that R package community standards are tested in a continious integration setup. The authors should try to alter their code to pass at least the R-CMD-check without warnings and errors. Thank you for this valuable feedback. While we do not intend to submit this package to CRAN or Bioconductor, we recognize the value of continuous integration and have ensured that the code now passes the R-CMD-check without warnings or errors. In the "Use cases" section, the authors claim that "Additional vignettes are provided on the SCUBA GitHub page", which is not true time of writing this review. Please add the mentioned vignettes to the GitHub page. We have added a vignette with examples of all major SCUBA functions (see the comment below). The provided R functions should contain runnable examples. Building a vignette would help the community to present the basic functions from the R package and provide more background information, if needed. I would suggest the authors to include a github workflow to create the R package documentation, vignettes and convert it into a website e.g. with the `pkgdown` package or similar workflow. We appreciate this feedback, and have improved our documentation to address these important observations. Specifically, we have added a pkgdown site at https://amc-heme.github.io/SCUBA/ . Here, we have added the “User Guide” vignette to the “Articles” tab, which contains a walkthrough of key functions in the SCUBA package for the access, exploration, and visualization of single-cell datasets. The vignette shows usage examples for all three object types currently supported by SCUBA. In addition to adding the vignette, we updated the function documentation to improve clarity and provide usage examples. Software I was able to install the software and run the examples given on the main github page, despite the need to pre-load the `Seurat` R package. As indicated in the Minor comments part, the three functions `reduction_names()`, `assay_names()` and `features_in_assay()` have been removed from the repository and the given example code block should be also removed from the github page. Thanks for letting us know about this. We have removed reduction_names() and assay_names() from the documentation to avoid this confusion. Features_in_assay() was added back to the package, and documentation on usage of this function is now on our pkgdown site, in the “User Guide” article. The Rmarkdown files on the github page https://github.com/amc-heme/SCUBA_Manuscript have been inspected and partially run. I have not re-created the subset data sets, however the code base seems to be fine. We have double-checked the code in amc-heme/SCUBA_Manuscript internally for consistent outputs. Please let us know if you notice further issues with the code in the manuscript repo. Major comments If many genes are requested by the `FetchData` function, creating a single `data.frame` has the offsite to not benefit from sparse data structures leading to high memory footprints. Please implement some checks to prevent a user given the local resources to request too many gene features. Thank you for this observation. We don’t feel that it is necessary to prevent users from doing this, but we have added a warning to users (shown below) in this scenario. The warning appears when 1000 or more genes are requested. "A very large number of features was requested (<> features). fetch_data is not intended to be used with feature queries of this length. Data is returned in a dense format, so the memory usage of the output may be very large. Also, this query may take a while to complete." Please remove "manually" from the sentence: "Currently, the most efective solution is to manually convert between object classes." Here, manually implies a programatically high efford to do so, which in my opinion is not true, given the existing converting tools like `SeuratWrapper`, `zellkonverter`, `SCEasy Converter` `scDIOR`. Please add the corresponding literature for the mentioned tools. Thank you for pointing this out. The sentence was changed as follows in the updated manuscript: "All major single-cell analysis packages implement conversion functions, and third-party packages such as sceasy, Zellconverter, and scDIOR are specifically designed for these conversions. Additionally, SeruatWrapper implements conversion functions that allow several otherwise-incompatible single-cell analysis packages to be used on Seurat objects." Citations for the corresponding literature have also been added to the revised manuscript. In your R DESCRIPTION file you set the `reticulate` and `anndata` R packages as suggests, however for your API to be fully functional these packages needs to be imported. Please change accordingly. We appreciate this observation. While we prefer not to require users to install anndata and reticulate if they are not using anndata objects, we have added a conditional statement in all exported AnnDataR6 methods to check if these packages are installed, and throw an error directing users to install these packages if they are not. Minor comments Please change the DESCRIPTION and add the corresponding author/creators in the github repository. This change was made. Please alter the examples from your initial github page so that they work as expected. E.g. the `FetchData` function for Seurat objects is not pre-loaded, one need to first import Seurat `library(Seurat)`. To keep users from having to import Seurat to use our FetchData methods, we moved them to a new generic defined within our package (fetch_data). Please remove the following example part from your github pages, since the functions have been removed and are not working anymore `reduction_names()`, `assay_names()` and `features_in_assay()`. All three functions have been removed from the README on our GitHub page. We added `features_in_assay()` back to SCUBA, and have added documentation for the function in our user guide vignette. Please update the corresponding `fetch_...` function main description and param field about what object types are supported, since the `AnnDataR6` class in most cases is supported but not mentioned. This has been corrected. All fetch_* functions and all functions that take an object as a parameter now mention all object types corrected. The description text for the `object` parameter is now also consistent across all functions. Please rephrase "Single-cell analysis can be inaccessible to bench scientists due to programming experience required, ...", in my opinion this sentence is formulated too harshly, as it is possible e.g. to convert and analyze single-cell objects with GUI-based solutions such as usegalaxy.eu and the SCEasy Converter plugin. We have modified this sentence to the following: “Single-cell analysis requires programming experience for full customization of analysis and visualization, and different object formats make it even more difficult for biologists to analyze data”. Please provide a working example for a default user without admin privileges how to setup and use `reticulate` in R for the usecase described here to access an `AnnData` object and how to install the prerequisite Python packages. The authors refer to the main `reticulate` documentation, however, showing a working code snippet example would be beneficial for scientists not fluent in both programming languages. Thanks for this suggestion. We have added this to the README, under the section “Additional Installation for anndata Objects”. Please remove "for all three object types" from Figure 5A "Common plotting script for all three object types", since the plotting function applies on the constructed intermediate `data.frame` object. This has been changed. The sentence now reads “Example script for visualizing expression of a gene by cluster in a density plot.” Figure 6, please change the code example to use the R default pipe operator `|>` instead of the `magrittr` pipe operator `%>%` so that one would not need to pre-load the corresponding libraries. This change has been made. Please see figure 6 in the revised submission. Competing Interests: No competing interests were disclosed. Close Report a concern Respond or Comment COMMENTS ON THIS REPORT Author Response 16 Jun 2025 William Showers , Division of Hematology, University of Colorado Anschutz Medical Campus, Aurora, USA 16 Jun 2025 Author Response Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see ... Continue reading Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. In this article the authors provide a valuable R package that implements a unified data access API for single-cell object formats like `anndata` objects (Python) and `Seurat/SingleCellExperiment` objects (R). The SCUBA API (implemented in R) keeps the original single-cell objects unmodified and use three data accession methods, namely `FetchData`, `fetch_metdata` and `fetch_reduction`. To more easily compare pre-processed data stored in common single-cell data formats, like `AnnData`, `SingleCellExperiment` (SCE) and `Seurat`, the authors fetch metadata from cells and genes from the original object and create a `data.frame` R object with the requested features. Using the `data.frame` object, downstream plotting function are provided to create plots in the `ggplot2` R package grammar. Code review Given the dependency issues related to R-base version and Python version, I would encourage the authors to submit their package to either CRAN or Bioconductor R repository so that R package community standards are tested in a continious integration setup. The authors should try to alter their code to pass at least the R-CMD-check without warnings and errors. Thank you for this valuable feedback. While we do not intend to submit this package to CRAN or Bioconductor, we recognize the value of continuous integration and have ensured that the code now passes the R-CMD-check without warnings or errors. In the "Use cases" section, the authors claim that "Additional vignettes are provided on the SCUBA GitHub page", which is not true time of writing this review. Please add the mentioned vignettes to the GitHub page. We have added a vignette with examples of all major SCUBA functions (see the comment below). The provided R functions should contain runnable examples. Building a vignette would help the community to present the basic functions from the R package and provide more background information, if needed. I would suggest the authors to include a github workflow to create the R package documentation, vignettes and convert it into a website e.g. with the `pkgdown` package or similar workflow. We appreciate this feedback, and have improved our documentation to address these important observations. Specifically, we have added a pkgdown site at https://amc-heme.github.io/SCUBA/ . Here, we have added the “User Guide” vignette to the “Articles” tab, which contains a walkthrough of key functions in the SCUBA package for the access, exploration, and visualization of single-cell datasets. The vignette shows usage examples for all three object types currently supported by SCUBA. In addition to adding the vignette, we updated the function documentation to improve clarity and provide usage examples. Software I was able to install the software and run the examples given on the main github page, despite the need to pre-load the `Seurat` R package. As indicated in the Minor comments part, the three functions `reduction_names()`, `assay_names()` and `features_in_assay()` have been removed from the repository and the given example code block should be also removed from the github page. Thanks for letting us know about this. We have removed reduction_names() and assay_names() from the documentation to avoid this confusion. Features_in_assay() was added back to the package, and documentation on usage of this function is now on our pkgdown site, in the “User Guide” article. The Rmarkdown files on the github page https://github.com/amc-heme/SCUBA_Manuscript have been inspected and partially run. I have not re-created the subset data sets, however the code base seems to be fine. We have double-checked the code in amc-heme/SCUBA_Manuscript internally for consistent outputs. Please let us know if you notice further issues with the code in the manuscript repo. Major comments If many genes are requested by the `FetchData` function, creating a single `data.frame` has the offsite to not benefit from sparse data structures leading to high memory footprints. Please implement some checks to prevent a user given the local resources to request too many gene features. Thank you for this observation. We don’t feel that it is necessary to prevent users from doing this, but we have added a warning to users (shown below) in this scenario. The warning appears when 1000 or more genes are requested. "A very large number of features was requested (<> features). fetch_data is not intended to be used with feature queries of this length. Data is returned in a dense format, so the memory usage of the output may be very large. Also, this query may take a while to complete." Please remove "manually" from the sentence: "Currently, the most efective solution is to manually convert between object classes." Here, manually implies a programatically high efford to do so, which in my opinion is not true, given the existing converting tools like `SeuratWrapper`, `zellkonverter`, `SCEasy Converter` `scDIOR`. Please add the corresponding literature for the mentioned tools. Thank you for pointing this out. The sentence was changed as follows in the updated manuscript: "All major single-cell analysis packages implement conversion functions, and third-party packages such as sceasy, Zellconverter, and scDIOR are specifically designed for these conversions. Additionally, SeruatWrapper implements conversion functions that allow several otherwise-incompatible single-cell analysis packages to be used on Seurat objects." Citations for the corresponding literature have also been added to the revised manuscript. In your R DESCRIPTION file you set the `reticulate` and `anndata` R packages as suggests, however for your API to be fully functional these packages needs to be imported. Please change accordingly. We appreciate this observation. While we prefer not to require users to install anndata and reticulate if they are not using anndata objects, we have added a conditional statement in all exported AnnDataR6 methods to check if these packages are installed, and throw an error directing users to install these packages if they are not. Minor comments Please change the DESCRIPTION and add the corresponding author/creators in the github repository. This change was made. Please alter the examples from your initial github page so that they work as expected. E.g. the `FetchData` function for Seurat objects is not pre-loaded, one need to first import Seurat `library(Seurat)`. To keep users from having to import Seurat to use our FetchData methods, we moved them to a new generic defined within our package (fetch_data). Please remove the following example part from your github pages, since the functions have been removed and are not working anymore `reduction_names()`, `assay_names()` and `features_in_assay()`. All three functions have been removed from the README on our GitHub page. We added `features_in_assay()` back to SCUBA, and have added documentation for the function in our user guide vignette. Please update the corresponding `fetch_...` function main description and param field about what object types are supported, since the `AnnDataR6` class in most cases is supported but not mentioned. This has been corrected. All fetch_* functions and all functions that take an object as a parameter now mention all object types corrected. The description text for the `object` parameter is now also consistent across all functions. Please rephrase "Single-cell analysis can be inaccessible to bench scientists due to programming experience required, ...", in my opinion this sentence is formulated too harshly, as it is possible e.g. to convert and analyze single-cell objects with GUI-based solutions such as usegalaxy.eu and the SCEasy Converter plugin. We have modified this sentence to the following: “Single-cell analysis requires programming experience for full customization of analysis and visualization, and different object formats make it even more difficult for biologists to analyze data”. Please provide a working example for a default user without admin privileges how to setup and use `reticulate` in R for the usecase described here to access an `AnnData` object and how to install the prerequisite Python packages. The authors refer to the main `reticulate` documentation, however, showing a working code snippet example would be beneficial for scientists not fluent in both programming languages. Thanks for this suggestion. We have added this to the README, under the section “Additional Installation for anndata Objects”. Please remove "for all three object types" from Figure 5A "Common plotting script for all three object types", since the plotting function applies on the constructed intermediate `data.frame` object. This has been changed. The sentence now reads “Example script for visualizing expression of a gene by cluster in a density plot.” Figure 6, please change the code example to use the R default pipe operator `|>` instead of the `magrittr` pipe operator `%>%` so that one would not need to pre-load the corresponding libraries. This change has been made. Please see figure 6 in the revised submission. Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. In this article the authors provide a valuable R package that implements a unified data access API for single-cell object formats like `anndata` objects (Python) and `Seurat/SingleCellExperiment` objects (R). The SCUBA API (implemented in R) keeps the original single-cell objects unmodified and use three data accession methods, namely `FetchData`, `fetch_metdata` and `fetch_reduction`. To more easily compare pre-processed data stored in common single-cell data formats, like `AnnData`, `SingleCellExperiment` (SCE) and `Seurat`, the authors fetch metadata from cells and genes from the original object and create a `data.frame` R object with the requested features. Using the `data.frame` object, downstream plotting function are provided to create plots in the `ggplot2` R package grammar. Code review Given the dependency issues related to R-base version and Python version, I would encourage the authors to submit their package to either CRAN or Bioconductor R repository so that R package community standards are tested in a continious integration setup. The authors should try to alter their code to pass at least the R-CMD-check without warnings and errors. Thank you for this valuable feedback. While we do not intend to submit this package to CRAN or Bioconductor, we recognize the value of continuous integration and have ensured that the code now passes the R-CMD-check without warnings or errors. In the "Use cases" section, the authors claim that "Additional vignettes are provided on the SCUBA GitHub page", which is not true time of writing this review. Please add the mentioned vignettes to the GitHub page. We have added a vignette with examples of all major SCUBA functions (see the comment below). The provided R functions should contain runnable examples. Building a vignette would help the community to present the basic functions from the R package and provide more background information, if needed. I would suggest the authors to include a github workflow to create the R package documentation, vignettes and convert it into a website e.g. with the `pkgdown` package or similar workflow. We appreciate this feedback, and have improved our documentation to address these important observations. Specifically, we have added a pkgdown site at https://amc-heme.github.io/SCUBA/ . Here, we have added the “User Guide” vignette to the “Articles” tab, which contains a walkthrough of key functions in the SCUBA package for the access, exploration, and visualization of single-cell datasets. The vignette shows usage examples for all three object types currently supported by SCUBA. In addition to adding the vignette, we updated the function documentation to improve clarity and provide usage examples. Software I was able to install the software and run the examples given on the main github page, despite the need to pre-load the `Seurat` R package. As indicated in the Minor comments part, the three functions `reduction_names()`, `assay_names()` and `features_in_assay()` have been removed from the repository and the given example code block should be also removed from the github page. Thanks for letting us know about this. We have removed reduction_names() and assay_names() from the documentation to avoid this confusion. Features_in_assay() was added back to the package, and documentation on usage of this function is now on our pkgdown site, in the “User Guide” article. The Rmarkdown files on the github page https://github.com/amc-heme/SCUBA_Manuscript have been inspected and partially run. I have not re-created the subset data sets, however the code base seems to be fine. We have double-checked the code in amc-heme/SCUBA_Manuscript internally for consistent outputs. Please let us know if you notice further issues with the code in the manuscript repo. Major comments If many genes are requested by the `FetchData` function, creating a single `data.frame` has the offsite to not benefit from sparse data structures leading to high memory footprints. Please implement some checks to prevent a user given the local resources to request too many gene features. Thank you for this observation. We don’t feel that it is necessary to prevent users from doing this, but we have added a warning to users (shown below) in this scenario. The warning appears when 1000 or more genes are requested. "A very large number of features was requested (<> features). fetch_data is not intended to be used with feature queries of this length. Data is returned in a dense format, so the memory usage of the output may be very large. Also, this query may take a while to complete." Please remove "manually" from the sentence: "Currently, the most efective solution is to manually convert between object classes." Here, manually implies a programatically high efford to do so, which in my opinion is not true, given the existing converting tools like `SeuratWrapper`, `zellkonverter`, `SCEasy Converter` `scDIOR`. Please add the corresponding literature for the mentioned tools. Thank you for pointing this out. The sentence was changed as follows in the updated manuscript: "All major single-cell analysis packages implement conversion functions, and third-party packages such as sceasy, Zellconverter, and scDIOR are specifically designed for these conversions. Additionally, SeruatWrapper implements conversion functions that allow several otherwise-incompatible single-cell analysis packages to be used on Seurat objects." Citations for the corresponding literature have also been added to the revised manuscript. In your R DESCRIPTION file you set the `reticulate` and `anndata` R packages as suggests, however for your API to be fully functional these packages needs to be imported. Please change accordingly. We appreciate this observation. While we prefer not to require users to install anndata and reticulate if they are not using anndata objects, we have added a conditional statement in all exported AnnDataR6 methods to check if these packages are installed, and throw an error directing users to install these packages if they are not. Minor comments Please change the DESCRIPTION and add the corresponding author/creators in the github repository. This change was made. Please alter the examples from your initial github page so that they work as expected. E.g. the `FetchData` function for Seurat objects is not pre-loaded, one need to first import Seurat `library(Seurat)`. To keep users from having to import Seurat to use our FetchData methods, we moved them to a new generic defined within our package (fetch_data). Please remove the following example part from your github pages, since the functions have been removed and are not working anymore `reduction_names()`, `assay_names()` and `features_in_assay()`. All three functions have been removed from the README on our GitHub page. We added `features_in_assay()` back to SCUBA, and have added documentation for the function in our user guide vignette. Please update the corresponding `fetch_...` function main description and param field about what object types are supported, since the `AnnDataR6` class in most cases is supported but not mentioned. This has been corrected. All fetch_* functions and all functions that take an object as a parameter now mention all object types corrected. The description text for the `object` parameter is now also consistent across all functions. Please rephrase "Single-cell analysis can be inaccessible to bench scientists due to programming experience required, ...", in my opinion this sentence is formulated too harshly, as it is possible e.g. to convert and analyze single-cell objects with GUI-based solutions such as usegalaxy.eu and the SCEasy Converter plugin. We have modified this sentence to the following: “Single-cell analysis requires programming experience for full customization of analysis and visualization, and different object formats make it even more difficult for biologists to analyze data”. Please provide a working example for a default user without admin privileges how to setup and use `reticulate` in R for the usecase described here to access an `AnnData` object and how to install the prerequisite Python packages. The authors refer to the main `reticulate` documentation, however, showing a working code snippet example would be beneficial for scientists not fluent in both programming languages. Thanks for this suggestion. We have added this to the README, under the section “Additional Installation for anndata Objects”. Please remove "for all three object types" from Figure 5A "Common plotting script for all three object types", since the plotting function applies on the constructed intermediate `data.frame` object. This has been changed. The sentence now reads “Example script for visualizing expression of a gene by cluster in a density plot.” Figure 6, please change the code example to use the R default pipe operator `|>` instead of the `magrittr` pipe operator `%>%` so that one would not need to pre-load the corresponding libraries. This change has been made. Please see figure 6 in the revised submission. Competing Interests: No competing interests were disclosed. Close Report a concern COMMENT ON THIS REPORT Views 0 Cite How to cite this report: Li H. Reviewer Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.169727.r346283 ) The direct URL for this report is: https://f1000research.com/articles/13-1256/v1#referee-response-346283 NOTE: it is important to ensure the information in square brackets after the title is included in this citation. Close Copy Citation Details Reviewer Report 17 Dec 2024 Huamei Li , Nanjing University, Nanjing, Jiangsu, China Approved VIEWS 0 https://doi.org/10.5256/f1000research.169727.r346283 Showers et al. developed the SCUBA R package as a unified API for single-cell data analysis. In single-cell and spatial transcriptomics studies, data format conversion between Seurat, SingleCellExperiment, and AnnData often presents challenges, leading to obstacles in downstream analyses. While ... Continue reading READ ALL Showers et al. developed the SCUBA R package as a unified API for single-cell data analysis. In single-cell and spatial transcriptomics studies, data format conversion between Seurat, SingleCellExperiment, and AnnData often presents challenges, leading to obstacles in downstream analyses. While several tools have been developed to address data format conversion issues, SCUBA provides a unified and user-friendly interface for handling multiple formats and simplifies single-cell data processing workflows, making it a promising tool for practical applications. However, several concerns regarding SCUBA require further clarification: 1) The README file available at https://github.com/amc-heme/SCUBA/tree/main does not include examples demonstrating how SCUBA reads Seurat, SingleCellExperiment, and AnnData formats from local files. Additionally, it is unclear whether SCUBA addresses compatibility issues arising from different versions of these formats, such as Seurat 4.0+ versus Seurat 5.0+. Can SCUBA facilitate seamless data format conversion and overcome challenges posed by version discrepancies? 2) While SCUBA provides application examples for single-cell datasets, it remains unclear whether the tool can be effectively extended to spatial transcriptomics datasets generated by different platforms. Clarification on its applicability to spatial datasets would be beneficial. 3) To enhance visualization capabilities, it is recommended that SCUBA include optional smoothing methods for displaying the expression distribution of feature genes. This would allow for better identification of regions with concentrated expression of specific features. 4) The SCUBA documentation could be further improved by providing more detailed explanations of the functions, their usage, and intended purposes. Additionally, including a comprehensive analysis example that integrates both single-cell and spatial transcriptomics data would help illustrate the full workflow and practical utility of SCUBA. Is the rationale for developing the new software tool clearly explained? Yes Is the description of the software tool technically sound? Yes Are sufficient details of the code, methods and analysis (if applicable) provided to allow replication of the software development and its use by others? Partly Is sufficient information provided to allow interpretation of the expected output datasets and any results generated using the tool? Yes Are the conclusions about the tool and its performance adequately supported by the findings presented in the article? Yes Competing Interests: No competing interests were disclosed. Reviewer Expertise: Bioinformatics, Immunogenetics, Single-cell and spatial technologies I confirm that I have read this submission and believe that I have an appropriate level of expertise to confirm that it is of an acceptable scientific standard. Close READ LESS CITE CITE HOW TO CITE THIS REPORT Li H. Reviewer Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.169727.r346283 ) The direct URL for this report is: https://f1000research.com/articles/13-1256/v1#referee-response-346283 NOTE: it is important to ensure the information in square brackets after the title is included in all citations of this article. COPY CITATION DETAILS Report a concern Author Response 09 Aug 2025 William Showers , Division of Hematology, University of Colorado Anschutz Medical Campus, Aurora, USA 09 Aug 2025 Author Response Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see ... Continue reading Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. Showers et al. developed the SCUBA R package as a unified API for single-cell data analysis. In single-cell and spatial transcriptomics studies, data format conversion between Seurat, SingleCellExperiment, and AnnData often presents challenges, leading to obstacles in downstream analyses. While several tools have been developed to address data format conversion issues, SCUBA provides a unified and user-friendly interface for handling multiple formats and simplifies single-cell data processing workflows, making it a promising tool for practical applications. However, several concerns regarding SCUBA require further clarification: 1) The README file available at https://github.com/amc-heme/SCUBA/tree/main does not include examples demonstrating how SCUBA reads Seurat, SingleCellExperiment, and AnnData formats from local files. Additionally, it is unclear whether SCUBA addresses compatibility issues arising from different versions of these formats, such as Seurat 4.0+ versus Seurat 5.0+. Can SCUBA facilitate seamless data format conversion and overcome challenges posed by version discrepancies? Thank you for this observation. We have added new documentation via a pkgdown website ( https://amc-heme.github.io/SCUBA/ ). The Article “User Guide” contains a note on how each object class is loaded. SCUBA is seamlessly compatible with Seurat v4 and v5 objects. We have added a note on this to the README. 2) While SCUBA provides application examples for single-cell datasets, it remains unclear whether the tool can be effectively extended to spatial transcriptomics datasets generated by different platforms. Clarification on its applicability to spatial datasets would be beneficial. SCUBA partially supports spatial datasets. Aspects of spatial datasets that can be expressed as a counts matrix can be loaded into SCUBA, but we do not yet support the loading of image files. We have added a note on this to the README. 3) To enhance visualization capabilities, it is recommended that SCUBA include optional smoothing methods for displaying the expression distribution of feature genes. This would allow for better identification of regions with concentrated expression of specific features. Thank you for the suggestion. While we agree that this is a valuable approach, we feel this is out of scope for the current tool, and welcome users to apply their own smoothing methods in plotting scripts based on SCUBA. 4) The SCUBA documentation could be further improved by providing more detailed explanations of the functions, their usage, and intended purposes. Additionally, including a comprehensive analysis example that integrates both single-cell and spatial transcriptomics data would help illustrate the full workflow and practical utility of SCUBA. Thank you for the suggestion. We have added the suggested documentation to the README and the user guide vignette on the pkgdown website. We have also updated function documentation in SCUBA v.1.1.0. Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. Showers et al. developed the SCUBA R package as a unified API for single-cell data analysis. In single-cell and spatial transcriptomics studies, data format conversion between Seurat, SingleCellExperiment, and AnnData often presents challenges, leading to obstacles in downstream analyses. While several tools have been developed to address data format conversion issues, SCUBA provides a unified and user-friendly interface for handling multiple formats and simplifies single-cell data processing workflows, making it a promising tool for practical applications. However, several concerns regarding SCUBA require further clarification: 1) The README file available at https://github.com/amc-heme/SCUBA/tree/main does not include examples demonstrating how SCUBA reads Seurat, SingleCellExperiment, and AnnData formats from local files. Additionally, it is unclear whether SCUBA addresses compatibility issues arising from different versions of these formats, such as Seurat 4.0+ versus Seurat 5.0+. Can SCUBA facilitate seamless data format conversion and overcome challenges posed by version discrepancies? Thank you for this observation. We have added new documentation via a pkgdown website ( https://amc-heme.github.io/SCUBA/ ). The Article “User Guide” contains a note on how each object class is loaded. SCUBA is seamlessly compatible with Seurat v4 and v5 objects. We have added a note on this to the README. 2) While SCUBA provides application examples for single-cell datasets, it remains unclear whether the tool can be effectively extended to spatial transcriptomics datasets generated by different platforms. Clarification on its applicability to spatial datasets would be beneficial. SCUBA partially supports spatial datasets. Aspects of spatial datasets that can be expressed as a counts matrix can be loaded into SCUBA, but we do not yet support the loading of image files. We have added a note on this to the README. 3) To enhance visualization capabilities, it is recommended that SCUBA include optional smoothing methods for displaying the expression distribution of feature genes. This would allow for better identification of regions with concentrated expression of specific features. Thank you for the suggestion. While we agree that this is a valuable approach, we feel this is out of scope for the current tool, and welcome users to apply their own smoothing methods in plotting scripts based on SCUBA. 4) The SCUBA documentation could be further improved by providing more detailed explanations of the functions, their usage, and intended purposes. Additionally, including a comprehensive analysis example that integrates both single-cell and spatial transcriptomics data would help illustrate the full workflow and practical utility of SCUBA. Thank you for the suggestion. We have added the suggested documentation to the README and the user guide vignette on the pkgdown website. We have also updated function documentation in SCUBA v.1.1.0. Competing Interests: We disclose no competing interests. Close Report a concern Respond or Comment COMMENTS ON THIS REPORT Author Response 09 Aug 2025 William Showers , Division of Hematology, University of Colorado Anschutz Medical Campus, Aurora, USA 09 Aug 2025 Author Response Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see ... Continue reading Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. Showers et al. developed the SCUBA R package as a unified API for single-cell data analysis. In single-cell and spatial transcriptomics studies, data format conversion between Seurat, SingleCellExperiment, and AnnData often presents challenges, leading to obstacles in downstream analyses. While several tools have been developed to address data format conversion issues, SCUBA provides a unified and user-friendly interface for handling multiple formats and simplifies single-cell data processing workflows, making it a promising tool for practical applications. However, several concerns regarding SCUBA require further clarification: 1) The README file available at https://github.com/amc-heme/SCUBA/tree/main does not include examples demonstrating how SCUBA reads Seurat, SingleCellExperiment, and AnnData formats from local files. Additionally, it is unclear whether SCUBA addresses compatibility issues arising from different versions of these formats, such as Seurat 4.0+ versus Seurat 5.0+. Can SCUBA facilitate seamless data format conversion and overcome challenges posed by version discrepancies? Thank you for this observation. We have added new documentation via a pkgdown website ( https://amc-heme.github.io/SCUBA/ ). The Article “User Guide” contains a note on how each object class is loaded. SCUBA is seamlessly compatible with Seurat v4 and v5 objects. We have added a note on this to the README. 2) While SCUBA provides application examples for single-cell datasets, it remains unclear whether the tool can be effectively extended to spatial transcriptomics datasets generated by different platforms. Clarification on its applicability to spatial datasets would be beneficial. SCUBA partially supports spatial datasets. Aspects of spatial datasets that can be expressed as a counts matrix can be loaded into SCUBA, but we do not yet support the loading of image files. We have added a note on this to the README. 3) To enhance visualization capabilities, it is recommended that SCUBA include optional smoothing methods for displaying the expression distribution of feature genes. This would allow for better identification of regions with concentrated expression of specific features. Thank you for the suggestion. While we agree that this is a valuable approach, we feel this is out of scope for the current tool, and welcome users to apply their own smoothing methods in plotting scripts based on SCUBA. 4) The SCUBA documentation could be further improved by providing more detailed explanations of the functions, their usage, and intended purposes. Additionally, including a comprehensive analysis example that integrates both single-cell and spatial transcriptomics data would help illustrate the full workflow and practical utility of SCUBA. Thank you for the suggestion. We have added the suggested documentation to the README and the user guide vignette on the pkgdown website. We have also updated function documentation in SCUBA v.1.1.0. Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. Showers et al. developed the SCUBA R package as a unified API for single-cell data analysis. In single-cell and spatial transcriptomics studies, data format conversion between Seurat, SingleCellExperiment, and AnnData often presents challenges, leading to obstacles in downstream analyses. While several tools have been developed to address data format conversion issues, SCUBA provides a unified and user-friendly interface for handling multiple formats and simplifies single-cell data processing workflows, making it a promising tool for practical applications. However, several concerns regarding SCUBA require further clarification: 1) The README file available at https://github.com/amc-heme/SCUBA/tree/main does not include examples demonstrating how SCUBA reads Seurat, SingleCellExperiment, and AnnData formats from local files. Additionally, it is unclear whether SCUBA addresses compatibility issues arising from different versions of these formats, such as Seurat 4.0+ versus Seurat 5.0+. Can SCUBA facilitate seamless data format conversion and overcome challenges posed by version discrepancies? Thank you for this observation. We have added new documentation via a pkgdown website ( https://amc-heme.github.io/SCUBA/ ). The Article “User Guide” contains a note on how each object class is loaded. SCUBA is seamlessly compatible with Seurat v4 and v5 objects. We have added a note on this to the README. 2) While SCUBA provides application examples for single-cell datasets, it remains unclear whether the tool can be effectively extended to spatial transcriptomics datasets generated by different platforms. Clarification on its applicability to spatial datasets would be beneficial. SCUBA partially supports spatial datasets. Aspects of spatial datasets that can be expressed as a counts matrix can be loaded into SCUBA, but we do not yet support the loading of image files. We have added a note on this to the README. 3) To enhance visualization capabilities, it is recommended that SCUBA include optional smoothing methods for displaying the expression distribution of feature genes. This would allow for better identification of regions with concentrated expression of specific features. Thank you for the suggestion. While we agree that this is a valuable approach, we feel this is out of scope for the current tool, and welcome users to apply their own smoothing methods in plotting scripts based on SCUBA. 4) The SCUBA documentation could be further improved by providing more detailed explanations of the functions, their usage, and intended purposes. Additionally, including a comprehensive analysis example that integrates both single-cell and spatial transcriptomics data would help illustrate the full workflow and practical utility of SCUBA. Thank you for the suggestion. We have added the suggested documentation to the README and the user guide vignette on the pkgdown website. We have also updated function documentation in SCUBA v.1.1.0. Competing Interests: We disclose no competing interests. Close Report a concern COMMENT ON THIS REPORT Comments on this article Comments (0) Version 2 VERSION 2 PUBLISHED 21 Oct 2024 ADD YOUR COMMENT Comment keyboard_arrow_left keyboard_arrow_right Open Peer Review Reviewer Status info_outline Alongside their report, reviewers assign a status to the article: Approved The paper is scientifically sound in its current form and only minor, if any, improvements are suggested Approved with reservations A number of small changes, sometimes more significant revisions are required to address specific details and improve the papers academic merit. Not approved Fundamental flaws in the paper seriously undermine the findings and conclusions Reviewer Reports Invited Reviewers 1 2 3 4 Version 2 (revision) 02 Jun 25 read read Version 1 21 Oct 24 read read read Huamei Li , Nanjing University, Nanjing, China Kristian Ullrich , Max Planck Institute for Evolutionary Biology, Plon, Germany Damian Panas , Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland; Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland Marcin Tabaka , Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland Benedikt Obermayer , Berlin Institute of Health at Charité – Universitätsmedizin Berlin, Berlin, Germany Comments on this article All Comments (0) Add a comment Sign up for content alerts Sign Up You are now signed up to receive this alert Browse by related subjects keyboard_arrow_left Back to all reports Reviewer Report 0 Views copyright © 2025 Obermayer B. This is an open access peer review report distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. 19 Aug 2025 | for Version 2 Benedikt Obermayer , Berlin Institute of Health at Charité – Universitätsmedizin Berlin, Berlin, Germany 0 Views copyright © 2025 Obermayer B. This is an open access peer review report distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. format_quote Cite this report speaker_notes Responses (0) Approved info_outline Alongside their report, reviewers assign a status to the article: Approved The paper is scientifically sound in its current form and only minor, if any, improvements are suggested Approved with reservations A number of small changes, sometimes more significant revisions are required to address specific details and improve the papers academic merit. Not approved Fundamental flaws in the paper seriously undermine the findings and conclusions This manuscript presents an R package for unified data access to single-cell genomics objects from different commonly used formats (Seurat, SingleCellExperiment, and anndata). In version 2, most issues raised by previous reviewers were satisfactorily addressed, and the paper has reached a sufficiently sound stage. I have one more major issue and a few small corrections that could be incorporated. Major issue: I agree with Damian Panas and Marcin Tabaka in that this package does not really present a significant advancement or novel solution to comprehensively address the problem of interoperability. People who manage to successfully set up reticulate and conda environments to be used within their R installation would be expected to be able to get necessary data out of objects in different formats. People with less expertise for which a visualization / data exploration tool allowing for different input formats might be most useful will probably not be able to set this up in a reasonable time frame. In that case, I'd prefer a web-based or maybe Docker-based explorer that accepts R as well as python objects as input. Minor issues: - I don't really understand the advantage of SCUBA over the anndata R package for reading h5ad files and accessing their contents, apart from a unified syntax. (However, anndata specific data structures such as the ad$raw slot don't seem to be accessible using SCUBA). SCUBA appears to be somewhat faster than anndata in my hands, but that is probably of little concern to most users. This could be explained better. - I noticed two typos (Suerat instead of Seurat in Fig. 1 caption, and SueratWrapper instead of SeuratWrapper on p4 bottom). - When installing the package, my existing conda env with anndata did not have a sufficiently recent version (including anndata.abc, which I think was introduced in 0.10). Requirements don't specify this - the plot functions still use the deprecated FetchData method. Why is density plot not part of the package if it's used in the User Guide? Is the rationale for developing the new software tool clearly explained? Yes Is the description of the software tool technically sound? Yes Are sufficient details of the code, methods and analysis (if applicable) provided to allow replication of the software development and its use by others? Yes Is sufficient information provided to allow interpretation of the expected output datasets and any results generated using the tool? Yes Are the conclusions about the tool and its performance adequately supported by the findings presented in the article? Partly Competing Interests No competing interests were disclosed. Reviewer Expertise Bioinformatics, single-cell genomics, computational biology I confirm that I have read this submission and believe that I have an appropriate level of expertise to confirm that it is of an acceptable scientific standard. reply Respond to this report Responses (0) Obermayer B. Peer Review Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.182803.r396950) NOTE: it is important to ensure the information in square brackets after the title is included in this citation. The direct URL for this report is: https://f1000research.com/articles/13-1256/v2#referee-response-396950 keyboard_arrow_left Back to all reports Reviewer Report 0 Views copyright © 2025 Tabaka M et al. This is an open access peer review report distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. 13 Aug 2025 | for Version 2 Marcin Tabaka , International Centre for Translaional Eye Research, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland Damian Panas , International Centre for Translational Eye Research, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Mazowieckie, Poland; ICTER, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland 0 Views copyright © 2025 Tabaka M et al. This is an open access peer review report distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. format_quote Cite this report speaker_notes Responses (0) Approved info_outline Alongside their report, reviewers assign a status to the article: Approved The paper is scientifically sound in its current form and only minor, if any, improvements are suggested Approved with reservations A number of small changes, sometimes more significant revisions are required to address specific details and improve the papers academic merit. Not approved Fundamental flaws in the paper seriously undermine the findings and conclusions The revised article comprises significant improvements on the initial submission. The comprehensive documentation, created using the pkgdown framework, is an essential addition. The documentation is now clearly structured, detailed, and supplemented by numerous examples. The authors have reformatted the manuscript to improve clarity and expanded the benchmarking section to provide a more informative performance comparison. Another significant addition is the new fetch_data() function, which resolves one of the most important issues raised in the initial submission. While a few minor problems presented earlier remain, the most critical concerns have been addressed and resolved. Overall, the current version of the SCUBA is a robust, high-quality tool that demonstrates thoughtful improvements in its usability. Competing Interests No competing interests were disclosed. Reviewer Expertise Single-cell Genomics, Bioinformatics We confirm that we have read this submission and believe that we have an appropriate level of expertise to confirm that it is of an acceptable scientific standard. reply Respond to this report Responses (0) Tabaka M and Panas D. Peer Review Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.182803.r389307) NOTE: it is important to ensure the information in square brackets after the title is included in this citation. The direct URL for this report is: https://f1000research.com/articles/13-1256/v2#referee-response-389307 keyboard_arrow_left Back to all reports Reviewer Report 0 Views copyright © 2025 Tabaka M et al. This is an open access peer review report distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. 29 Jan 2025 | for Version 1 Damian Panas , International Centre for Translational Eye Research, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Mazowieckie, Poland; ICTER, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland Marcin Tabaka , International Centre for Translaional Eye Research, Institute of Physical Chemistry, Polish Academy of Sciences, Warsaw, Poland 0 Views copyright © 2025 Tabaka M et al. This is an open access peer review report distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. format_quote Cite this report speaker_notes Responses (1) Not Approved info_outline Alongside their report, reviewers assign a status to the article: Approved The paper is scientifically sound in its current form and only minor, if any, improvements are suggested Approved with reservations A number of small changes, sometimes more significant revisions are required to address specific details and improve the papers academic merit. Not approved Fundamental flaws in the paper seriously undermine the findings and conclusions In this study, William M. Showers and colleagues developed SCUBA, an R package designed to facilitate the access to single-cell data stored in various formats commonly utilized by single-cell data analysis software in R (Seurat, Scran) or Python (Scanpy). These single-cell data storage formats include SeuratObject (Seurat), SingleCellExperiment (Scran, Bioconductor’s single-cell tools), Anndata (Scanpy). Interoperability between R-based and Python-based tools and data types is a real problem in bioinformatics. Several tools are typically used in this case, such as zellkonverter, anndataR, sceasy, or SeuratDisk. However, these tools rely on data type conversion, which can be computationally expensive. SCUBA implements a unified API for single-cell object formats to efficiently access data for exploratory analysis and visualization. It extracts from storage objects using FetchData methods a table with requested features, metadata, and reduction coordinates for each cell. The manuscript is clearly written, with a logical structure that effectively conveys the study's objective and organized in the following structure: 1) Introduction; 2) Methods including subsection Implementation and Operation; 3) Use cases; and 4) Conclusions. The “Use cases” section involve examples of Scuba usage: 1) application of FetchData function to retrieve features, metadata, and dimensionality reduction coordinates; 2) S3 generics and methods for similar tasks as in (1) including functions fetch_metadata and fetch_reduction; 3) speed tests of the functions for SeuratObjects stored in RDS format, SingleCellExperiment and Anndata in h5 formats; 3) presentation of example scripts for single-cell data exploration and visualization. While the issue of single-cell data interoperability is a well-recognized and pervasive challenge in the field, the manuscript in the current form does not appear to present a significant advancement or novel solution to address this problem comprehensively. It represents rather a set of functions that allows accessing data from various single-cell data objects needed for visualization purposes and should be a part of their scExploreR package rather than the standalone package. Other comments: 1) The authors justify the need for SCUBA development by the fact that conversion between different data storage formats results in data loss upon conversion or this process is error-prone. Additionally, the rapid development of single-cell packages means that conversion functions are difficult to maintain and frequently break due to changes in other packages. I don’t understand why data is lost during conversion or why it is error-prone and how their approach overcome these limitations. For me, Scuba has exactly the same problems. In case of mentioned updates in single-cell third-party software and storage formats, Authors’ SCUBA code will require updates in the same way. 2) Authors should explain how different visualization software like CellxGene and many others retrieve features or cell metadata and benchmark them against SCUBA. 3) One of the most common features of exploratory analysis is retrieval of feature values such as gene expression or chromatin accessibility from raw count or processed feature matrices. While this function is presented in Figure 2, it is omitted in the performance testing in Figure 4. Why? Can SCUBA extract, for example, gene expression values for a specified gene from huge matrices (500k cells) from SeuratObjects, SingleCellExperiments, Anndata objects in efficient manner? Authors show only retrieval of cell coordinates and cell metadata which are stored in smaller data structures. 4) It is not clear if Authors developed also a new faster version of FetchData for SeuratObject. 5) The speed tests in Figure 4 are confusing. It’s not clear when Authors use native “FetchData” functions from Seurat/Scanpy and when from SCUBA. For example, Figure 4: fetch_metadata is slower than “FetchData” from Scanpy for anndata? 6) All the differences in run times in A-C are of the order of 0.5-2 seconds, so negligible for users analyzing the single-cell data. 7) Authors state: “Analysis tools generally only accept one object class, forcing users to commit to a suite of packages at the beginning of an analysis. This restriction limits access to tools outside that suite, creating “walled gardens” that pose several challenges for single-cell analysis.” How Scuba overcomes this problem? 8) The package lacks robust and well-organized documentation, such as that provided by the aforementioned zellkoverter, anndataR, or SeuratDisk. The use of the FetchData function is also unclear. The name exceptionally follows the Pascal case naming convention, unlike all other functions which follow the Camel case. If this is done deliberately, e.g., to highlight the use of the Seurat or SeuratObject packages, please consider including a namespace so that the user is aware of the external packages being employed. Alternatively, consider adding the fetch_data function to make the SCUBA package appear more like a closed, independent toolkit. Is the rationale for developing the new software tool clearly explained? Partly Is the description of the software tool technically sound? Partly Are sufficient details of the code, methods and analysis (if applicable) provided to allow replication of the software development and its use by others? Partly Is sufficient information provided to allow interpretation of the expected output datasets and any results generated using the tool? Yes Are the conclusions about the tool and its performance adequately supported by the findings presented in the article? No Competing Interests No competing interests were disclosed. Reviewer Expertise Single-cell Genomics, Bioinformatics We confirm that we have read this submission and believe that we have an appropriate level of expertise to state that we do not consider it to be of an acceptable scientific standard, for reasons outlined above. reply Respond to this report Responses (1) Author Response 16 Jun 2025 William Showers, Division of Hematology, University of Colorado Anschutz Medical Campus, Aurora, USA Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. In this study, William M. Showers and colleagues developed SCUBA, an R package designed to facilitate the access to single-cell data stored in various formats commonly utilized by single-cell data analysis software in R (Seurat, Scran) or Python (Scanpy). These single-cell data storage formats include SeuratObject (Seurat), SingleCellExperiment (Scran, Bioconductor’s single-cell tools), Anndata (Scanpy). Interoperability between R-based and Python-based tools and data types is a real problem in bioinformatics. Several tools are typically used in this case, such as zellkonverter, anndataR, sceasy, or SeuratDisk. However, these tools rely on data type conversion, which can be computationally expensive. SCUBA implements a unified API for single-cell object formats to efficiently access data for exploratory analysis and visualization. It extracts from storage objects using FetchData methods a table with requested features, metadata, and reduction coordinates for each cell. The manuscript is clearly written, with a logical structure that effectively conveys the study's objective and organized in the following structure: 1) Introduction; 2) Methods including subsection Implementation and Operation; 3) Use cases; and 4) Conclusions. The “Use cases” section involve examples of Scuba usage: 1) application of FetchData function to retrieve features, metadata, and dimensionality reduction coordinates; 2) S3 generics and methods for similar tasks as in (1) including functions fetch_metadata and fetch_reduction; 3) speed tests of the functions for SeuratObjects stored in RDS format, SingleCellExperiment and Anndata in h5 formats; 3) presentation of example scripts for single-cell data exploration and visualization. While the issue of single-cell data interoperability is a well-recognized and pervasive challenge in the field, the manuscript in the current form does not appear to present a significant advancement or novel solution to address this problem comprehensively. It represents rather a set of functions that allows accessing data from various single-cell data objects needed for visualization purposes and should be a part of their scExploreR package rather than the standalone package. Thank you for this assessment. The observation that SCUBA is a set of functions for accessing data from single-cell objects is correct, but we disagree that SCUBA should not be a standalone package. The functions provided by SCUBA are useful both in fetching data for interactive report generation (the usage context for scExploreR), and for static report generation by bioinformaticians. The consistent usage of SCUBA across object formats facilitates, for example, re-running a specific visualization script on data from a group that uses a different object class. SCUBA is a tool for developers to work seamlessly across different object classes, and we envision it as the basis of an analysis suite of static visualization packages, as well as the basis of scExploreR. We improved our documentation with examples of how users would integrate SCUBA into their analysis scripts. Other comments: 1) The authors justify the need for SCUBA development by the fact that conversion between different data storage formats results in data loss upon conversion or this process is error-prone. Additionally, the rapid development of single-cell packages means that conversion functions are difficult to maintain and frequently break due to changes in other packages. I don’t understand why data is lost during conversion or why it is error-prone and how their approach overcome these limitations. For me, Scuba has exactly the same problems. In case of mentioned updates in single-cell third-party software and storage formats, Authors’ SCUBA code will require updates in the same way. While it is true that SCUBA is vulnerable to changes in underlying object class implementation and must be maintained, we see this vulnerability as being less severe than with conversion packages. Conversion methods such as those mentioned aim to convert the entirety of each object class to another class, while SCUBA functions each extract small subsets of data. While still requiring active maintenance to track upstream changes, we believe this atomic approach is substantially less vulnerable to breaking changes that affect the entire package. 2) Authors should explain how different visualization software like CellxGene and many others retrieve features or cell metadata and benchmark them against SCUBA. Thank you for the suggestion. We don’t feel this is in scope, as the API for data access in CELLxGENE and other visualization software is not exposed to end users in the way that Seurat’s FetchData is. 3) One of the most common features of exploratory analysis is retrieval of feature values such as gene expression or chromatin accessibility from raw count or processed feature matrices. While this function is presented in Figure 2, it is omitted in the performance testing in Figure 4. Why? Can SCUBA extract, for example, gene expression values for a specified gene from huge matrices (500k cells) from SeuratObjects, SingleCellExperiments, Anndata objects in efficient manner? Authors show only retrieval of cell coordinates and cell metadata which are stored in smaller data structures. Thank you for pointing this out. The function mentioned for retrieval of gene expression data was benchmarked in figure 4A. The captions for figure 4C and figure 4A were switched, which incorrectly suggested that figure 4A was benchmarking fetch_reduction. We regret the confusion caused by this error and have corrected it in the revised version. Figure 4A has also been changed to more clearly reflect that the performance of the original Seruat FetchData is being compared to the methods added in SCUBA. 4) It is not clear if Authors developed also a new faster version of FetchData for SeuratObject. We did not. Figure 4A has been updated to make this clear. In addition, we created a snake case fetch_data generic in response to comment 8, below. `fetch_data.Seurat` is simply a wrapper for Seurat’s FetchData, while `fetch_data.SingleCellExperiment` and `fetch_data.AnnDataR6` are added by SCUBA. This has been made clear in the manuscript and the updated documentation. 5) The speed tests in Figure 4 are confusing. It’s not clear when Authors use native “FetchData” functions from Seurat/Scanpy and when from SCUBA. For example, Figure 4: fetch_metadata is slower than “FetchData” from Scanpy for anndata? As mentioned above, we feel that the new generic fetch_data makes this clear. Figure 4B and figure 4C compare the `fetch_data` method in SCUBA to `fetch_metadata` and `fetch_reduction`, respectively. 6) All the differences in run times in A-C are of the order of 0.5-2 seconds, so negligible for users analyzing the single-cell data. Thanks for this observation. We agree in the context of interactive analysis in an R session, but disagree in the context of interactive web apps that plot data from single-cell objects with many cells. Regardless, while this is a valid point, we feel the main benefit of SCUBA is the consistency in syntax across object formats. 7) Authors state: “Analysis tools generally only accept one object class, forcing users to commit to a suite of packages at the beginning of an analysis. This restriction limits access to tools outside that suite, creating “walled gardens” that pose several challenges for single-cell analysis.” How Scuba overcomes this problem? While SCUBA does not fully overcome this problem, we see SCUBA as being a dependency of packages that would do so. We envision an analysis suite with packages for analyses such as differential gene expression and gene set enrichment analysis, as well as static and interactive visualizations. Packages built on SCUBA access functions will be flexible by default to input object class, and should be easier for end users to use compared to running a function from a conversion package, and then running an existing function from an analysis package. We also expect packages based on SCUBA to be easier to develop, since the access functions are easier to use than running class-specific access code, and have consistent syntax. 8) The package lacks robust and well-organized documentation, such as that provided by the aforementioned zellkoverter, anndataR, or SeuratDisk. The use of the FetchData function is also unclear. The name exceptionally follows the Pascal case naming convention, unlike all other functions which follow the Camel case. If this is done deliberately, e.g., to highlight the use of the Seurat or SeuratObject packages, please consider including a namespace so that the user is aware of the external packages being employed. Alternatively, consider adding the fetch_data function to make the SCUBA package appear more like a closed, independent toolkit. We appreciate these observations. In addition to overhauling the function documentation for clarity, we added a pkgdown site at https://amc-heme.github.io/SCUBA/ . In the site, we have added the “User Guide” vignette to the “Articles” tab, which contains a walkthrough of key functions in the SCUBA package for the access, exploration, and visualization of single-cell datasets. As suggested, we created a new generic fetch_data, and moved the pascal case FetchData methods added by SCUBA to this generic. The fetch_data method for Seurat is a wrapper for Seurat’s FetchData method, and the fetch_data methods for SingleCellExperiment and anndata are added by SCUBA. In addition to improving clarity, the fetch_data generic removes the need for a dependency on Seurat. View more View less Competing Interests No competing interests were disclosed. reply Respond Report a concern Panas D and Tabaka M. Peer Review Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.169727.r350233) NOTE: it is important to ensure the information in square brackets after the title is included in this citation. The direct URL for this report is: https://f1000research.com/articles/13-1256/v1#referee-response-350233 keyboard_arrow_left Back to all reports Reviewer Report 0 Views copyright © 2025 Ullrich K. This is an open access peer review report distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. 15 Jan 2025 | for Version 1 Kristian Ullrich , Scientific IT group, Max Planck Institute for Evolutionary Biology, Plon, Germany 0 Views copyright © 2025 Ullrich K. This is an open access peer review report distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. format_quote Cite this report speaker_notes Responses (1) Approved With Reservations info_outline Alongside their report, reviewers assign a status to the article: Approved The paper is scientifically sound in its current form and only minor, if any, improvements are suggested Approved with reservations A number of small changes, sometimes more significant revisions are required to address specific details and improve the papers academic merit. Not approved Fundamental flaws in the paper seriously undermine the findings and conclusions In this article the authors provide a valuable R package that implements a unified data access API for single-cell object formats like `anndata` objects (Python) and `Seurat/SingleCellExperiment` objects (R). The SCUBA API (implemented in R) keeps the original single-cell objects unmodified and use three data accession methods, namely `FetchData`, `fetch_metdata` and `fetch_reduction`. To more easily compare pre-processed data stored in common single-cell data formats, like `AnnData`, `SingleCellExperiment` (SCE) and `Seurat`, the authors fetch metadata from cells and genes from the original object and create a `data.frame` R object with the requested features. Using the `data.frame` object, downstream plotting function are provided to create plots in the `ggplot2` R package grammar. Code review Given the dependency issues related to R-base version and Python version, I would encourage the authors to submit their package to either CRAN or Bioconductor R repository so that R package community standards are tested in a continious integration setup. The authors should try to alter their code to pass at least the R-CMD-check without warnings and errors. In the "Use cases" section, the authors claim that "Additional vignettes are provided on the SCUBA GitHub page", which is not true time of writing this review. Please add the mentioned vignettes to the GitHub page. The provided R functions should contain runnable examples. Building a vignette would help the community to present the basic functions from the R package and provide more background information, if needed. I would suggest the authors to include a github workflow to create the R package documentation, vignettes and convert it into a website e.g. with the `pkgdown` package or similar workflow. Software I was able to install the software and run the examples given on the main github page, despite the need to pre-load the `Seurat` R package. As indicated in the Minor comments part, the three functions `reduction_names()`, `assay_names()` and `features_in_assay()` have been removed from the repository and the given example code block should be also removed from the github page. The Rmarkdown files on the github page https://github.com/amc-heme/SCUBA_Manuscript has been inspected and partially run. I have not re-created the subset data sets, however the code base seems to be fine. Major comments If many genes are requested by the `FetchData` function, creating a single `data.frame` has the offsite to not benefit from sparse data structures leading to high memory footprints. Please implement some checks to prevent a user given the local resources to request too many gene features. Please remove "manually" from the sentence: "Currently, the most efective solution is to manually convert between object classes." Here, manually implies a programatically high efford to do so, which in my opinion is not true, given the existing converting tools like `SeuratWrapper`, `zellkonverter`, `SCEasy Converter` `scDIOR`. Please add the corresponding literature for the mentioned tools. In your R DESCRIPTION file you set the `reticulate` and `anndata` R packages as suggests, however for your API to be fully functional these packages needs to be imported. Please change accordingly. Minor comments Please change the DESCRIPTION and add the corresponding author/creators in the github repository. Please alter the examples from your initial github page so that they work as expected. E.g. the `FetchData` function for Seurat objects is not pre-loaded, one need to first import Seurat `library(Seurat)`. Please remove the following example part from your github pages, sicne the functions have been removed and are not working anymore `reduction_names()`, `assay_names()` and `features_in_assay()`. Please update the corresponding `fetch_...` function main description and param field about what object types are supported, since the `AnnDataR6` class in most cases is supported but not mentioned. Please rephrase "Single-cell analysis can be inaccessible to bench scientists due to programming experience required, ...", in my opinion this sentence is formulated too harshly, as it is possible e.g. to convert and analyze single-cell objects with GUI-based solutions such as usegalaxy.eu and the SCEasy Converter plugin. Please provide a working example for a default user without admin priviliges how to setup and use `reticulate` in R for the usecase described here to access an `AnnData` object and how to install the prerequisite Python packages. The authors refer to the main `reticulate` documentation, however, showing a working code snippet example would be beneficial for scientists not fluent in both programming languages. Please remove "for all three object types" from Figure 5A "Common plotting script for all three object types", since the plotting function applies on the constructed intermediate `data.frame` object. Figure 6, please change the code example to use the R default pipe operator `|>` instead of the `magrittr` pipe operator `%>%` so that one would not need to pre-load the corresponding libraries. Is the rationale for developing the new software tool clearly explained? Yes Is the description of the software tool technically sound? Partly Are sufficient details of the code, methods and analysis (if applicable) provided to allow replication of the software development and its use by others? Yes Is sufficient information provided to allow interpretation of the expected output datasets and any results generated using the tool? Yes Are the conclusions about the tool and its performance adequately supported by the findings presented in the article? Partly References 1. Cakir B, Prete M, Huang N, van Dongen S, et al.: Comparison of visualization tools for single-cell RNAseq data. NAR Genom Bioinform . 2020; 2 (3): lqaa052 PubMed Abstract | Publisher Full Text 2. Feng H, Lin L, Chen J: scDIOR: single cell RNA-seq data IO software. BMC Bioinformatics . 2022; 23 (1): 16 PubMed Abstract | Publisher Full Text Competing Interests No competing interests were disclosed. Reviewer Expertise Comparative Genomics, Bioinformatics, R Programming I confirm that I have read this submission and believe that I have an appropriate level of expertise to confirm that it is of an acceptable scientific standard, however I have significant reservations, as outlined above. reply Respond to this report Responses (1) Author Response 16 Jun 2025 William Showers, Division of Hematology, University of Colorado Anschutz Medical Campus, Aurora, USA Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. In this article the authors provide a valuable R package that implements a unified data access API for single-cell object formats like `anndata` objects (Python) and `Seurat/SingleCellExperiment` objects (R). The SCUBA API (implemented in R) keeps the original single-cell objects unmodified and use three data accession methods, namely `FetchData`, `fetch_metdata` and `fetch_reduction`. To more easily compare pre-processed data stored in common single-cell data formats, like `AnnData`, `SingleCellExperiment` (SCE) and `Seurat`, the authors fetch metadata from cells and genes from the original object and create a `data.frame` R object with the requested features. Using the `data.frame` object, downstream plotting function are provided to create plots in the `ggplot2` R package grammar. Code review Given the dependency issues related to R-base version and Python version, I would encourage the authors to submit their package to either CRAN or Bioconductor R repository so that R package community standards are tested in a continious integration setup. The authors should try to alter their code to pass at least the R-CMD-check without warnings and errors. Thank you for this valuable feedback. While we do not intend to submit this package to CRAN or Bioconductor, we recognize the value of continuous integration and have ensured that the code now passes the R-CMD-check without warnings or errors. In the "Use cases" section, the authors claim that "Additional vignettes are provided on the SCUBA GitHub page", which is not true time of writing this review. Please add the mentioned vignettes to the GitHub page. We have added a vignette with examples of all major SCUBA functions (see the comment below). The provided R functions should contain runnable examples. Building a vignette would help the community to present the basic functions from the R package and provide more background information, if needed. I would suggest the authors to include a github workflow to create the R package documentation, vignettes and convert it into a website e.g. with the `pkgdown` package or similar workflow. We appreciate this feedback, and have improved our documentation to address these important observations. Specifically, we have added a pkgdown site at https://amc-heme.github.io/SCUBA/ . Here, we have added the “User Guide” vignette to the “Articles” tab, which contains a walkthrough of key functions in the SCUBA package for the access, exploration, and visualization of single-cell datasets. The vignette shows usage examples for all three object types currently supported by SCUBA. In addition to adding the vignette, we updated the function documentation to improve clarity and provide usage examples. Software I was able to install the software and run the examples given on the main github page, despite the need to pre-load the `Seurat` R package. As indicated in the Minor comments part, the three functions `reduction_names()`, `assay_names()` and `features_in_assay()` have been removed from the repository and the given example code block should be also removed from the github page. Thanks for letting us know about this. We have removed reduction_names() and assay_names() from the documentation to avoid this confusion. Features_in_assay() was added back to the package, and documentation on usage of this function is now on our pkgdown site, in the “User Guide” article. The Rmarkdown files on the github page https://github.com/amc-heme/SCUBA_Manuscript have been inspected and partially run. I have not re-created the subset data sets, however the code base seems to be fine. We have double-checked the code in amc-heme/SCUBA_Manuscript internally for consistent outputs. Please let us know if you notice further issues with the code in the manuscript repo. Major comments If many genes are requested by the `FetchData` function, creating a single `data.frame` has the offsite to not benefit from sparse data structures leading to high memory footprints. Please implement some checks to prevent a user given the local resources to request too many gene features. Thank you for this observation. We don’t feel that it is necessary to prevent users from doing this, but we have added a warning to users (shown below) in this scenario. The warning appears when 1000 or more genes are requested. "A very large number of features was requested (<> features). fetch_data is not intended to be used with feature queries of this length. Data is returned in a dense format, so the memory usage of the output may be very large. Also, this query may take a while to complete." Please remove "manually" from the sentence: "Currently, the most efective solution is to manually convert between object classes." Here, manually implies a programatically high efford to do so, which in my opinion is not true, given the existing converting tools like `SeuratWrapper`, `zellkonverter`, `SCEasy Converter` `scDIOR`. Please add the corresponding literature for the mentioned tools. Thank you for pointing this out. The sentence was changed as follows in the updated manuscript: "All major single-cell analysis packages implement conversion functions, and third-party packages such as sceasy, Zellconverter, and scDIOR are specifically designed for these conversions. Additionally, SeruatWrapper implements conversion functions that allow several otherwise-incompatible single-cell analysis packages to be used on Seurat objects." Citations for the corresponding literature have also been added to the revised manuscript. In your R DESCRIPTION file you set the `reticulate` and `anndata` R packages as suggests, however for your API to be fully functional these packages needs to be imported. Please change accordingly. We appreciate this observation. While we prefer not to require users to install anndata and reticulate if they are not using anndata objects, we have added a conditional statement in all exported AnnDataR6 methods to check if these packages are installed, and throw an error directing users to install these packages if they are not. Minor comments Please change the DESCRIPTION and add the corresponding author/creators in the github repository. This change was made. Please alter the examples from your initial github page so that they work as expected. E.g. the `FetchData` function for Seurat objects is not pre-loaded, one need to first import Seurat `library(Seurat)`. To keep users from having to import Seurat to use our FetchData methods, we moved them to a new generic defined within our package (fetch_data). Please remove the following example part from your github pages, since the functions have been removed and are not working anymore `reduction_names()`, `assay_names()` and `features_in_assay()`. All three functions have been removed from the README on our GitHub page. We added `features_in_assay()` back to SCUBA, and have added documentation for the function in our user guide vignette. Please update the corresponding `fetch_...` function main description and param field about what object types are supported, since the `AnnDataR6` class in most cases is supported but not mentioned. This has been corrected. All fetch_* functions and all functions that take an object as a parameter now mention all object types corrected. The description text for the `object` parameter is now also consistent across all functions. Please rephrase "Single-cell analysis can be inaccessible to bench scientists due to programming experience required, ...", in my opinion this sentence is formulated too harshly, as it is possible e.g. to convert and analyze single-cell objects with GUI-based solutions such as usegalaxy.eu and the SCEasy Converter plugin. We have modified this sentence to the following: “Single-cell analysis requires programming experience for full customization of analysis and visualization, and different object formats make it even more difficult for biologists to analyze data”. Please provide a working example for a default user without admin privileges how to setup and use `reticulate` in R for the usecase described here to access an `AnnData` object and how to install the prerequisite Python packages. The authors refer to the main `reticulate` documentation, however, showing a working code snippet example would be beneficial for scientists not fluent in both programming languages. Thanks for this suggestion. We have added this to the README, under the section “Additional Installation for anndata Objects”. Please remove "for all three object types" from Figure 5A "Common plotting script for all three object types", since the plotting function applies on the constructed intermediate `data.frame` object. This has been changed. The sentence now reads “Example script for visualizing expression of a gene by cluster in a density plot.” Figure 6, please change the code example to use the R default pipe operator `|>` instead of the `magrittr` pipe operator `%>%` so that one would not need to pre-load the corresponding libraries. This change has been made. Please see figure 6 in the revised submission. View more View less Competing Interests No competing interests were disclosed. reply Respond Report a concern Ullrich K. Peer Review Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.169727.r334007) NOTE: it is important to ensure the information in square brackets after the title is included in this citation. The direct URL for this report is: https://f1000research.com/articles/13-1256/v1#referee-response-334007 keyboard_arrow_left Back to all reports Reviewer Report 0 Views copyright © 2024 Li H. This is an open access peer review report distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. 17 Dec 2024 | for Version 1 Huamei Li , Nanjing University, Nanjing, Jiangsu, China 0 Views copyright © 2024 Li H. This is an open access peer review report distributed under the terms of the Creative Commons Attribution License , which permits unrestricted use, distribution, and reproduction in any medium, provided the original work is properly cited. format_quote Cite this report speaker_notes Responses (1) Approved info_outline Alongside their report, reviewers assign a status to the article: Approved The paper is scientifically sound in its current form and only minor, if any, improvements are suggested Approved with reservations A number of small changes, sometimes more significant revisions are required to address specific details and improve the papers academic merit. Not approved Fundamental flaws in the paper seriously undermine the findings and conclusions Showers et al. developed the SCUBA R package as a unified API for single-cell data analysis. In single-cell and spatial transcriptomics studies, data format conversion between Seurat, SingleCellExperiment, and AnnData often presents challenges, leading to obstacles in downstream analyses. While several tools have been developed to address data format conversion issues, SCUBA provides a unified and user-friendly interface for handling multiple formats and simplifies single-cell data processing workflows, making it a promising tool for practical applications. However, several concerns regarding SCUBA require further clarification: 1) The README file available at https://github.com/amc-heme/SCUBA/tree/main does not include examples demonstrating how SCUBA reads Seurat, SingleCellExperiment, and AnnData formats from local files. Additionally, it is unclear whether SCUBA addresses compatibility issues arising from different versions of these formats, such as Seurat 4.0+ versus Seurat 5.0+. Can SCUBA facilitate seamless data format conversion and overcome challenges posed by version discrepancies? 2) While SCUBA provides application examples for single-cell datasets, it remains unclear whether the tool can be effectively extended to spatial transcriptomics datasets generated by different platforms. Clarification on its applicability to spatial datasets would be beneficial. 3) To enhance visualization capabilities, it is recommended that SCUBA include optional smoothing methods for displaying the expression distribution of feature genes. This would allow for better identification of regions with concentrated expression of specific features. 4) The SCUBA documentation could be further improved by providing more detailed explanations of the functions, their usage, and intended purposes. Additionally, including a comprehensive analysis example that integrates both single-cell and spatial transcriptomics data would help illustrate the full workflow and practical utility of SCUBA. Is the rationale for developing the new software tool clearly explained? Yes Is the description of the software tool technically sound? Yes Are sufficient details of the code, methods and analysis (if applicable) provided to allow replication of the software development and its use by others? Partly Is sufficient information provided to allow interpretation of the expected output datasets and any results generated using the tool? Yes Are the conclusions about the tool and its performance adequately supported by the findings presented in the article? Yes Competing Interests No competing interests were disclosed. Reviewer Expertise Bioinformatics, Immunogenetics, Single-cell and spatial technologies I confirm that I have read this submission and believe that I have an appropriate level of expertise to confirm that it is of an acceptable scientific standard. reply Respond to this report Responses (1) Author Response 09 Aug 2025 William Showers, Division of Hematology, University of Colorado Anschutz Medical Campus, Aurora, USA Thank you for the time and effort invested in your review. We have modified the manuscript and package, and we feel it is stronger thanks to your feedback. Please see below for point-by-point responses. Showers et al. developed the SCUBA R package as a unified API for single-cell data analysis. In single-cell and spatial transcriptomics studies, data format conversion between Seurat, SingleCellExperiment, and AnnData often presents challenges, leading to obstacles in downstream analyses. While several tools have been developed to address data format conversion issues, SCUBA provides a unified and user-friendly interface for handling multiple formats and simplifies single-cell data processing workflows, making it a promising tool for practical applications. However, several concerns regarding SCUBA require further clarification: 1) The README file available at https://github.com/amc-heme/SCUBA/tree/main does not include examples demonstrating how SCUBA reads Seurat, SingleCellExperiment, and AnnData formats from local files. Additionally, it is unclear whether SCUBA addresses compatibility issues arising from different versions of these formats, such as Seurat 4.0+ versus Seurat 5.0+. Can SCUBA facilitate seamless data format conversion and overcome challenges posed by version discrepancies? Thank you for this observation. We have added new documentation via a pkgdown website ( https://amc-heme.github.io/SCUBA/ ). The Article “User Guide” contains a note on how each object class is loaded. SCUBA is seamlessly compatible with Seurat v4 and v5 objects. We have added a note on this to the README. 2) While SCUBA provides application examples for single-cell datasets, it remains unclear whether the tool can be effectively extended to spatial transcriptomics datasets generated by different platforms. Clarification on its applicability to spatial datasets would be beneficial. SCUBA partially supports spatial datasets. Aspects of spatial datasets that can be expressed as a counts matrix can be loaded into SCUBA, but we do not yet support the loading of image files. We have added a note on this to the README. 3) To enhance visualization capabilities, it is recommended that SCUBA include optional smoothing methods for displaying the expression distribution of feature genes. This would allow for better identification of regions with concentrated expression of specific features. Thank you for the suggestion. While we agree that this is a valuable approach, we feel this is out of scope for the current tool, and welcome users to apply their own smoothing methods in plotting scripts based on SCUBA. 4) The SCUBA documentation could be further improved by providing more detailed explanations of the functions, their usage, and intended purposes. Additionally, including a comprehensive analysis example that integrates both single-cell and spatial transcriptomics data would help illustrate the full workflow and practical utility of SCUBA. Thank you for the suggestion. We have added the suggested documentation to the README and the user guide vignette on the pkgdown website. We have also updated function documentation in SCUBA v.1.1.0. View more View less Competing Interests We disclose no competing interests. reply Respond Report a concern Li H. Peer Review Report For: SCUBA implements a storage format-agnostic API for single-cell data access in R [version 2; peer review: 3 approved, 1 approved with reservations] . F1000Research 2025, 13 :1256 ( https://doi.org/10.5256/f1000research.169727.r346283) NOTE: it is important to ensure the information in square brackets after the title is included in this citation. The direct URL for this report is: https://f1000research.com/articles/13-1256/v1#referee-response-346283 Alongside their report, reviewers assign a status to the article: Approved - the paper is scientifically sound in its current form and only minor, if any, improvements are suggested Approved with reservations - A number of small changes, sometimes more significant revisions are required to address specific details and improve the papers academic merit. Not approved - fundamental flaws in the paper seriously undermine the findings and conclusions Adjust parameters to alter display View on desktop for interactive features Includes Interactive Elements View on desktop for interactive features Competing Interests Policy Provide sufficient details of any financial or non-financial competing interests to enable users to assess whether your comments might lead a reasonable person to question your impartiality. Consider the following examples, but note that this is not an exhaustive list: Examples of 'Non-Financial Competing Interests' Within the past 4 years, you have held joint grants, published or collaborated with any of the authors of the selected paper. You have a close personal relationship (e.g. parent, spouse, sibling, or domestic partner) with any of the authors. You are a close professional associate of any of the authors (e.g. scientific mentor, recent student). You work at the same institute as any of the authors. You hope/expect to benefit (e.g. favour or employment) as a result of your submission. You are an Editor for the journal in which the article is published. Examples of 'Financial Competing Interests' You expect to receive, or in the past 4 years have received, any of the following from any commercial organisation that may gain financially from your submission: a salary, fees, funding, reimbursements. You expect to receive, or in the past 4 years have received, shared grant support or other funding with any of the authors. You hold, or are currently applying for, any patents or significant stocks/shares relating to the subject matter of the paper you are commenting on. Stay Updated Sign up for content alerts and receive a weekly or monthly email with all newly published articles Register with F1000Research Already registered? Sign in Not now, thanks close PLEASE NOTE If you are an AUTHOR of this article, please check that you signed in with the account associated with this article otherwise we cannot automatically identify your role as an author and your comment will be labelled as a “User Comment”. If you are a REVIEWER of this article, please check that you have signed in with the account associated with this article and then go to your account to submit your report, please do not post your review here. If you do not have access to your original account, please contact us . All commenters must hold a formal affiliation as per our Policies . The information that you give us will be displayed next to your comment. User comments must be in English, comprehensible and relevant to the article under discussion. We reserve the right to remove any comments that we consider to be inappropriate, offensive or otherwise in breach of the User Comment Terms and Conditions . Commenters must not use a comment for personal attacks. When criticisms of the article are based on unpublished data, the data should be made available. I accept the User Comment Terms and Conditions Please confirm that you accept the User Comment Terms and Conditions. Affiliation ✕ refresh Please enter your institution. Note: To add your institution or organisation, start typing the name and then select the correct name from the list. Where applicable, the name will appear in both the original language and in English. Do not paste in the name. If the name does not appear in the drop-down list, we will display the information you have entered. ✕ refresh Country/Region * USA UK Canada China France Germany Afghanistan Aland Islands Albania Algeria American Samoa Andorra Angola Anguilla Antarctica Antigua and Barbuda Argentina Armenia Aruba Australia Austria Azerbaijan Bahamas Bahrain Bangladesh Barbados Belarus Belgium Belize Benin Bermuda Bhutan Bolivia Bosnia and Herzegovina Botswana Bouvet Island Brazil British Indian Ocean Territory British Virgin Islands Brunei Bulgaria Burkina Faso Burundi Cambodia Cameroon Canada Cape Verde Cayman Islands Central African Republic Chad Chile China Christmas Island Cocos (Keeling) Islands Colombia Comoros Congo Cook Islands Costa Rica Cote d'Ivoire Croatia Cuba Cyprus Czech Republic Democratic Republic of the Congo Denmark Djibouti Dominica Dominican Republic Ecuador Egypt El Salvador Equatorial Guinea Eritrea Estonia Ethiopia Falkland Islands Faroe Islands Federated States of Micronesia Fiji Finland France French Guiana French Polynesia French Southern Territories Gabon Georgia Germany Ghana Gibraltar Greece Greenland Grenada Guadeloupe Guam Guatemala Guernsey Guinea Guinea-Bissau Guyana Haiti Heard Island and Mcdonald Islands Holy See (Vatican City State) Honduras Hong Kong Hungary Iceland India Indonesia Iran Iraq Ireland Israel Italy Jamaica Japan Jersey Jordan Kazakhstan Kenya Kiribati Kosovo (Serbia and Montenegro) Kuwait Kyrgyzstan Lao People's Democratic Republic Latvia Lebanon Lesotho Liberia Libya Liechtenstein Lithuania Luxembourg Macao Madagascar Malawi Malaysia Maldives Mali Malta Marshall Islands Martinique Mauritania Mauritius Mayotte Mexico Minor Outlying Islands of the United States Moldova Monaco Mongolia Montenegro Montserrat Morocco Mozambique Myanmar Namibia Nauru Nepal Netherlands Antilles New Caledonia New Zealand Nicaragua Niger Nigeria Niue Norfolk Island North Korea North Macedonia Northern Mariana Islands Norway Oman Pakistan Palau Palestinian Territory Panama Papua New Guinea Paraguay Peru Philippines Pitcairn Poland Portugal Puerto Rico Qatar Reunion Romania Russian Federation Rwanda Saint Helena Saint Kitts and Nevis Saint Lucia Saint Pierre and Miquelon Saint Vincent and the Grenadines Samoa San Marino Sao Tome and Principe Saudi Arabia Senegal Serbia Seychelles Sierra Leone Singapore Slovakia Slovenia Solomon Islands Somalia South Africa South Georgia and the South Sandwich Is South Korea South Sudan Spain Sri Lanka Sudan Suriname Svalbard and Jan Mayen Swaziland Sweden Switzerland Syria Taiwan Tajikistan Tanzania Thailand The Gambia The Netherlands Timor-Leste Togo Tokelau Tonga Trinidad and Tobago Tunisia Turkey Turkmenistan Turks and Caicos Islands Tuvalu UK USA Uganda Ukraine United Arab Emirates United States Virgin Islands Uruguay Uzbekistan Vanuatu Venezuela Vietnam Wallis and Futuna West Bank and Gaza Strip Western Sahara Yemen Zambia Zimbabwe Please select your country/region. You must enter a comment. Competing Interests Please disclose any competing interests that might be construed to influence your judgment of the article's or peer review report's validity or importance. Competing Interests Policy Provide sufficient details of any financial or non-financial competing interests to enable users to assess whether your comments might lead a reasonable person to question your impartiality. Consider the following examples, but note that this is not an exhaustive list: Examples of 'Non-Financial Competing Interests' Within the past 4 years, you have held joint grants, published or collaborated with any of the authors of the selected paper. You have a close personal relationship (e.g. parent, spouse, sibling, or domestic partner) with any of the authors. You are a close professional associate of any of the authors (e.g. scientific mentor, recent student). You work at the same institute as any of the authors. You hope/expect to benefit (e.g. favour or employment) as a result of your submission. You are an Editor for the journal in which the article is published. Examples of 'Financial Competing Interests' You expect to receive, or in the past 4 years have received, any of the following from any commercial organisation that may gain financially from your submission: a salary, fees, funding, reimbursements. You expect to receive, or in the past 4 years have received, shared grant support or other funding with any of the authors. You hold, or are currently applying for, any patents or significant stocks/shares relating to the subject matter of the paper you are commenting on. Please state your competing interests The comment has been saved. An error has occurred. Please try again. Cancel Post var lTitle = "SCUBA implements a storage format-agnostic...".replace("'", ''); var linkedInUrl = "http://www.linkedin.com/shareArticle?url=https://f1000research.com/articles/13-1256/v2" + "&title=" + encodeURIComponent(lTitle) + "&summary=" + encodeURIComponent('Read the article by '); var deliciousUrl = "https://del.icio.us/post?url=https://f1000research.com/articles/13-1256/v2&title=" + encodeURIComponent(lTitle); var redditUrl = "http://reddit.com/submit?url=https://f1000research.com/articles/13-1256/v2" + "&title=" + encodeURIComponent(lTitle); linkedInUrl += encodeURIComponent('Showers WM et al.'); var offsetTop = /chrome/i.test( navigator.userAgent ) ? 4 : -10; var addthis_config = { ui_offset_top: offsetTop, services_compact : "facebook,twitter,www.linkedin.com,www.mendeley.com,reddit.com", services_expanded : "facebook,twitter,www.linkedin.com,www.mendeley.com,reddit.com", services_custom : [ { name: "LinkedIn", url: linkedInUrl, icon:"/img/icon/at_linkedin.svg" }, { name: "Mendeley", url: "http://www.mendeley.com/import/?url=https://f1000research.com/articles/13-1256/v2/mendeley", icon:"/img/icon/at_mendeley.svg" }, { name: "Reddit", url: redditUrl, icon:"/img/icon/at_reddit.svg" }, ] }; var addthis_share = { url: "https://f1000research.com/articles/13-1256", templates : { twitter : "SCUBA implements a storage format-agnostic API for single-cell.... Showers WM et al., published by " + "@F1000Research" + ", https://f1000research.com/articles/13-1256/v2" } }; if (typeof(addthis) != "undefined"){ addthis.addEventListener('addthis.ready', checkCount); addthis.addEventListener('addthis.menu.share', checkCount); } $(".f1r-shares-twitter").attr("href", "https://twitter.com/intent/tweet?text=" + addthis_share.templates.twitter); $(".f1r-shares-facebook").attr("href", "https://www.facebook.com/sharer/sharer.php?u=" + addthis_share.url); $(".f1r-shares-linkedin").attr("href", addthis_config.services_custom[0].url); $(".f1r-shares-reddit").attr("href", addthis_config.services_custom[2].url); $(".f1r-shares-mendelay").attr("href", addthis_config.services_custom[1].url); function checkCount(){ setTimeout(function(){ $(".addthis_button_expanded").each(function(){ var count = $(this).text(); if (count !== "" && count != "0") $(this).removeClass("is-hidden"); else $(this).addClass("is-hidden"); }); }, 1000); } close How to cite this report {{reportCitation}} Cancel Copy Citation Details $(function(){R.ui.buttonDropdowns('.dropdown-for-downloads');}); $(function(){R.ui.toolbarDropdowns('.toolbar-dropdown-for-downloads');}); $.get("/articles/acj/154675/182803") new F1000.Clipboard(); new F1000.ThesaurusTermsDisplay("articles", "article", "182803"); $(document).ready(function() { $( "#frame1" ).on('load', function() { var mydiv = $(this).contents().find("div"); var h = mydiv.height(); console.log(h) }); var tooltipLivingFigure = jQuery(".interactive-living-figure-label .icon-more-info"), titleLivingFigure = tooltipLivingFigure.attr("title"); tooltipLivingFigure.simpletip({ fixed: true, position: ["-115", "30"], baseClass: 'small-tooltip', content:titleLivingFigure + " " }); tooltipLivingFigure.removeAttr("title"); $("body").on("click", ".cite-living-figure", function(e) { e.preventDefault(); var ref = $(this).attr("data-ref"); $(this).closest(".living-figure-list-container").find("#" + ref).fadeIn(200); }); $("body").on("click", ".close-cite-living-figure", function(e) { e.preventDefault(); $(this).closest(".popup-window-wrapper").fadeOut(200); }); $(document).on("mouseup", function(e) { var metricsContainer = $(".article-metrics-popover-wrapper"); if (!metricsContainer.is(e.target) && metricsContainer.has(e.target).length === 0) { $(".article-metrics-close-button").click(); } }); var articleId = $('#articleId').val(); if($("#main-article-count-box").attachArticleMetrics) { $("#main-article-count-box").attachArticleMetrics(articleId, { articleMetricsView: true }); } }); var figshareWidget = $(".new_figshare_widget"); if (figshareWidget.length > 0) { window.figshare.load("f1000", function(Widget) { // Select a tag/tags defined in your page. In this tag we will place the widget. _.map(figshareWidget, function(el){ var widget = new Widget({ articleId: $(el).attr("figshare_articleId") //height:300 // this is the height of the viewer part. [Default: 550] }); widget.initialize(); // initialize the widget widget.mount(el); // mount it in a tag that's on your page // this will save the widget on the global scope for later use from // your JS scripts. This line is optional. //window.widget = widget; }); }); } close Error Close Add Reset F1000.MICROSERVICES.AFFILIATION = ''; $(document).ready(function () { $('.js-affiliations-form').each((index, form) => { new AffiliationForm({ formId: form.id, institutionErrorSelector: '.comment-enter-institution', departmentErrorSelector: '.comment-enter-department', placeSelector: '.js-add-comment-place', stateSelector: '.js-add-comment-state', zipCodeSelector: '.js-add-comment-zipcode', countrySelector: '.js-add-comment-country', countryErrorSelector: '.comment-enter-country', }); }); }); $(document).ready(function () { var reportIds = { "395398": 0, "395399": 0, "395396": 0, "395397": 0, "395394": 0, "395395": 0, "395393": 0, "395402": 0, "395400": 0, "395401": 0, "396950": 14, "396951": 0, "396948": 0, "350231": 0, "396949": 0, "350230": 0, "396946": 0, "396947": 0, "396945": 0, "350237": 0, "350236": 0, "350239": 0, "350238": 0, "396954": 0, "350233": 54, "350232": 0, "396952": 0, "350235": 0, "396953": 0, "350234": 0, "389797": 0, "389796": 0, "389799": 0, "389798": 0, "346285": 0, "346284": 0, "346287": 0, "346286": 0, "389801": 0, "346281": 0, "389800": 0, "346280": 0, "346283": 26, "389802": 0, "346282": 0, "334005": 0, "334004": 0, "334007": 28, "334006": 0, "334001": 0, "346289": 0, "334000": 0, "346288": 0, "334003": 0, "334002": 0, "389309": 0, "389308": 0, "334009": 0, "334008": 0, "389307": 17, "337221": 0, "337220": 0, "337223": 0, "337222": 0, "337229": 0, "337228": 0, "337225": 0, "337224": 0, "337227": 0, "337226": 0, "393582": 0, "393583": 0, "393580": 0, "393581": 0, "393579": 0, "391285": 0, "391287": 0, "393588": 0, "391286": 0, "393586": 0, "393587": 0, "393584": 0, "393585": 0, "391293": 0, "391292": 0, "391294": 0, "391289": 0, "391288": 0, "391291": 0, "391290": 0, }; $(".referee-response-container,.js-referee-report").each(function(index, el) { var reportId = $(el).attr("data-reportid"), reportCount = reportIds[reportId] || 0; $(el).find(".comments-count-container,.js-referee-report-views").html(reportCount); }); var uuidInput = $("#article_uuid"), oldUUId = uuidInput.val(), newUUId = "479c3fc7-b896-4f11-9a76-c8bf041a1fc8"; uuidInput.val(newUUId); $("a[href*='article_uuid=']").each(function(index, el) { var newHref = $(el).attr("href").replace(oldUUId, newUUId); $(el).attr("href", newHref); }); }); An innovative open access publishing platform offering rapid publication and open peer review, whilst supporting data deposition and sharing. Browse Gateways Collections How it Works Contact For Developers Cookie Notice Privacy Notice RSS Submit Your Research Follow us © 2012-2026 F1000 Research Ltd. ISSN 2046-1402 | Legal | Partner of Research4Life • CrossRef • ORCID • FAIRSharing R.templateTests.simpleTemplate = R.template(' $text $text $text $text $text '); R.templateTests.runTests(); var F1000platform = new F1000.Platform({ name: "f1000research", displayName: "F1000Research", hostName: "f1000research.com", id: "1", editorialEmail: "[email protected]", infoEmail: "[email protected]", usePmcStats: true }); $(function(){R.ui.dropdowns('.dropdown-for-authors, .dropdown-for-about, .dropdown-for-myresearch');}); // $(function(){R.ui.dropdowns('.dropdown-for-referees');}); $(document).ready(function () { if ($(".cookie-warning").is(":visible")) { $(".sticky").css("margin-bottom", "35px"); $(".devices").addClass("devices-and-cookie-warning"); } $(".cookie-warning .close-button").click(function (e) { $(".devices").removeClass("devices-and-cookie-warning"); $(".sticky").css("margin-bottom", "0"); }); $("#tweeter-feed .tweet-message").each(function (i, message) { var self = $(message); self.html(linkify(self.html())); }); $(".partner").on("mouseenter mouseleave", function() { $(this).find(".gray-scale, .colour").toggleClass("is-hidden"); }); }); Sign In Remember me Forgotten your password? Sign In Cancel Email or password not correct. Please try again Please wait... $(function(){ // Note: All the setup needs to run against a name attribute and *not* the id due the clonish // nature of facebox... $("a[id=googleSignInButton]").click(function(event){ event.preventDefault(); $("input[id=oAuthSystem]").val("GOOGLE"); $("form[id=oAuthForm]").submit(); }); $("a[id=facebookSignInButton]").click(function(event){ event.preventDefault(); $("input[id=oAuthSystem]").val("FACEBOOK"); $("form[id=oAuthForm]").submit(); }); $("a[id=orcidSignInButton]").click(function(event){ event.preventDefault(); $("input[id=oAuthSystem]").val("ORCID"); $("form[id=oAuthForm]").submit(); }); }); If you've forgotten your password, please enter your email address below and we'll send you instructions on how to reset your password. The email address should be the one you originally registered with F1000. Email address not valid, please try again You registered with F1000 via Google, so we cannot reset your password. To sign in, please click here . If you still need help with your Google account password, please click here . You registered with F1000 via Facebook, so we cannot reset your password. To sign in, please click here . If you still need help with your Facebook account password, please click here . Code not correct, please try again Reset password Cancel Email us for further assistance. Server error, please try again. If your email address is registered with us, we will email you instructions to reset your password. If you think you should have received this email but it has not arrived, please check your spam filters and/or contact for further assistance. Please wait... Register $(document).ready(function () { signIn.createSignInAsRow($("#sign-in-form-gfb-popup")); $(".target-field").each(function () { var uris = $(this).val().split("/"); if (uris.pop() === "login") { $(this).val(uris.toString().replace(",","/")); } }); });

Text is read by the "Ask this paper" AI Q&A widget below. Extraction quality varies by source — PMC NXML preserves structure cleanly, OA-HTML may include some navigation residue, and OA-PDF can have broken hyphenation. The publisher copy (via DOI) is the canonical version.

My notes (saved in your browser only)

Ask this paper AI returns verbatim quotes from the full text · source: preprint-html

Answers must be backed by verbatim quotes from this paper's full text. Hallucinated quotes are dropped automatically; if no verbatim passage answers the question, we say so. How this works

Citation neighborhood (no data yet)

We don't have any in-corpus citations linked to this paper yet. This is a recent paper (2025) — citers typically take a year or two to land, and the OpenAlex reference graph may still be filling in.

Source provenance

europepmc
last seen: 2026-05-20T01:45:00.602351+00:00