Psilocin fosters neuroplasticity in iPSC-derived human cortical neurons.
The 5 matches
- [1] § Materials and methods › Statistical analysis visualization ↔ explorer/src/components/atlas.js, lines 162 to 216 · score 0.56 · post hoc, independent biological replicates, rank, genetically, cell · Report a mismatch
- [2] § Materials and methods › Statistical analysis visualization ↔ site/_import/components/atlas.5a109658.js, lines 162 to 217 · score 0.56 · post hoc, independent biological replicates, rank, genetically, cell · Report a mismatch
- [3] § Materials and methods › RNA bulk sequencing and analysis ↔ site/_import/components/atlas.5a109658.js, lines 162 to 217 · score 0.56 · DESeq2, Stranded, imported, RNA, quality, db · Report a mismatch
- [4] § Results › Psilocin induces gene expression changes associated with axonal and synaptic plasticity ↔ src/transcriptomics/report_dna_maintenance.py, lines 93 to 129 · score 0.52 · overlapping assignment, stronger, enriched, transcriptome, enrichment, pathway · Report a mismatch
- [5] § Materials and methods › RNA bulk sequencing and analysis ↔ src/transcriptomics/report_results.py, lines 28 to 122 · score 0.51 · DESeq2, RIN, hs, library, padj, imported · Report a mismatch
Paper
Loaded from Europe PMC by your browser; OSCR does not store it: doi.org · Europe PMC
The paper is loaded when this pane is shown.
The authors' code
JavaScript · 217 lines · 47 KB · CC-BY-4.0 · 2 matches
- import {contrasts,names,label,fmt,sci,color,edgeGenes,csvText} from "./format.0a1392e2.js";
- const NS='http://www.w3.org/2000/svg';
- function el(tag,cls,text){const n=document.createElement(tag);if(cls)n.className=cls;if(text!==undefined)n.textContent=text;return n;}
- function svgNode(tag,attrs={},text){const n=document.createElementNS(NS,tag);for(const[k,v]of Object.entries(attrs))n.setAttribute(k,v);if(text!==undefined)n.textContent=text;return n;}
- function svg(w,h,title){const n=svgNode('svg',{viewBox:`0 0 ${w} ${h}`,role:'img','aria-label':title,style:'font-family:ui-sans-serif,system-ui,-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif;font-size:12px;fill:#43534b'});n.append(svgNode('title',{},title));return n;}
- function text(s,x,y,t,attrs={}){s.append(svgNode('text',{x,y,...attrs},t));}
- function line(s,x1,y1,x2,y2,attrs={}){s.append(svgNode('line',{x1,y1,x2,y2,stroke:'#d7dedf',...attrs}));}
- function button(t,fn,cls=''){const b=el('button',cls,t);b.type='button';b.onclick=fn;return b;}
- function icon(kind){const s=svgNode('svg',{viewBox:'0 0 24 24','aria-hidden':'true',focusable:'false'});if(kind==='share'){s.append(svgNode('circle',{cx:18,cy:5,r:2.5}),svgNode('circle',{cx:6,cy:12,r:2.5}),svgNode('circle',{cx:18,cy:19,r:2.5}),svgNode('path',{d:'M8.2 10.8 15.8 6.2M8.2 13.2l7.6 4.6',fill:'none',stroke:'currentColor','stroke-width':1.8,'stroke-linecap':'round'}));}else if(kind==='fullscreen'){s.append(svgNode('path',{d:'M8 3H3v5M16 3h5v5M21 16v5h-5M3 16v5h5',fill:'none',stroke:'currentColor','stroke-width':1.8,'stroke-linecap':'round','stroke-linejoin':'round'}));}else if(kind==='print'){s.append(svgNode('path',{d:'M7 8V3h10v5M7 17H4V9h16v8h-3M7 14h10v7H7z',fill:'none',stroke:'currentColor','stroke-width':1.8,'stroke-linejoin':'round'}),svgNode('circle',{cx:17,cy:11.5,r:1,fill:'currentColor'}));}else if(kind==='github'){s.append(svgNode('path',{d:'M12 2.7a9.3 9.3 0 0 0-2.94 18.12c.47.09.64-.2.64-.45v-1.75c-2.61.57-3.16-1.11-3.16-1.11-.43-1.08-1.04-1.36-1.04-1.36-.85-.58.06-.57.06-.57.94.07 1.43.96 1.43.96.84 1.43 2.2 1.02 2.74.78.08-.6.33-1.02.6-1.26-2.08-.24-4.27-1.04-4.27-4.64 0-1.03.37-1.87.97-2.53-.1-.24-.42-1.2.09-2.5 0 0 .79-.25 2.56.97A8.9 8.9 0 0 1 12 6.36c.79 0 1.58.11 2.32.31 1.77-1.22 2.55-.97 2.55-.97.51 1.3.19 2.26.1 2.5.6.66.96 1.5.96 2.53 0 3.61-2.2 4.4-4.29 4.63.34.29.64.84.64 1.7v2.53c0 .25.17.54.65.45A9.3 9.3 0 0 0 12 2.7Z',fill:'currentColor'}));}else{s.append(svgNode('circle',{cx:12,cy:12,r:10,fill:'#a6ce39'}),svgNode('text',{x:12,y:16,'text-anchor':'middle',fill:'#fff','font-size':11,'font-weight':700},'iD'));}return s;}
- function iconButton(textValue,kind,fn,cls){const b=button('',fn,cls);b.append(icon(kind),document.createTextNode(textValue));return b;}
- function download(filename,content,type='text/csv'){const url=URL.createObjectURL(new Blob([content],{type}));const a=el('a');a.href=url;a.download=filename;a.click();setTimeout(()=>URL.revokeObjectURL(url),1000);}
- function downloadButton(rows,name){return button('↓ Download data',()=>download(name,csvText(rows)),'secondary');}
- function note(t){return el('p','note',t);}
- function heading(t,sub){const n=el('header','section-heading');n.append(el('h2','',t),el('p','',sub));return n;}
- function select(title,values,current,fn){const wrap=el('label','control');wrap.append(el('span','',title));const s=el('select');s.setAttribute('aria-label',title);for(const[v,t]of values){const o=el('option','',t);o.value=v;s.append(o);}s.value=current;s.onchange=()=>fn(s.value);wrap.append(s);return wrap;}
- function table(rows,cols){const w=el('div','table-scroll'),t=el('table'),head=el('thead'),tr=el('tr');for(const [,name]of cols)tr.append(el('th','',name));head.append(tr);t.append(head);const body=el('tbody');for(const r of rows){const row=el('tr');for(const[k,,format]of cols){const cell=el('td',typeof r[k]==='number'?'numeric':k==='gene'?'gene-symbol-cell':'',format?format(r[k],r):r[k]??'Not estimable');row.append(cell);}body.append(row);}t.append(body);w.append(t);return w;}
- function status(s){return el('span',`status ${s==='robust'?'stable':s==='unsupported'?'unsupported':'mixed'}`,s||'Not classified');}
- function scaleKey(limit,title){const box=el('div','scale-key');box.append(el('span','',title),el('i','gradient'),el('span','',`−${limit} · 0 · +${limit}`));return box;}
- function printFigure(shell,title){const copy=shell.cloneNode(true);copy.querySelector('.figure-toolbar')?.remove();const frame=el('iframe','figure-print-frame');frame.title=`Printable ${title}`;frame.setAttribute('aria-hidden','true');frame.onload=()=>{const win=frame.contentWindow;if(!win)return;win.focus();win.print();setTimeout(()=>frame.remove(),1000);};document.body.append(frame);const doc=frame.contentDocument;doc.open();doc.write(`<!doctype html><title>${title}</title><style>body{margin:24px;color:#17312f;font:13px system-ui,sans-serif}.figure-shell{width:100%;margin:0}.figure-context{display:block;margin:0 0 16px}.figure-context strong,.figure-context span{display:block}.figure-context strong{font-size:18px}.figure-context span{margin-top:4px;color:#40564e}.heatmap-scroll,.dna-map-scroll,.matrix-scroll{max-height:none!important;overflow:visible!important;background:#fff!important}.landscape-layout{display:grid;grid-template-columns:minmax(0,1.7fr) minmax(260px,1fr);gap:20px}.atlas svg{display:block;width:100%;height:auto}button{display:none}@page{margin:12mm}</style>${copy.outerHTML}`);doc.close();}
- function enhancePlots(scope){
- const requestName=['requestFullscreen','webkitRequestFullscreen'].find(name=>typeof document.documentElement[name]==='function');
- const exitName=['exitFullscreen','webkitExitFullscreen'].find(name=>typeof document[name]==='function');
- if(!requestName||!exitName)return;
- const candidates=[...scope.querySelectorAll('[data-fullscreen-title],svg[aria-label]')];
- for(const plot of candidates){
- const host=plot.closest('[data-fullscreen-host]')|| (plot.matches('svg')&&plot.parentElement?.matches('.heatmap-scroll,.dna-map-scroll')?plot.parentElement:plot);
- if(host.closest('.figure-shell'))continue;
- const title=host.dataset.fullscreenTitle||plot.getAttribute('aria-label')||'Scientific visualization';
- const info=host.dataset.fullscreenInfo||title;
- const shell=el('figure','figure-shell');shell.setAttribute('aria-label',`${title} with fullscreen control`);
- const toolbar=el('div','figure-toolbar');
- const context=el('figcaption','figure-context');context.append(el('strong','',title),el('span','',info));
- const full=button('',async()=>{try{if((document.fullscreenElement||document.webkitFullscreenElement)===shell)await document[exitName]();else await shell[requestName]();}catch(error){if(error?.name!=='NotAllowedError')console.warn('Fullscreen request failed',error);}},'figure-fullscreen');full.append(icon('fullscreen'));
- const print=button('',()=>printFigure(shell,title),'figure-print');print.append(icon('print'));
- full.setAttribute('aria-label',`View ${title} in full screen`);full.title='View plot and information in full screen';
- const update=()=>{const active=(document.fullscreenElement||document.webkitFullscreenElement)===shell;full.setAttribute('aria-label',active?'Exit full screen':`View ${title} in full screen`);full.title=active?'Exit full screen':'View plot and information in full screen';};
- shell.addEventListener('fullscreenchange',update);shell.addEventListener('webkitfullscreenchange',update);
- print.setAttribute('aria-label',`Print ${title}`);print.title='Print this plot and its visible information';toolbar.append(full,print);host.before(shell);shell.append(toolbar,context,host);
- }
- }
- export function createAtlas(data,provenance,loadGenes){
- const root=el('div','atlas');let genesPromise;const getGenes=()=>genesPromise??=(loadGenes());
- const landscapeMap=new Map(data.landscape.map(g=>[g.gene,g]));
- const profileMap=new Map(data.landscape.map(g=>[g.gene,data.profiles.filter(p=>p.gene===g.gene)]));
- const tabs=[['overview','Overview'],['landscape','OXPHOS landscape'],['genes','Gene explorer'],['pathways','Pathways'],['robustness','Robustness'],['dna','DNA maintenance'],['methods','Methods & sources']];
- let tab='overview',selected='GPX4',pathway='HALLMARK_OXIDATIVE_PHOSPHORYLATION',contrast='day1_vs_control',group='All functions',pathwayTier='all',dnaGene='ACD',dnaContrast='day1_vs_control',dnaFilter='All genes';
- const params=new URLSearchParams(location.hash.slice(1));if(tabs.some(x=>x[0]===params.get('view')))tab=params.get('view');selected=params.get('gene')||selected;pathway=params.get('pathway')||pathway;if(contrasts[params.get('contrast')])contrast=params.get('contrast');if(['all','primary','secondary','exploratory'].includes(params.get('tier')))pathwayTier=params.get('tier');group=params.get('group')||group;if(tab==='dna'){dnaGene=params.get('gene')||dnaGene;if(contrasts[params.get('contrast')])dnaContrast=params.get('contrast');dnaFilter=params.get('annotation')||dnaFilter;}
- function syncLocation(){const q=new URLSearchParams({view:tab});if(tab==='genes'||tab==='landscape')q.set('gene',selected);if(tab==='landscape'&&group!=='All functions')q.set('group',group);if(tab==='pathways'||tab==='robustness'){q.set('pathway',pathway);q.set('contrast',contrast);}if(tab==='pathways'&&pathwayTier!=='all')q.set('tier',pathwayTier);if(tab==='dna'){q.set('gene',dnaGene);q.set('contrast',dnaContrast);if(dnaFilter!=='All genes')q.set('annotation',dnaFilter);}history.replaceState(null,'',`#${q}`);return location.href;}
- function shareDetails(){const section=tabs.find(([id])=>id===tab)?.[1]||'Atlas',displayGene=body.querySelector('.gene-symbol')?.textContent||selected;let focus='';if(tab==='genes'||tab==='landscape')focus=`Gene: ${displayGene}`;else if(tab==='pathways'||tab==='robustness')focus=`${label(pathway)} · ${contrasts[contrast]}`;else if(tab==='dna')focus=`Gene: ${displayGene} · ${contrasts[dnaContrast]}${dnaFilter!=='All genes'?` · ${dnaFilter}`:''}`;const title=`Psilocin transcriptomic atlas · ${section}${focus?` · ${focus}`:''}`;return{title,text:`${title}. Germann reanalysis of Schmidt et al. (2026).`,url:syncLocation()};}
- async function shareCurrent(){const payload=shareDetails();if(typeof navigator.share==='function'){try{await navigator.share(payload);return;}catch(error){if(error?.name==='AbortError')return;console.warn('Native share request failed; opening email instead',error);}}location.href=`mailto:?subject=${encodeURIComponent(payload.title)}&body=${encodeURIComponent(`${payload.text}\n\n${payload.url}`)}`;}
- const top=el('header','masthead');
- const home=el('a','wordmark','PSILOCIN / TRANSCRIPTOMIC ATLAS');home.href='https://psilocybin-research.github.io/psilocin-human-neuron-transcriptomics/';
- const meta=el('div','masthead-meta');
- const identity=el('div','academic-identity');
- const author=el('div','author-line');
- const authorLink=el('a','','Germann, Christopher B.');authorLink.href='https://zenodo.org/search?q=metadata.creators.person_or_org.name:%22Germann,+Christopher+B.%22';authorLink.target='_blank';authorLink.rel='noopener';
- const orcid=el('a','orcid');orcid.href='https://orcid.org/0000-0002-1573-4651';orcid.target='_blank';orcid.rel='noopener';orcid.append(icon('orcid'),document.createTextNode('ORCID 0000-0002-1573-4651'));
- author.append(authorLink,orcid);
- const affiliation=el('div','affiliation','Faculty of Health, School of Medicine, University of Witten/Herdecke');identity.append(author,affiliation);
- const citations=el('div','header-citations');
- const sourceCitation=el('div','header-citation');sourceCitation.append(el('span','citation-label','Source study'));
- const sourceStudy=el('a','citation-text','Schmidt M, Hoffrichter A, Davoudi M, et al. (2026). Psilocin fosters neuroplasticity in iPSC-derived human cortical neurons. eLife 14:RP104006. doi:10.7554/eLife.104006.3');sourceStudy.href='https://doi.org/10.7554/eLife.104006.3';sourceStudy.target='_blank';sourceStudy.rel='noopener';sourceCitation.append(sourceStudy);
- const analysisCitation=el('div','header-citation');analysisCitation.append(el('span','citation-label','Secondary analysis'));
- const analysisStatus=el('span','citation-text','Germann CB. Metabolic and redox transcriptional signatures after brief psilocin exposure in human iPSC-derived cortical neurons: a secondary analysis. Submitted to bioRxiv; screening in progress.');analysisStatus.title='No public bioRxiv record is available yet; this status will be replaced by the live preprint citation after posting.';analysisCitation.append(analysisStatus);
- const archiveCitation=el('div','header-citation');archiveCitation.append(el('span','citation-label','Software · atlas'));
- const archive=el('a','citation-text','Germann CB (2026). A brief perturbation. A broad transcriptional signature: psilocin human-neuron transcriptomics (Version 1.0.1) [Computer software]. Zenodo. doi:10.5281/zenodo.22849800');archive.href='https://doi.org/10.5281/zenodo.22849800';archive.target='_blank';archive.rel='noopener';archiveCitation.append(archive);
- citations.append(sourceCitation,analysisCitation,archiveCitation);
- const headerActions=el('div','header-actions');
- const repository=el('a','header-repository');repository.href='https://github.com/psilocybin-research/psilocin-human-neuron-transcriptomics';repository.target='_blank';repository.rel='noopener';repository.title='Open the public GitHub repository';repository.append(icon('github'),el('span','repository-full','github.com/psilocybin-research/psilocin-human-neuron-transcriptomics'),el('span','repository-short','GitHub repository'));
- const sourceData=el('a','header-source','Original source data · Dryad ↗');sourceData.href='https://doi.org/10.5061/dryad.xsj3tx9w3';sourceData.target='_blank';sourceData.rel='noopener';
- headerActions.append(repository,el('span','release','v1.0.1'),sourceData);
- const share=iconButton('Share','share',shareCurrent,'native-share');share.setAttribute('aria-label','Share the current atlas analysis');share.title=typeof navigator.share==='function'?'Share the current view':'Share the current view by email';headerActions.append(share);
- meta.append(identity,citations,headerActions);top.append(home,meta);
- const nav=el('nav','tabs');nav.setAttribute('aria-label','Explorer sections');
- const body=el('div','atlas-body');
- const footer=el('footer','source-footer');footer.append(el('span','', 'Source study · Schmidt M, Hoffrichter A, Davoudi M, Horschitz S, Lau T, Meinhardt MW, Spanagel R, Ladewig J, Köhr G, Koch P. (2026). Psilocin fosters neuroplasticity in iPSC-derived human cortical neurons. eLife, 14, RP104006. '));const doi=el('a','','https://doi.org/10.7554/eLife.104006.3');doi.href='https://doi.org/10.7554/eLife.104006.3';doi.target='_blank';doi.rel='noopener';footer.append(doi);
- root.append(top,nav,body,footer);
- const toTop=button('↑',()=>window.scrollTo({top:0,behavior:'smooth'}),'scroll-top');toTop.setAttribute('aria-label','Scroll to top');toTop.title='Scroll to top';toTop.hidden=true;root.append(toTop);const updateScrollProgress=()=>{const range=document.documentElement.scrollHeight-innerHeight;const progress=range>0?Math.min(1,Math.max(0,scrollY/range)):0;toTop.style.setProperty('--scroll-progress',`${progress*360}deg`);toTop.hidden=progress<.06;};addEventListener('scroll',updateScrollProgress,{passive:true});addEventListener('resize',updateScrollProgress);updateScrollProgress();
- function go(next,gene){tab=next;if(gene)selected=gene;syncLocation();render();}
- for(const [id,t]of tabs)nav.append(button(t,()=>go(id)));
- function render(){syncLocation();[...nav.children].forEach((b,i)=>{b.classList.toggle('active',tabs[i][0]===tab);b.setAttribute('aria-current',tabs[i][0]===tab?'page':'false');});body.replaceChildren();({overview,landscape,genesView,pathways,robustness,dna:dnaView,methods}[tab==='genes'?'genesView':tab])();enhancePlots(body);}
- function overview(){
- const hero=el('section','hero');const intro=el('div');intro.append(el('div','eyebrow','HUMAN CORTICAL NEURONS · BULK RNA SEQUENCING'),el('h1','','A brief perturbation. A broad transcriptional signature.'),el('p','standfirst','A 10-minute psilocin exposure is associated with later OXPHOS-centered transcription in the Schmidt dataset, alongside bounded exploratory DNA-maintenance evidence. Inspect the genes, pathways and within-dataset checks behind these observations.'),button('Explore the 113-gene landscape →',()=>go('landscape'),'primary'));
- const metrics=el('div','metrics');for(const [v,t]of [['113','genes in the leading-edge union'],['89','leading-edge genes shared across days'],['3','differentiation blocks · 9 aggregated profiles']]){const m=el('div');m.append(el('strong','',v),el('span','',t));metrics.append(m);}hero.append(intro,metrics);body.append(hero);
- const timeline=el('div','timeline');for(const [a,b]of [['10 min','10 µM psilocin'],['Washout','Exposure ends'],['Day 1 & Day 3','Later RNA sampling']]){const n=el('div');n.append(el('strong','',a),el('span','',b));timeline.append(n);}body.append(timeline);
- const source=el('section','source-study');source.append(el('h2','','Source study'),el('p','','Independent secondary analysis of Schmidt M, Hoffrichter A, Davoudi M, Horschitz S, Lau T, Meinhardt MW, Spanagel R, Ladewig J, Köhr G, Koch P. (2026). Psilocin fosters neuroplasticity in iPSC-derived human cortical neurons. eLife, 14, RP104006.'));const article=el('a','source-link','Read the article ↗');article.href='https://doi.org/10.7554/eLife.104006.3';article.target='_blank';article.rel='noopener';source.append(article);body.append(source);
- body.append(heading('The complete primary result','Five prespecified Hallmark sets × three contrasts. The color shows NES; the label shows the frozen directional classification.'));
- const p=data.pathways.filter(p=>p.tier==='primary');const mat=el('div','pathway-matrix');mat.append(el('div'));for(const c of data.contrasts)mat.append(el('div','matrix-head',contrasts[c]));
- for(const id of Object.keys(names)){mat.append(el('div','matrix-row',label(id)));for(const c of data.contrasts){const p1=p.find(r=>r.pathway===id&&r.contrast===c);const cell=button('',()=>{pathway=id;contrast=c;pathwayTier='primary';go('pathways');},'matrix-cell');cell.style.background=color(p1.NES,3.6);cell.append(el('strong','',fmt(p1.NES)),el('small','',`15-test q = ${sci(p1.family_fdr)}`),status(p1.robustness));cell.setAttribute('aria-label',`${label(id)}, ${contrasts[c]}, NES ${fmt(p1.NES)}, ${p1.robustness}`);mat.append(cell);}}
- const scroll=el('div','matrix-scroll');scroll.dataset.fullscreenTitle='Complete primary pathway matrix';scroll.dataset.fullscreenInfo='Five prespecified Hallmark pathways across three contrasts. Color encodes NES; each cell reports the 15-test family q-value and frozen directional classification.';scroll.append(mat);body.append(el('p','mobile-hint','Swipe the matrix horizontally to inspect all three contrasts.'),scroll,scaleKey(3.6,'NES'),note('“Robust” means same direction across the frozen block and RNA-quality checks, with primary q < 0.05. These q-values quantify competitive enrichment in the ranked transcriptome; they are not biological-replication p-values across the three differentiation blocks.'),downloadButton(p,'primary-15-tests.csv'));
- body.append(heading('Broad OXPHOS signal; narrower redox mechanism unresolved','The primary contribution is a distributed OXPHOS-centered signature at both sampled days: 95 and 107 leading-edge genes, 89 shared, with consistent direction across the frozen within-dataset checks. The separate post-primary targeted tier did not establish NRF2, glutathione or their joint NRF2–glutathione–PPP prediction as the specific mechanism; that narrower result does not negate the broader transcriptional finding.'));
- body.append(table(data.targeted,[['module','Target',v=>label(v)],['contrast','Contrast',v=>contrasts[v]],['method','Statistic type'],['estimate','Estimate',v=>fmt(v)],['family_fdr','8-test q',sci],['robustness','Classification']]));
- body.append(heading('Exploratory DNA-maintenance evidence','The frozen exploratory family identified positive DNA-repair and telomere-maintenance enrichment at both sampled days. In a separately corrected post hoc decomposition, DNA repair remained supported after telomere-set genes were removed; telomere maintenance after removal of DNA-repair genes met the follow-up threshold only at Day 1. DNA-replication enrichment and mixed cell-cycle controls leave specificity unresolved. These results nominate a genome-maintenance-associated transcriptional dimension for functional study; they do not demonstrate DNA-repair activity, telomere maintenance or proliferation.'));
- body.append(button('Inspect the bounded DNA-maintenance follow-up →',()=>go('dna'),'secondary'));
- body.append(heading('Study design and interpretation','The principal design constraint is stated here after the scientific evidence; complete model, multiplicity and provenance details are retained under Methods & sources.'));
- const boundary=el('aside','boundary');boundary.append(el('strong','','Interpretation boundary'),el('p','','Three differentiation blocks, two genetic backgrounds. Source materials describe vehicle controls at matching time points, but public RNA-seq metadata do not link individual control libraries to harvest day. This reanalysis uses the available common control pool; a treatment × time interaction cannot be estimated.'));body.append(boundary,button('Review methods and provenance →',()=>go('methods'),'secondary'));
- }
- function landscape(){
- body.append(heading('The OXPHOS landscape','All 113 leading-edge genes, grouped descriptively by function. Select a row to inspect its exact effects and nine expression profiles.'));
- const controls=el('div','controls');controls.append(select('Functional group',[['All functions','All functions'],...[...new Set(data.landscape.map(g=>g.functional_group))].map(v=>[v,v])],group,v=>{group=v;syncLocation();landscapeRender();}),scaleKey(2.5,'Expression · row z'),scaleKey(1.5,'Effect · log₂ fold change'));
- body.append(controls);const split=el('div','landscape-layout'),heat=el('div','heatmap-scroll'),detail=el('aside','gene-detail');split.dataset.fullscreenHost='true';split.dataset.fullscreenTitle='The OXPHOS landscape';split.dataset.fullscreenInfo='Select a gene row to retain its exact effects and nine-profile detail alongside the heatmap.';split.append(heat,detail);body.append(split);
- function landscapeRender(){heat.replaceChildren();const rows=data.landscape.filter(g=>group==='All functions'||g.functional_group===group);const s=svg(680,60+rows.length*15+new Set(rows.map(g=>g.functional_group)).size*22,'Interactive OXPHOS expression and effect heatmap');s.classList.add('heatmap');
- const profileX=125,cell=32,fx=448;
- ['68_3 / B1','68_3 / B2','69_2 / B1'].forEach((t,i)=>text(s,profileX+i*100+46,14,t,{'text-anchor':'middle','font-weight':600}));
- for(let i=0;i<9;i++)text(s,profileX+i*cell+Math.floor(i/3)*4+15,35,['Ctrl','D1','D3'][i%3],{'text-anchor':'middle'});
- ['D1/C','D3/C','D3/D1'].forEach((t,i)=>text(s,fx+i*45+20,35,t,{'text-anchor':'middle'}));text(s,594,35,'LE');
- let groupOffset=0;rows.forEach((g,i)=>{if(i===0||g.functional_group!==rows[i-1].functional_group){text(s,8,59+i*15+groupOffset,g.functional_group,{'font-size':10,'font-weight':600});groupOffset+=22;}const y=46+i*15+groupOffset;const r=svgNode('g',{tabindex:0,role:'button','aria-label':`Inspect ${g.gene}, ${g.functional_group}`});r.classList.add('gene-row');r.append(svgNode('rect',{x:0,y,width:670,height:15,fill:g.gene===selected?'#edf3f1':'transparent'}));r.append(svgNode('text',{x:114,y:y+11,'text-anchor':'end'},g.gene));
- profileMap.get(g.gene).forEach((p,j)=>{const c=svgNode('rect',{x:profileX+j*cell+Math.floor(j/3)*4,y,width:cell-.4,height:14.5,fill:color(p.row_z)});c.append(svgNode('title',{},`${g.gene} · ${p.block} · ${p.condition}\nVST ${fmt(p.vst,4)} · row z ${fmt(p.row_z,4)}\nMean RIN ${fmt(p.RIN_mean)} · ${p.libraries_n} source libraries`));r.append(c);});
- [g.day1_log2fc,g.day3_log2fc,g.day3_minus_day1_log2fc].forEach((v,j)=>{const c=svgNode('rect',{x:fx+j*45,y,width:44.5,height:14.5,fill:color(v,1.5)});c.append(svgNode('title',{},`${g.gene} · ${contrasts[data.contrasts[j]]}\nlog₂ fold change ${fmt(v,5)}`));r.append(c);});
- r.append(svgNode('rect',{x:594,y,width:12,height:14,fill:g.leading_edge==='Shared'?'#243c3c':g.leading_edge==='Day 1 only'?'#56b4e9':'#d55e00'}));
- const choose=()=>{selected=g.gene;syncLocation();geneDetail(detail,selected);heat.querySelectorAll('.gene-row > rect:first-child').forEach(x=>x.setAttribute('fill','transparent'));r.firstChild.setAttribute('fill','#edf3f1');};r.onclick=choose;r.onkeydown=e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();choose();}};s.append(r);
- });heat.append(s);geneDetail(detail,selected);
- }
- landscapeRender();body.append(note('LE: charcoal = shared; blue = Day 1 only; orange = Day 3 only. VST uses blind=FALSE. Row z-scores are scaled across all nine profiles and colors saturate at ±2.5; effect colors saturate at ±1.5. Functional filtering does not recalculate scaling or fit a model. Leading-edge selection makes this a descriptive view.'),downloadButton(data.profiles,'oxphos-nine-profile-expression.csv'),button('↓ Download heatmap SVG',()=>download('oxphos-landscape.svg',new XMLSerializer().serializeToString(heat.querySelector('svg')),'image/svg+xml'),'secondary'));
- }
- async function geneDetail(container,symbol){
- container.replaceChildren(el('div','eyebrow','GENE DETAIL'),el('h3','gene-symbol',symbol),note('Loading archived estimates…'));const token=symbol;container.dataset.gene=token;
- const genes=await getGenes();if(container.dataset.gene!==token||!container.isConnected)return;
- const alias=data.aliases.find(a=>a.current_symbol===symbol||a.source_symbol===symbol||a.selected_gene_id===symbol);
- const gene=genes.find(g=>g.id===symbol)||genes.find(g=>g.symbol===symbol&&g.selected)||genes.find(g=>g.symbol===symbol)||genes.find(g=>g.id===alias?.selected_gene_id);
- container.replaceChildren(el('div','eyebrow','GENE DETAIL'),el('h3','gene-symbol',gene?.symbol||symbol));
- if(!gene){container.append(note('This identifier is absent from the filtered gene results. Absence is not a null result.'));return;}
- container.append(el('p','identifier',gene.id));const info=landscapeMap.get(gene.symbol);if(info)container.append(el('p','',info.functional_group),status(info.leading_edge));
- if(alias)container.append(note(`Alias sensitivity: ${alias.source_symbol||'absent'} → ${alias.current_symbol}; ${alias.status}. These primary estimates retain source symbols.`));
- if(!gene.selected)container.append(note('This gene ID was not the representative selected for symbol-based ranking. Estimates below remain gene-level results.'));
- const effects=gene.effects.map((e,i)=>({...e,contrast:contrasts[data.contrasts[i]]}));
- const s=svg(340,174,`${gene.symbol} model estimates and approximate 95% Wald intervals`);const limit=Math.max(.5,...effects.filter(e=>e.log2FoldChange!==null&&e.lfcSE!==null).map(e=>Math.abs(e.log2FoldChange)+1.96*e.lfcSE));const x=v=>172+v/limit*148;
- line(s,x(0),20,x(0),134,{stroke:'#879998','stroke-dasharray':'3 3'});
- effects.forEach((e,i)=>{const y=40+i*42;text(s,4,y-10,['D1 / control','D3 / control','D3 / D1'][i]);if(e.log2FoldChange!==null&&e.lfcSE!==null){line(s,x(e.log2FoldChange-1.96*e.lfcSE),y,x(e.log2FoldChange+1.96*e.lfcSE),y,{stroke:'#236461','stroke-width':2});s.append(svgNode('circle',{cx:x(e.log2FoldChange),cy:y,r:4,fill:'#236461'}));}});
- [-limit,0,limit].forEach(v=>text(s,x(v),152,fmt(v),{'text-anchor':'middle'}));text(s,172,171,'log₂ fold change · approximate 95% Wald interval',{'text-anchor':'middle','font-size':10});container.append(s);
- container.append(table(effects,[['contrast','Contrast'],['log2FoldChange','log₂FC',v=>fmt(v,3)],['lfcSE','SE',v=>fmt(v,3)],['padj','Gene FDR',sci]]));
- const profiles=profileMap.get(gene.symbol);if(profiles){const ps=svg(340,174,`${gene.symbol} variance-stabilized expression across nine pooled profiles`);const lo=Math.min(...profiles.map(p=>p.vst))-.2,hi=Math.max(...profiles.map(p=>p.vst))+.2;const y=v=>130-(v-lo)/(hi-lo)*105;
- for(let k=0;k<3;k++){const vals=profiles.slice(k*3,k*3+3);const points=vals.map((p,j)=>`${58+j*112},${y(p.vst)}`).join(' ');ps.append(svgNode('polyline',{points,fill:'none',stroke:['#0072b2','#69a2b8','#d55e00'][k],'stroke-width':1.5}));vals.forEach((p,j)=>{const dot=svgNode('circle',{cx:58+j*112,cy:y(p.vst),r:4,fill:['#0072b2','#69a2b8','#d55e00'][k]});dot.append(svgNode('title',{},`${p.block}, ${p.condition}: VST ${fmt(p.vst,4)}; RIN ${fmt(p.RIN_mean)}; ${p.libraries_n} libraries`));ps.append(dot);});}
- ['Control','Day 1','Day 3'].forEach((t,j)=>text(ps,58+j*112,150,t,{'text-anchor':'middle'}));text(ps,3,20,fmt(hi));text(ps,3,134,fmt(lo));text(ps,170,171,'VST · pooled profiles, separate cultures',{'text-anchor':'middle','font-size':10});container.append(el('h4','','Nine pooled profiles'),ps,note('Lines link conditions within each block for comparison; cultures were not sampled longitudinally. Dark blue: 68_3/B1; light blue: 68_3/B2; orange: 69_2/B1.'));}
- else container.append(note('Nine-profile expression is included for the 113 OXPHOS leading-edge genes. This gene has archived model estimates only in this companion.'));
- const memberships=Object.entries(data.membership).filter(([,gs])=>gs.includes(gene.symbol)).map(([id])=>label(id));container.append(el('h4','','Frozen pathway memberships'),el('p','',memberships.join(' · ')||'No literal-symbol membership in the frozen sets.'));
- container.append(note('Intervals use the archived unshrunken coefficient ±1.96 × SE. Gene FDR is distinct from pathway-family q. Three blocks limit generalization.'),downloadButton(effects,`${gene.symbol}-model-estimates.csv`));enhancePlots(container);
- }
- async function genesView(){
- body.append(heading('Gene explorer','Search all 21,154 filtered gene IDs, including the 21,098 representatives used for symbol-based ranking. Verified ATP5 aliases resolve to their original identifiers.'));
- const search=el('input');search.type='search';search.placeholder='Search symbol, Ensembl ID or verified alias…';search.setAttribute('aria-label','Search genes');search.value=selected;
- const layout=el('div','gene-layout'),results=el('div','gene-results'),detail=el('article','gene-detail');body.append(search,layout);layout.append(results,detail);geneDetail(detail,selected);
- const genes=await getGenes();if(!search.isConnected)return;
- function searchResults(){const q=search.value.trim().toUpperCase();const aliasIds=new Set(data.aliases.filter(a=>a.current_symbol.includes(q)).map(a=>a.selected_gene_id));const found=genes.filter(g=>g.symbol.toUpperCase().includes(q)||g.id.toUpperCase().includes(q)||aliasIds.has(g.id));results.replaceChildren(note(`${found.length.toLocaleString()} matches${found.length>60?' · showing first 60 alphabetically':''}`));found.sort((a,b)=>a.symbol.localeCompare(b.symbol));for(const g of found.slice(0,60)){const b=button('',()=>{selected=g.id;geneDetail(detail,g.id);syncLocation();},'gene-hit');b.append(el('strong','',g.symbol),el('small','',g.id),el('small','',g.selected?'Rank representative':'Nonrepresentative duplicate'));results.append(b);}if(!found.length)results.append(note('No matching filtered gene. Try its source symbol or Ensembl ID.'));}
- search.oninput=searchResults;searchResults();
- }
- function pathways(){
- body.append(heading('Pathway evidence','Browse frozen primary, secondary and exploratory sets. Curves reconstruct the archived weighted ranking score; q-values and classifications come directly from the result tables.'));
- const eligible=data.pathways.filter(p=>pathwayTier==='all'||p.tier===pathwayTier);if(!eligible.some(p=>p.pathway===pathway))pathway=eligible[0].pathway;const choices=[...new Map(eligible.map(p=>[p.pathway,[p.pathway,`${label(p.pathway)} · ${p.tier}`]])).values()];
- const controls=el('div','controls');controls.append(select('Evidence tier',[['all','All frozen tiers'],['primary','Primary · 15 tests'],['secondary','Secondary · 21 tests'],['exploratory','Exploratory · 6 tests']],pathwayTier,v=>{pathwayTier=v;render();}),select('Pathway',choices,pathway,v=>{pathway=v;render();}),select('Contrast',Object.entries(contrasts),contrast,v=>{contrast=v;render();}));body.append(controls);
- const row=eligible.find(p=>p.pathway===pathway&&p.contrast===contrast);if(!row)return;
- const summary=el('div','result-summary');summary.append(el('strong','',`NES ${fmt(row.NES)}`),el('span','',`${({primary:'15-test primary',secondary:'21-test secondary',exploratory:'6-test exploratory'})[row.tier]} q = ${sci(row.family_fdr)}`),status(row.robustness));body.append(summary);
- const curve=data.curves[pathway+'|'+contrast];
- if(curve){const s=svg(900,275,`${label(pathway)} weighted running enrichment`),points=curve.points;const low=Math.min(0,...points.map(p=>p[1]))-.04,high=Math.max(0,...points.map(p=>p[1]))+.04;const x=v=>60+v*8.05,y=v=>230-(v-low)/(high-low)*195;
- line(s,60,y(0),865,y(0),{stroke:'#9aabaa'});[0,25,50,75,100].forEach(v=>{line(s,x(v),30,x(v),230);text(s,x(v),250,`${v}%`,{'text-anchor':'middle'});});for(let i=0;i<4;i++){const v=low+(high-low)*i/3;text(s,49,y(v)+4,fmt(v),{'text-anchor':'end'});}for(const h of curve.hits)line(s,x(h),232,x(h),238,{stroke:'#367393','stroke-opacity':.2});s.append(svgNode('polyline',{points:points.map(([a,b])=>`${x(a)},${y(b)}`).join(' '),fill:'none',stroke:'#a34850','stroke-width':2.3}));text(s,450,273,'Position in ranked transcriptome',{'text-anchor':'middle'});body.append(s,note(`${row.size} mapped genes; ${edgeGenes(row).length} leading-edge genes. The curve is sampled for display with both extrema retained; the exported q-value is unchanged.`));}
- else body.append(note('Untestable under the frozen minimum set size of 15. A stored q=1 for this row is bookkeeping, not evidence for a biological null.'));
- body.append(downloadButton([row],'pathway-result.csv'),el('h3','','Leading-edge genes'));
- const chips=el('div','chips');for(const g of edgeGenes(row))chips.append(button(g,()=>go('genes',g)));body.append(chips,note('Gene overlap means pathway results are not independent confirmations. Choosing a contrast or gene here changes the display only.'));
- }
- function robustness(){
- body.append(heading('What “robust” means here','Direction agreement across the frozen block omissions and RNA-quality checks. Significance in every small subset was not required.'));
- const choices=[...new Map(data.pathways.map(p=>[p.pathway,[p.pathway,`${label(p.pathway)} · ${p.tier}`]])).values()];
- const controls=el('div','controls');controls.append(select('Pathway',choices,pathway,v=>{pathway=v;render();}),select('Contrast',Object.entries(contrasts),contrast,v=>{contrast=v;render();}));body.append(controls);
- const rows=data.sensitivities.filter(r=>r.pathway===pathway&&r.contrast===contrast);const all=Math.max(1,...rows.filter(r=>r.NES!==null).map(r=>Math.abs(r.NES)));const s=svg(900,rows.length*30+62,'Pathway normalized enrichment score across all archived variants');const x=v=>550+v/(all+.3)*300;
- line(s,x(0),15,x(0),rows.length*30+20,{stroke:'#647d7d','stroke-dasharray':'4 4'});
- rows.forEach((r,i)=>{const y=30+i*30;text(s,12,y+4,r.variant.replaceAll('__',' / ').replaceAll('_',' '));line(s,320,y,875,y,{stroke:'#edf0f0'});if(r.NES!==null){const dot=svgNode('circle',{cx:x(r.NES),cy:y,r:r.variant==='primary'?6:4,fill:r.variant.startsWith('block_')?'#9a6960':'#236461'});dot.append(svgNode('title',{},`${r.variant}\nNES ${fmt(r.NES,5)}\nFamily q ${sci(r.family_fdr)}`));s.append(dot);}else text(s,550,y,'Not estimable');});[-all,0,all].forEach(v=>text(s,x(v),rows.length*30+47,fmt(v),{'text-anchor':'middle'}));body.append(s,note('NES is a normalized gene-ranking enrichment statistic, not a biological-sample effect size. Brown points are descriptive single-block rankings; they do not increase the number of independent blocks.'),downloadButton(rows,'all-robustness-variants.csv'));
- body.append(table(rows,[['variant','Variant'],['NES','NES',v=>fmt(v,4)],['family_fdr','Within-variant family q',sci],['rank_kind','Rank type']]));
- if(pathway==='HALLMARK_OXIDATIVE_PHOSPHORYLATION'){body.append(el('h3','','Post-freeze alias sensitivity'),note('The alias-expanded OXPHOS comparison is a separate one-set sensitivity and never replaces the frozen 15-test primary q-values.'));const aliases=data.aliasSensitivity.filter(r=>r.contrast===contrast);body.append(table(aliases,[['variant','Variant'],['baseline_NES','Literal NES',v=>fmt(v,4)],['NES','Alias NES',v=>fmt(v,4)]]),downloadButton(aliases,'post-freeze-alias-sensitivity.csv'));}
- }
- function dnaView(){
- body.append(heading('DNA maintenance','The two frozen exploratory pathways, followed by a separately specified post hoc decomposition. These results remain subordinate to the primary metabolic analysis.'));
- body.append(el('aside','boundary','Transcriptional enrichment ≠ DNA repair activity or telomere preservation. Cell-cycle context and shared pathway membership complicate specificity.'));
- const frozen=data.pathways.filter(p=>p.tier==='exploratory');
- body.append(el('h3','','Frozen exploratory family · 6 tests'),table(frozen,[['pathway','Pathway',label],['contrast','Contrast',v=>contrasts[v]],['NES','NES',v=>fmt(v,3)],['family_fdr','6-test q',sci],['robustness','Direction class']]),downloadButton(frozen,'frozen-exploratory-6-tests.csv'));
- body.append(heading('Which genes carry the telomere signal?','All 30 genes in the two-day leading-edge union: 27 at Day 1, 25 at Day 3, 22 shared. Functional annotations overlap; they are not additional enrichment tests.'));
- const controls=el('div','controls');const mapHost=el('div','dna-map-scroll'),detail=el('aside','gene-detail');
- controls.append(select('Telomere annotation',[['All genes','All genes'],['Packaging / protection','Packaging / protection'],['Telomerase extension / RNP','Telomerase extension / RNP'],['C-strand synthesis','C-strand synthesis'],['Recombination / chromatin / TERRA','Recombination / chromatin / TERRA']],dnaFilter,v=>{dnaFilter=v;syncLocation();draw();}),scaleKey(1.5,'Effect · log₂ fold change'));
- body.append(controls);const layout=el('div','landscape-layout');layout.dataset.fullscreenHost='true';layout.dataset.fullscreenTitle='Telomere leading-edge gene map';layout.dataset.fullscreenInfo='Select a gene row to retain its associated archived estimates alongside the map.';layout.append(mapHost,detail);body.append(layout);
- function draw(){
- const rows=data.dna.decomposition.filter(g=>dnaFilter==='All genes'||g.modules.split(';').includes(dnaFilter));const s=svg(680,108+rows.length*22,'Telomere leading-edge genes, model effects and overlapping descriptive annotations');s.classList.add('dna-map');
- const columns=[['D1/Ctrl',137],['D3/Ctrl',197],['LE D1',265],['LE D3',310],['DNA',365],['Protect',425],['RNP',479],['C-strand',541],['TERRA',611]];
- columns.forEach(([v,x])=>text(s,x,38,v,{'text-anchor':'middle','font-size':11}));text(s,8,72,'Gene',{'font-weight':600});
- rows.forEach((g,i)=>{const y=86+i*22,r=svgNode('g',{role:'button',tabindex:0,'aria-label':`Inspect DNA-maintenance gene ${g.gene}`});r.classList.add('dna-row');r.append(svgNode('text',{x:8,y:y+15},g.gene));
- [g.day1_log2fc,g.day3_log2fc].forEach((v,j)=>{const c=svgNode('rect',{x:110+j*60,y,width:54,height:21,fill:color(v,1.5)});c.append(svgNode('title',{},`${g.gene} · ${j?'Day 3':'Day 1'} log₂FC ${fmt(v,5)}`));r.append(c);});
- const bits=[g.day1_le,g.day3_le,g.dna_member,g.modules.includes('Packaging'),g.reaction_ids.includes('R-HSA-164616'),g.modules.includes('C-strand'),g.reaction_ids.includes('R-HSA-9670149')];
- bits.forEach((hit,j)=>{const c=svgNode('rect',{x:columns[j+2][1]-8,y:y+3,width:16,height:16,fill:hit?'#365c53':'#edf0ed'});c.append(svgNode('title',{},`${columns[j+2][0]}: ${hit?'member':'not annotated'}`));r.append(c);});
- const choose=()=>{dnaGene=g.gene;syncLocation();geneDetail(detail,dnaGene);};r.onclick=choose;r.onkeydown=e=>{if(e.key==='Enter'||e.key===' '){e.preventDefault();choose();}};s.append(r);
- });mapHost.replaceChildren(s);
- }
- draw();geneDetail(detail,dnaGene);
- body.append(note('DNA marks membership in the entire frozen Hallmark DNA-repair set. Protect: packaging/protection; RNP: telomerase RNP assembly participants; C-strand: synthesis; TERRA: transcription-reaction participants, including associated complexes. Child-set membership uses MSigDB 2026.1.Hs. Packaging (absent from that GMT) and reaction annotations use the recorded Reactome 97 snapshot. Membership does not measure telomerase or TERRA activity.'),downloadButton(data.dna.decomposition,'telomere-30-gene-decomposition.csv'));
- body.append(el('h3','','Gene-set redundancy'),table(data.dna.overlap,[['scope','Comparison'],['dna_n','DNA repair'],['telomere_n','Telomere'],['shared_n','Shared'],['jaccard','Jaccard',v=>fmt(v,3)],['fraction_telomere','Fraction of telomere',v=>fmt(v,3)]]),downloadButton(data.dna.overlap,'dna-telomere-overlap.csv'));
- body.append(heading('Overlap removal and cell-cycle context','Post hoc family: eight sets × three contrasts, 24-test BH correction. All results and ten variants are retained. Positive enrichment after subtraction does not establish biological independence.'));
- const follow=el('div');body.append(follow);
- const renderTests=()=>{const rows=data.dna.tests.filter(r=>r.contrast===dnaContrast);follow.replaceChildren(table(rows,[['module','Set',label],['mapped','Mapped'],['NES','NES',v=>fmt(v,3)],['family_fdr','24-test q',sci],['robustness','Direction class']]));};
- const chooser=select('DNA follow-up contrast',Object.entries(contrasts),dnaContrast,v=>{dnaContrast=v;syncLocation();renderTests();});body.insertBefore(chooser,follow);renderTests();
- body.append(note('DNA repair remains robust at both sampled days after removing telomere genes. Telomere-minus-DNA-repair is positive at both days but meets the new q threshold only at Day 1. DNA replication is enriched at both days, with block-dependent Day-3 direction. E2F, G2M and mitotic spindle do not meet the 24-test threshold. These mixed findings limit a repair-specific interpretation.'),downloadButton(data.dna.tests,'post-hoc-dna-24-tests.csv'));
- const variants=el('details');variants.append(el('summary','','Inspect all 240 follow-up results'),table(data.dna.sensitivities,[['module','Set',label],['contrast','Contrast',v=>contrasts[v]],['variant','Variant'],['NES','NES',v=>fmt(v,3)],['family_fdr','24-test q',sci]]),downloadButton(data.dna.sensitivities,'post-hoc-dna-all-variants.csv'));body.append(variants);
- body.append(heading('Concordance across sampled days','Descriptive correlations among selected leading-edge genes sharing the same controls. No correlation p-values or persistence claim.'));
- const points=data.dna.genes,lim=Math.max(1,...points.flatMap(g=>[Math.abs(g.day1_log2FoldChange),Math.abs(g.day3_log2FoldChange)]));const plot=svg(640,350,'Day-1 and Day-3 DNA-maintenance leading-edge gene effects');const px=v=>336+v/lim*260,py=v=>165-v/lim*125;
- line(plot,px(-lim),py(0),px(lim),py(0));line(plot,px(0),py(-lim),px(0),py(lim));line(plot,px(-lim),py(-lim),px(lim),py(lim),{'stroke-dasharray':'4 4'});
- for(const v of [-lim,0,lim]){text(plot,px(v),310,fmt(v),{'text-anchor':'middle'});text(plot,58,py(v)+4,fmt(v),{'text-anchor':'end'});}
- for(const g of points){const dot=svgNode('circle',{cx:px(g.day1_log2FoldChange),cy:py(g.day3_log2FoldChange),r:4,fill:g.in_telomere_le_union?'#a45845':'#317b82','fill-opacity':.8,tabindex:0,role:'button','aria-label':`Inspect concordance gene ${g.gene}`});dot.append(svgNode('title',{},`${g.gene} · D1 ${fmt(g.day1_log2FoldChange,4)} · D3 ${fmt(g.day3_log2FoldChange,4)}`));dot.onclick=()=>go('genes',g.gene);dot.onkeydown=e=>{if(e.key==='Enter'){go('genes',g.gene);}};plot.append(dot);}
- text(plot,320,341,'Day 1 / common control · log₂ fold change',{'text-anchor':'middle'});text(plot,15,167,'Day 3 / common control · log₂ fold change',{transform:'rotate(-90 15 167)','text-anchor':'middle','font-size':11});body.append(plot,note('Rust: telomere leading-edge union (including overlap); teal: DNA-repair leading-edge union only. Dashed line: equal estimates. Click a point to open the archived gene estimates.'),table(data.dna.concordance,[['selection','Gene selection',label],['statistic','Statistic'],['n','N genes'],['spearman','Spearman ρ',v=>fmt(v,3)],['same_sign_n','Same sign'],['positive_both_n','Positive both']]),downloadButton(data.dna.genes,'dna-cross-day-gene-effects.csv'));
- const panel=el('details');panel.append(el('summary','','Canonical gene panel · includes absent and mixed results'),note('Transcriptome-wide gene FDR from the original fits; no new panel-specific tests. H2AX/H2AFX are listed as source-symbol checks, not counted as separate biological evidence. TERT absence is not a measured null.'),table(data.dna.panel,[['gene','Gene'],['contrast','Contrast',v=>contrasts[v]],['availability','Availability'],['log2FoldChange','log₂FC',v=>fmt(v,3)],['gene_fdr','Original gene FDR',sci]]),downloadButton(data.dna.panel,'dna-canonical-panel.csv'));body.append(panel);
- }
- function methods(){
- body.append(heading('Methods, provenance & reuse','A static view of an archived analysis. Browser interactions select and display results; they do not refit DESeq2, rerun enrichment or create new confirmatory tests.'));
- const sections=[['Experimental unit','Raw counts from 23 source libraries were computationally aggregated into nine block × condition profiles. There are three differentiation blocks and two genetic backgrounds. Cells, genes and libraries are not independent biological replicates.'],['Model and multiplicity','DESeq2 ~ block + condition; unshrunken Wald ranks; fgseaMultilevel. The five primary pathways and three contrasts form one 15-test BH family. Secondary (21 tests), exploratory (6 tests), post-primary targeted (8 tests) and post hoc DNA-maintenance (24 tests) families are separate.'],['Temporal interpretation','Source materials describe vehicle controls at matching time points, but public RNA-seq metadata do not recover individual control-library harvest days. This reanalysis compares both sampled days with one available common control pool, so treated Day 3 / Day 1 is not a treatment-by-time interaction.'],['Scope of the observation','Transcriptional enrichment does not establish respiration, ATP production, redox state, resilience, telomere protection or a mechanism linking these cultures to human outcomes.'],['Figure 3 construction','DESeq2 VST with blind=FALSE; within-gene z-scores over nine explicitly ordered profiles. Expression and effect colors saturate at ±2.5 and ±1.5. Functional groups are project display assignments, not new enrichment families. All 113 genes were selected from OXPHOS leading edges.'],['Archive','Version 1.0.1 · https://doi.org/10.5281/zenodo.22849800']];for(const[t,p]of sections){const c=el('section','method-card');c.append(el('h3','',t),el('p','',p));body.append(c);}
- const citation=el('section','citation-card');citation.append(el('h3','','Source-study citation'),el('p','','Schmidt M, Hoffrichter A, Davoudi M, Horschitz S, Lau T, Meinhardt MW, Spanagel R, Ladewig J, Köhr G, Koch P. (2026). Psilocin fosters neuroplasticity in iPSC-derived human cortical neurons. eLife, 14, RP104006. https://doi.org/10.7554/eLife.104006.3'));body.append(citation);
- const links=el('p');for(const[t,u]of [['Original article',provenance.article],['Author RNA-seq repository',provenance.source],['Dryad phenotype record','https://doi.org/10.5061/dryad.xsj3tx9w3'],['Archived reanalysis','https://doi.org/10.5281/zenodo.22849800']]){const a=el('a','source-link',t+' ↗');a.href=u;a.target='_blank';a.rel='noopener';links.append(a);}body.append(links,el('h3','','Frozen plan record'));
- const pre=el('pre','hash-record',JSON.stringify(provenance.freeze,null,2));body.append(pre,el('h3','','Exact input checksums'),table(Object.entries(provenance.inputs).map(([path,sha256])=>({path,sha256})),[['path','Source file'],['sha256','SHA-256']]),button('↓ Download provenance JSON',()=>download('provenance.json',JSON.stringify(provenance,null,2),'application/json'),'secondary'),button('↓ Download complete atlas JSON',()=>download('atlas.json',JSON.stringify(data),'application/json'),'secondary'));
- }
- render();return root;
- }
atlas.5a109658.js at commit 865b542, under CC-BY-4.0 · at the source
Overview
- Department of Translational Brain Research, Central Institute of Mental Health (ZI), University of Heidelberg/ Medical Faculty Mannheim, Mannheim, Germany
- Hector Institute for Translational Brain Research (HITBR gGmbH), Mannheim, Germany
- German Cancer Research Center (DKFZ), Heidelberg, Germany
- Department of Neuroanatomy, Mannheim Centre for Translational Neuroscience (MCTN), Medical Faculty Mannheim, Heidelberg University, Mannheim, Germany
- Institute for Psychopharmacology, Central Institute of Mental Health (ZI), University of Heidelberg/Medical Faculty Mannheim, Mannheim, Germany
- Molecular Neuroimaging, Central Institute of Mental Health (ZI), University of Heidelberg/ Medical Faculty Mannheim, Mannheim, Germany
- German Center for Mental Health (DZPG), partner site Mannheim-Heidelberg-Ulm, Mannheim, Germany
- Department of Neurophysiology, Mannheim Center for Translational Neuroscience (MCTN), University of Heidelberg/Medical Faculty Mannheim, Mannheim, Germany
Abstract
Psilocybin is studied as innovative medication in anxiety, substance abuse and treatment-resistant depression. Animal studies show that psychedelics promote neuronal plasticity by strengthening synaptic responses and protein synthesis. However, the exact molecular and cellular changes induced by psilocybin in the human brain are not known. Here, we treated human cortical neurons derived from induced pluripotent stem cells with the 5-HT2A receptor agonist psilocin – the psychoactive metabolite of psilocybin. We analyzed how exposure to psilocin affects gene expression, neuronal morphology, synaptic markers and neuronal function. Psilocin provoked a 5-HT2A-R-mediated augmentation of BDNF abundance. Transcriptomic profiling identified gene expression signatures priming neurons to neuroplasticity. On a morphological level, psilocin induced enhanced neuronal complexity and increased expression of synaptic proteins, in particular in the postsynaptic compartment. Consistently, we observed an increased excitability and enhanced synaptic network activity in neurons treated with psilocin. In conclusion, exposure of human neurons to psilocin might induce a state of enhanced neuronal plasticity, which could explain why psilocin is beneficial in the treatment of neuropsychiatric disorders where synaptic dysfunctions are discussed.
Reproduced under the paper's license (CC BY), from the paper cited above.
Repositories
Its files are read in the Code ↔ Paper reader above, with 5 matches between paragraphs and lines of code.
ahoffrichter/schmidt_et_al_2025
c565709affafbea09406bd7b42fe494f08db6cce, 30 March 2026Availability: 1 check, the latest on 30 September 2026: the link answers
- 30 September 2026: the link answers
5 files
- r-scripts/
001_Data_preparation_Sch , R, 100 linesmidt_et_al_2024.Rmd - r-scripts/
002_Figure3_Schmidt_et_a , R, 1,051 linesl_2024.Rmd - r-scripts/
003_Supplementary_Figure , R, 732 lines3_Schmidt_et_al.Rmd - LICENSE, License, 21 lines
- README.md, Text, 6 lines
Zenodo 22849800
Availability: 2 checks, the latest on 30 September 2026: the link answers (HTTP 200)
- 30 September 2026: the link answers (HTTP 200)
- 30 September 2026: the link answers (HTTP 200)
psilocybin-research/psilocin-human-neuron-transcriptomics
865b5425bb3084188f9d231e93397af6e572113c, 20 September 2026Availability: 1 check, the latest on 30 September 2026: the link answers
- 30 September 2026: the link answers
51 files
- explorer/
observablehq.config.js , JavaScript, 120 lines - explorer/
src/ , JavaScript, 216 lines, 1 matchcomponents/ atlas.js - explorer/
src/ , JavaScript, 16 linescomponents/ format.js - explorer/
test/ , JavaScript, 50 linesdata.test.js - explorer/
test/ , JavaScript, 70 linesmetadata.test.js - site/
_import/ , JavaScript, 217 lines, 2 matchescomponents/ atlas.5a109658.js - site/
_import/ , JavaScript, 16 linescomponents/ format.0a1392e2.js - site/
_observablehq/ , JavaScript, 1 lineclient.4a52a1f6.js - site/
_observablehq/ , JavaScript, 7 linesruntime.fa9f71c0.js - site/
_observablehq/ , JavaScript, 1 linestdlib.bc967ff7.js - src/
__init__.py , Python, 1 line - src/
acquisition/ , Python, 1 line__init__.py - src/
acquisition/ , Python, 38 linesanalysis_inputs.py - src/
acquisition/ , Python, 147 linesdownload.py - src/
acquisition/ , Python, 30 linesreactome_dna_annotation. py - src/
acquisition/ , Python, 17 linesreactome_dna_reactions.p y - src/
acquisition/ , Python, 40 linesrestore.py - src/
acquisition/ , Python, 39 linesschmidt_context.py - src/
audit/ , Python, 1 line__init__.py - src/
audit/ , Python, 59 linescontrol_resolution.py - src/
audit/ , Python, 146 linesinventory.py - src/
audit/ , Python, 150 linesschmidt_design.py - src/
figures/ , Python, 15 linesaudit_explorer_runtime.p y - src/
figures/ , Python, 49 linesaudit_publication_figure s.py - src/
figures/ , Python, 81 linesexport_explorer.py - src/
figures/ , R, 4 linesfigure_style.R - src/
quick_start.R , R, 101 lines - src/
transcriptomics/ , R, 134 linesanalyze.R - src/
transcriptomics/ , R, 39 linesdna_maintenance.R - src/
transcriptomics/ , Python, 21 linesfreeze.py - src/
transcriptomics/ , R, 27 lineshelpers.R - src/
transcriptomics/ , R, 106 linesoxphos_alias_sensitivity .R - src/
transcriptomics/ , R, 198 linesoxphos_gene_heatmap.R - src/
transcriptomics/ , Python, 37 linesprepare_gene_sets.py - src/
transcriptomics/ , R, 208 linespublication_figures.R - src/
transcriptomics/ , R, 99 linesqc_reproduce.R - src/
transcriptomics/ , Python, 129 lines, 1 matchreport_dna_maintenance.p y - src/
transcriptomics/ , Python, 19 linesreport_oxphos_gene_summa ry.py - src/
transcriptomics/ , Python, 123 lines, 1 matchreport_results.py - src/
transcriptomics/ , R, 7 linesrestore_environment.R - src/
transcriptomics/ , R, 45 linestargeted_redox.R - src/
validate_release.py , Python, 243 lines - src/
zenodo_release.py , Python, 246 lines - tests/
test_dna_maintenance.py , Python, 46 lines - tests/
test_identity.py , Python, 40 lines - tests/
test_provenance.py , Python, 47 lines - tests/
test_reporting.py , Python, 46 lines - tests/
test_schmidt_design.py , Python, 60 lines - tests/
test_transcriptomics.R , R, 10 lines - LICENSE.md, License, 23 lines
- README.md, Text, 213 lines
Zenodo 22843280
Availability: 1 check, the latest on 30 September 2026: the link answers (HTTP 200)
- 30 September 2026: the link answers (HTTP 200)
Zenodo 22843281
Availability: 1 check, the latest on 30 September 2026: the link answers (HTTP 200)
- 30 September 2026: the link answers (HTTP 200)
The paper's code and data availability statement is in the Data section.
Tracing map
Proposed by the machine: these links were found in the paper and verified at the source, without human review. The map will receive a Zenodo DOI once one of the paper's authors has validated it with their ORCID.
What the map holds:
- 5 repositories of the authors' code, each at its verified commit, with its license and how the link was found in the paper;
- 52 scripts, each with its path and the digest of its content;
- 5 matches between paragraphs of the paper and lines of the code (method lexical-v1);
- neither the text of the paper nor the code itself.
Its JSON (tracing-map.json) is deposited on Zenodo with its DOI once the map is validated.
Data
Datasets cited
- doi:10.5061/
dryad.xsj3tx9w3 , at Dryad; found in “Data availability”
Data availability
The R code used to analyze RNAseq data is available at https://
The following dataset was generated:
Schmidt M, Hoffrichter A, Davoudi M, Horschitz S, Lau T, Meinhardt MW, Spanagel R, Ladewig J, Köhr G, Koch P. 2026. Psilocin fosters neuroplasticity in iPSC-derived human cortical neurons. Dryad Digital Repository.
Reproduced under the paper's license (CC BY), from the paper cited above.
Versions
The history of this record: each version stored by the harvester or made by a correction of its authors or of the maintainers of its code, and what changed in its facts. The texts of the paper (its abstract, its availability statements) are not part of it; versions that changed only those are not listed.
Version 1, 30 September 2026: the first record
Recorded: type, language, journal, volume, pages, dates, 10 authors, 1 keyword, 10 MeSH terms, 2 funders, 59 references.
Cite
This paper
Schmidt, M., Hoffrichter, A., Davoudi, M., Horschitz, S., Lau, T., Meinhardt, M. W., Spanagel, R., Ladewig, J., Köhr, G., & Koch, P. (2026). Psilocin fosters neuroplasticity in iPSC-derived human cortical neurons. eLife, 14, RP104006. https://
BibTeX
@article{schmidt2026psil
author = {Schmidt, Malin and Hoffrichter, Anne and Davoudi, Mahnaz and Horschitz, Sandra and Lau, Thorsten and Meinhardt, Marcus W and Spanagel, Rainer and Ladewig, Julia and Köhr, Georg and Koch, Philipp},
title = {{Psilocin fosters neuroplasticity in iPSC-derived human cortical neurons}},
journal = {eLife},
year = {2026},
month = mar,
volume = {14},
pages = {RP104006},
publisher = {eLife Sciences Publications, Ltd},
issn = {2050-084X},
doi = {10.7554/
url = {https://
pmid = {41891829},
pmcid = {PMC13030890}
}
RIS
TY - JOUR
AU - Schmidt, Malin
AU - Hoffrichter, Anne
AU - Davoudi, Mahnaz
AU - Horschitz, Sandra
AU - Lau, Thorsten
AU - Meinhardt, Marcus W
AU - Spanagel, Rainer
AU - Ladewig, Julia
AU - Köhr, Georg
AU - Koch, Philipp
TI - Psilocin fosters neuroplasticity in iPSC-derived human cortical neurons
T2 - eLife
J2 - eLife
PY - 2026
DA - 2026/
VL - 14
SP - RP104006
SN - 2050-084X
PB - eLife Sciences Publications, Ltd
DO - 10.7554/
UR - https://
LA - en
ER -
CSL-JSON
{
"id": "10.7554/
"type": "article-journal",
"title": "Psilocin fosters neuroplasticity in iPSC-derived human cortical neurons",
"container-title": "eLife",
"author": [
{
"family": "Schmidt",
"given": "Malin"
},
{
"family": "Hoffrichter",
"given": "Anne"
},
{
"family": "Davoudi",
"given": "Mahnaz"
},
{
"family": "Horschitz",
"given": "Sandra"
},
{
"family": "Lau",
"given": "Thorsten"
},
{
"family": "Meinhardt",
"given": "Marcus W"
},
{
"family": "Spanagel",
"given": "Rainer"
},
{
"family": "Ladewig",
"given": "Julia"
},
{
"family": "Köhr",
"given": "Georg"
},
{
"family": "Koch",
"given": "Philipp"
}
],
"container-title-short":
"volume": "14",
"page": "RP104006",
"DOI": "10.7554/
"PMID": "41891829",
"PMCID": "PMC13030890",
"ISSN": "2050-084X",
"publisher": "eLife Sciences Publications, Ltd",
"URL": "https://
"language": "en",
"issued": {
"date-parts": [
[
2026,
3,
27
]
]
}
}
The tracing map gets a citation of its own once an author has validated it and it has a DOI.
Similar papers
The papers with a page that share the most with this one: the tools found in their code, their categories, datasets, cited references and authors, the rarest counting most.
- [1] doi:10.1038/s41467-025-64980-0 [code]
- Capturing disease severity in LIS1-lissencephaly reveals proteostasis dysregulation in patient-derived forebrain organoids.Journal: Nature communicationsIn common: circlize, clusterProfiler, ComplexHeatmap, 4 other tools, genetics / omics, 3 authors
- [2] doi:10.1038/s41467-025-57339-y [code]
- Cell type-specific multi-omics analysis of cocaine use disorder in the human caudate nucleus.Journal: Nature communicationsIn common: circlize, clusterProfiler, ComplexHeatmap, 3 other tools, genetics / omics, cellular / molecular, 3 authors
- [3] doi:10.1038/s41419-022-05340-4 [code]
- Diverse maturity-dependent and complementary anti-apoptotic brakes safeguard human iPSC-derived neurons from cell death.Journal: Cell death & diseaseIn common: clusterProfiler, DESeq2, patchwork, 2 other tools, cellular / molecular, 3 authors
- [4] doi:10.1038/s41380-024-02439-2
- Lasting dynamic effects of the psychedelic 2,5-dimethoxy-4-iodoamph
etamine ((±)-DOI) on cognitive flexibility. Journal: Molecular psychiatryIn common: 12 references - [5] doi:10.1007/s43440-024-00679-1 [code]
- Assessing the effects of 5-HT<sub>2A</
sub> and 5-HT<sub>5A</ sub> receptor antagonists on DOI-induced head-twitch response in male rats using marker-less deep learning algorithms. Journal: Pharmacological reports : PRIn common: pandas, NumPy, cellular / molecular, 10 references - [6] doi:10.1038/s41398-023-02690-1
- Psilocybin-induced default mode network hypoconnectivity is blunted in alcohol-dependent rats.Journal: Translational psychiatryIn common: 4 references, 2 authors
- [7] doi:10.1038/s41467-025-64887-w [code]
- Sex-specific role of the 5-HT&
lt;sub& gt;2A& lt;/ sub& gt; receptor in psilocybin-induced extinction of opioid reward. Journal: Nature communicationsIn common: clusterProfiler, DESeq2, reshape2, 2 other tools, cellular / molecular, 7 references - [8] doi:10.1038/s41398-024-03139-9 [code]
- Multi-omics profiling of DNA methylation and gene expression alterations in human cocaine use disorder.Journal: Translational psychiatryIn common: clusterProfiler, DESeq2, reshape2, 2 other tools, genetics / omics, cellular / molecular, 2 references, author Rainer Spanagel
- [9] doi:10.1038/s41398-024-03189-z [code]
- Prefrontal electrophysiological biomarkers and mechanism-based drug effects in a rat model of alcohol addiction.Journal: Translational psychiatryIn common: 2 references, 2 authors
- [10] doi:10.1007/s00213-023-06394-8 [code]
- Effect of LSD and music on the time-varying brain dynamics.Journal: PsychopharmacologyIn common: ggplot2, tidyverse, pandas, 1 other tool, 6 references
Contribute
The authors of this paper can claim it, correct its record and validate its tracing map, and the maintainers of its code (its owner, or a public member of its organization) correct what it says of their repository; anyone signed in can ask for its removal. Every request goes to OSCR's own machine, which answers it; your account page follows them.
Sign in with ORCID to claim this paper as one of its authors, correct its record or validate its tracing map: when the paper's metadata lists your ORCID iD, you are recognized at once. Maintainers of its code: sign in with GitHub, then claim the repository on your account page.
Claim this paper
Correct its record
Say what each link of this record is, remove the ones that are not the paper's, add the ones that are missing. The correction becomes a new version of the record, in its Versions section.
Validate its tracing map
You validate the map as this page shows it: 5 repositories of the authors' code, each at its verified commit and with its license, 52 scripts, and 5 matches between paragraphs and code (see the Code and Map sections). It then receives a DOI on Zenodo, with you (your ORCID iD) and OSCR as its creators; the code itself is not deposited.
The map's fingerprint: sha256:062be2a566f36786…
Add the badge to the code's README
If you are an author or a maintainer of this paper's code, you can add this badge. It says what OSCR knows of the paper (its code, its validated tracing map) and links the code to this page. Paste one of these snippets under the README's title. Keep the two marks around it, so that the badge can be replaced in place and is never added twice. OSCR changes nothing in your repository.
Markdown
<!-- oscr-badge:start -->
[](https://openscicode.org/badge/doi/10.7554/elife.104006)
<!-- oscr-badge:end -->reStructuredText
.. oscr-badge:start
.. image:: https://openscicode.org/badge/doi/10.7554/elife.104006.svg
:target: https://openscicode.org/badge/doi/10.7554/elife.104006
:alt: OSCR
.. oscr-badge:endHTML
<!-- oscr-badge:start -->
<a href="https://openscicode.org/badge/doi/10.7554/elife.104006"><img src="https://openscicode.org/badge/doi/10.7554/elife.104006.svg" alt="OSCR"></a>
<!-- oscr-badge:end -->On GitHub, open the README, choose Edit (the pencil), paste the snippet under the title, then "Commit changes".
- ahoffrichter/schmidt_et_al_2025: README.md on GitHub
- psilocybin-research/psilocin-human-neuron-transcriptomics: README.md on GitHub
If you choose to, you can have the badge kept up to date for you, with oscr badge --write from the command line or with the GitHub Action in your repository's workflows. Every other form and option (a card, AsciiDoc, LaTeX, shields.io) is on the badge page.
Request its removal
To ask OSCR to remove this record, the copies of its authors' scripts or its tracing map, use the removal request page: signed in, you say who you are, what to remove and why, then review and confirm the request. Published rules decide every request (how).
Discussion, reproductions, activity
Discussion: code errors and mismatches between the code and the paper about this paper and its code, from readers and its authors, beside the paper and its tracing map.
Report a mismatch between the code and the paper · Report a code error (signed in)
Reproductions: reports from readers who ran the authors' code and did not get the paper's result, what they ran, with which environment, commit and data.
Report a reproduction failure (signed in)
Versions of its code: the releases of its code tied to a version of this paper (the preprint, the accepted manuscript, the version of record…), each with the tracing map versioned with it.
Activity: what happens around this paper: new versions of its record, its map's validation, discussions and reproductions. It opens with sign-in.
