UNPKG

jsfitsio

Version:

FITS I/O javascript library.

2 lines 12.7 kB
!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define("jsfitsio",[],e):"object"==typeof exports?exports.jsfitsio=e():t.jsfitsio=e()}(this,(()=>(()=>{var t,e,r={603:()=>{}},n={};function i(t){var e=n[t];if(void 0!==e)return e.exports;var s=n[t]={exports:{}};return r[t].call(s.exports,s,s.exports,i),s.exports}i.m=r,i.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return i.d(e,{a:e}),e},i.d=(t,e)=>{for(var r in e)i.o(e,r)&&!i.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},i.f={},i.e=t=>Promise.all(Object.keys(i.f).reduce(((e,r)=>(i.f[r](t,e),e)),[])),i.u=t=>t+".js",i.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),t={},e="jsfitsio:",i.l=(r,n,s,o)=>{if(t[r])t[r].push(n);else{var a,l;if(void 0!==s)for(var c=document.getElementsByTagName("script"),u=0;u<c.length;u++){var p=c[u];if(p.getAttribute("src")==r||p.getAttribute("data-webpack")==e+s){a=p;break}}a||(l=!0,(a=document.createElement("script")).charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.setAttribute("data-webpack",e+s),a.src=r),t[r]=[n];var h=(e,n)=>{a.onerror=a.onload=null,clearTimeout(m);var i=t[r];if(delete t[r],a.parentNode&&a.parentNode.removeChild(a),i&&i.forEach((t=>t(n))),e)return e(n)},m=setTimeout(h.bind(null,void 0,{type:"timeout",target:a}),12e4);a.onerror=h.bind(null,a.onerror),a.onload=h.bind(null,a.onload),l&&document.head.appendChild(a)}},i.r=t=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},(()=>{var t;i.g.importScripts&&(t=i.g.location+"");var e=i.g.document;if(!t&&e&&(e.currentScript&&(t=e.currentScript.src),!t)){var r=e.getElementsByTagName("script");if(r.length)for(var n=r.length-1;n>-1&&(!t||!/^http(s?):/.test(t));)t=r[n--].src}if(!t)throw new Error("Automatic publicPath is not supported in this browser");t=t.replace(/#.*$/,"").replace(/\?.*$/,"").replace(/\/[^\/]+$/,"/"),i.p=t})(),(()=>{var t={202:0,924:0};i.f.j=(e,r)=>{var n=i.o(t,e)?t[e]:void 0;if(0!==n)if(n)r.push(n[2]);else{var s=new Promise(((r,i)=>n=t[e]=[r,i]));r.push(n[2]=s);var o=i.p+i.u(e),a=new Error;i.l(o,(r=>{if(i.o(t,e)&&(0!==(n=t[e])&&(t[e]=void 0),n)){var s=r&&("load"===r.type?"missing":r.type),o=r&&r.target&&r.target.src;a.message="Loading chunk "+e+" failed.\n("+s+": "+o+")",a.name="ChunkLoadError",a.type=s,a.request=o,n[1](a)}}),"chunk-"+e,e)}};var e=(e,r)=>{var n,s,[o,a,l]=r,c=0;if(o.some((e=>0!==t[e]))){for(n in a)i.o(a,n)&&(i.m[n]=a[n]);l&&l(i)}for(e&&e(r);c<o.length;c++)s=o[c],i.o(t,s)&&t[s]&&t[s][0](),t[s]=0},r=this.webpackChunkjsfitsio=this.webpackChunkjsfitsio||[];r.forEach(e.bind(null,0)),r.push=e.bind(null,r.push.bind(r))})();var s={};return(()=>{"use strict";i.r(s),i.d(s,{FITSHeaderItem:()=>t,FITSHeaderManager:()=>e,FITSParser:()=>c,FITSWriter:()=>n,ParseHeader:()=>o,ParsePayload:()=>l,ParseUtils:()=>a});class t{_key="";_value="";_comment="";constructor(t,e,r){this._key=t,this._value=e,this._comment=r}get key(){return this._key}get comment(){return this._comment}get value(){return this._value}}class e{static SIMPLE="SIMPLE";static BITPIX="BITPIX";static BZERO="BZERO";static BSCALE="BSCALE";static BLANK="BLANK";static NAXIS="NAXIS";static NAXIS1="NAXIS1";static NAXIS2="NAXIS2";static DATAMIN="DATAMIN";static DATAMAX="DATAMAX";static CRVAL1="CRVAL1";static CRVAL2="CRVAL2";static CTYPE1="CTYPE1";static CTYPE2="CTYPE2";static CRPIX1="CRPIX1";static CRPIX2="CRPIX2";static ORIGIN="ORIGIN";static COMMENT="COMMENT";items=[];constructor(){this.items[0]=new t(e.SIMPLE,"T",""),this.items[1]=new t(e.BITPIX,"",""),this.items[2]=new t(e.NAXIS,2,""),this.items[3]=new t(e.NAXIS1,"",""),this.items[4]=new t(e.NAXIS2,"","")}insert(t){t.key===e.SIMPLE?this.items[0]=t:t.key===e.BITPIX?this.items[1]=t:t.key===e.NAXIS?this.items[2]=t:t.key===e.NAXIS1?this.items[3]=t:t.key===e.NAXIS2?this.items[4]=t:this.items.push(t)}getItems(){return this.items}remove(t){this.items=this.items.filter((e=>e.key!==t))}findById(t){return this.items.find((e=>e.key===t))||null}}var r=i(603);class n{static createFITS(t){const e=this.createHeader(t.header),r=this.createData(t.data,t.header),n=new Uint8Array(e.length+r.length);return n.set(e,0),n.set(r,e.length),n}static createHeader(t){const e=2880,r=new Set(["BITPIX","NAXIS","PCOUNT","GCOUNT"]),n=new Set(["SIMPLE","EXTEND"]),i=t.getItems();function s(t){return(t??"").toUpperCase().padEnd(8," ").slice(0,8)}function o(t){return t.length>=80?t.slice(0,80):t.padEnd(80," ")}function a(t,e){const r=s(t),n=80-r.length,i=(e??"").toString();if(!i.length)return[o(r)];const a=[];for(let t=0;t<i.length;t+=n)a.push(o(r+i.slice(t,t+n)));return a}function l(t,e,i){const l=t.toUpperCase();if("END"===l)return[o("END")];if("COMMENT"===l||"HISTORY"===l)return a(l,(e??i??"").toString());let c=s(l)+function(t,e){const i=t.toUpperCase();if(n.has(i))return`= ${(!0===e||"T"===e||"t"===e?"T":"F").padStart(20," ")}`;if(r.has(i)||/^NAXIS\d+$/.test(i)){const t=Number(e);if(!Number.isFinite(t)||!Number.isInteger(t))throw new Error(`FITS header: ${i} must be an integer, got ${e}`);return`= ${String(t).padStart(20," ")}`}if("number"==typeof e){let t=Number.isInteger(e)?String(e):e.toExponential(10).replace("e","E");return t.length>20&&(t=e.toExponential(8).replace("e","E")),`= ${t.padStart(20," ")}`}return"string"==typeof e?`= '${e.replace(/^'+|'+$/g,"").replace(/'/g,"''")}'`:""}(l,e);if(i&&i.length>0){const t=` / ${i}`,e=80-c.length;if(!(e>0))return[o(c),...a("COMMENT",i)];{c+=t.slice(0,e);const r=t.slice(e).replace(/^\s*\/\s*/,"");if(r.length>0)return[o(c),...a("COMMENT",r)]}}return[o(c)]}const c=new Map(i.map((t=>[t.key.toUpperCase(),t]))),u=[],p=c.get("SIMPLE");if(!p)throw new Error("Missing mandatory SIMPLE card");u.push(...l("SIMPLE",p.value,p.comment));const h=c.get("BITPIX");if(!h)throw new Error("Missing mandatory BITPIX card");u.push(...l("BITPIX",h.value,h.comment));const m=c.get("NAXIS");if(!m)throw new Error("Missing mandatory NAXIS card");const f=Number(m.value)||0;u.push(...l("NAXIS",f,m.comment));for(let t=1;t<=f;t++){const e=`NAXIS${t}`,r=c.get(e);if(!r)throw new Error(`Missing mandatory ${e} card`);u.push(...l(e,r.value,r.comment))}const I=c.get("EXTEND");I&&u.push(...l("EXTEND",I.value,I.comment));for(const t of i){const e=t.key.toUpperCase();"SIMPLE"===e||"BITPIX"===e||"NAXIS"===e||/^NAXIS\d+$/.test(e)||"EXTEND"===e||"END"===e||u.push(...l(t.key,t.value,t.comment))}u.push(o("END"));let d=u.join("");const g=d.length%e?e-d.length%e:0;return g&&(d+=" ".repeat(g)),(new TextEncoder).encode(d)}static createData(t,e){const r=t.reduce(((t,e)=>t+e.length),0),n=Math.abs(Number(e.findById("BITPIX")?.value??0)),i=Number(e.findById("NAXIS")?.value??0);let s=1;for(let t=1;t<=i;t++)s*=Number(e.findById(`NAXIS${t}`)?.value??0);const o=i>0?s*(n/8):0;if(o&&o!==r)throw new Error(`Data length ${r} does not match header expectation ${o} (BITPIX=${n}, NAXIS=${i})`);let a=new Uint8Array(r),l=0;for(const e of t)a.set(e,l),l+=e.length;const c=a.length%2880;if(c){const t=2880-c,e=new Uint8Array(a.length+t);e.set(a),a=e}return a}static writeFITSFile(t,e){const n=this.createFITS(t);try{r.writeFileSync(e,n),console.log(`FITS file written successfully to: ${e}`)}catch(t){console.error(`Error writing FITS file: ${t}`)}}}class o{static getFITSItemValue(t,e){const r=t.findById(e);let n=null;return r&&(n=Number(r.value)),n}static parse(r){const n=new TextDecoder("ascii").decode(r.slice(0,2880)),i=new e,s=n.match(/.{1,80}/g)||[];for(const e of s){const r=e.slice(0,8).trim();let n,s="";if(r&&"END"!==r){const o=e.slice(10).trim().split("/")[0].trim();n=isNaN(Number(o))?o:Number(o),e.includes("/")&&(s=e.slice(10).trim().split("/")[1].trim());const a=new t(r,n,s);i.insert(a)}}return i}}class a{static getStringAt(t,e,r){const n=[];for(let i=e,s=0;i<e+r;i++,s++)n[s]=String.fromCharCode(255&t.charCodeAt(i));return n.join("")}static byteString(t){if(t<0||t>255||t%1!=0)throw new Error(t+" does not fit in a byte");return("000000000"+t.toString(2)).substr(-8)}static parse32bitSinglePrecisionFloatingPoint(t,e,r,n){let i=(((t<<8)+e<<8)+r<<8)+n;return i<0&&(i+=4294967296),(1+(8388607&i)/8388608)*Math.pow(2,((2139095040&i)>>23)-127)}static convertBlankToBytes(t,e){let r=Math.abs(t).toString(2);for(;r.length/8<e;)r+="0";const n=new ArrayBuffer(e),i=new Uint8Array(n);for(let t=0;t<e;t++)i[t]=parseInt(r.substr(8*t,8*(t+1)),2);return i}static parseFloatingPointFormat(t,e,r){const n=[];for(let e=t.length;e;e-=1){let r=t[e-1];for(let t=8;t;t-=1)n.push(r%2?1:0),r>>=1}n.reverse();const i=n.join(""),s=(1<<e-1)-1,o=parseInt(i.substring(0,1),2)?-1:1,a=parseInt(i.substring(1,1+e),2),l=parseInt(i.substring(1+e),2);return a===(1<<e)-1?0!==l?null:o*(1/0):a>0?o*Math.pow(2,a-s)*(1+l/Math.pow(2,r)):0!==l?o*Math.pow(2,-(s-1))*(l/Math.pow(2,r)):0*o}static generate16bit2sComplement(t){throw new TypeError("not implemented yet"+t)}static parse16bit2sComplement(t,e){const r=t<<8|e;return 32768&r?4294901760|r:r}static parse32bit2sComplement(t,e,r,n){const i=t<<24|e<<16|r<<8|n;let s=4294967295&i;return(2147483648&i)>>31?(s=1+(4294967295&~i),-1*s):s}static getByteAt(t,e){return 255&t.charCodeAt(e+0)}static extractPixelValue(t,e,r){let n=null;if(8==r)n=e[0];else if(16==r)n=a.parse16bit2sComplement(e[t],e[t+1]);else if(32==r)n=a.parse32bit2sComplement(e[t],e[t+1],e[t+2],e[t+3]);else if(-32==r)n=a.parseFloatingPointFormat(e.slice(t,t+8),8,23);else{if(64==r)throw new Error("BITPIX=64 -> 64-bit 2's complement binary integer NOT supported yet.");-64==r&&(n=a.parseFloatingPointFormat(e.slice(t,t+8),11,52))}return n}}class l{static computePhysicalMinAndMax(r,n){const i=o.getFITSItemValue(r,e.BITPIX);if(null===i)return null;const s=o.getFITSItemValue(r,e.NAXIS1);if(null===s)return null;const a=o.getFITSItemValue(r,e.NAXIS2);if(null===a)return null;const c=o.getFITSItemValue(r,e.DATAMIN),u=o.getFITSItemValue(r,e.DATAMAX);if(!i||!s||!a)return null;if(!u||!c){const[e,i]=l.computePhysicalValues(n,r);if(e&&i){const n=new t("DATAMAX",e,"computed by jsfitsio"),s=new t("DATAMIN",i,"computed by jsfitsio");r.insert(n),r.insert(s)}}const p=new t("END","","");return r.insert(p),r}static computePhysicalValues(t,r){const n=o.getFITSItemValue(r,e.BITPIX);if(null===n||isNaN(n))return[null,null];const i=o.getFITSItemValue(r,e.BLANK);if(null===i||isNaN(n))return[null,null];let s=o.getFITSItemValue(r,e.BZERO);null===s&&(s=0);let a=o.getFITSItemValue(r,e.BSCALE);null===a&&(a=1);let c=0;const u=Math.abs(n/8),p=t.byteLength/u;let h=null,m=null,f=null;for(i&&(f=l.pixel2physicalValue(i,a,s));c<p;){let e=l.extractPixelValue(t,u*c,n);if(null===e){c++;continue}let r=l.pixel2physicalValue(e,a,s);h||(h=r),m||(m=r),null!==f&&f===r||(null!==r&&(r<h||null===h)&&(h=r),null!==r&&(r>m||null===m)&&(m=r)),c++}return[h,m]}static pixel2physicalValue(t,e,r){if(null===r||null===e)throw new Error("Either BZERO or BSCALE is null");return r+e*t}static extractPixelValue(t,e,r){let n=null;if(16==r)n=a.parse16bit2sComplement(t[e],t[e+1]);else if(32==r)n=a.parse32bit2sComplement(t[e],t[e+1],t[e+2],t[e+3]);else if(-32==r)n=a.parseFloatingPointFormat(t.slice(e,e+4),8,23);else{if(64==r)throw new Error("BITPIX=64 -> 64-bit 2's complement binary integer NOT supported yet.");-64==r&&(n=a.parseFloatingPointFormat(t.slice(e,e+8),11,52))}return n}}class c{static async loadFITS(t){try{const e=await c.getFile(t);if(e?.byteLength)return c.processFits(e)}catch(t){console.error("Error loading FITS file:",t)}return null}static processFits(t){const e=o.parse(t),r=l.computePhysicalMinAndMax(e,t);if(null==r)return null;const n=function(t){const e=t.length%2880;if(0===e)return t;const r=new Uint8Array(t.length+(2880-e));return r.set(t),r}(new Uint8Array(t.slice(2880)));return{header:r,data:c.createMatrix(n,e)}}static createMatrix(t,r){const n=o.getFITSItemValue(r,e.NAXIS1);if(null===n)throw new Error("NAXIS1 not defined.");const i=o.getFITSItemValue(r,e.NAXIS2);if(null===i)throw new Error("NAXIS2 not defined.");const s=o.getFITSItemValue(r,e.BITPIX);if(null===s)throw new Error("BITPIX not defined.");const a=Math.abs(s/8),l=[];for(let e=0;e<i;e++)l.push(t.slice(e*n*a,(e+1)*n*a));return l}static saveFITSLocally(t,e){return n.writeFITSFile(t,e)}static async getFile(t){if(t.substring(0,5).toLowerCase().includes("http")){const e=await i.e(646).then(i.bind(i,646)),r=await e.getFile(t);return r?.byteLength?new Uint8Array(r):new Uint8Array(0)}{const e=await i.e(483).then(i.bind(i,483)),r=await e.getLocalFile(t);return r?.length?new Uint8Array(r):new Uint8Array(0)}}}})(),s})())); //# sourceMappingURL=jsfitsio.js.map