{"version":3,"file":"spectrum-generator.min.js","sources":["../node_modules/ml-peak-shape-generator/src/util/constants.js","../node_modules/ml-peak-shape-generator/src/util/erfinv.js","../node_modules/ml-peak-shape-generator/src/classes/Gaussian.js","../node_modules/ml-peak-shape-generator/src/classes/Lorentzian.js","../node_modules/ml-peak-shape-generator/src/classes/PseudoVoigt.js","../node_modules/ml-peak-shape-generator/src/classes/Gaussian2D.js","../node_modules/ml-peak-shape-generator/src/util/getShapeGenerator.js","../node_modules/d3-random/src/defaultSource.js","../node_modules/d3-random/src/uniform.js","../node_modules/d3-random/src/normal.js","../node_modules/ml-xsadd/lib-es6/xsadd.js","../src/util/addNoise.js","../src/index.js","../src/util/addBaseline.js"],"sourcesContent":["export const GAUSSIAN_EXP_FACTOR = -4 * Math.LN2;\nexport const ROOT_PI_OVER_LN2 = Math.sqrt(Math.PI / Math.LN2);\nexport const ROOT_THREE = Math.sqrt(3);\nexport const ROOT_2LN2 = Math.sqrt(2 * Math.LN2);\nexport const ROOT_2LN2_MINUS_ONE = Math.sqrt(2 * Math.LN2) - 1;\n","// https://en.wikipedia.org/wiki/Error_function#Inverse_functions\n// This code yields to a good approximation\n\n// If needed a better implementation using polynomial can be found on https://en.wikipedia.org/wiki/Error_function#Inverse_functions\n\nexport default function erfinv(x) {\n  let a = 0.147;\n  if (x === 0) return 0;\n  let ln1MinusXSqrd = Math.log(1 - x * x);\n  let lnEtcBy2Plus2 = ln1MinusXSqrd / 2 + 2 / (Math.PI * a);\n  let firstSqrt = Math.sqrt(lnEtcBy2Plus2 ** 2 - ln1MinusXSqrd / a);\n  let secondSqrt = Math.sqrt(firstSqrt - lnEtcBy2Plus2);\n  return secondSqrt * (x > 0 ? 1 : -1);\n}\n","import {\n  ROOT_2LN2,\n  GAUSSIAN_EXP_FACTOR,\n  ROOT_PI_OVER_LN2,\n} from '../util/constants';\nimport erfinv from '../util/erfinv';\n\nexport class Gaussian {\n  /**\n   * @param {object} [options = {}]\n   * @param {number} [options.height=4*LN2/(PI*FWHM)] Define the height of the peak, by default area=1 (normalized)\n   * @param {number} [options.fwhm = 500] - Full Width at Half Maximum in the number of points in FWHM.\n   * @param {number} [options.sd] - Standard deviation, if it's defined options.fwhm will be ignored and the value will be computed sd * Math.sqrt(8 * Math.LN2);\n   */\n  constructor(options = {}) {\n    this.fwhm = options.sd\n      ? Gaussian.widthToFWHM(2 * options.sd)\n      : options.fwhm\n      ? options.fwhm\n      : 500;\n    this.height =\n      options.height === undefined\n        ? Math.sqrt(-GAUSSIAN_EXP_FACTOR / Math.PI) / this.fwhm\n        : options.height;\n  }\n  /**\n   * Calculate a gaussian shape\n   * @param {object} [options = {}]\n   * @param {number} [options.factor = 6] - Number of time to take fwhm to calculate length. Default covers 99.99 % of area.\n   * @param {number} [options.length = fwhm * factor + 1] - total number of points to calculate\n   * @return {Float64Array} y values\n   */\n\n  getData(options = {}) {\n    let { length, factor = this.getFactor() } = options;\n\n    if (!length) {\n      length = Math.min(Math.ceil(this.fwhm * factor), Math.pow(2, 25) - 1);\n      if (length % 2 === 0) length++;\n    }\n\n    const center = (length - 1) / 2;\n    const data = new Float64Array(length);\n    for (let i = 0; i <= center; i++) {\n      data[i] = this.fct(i - center) * this.height;\n      data[length - 1 - i] = data[i];\n    }\n\n    return data;\n  }\n\n  /**\n   * Return a parameterized function of a gaussian shape (see README for equation).\n   * @param {number} x - x value to calculate.\n   * @returns {number} - the y value of gaussian with the current parameters.\n   */\n  fct(x) {\n    return Gaussian.fct(x, this.fwhm);\n  }\n\n  /**\n   * Calculate the number of times FWHM allows to reach a specific area coverage\n   * @param {number} [area=0.9999]\n   * @returns {number}\n   */\n  getFactor(area = 0.9999) {\n    return Gaussian.getFactor(area);\n  }\n\n  /**\n   * Calculate the area of the shape.\n   * @returns {number} - returns the area.\n   */\n\n  getArea() {\n    return Gaussian.getArea(this.fwhm, { height: this.height });\n  }\n\n  /**\n   * Compute the value of Full Width at Half Maximum (FWHM) from the width between the inflection points.\n   * //https://mathworld.wolfram.com/GaussianFunction.html\n   * @param {number} width - Width between the inflection points\n   * @returns {number} fwhm\n   */\n  widthToFWHM(width) {\n    //https://mathworld.wolfram.com/GaussianFunction.html\n    return Gaussian.widthToFWHM(width);\n  }\n\n  /**\n   * Compute the value of width between the inflection points from Full Width at Half Maximum (FWHM).\n   * //https://mathworld.wolfram.com/GaussianFunction.html\n   * @param {number} fwhm - Full Width at Half Maximum.\n   * @returns {number} width\n   */\n  fwhmToWidth(fwhm = this.fwhm) {\n    return Gaussian.fwhmToWidth(fwhm);\n  }\n\n  /**\n   * set a new full width at half maximum\n   * @param {number} fwhm - full width at half maximum\n   */\n  setFWHM(fwhm) {\n    this.fwhm = fwhm;\n  }\n\n  /**\n   * set a new height\n   * @param {number} height - The maximal intensity of the shape.\n   */\n  setHeight(height) {\n    this.height = height;\n  }\n}\n\n/**\n * Return a parameterized function of a gaussian shape (see README for equation).\n * @param {number} x - x value to calculate.\n * @param {number} fwhm - full width half maximum\n * @returns {number} - the y value of gaussian with the current parameters.\n */\nGaussian.fct = function fct(x, fwhm = 500) {\n  return Math.exp(GAUSSIAN_EXP_FACTOR * Math.pow(x / fwhm, 2));\n};\n\n/**\n * Compute the value of Full Width at Half Maximum (FWHM) from the width between the inflection points.\n * //https://mathworld.wolfram.com/GaussianFunction.html\n * @param {number} width - Width between the inflection points\n * @returns {number} fwhm\n */\nGaussian.widthToFWHM = function widthToFWHM(width) {\n  return width * ROOT_2LN2;\n};\n\n/**\n * Compute the value of width between the inflection points from Full Width at Half Maximum (FWHM).\n * //https://mathworld.wolfram.com/GaussianFunction.html\n * @param {number} fwhm - Full Width at Half Maximum.\n * @returns {number} width\n */\nGaussian.fwhmToWidth = function fwhmToWidth(fwhm) {\n  return fwhm / ROOT_2LN2;\n};\n\n/**\n * Calculate the area of a specific shape.\n * @param {number} fwhm - Full width at half maximum.\n * @param {object} [options = {}] - options.\n * @param {number} [options.height = 1] - Maximum y value of the shape.\n * @returns {number} - returns the area of the specific shape and parameters.\n */\n\nGaussian.getArea = function getArea(fwhm, options = {}) {\n  let { height = 1 } = options;\n  return (height * ROOT_PI_OVER_LN2 * fwhm) / 2;\n};\n\n/**\n * Calculate the number of times FWHM allows to reach a specific area coverage.\n * @param {number} [area=0.9999]\n * @returns {number}\n */\nGaussian.getFactor = function getFactor(area = 0.9999) {\n  return Math.sqrt(2) * erfinv(area);\n};\n","import { ROOT_THREE } from '../util/constants';\n\nexport class Lorentzian {\n  /**\n   * @param {object} [options = {}]\n   * @param {number} [options.height=2/(PI*FWHM)] Define the height of the peak, by default area=1 (normalized)\n   * @param {number} [options.fwhm = 500] - Full Width at Half Maximum in the number of points in FWHM.\n   * @param {number} [options.sd] - Standard deviation, if it's defined options.fwhm will be ignored and the value will be computed sd * Math.sqrt(8 * Math.LN2);\n   */\n  constructor(options = {}) {\n    this.fwhm = options.fwhm === undefined ? 500 : options.fwhm;\n    this.height =\n      options.height === undefined ? 2 / Math.PI / this.fwhm : options.height;\n  }\n  /**\n   * Calculate a lorentzian shape\n   * @param {object} [options = {}]\n   * @param {number} [options.factor = Math.tan(Math.PI * (0.9999 - 0.5))] - Number of time to take fwhm to calculate length. Default covers 99.99 % of area.\n   * @param {number} [options.length = fwhm * factor + 1] - total number of points to calculate\n   * @return {Float64Array} y values\n   */\n  getData(options = {}) {\n    let { length, factor = this.getFactor() } = options;\n\n    if (!length) {\n      length = Math.min(Math.ceil(this.fwhm * factor), Math.pow(2, 25) - 1);\n      if (length % 2 === 0) length++;\n    }\n\n    const center = (length - 1) / 2;\n    const data = new Float64Array(length);\n    for (let i = 0; i <= center; i++) {\n      data[i] = this.fct(i - center) * this.height;\n      data[length - 1 - i] = data[i];\n    }\n    return data;\n  }\n\n  /**\n   * Return a parameterized function of a lorentzian shape (see README for equation).\n   * @param {number} x - x value to calculate.\n   * @returns {number} - the y value of lorentzian with the current parameters.\n   */\n  fct(x) {\n    return Lorentzian.fct(x, this.fwhm);\n  }\n\n  /**\n   * Calculate the number of times FWHM allows to reach a specific area coverage\n   * @param {number} [area=0.9999]\n   * @returns {number}\n   */\n  getFactor(area = 0.9999) {\n    return Lorentzian.getFactor(area);\n  }\n\n  /**\n   * Calculate the area of the shape.\n   * @returns {number} - returns the area.\n   */\n\n  getArea() {\n    return Lorentzian.getArea(this.fwhm, { height: this.height });\n  }\n\n  /**\n   * Compute the value of width between the inflection points of a specific shape from Full Width at Half Maximum (FWHM).\n   * //https://mathworld.wolfram.com/LorentzianFunction.html\n   * @param {number} [fwhm] - Full Width at Half Maximum.\n   * @returns {number} width between the inflection points\n   */\n  fwhmToWidth(fwhm = this.fwhm) {\n    return Lorentzian.fwhmToWidth(fwhm);\n  }\n\n  /**\n   * Compute the value of Full Width at Half Maximum (FWHM) of a specific shape from the width between the inflection points.\n   * //https://mathworld.wolfram.com/LorentzianFunction.html\n   * @param {number} [width] Width between the inflection points\n   * @returns {number} fwhm\n   */\n  widthToFWHM(width) {\n    return Lorentzian.widthToFWHM(width);\n  }\n  /**\n   * set a new full width at half maximum\n   * @param {number} fwhm - full width at half maximum\n   */\n  setFWHM(fwhm) {\n    this.fwhm = fwhm;\n  }\n\n  /**\n   * set a new height\n   * @param {number} height - The maximal intensity of the shape.\n   */\n  setHeight(height) {\n    this.height = height;\n  }\n}\n\n/**\n * Return a parameterized function of a gaussian shape (see README for equation).\n * @param {number} x - x value to calculate.\n * @param {number} fwhm - full width half maximum\n * @returns {number} - the y value of gaussian with the current parameters.\n */\nLorentzian.fct = function fct(x, fwhm) {\n  const squareFWHM = fwhm * fwhm;\n  return squareFWHM / (4 * Math.pow(x, 2) + squareFWHM);\n};\n\n/**\n * Compute the value of width between the inflection points of a specific shape from Full Width at Half Maximum (FWHM).\n * //https://mathworld.wolfram.com/LorentzianFunction.html\n * @param {number} [fwhm] - Full Width at Half Maximum.\n * @returns {number} width between the inflection points\n */\nLorentzian.fwhmToWidth = function fwhmToWidth(fwhm) {\n  return fwhm / ROOT_THREE;\n};\n\n/**\n * Compute the value of Full Width at Half Maximum (FWHM) of a specific shape from the width between the inflection points.\n * //https://mathworld.wolfram.com/LorentzianFunction.html\n * @param {number} [width] Width between the inflection points\n * @returns {number} fwhm\n */\nLorentzian.widthToFWHM = function widthToFWHM(width) {\n  return width * ROOT_THREE;\n};\n\n/**\n * Calculate the area of a specific shape.\n * @param {number} fwhm - Full width at half maximum.\n * @param {*} [options = {}] - options.\n * @param {number} [options.height = 1] - Maximum y value of the shape.\n * @returns {number} - returns the area of the specific shape and parameters.\n */\nLorentzian.getArea = function getArea(fwhm, options = {}) {\n  let { height = 1 } = options;\n\n  return (height * Math.PI * fwhm) / 2;\n};\n\n/**\n * Calculate the number of times FWHM allows to reach a specific area coverage\n * @param {number} [area=0.9999]\n * @returns {number}\n */\nLorentzian.getFactor = function getFactor(area = 0.9999) {\n  return 2 * Math.tan(Math.PI * (area - 0.5));\n};\n","import {\n  GAUSSIAN_EXP_FACTOR,\n  ROOT_2LN2_MINUS_ONE,\n  ROOT_PI_OVER_LN2,\n} from '../util/constants';\n\nimport { Gaussian } from './Gaussian';\nimport { Lorentzian } from './Lorentzian';\n\nexport class PseudoVoigt {\n  /**\n   * @param {object} [options={}]\n   * @param {number} [options.height=1/(mu*FWHM/sqrt(4*LN2/PI)+(1-mu)*fwhm*PI*0.5)] Define the height of the peak, by default area=1 (normalized)\n   * @param {number} [options.fwhm=500] - Full Width at Half Maximum in the number of points in FWHM.\n   * @param {number} [options.mu=0.5] - ratio of gaussian contribution.\n   */\n\n  constructor(options = {}) {\n    this.mu = options.mu === undefined ? 0.5 : options.mu;\n    this.fwhm = options.fwhm === undefined ? 500 : options.fwhm;\n    this.height =\n      options.height === undefined\n        ? 1 /\n          ((this.mu / Math.sqrt(-GAUSSIAN_EXP_FACTOR / Math.PI)) * this.fwhm +\n            ((1 - this.mu) * this.fwhm * Math.PI) / 2)\n        : options.height;\n  }\n\n  /**\n   * Calculate a linear combination of gaussian and lorentzian function width an same full width at half maximum\n   * @param { object } [options = {}]\n   * @param { number } [options.factor = 2 * Math.tan(Math.PI * (0.9999 - 0.5))] - Number of time to take fwhm in the calculation of the length.Default covers 99.99 % of area.\n   * @param { number } [options.length = fwhm * factor + 1] - total number of points to calculate\n   * @return { object } - { fwhm, data<Float64Array>} - An with the number of points at half maximum and the array of y values covering the 99.99 % of the area.\n   */\n\n  getData(options = {}) {\n    let { length, factor = this.getFactor() } = options;\n    if (!length) {\n      length = Math.ceil(this.fwhm * factor);\n      if (length % 2 === 0) length++;\n    }\n\n    const center = (length - 1) / 2;\n\n    let data = new Float64Array(length);\n    for (let i = 0; i <= center; i++) {\n      data[i] = this.fct(i - center) * this.height;\n      data[length - 1 - i] = data[i];\n    }\n\n    return data;\n  }\n\n  /**\n   * Return a parameterized function of a linear combination of Gaussian and Lorentzian shapes where the full width at half maximum are the same for both kind of shapes (see README for equation).\n   * @param {number} [x] x value to calculate.\n   * @returns {number} - the y value of a pseudo voigt with the current parameters.\n   */\n\n  fct(x) {\n    return PseudoVoigt.fct(x, this.fwhm, this.mu);\n  }\n\n  /**\n   * Calculate the number of times FWHM allows to reach a specific area coverage\n   * @param {number} [area=0.9999] - required area to be coverage\n   * @param {number} [mu=this.mu] - ratio of gaussian contribution.\n   * @returns {number}\n   */\n  getFactor(area = 0.9999, mu = this.mu) {\n    return PseudoVoigt.getFactor(area, mu);\n  }\n\n  /**\n   * Calculate the area of the shape.\n   * @returns {number} - returns the area.\n   */\n  getArea() {\n    return PseudoVoigt.getArea(this.fwhm, { height: this.height, mu: this.mu });\n  }\n\n  /**\n   * Compute the value of Full Width at Half Maximum (FMHM) from width between the inflection points.\n   * @param {number} width - width between the inflection points\n   * @param {number} [mu = 0.5] - ratio of gaussian contribution.\n   * @returns {number} Full Width at Half Maximum (FMHM).\n   */\n  widthToFWHM(width, mu) {\n    return PseudoVoigt.widthToFWHM(width, mu);\n  }\n  /**\n   * Compute the value of width between the inflection points from Full Width at Half Maximum (FWHM).\n   * @param {number} fwhm - Full Width at Half Maximum.\n   * @param {number} [mu] - ratio of gaussian contribution.\n   * @returns {number} width between the inflection points.\n   */\n  fwhmToWidth(fwhm = this.fwhm, mu = this.mu) {\n    return PseudoVoigt.fwhmToWidth(fwhm, mu);\n  }\n\n  /**\n   * set a new full width at half maximum\n   * @param {number} fwhm - full width at half maximum\n   */\n  setFWHM(fwhm) {\n    this.fwhm = fwhm;\n  }\n\n  /**\n   * set a new height\n   * @param {number} height - The maximal intensity of the shape.\n   */\n  setHeight(height) {\n    this.height = height;\n  }\n\n  /**\n   * set a new mu\n   * @param {number} mu - ratio of gaussian contribution.\n   */\n  setMu(mu) {\n    this.mu = mu;\n  }\n}\n\n/**\n * Return a parameterized function of a gaussian shape (see README for equation).\n * @param {number} x - x value to calculate.\n * @param {number} fwhm - full width half maximum\n * @param {number} [mu=0.5] - ratio of gaussian contribution.\n * @returns {number} - the y value of gaussian with the current parameters.\n */\nPseudoVoigt.fct = function fct(x, fwhm, mu = 0.5) {\n  return (1 - mu) * Lorentzian.fct(x, fwhm) + mu * Gaussian.fct(x, fwhm);\n};\n\n/**\n * Compute the value of Full Width at Half Maximum (FMHM) from width between the inflection points.\n * @param {number} width - width between the inflection points\n * @param {number} [mu = 0.5] - ratio of gaussian contribution.\n * @returns {number} Full Width at Half Maximum (FMHM).\n */\nPseudoVoigt.widthToFWHM = function widthToFWHM(width, mu = 0.5) {\n  return width * (mu * ROOT_2LN2_MINUS_ONE + 1);\n};\n/**\n * Compute the value of width between the inflection points from Full Width at Half Maximum (FWHM).\n * @param {number} fwhm - Full Width at Half Maximum.\n * @param {number} [mu = 0.5] - ratio of gaussian contribution.\n * @returns {number} width between the inflection points.\n */\nPseudoVoigt.fwhmToWidth = function fwhmToWidth(fwhm, mu = 0.5) {\n  return fwhm / (mu * ROOT_2LN2_MINUS_ONE + 1);\n};\n\n/**\n * Calculate the area of a specific shape.\n * @param {number} fwhm - Full width at half maximum.\n * @param {*} [options = {}] - options.\n * @param {number} [options.height = 1] - Maximum y value of the shape.\n * @param {number} [options.mu = 0.5] - ratio of gaussian contribution.\n * @returns {number} - returns the area of the specific shape and parameters.\n */\nPseudoVoigt.getArea = function getArea(fwhm, options = {}) {\n  let { height = 1, mu = 0.5 } = options;\n  return (fwhm * height * (mu * ROOT_PI_OVER_LN2 + (1 - mu) * Math.PI)) / 2;\n};\n\n/**\n * Calculate the number of times FWHM allows to reach a specific area coverage\n * @param {number} [area=0.9999] - required area to be coverage\n * @param {number} [mu=this.mu] - ratio of gaussian contribution.\n * @returns {number}\n */\nPseudoVoigt.getFactor = function getFactor(area = 0.9999, mu = 0.5) {\n  return mu < 1 ? Lorentzian.getFactor(area) : Gaussian.getFactor(area);\n};\n","import { ROOT_2LN2, GAUSSIAN_EXP_FACTOR } from '../util/constants';\nimport erfinv from '../util/erfinv';\n\nlet axis = ['x', 'y'];\n\nexport class Gaussian2D {\n  /**\n   * @param {object} [options = {}]\n   * @param {number} [options.height=4*LN2/(PI*xFWHM*yFWHM)] Define the height of the peak, by default area=1 (normalized).\n   * @param {number} [options.fwhm = 500] - Full Width at Half Maximum in the number of points in FWHM used if x or y has not the fwhm property.\n   * @param {object} [options.x] - Options for x axis.\n   * @param {number} [options.x.fwhm = fwhm] - Full Width at Half Maximum in the number of points in FWHM for x axis.\n   * @param {number} [options.x.sd] - Standard deviation for x axis, if it's defined options.x.fwhm will be ignored and the value will be computed sd * Math.sqrt(8 * Math.LN2);\n   * @param {object} [options.y] - Options for y axis.\n   * @param {number} [options.y.fwhm = fwhm] - Full Width at Half Maximum in the number of points in FWHM for y axis.\n   * @param {number} [options.y.sd] - Standard deviation for y axis, if it's defined options.y.fwhm will be ignored and the value will be computed sd * Math.sqrt(8 * Math.LN2);\n   */\n  constructor(options = {}) {\n    let { fwhm: globalFWHM = 500 } = options;\n\n    for (let i of axis) {\n      let fwhm;\n      if (!options[i]) {\n        fwhm = globalFWHM;\n      } else {\n        fwhm = options[i].sd\n          ? Gaussian2D.widthToFWHM(2 * options[i].sd)\n          : options[i].fwhm || globalFWHM;\n      }\n      this[i] = { fwhm };\n    }\n\n    this.height =\n      options.height === undefined\n        ? -GAUSSIAN_EXP_FACTOR / Math.PI / this.x.fwhm / this.y.fwhm\n        : options.height;\n  }\n  /**\n   * Calculate a Gaussian2D shape\n   * @param {object} [options = {}]\n   * @param {number} [options.factor] - Number of time to take fwhm to calculate length. Default covers 99.99 % of area.\n   * @param {object} [options.x] - parameter for x axis.\n   * @param {number} [options.x.length=fwhm*factor+1] - length on x axis.\n   * @param {number} [options.x.factor=factor] - Number of time to take fwhm to calculate length. Default covers 99.99 % of area.\n   * @param {object} [options.y] - parameter for y axis.\n   * @param {number} [options.y.length=fwhm*factor+1] - length on y axis.\n   * @param {number} [options.y.factor=factor] - Number of time to take fwhm to calculate length. Default covers 99.99 % of area.\n   * @return {Array<Float64Array>} - z values.\n   */\n\n  getData(options = {}) {\n    let { x = {}, y = {}, factor = this.getFactor(), length } = options;\n\n    let xLength = x.length || length;\n    if (!xLength) {\n      let { factor: xFactor = factor } = x;\n      xLength = Math.min(Math.ceil(this.x.fwhm * xFactor), Math.pow(2, 25) - 1);\n      if (xLength % 2 === 0) xLength++;\n    }\n\n    let yLength = y.length || length;\n    if (!yLength) {\n      let { factor: yFactor = factor } = y;\n      yLength = Math.min(Math.ceil(this.y.fwhm * yFactor), Math.pow(2, 25) - 1);\n      if (yLength % 2 === 0) yLength++;\n    }\n\n    const xCenter = (xLength - 1) / 2;\n    const yCenter = (yLength - 1) / 2;\n    const data = new Array(xLength);\n    for (let i = 0; i < xLength; i++) {\n      data[i] = new Array(yLength);\n    }\n\n    for (let i = 0; i < xLength; i++) {\n      for (let j = 0; j < yLength; j++) {\n        data[i][j] = this.fct(i - xCenter, j - yCenter) * this.height;\n      }\n    }\n\n    return data;\n  }\n\n  /**\n   * Return the intensity value of a 2D gaussian shape (see README for equation).\n   * @param {number} x - x value to calculate.\n   * @param {number} y - y value to calculate.\n   * @returns {number} - the z value of bi-dimensional gaussian with the current parameters.\n   */\n  fct(x, y) {\n    return Gaussian2D.fct(x, y, this.x.fwhm, this.y.fwhm);\n  }\n\n  /**\n   * Calculate the number of times FWHM allows to reach a specific volume coverage.\n   * @param {number} [volume=0.9999]\n   * @returns {number}\n   */\n  getFactor(volume = 0.9999) {\n    return Gaussian2D.getFactor(volume);\n  }\n\n  /**\n   * Calculate the volume of the shape.\n   * @returns {number} - returns the volume.\n   */\n\n  getVolume() {\n    return Gaussian2D.getVolume(this.x.fwhm, this.y.fwhm, {\n      height: this.height,\n    });\n  }\n\n  /**\n   * Compute the value of Full Width at Half Maximum (FWHM) from the width between the inflection points.\n   * //https://mathworld.wolfram.com/Gaussian2DFunction.html\n   * @param {number} width - Width between the inflection points\n   * @returns {number} fwhm\n   */\n  widthToFWHM(width) {\n    //https://mathworld.wolfram.com/Gaussian2DFunction.html\n    return Gaussian2D.widthToFWHM(width);\n  }\n\n  /**\n   * Compute the value of width between the inflection points from Full Width at Half Maximum (FWHM).\n   * //https://mathworld.wolfram.com/Gaussian2DFunction.html\n   * @param {number} fwhm - Full Width at Half Maximum.\n   * @returns {number} width\n   */\n  fwhmToWidth(fwhm = this.x.fwhm) {\n    return Gaussian2D.fwhmToWidth(fwhm);\n  }\n\n  /**\n   * set a new full width at half maximum\n   * @param {number} fwhm - full width at half maximum\n   * @param {string|Array<string>} axisLabel - label of axis, if it is undefined fwhm is set to both axis.\n   */\n  setFWHM(fwhm, axisLabel) {\n    if (!axisLabel) axisLabel = axis;\n    if (!Array.isArray(axisLabel)) axisLabel = [axisLabel];\n    for (let i of axisLabel) {\n      let axisName = i.toLowerCase();\n      if (axisName !== 'y' && axisName !== 'x') {\n        throw new Error('axis label should be x or y');\n      }\n      this[axisName].fwhm = fwhm;\n    }\n  }\n\n  /**\n   * set a new height\n   * @param {number} height - The maximal intensity of the shape.\n   */\n  setHeight(height) {\n    this.height = height;\n  }\n}\n\n/**\n * Return a parameterized function of a Gaussian2D shape (see README for equation).\n * @param {number} x - x value to calculate.\n * @param {number} y - y value to calculate.\n * @param {number} fwhmX - full width half maximum in the x axis.\n * @param {number} fwhmY - full width half maximum in the y axis.\n * @returns {number} - the z value of bi-dimensional gaussian with the current parameters.\n */\nGaussian2D.fct = function fct(x, y, xFWHM = 500, yFWHM = 500) {\n  return Math.exp(\n    GAUSSIAN_EXP_FACTOR * (Math.pow(x / xFWHM, 2) + Math.pow(y / yFWHM, 2)),\n  );\n};\n\n/**\n * Compute the value of Full Width at Half Maximum (FWHM) from the width between the inflection points.\n * //https://mathworld.wolfram.com/Gaussian2DFunction.html\n * @param {number} width - Width between the inflection points\n * @returns {number} fwhm\n */\nGaussian2D.widthToFWHM = function widthToFWHM(width) {\n  return width * ROOT_2LN2;\n};\n\n/**\n * Compute the value of width between the inflection points from Full Width at Half Maximum (FWHM).\n * //https://mathworld.wolfram.com/Gaussian2DFunction.html\n * @param {number} fwhm - Full Width at Half Maximum.\n * @returns {number} width\n */\nGaussian2D.fwhmToWidth = function fwhmToWidth(fwhm) {\n  return fwhm / ROOT_2LN2;\n};\n\n/**\n * Calculate the volume of a specific shape.\n * @param {number} xFWHM - Full width at half maximum for x axis.\n * @param {number} yFWHM - Full width at half maximum for y axis.\n * @param {object} [options = {}] - options.\n * @param {number} [options.height = 1] - Maximum z value of the shape.\n * @returns {number} - returns the area of the specific shape and parameters.\n */\n\nGaussian2D.getVolume = function getVolume(xFWHM, yFWHM, options = {}) {\n  let { height = 1 } = options;\n  return (height * Math.PI * xFWHM * yFWHM) / Math.LN2 / 4;\n};\n\n/**@TODO look for a better factor\n * Calculate the number of times FWHM allows to reach a specific volume coverage.\n * @param {number} [volume=0.9999]\n * @returns {number}\n */\nGaussian2D.getFactor = function getFactor(volume = 0.9999) {\n  return Math.sqrt(2) * erfinv(volume);\n};\n","import { Gaussian } from '../classes/Gaussian';\nimport { Gaussian2D } from '../classes/Gaussian2D';\nimport { Lorentzian } from '../classes/Lorentzian';\nimport { PseudoVoigt } from '../classes/PseudoVoigt';\n\nexport function getShapeGenerator(options) {\n  let { kind = 'Gaussian', options: shapeOptions } = options;\n  switch (kind.toLowerCase().replace(/[^a-z^0-9]/g, '')) {\n    case 'gaussian':\n      return new Gaussian(shapeOptions);\n    case 'lorentzian':\n      return new Lorentzian(shapeOptions);\n    case 'pseudovoigt':\n      return new PseudoVoigt(shapeOptions);\n    case 'gaussian2d':\n      return new Gaussian2D(shapeOptions);\n    default:\n      throw new Error(`Unknown kind: ${kind}`);\n  }\n}\n","export default Math.random;\n","import defaultSource from \"./defaultSource.js\";\n\nexport default (function sourceRandomUniform(source) {\n  function randomUniform(min, max) {\n    min = min == null ? 0 : +min;\n    max = max == null ? 1 : +max;\n    if (arguments.length === 1) max = min, min = 0;\n    else max -= min;\n    return function() {\n      return source() * max + min;\n    };\n  }\n\n  randomUniform.source = sourceRandomUniform;\n\n  return randomUniform;\n})(defaultSource);\n","import defaultSource from \"./defaultSource.js\";\n\nexport default (function sourceRandomNormal(source) {\n  function randomNormal(mu, sigma) {\n    var x, r;\n    mu = mu == null ? 0 : +mu;\n    sigma = sigma == null ? 1 : +sigma;\n    return function() {\n      var y;\n\n      // If available, use the second previously-generated uniform random.\n      if (x != null) y = x, x = null;\n\n      // Otherwise, generate a new x and y.\n      else do {\n        x = source() * 2 - 1;\n        y = source() * 2 - 1;\n        r = x * x + y * y;\n      } while (!r || r > 1);\n\n      return mu + sigma * y * Math.sqrt(-2 * Math.log(r) / r);\n    };\n  }\n\n  randomNormal.source = sourceRandomNormal;\n\n  return randomNormal;\n})(defaultSource);\n","const LOOP = 8;\nconst FLOAT_MUL = 1 / 16777216;\nconst sh1 = 15;\nconst sh2 = 18;\nconst sh3 = 11;\nfunction multiply_uint32(n, m) {\n    n >>>= 0;\n    m >>>= 0;\n    const nlo = n & 0xffff;\n    const nhi = n - nlo;\n    return (((nhi * m) >>> 0) + nlo * m) >>> 0;\n}\nexport default class XSadd {\n    constructor(seed = Date.now()) {\n        this.state = new Uint32Array(4);\n        this.init(seed);\n        this.random = this.getFloat.bind(this);\n    }\n    /**\n     * Returns a 32-bit integer r (0 <= r < 2^32)\n     */\n    getUint32() {\n        this.nextState();\n        return (this.state[3] + this.state[2]) >>> 0;\n    }\n    /**\n     * Returns a floating point number r (0.0 <= r < 1.0)\n     */\n    getFloat() {\n        return (this.getUint32() >>> 8) * FLOAT_MUL;\n    }\n    init(seed) {\n        if (!Number.isInteger(seed)) {\n            throw new TypeError('seed must be an integer');\n        }\n        this.state[0] = seed;\n        this.state[1] = 0;\n        this.state[2] = 0;\n        this.state[3] = 0;\n        for (let i = 1; i < LOOP; i++) {\n            this.state[i & 3] ^=\n                (i +\n                    multiply_uint32(1812433253, this.state[(i - 1) & 3] ^ ((this.state[(i - 1) & 3] >>> 30) >>> 0))) >>>\n                    0;\n        }\n        this.periodCertification();\n        for (let i = 0; i < LOOP; i++) {\n            this.nextState();\n        }\n    }\n    periodCertification() {\n        if (this.state[0] === 0 &&\n            this.state[1] === 0 &&\n            this.state[2] === 0 &&\n            this.state[3] === 0) {\n            this.state[0] = 88; // X\n            this.state[1] = 83; // S\n            this.state[2] = 65; // A\n            this.state[3] = 68; // D\n        }\n    }\n    nextState() {\n        let t = this.state[0];\n        t ^= t << sh1;\n        t ^= t >>> sh2;\n        t ^= this.state[3] << sh3;\n        this.state[0] = this.state[1];\n        this.state[1] = this.state[2];\n        this.state[2] = this.state[3];\n        this.state[3] = t;\n    }\n}\n","import { randomUniform, randomNormal } from 'd3-random';\nimport XSAdd from 'ml-xsadd';\n\nexport default function addNoise(data, percent = 0, options = {}) {\n  const { distribution = 'uniform', seed } = options;\n\n  let generateRandomNumber;\n  switch (distribution) {\n    case 'uniform': {\n      generateRandomNumber = getRandom(randomUniform, seed, -0.5, 0.5);\n      break;\n    }\n    case 'normal': {\n      generateRandomNumber = getRandom(randomNormal, seed);\n      break;\n    }\n    default:\n      throw new Error(`Unknown distribution ${options.distribution}`);\n  }\n\n  if (!percent) return data;\n  let ys = data.y;\n  let factor = (percent * findMax(ys)) / 100;\n  for (let i = 0; i < ys.length; i++) {\n    ys[i] += generateRandomNumber() * factor;\n  }\n  return data;\n}\n\nfunction getRandom(func, seed, ...args) {\n  return typeof seed === 'number'\n    ? func.source(new XSAdd(seed).random)(...args)\n    : func(...args);\n}\n\nfunction findMax(array) {\n  let max = Number.MIN_VALUE;\n  for (let item of array) {\n    if (item > max) max = item;\n  }\n  return max;\n}\n","import { getShapeGenerator } from 'ml-peak-shape-generator';\n\nimport addBaseline from './util/addBaseline.js';\nimport addNoise from './util/addNoise.js';\n\nexport class SpectrumGenerator {\n  /**\n   *\n   * @param {object} [options={}]\n   * @param {number} [options.from=0]\n   * @param {number} [options.to=0]\n   * @param {function} [options.nbPoints=10001]\n   * @param {number} [options.factor] default value depends of the shape in order to cover 99.99% of the surface\n   * @param {object} [options.shape={kind:'gaussian'}]\n   * @param {string} [options.shape.kind] kind of shape, gaussian, lorentzian or pseudovoigt\n   * @param {object} [options.shape.options] options for the shape (like `mu` for pseudovoigt)\n   */\n  constructor(options = {}) {\n    options = Object.assign(\n      {},\n      {\n        from: 0,\n        to: 1000,\n        nbPoints: 10001,\n        peakWidthFct: () => 5,\n        shape: {\n          kind: 'gaussian',\n        },\n      },\n      options,\n    );\n\n    this.from = options.from;\n    this.to = options.to;\n    this.nbPoints = options.nbPoints;\n    this.interval = (this.to - this.from) / (this.nbPoints - 1);\n    this.peakWidthFct = options.peakWidthFct;\n    this.maxPeakHeight = Number.MIN_SAFE_INTEGER;\n\n    let shapeGenerator = getShapeGenerator(options.shape);\n    this.shape = shapeGenerator;\n\n    assertNumber(this.from, 'from');\n    assertNumber(this.to, 'to');\n    assertInteger(this.nbPoints, 'nbPoints');\n\n    if (this.to <= this.from) {\n      throw new RangeError('to option must be larger than from');\n    }\n\n    if (typeof this.peakWidthFct !== 'function') {\n      throw new TypeError('peakWidthFct option must be a function');\n    }\n\n    this.reset();\n  }\n\n  addPeaks(peaks, options) {\n    if (\n      !Array.isArray(peaks) &&\n      (typeof peaks !== 'object' ||\n        peaks.x === undefined ||\n        peaks.y === undefined ||\n        !Array.isArray(peaks.x) ||\n        !Array.isArray(peaks.y) ||\n        peaks.x.length !== peaks.y.length)\n    ) {\n      throw new TypeError(\n        'peaks must be an array or an object containing x[] and y[]',\n      );\n    }\n    if (Array.isArray(peaks)) {\n      for (const peak of peaks) {\n        this.addPeak(peak, options);\n      }\n    } else {\n      for (let i = 0; i < peaks.x.length; i++) {\n        this.addPeak([peaks.x[i], peaks.y[i]], options);\n      }\n    }\n\n    return this;\n  }\n\n  /**\n   *\n   * @param {[x,y]|[x,y,w]|{x,y,width}} [peak]\n   * @param {*} options\n   */\n  addPeak(peak, options = {}) {\n    if (\n      typeof peak !== 'object' ||\n      (peak.length !== 2 &&\n        peak.length !== 3 &&\n        (peak.x === undefined || peak.y === undefined))\n    ) {\n      throw new Error(\n        'peak must be an array with two (or three) values or an object with {x,y,width?}',\n      );\n    }\n\n    let xPosition;\n    let intensity;\n    let peakWidth;\n    let peakOptions;\n    if (Array.isArray(peak)) {\n      [xPosition, intensity, peakWidth, peakOptions] = peak;\n    } else {\n      xPosition = peak.x;\n      intensity = peak.y;\n      peakWidth = peak.width;\n      peakOptions = peak.options;\n    }\n\n    if (intensity > this.maxPeakHeight) this.maxPeakHeight = intensity;\n\n    let {\n      width = peakWidth === undefined\n        ? this.peakWidthFct(xPosition)\n        : peakWidth,\n      widthLeft,\n      widthRight,\n      shape: shapeOptions,\n    } = options;\n\n    if (peakOptions) {\n      Object.assign(shapeOptions || {}, peakOptions || {});\n    }\n\n    let shapeGenerator = shapeOptions\n      ? getShapeGenerator(shapeOptions)\n      : this.shape;\n\n    if (!widthLeft) widthLeft = width;\n    if (!widthRight) widthRight = width;\n\n    let factor =\n      options.factor === undefined\n        ? shapeGenerator.getFactor()\n        : options.factor;\n\n    const firstValue = xPosition - (widthLeft / 2) * factor;\n    const lastValue = xPosition + (widthRight / 2) * factor;\n\n    const firstPoint = Math.max(\n      0,\n      Math.floor((firstValue - this.from) / this.interval),\n    );\n    const lastPoint = Math.min(\n      this.nbPoints - 1,\n      Math.ceil((lastValue - this.from) / this.interval),\n    );\n    const middlePoint = Math.round((xPosition - this.from) / this.interval);\n    // PEAK SHAPE MAY BE ASYMMETRC (widthLeft and widthRight) !\n    // we calculate the left part of the shape\n\n    shapeGenerator.setFWHM(widthLeft);\n    for (let index = firstPoint; index < Math.max(middlePoint, 0); index++) {\n      this.data.y[index] +=\n        intensity * shapeGenerator.fct(this.data.x[index] - xPosition);\n    }\n\n    // we calculate the right part of the gaussian\n    shapeGenerator.setFWHM(widthRight);\n    for (\n      let index = Math.min(middlePoint, lastPoint);\n      index <= lastPoint;\n      index++\n    ) {\n      this.data.y[index] +=\n        intensity * shapeGenerator.fct(this.data.x[index] - xPosition);\n    }\n\n    return this;\n  }\n\n  addBaseline(baselineFct) {\n    addBaseline(this.data, baselineFct);\n    return this;\n  }\n\n  addNoise(percent, options) {\n    addNoise(this.data, percent, options);\n    return this;\n  }\n\n  getSpectrum(options = {}) {\n    if (typeof options === 'boolean') {\n      options = { copy: options };\n    }\n    const { copy = true, threshold = 0 } = options;\n    if (threshold) {\n      let minPeakHeight = this.maxPeakHeight * threshold;\n      let x = [];\n      let y = [];\n      for (let i = 0; i < this.data.x.length; i++) {\n        if (this.data.y[i] >= minPeakHeight) {\n          x.push(this.data.x[i]);\n          y.push(this.data.y[i]);\n        }\n      }\n      return { x, y };\n    }\n    if (copy) {\n      return {\n        x: this.data.x.slice(),\n        y: this.data.y.slice(),\n      };\n    } else {\n      return this.data;\n    }\n  }\n\n  reset() {\n    const spectrum = (this.data = {\n      x: new Float64Array(this.nbPoints),\n      y: new Float64Array(this.nbPoints),\n    });\n\n    for (let i = 0; i < this.nbPoints; i++) {\n      spectrum.x[i] = this.from + i * this.interval;\n    }\n\n    return this;\n  }\n}\n\nfunction assertInteger(value, name) {\n  if (!Number.isInteger(value)) {\n    throw new TypeError(`${name} option must be an integer`);\n  }\n}\n\nfunction assertNumber(value, name) {\n  if (!Number.isFinite(value)) {\n    throw new TypeError(`${name} option must be a number`);\n  }\n}\n\nexport function generateSpectrum(peaks, options = {}) {\n  const generator = new SpectrumGenerator(options);\n\n  generator.addPeaks(peaks, options);\n  if (options.baseline) generator.addBaseline(options.baseline);\n  if (options.noise) generator.addNoise(options.noise.percent, options.noise);\n  return generator.getSpectrum({\n    threshold: options.threshold,\n  });\n}\n","export default function addBaseline(data, baselineFct) {\n  if (!baselineFct) return data;\n  let xs = data.x;\n  let ys = data.y;\n  for (let i = 0; i < xs.length; i++) {\n    ys[i] += baselineFct(xs[i]);\n  }\n  return data;\n}\n"],"names":["GAUSSIAN_EXP_FACTOR","Math","LN2","ROOT_PI_OVER_LN2","sqrt","PI","ROOT_THREE","ROOT_2LN2","ROOT_2LN2_MINUS_ONE","erfinv","x","ln1MinusXSqrd","log","lnEtcBy2Plus2","firstSqrt","Gaussian","constructor","options","fwhm","sd","widthToFWHM","height","undefined","this","getData","length","factor","getFactor","min","ceil","pow","center","data","Float64Array","i","fct","area","getArea","width","fwhmToWidth","setFWHM","setHeight","exp","Lorentzian","squareFWHM","tan","PseudoVoigt","mu","setMu","axis","Gaussian2D","globalFWHM","y","xLength","xFactor","yLength","yFactor","xCenter","yCenter","Array","j","volume","getVolume","axisLabel","isArray","axisName","toLowerCase","Error","getShapeGenerator","kind","shapeOptions","replace","xFWHM","yFWHM","random","sourceRandomUniform","source","randomUniform","max","arguments","defaultSource","sourceRandomNormal","randomNormal","sigma","r","multiply_uint32","n","m","nlo","XSadd","seed","Date","now","state","Uint32Array","init","getFloat","bind","getUint32","nextState","Number","isInteger","TypeError","periodCertification","t","addNoise","percent","distribution","generateRandomNumber","getRandom","ys","array","MIN_VALUE","item","findMax","func","args","XSAdd","SpectrumGenerator","Object","assign","from","to","nbPoints","peakWidthFct","shape","interval","maxPeakHeight","MIN_SAFE_INTEGER","shapeGenerator","assertNumber","value","name","assertInteger","RangeError","reset","addPeaks","peaks","peak","addPeak","xPosition","intensity","peakWidth","peakOptions","widthLeft","widthRight","firstValue","lastValue","firstPoint","floor","lastPoint","middlePoint","round","index","addBaseline","baselineFct","xs","getSpectrum","copy","threshold","minPeakHeight","push","slice","spectrum","isFinite","generator","baseline","noise"],"mappings":"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"}