function getRandomWithinPercent(value, percent)
{
  // Calculate the % range
  const range = value * percent;

  // Calculate min and max bounds
  const min = value - range;
  const max = value + range;

  // Generate random number within the range
  return Math.random() * (max - min) + min;
}

function computeMz(mass, charge)
{
  let mz = 1;

  if (charge == 0)
  {
    mz = mass;
  }
  else
  {
    mz = mass / charge;
  }
  return mz
}

var seq_ed_wnd = progWnd.openSequence("/home/rusconi/devel/massxpert3/development/data/polSeqs/chicken-telokin.mxp");

polymer = seq_ed_wnd.getPolymer();
polymer.setLeftEndModifByName("Acetylation");

let phosphoserine_index = 12;
polymer.modifyMonomer(phosphoserine_index, "Phosphorylation", /*override*/ false);

calc_options = polymer.getCalcOptions();
ionizer = polymer.getIonizer();

seq_ed_wnd.setTraceColor("red");

mass_peak_shaper_dlg = seq_ed_wnd.configureMassPeakShaper();
mpscw = mass_peak_shaper_dlg.getConfigWidget();

// Craft a dictionary with all the start_index : stop_index of all the
// telokin species present in DEAE fraction 2 that bears not a single
// E residue at the C-terminus (all proteins ends in index 150).
// We also need to account for the 3 initiation start codons
// for the N-terminal peptide
// MAMISGMSGRK ASGSSPTSPINA
// 0         10           22
// let nterm_indices_list = [1, 2, 7];

let pep_indices_dict = {
  1: [150],
  2: [150],
  7: [150]
};

z = 1;
intensity = 1e6;
let random_intensity = 0;

for (let start_index in pep_indices_dict)
{
  print(start_index + "is:" + pep_indices_dict[start_index])

  for (let end_index of pep_indices_dict[start_index])
  {
    range_as_string = `[${start_index}-${end_index}]`;
    print(range_as_string)

    seq_ed_wnd.setIndexRanges(range_as_string, libXpertMassCore.Enums.LocationType.INDEX);
    calc_options.setIndexRange(start_index, end_index);

    ionizer.level = z;
    polymer.setIonizer(ionizer);

    // We discovered that in fact the N-terminus is always acetylated (Table 2 of the article)

    calc_options.setPolymerEntities(libXpertMassCore.Enums.ChemicalEntity.LEFT_END_MODIF | libXpertMassCore.Enums.ChemicalEntity.FORCE_LEFT_END_MODIF);

    // In that same article we saw that the peptide can be phosphorylated or not.

    // Without Phosphorylation
    calc_options.setMonomerEntities(libXpertMassCore.Enums.ChemicalEntity.NONE);
    polymer.setCalcOptions(calc_options)
    polymer.calculateMasses(calc_options, ionizer)
    let mono = polymer.getMass(libXpertMassCore.Enums.MassType.MONO)
    print("mono: " + mono)
    mass_peak_shaper_dlg.setParameters(mono, 150,
      libXpertMassCore.Enums.MassPeakShapeType.GAUSSIAN, 200000, 0, 6);
    mpscw.checkParameters();
    seq_ed_wnd.setCalcOptions(calc_options)
    random_intensity = getRandomWithinPercent(intensity, 0.10);
    seq_ed_wnd.setNormalizationIntensity(random_intensity);
    seq_ed_wnd.synthesizeMassSpectra();

    // With Phosphorylation, only if the peptide has a modification.
    if (polymer.hasModifiedMonomer(start_index, end_index))
    {
      calc_options.setMonomerEntities(libXpertMassCore.Enums.ChemicalEntity.MODIF);
      polymer.setCalcOptions(calc_options)
      polymer.calculateMasses(calc_options, ionizer)
      mono = polymer.getMass(libXpertMassCore.Enums.MassType.MONO)
      print("mono: " + mono)
      mass_peak_shaper_dlg.setParameters(mono, 150,
        libXpertMassCore.Enums.MassPeakShapeType.GAUSSIAN, 200000, 0, 6);
      seq_ed_wnd.setCalcOptions(calc_options);
      random_intensity = getRandomWithinPercent(intensity, 0.10);
      seq_ed_wnd.setNormalizationIntensity(random_intensity);
      seq_ed_wnd.synthesizeMassSpectra();
    }
  }
}
