PageSourceSearch

https://biodesign.top/app/assets/RamanSPy.CscMsscV.js

js biodesign.top collected 2026-10-04 04:32:49 UTC 15,465 bytes, 7 lines download raw bytes

1import{u as pe,a as D,r as c,c as m,b as r,i as ce,e as t,f as b,h as x,w as v,J as H,d as I,F as W,m as J,v as N,t as u,n as Q,g as be,H as xe,y as q,x as a,G as me}from"./index.DM3-Y06c.js";import{M as ve}from"./ModuleHeader.BdVJZvEv.js";import{_ as fe}from"./FileUpload.s0lIusZc.js";const ge={class:"w-full max-w-none px-4 md:px-8 xl:px-10 mx-auto animate-fade-in pb-20"},ye={class:"grid grid-cols-1 xl:grid-cols-[300px_minmax(0,1fr)] gap-6"},we={class:"bg-lab-800 rounded-xl border border-lab-700 p-5 h-fit xl:sticky xl:top-4 space-y-4"},he={key:0,class:"space-y-2 rounded-lg border border-lab-700 bg-lab-900/40 p-3"},_e=["value"],ke={class:"grid grid-cols-2 gap-2 pt-1"},Se={key:1},Ce={class:"border-t border-lab-700 pt-4 space-y-3"},Le={class:"rounded-lg border border-lab-700 bg-lab-900/40 p-3 text-sm"},Re={class:"flex items-center gap-2 mb-1"},Me={class:"text-white font-bold"},$e={class:"text-xs"},Ae=["disabled"],Pe={key:0,class:"fa-solid fa-spinner fa-spin mr-2"},Ne={key:1,class:"fa-solid fa-bolt mr-2"},Be={class:"space-y-6"},Ve={class:"bg-lab-800 rounded-xl border border-lab-700 p-6 space-y-4"},Ue={key:0,class:"text-sm text-slate-400"},De={key:2,class:"text-sm text-red-400 whitespace-pre-wrap"},He={key:3,class:"text-sm text-green-400"},Ie={key:0,class:"bg-lab-800 rounded-xl border border-lab-700 p-8 text-center text-slate-300"},Te={key:1,class:"bg-lab-800 rounded-xl border border-lab-700 p-6 space-y-5"},Fe={class:"flex flex-wrap items-center justify-between gap-3"},Ee=["disabled"],ze={class:"grid grid-cols-2 md:grid-cols-4 gap-3 text-sm"},Oe={class:"rounded-lg bg-lab-900/50 border border-lab-700 px-3 py-2"},Ge={class:"text-white font-bold"},je={class:"rounded-lg bg-lab-900/50 border border-lab-700 px-3 py-2"},We={class:"text-white font-mono text-xs"},Je={class:"rounded-lg bg-lab-900/50 border border-lab-700 px-3 py-2"},Qe={class:"text-white font-bold"},qe={class:"rounded-lg bg-lab-900/50 border border-lab-700 px-3 py-2"},Ze={class:"text-white font-bold"},Ke={key:0,class:"rounded-lg border border-lab-700 bg-lab-900/40 p-4 overflow-x-auto"},Xe=["innerHTML"],Ye={key:1,class:"rounded-lg border border-lab-700 bg-lab-900/40 p-4 overflow-x-auto"},et={class:"text-xs text-slate-400 mb-2"},tt={key:0,class:"text-amber-400 ml-2"},st=["innerHTML"],ot={key:2,class:"grid grid-cols-1 md:grid-cols-2 gap-4"},lt={class:"text-xs text-slate-400 mb-2"},at=["src","alt"],ut={__name:"RamanSPy",setup(nt){const R=pe(),Z=[{id:"whitaker_hayes",label:"Despike · Whitaker–Hayes"},{id:"savgol",label:"Denoise · Savitzky–Golay"},{id:"whittaker",label:"Denoise · Whittaker"},{id:"gaussian",label:"Denoise · Gaussian"},{id:"aspls",label:"Baseline · asPLS"},{id:"asls",label:"Baseline · ASLS"},{id:"airpls",label:"Baseline · airPLS"},{id:"minmax",label:"Normalise · MinMax"},{id:"vector",label:"Normalise · Vector"},{id:"auc",label:"Normalise · AUC"}],l=D({loader:"sample",protocol:"georgiev2023_P1",analysis:"pca",nComponents:5,laserExcitation:532,pipelineSteps:["whitaker_hayes","savgol","aspls","minmax"],cropLow:700,cropHigh:1800}),f=D({file:null,fileName:""}),n=D({loading:!1,error:null,doneMsg:null}),g=c(null),y=c(null),w=c([]),M=c(""),h=c(null),_=c([]),k=c(""),B=c(""),S=c(!1),V=c(null),T=m(()=>R.calculateTaskCost("raman_spy",{})),U=m(()=>R.hasEnoughQuota(T.value)),F=m(()=>l.loader==="sample"||!!f.file),K=m(()=>!!(g.value||y.value||_.value.length)),X=m(()=>({csv:".csv,.txt,.tsv",witec:".mat",ocean_insight:".txt",labspec:".txt",renishaw:".wdf"})[l.loader]||"*"),Y=m(()=>({csv:"Two-column spectrum or numeric matrix",witec:"WITec Suite .mat export",ocean_insight:"OceanView .txt",labspec:"LabSpec .txt",renishaw:"WiRE .wdf"})[l.loader]||"Select a file"),ee=m(()=>{const o=h.value?.shape;return Array.isArray(o)?o.join(" × "):"—"});function te(o){const e=o.target?.files?.[0];f.file=e||null,f.fileName=e?e.name:""}function E(o,e=640,s=220){if(!o?.length)return"";const i={l:48,r:16,t:16,b:36};let $=1/0,C=-1/0,A=1/0,L=-1/0;for(const d of o)for(let p=0;p<d.x.length;p++)$=Math.min($,d.x[p]),C=Math.max(C,d.x[p]),A=Math.min(A,d.y[p]),L=Math.max(L,d.y[p]);if(!(C>$)||!(L>A))return"";const le=e-i.l-i.r,ae=s-i.t-i.b,ne=d=>i.l+(C-d)/(C-$)*le,re=d=>i.t+(L-d)/(L-A)*ae,P=["#fb7185","#38bdf8","#a3e635","#fbbf24","#c084fc","#f472b6"];let G="";o.forEach((d,p)=>{const de=d.x.map((ue,j)=>`${j===0?"M":"L"}${ne(ue).toFixed(1)},${re(d.y[j]).toFixed(1)}`).join(" ");G+=`<path d="${de}" fill="none" stroke="${P[p%P.length]}" stroke-width="1.5"/>`});const ie=o.map((d,p)=>`<text x="${i.l+p*90}" y="14" fill="${P[p%P.length]}" font-size="11">${d.label}</text>`).join("");return`<svg xmlns="http://www.w3.org/2000/svg" width="${e}" height="${s}" viewBox="0 0 ${e} ${s}">
2    <rect width="100%" height="100%" fill="#0f172a"/>
3    ${ie}
4    ${G}
5    <text x="${e/2}" y="${s-8}" fill="#94a3b8" font-size="11" text-anchor="middle">Wavenumber (cm⁻¹)</text>
6    <text x="12" y="${s/2}" fill="#94a3b8" font-size="11" transform="rotate(-90 12 ${s/2})">Intensity</text>
7  </svg>`}const z=m(()=>{const o=[];return g.value&&o.push({label:"Before",x:g.value.wavenumber||[],y:g.value.intensity||[]}),y.value&&o.push({label:"After",x:y.value.wavenumber||[],y:y.value.intensity||[]}),E(o)}),O=m(()=>{if(!w.value.length)return"";const o=w.value.map((e,s)=>({label:`C${s+1}`,x:e.wavenumber||[],y:e.intensity||[]}));return E(o,640,240)});async function se(){if(!(!k.value||S.value)){S.value=!0;try{const o=await q.get(k.value,{responseType:"blob"}),e=new Blob([o.data],{type:"application/zip"}),s=window.URL.createObjectURL(e),i=document.createElement("a");i.href=s,i.download=B.value||"raman_spy_results.zip",document.body.appendChild(i),i.click(),document.body.removeChild(i),window.URL.revokeObjectURL(s)}catch(o){let e=o.response?.data?.error||o.message||"Download failed";if(o.response?.data instanceof Blob)try{e=JSON.parse(await o.response.data.text()).error||e}catch{}n.error=e}finally{S.value=!1}}}async function oe(){if(n.error=null,n.doneMsg=null,g.value=null,y.value=null,w.value=[],M.value="",h.value=null,_.value=[],k.value="",B.value="",V.value=null,!F.value){n.error="Select a file or use the demo loader";return}if(!U.value){n.error="Insufficient quota";return}n.loading=!0;try{const o=new FormData;o.append("loader",l.loader),o.append("protocol",l.protocol),o.append("analysis",l.analysis),o.append("n_components",String(l.nComponents)),o.append("laser_excitation",String(l.laserExcitation)),l.protocol==="custom"&&(o.append("pipeline_steps",JSON.stringify(l.pipelineSteps)),l.cropLow!=null&&l.cropHigh!=null&&o.append("crop_region",JSON.stringify([l.cropLow,l.cropHigh]))),l.loader!=="sample"&&f.file&&o.append("file",f.file);const{data:e}=await q.post("/api/raman-spy/run",o,{timeout:3e5});if(!e?.success){n.error=e?.error||"Run failed";return}h.value=e.summary||null,g.value=e.spectra_before||null,y.value=e.spectra_after||null;const s=e.analysis||{};w.value=Array.isArray(s.components)?s.components:[],M.value=s.skipped?s.skip_reason||"Analysis 
7skipped":"",_.value=Array.isArray(e.figures)?e.figures:[],k.value=e.download?.url||"",B.value=e.download?.filename||"raman_spy_results.zip",V.value=e.compute_cost,n.doneMsg=e.message||`Done · charged ${e.compute_cost} units`,await R.refreshUser?.()}catch(o){n.error=o.response?.data?.error||o.message||"Run failed"}finally{n.loading=!1}}return(o,e)=>(a(),r("div",ge,[ce(ve,{title:"RamanSPy",desc:"Preprocess and analyse Raman spectra / spectral images on the server — results appear on this page immediately. Built on RamanSPy (Georgiev et al., Anal. Chem. 2024).",color:"text-rose-400",border:"border-rose-500/50"}),t("div",ye,[t("aside",we,[e[22]||(e[22]=t("h3",{class:"text-white font-bold text-sm flex items-center"},[t("i",{class:"fa-solid fa-sliders mr-2 text-rose-400"}),x("Settings ")],-1)),t("div",null,[e[9]||(e[9]=t("label",{class:"block text-xs text-slate-400 mb-1"},"Data loader",-1)),v(t("select",{"onUpdate:modelValue":e[0]||(e[0]=s=>l.loader=s),class:"w-full bg-lab-900 border border-lab-700 rounded-lg px-3 py-2 text-white text-sm outline-none focus:border-rose-500"},[...e[8]||(e[8]=[I('<option value="sample">Built-in demo</option><option value="csv">CSV / TSV</option><option value="witec">WITec (.mat)</option><option value="ocean_insight">Ocean Insight (.txt)</option><option value="labspec">HORIBA LabSpec (.txt)</option><option value="renishaw">Renishaw (.wdf)</option>',6)])],512),[[H,l.loader]])]),t("div",null,[e[11]||(e[11]=t("label",{class:"block text-xs text-slate-400 mb-1"},"Preprocessing",-1)),v(t("select",{"onUpdate:modelValue":e[1]||(e[1]=s=>l.protocol=s),class:"w-full bg-lab-900 border border-lab-700 rounded-lg px-3 py-2 text-white text-sm outline-none focus:border-rose-500"},[...e[10]||(e[10]=[I('<option value="georgiev2023_P1">Protocol · Georgiev 2023 P1</option><option value="georgiev2023_P3">Protocol · Georgiev 2023 P3</option><option value="bergholt2016">Protocol · Bergholt 2016</option><option value="custom">Custom pipeline</option><option value="none">None</option>',5)])],512),[[H,l.protocol]])]),l.protocol==="custom"?(a(),r("div",he,[e[14]||(e[14]=t("p",{class:"text-xs text-slate-400"},"Steps (top → bottom)",-1)),(a(),r(W,null,J(Z,s=>t("label",{key:s.id,class:"flex items-center gap-2 text-sm text-slate-300 cursor-pointer"},[v(t("input",{"onUpdate:modelValue":e[2]||(e[2]=i=>l.pipelineSteps=i),type:"checkbox",value:s.id,class:"rounded border-lab-600"},null,8,_e),[[me,l.pipelineSteps]]),x(" "+u(s.label),1)])),64)),t("div",ke,[t("div",null,[e[12]||(e[12]=t("label",{class:"block text-[10px] text-slate-500 mb-0.5"},"Crop low",-1)),v(t("input",{"onUpdate:modelValue":e[3]||(e[3]=s=>l.cropLow=s),type:"number",class:"w-full bg-lab-900 border border-lab-700 rounded px-2 py-1 text-white text-xs",placeholder:"700"},null,512),[[N,l.cropLow,void 0,{number:!0}]])]),t("div",null,[e[13]||(e[13]=t("label",{class:"block text-[10px] text-slate-500 mb-0.5"},"Crop high",-1)),v(t("input",{"onUpdate:modelValue":e[4]||(e[4]=s=>l.cropHigh=s),type:"number",class:"w-full bg-lab-900 border border-lab-700 rounded px-2 py-1 text-white text-xs",placeholder:"1800"},null,512),[[N,l.cropHigh,void 0,{number:!0}]])])])])):b("",!0),t("div",null,[e[16]||(e[16]=t("label",{class:"block text-xs text-slate-400 mb-1"},"Analysis",-1)),v(t("select",{"onUpdate:modelValue":e[5]||(e[5]=s=>l.analysis=s),class:"w-full bg-lab-900 border border-lab-700 rounded-lg px-3 py-2 text-white text-sm outline-none focus:border-rose-500"},[...e[15]||(e[15]=[I('<option value="none">None (preprocess only)</option><option value="pca">PCA</option><option value="nmf">NMF</option><option value="nfindr">NFINDR unmixing</option><option value="vca">VCA unmixing</option>',5)])],512),[[H,l.analysis]])]),l.analysis!=="none"?(a(),r("div",Se,[e[17]||(e[17]=t("label",{class:"block text-xs text-slate-400 mb-1"},"Components / endmembers",-1)),v(t("input",{"onUpdate:modelValue":e[6]||(e[6]=s=>l.nComponents=s),type:"number",min:"2",max:"20",class:"w-full bg-lab-900 border border-lab-700 rounded-lg px-3 py-2 text-white text-sm outline-none focus:border-rose-500"},null,512),[[N,l.nComponents,void 0,{number:!0}]])])):b("",!0),t("div",null,[e[18]||(e[18]=t("label",{class:"block text-xs text-slate-400 mb-1"},"Laser excitation (nm)",-1)),v(t("input",{"onUpdate:modelValue":e[7]||
7(e[7]=s=>l.laserExcitation=s),type:"number",class:"w-full bg-lab-900 border border-lab-700 rounded-lg px-3 py-2 text-white text-sm outline-none focus:border-rose-500"},null,512),[[N,l.laserExcitation,void 0,{number:!0}]])]),t("div",Ce,[t("div",Le,[t("div",Re,[e[19]||(e[19]=t("i",{class:"fa-solid fa-calculator text-rose-400"},null,-1)),e[20]||(e[20]=t("span",{class:"text-slate-400"},"Cost:",-1)),t("span",Me,u(T.value)+" units",1)]),t("div",$e,[e[21]||(e[21]=t("span",{class:"text-slate-500"},"Balance:",-1)),t("span",{class:Q([U.value?"text-green-400":"text-red-400","font-bold ml-1"])},u(be(R).quotaRemaining)+" units ",3)])]),t("button",{type:"button",class:"w-full px-4 py-2.5 rounded-lg text-sm font-bold bg-rose-500 text-white hover:bg-rose-400 transition disabled:opacity-40 disabled:cursor-not-allowed",disabled:!F.value||n.loading||!U.value,onClick:oe},[n.loading?(a(),r("i",Pe)):(a(),r("i",Ne)),x(" "+u(n.loading?"Running…":"Run & visualize"),1)],8,Ae)])]),t("div",Be,[t("div",Ve,[e[23]||(e[23]=t("h3",{class:"text-white font-bold text-sm flex items-center"},[t("i",{class:"fa-solid fa-upload mr-2 text-rose-400"}),x(" Input ")],-1)),l.loader==="sample"?(a(),r("p",Ue," Demo mode: generates a synthetic spectral image when analysis is selected, or a single spectrum for preprocess-only. ")):(a(),xe(fe,{key:1,"file-name":f.fileName,color:"text-rose-400",border:"border-rose-500/40 group-hover:border-rose-500/60",accept:X.value,"hint-text":Y.value,onChange:te},null,8,["file-name","accept","hint-text"])),n.error?(a(),r("p",De,u(n.error),1)):b("",!0),n.doneMsg?(a(),r("p",He,u(n.doneMsg),1)):b("",!0)]),n.loading?(a(),r("div",Ie,[...e[24]||(e[24]=[t("i",{class:"fa-solid fa-spinner fa-spin text-rose-400 text-2xl mb-3"},null,-1),t("p",{class:"text-sm"},"Running RamanSPy on the server…",-1),t("p",{class:"text-xs text-slate-500 mt-1"},"Large images may take up to a few minutes.",-1)])])):K.value?(a(),r("div",Te,[t("div",Fe,[e[26]||(e[26]=t("h3",{class:"text-white font-bold text-sm flex items-center"},[t("i",{class:"fa-solid fa-chart-area mr-2 text-rose-400"}),x(" Results ")],-1)),k.value?(a(),r("button",{key:0,type:"button",class:"px-3 py-1.5 rounded-lg text-xs font-bold border border-rose-500/40 text-rose-300 hover:bg-rose-500/10 disabled:opacity-50",disabled:S.value,onClick:se},[t("i",{class:Q([S.value?"fa-solid fa-spinner fa-spin":"fa-solid fa-download","mr-1"])},null,2),e[25]||(e[25]=x(" Download ZIP ",-1))],8,Ee)):b("",!0)]),t("div",ze,[t("div",Oe,[e[27]||(e[27]=t("div",{class:"text-xs text-slate-500"},"Type",-1)),t("div",Ge,u(h.value?.dtype||"—"),1)]),t("div",je,[e[28]||(e[28]=t("div",{class:"text-xs text-slate-500"},"Shape",-1)),t("div",We,u(ee.value),1)]),t("div",Je,[e[29]||(e[29]=t("div",{class:"text-xs text-slate-500"},"Analysis",-1)),t("div",Qe,u(h.value?.analysis||"—"),1)]),t("div",qe,[e[30]||(e[30]=t("div",{class:"text-xs text-slate-500"},"Charged",-1)),t("div",Ze,u(V.value??"—")+" u",1)])]),z.value?(a(),r("div",Ke,[e[31]||(e[31]=t("p",{class:"text-xs text-slate-400 mb-2"},"Mean spectrum · before / after",-1)),t("div",{innerHTML:z.value,class:"min-w-[480px]"},null,8,Xe)])):b("",!0),O.value?(a(),r("div",Ye,[t("p",et,[x(" Analysis components ("+u(w.value.length)+") ",1),M.value?(a(),r("span",tt,u(M.value),1)):b("",!0)]),t("div",{innerHTML:O.value,class:"min-w-[480px]"},null,8,st)])):b("",!0),_.value.length?(a(),r("div",ot,[(a(!0),r(W,null,J(_.value,(s,i)=>(a(),r("figure",{key:i,class:"rounded-lg border border-lab-700 bg-lab-900/40 p-3"},[t("figcaption",lt,u(s.name),1),t("img",{src:s.data_url,alt:s.name,class:"w-full rounded bg-lab-950"},null,8,at)]))),128))])):b("",!0)])):b("",!0),e[32]||(e[32]=t("p",{class:"text-xs text-slate-500 leading-relaxed"},[x(" Based on "),t("a",{class:"text-rose-400 hover:underline",href:"https://github.com/barahona-research-group/RamanSPy",target:"_blank",rel:"noopener"},"RamanSPy"),x(" — "),t("a",{class:"text-rose-400 hover:underline",href:"https://doi.org/10.1021/acs.analchem.4c00383",target:"_blank",rel:"noopener"},"Georgiev et al., Analytical Chemistry 2024"),x(". Computation runs synchronously on the server and streams figures back to this page. ")],-1))])])]))}};export{ut as default};

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.