text:
// --------------------------------------------------------------------------
//                   OpenMS -- Open-Source Mass Spectrometry
// --------------------------------------------------------------------------
// Copyright The OpenMS Team -- Eberhard Karls University Tuebingen,
// ETH Zurich, and Freie Universitaet Berlin 2002-2021.
//
// This software is released under a three-clause BSD license:
//  * Redistributions of source code must retain the above copyright
//    notice, this list of conditions and the following disclaimer.
//  * Redistributions in binary form must reproduce the above copyright
//    notice, this list of conditions and the following disclaimer in the
//    documentation and/or other materials provided with the distribution.
//  * Neither the name of any author or any participating institution
//    may be used to endorse or promote products derived from this software
//    without specific prior written permission.
// For a full list of authors, refer to the file AUTHORS.
// --------------------------------------------------------------------------
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL ANY OF THE AUTHORS OR THE CONTRIBUTING
// INSTITUTIONS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
// OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
// WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
// OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
// ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
// --------------------------------------------------------------------------
// $Maintainer: George Rosenberger $
// $Authors: George Rosenberger, Hannes Roest $
// --------------------------------------------------------------------------

#include <OpenMS/ANALYSIS/OPENSWATH/MRMDecoy.h>
#include <OpenMS/CHEMISTRY/ModificationsDB.h>
#include <OpenMS/ANALYSIS/OPENSWATH/DATAACCESS/DataAccessHelper.h>

#include <OpenMS/CONCEPT/LogStream.h>
#include <OpenMS/MATH/MISC/MathFunctions.h>

#include <boost/assign.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int.hpp>
#include <boost/random/variate_generator.hpp>
#include <boost/unordered_map.hpp>
#include <unordered_set>

namespace OpenMS
{

  MRMDecoy::MRMDecoy() :
    DefaultParamHandler("MRMDecoy"),
    ProgressLogger()
  {
    defaults_.setValue("non_shuffle_pattern", "KRP", "Residues to not shuffle (keep at a constant position when shuffling). Default is 'KPR' to not shuffle lysine, arginine and proline.");

    defaults_.setValue("keepPeptideNTerm", "true", "Whether to keep peptide N terminus constant when shuffling / reversing.", {"advanced"});
    defaults_.setValidStrings("keepPeptideNTerm", {"true","false"});

    defaults_.setValue("keepPeptideCTerm", "true", "Whether to keep peptide C terminus constant when shuffling / reversing.", {"advanced"});
    defaults_.setValidStrings("keepPeptideCTerm", {"true","false"});

    // write defaults into Param object param_
    defaultsToParam_();
  }

  void MRMDecoy::updateMembers_()
  {
    keep_const_pattern_ = param_.getValue("non_shuffle_pattern").toString();
    keepN_ = param_.getValue("keepPeptideNTerm").toBool();
    keepC_ = param_.getValue("keepPeptideCTerm").toBool();
  }

  MRMDecoy::IndexType MRMDecoy::findFixedResidues(const std::string& sequence,
      bool keepN, bool keepC, const OpenMS::String& keep_const_pattern)
  {
    // also blocks both N- and C-terminus from shuffling if required
    MRMDecoy::IndexType idx;
    for (size_t i = 0; i < sequence.size(); i++)
    {
      if ( (keepN && i == 0) || (keepC && i + 1 == sequence.size()))
      {
        idx.push_back(i);
        continue;
      }

      for (size_t j = 0; j < keep_const_pattern.size(); j++)
      {
        if (sequence[i] == keep_const_pattern[j])
        {
          idx.push_back(i);
        }
      }
    }
    return idx;
  }

  MRMDecoy::IndexType MRMDecoy::findFixedResidues_(const std::string& sequence) const
  {
    return MRMDecoy::findFixedResidues(sequence, false, false, keep_const_pattern_);
  }

  MRMDecoy::IndexType MRMDecoy::findFixedAndTermResidues_(const std::string& sequence) const
  {
    return MRMDecoy::findFixedResidues(sequence, keepN_, keepC_, keep_const_pattern_);
  }

  float MRMDecoy::AASequenceIdentity(const String& sequence, const String& decoy) const
  {
    OPENMS_PRECONDITION(sequence.size() == decoy.size(), "Cannot compare two sequences of unequal length");

    std::vector<char> sequence_v(sequence.begin(), sequence.end());
    std::vector<char> decoy_v(decoy.begin(), decoy.end());
    int running = 0;
    for (Size i = 0; i < sequence_v.size(); i++)
    {
      if (sequence_v[i] == decoy_v[i])
      {
        running += 1;
      }
    }
    double identity = (double) running / sequence_v.size();
    return identity;
  }

  OpenMS::TargetedExperiment::Peptide MRMDecoy::shufflePeptide(
    OpenMS::TargetedExperiment::Peptide peptide, const double identity_threshold, int seed,
    const int max_attempts) const
  {
#ifdef DEBUG_MRMDECOY
    std::cout << " shuffle peptide " << peptide.sequence << std::endl;
    seed = 41;
#endif
    if (seed == -1)
    {
      seed = time(nullptr);
    }
    OpenMS::TargetedExperiment::Peptide shuffled = peptide;

    //TODO use Math::RandomShuffler (=same approach) and put this rather general method somewhere more prominent.
    boost::mt19937 generator(seed);
    boost::uniform_int<> uni_dist;
    boost::variate_generator<boost::mt19937&, boost::uniform_int<> > pseudoRNG(generator, uni_dist);

    std::string aa[] =
    {
      "A", "N", "D", "C", "E", "Q", "G", "H", "I", "L", "M", "F", "S", "T", "W",
      "Y", "V"
    };
    int aa_size = 17;

    int attempts = 0;
    // loop: copy the original peptide, attempt to shuffle it and check whether difference is large enough
    while (MRMDecoy::AASequenceIdentity(peptide.sequence, shuffled.sequence) > identity_threshold &&
           attempts < max_attempts)
    {
      // Block tryptic residues and N-/C-terminus from shuffling
      MRMDecoy::IndexType idx = findFixedAndTermResidues_(peptide.sequence);

      shuffled = peptide;
      std::vector<Size> peptide_index;
      for (Size i = 0; i < peptide.sequence.size(); i++)
      {
        peptide_index.push_back(i);
      }

      // we erase the indices where K/P/R are (from the back / in reverse order
      // to not delete indices we access later)
      for (IndexType::reverse_iterator it = idx.rbegin(); it != idx.rend(); ++it)
      {
        peptide_index.erase(peptide_index.begin() + *it);
      }

      // shuffle the peptide index (without the K/P/R which we leave in place)
      // one could also use std::random_shuffle here but then the code becomes
      // not testable since the implementation of std::random_shuffle differs
      // between libc++ (llvm/mac-osx) and libstdc++ (gcc) and VS
      // see also https://code.google.com/p/chromium/issues/detail?id=358564
      // the actual code here for the shuffling is based on the implementation of
      // std::random_shuffle in libstdc++
      if (peptide_index.begin() != peptide_index.end())
      {
        for (std::vector<Size>::iterator pI_it = peptide_index.begin() + 1; pI_it != peptide_index.end(); ++pI_it)
        {
          // swap current position with random element from vector
          // swapping positions are random in range [0, current_position + 1)
          // which can be at most [0, n)
          std::iter_swap(pI_it, peptide_index.begin() + pseudoRNG((pI_it - peptide_index.begin()) + 1));
        }
      }

      // re-insert the missing K/P/R at the appropriate places
      for (IndexType::iterator it = idx.begin(); it != idx.end(); ++it)
      {
        peptide_index.insert(peptide_index.begin() + *it, *it);
      }

      // use the shuffled index to create the new peptide sequence and
      // then to place the modifications at their appropriate places (make sure
      // that the modifications are placed with their initial amino acids).
      for (Size i = 0; i < peptide_index.size(); i++)
      {
        shuffled.sequence[i] = peptide.sequence[peptide_index[i]];
      }
      for (Size j = 0; j < shuffled.mods.size(); j++)
      {
        for (Size k = 0; k < peptide_index.size(); k++)
        {
          // C and N terminal mods are implicitly not shuffled because they live at positions -1 and sequence.size()
          if (boost::numeric_cast<int>(peptide_index[k]) == shuffled.mods[j].location)
          {
            shuffled.mods[j].location = boost::numeric_cast<int>(k);
            break;
          }
        }
      }

#ifdef DEBUG_MRMDECOY
      for (Size j = 0; j < shuffled.mods.size(); j++)
      {
        std::cout << " position after shuffling " << shuffled.mods[j].location << " mass difference " << shuffled.mods[j].mono_mass_delta << std::endl;
      }
#endif

      ++attempts;

      // If our attempts have failed so far, we will mutate a random AA of
      // the sequence and see whether we can achieve sufficient shuffling with
      // the new sequence.
      if (attempts % 10 == 9)
      {
        OpenMS::AASequence shuffled_sequence = TargetedExperimentHelper::getAASequence(shuffled);
        int res_pos = (pseudoRNG() % aa_size);
        int pep_pos = -1;
        size_t pos_trials = 0;
        while (pep_pos < 0 && pos_trials < shuffled_sequence.size())
        {
          // select position to mutate (and ensure we are not changing N/C terminus or any modified position doing it)
          pep_pos = (pseudoRNG() % shuffled_sequence.size());
          if (shuffled_sequence[pep_pos].isModified() || (pep_pos == 0) || (pep_pos == (int)(shuffled_sequence.size() - 1)))
          {
            pep_pos = -1;
          }
          else
          {
            if (pep_pos == 0)
            {
              shuffled_sequence = AASequence::fromString(aa[res_pos]) + shuffled_sequence.getSuffix(shuffled_sequence.size() - pep_pos - 1);
            }
            else if (pep_pos == (int)(shuffled_sequence.size() - 1))
            {
              shuffled_sequence = shuffled_sequence.getPrefix(pep_pos) + AASequence::fromString(aa[res_pos]);
            }
            else
            {
              shuffled_sequence = shuffled_sequence.getPrefix(pep_pos) + AASequence::fromString(aa[res_pos]) + shuffled_sequence.getSuffix(shuffled_sequence.size() - pep_pos - 1);
            }
          }
          ++pos_trials;
        }
        shuffled.sequence = shuffled_sequence.toUnmodifiedString();
        peptide = shuffled;
      }
    }

    return shuffled;
  }

  OpenMS::TargetedExperiment::Peptide MRMDecoy::reversePeptide(
      const OpenMS::TargetedExperiment::Peptide& peptide, const bool keepN, const bool keepC,
      const String& const_pattern)
  {
    OpenMS::TargetedExperiment::Peptide reversed = peptide;
    // Block tryptic residues and N-/C-terminus from shuffling
    MRMDecoy::IndexType idx = MRMDecoy::findFixedResidues(peptide.sequence, keepN, keepC, const_pattern);

    std::vector<Size> peptide_index;
    for (Size i = 0; i < peptide.sequence.size(); i++)
    {
      peptide_index.push_back(i);
    }

    // we erase the indices where K/P/R are (from the back / in reverse order
    // to not delete indices we access later)
    for (IndexType::reverse_iterator it = idx.rbegin(); it != idx.rend(); ++it)
    {
      peptide_index.erase(peptide_index.begin() + *it);
    }

    // reverse the peptide index
    std::reverse(peptide_index.begin(), peptide_index.end());

    // re-insert the missing K/P/R at the appropriate places
    for (IndexType::iterator it = idx.begin(); it != idx.end(); ++it)
    {
      peptide_index.insert(peptide_index.begin() + *it, *it);
    }

    // use the reversed index to create the new peptide sequence and
    // then to place the modifications at their appropriate places (make sure
    // that the modifications are placed with their initial amino acids).
    for (Size i = 0; i < peptide_index.size(); i++)
    {
      reversed.sequence[i] = peptide.sequence[peptide_index[i]];
    }
    for (Size j = 0; j < reversed.mods.size(); j++)
    {
      for (Size k = 0; k < peptide_index.size(); k++)
      {
        // C and N terminal mods are implicitly not reversed because they live at positions -1 and sequence.size()
        if (boost::numeric_cast<int>(peptide_index[k]) == reversed.mods[j].location)
        {
          reversed.mods[j].location = boost::numeric_cast<int>(k);
          break;
        }
      }
    }
    return reversed;
  }

  OpenMS::TargetedExperiment::Peptide MRMDecoy::pseudoreversePeptide_(
    const OpenMS::TargetedExperiment::Peptide& peptide) const
  {
    return MRMDecoy::reversePeptide(peptide, false, true);
  }

  OpenMS::TargetedExperiment::Peptide MRMDecoy::reversePeptide_(
    const OpenMS::TargetedExperiment::Peptide& peptide) const
  {
    return MRMDecoy::reversePeptide(peptide, false, false);
  }

  void MRMDecoy::switchKR(OpenMS::TargetedExperiment::Peptide& peptide) const
  {
    static std::string aa[] =
    {
      "A", "N", "D", "C", "E", "Q", "G", "H", "I", "L", "M", "F", "S", "T", "W",
      "Y", "V"
    };
    int aa_size = 17;

    static boost::mt19937 generator(42);
    static boost::uniform_int<> uni_dist;
    static boost::variate_generator<boost::mt19937&, boost::uniform_int<> > pseudoRNG(generator, uni_dist);

    Size lastAA = peptide.sequence.size() - 1;
    if (peptide.sequence[lastAA] == 'K')
    {
      peptide.sequence[lastAA] = 'R';
    }
    else if (peptide.sequence[lastAA] == 'R')
    {
      peptide.sequence[lastAA] = 'K';
    }
    else
    {
      // randomize
      int res_pos = (pseudoRNG() % aa_size);
      peptide.sequence[lastAA] = (char)aa[res_pos][0];
    }
  }

  bool MRMDecoy::hasCNterminalMods_(const OpenMS::TargetedExperiment::Peptide& peptide, bool checkCterminalAA) const
  {
    for (Size j = 0; j < peptide.mods.size(); j++)
    {
      if (peptide.mods[j].location == -1 || peptide.mods[j].location == (int)peptide.sequence.size())
      {
        return true;
      }
      if (checkCterminalAA && peptide.mods[j].location == (int)peptide.sequence.size() - 1)
      {
        return true;
      }
    }
    return false;
  }

  String MRMDecoy::getModifiedPeptideSequence_(const OpenMS::TargetedExperiment::Peptide& pep) const
  {
    String full_peptide_name;
    for (int loc = -1; loc <= (int)pep.sequence.size(); loc++)
    {
      if (loc > -1 && loc < (int)pep.sequence.size())
      {
        full_peptide_name += pep.sequence[loc];
      }
      // C-terminal and N-terminal modifications may be at positions -1 or pep.sequence
      for (Size modloc = 0; modloc < pep.mods.size(); modloc++)
      {
        if (pep.mods[modloc].location == loc)
        {
          full_peptide_name += "(UniMod:" + String(pep.mods[modloc].unimod_id) + ")";
        }
      }
    }
    return full_peptide_name;
  }

  void MRMDecoy::generateDecoys(const OpenMS::TargetedExperiment& exp, OpenMS::TargetedExperiment& dec,
                                const String& method, const double aim_decoy_fraction, const bool do_switchKR,
                                const String& decoy_tag, const int max_attempts, const double identity_threshold,
                                const double precursor_mz_shift, const double product_mz_shift, const double product_mz_threshold,
                                const std::vector<String>& fragment_types, const std::vector<size_t>& fragment_charges,
                                const bool enable_specific_losses, const bool enable_unspecific_losses, const int round_decPow) const
  {
    MRMIonSeries mrmis;
    MRMDecoy::PeptideVectorType peptides, decoy_peptides;
    MRMDecoy::ProteinVectorType proteins, decoy_proteins;
    MRMDecoy::TransitionVectorType decoy_transitions;
    for (Size i = 0; i < exp.getProteins().size(); i++)
    {
      OpenMS::TargetedExperiment::Protein protein = exp.getProteins()[i];
      protein.id = decoy_tag + protein.id;
      proteins.push_back(protein);
    }

    srand(time(0));
    std::vector<size_t> item_list, selection_list;
    item_list.reserve(exp.getPeptides().size());
    for (Size k = 0; k < exp.getPeptides().size(); k++) {item_list.push_back(k);}

    if (aim_decoy_fraction > 1.0)
    {
      throw Exception::IllegalArgument(__FILE__, __LINE__, OPENMS_PRETTY_FUNCTION, "Decoy fraction needs to be less than one (values larger than one currently not supported).");
    }
    else if (aim_decoy_fraction < 1.0)
    {
      Math::RandomShuffler shuffler;
      shuffler.portable_random_shuffle(item_list.begin(), item_list.end());
      selection_list.reserve(aim_decoy_fraction * exp.getPeptides().size());
      Size k = 0;
      while (selection_list.size() < aim_decoy_fraction * exp.getPeptides().size())
      {
        selection_list.push_back( item_list[ k++ % item_list.size() ]);
      }
    }
    else
    {
      selection_list = item_list;
    }

    // Create an unordered_map of all peptide sequences and their IDs, this will be used to search if a decoy sequence is also a target sequence
    std::unordered_map<std::string, std::string> allPeptideSequences;
    for (const auto& pep_idx: selection_list)
    {
      OpenMS::TargetedExperiment::Peptide peptide = exp.getPeptides()[pep_idx];

      // create a modified peptide sequence string
      allPeptideSequences[MRMDecoy::getModifiedPeptideSequence_(peptide)] = peptide.id;
    }

    std::unordered_set<String> exclusion_peptides;
    // Go through all peptides and apply the decoy method to the sequence
    // (pseudo-reverse, reverse or shuffle). Then set the peptides and proteins of the decoy
    // experiment.
    Size progress = 0;
    startProgress(0, selection_list.size(), "Generating decoy peptides");
    for (const auto& pep_idx : selection_list)
    {
      setProgress(++progress);

      OpenMS::TargetedExperiment::Peptide peptide = exp.getPeptides()[pep_idx];

      peptide.id = decoy_tag + peptide.id;

      if (!peptide.getPeptideGroupLabel().empty())
      {
        peptide.setPeptideGroupLabel(decoy_tag + peptide.getPeptideGroupLabel());
      }

      if (method == "pseudo-reverse")
      {
        // exclude peptide if it has C/N terminal modifications because we can't do a (partial) reverse
        if (MRMDecoy::hasCNterminalMods_(peptide, do_switchKR))
        {
          OPENMS_LOG_DEBUG << "[peptide] Skipping " << peptide.id << " due to C/N-terminal modifications" << std::endl;
          exclusion_peptides.insert(peptide.id);
        }
        else
        {
          peptide = MRMDecoy::pseudoreversePeptide_(peptide);
          if (do_switchKR) { switchKR(peptide); }
        }
      }
      else if (method == "reverse")
      {
        // exclude peptide if it has C/N terminal modifications because we can't do a (partial) reverse
        if (MRMDecoy::hasCNterminalMods_(peptide, false))
        {
          OPENMS_LOG_DEBUG << "[peptide] Skipping " << peptide.id << " due to C/N-terminal modifications" << std::endl;
          exclusion_peptides.insert(peptide.id);
        }
        else
        {
          peptide = MRMDecoy::reversePeptide_(peptide);
        }
      }
      else if (method == "shuffle")
      {
        peptide = MRMDecoy::shufflePeptide(peptide, identity_threshold, -1, max_attempts);
        if (do_switchKR && MRMDecoy::hasCNterminalMods_(peptide, do_switchKR))
        {
          OPENMS_LOG_DEBUG << "[peptide] Skipping " << peptide.id << " due to C/N-terminal modifications" << std::endl;
          exclusion_peptides.insert(peptide.id);
        }
        else if (do_switchKR) { switchKR(peptide); }
      }

      // Check that the decoy sequence does not happen to be a target sequence AND is not already present
      if (allPeptideSequences.find(peptide.sequence) != allPeptideSequences.end())
      {
        OPENMS_LOG_DEBUG << "[peptide] Skipping " << peptide.id << " since decoy peptide is also a target peptide or this decoy peptide is already present" << std::endl;
        exclusion_peptides.insert(peptide.id);
      }
      else
      {
        // Since this decoy will be added, add it to the peptide map so that the same decoy is not added twice
        OPENMS_LOG_DEBUG << "[peptide] adding " << peptide.id << " to master list of peptides " << std::endl;
        allPeptideSequences[MRMDecoy::getModifiedPeptideSequence_(peptide)] = peptide.id;
      }

      for (Size prot_idx = 0; prot_idx < peptide.protein_refs.size(); ++prot_idx)
      {
        peptide.protein_refs[prot_idx] = decoy_tag + peptide.protein_refs[prot_idx];
      }

      peptides.push_back(peptide);
    }
    endProgress();
    dec.setPeptides(peptides); // temporary set peptides, overwrite later again!

    // hash of the peptide reference containing all transitions
    MRMDecoy::PeptideTransitionMapType peptide_trans_map;
    for (Size i = 0; i < exp.getTransitions().size(); i++)
    {
      peptide_trans_map[exp.getTransitions()[i].getPeptideRef()].push_back(&exp.getTransitions()[i]);
    }

    progress = 0;
    startProgress(0, peptide_trans_map.size(), "Generating decoy transitions");
    for (MRMDecoy::PeptideTransitionMapType::iterator pep_it = peptide_trans_map.begin();
         pep_it != peptide_trans_map.end(); ++pep_it)
    {
      setProgress(++progress);

      String peptide_ref = pep_it->first;
      String decoy_peptide_ref = decoy_tag + pep_it->first; // see above, the decoy peptide id is computed deterministically from the target id
      if (!dec.hasPeptide(decoy_peptide_ref)) { continue; }
      const TargetedExperiment::Peptide target_peptide = exp.getPeptideByRef(peptide_ref);

      const TargetedExperiment::Peptide decoy_peptide = dec.getPeptideByRef(decoy_peptide_ref);
      OpenMS::AASequence target_peptide_sequence = TargetedExperimentHelper::getAASequence(target_peptide);
      OpenMS::AASequence decoy_peptide_sequence = TargetedExperimentHelper::getAASequence(decoy_peptide);

      int decoy_charge = 1;
      int target_charge = 1;
      if (decoy_peptide.hasCharge()) { decoy_charge = decoy_peptide.getChargeState(); }
      if (target_peptide.hasCharge()) { target_charge = target_peptide.getChargeState(); }

      MRMIonSeries::IonSeries decoy_ionseries = mrmis.getIonSeries(decoy_peptide_sequence, decoy_charge,
                                                                   fragment_types, fragment_charges, enable_specific_losses,
                                                                   enable_unspecific_losses, round_decPow);
      MRMIonSeries::IonSeries target_ionseries = mrmis.getIonSeries(target_peptide_sequence, target_charge,
                                                                    fragment_types, fragment_charges, enable_specific_losses,
                                                                    enable_unspecific_losses, round_decPow);

      // Compute (new) decoy precursor m/z based on the K/R replacement and the AA changes in the shuffle algorithm
      double decoy_precursor_mz = decoy_peptide_sequence.getMZ(decoy_charge);
      decoy_precursor_mz += precursor_mz_shift; // fix for TOPPView: Duplicate precursor MZ is not displayed.

      for (Size i = 0; i < pep_it->second.size(); i++)
      {
        const ReactionMonitoringTransition tr = *(pep_it->second[i]);

        if (!tr.isDetectingTransition() || tr.getDecoyTransitionType() == ReactionMonitoringTransition::DECOY)
        {
          continue;
        }

        ReactionMonitoringTransition decoy_tr = tr; // copy the target transition

        decoy_tr.setNativeID(decoy_tag + tr.getNativeID());
        decoy_tr.setDecoyTransitionType(ReactionMonitoringTransition::DECOY);
        decoy_tr.setPrecursorMZ(decoy_precursor_mz);

        // determine the current annotation for the target ion and then select
        // the appropriate decoy ion for this target transition
        std::pair<String, double> targetion = mrmis.annotateIon(target_ionseries, tr.getProductMZ(), product_mz_threshold);
        std::pair<String, double> decoyion = mrmis.getIon(decoy_ionseries, targetion.first);

        if (method == "shift")
        {
          decoy_tr.setProductMZ(decoyion.second + product_mz_shift);
        }
        else
        {
          decoy_tr.setProductMZ(decoyion.second);
        }
        decoy_tr.setPeptideRef(decoy_tag + tr.getPeptideRef());

        if (decoyion.second > 0)
        {
          decoy_transitions.push_back(decoy_tr);
        }
        else
        {
          // transition could not be annotated, remove whole peptide
          exclusion_peptides.insert(decoy_tr.getPeptideRef());
          OPENMS_LOG_DEBUG << "[peptide] Skipping " << decoy_tr.getPeptideRef() << " due to missing annotation" << std::endl;
        }
      } // end loop over transitions

    } // end loop over peptides
    endProgress();

    decoy_transitions.erase(std::remove_if(
                            decoy_transitions.begin(), decoy_transitions.end(),
                            [&exclusion_peptides](const OpenMS::ReactionMonitoringTransition& tr)
    {
      return exclusion_peptides.find(tr.getPeptideRef()) != exclusion_peptides.end();
    }), decoy_transitions.end());
    dec.setTransitions(std::move(decoy_transitions));

    std::unordered_set<String> protein_ids;
    decoy_peptides.reserve(peptides.size());
    for (const auto& peptide : peptides)
    {
      // Check if peptide has any transitions left
      if (exclusion_peptides.find(peptide.id) == exclusion_peptides.end())
      {
        decoy_peptides.push_back(peptide);
        for (Size j = 0; j < peptide.protein_refs.size(); ++j)
        {
          protein_ids.insert(peptide.protein_refs[j]);
        }
      }
      else
      {
        OPENMS_LOG_DEBUG << "[peptide] Skipping " << peptide.id << " due to missing transitions" << std::endl;
      }
    }

    decoy_proteins.reserve(proteins.size());
    for (const auto& protein : proteins)
    {
      // Check if protein has any peptides left
      if (protein_ids.find(protein.id) != protein_ids.end())
      {
        decoy_proteins.push_back(protein);
      }
      else
      {
        OPENMS_LOG_DEBUG << "[protein] Skipping " << protein.id << " due to missing peptides" << std::endl;
      }
    }

    dec.setPeptides(std::move(decoy_peptides));
    dec.setProteins(std::move(decoy_proteins));

  }

}


text:
#pragma once

#include "Client.hpp"

#include <boost/asio.hpp>
#include <memory>
#include <list>
#include <unordered_map>

class ControlServer
{
public:
	typedef enum
	{
		CTRL_LOGIN = 0,
		CTRL_LOGOUT,
		GAME_PLAYER_JOINED,
		GAME_PLAYER_LEFT,
		GAME_KICK_PLAYER,
		GAME_BAN_PLAYER,
		GAME_LOG_ENTRY
	} MessageType;

	#pragma pack(push, 1)
	typedef struct
	{
		UINT8 type; /* MessageType */
		UINT32 sz;
	} MessageHeader;
	#pragma pack(pop)

	#pragma pack(push, 1)
	typedef struct
	{
		UINT32 id;
		UINT32 uid;
		BYTE ipAddress[4];
		UINT16 port;
		BYTE name[30];
		UINT32 role;
	} MsgPlayerJoined;
	#pragma pack(pop)

	#pragma pack(push, 1)
	typedef struct
	{
		UINT32 uid;
	} MsgPlayerLeft;
	#pragma pack(pop)

	#pragma pack(push, 1)
		typedef struct
	{
		UINT32 uid;
	} MsgPlayerKick;
	#pragma pack(pop)

	ControlServer(UINT16 port);
	~ControlServer();

	virtual void run();
	virtual void sendMessage(unsigned long long id, MessageType type, const BYTE *msg, unsigned sz);
	virtual void broadcastMessage(MessageType type, const BYTE *msg, unsigned sz);

private:
	const char *PASSWORD = "hello";

	void disconnectClient(std::shared_ptr<Client> &client) noexcept;
	void setupAccept();
	void handleAccept(std::shared_ptr<Client> &client, const boost::system::error_code &error);
	void setupRead(std::shared_ptr<Client> &client);
	void handleRead(const boost::system::error_code &err, size_t nBytes, std::shared_ptr<Client> &client);
	void loginClient(unsigned long long id, const BYTE *msg, unsigned sz);
	void logoutClient(unsigned long long id, const BYTE *msg, unsigned sz);
	void kickPlayer(unsigned long long id, const BYTE *msg, unsigned sz);

	std::unordered_map<
		MessageType,
		std::function<void(unsigned long long, const BYTE *, unsigned)>
	> msgMap;
	std::list<std::shared_ptr<Client>> clients;
	boost::asio::io_service ioService;
	boost::asio::ip::tcp::acceptor acceptor;
	std::vector<boost::asio::ip::tcp::socket> sockets;
	unsigned long long int clientIdCounter = 0;
};

ext: hpp

max_stars_repo_name: RaJiska/WarbandServerQuery

max_issues_repo_name: RaJiska/WarbandServerQuery

max_forks_repo_name: RaJiska/WarbandServerQuery


text:
// Copyright Vladimir Prus 2004.
// Distributed under the Boost Software License, Version 1.0.
// (See accompanying file LICENSE_1_0.txt
// or copy at http://www.boost.org/LICENSE_1_0.txt)

#include <fstream>
#include <locale.h>
#include <locale>
#include <iostream>
#include <string>
#include <locale>
#include <stdexcept>

#include <boost/config.hpp>

#define BOOST_PROGRAM_OPTIONS_SOURCE
#include <boost/program_options/config.hpp>
#include <boost/program_options/detail/convert.hpp>
#include <boost/program_options/detail/utf8_codecvt_facet.hpp>
#include <boost/throw_exception.hpp>

#include <boost/bind.hpp>

using namespace std;

namespace boost { namespace detail {

    /* Internal function to actually perform conversion.
       The logic in from_8_bit and to_8_bit function is exactly
       the same, except that one calls 'in' method of codecvt and another
       calls the 'out' method, and that syntax difference makes straightforward
       template implementation impossible.

       This functions takes a 'fun' argument, which should have the same
       parameters and return type and the in/out methods. The actual converting
       function will pass functional objects created with boost::bind.
       Experiments show that the performance loss is less than 10%.
    */
    template<class ToChar, class FromChar, class Fun>
    std::basic_string<ToChar>
    convert(const std::basic_string<FromChar>& s, Fun fun)

    {
        std::basic_string<ToChar> result;

        std::mbstate_t state = std::mbstate_t();

        const FromChar* from = s.data();
        const FromChar* from_end = s.data() + s.size();
        // The interface of cvt is not really iterator-like, and it's
        // not possible the tell the required output size without the conversion.
        // All we can is convert data by pieces.
        while(from != from_end) {

            // std::basic_string does not provide non-const pointers to the data,
            // so converting directly into string is not possible.
            ToChar buffer[32];

            ToChar* to_next = buffer;
            // Need variable because boost::bind doesn't work with rvalues.
            ToChar* to_end = buffer + 32;
            std::codecvt_base::result r =
                fun(state, from, from_end, from, buffer, to_end, to_next);

            if (r == std::codecvt_base::error)
                boost::throw_exception(
                    std::logic_error("character conversion failed"));
            // 'partial' is not an error, it just means not all source
            // characters were converted. However, we need to check that at
            // least one new target character was produced. If not, it means
            // the source data is incomplete, and since we don't have extra
            // data to add to source, it's error.
            if (to_next == buffer)
                boost::throw_exception(
                    std::logic_error("character conversion failed"));

            // Add converted characters
            result.append(buffer, to_next);
        }

        return result;
    }
}}

namespace boost {

#ifndef BOOST_NO_STD_WSTRING
    BOOST_PROGRAM_OPTIONS_DECL std::wstring
    from_8_bit(const std::string& s,
               const std::codecvt<wchar_t, char, std::mbstate_t>& cvt)
    {
        return detail::convert<wchar_t>(
            s,
            boost::bind(&std::codecvt<wchar_t, char, mbstate_t>::in,
                        &cvt,
                        _1, _2, _3, _4, _5, _6, _7));
    }

    BOOST_PROGRAM_OPTIONS_DECL std::string
    to_8_bit(const std::wstring& s,
             const std::codecvt<wchar_t, char, std::mbstate_t>& cvt)
    {
        return detail::convert<char>(
            s,
            boost::bind(&codecvt<wchar_t, char, mbstate_t>::out,
                        &cvt,
                        _1, _2, _3, _4, _5, _6, _7));
    }

    namespace {
        boost::program_options::detail::utf8_codecvt_facet
            utf8_facet;
    }

    BOOST_PROGRAM_OPTIONS_DECL std::wstring
    from_utf8(const std::string& s)
    {
        return from_8_bit(s, utf8_facet);
    }

    BOOST_PROGRAM_OPTIONS_DECL std::string
    to_utf8(const std::wstring& s)
    {
        return to_8_bit(s, utf8_facet);
    }

    BOOST_PROGRAM_OPTIONS_DECL std::wstring
    from_local_8_bit(const std::string& s)
    {
        typedef codecvt<wchar_t, char, mbstate_t> facet_type;
        return from_8_bit(s,
                          BOOST_USE_FACET(facet_type, locale()));
    }

    BOOST_PROGRAM_OPTIONS_DECL std::string
    to_local_8_bit(const std::wstring& s)
    {
        typedef codecvt<wchar_t, char, mbstate_t> facet_type;
        return to_8_bit(s,
                        BOOST_USE_FACET(facet_type, locale()));
    }
#endif

    namespace program_options
    {
        BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::string& s)
        {
            return s;
        }

#ifndef BOOST_NO_STD_WSTRING
        BOOST_PROGRAM_OPTIONS_DECL std::string to_internal(const std::wstring& s)
        {
            return to_utf8(s);
        }
#endif
    }

}

ext: cpp


text:
// Copyright 2006-2008 Daniel James.
// Distributed under the Boost Software License, Version 1.0. (See accompanying
// file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)

#define HASH_NAMESPACE boost
#include <boost/functional/hash.hpp>
#define BOOST_HASH_NO_EXTENSIONS
#include <boost/functional/hash.hpp>
#include <boost/detail/lightweight_test.hpp>
#include <deque>
#include <cassert>

int main()
{
    std::deque<int> x;

    x.push_back(1);
    x.push_back(2);

    HASH_NAMESPACE::hash<std::deque<int> > hasher;
    BOOST_TEST(hasher(x) == HASH_NAMESPACE::hash_value(x));

    return boost::report_errors();
}


text:
// Copyright (c) 2010 Satoshi Nakamoto
// Copyright (c) 2009-2015 The Bitcoin Core developers
// Distributed under the MIT software license, see the accompanying
// file COPYING or http://www.opensource.org/licenses/mit-license.php.

#include "chainparams.h"
#include "consensus/merkle.h"
#include "consensus/consensus.h"
#include "zerocoin_params.h"

#include "tinyformat.h"
#include "util.h"
#include "utilstrencodings.h"
#include "libzerocoin/bitcoin_bignum/bignum.h"

#include <assert.h>

#include <boost/assign/list_of.hpp>

#include "chainparamsseeds.h"
#include "arith_uint256.h"

static CBlock CreateGenesisBlock(const char *pszTimestamp, const CScript &genesisOutputScript, uint32_t nTime, uint32_t nNonce,
        uint32_t nBits, int32_t nVersion, const CAmount &genesisReward,
        std::vector<unsigned char> extraNonce) {
    CMutableTransaction txNew;
    txNew.nVersion = 1;
    txNew.vin.resize(1);
    txNew.vout.resize(1);
    txNew.vin[0].scriptSig = CScript() << 504365040 << CBigNum(4).getvch() << std::vector < unsigned char >
    ((const unsigned char *) pszTimestamp, (const unsigned char *) pszTimestamp + strlen(pszTimestamp)) << extraNonce;
    txNew.vout[0].nValue = genesisReward;
    txNew.vout[0].scriptPubKey = genesisOutputScript;

    CBlock genesis;
    genesis.nTime = nTime;
    genesis.nBits = nBits;
    genesis.nNonce = nNonce;
    genesis.nVersion = nVersion;
    genesis.vtx.push_back(txNew);
    genesis.hashPrevBlock.SetNull();
    genesis.hashMerkleRoot = BlockMerkleRoot(genesis);
    return genesis;
}

/**
 * Build the genesis block. Note that the output of its generation
 * transaction cannot be spent since it did not originally exist in the
 * database.
 *
 * CBlock(hash=000000000019d6, ver=1, hashPrevBlock=00000000000000, hashMerkleRoot=4a5e1e, nTime=1231006505, nBits=1d00ffff, nNonce=2083236893, vtx=1)
 *   CTransaction(hash=4a5e1e, ver=1, vin.size=1, vout.size=1, nLockTime=0)
 *     CTxIn(COutPoint(000000, -1), coinbase 04ffff001d0104455468652054696d65732030332f4a616e2f32303039204368616e63656c6c6f72206f6e206272696e6b206f66207365636f6e64206261696c6f757420666f722062616e6b73)
 *     CTxOut(nValue=50.00000000, scriptPubKey=0x5F1DF16B2B704C8A578D0B)
 *   vMerkleTree: 4a5e1e
 */
static CBlock CreateGenesisBlock(uint32_t nTime, uint32_t nNonce, uint32_t nBits, int32_t nVersion, const CAmount &genesisReward,
        std::vector<unsigned char> extraNonce) {
    const char *pszTimestamp = "Bitcoin Recovers from Below $7.2K After Schiff Says ‘Game Is Over";
    const CScript genesisOutputScript = CScript();
    return CreateGenesisBlock(pszTimestamp, genesisOutputScript, nTime, nNonce, nBits, nVersion, genesisReward,
                              extraNonce);
}
/**
 * Main network
 */
/**
 * What makes a good checkpoint block?
 * + Is surrounded by blocks with reasonable timestamps
 *   (no blocks before with a timestamp after, none after with
 *    timestamp before)
 * + Contains no strange transactions
 */

class CMainParams : public CChainParams {
public:
    CMainParams() {
        strNetworkID = "main";

        consensus.chainType = Consensus::chainMain;

        consensus.nSubsidyHalvingFirst = 302438;
        consensus.nSubsidyHalvingInterval = 420000;
        consensus.nSubsidyHalvingStopBlock = 3646849;

        consensus.nMajorityEnforceBlockUpgrade = 8100;
        consensus.nMajorityRejectBlockOutdated = 10260;
        consensus.nMajorityWindow = 10800;
        consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
        //static const int64 nInterval = nTargetTimespan / nTargetSpacing;
        consensus.nPowTargetTimespan = 40 * 60; // 40 minutes between retargets
        consensus.nPowTargetSpacing = 120; // alternate PoW/PoS every one minute
        consensus.nDgwPastBlocks = 30; // number of blocks to average in Dark Gravity Wave
        consensus.fPowAllowMinDifficultyBlocks = false;
        consensus.fPowNoRetargeting = false;
        consensus.nRuleChangeActivationThreshold = 10260; // 95% of 10800
        consensus.nMinerConfirmationWindow = 10800; // nPowTargetTimespan / nPowTargetSpacing
        consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
        consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1580217929; // January 1, 2008
        consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1611840329; // December 31, 2008

        // Deployment of BIP68, BIP112, and BIP113.
        consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
        consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1580217929; // May 1st, 2016
        consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1611840329; // May 1st, 2017

        // Deployment of SegWit (BIP141, BIP143, and BIP147)
        consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
        consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1580217929; // November 15th, 2016.
        consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1611840329; // November 15th, 2017.

        // The best chain should have at least this much work
        consensus.nMinimumChainWork = uint256S("0x0");

        consensus.nCheckBugFixedAtBlock = ZC_CHECK_BUG_FIXED_AT_BLOCK;
        consensus.nIndexnodePaymentsBugFixedAtBlock = ZC_INDEXNODE_PAYMENT_BUG_FIXED_AT_BLOCK;
	    consensus.nSpendV15StartBlock = ZC_V1_5_STARTING_BLOCK;
	    consensus.nSpendV2ID_1 = ZC_V2_SWITCH_ID_1;
	    consensus.nSpendV2ID_10 = ZC_V2_SWITCH_ID_10;
	    consensus.nSpendV2ID_25 = ZC_V2_SWITCH_ID_25;
	    consensus.nSpendV2ID_50 = ZC_V2_SWITCH_ID_50;
	    consensus.nSpendV2ID_100 = ZC_V2_SWITCH_ID_100;
	    consensus.nModulusV2StartBlock = ZC_MODULUS_V2_START_BLOCK;
        consensus.nModulusV1MempoolStopBlock = ZC_MODULUS_V1_MEMPOOL_STOP_BLOCK;
	    consensus.nModulusV1StopBlock = ZC_MODULUS_V1_STOP_BLOCK;
        consensus.nMultipleSpendInputsInOneTxStartBlock = ZC_MULTIPLE_SPEND_INPUT_STARTING_BLOCK;
        consensus.nDontAllowDupTxsStartBlock = 1;

        // indexnode params
        consensus.nIndexnodePaymentsStartBlock = HF_INDEXNODE_PAYMENT_START; // not true, but it's ok as long as it's less then nIndexnodePaymentsIncreaseBlock

        consensus.nDisableZerocoinStartBlock = 1;

        nMaxTipAge = 6 * 60 * 60; // ~144 blocks behind -> 2 x fork detection time, was 24 * 60 * 60 in bitcoin

        nPoolMaxTransactions = 3;
        nFulfilledRequestExpireTime = 60*60; // fulfilled requests expire in 1 hour
        strSporkPubKey = "024faf77b973d9c858991c6e1d6b5865f6221831467691718108ebbb907e7d5ccd";
        //Stake stuff
        consensus.nFirstPOSBlock = 52;
        consensus.nStakeTimestampMask = 0xf; // 15
        consensus.posLimit = uint256S("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");

        /**
         * The message start string is designed to be unlikely to occur in normal data.
         * The characters are rarely used upper ASCII, not valid as UTF-8, and produce
       `  * a large 32-bit integer with any alignment.
         */
        //btzc: update index pchMessage
        pchMessageStart[0] = 0xe5;
        pchMessageStart[1] = 0xd3;
        pchMessageStart[2] = 0xf7;
        pchMessageStart[3] = 0x4d;
        nDefaultPort = 7082;
        nPruneAfterHeight = 100000;
        /**
         * btzc: index init genesis block
         * nBits = 0x1e0ffff0
         * nTime = 1414776286
         * nNonce = 142392
         * genesisReward = 0 * COIN
         * nVersion = 2
         * extraNonce
         */
        std::vector<unsigned char> extraNonce(4);
	    extraNonce[0] = 0x81;
        extraNonce[1] = 0x3a;
        extraNonce[2] = 0x00;
        extraNonce[3] = 0x00;
        genesis = CreateGenesisBlock(ZC_GENESIS_BLOCK_TIME, 48351, 0x1e00ffff, 2, 0 * COIN, extraNonce);
        // std::cout << "index new hashMerkleRoot hash: " << genesis.hashMerkleRoot.ToString() << std::endl;
        // std::cout << "index new genesis hash: " << genesis.GetHash().ToString() << std::endl;
        consensus.hashGenesisBlock = genesis.GetHash();
        // uint32_t nGenesisTime = ZC_GENESIS_BLOCK_TIME;
        // arith_uint256 test;
        // bool fNegative;
        // bool fOverflow;
        // test.SetCompact(0x1e00ffff, &fNegative, &fOverflow);
        // std::cout << "Test threshold: " << test.GetHex() << "\n\n";
        // int genesisNonce = 0;
        // uint256 TempHashHolding = uint256S("0x0000000000000000000000000000000000000000000000000000000000000000");
        // uint256 BestBlockHash = uint256S("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
        // for (int i=0;i<40000000;i++) {
        //     genesis = CreateGenesisBlock(nGenesisTime, i, 0x1e00ffff, 2, 0 * COIN,extraNonce);
        //     //genesis.hashPrevBlock = TempHashHolding;
        //     consensus.hashGenesisBlock = genesis.GetHash();
        //     arith_uint256 BestBlockHashArith = UintToArith256(BestBlockHash);
        //     if (UintToArith256(consensus.hashGenesisBlock) < BestBlockHashArith) {
        //         BestBlockHash = consensus.hashGenesisBlock;
        //         std::cout << BestBlockHash.GetHex() << " Nonce: " << i << "\n";
        //         std::cout << "   PrevBlockxHash: " << genesis.hashPrevBlock.GetHex() << "\n";
        // 	std::cout << "hashGenesisBlocxk to 0x" << BestBlockHash.GetHex() << std::endl;
        // 	std::cout << "Genesis xNonce to " << genesisNonce << std::endl;
        // 	std::cout << "Genesisx Merkle " << genesis.hashMerkleRoot.GetHex() << std::endl;
        //     }
        //     TempHashHolding = consensus.hashGenesisBlock;
        //     if (BestBlockHashArith < test) {
        //         genesisNonce = i - 1;
        //         break;
        //     }
        //     //std::cout << consensus.hashGenesisBlock.GetHex() << "\n";
        // }
        // std::cout << "\n";
        // std::cout << "\n";
        // std::cout << "FINAL\n";
        // std::cout << "hashGenesisBlock to 0x" << BestBlockHash.GetHex() << std::endl;
        // std::cout << "Genesis Nonce to " << genesisNonce << std::endl;
        // std::cout << "Genesis Merkle " << genesis.hashMerkleRoot.GetHex() << std::endl;
        // std::cout << "\n";
        // std::exit(0);
        assert(consensus.hashGenesisBlock == uint256S("0x000000263aa7c2332ccdaa9f5ae5b9008c685c6c263020d2529432ed5bd77b32"));
        assert(genesis.hashMerkleRoot     == uint256S("b6f05125e30ba39aac82cd89a07afe985ecf1fbbceeb2abde4e6e78da22a9b22"));
        //Initial seeders for use
        vSeeds.push_back(CDNSSeedData("mineit.io", "mineit.io", false));
        vSeeds.push_back(CDNSSeedData("202.182.107.84", "202.182.107.84", false));
        vSeeds.push_back(CDNSSeedData("idxseeder.mineit.io", "idxseeder.ineit.io", false));
        vSeeds.push_back(CDNSSeedData("45.76.196.198", "45.76.196.198", false));
        vSeeds.push_back(CDNSSeedData("198.13.41.221", "198.13.41.221", false));
        vSeeds.push_back(CDNSSeedData("202.182.101.157", "202.182.101.157", false));
        vSeeds.push_back(CDNSSeedData("207.148.96.237", "207.148.96.237", false));

        // Note that of those with the service bits flag, most only support a subset of possible options
        base58Prefixes[PUBKEY_ADDRESS] = std::vector < unsigned char > (1, 102);//Index address starts with 'i'
        base58Prefixes[SCRIPT_ADDRESS] = std::vector < unsigned char > (1, 7);
        base58Prefixes[SECRET_KEY] = std::vector < unsigned char > (1, 210);
        base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x88)(0xB2)(0x1E).convert_to_container < std::vector < unsigned char > > ();
        base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x88)(0xAD)(0xE4).convert_to_container < std::vector < unsigned char > > ();

        vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_main, pnSeed6_main + ARRAYLEN(pnSeed6_main));

        fMiningRequiresPeers = false;
        fDefaultConsistencyChecks = false;
        fRequireStandard = true;
        fMineBlocksOnDemand = false;
        fTestnetToBeDeprecatedFieldRPC = false;
        nConsecutivePoWHeight = 40000;
        nMaxPoWBlocks = 1000;
        checkpointData = (CCheckpointData) {
                boost::assign::map_list_of
                    (0, genesis.GetHash()),
                ZC_GENESIS_BLOCK_TIME, // * UNIX timestamp of last checkpoint block
                2,    // * total number of transactions between genesis and last checkpoint
                //   (the tx=... number in the SetBestChain debug.log lines)
                1440     // * estimated number of transactions per day after checkpoint
        };
        consensus.nSpendV15StartBlock = ZC_V1_5_STARTING_BLOCK;
        consensus.nSpendV2ID_1 = ZC_V2_SWITCH_ID_1;
        consensus.nSpendV2ID_10 = ZC_V2_SWITCH_ID_10;
        consensus.nSpendV2ID_25 = ZC_V2_SWITCH_ID_25;
        consensus.nSpendV2ID_50 = ZC_V2_SWITCH_ID_50;
        consensus.nSpendV2ID_100 = ZC_V2_SWITCH_ID_100;
        consensus.nModulusV2StartBlock = ZC_MODULUS_V2_START_BLOCK;
        consensus.nModulusV1MempoolStopBlock = ZC_MODULUS_V1_MEMPOOL_STOP_BLOCK;
        consensus.nModulusV1StopBlock = ZC_MODULUS_V1_STOP_BLOCK;

        // Sigma related values.
        consensus.nSigmaStartBlock = ZC_SIGMA_STARTING_BLOCK;
        consensus.nSigmaPaddingBlock = ZC_SIGMA_PADDING_BLOCK;
        consensus.nDisableUnpaddedSigmaBlock = ZC_SIGMA_DISABLE_UNPADDED_BLOCK;
        consensus.nOldSigmaBanBlock = ZC_OLD_SIGMA_BAN_BLOCK;
        consensus.nZerocoinV2MintMempoolGracefulPeriod = ZC_V2_MINT_GRACEFUL_MEMPOOL_PERIOD;
        consensus.nZerocoinV2MintGracefulPeriod = ZC_V2_MINT_GRACEFUL_PERIOD;
        consensus.nZerocoinV2SpendMempoolGracefulPeriod = ZC_V2_SPEND_GRACEFUL_MEMPOOL_PERIOD;
        consensus.nZerocoinV2SpendGracefulPeriod = ZC_V2_SPEND_GRACEFUL_PERIOD;
        consensus.nMaxSigmaInputPerBlock = ZC_SIGMA_INPUT_LIMIT_PER_BLOCK;
        consensus.nMaxValueSigmaSpendPerBlock = ZC_SIGMA_VALUE_SPEND_LIMIT_PER_BLOCK;
        consensus.nMaxSigmaInputPerTransaction = ZC_SIGMA_INPUT_LIMIT_PER_TRANSACTION;
        consensus.nMaxValueSigmaSpendPerTransaction = ZC_SIGMA_VALUE_SPEND_LIMIT_PER_TRANSACTION;
        consensus.nZerocoinToSigmaRemintWindowSize = 0;

        // Dandelion related values.
        consensus.nDandelionEmbargoMinimum = DANDELION_EMBARGO_MINIMUM;
        consensus.nDandelionEmbargoAvgAdd = DANDELION_EMBARGO_AVG_ADD;
        consensus.nDandelionMaxDestinations = DANDELION_MAX_DESTINATIONS;
        consensus.nDandelionShuffleInterval = DANDELION_SHUFFLE_INTERVAL;
        consensus.nDandelionFluff = DANDELION_FLUFF;
    }
};

static CMainParams mainParams;

/**
 * Testnet (v3)
 */
class CTestNetParams : public CChainParams {
public:
    CTestNetParams() {
        strNetworkID = "test";

        consensus.chainType = Consensus::chainTestnet;

        consensus.nSubsidyHalvingFirst = 302438;
        consensus.nSubsidyHalvingInterval = 420000;
        consensus.nSubsidyHalvingStopBlock = 3646849;

        consensus.nMajorityEnforceBlockUpgrade = 51;
        consensus.nMajorityRejectBlockOutdated = 75;
        consensus.nMajorityWindow = 100;
        consensus.BIP34Hash = uint256S("0x0000000023b3a96d3484e5abb3755c413e7d41500f8e2a5c3f0dd01299cd8ef8");
        consensus.powLimit = uint256S("00000fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
        consensus.posLimit = uint256S("00ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
        //Proof-of-Stake related values
        consensus.nFirstPOSBlock = 135;//TODO akshaynexus :This needs to be decided
        consensus.nStakeTimestampMask = 0xf; // 15
        consensus.nPowTargetTimespan = 5 * 60; // 5 minutes between retargets
        consensus.nPowTargetSpacing = 1 * 60; // 1 minute blocks
        consensus.fPowAllowMinDifficultyBlocks = true;
        consensus.fPowNoRetargeting = false;
        consensus.nRuleChangeActivationThreshold = 1512; // 75% for testchains
        consensus.nMinerConfirmationWindow = 2016; // nPowTargetTimespan / nPowTargetSpacing
        consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
        consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 1199145601; // January 1, 2008
        consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 1230767999; // December 31, 2008

        // Deployment of BIP68, BIP112, and BIP113.
        consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
        consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 1456790400; // March 1st, 2016
        consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 1493596800; // May 1st, 2017

        // Deployment of SegWit (BIP141, BIP143, and BIP147)
        consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
        consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 1462060800; // May 1st 2016
        consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 1493596800; // May 1st 2017

        // The best chain should have at least this much work.
        consensus.nMinimumChainWork = uint256S("0x0");

        consensus.nSpendV15StartBlock = 5000;
        consensus.nCheckBugFixedAtBlock = 1;
        consensus.nIndexnodePaymentsBugFixedAtBlock = 1;

        consensus.nSpendV2ID_1 = ZC_V2_TESTNET_SWITCH_ID_1;
        consensus.nSpendV2ID_10 = ZC_V2_TESTNET_SWITCH_ID_10;
        consensus.nSpendV2ID_25 = ZC_V2_TESTNET_SWITCH_ID_25;
        consensus.nSpendV2ID_50 = ZC_V2_TESTNET_SWITCH_ID_50;
        consensus.nSpendV2ID_100 = ZC_V2_TESTNET_SWITCH_ID_100;
        consensus.nModulusV2StartBlock = ZC_MODULUS_V2_TESTNET_START_BLOCK;
        consensus.nModulusV1MempoolStopBlock = ZC_MODULUS_V1_TESTNET_MEMPOOL_STOP_BLOCK;
        consensus.nModulusV1StopBlock = ZC_MODULUS_V1_TESTNET_STOP_BLOCK;
        consensus.nMultipleSpendInputsInOneTxStartBlock = 1;
        consensus.nDontAllowDupTxsStartBlock = 18825;

        // Indexnode params testnet
        consensus.nIndexnodePaymentsStartBlock = 2200;
        nMaxTipAge = 0x7fffffff; // allow mining on top of old blocks for testnet

        consensus.nDisableZerocoinStartBlock = 50500;

        nPoolMaxTransactions = 3;
        nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes
        strSporkPubKey = "046f78dcf911fbd61910136f7f0f8d90578f68d0b3ac973b5040fb7afb501b5939f39b108b0569dca71488f5bbf498d92e4d1194f6f941307ffd95f75e76869f0e";
        strIndexnodePaymentsPubKey = "046f78dcf911fbd61910136f7f0f8d90578f68d0b3ac973b5040fb7afb501b5939f39b108b0569dca71488f5bbf498d92e4d1194f6f941307ffd95f75e76869f0e";

        pchMessageStart[0] = 0xcf;
        pchMessageStart[1] = 0xfc;
        pchMessageStart[2] = 0xbe;
        pchMessageStart[3] = 0xea;
        nDefaultPort = 18168;
        nPruneAfterHeight = 1000;
        /**
         * btzc: testnet params
         * nTime: 1414776313
         * nNonce: 1620571
         */
        std::vector<unsigned char> extraNonce(4);
        extraNonce[0] = 0x08;
        extraNonce[1] = 0x00;
        extraNonce[2] = 0x00;
        extraNonce[3] = 0x00;
        genesis = CreateGenesisBlock(ZC_GENESIS_BLOCK_TIME, 215095, 504365040, 2, 0 * COIN, extraNonce);
        consensus.hashGenesisBlock = genesis.GetHash();
        // uint32_t nGenesisTime = ZC_GENESIS_BLOCK_TIME;
        // arith_uint256 test;
        // bool fNegative;
        // bool fOverflow;
        // test.SetCompact(504365040, &fNegative, &fOverflow);
        // std::cout << "Test threshold: " << test.GetHex() << "\n\n";
        // int genesisNonce = 0;
        // uint256 TempHashHolding = uint256S("0x0000000000000000000000000000000000000000000000000000000000000000");
        // uint256 BestBlockHash = uint256S("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
        // for (int i=0;i<40000000;i++) {
        //     genesis = CreateGenesisBlock(nGenesisTime, i, 504365040, 2, 0 * COIN,extraNonce);
        //     //genesis.hashPrevBlock = TempHashHolding;
        //     consensus.hashGenesisBlock = genesis.GetHash();
        //     arith_uint256 BestBlockHashArith = UintToArith256(BestBlockHash);
        //     if (UintToArith256(consensus.hashGenesisBlock) < BestBlockHashArith) {
        //         BestBlockHash = consensus.hashGenesisBlock;
        //         std::cout << BestBlockHash.GetHex() << " Nonce: " << i << "\n";
        //         std::cout << "   PrevBlockxHash: " << genesis.hashPrevBlock.GetHex() << "\n";
        // 	std::cout << "hashGenesisBlocxk to 0x" << BestBlockHash.GetHex() << std::endl;
        // 	std::cout << "Genesis xNonce to " << genesisNonce << std::endl;
        // 	std::cout << "Genesisx Merkle " << genesis.hashMerkleRoot.GetHex() << std::endl;
        //     }
        //     TempHashHolding = consensus.hashGenesisBlock;
        //     if (BestBlockHashArith < test) {
        //         genesisNonce = i - 1;
        //         break;
        //     }
        //     //std::cout << consensus.hashGenesisBlock.GetHex() << "\n";
        // }
        // std::cout << "\n";
        // std::cout << "\n";
        // std::cout << "FINALTEST\n";
        // std::cout << "hashGenesisBlock to 0x" << BestBlockHash.GetHex() << std::endl;
        // std::cout << "Genesis Nonce to " << genesisNonce << std::endl;
        // std::cout << "Genesis Merkle " << genesis.hashMerkleRoot.GetHex() << std::endl;
        // std::cout << "ENDTEST\n";
        // std::exit(0);
        // std::cout << "index testnet genesisBlock hash: " << consensus.hashGenesisBlock.ToString() << std::endl;
        // std::cout << "index testnet hashMerkleRoot hash: " << genesis.hashMerkleRoot.ToString() << std::endl;
        // //btzc: update testnet index hashGenesisBlock and hashMerkleRoot

        assert(consensus.hashGenesisBlock ==
                uint256S("0x00000bab1c62ca4063a0b1c2f0562cf6427e047333359106b8799cfa923c79f3"));
        assert(genesis.hashMerkleRoot ==
                uint256S("3f105b7ee0068c963cab5e889bcec419d82646b9060905f559eb8c4c1975f4c6"));
        vFixedSeeds.clear();
        vSeeds.clear();
        // nodes with support for servicebits filtering should be at the top
        // index test seeds
        // vSeeds.push_back(CDNSSeedData("beta1.indexchain.org", "beta1.indexchain.org", false));

        base58Prefixes[PUBKEY_ADDRESS] = std::vector < unsigned char > (1, 65);
        base58Prefixes[SCRIPT_ADDRESS] = std::vector < unsigned char > (1, 178);
        base58Prefixes[SECRET_KEY] = std::vector < unsigned char > (1, 185);
        base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container < std::vector < unsigned char > > ();
        base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container < std::vector < unsigned char > > ();
        vFixedSeeds = std::vector<SeedSpec6>(pnSeed6_test, pnSeed6_test + ARRAYLEN(pnSeed6_test));

        fMiningRequiresPeers = true;
        fDefaultConsistencyChecks = false;
        fRequireStandard = false;
        fMineBlocksOnDemand = false;
        fTestnetToBeDeprecatedFieldRPC = true;

        checkpointData = (CCheckpointData) {
                boost::assign::map_list_of
                    (0, uint256S("0x00000bab1c62ca4063a0b1c2f0562cf6427e047333359106b8799cfa923c79f3")),
                    ZC_GENESIS_BLOCK_TIME,
                    0,
                    100.0
        };

        consensus.nSpendV15StartBlock = ZC_V1_5_TESTNET_STARTING_BLOCK;
        consensus.nSpendV2ID_1 = ZC_V2_TESTNET_SWITCH_ID_1;
        consensus.nSpendV2ID_10 = ZC_V2_TESTNET_SWITCH_ID_10;
        consensus.nSpendV2ID_25 = ZC_V2_TESTNET_SWITCH_ID_25;
        consensus.nSpendV2ID_50 = ZC_V2_TESTNET_SWITCH_ID_50;
        consensus.nSpendV2ID_100 = ZC_V2_TESTNET_SWITCH_ID_100;
        consensus.nModulusV2StartBlock = ZC_MODULUS_V2_TESTNET_START_BLOCK;
        consensus.nModulusV1MempoolStopBlock = ZC_MODULUS_V1_TESTNET_MEMPOOL_STOP_BLOCK;
        consensus.nModulusV1StopBlock = ZC_MODULUS_V1_TESTNET_STOP_BLOCK;
        // Sigma related values.
        consensus.nSigmaStartBlock = ZC_SIGMA_TESTNET_STARTING_BLOCK;
        consensus.nSigmaPaddingBlock = ZC_SIGMA_TESTNET_PADDING_BLOCK;
        consensus.nDisableUnpaddedSigmaBlock = ZC_SIGMA_TESTNET_DISABLE_UNPADDED_BLOCK;
        consensus.nOldSigmaBanBlock = 70416;
        consensus.nZerocoinV2MintMempoolGracefulPeriod = ZC_V2_MINT_TESTNET_GRACEFUL_MEMPOOL_PERIOD;
        consensus.nZerocoinV2MintGracefulPeriod = ZC_V2_MINT_TESTNET_GRACEFUL_PERIOD;
        consensus.nZerocoinV2SpendMempoolGracefulPeriod = ZC_V2_SPEND_TESTNET_GRACEFUL_MEMPOOL_PERIOD;
        consensus.nZerocoinV2SpendGracefulPeriod = ZC_V2_SPEND_TESTNET_GRACEFUL_PERIOD;
            consensus.nMaxSigmaInputPerBlock = ZC_SIGMA_INPUT_LIMIT_PER_BLOCK;
            consensus.nMaxValueSigmaSpendPerBlock = ZC_SIGMA_VALUE_SPEND_LIMIT_PER_BLOCK;
            consensus.nMaxSigmaInputPerTransaction = ZC_SIGMA_INPUT_LIMIT_PER_TRANSACTION;
            consensus.nMaxValueSigmaSpendPerTransaction = ZC_SIGMA_VALUE_SPEND_LIMIT_PER_TRANSACTION;
            consensus.nZerocoinToSigmaRemintWindowSize = 50000;

            // Dandelion related values.
            consensus.nDandelionEmbargoMinimum = DANDELION_TESTNET_EMBARGO_MINIMUM;
            consensus.nDandelionEmbargoAvgAdd = DANDELION_TESTNET_EMBARGO_AVG_ADD;
            consensus.nDandelionMaxDestinations = DANDELION_MAX_DESTINATIONS;
            consensus.nDandelionShuffleInterval = DANDELION_SHUFFLE_INTERVAL;
            consensus.nDandelionFluff = DANDELION_FLUFF;
    }
};

static CTestNetParams testNetParams;

/**
 * Regression test
 */
class CRegTestParams : public CChainParams {
public:
    CRegTestParams() {
        strNetworkID = "regtest";

        consensus.chainType = Consensus::chainRegtest;

        consensus.nSubsidyHalvingFirst = 302438;
        consensus.nSubsidyHalvingInterval = 420000;
        consensus.nSubsidyHalvingStopBlock = 3646849;

        consensus.nMajorityEnforceBlockUpgrade = 750;
        consensus.nMajorityRejectBlockOutdated = 950;
        consensus.nMajorityWindow = 1000;
        consensus.powLimit = uint256S("7fffff0000000000000000000000000000000000000000000000000000000000");
        consensus.nPowTargetTimespan = 60 * 60 * 1000; // 60 minutes between retargets
        consensus.nPowTargetSpacing = 1; // 10 minute blocks
        consensus.fPowAllowMinDifficultyBlocks = true;
        consensus.fPowNoRetargeting = true;
        consensus.nIndexnodePaymentsStartBlock = 120;
        consensus.nRuleChangeActivationThreshold = 108; // 75% for testchains
        consensus.nMinerConfirmationWindow = 144; // Faster than normal for regtest (144 instead of 2016)
        consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].bit = 28;
        consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nStartTime = 0;
        consensus.vDeployments[Consensus::DEPLOYMENT_TESTDUMMY].nTimeout = 999999999999ULL;
        consensus.vDeployments[Consensus::DEPLOYMENT_CSV].bit = 0;
        consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nStartTime = 0;
        consensus.vDeployments[Consensus::DEPLOYMENT_CSV].nTimeout = 999999999999ULL;
        consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].bit = 1;
        consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nStartTime = 0;
        consensus.vDeployments[Consensus::DEPLOYMENT_SEGWIT].nTimeout = 999999999999ULL;

        // The best chain should have at least this much work.
        consensus.nMinimumChainWork = uint256S("0x00");
        // Indexnode code
        nFulfilledRequestExpireTime = 5*60; // fulfilled requests expire in 5 minutes
        nMaxTipAge = 6 * 60 * 60; // ~144 blocks behind -> 2 x fork detection time, was 24 * 60 * 60 in bitcoin

        consensus.nCheckBugFixedAtBlock = 120;
        consensus.nIndexnodePaymentsBugFixedAtBlock = 1;
        consensus.nSpendV15StartBlock = 1;
        consensus.nSpendV2ID_1 = 2;
        consensus.nSpendV2ID_10 = 3;
        consensus.nSpendV2ID_25 = 3;
        consensus.nSpendV2ID_50 = 3;
        consensus.nSpendV2ID_100 = 3;
        consensus.nModulusV2StartBlock = 130;
        consensus.nModulusV1MempoolStopBlock = 135;
        consensus.nModulusV1StopBlock = 140;
        consensus.nMultipleSpendInputsInOneTxStartBlock = 1;
        consensus.nDontAllowDupTxsStartBlock = 1;

        consensus.nDisableZerocoinStartBlock = INT_MAX;

        pchMessageStart[0] = 0xfa;
        pchMessageStart[1] = 0xbf;
        pchMessageStart[2] = 0xb5;
        pchMessageStart[3] = 0xda;
        nDefaultPort = 18444;
        nPruneAfterHeight = 1000;

        /**
          * btzc: testnet params
          * nTime: 1414776313
          * nNonce: 1620571
          */
        std::vector<unsigned char> extraNonce(4);
        extraNonce[0] = 0x08;
        extraNonce[1] = 0x00;
        extraNonce[2] = 0x00;
        extraNonce[3] = 0x00;
        genesis = CreateGenesisBlock(ZC_GENESIS_BLOCK_TIME, 5, 0x207fffff, 2, 0 * COIN, extraNonce);
        consensus.hashGenesisBlock = genesis.GetHash();
        // uint32_t nGenesisTime = ZC_GENESIS_BLOCK_TIME;
        // arith_uint256 test;
        // bool fNegative;
        // bool fOverflow;
        // test.SetCompact(0x207fffff, &fNegative, &fOverflow);
        // std::cout << "Test threshold: " << test.GetHex() << "\n\n";
        // int genesisNonce = 0;
        // uint256 TempHashHolding = uint256S("0x0000000000000000000000000000000000000000000000000000000000000000");
        // uint256 BestBlockHash = uint256S("0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff");
        // for (int i=0;i<40000000;i++) {
        //     genesis = CreateGenesisBlock(nGenesisTime, i, 0x207fffff, 2, 0 * COIN,extraNonce);
        //     //genesis.hashPrevBlock = TempHashHolding;
        //     consensus.hashGenesisBlock = genesis.GetHash();
        //     arith_uint256 BestBlockHashArith = UintToArith256(BestBlockHash);
        //     if (UintToArith256(consensus.hashGenesisBlock) < BestBlockHashArith) {
        //         BestBlockHash = consensus.hashGenesisBlock;
        //         std::cout << BestBlockHash.GetHex() << " Nonce: " << i << "\n";
        //         std::cout << "   PrevBlockxHash: " << genesis.hashPrevBlock.GetHex() << "\n";
        // 	std::cout << "hashGenesisBlocxk to 0x" << BestBlockHash.GetHex() << std::endl;
        // 	std::cout << "Genesis xNonce to " << genesisNonce << std::endl;
        // 	std::cout << "Genesisx Merkle " << genesis.hashMerkleRoot.GetHex() << std::endl;
        //     }
        //     TempHashHolding = consensus.hashGenesisBlock;
        //     if (BestBlockHashArith < test) {
        //         genesisNonce = i - 1;
        //         break;
        //     }
        //     //std::cout << consensus.hashGenesisBlock.GetHex() << "\n";
        // }
        // std::cout << "\n";
        // std::cout << "\n";
        // std::cout << "FINAL\n";
        // std::cout << "REGTEST hashGenesisBlock to 0x" << BestBlockHash.GetHex() << std::endl;
        // std::cout << "REGTEST Genesis Nonce to " << genesisNonce << std::endl;
        // std::cout << "REGTEST Genesis Merkle " << genesis.hashMerkleRoot.GetHex() << std::endl;
        // std::cout << "\n";
        //    exit(0);
        //btzc: update regtest index hashGenesisBlock and hashMerkleRoot
    //    std::cout << "index regtest genesisBlock hash: " << consensus.hashGenesisBlock.ToString() << std::endl;
    //    std::cout << "index regtest hashMerkleRoot hash: " << genesis.hashMerkleRoot.ToString() << std::endl;
        //btzc: update testnet index hashGenesisBlock and hashMerkleRoot
        assert(consensus.hashGenesisBlock ==
              uint256S("0x5b3c937d388c0d1682d5ce5a6483a0f4cdd5c398346432ad6a4a54f6e4cb084d"));
        assert(genesis.hashMerkleRoot ==
              uint256S("3f105b7ee0068c963cab5e889bcec419d82646b9060905f559eb8c4c1975f4c6"));
        //Disable consecutive checks
        nConsecutivePoWHeight = INT_MAX;
        nMaxPoWBlocks = 101;
        consensus.nFirstPOSBlock = nConsecutivePoWHeight;//TODO akshaynexus :This needs to be decided

        vFixedSeeds.clear(); //!< Regtest mode doesn't have any fixed seeds.
        vSeeds.clear();      //!< Regtest mode doesn't have any DNS seeds.

        fMiningRequiresPeers = false;
        fDefaultConsistencyChecks = true;
        fRequireStandard = false;
        fMineBlocksOnDemand = true;
        fTestnetToBeDeprecatedFieldRPC = false;

        checkpointData = (CCheckpointData) {
            boost::assign::map_list_of
                (0, uint256S("0x5b3c937d388c0d1682d5ce5a6483a0f4cdd5c398346432ad6a4a54f6e4cb084d")),
                0,
                0,
                0
        };
        base58Prefixes[PUBKEY_ADDRESS] = std::vector < unsigned char > (1, 65);
        base58Prefixes[SCRIPT_ADDRESS] = std::vector < unsigned char > (1, 178);
        base58Prefixes[SECRET_KEY] = std::vector < unsigned char > (1, 239);
        base58Prefixes[EXT_PUBLIC_KEY] = boost::assign::list_of(0x04)(0x35)(0x87)(0xCF).convert_to_container < std::vector < unsigned char > > ();
        base58Prefixes[EXT_SECRET_KEY] = boost::assign::list_of(0x04)(0x35)(0x83)(0x94).convert_to_container < std::vector < unsigned char > > ();

        nSpendV15StartBlock = ZC_V1_5_TESTNET_STARTING_BLOCK;
        nSpendV2ID_1 = ZC_V2_TESTNET_SWITCH_ID_1;
        nSpendV2ID_10 = ZC_V2_TESTNET_SWITCH_ID_10;
        nSpendV2ID_25 = ZC_V2_TESTNET_SWITCH_ID_25;
        nSpendV2ID_50 = ZC_V2_TESTNET_SWITCH_ID_50;
        nSpendV2ID_100 = ZC_V2_TESTNET_SWITCH_ID_100;
        nModulusV2StartBlock = ZC_MODULUS_V2_TESTNET_START_BLOCK;
        nModulusV1MempoolStopBlock = ZC_MODULUS_V1_TESTNET_MEMPOOL_STOP_BLOCK;
        nModulusV1StopBlock = ZC_MODULUS_V1_TESTNET_STOP_BLOCK;

        // Sigma related values.
        consensus.nSigmaStartBlock = 400;
        consensus.nSigmaPaddingBlock = 550;
        consensus.nDisableUnpaddedSigmaBlock = 510;
        consensus.nOldSigmaBanBlock = 450;
        consensus.nZerocoinV2MintMempoolGracefulPeriod = 2;
        consensus.nZerocoinV2MintGracefulPeriod = 5;
        consensus.nZerocoinV2SpendMempoolGracefulPeriod = 10;
        consensus.nZerocoinV2SpendGracefulPeriod = 20;
            consensus.nMaxSigmaInputPerBlock = ZC_SIGMA_INPUT_LIMIT_PER_BLOCK;
            consensus.nMaxValueSigmaSpendPerBlock = ZC_SIGMA_VALUE_SPEND_LIMIT_PER_BLOCK;
            consensus.nMaxSigmaInputPerTransaction = ZC_SIGMA_INPUT_LIMIT_PER_TRANSACTION;
            consensus.nMaxValueSigmaSpendPerTransaction = ZC_SIGMA_VALUE_SPEND_LIMIT_PER_TRANSACTION;
            consensus.nZerocoinToSigmaRemintWindowSize = 1000;

            // Dandelion related values.
            consensus.nDandelionEmbargoMinimum = 0;
            consensus.nDandelionEmbargoAvgAdd = 1;
            consensus.nDandelionMaxDestinations = DANDELION_MAX_DESTINATIONS;
            consensus.nDandelionShuffleInterval = DANDELION_SHUFFLE_INTERVAL;
            consensus.nDandelionFluff = DANDELION_FLUFF;
    }

    void UpdateBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) {
        consensus.vDeployments[d].nStartTime = nStartTime;
        consensus.vDeployments[d].nTimeout = nTimeout;
    }
};

static CRegTestParams regTestParams;

static CChainParams *pCurrentParams = 0;

const CChainParams &Params() {
    assert(pCurrentParams);
    return *pCurrentParams;
}

CChainParams &Params(const std::string &chain) {
    if (chain == CBaseChainParams::MAIN)
        return mainParams;
    else if (chain == CBaseChainParams::TESTNET)
        return testNetParams;
    else if (chain == CBaseChainParams::REGTEST)
        return regTestParams;
    else
        throw std::runtime_error(strprintf("%s: Unknown chain %s.", __func__, chain));
}

void SelectParams(const std::string &network) {
    SelectBaseParams(network);
    pCurrentParams = &Params(network);
}

void UpdateRegtestBIP9Parameters(Consensus::DeploymentPos d, int64_t nStartTime, int64_t nTimeout) {
    regTestParams.UpdateBIP9Parameters(d, nStartTime, nTimeout);
}

max_issues_repo_name: Lavacoreteam/Index

max_forks_repo_name: Lavacoreteam/Index


text:
/**
 * @example types/test/position_test.cc
 */
#include <boost/test/unit_test.hpp>
#include <usml/types/types.h>
#include <iostream>

BOOST_AUTO_TEST_SUITE(position_test)

using namespace boost::unit_test;
using namespace usml::types;

/**
 * @ingroup types_test
 * @{
 */

/**
 * Compare the earth's radius at specific latitudes to known values.
 * Generate errors if values differ by more that 1E-6 percent.
 *
 * @xref WGS 84 IMPLEMENTATION MANUAL, Version 2.4, 1998.
 *       See http://www.dqts.net/wgs84.htm for more information.
 */
BOOST_AUTO_TEST_CASE( earth_radius_test ) {
    cout << "=== position_test: earth_radius_test ===" << endl;

    double radius90 = 6399593.62578493 ;
    double radius45 = 6378101.030201019 ;
    double radius00 = 6356752.314245179 ;

    wposition::compute_earth_radius(90.0);
    cout << "earth_radius at 90.0 latitude: "
         << wposition::earth_radius << endl;
    BOOST_CHECK_CLOSE( wposition::earth_radius, radius90, 1e-6 );

    wposition::compute_earth_radius(45.0);
    cout << "earth_radius at 45.0 latitude: "
         << wposition::earth_radius << endl;
    BOOST_CHECK_CLOSE( wposition::earth_radius, radius45, 1e-6 );

    wposition::compute_earth_radius(0.0);
    cout << "earth_radius at  0.0 latitude: "
         << wposition::earth_radius << endl;
    BOOST_CHECK_CLOSE( wposition::earth_radius, radius00, 1e-6 );
}

/**
 * Compute the dot product between set of vectors at different latitudes
 * and a vector pointing due north.  If correct, the dots products
 * should correspond to the angles defined by the latitudes of
 * the original points.
 *
 * Generate errors if values differ by more that 1E-6 percent.
 */
BOOST_AUTO_TEST_CASE( dot_test ) {
    cout << "=== position_test: dot_test ===" << endl;

    // define a series of lat/long points on earth

    wposition points(10);
    for ( int n=0; n < 10; ++n ) {
        points.latitude( n, 0, 10.0*n );
        points.longitude( n, 0, 90.0+10.0*n );
    }

    // dot this with vector through the north pole

    wposition1 north( 90.0, 0.0 );
    matrix<double> angle( 10, 1 );
    points.dotnorm( north, angle );
    angle = to_degrees( acos(angle) );

    // check the answer

    for ( int n=0; n < 10; ++n ) {
        double analytic = 90.0 - 10.0 * n ;
        cout << "angle=" << angle(n,0) << " analytic=" << analytic << endl;
        BOOST_CHECK_CLOSE( angle(n,0), analytic, 1e-6 );
    }
}

/**
 * Compute the dot product between a vector at different latitudes
 * and a vector pointing due north.  If correct, the dots products
 * should correspond to the angles defined by the latitudes of
 * the original points.
 *
 * Generate errors if values differ by more that 1E-6 percent.
 */
BOOST_AUTO_TEST_CASE( dot1_test ) {
    cout << "=== position_test: dot1_test ===" << endl;

    // define a series of lat/long points on earth

    wposition1 point ;
    for ( int n=0; n < 10; ++n ) {
        point.latitude( 10.0*n );
        point.longitude( 90.0+10.0*n );

        // dot this with vector through the north pole

        wposition1 north( 90.0, 0.0 );
        double angle = point.dotnorm( north );
        angle = to_degrees( acos(angle) );

        // check the answer

        double analytic = 90.0 - 10.0 * n ;
        cout << "angle=" << angle << " analytic=" << analytic << endl;
        BOOST_CHECK_CLOSE( angle, analytic, 1e-6 );
    }
}

/**
 * Compute the straight line distance between a wposition vector
 * at different latitudes and the point 40N 45E. The results are
 * compared to the analytic solution
 *

 *          distance^2 = 2 R^2 ( 1-cos(40-latitude) )
 *

 * Generate errors if values differ by more that 1E-6 meters.  The one
 * expection to this accuracy is the case where distance is almost zero.
 * In that case, the calculation accuracy is limited to 0.02 meters.
 */
BOOST_AUTO_TEST_CASE( distance_test ) {
    cout << "=== position_test: distance_test ===" << endl;

    // define a series of lat/long points on earth

    wposition points(10);
    for ( int n=0; n < 10; ++n ) {
        points.latitude( n, 0, 10.0*n );
        points.longitude( n, 0, 45.0 );
    }

    // compute the distance to some point on earth

    wposition1 origin( 40.0, 45.0 );
    matrix<double> distance( 10, 1 );
    points.distance( origin, distance );

    // check the answer
    // distance^2 = 2 R^2 ( 1-cos(angle) )

    for ( int n=0; n < 10; ++n ) {
        double analytic = wposition::earth_radius
            * sqrt( 2.0 * ( 1.0 - cos( to_radians(40.0-10.0*n) ) ) );
        cout << "distance=" << distance(n,0) << " analytic=" << analytic << endl;
        if ( analytic > 1e-6 ) {
            BOOST_CHECK_CLOSE( distance(n,0), analytic, 1e-10 );
        } else {
            BOOST_CHECK_SMALL( distance(n,0)-analytic, 0.1 );
        }
    }
}

/**
 * Compute the straight line distance between a series of wposition1 vectors
 * at different latitudes and the point 40N 45E. The results are compared
 * to the analytic solution
 *

 *          distance^2 = 2 R^2 ( 1-cos(40-latitude) )
 *

 * Generate errors if values differ by more that 1E-6 meters.  The one
 * expection to this accuracy is the case where distance is almost zero.
 * In that case, the calculation accuracy is limited to 0.02 meters.
 */
BOOST_AUTO_TEST_CASE( distance1_test ) {
    cout << "=== position_test: distance1_test ===" << endl;

    // define a series of lat/long points on earth

    wposition1 point ;
    for ( int n=0; n < 10; ++n ) {
        point.latitude( 10.0*n );
        point.longitude( 45.0 );

        // compute the distance to some point on earth

        wposition1 origin( 40.0, 45.0 );
        double distance = point.distance( origin );

        // check the answer
        // distance^2 = 2 R^2 ( 1-cos(angle) )

        double analytic = wposition::earth_radius
            * sqrt( 2.0 * ( 1.0 - cos( to_radians(40.0-10.0*n) ) ) );
        cout << "distance=" << distance << " analytic=" << analytic << endl;
        if ( analytic > 1e-6 ) {
            BOOST_CHECK_CLOSE( distance, analytic, 1e-10 );
        } else {
            BOOST_CHECK_SMALL( distance-analytic, 0.1 );
        }
    }
}

/**
 * Compute the great circle range and bearing between JFK and LAX airports.
 * Based on the "Worked Examples" in Aviation Formulary.
 * Requires an earth radius based on the definition where
 * 1 nmi = 1 min latitude = 1852.0 meters. Generate errors if values differ
 * from Williams' answers, in radians, by more that 1e-4%
 *
 * The process is then reversed to predict the location of JFK using this
 * range and bearing from LAX.  Those answers are required to be within
 * 1e-10% of the true location for JFK.
 *
 * @xref E. Williams, "Aviation Formulary V1.43",
 * http://williams.best.vwh.net/avform.htm , July 2010.
 */
BOOST_AUTO_TEST_CASE( gc_range_test ) {
    cout << "=== position_test: gc_range_test ===" << endl;
    double orig_radius = wposition::earth_radius ;
    wposition::earth_radius =  180.0/M_PI*60.0*1852.0 ; // radius used in Aviation Formulary.

    // compute range and bearing from LAX to JFK

    wposition1 jfk( 40.0 + 38.0/60.0, -(73.0 + 47.0/60.0) ) ;
    wposition1 lax( 33.0 + 57.0/60.0, -(118.0 + 24.0/60.0) ) ;

    double range, bearing ;
    range = lax.gc_range( jfk, &bearing ) ;

    cout << "LAX to JFK: range = " << (range/wposition::earth_radius) << " rad bearing = " << bearing << " rad" << endl ;
    cout << "LAX to JFK: range = " << (range/1852.0) << " nmi bearing = " << to_degrees(bearing) << " deg" << endl ;

    BOOST_CHECK_CLOSE( range/wposition::earth_radius, 0.623585, 1e-4 );
    BOOST_CHECK_CLOSE( bearing, 1.150035, 1e-4 );

    // reverse the process by computing location at this range/bearing from LAX

    wposition1 unk( lax, range, bearing ) ;
    cout << "JFK: " << jfk.latitude() << "N " << -jfk.longitude() << "W" << endl ;
    cout << "UNK: " << unk.latitude() << "N " << -unk.longitude() << "W" << endl ;

    BOOST_CHECK_CLOSE( unk.latitude(), jfk.latitude(), 1e-10 );
    BOOST_CHECK_CLOSE( unk.longitude(), jfk.longitude(), 1e-10 );

    wposition::earth_radius = orig_radius ;
}

/// @}

BOOST_AUTO_TEST_SUITE_END()

ext: cc

max_stars_repo_name: fraclipe/UnderSeaModelingLibrary

max_issues_repo_name: Wolframy-NUDT/UnderSeaModelingLibrary

max_forks_repo_name: Wolframy-NUDT/UnderSeaModelingLibrary


text:
#pragma once

#include <deal.II/base/mpi.h>
#include <deal.II/dofs/dof_handler.h>
#include <deal.II/dofs/dof_renumbering.h>
#include <deal.II/grid/grid_tools.h>
#include <deal.II/grid/tria.h>

#include "grid/grid_partitioner.hpp"

namespace boltzmann {

class GridPartitionerLinear : public GridPartitioner<2>
{
 public:
  GridPartitionerLinear()
      : GridPartitionerLinear(-1)
  { }

  GridPartitionerLinear(int nprocs)
  {
    if (nprocs == -1)
      nprocs_ = dealii::Utilities::MPI::n_mpi_processes(MPI_COMM_WORLD);
    else
      nprocs_ = nprocs;
  }

  int n_processes() const { return nprocs_; }

  /**
   * Distribute cells by cell_id on processors...
   *
   * @param dof_handler
   * @param triangulation
   */
  virtual void partition(dealii::DoFHandler<2>& dof_handler,
                         dealii::Triangulation<2>& triangulation) const;

 protected:
  using GridPartitioner<2>::nprocs_;
};

void GridPartitionerLinear::partition(dealii::DoFHandler<2>& dof_handler,
                                      dealii::Triangulation<2>& triangulation) const
{
  const int DIM = 2;
  // partition triangulationp
  const unsigned int nelems = triangulation.n_active_quads();
  const unsigned int local_size = std::ceil(nelems / (1.0 * nprocs_));

  for (auto cell_it : triangulation.active_cell_iterators()) {
    // tested index returns the cell label defined by gmsh
    int i = cell_it->index();
    //    int subdomain_id = vertices[i][dir] / delta;
    int subdomain_id = i / local_size;

    AssertThrow(subdomain_id < nprocs_, dealii::ExcMessage("index error"));

    cell_it->set_subdomain_id(subdomain_id);
  }

  dealii::DoFRenumbering::boost::Cuthill_McKee(dof_handler);
  dealii::DoFRenumbering::subdomain_wise(dof_handler);
}

}  // end namespace boltzmann


text:
//------------------------------------------------------------------------------
/*
    This file is part of rippled: https://github.com/ripple/rippled
    Copyright (c) 2012, 2013 Ripple Labs Inc.

    Permission to use, copy, modify, and/or distribute this software for any
    purpose  with  or without fee is hereby granted, provided that the above
    copyright notice and this permission notice appear in all copies.

    THE  SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
    WITH  REGARD  TO  THIS  SOFTWARE  INCLUDING  ALL  IMPLIED  WARRANTIES  OF
    MERCHANTABILITY  AND  FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
    ANY  SPECIAL ,  DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
    WHATSOEVER  RESULTING  FROM  LOSS  OF USE, DATA OR PROFITS, WHETHER IN AN
    ACTION  OF  CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
    OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
//==============================================================================

#include <ripple/basics/BasicConfig.h>
#include <ripple/basics/StringUtilities.h>
#include <boost/regex.hpp>
#include <algorithm>

namespace ripple {

Section::Section(std::string const& name) : name_(name)
{
}

void
Section::set(std::string const& key, std::string const& value)
{
    lookup_.insert_or_assign(key, value);
}

void
Section::append(std::vector<std::string> const& lines)
{
    // <key> '=' <value>
    static boost::regex const re1(
        "^"                        // start of line
        "(?:\\s*)"                 // whitespace (optonal)
        "([a-zA-Z][_a-zA-Z0-9]*)"  // <key>
        "(?:\\s*)"                 // whitespace (optional)
        "(?:=)"                    // '='
        "(?:\\s*)"                 // whitespace (optional)
        "(.*\\S+)"                 // <value>
        "(?:\\s*)"                 // whitespace (optional)
        ,
        boost::regex_constants::optimize);

    lines_.reserve(lines_.size() + lines.size());
    for (auto line : lines)
    {
        auto remove_comment = [](std::string& val) -> bool {
            bool removed_trailing = false;
            auto comment = val.find('#');
            while (comment != std::string::npos)
            {
                if (comment == 0)
                {
                    // entire value is a comment. In most cases, this
                    // would have already been handled by the file reader
                    val = "";
                    break;
                }
                else if (val.at(comment - 1) == '\\')
                {
                    // we have an escaped comment char. Erase the escape char
                    // and keep looking
                    val.erase(comment - 1, 1);
                }
                else
                {
                    // this must be a real comment. Extract the value
                    // as a substring and stop looking.
                    val = trim_whitespace(val.substr(0, comment));
                    removed_trailing = true;
                    break;
                }

                comment = val.find('#', comment);
            }
            return removed_trailing;
        };

        if (remove_comment(line) && !line.empty())
            had_trailing_comments_ = true;

        if (line.empty())
            continue;

        boost::smatch match;
        if (boost::regex_match(line, match, re1))
            set(match[1], match[2]);
        else
            values_.push_back(line);

        lines_.push_back(std::move(line));
    }
}

bool
Section::exists(std::string const& name) const
{
    return lookup_.find(name) != lookup_.end();
}

std::ostream&
operator<<(std::ostream& os, Section const& section)
{
    for (auto const& [k, v] : section.lookup_)
        os << k << "=" << v << "\n";
    return os;
}

//------------------------------------------------------------------------------

bool
BasicConfig::exists(std::string const& name) const
{
    return map_.find(name) != map_.end();
}

Section&
BasicConfig::section(std::string const& name)
{
    return map_[name];
}

Section const&
BasicConfig::section(std::string const& name) const
{
    static Section none("");
    auto const iter = map_.find(name);
    if (iter == map_.end())
        return none;
    return iter->second;
}

void
BasicConfig::overwrite(
    std::string const& section,
    std::string const& key,
    std::string const& value)
{
    auto const result = map_.emplace(
        std::piecewise_construct,
        std::make_tuple(section),
        std::make_tuple(section));
    result.first->second.set(key, value);
}

void
BasicConfig::deprecatedClearSection(std::string const& section)
{
    auto i = map_.find(section);
    if (i != map_.end())
        i->second = Section(section);
}

void
BasicConfig::legacy(std::string const& section, std::string value)
{
    map_[section].legacy(std::move(value));
}

std::string
BasicConfig::legacy(std::string const& sectionName) const
{
    return section(sectionName).legacy();
}

void
BasicConfig::build(IniFileSections const& ifs)
{
    for (auto const& entry : ifs)
    {
        auto const result = map_.emplace(
            std::piecewise_construct,
            std::make_tuple(entry.first),
            std::make_tuple(entry.first));
        result.first->second.append(entry.second);
    }
}

std::ostream&
operator<<(std::ostream& ss, BasicConfig const& c)
{
    for (auto const& [k, v] : c.map_)
        ss << "[" << k << "]\n" << v;
    return ss;
}

}  // namespace ripple

max_stars_repo_name: fff-source/rippled

max_issues_repo_name: fff-source/rippled

max_forks_repo_name: fff-source/rippled


text:
#include <fstream>
#include <iostream>
#include <vector>

#include "boost/filesystem.hpp"
#include <boost/algorithm/string.hpp>

#include "BINPointReader.hpp"

namespace fs = boost::filesystem;

using std::ifstream;
using std::cout;
using std::endl;
using std::vector;
using boost::iequals;
using std::ios;

BINPointReader::BINPointReader(string path,  AABB aabb, double scale){
	this->path = path;
	this->aabb = aabb;
	this->scale = scale;

	if(fs::is_directory(path)){
		// if directory is specified, find all las and laz files inside directory

		for(fs::directory_iterator it(path); it != fs::directory_iterator(); it++){
			fs::path filepath = it->path();
			if(fs::is_regular_file(filepath)){
				files.push_back(filepath.string());
			}
		}
	}else{
		files.push_back(path);
	}

	currentFile = files.begin();
	reader = new ifstream(*currentFile, ios::in | ios::binary);

	attributes.add(PointAttribute::POSITION_CARTESIAN);
	attributes.add(PointAttribute::COLOR_PACKED);
}

BINPointReader::~BINPointReader(){
		close();
}

void BINPointReader::close(){
	if(reader != NULL){
		reader->close();
		delete reader;
		reader = NULL;
	}
}

long BINPointReader::numPoints(){
	//TODO

	return 0;
}

bool BINPointReader::readNextPoint(){
	bool hasPoints = reader->good();

	if(!hasPoints){
		// try to open next file, if available
		reader->close();
		delete reader;
		reader = NULL;
		currentFile++;

		if(currentFile != files.end()){
			reader = new ifstream(*currentFile, ios::in | ios::binary);
			hasPoints = reader->good();
		}
	}

	if(hasPoints){
		point = Point();
		char* buffer = new char[attributes.byteSize];
		reader->read(buffer, attributes.byteSize);

		if(!reader->good()){
			return false;
		}

		int offset = 0;
		for(int i = 0; i < attributes.size(); i++){
			const PointAttribute attribute = attributes[i];
			if(attribute == PointAttribute::POSITION_CARTESIAN){
				int* iBuffer = reinterpret_cast<int*>(buffer+offset);
				point.x = (iBuffer[0] * scale) + aabb.min.x;
				point.y = (iBuffer[1] * scale) + aabb.min.y;
				point.z = (iBuffer[2] * scale) + aabb.min.z;
			}else if(attribute == PointAttribute::COLOR_PACKED){
				unsigned char* ucBuffer = reinterpret_cast<unsigned char*>(buffer+offset);
				point.r = ucBuffer[0];
				point.g = ucBuffer[1];
				point.b = ucBuffer[2];
				point.a = 255;
			}
			offset += attribute.byteSize;
		}

		delete [] buffer;
	}

	return hasPoints;
}

Point BINPointReader::getPoint(){
	return point;
}

AABB BINPointReader::getAABB(){
	AABB aabb;
	//TODO

	return aabb;
}

max_stars_repo_name: tigerfoot/PotreeConverter

max_issues_repo_name: tigerfoot/PotreeConverter

max_forks_repo_name: tigerfoot/PotreeConverter