Project: s41467-024-52886-2 | Function: CS_ConsensusPosition::set (cpp)

system: You are an expert C++ programmer implementing algorithms from scientific papers.
Complete the masked function based on the algorithm description.
Follow C++ best practices and maintain consistent code style.
Return **only** the complete C++ function code.

user: Complete this C++ function:

**DESCRIPTION:** Implements consensus base calling using quality-weighted voting across multiple reverse transcription rounds to identify the most likely nucleotide at each position

**KEY TERMS:** {
  "tabQuals": "quality score accumulator per base",
  "vCalls_": "base calls from multiple RT rounds",
  "vQuals_": "quality scores from multiple RT rounds",
  "cs_": "consensus base call",
  "csQual_": "consensus quality score",
  "altQual_": "alternative base quality score"
}

**CONTEXT CODE:** 
//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////


CS_Consensus::CS_Consensus(std::vector<std::string> &vSeq, std::vector<std::string> &vQual, int csLg, std::vector<int> &vPosFirstBreakPoint, BasesIndices &BI, int illuminaMinScore){
  this->vSeq_ = vSeq;
  this->vQual_ = vQual;
  this->vPosFirstBreakPoint_ = vPosFirstBreakPoint;
  this->csLg_ = csLg;
  this->setMapOfConsensusPositions(BI, illuminaMinScore);
}

std::string CS_Consensus::getConsensus(void){
  return this->consensusSeq_;
}

int CS_Consensus::getLength(void){
  return this->csLg_;
}

int CS_Consensus::getDepth(int pos){
  if( pos >= this->csLg_ ){ return -1; }
  return this->vPos_[pos].getDepth();
}

bool CS_Consensus::getParameters(int pos, char *cs, int *csQual, int *altQual, int *depth){
  if( pos<0 || pos >= this->csLg_ ){ return -1; }
  return this->vPos_[pos].getParameters(cs, csQual, altQual, depth);
}

bool CS_Consensus::setMapOfConsensusPositions(BasesIndices &BI, int illuminaMinScore){

  int csLg = this->csLg_;
  int nbSeq = this->vSeq_.size();

  //CS_ConsensusPosition csp;
  this->vPos_.resize(csLg);

  for(int iSeq=0 ; iSeq < nbSeq ; iSeq++){
    int seqLength = this->vSeq_[iSeq].size();
    int posFirstBreakPoint = this->vPosFirstBreakPoint_[iSeq];
    for(int sPos=0 ; sPos<seqLength ; sPos++){
    // Convert position in sequence into position in (debreaked) consensus
      int csPos = ((sPos - posFirstBreakPoint)+2*csLg)%csLg; // Here I have to add 2*csLg because c++ modulo does not work the same as R modulo --> can return negative value!
      this->vPos_[csPos].add(this->vSeq_[iSeq][sPos], this->vQual_[iSeq][sPos] - illuminaMinScore);
    }
  }

  std::string consensusSeq(csLg, '?');
  for(int i=0 ; i<csLg ; i++){
    this->vPos_[i].set(BI);
    consensusSeq[i] = this->vPos_[i].getConsensus();
  }
  this->consensusSeq_ = consensusSeq;

  // Alternative (might be faster?): for each position in the consensus, find all corresponding positions in the sequences and construct the corresponding CS_ConsensusPosition
  return true;
}


bool CS_Consensus::getConsensus(std::string &seq, std::string &qual){
  if( this->csLg_ == 0 ){
    return false;
  }

  seq = this->consensusSeq_;
  qual = seq;
  int lg = seq.size();
  for(int i=0 ; i<lg ; i++){
    int iQual = this->vPos_[i].getCsQual();
    if( iQual > 42 ){ iQual = 42; }
    char cQual = (char)(iQual + 33);
    qual[i] = cQual;
  }
  return true;
}

bool CS_Consensus::printDetails(std::ostream &os, BasesIndices &BI){

  for(int i=0 ; i<this->csLg_ ; i++){
    os<<i<<'\t';
    this->vPos_[i].print(os);
    os<<'\n';
  }
  
  /*
  std::map<int, CS_ConsensusPosition>::iterator itm;
  for(itm=this->mPos_.begin() ; itm!=this->mPos_.end() ; itm++){
    os<<itm->first<<'\t';
    (itm->second).print(os);
    os<<'\n';
  }
  */
  return true;  
}



double CS_Consensus::getPrctMismatchesInsideConsensus(int *nbMatch, int *nbMismatch){
  (*nbMatch) = 0;
  (*nbMismatch) = 0;
  for(int i=0 ; i<this->csLg_ ; i++){
    int nbM, nbMM;
    this->vPos_[i].getNbMatchAndMismatch(&nbM, &nbMM);
    (*nbMatch) += nbM;
    (*nbMismatch) += nbMM;
  }
  int total = (*nbMatch) + (*nbMismatch);
  double res = (double)((double)(*nbMismatch)/(double)total);
  return res;
}


Complete the function implementation replacing "throw std::runtime_error("Not implemented");".