kmeraffect.cpp 4.32 KB
Newer Older
Mikaël Salson's avatar
Mikaël Salson committed
1
/*
2 3 4 5 6 7 8
  This file is part of Vidjil <http://www.vidjil.org>
  Copyright (C) 2011, 2012, 2013, 2014, 2015 by Bonsai bioinformatics 
  at CRIStAL (UMR CNRS 9189, Université Lille) and Inria Lille
  Contributors: 
      Mathieu Giraud <mathieu.giraud@vidjil.org>
      Mikaël Salson <mikael.salson@vidjil.org>
      Marc Duez <marc.duez@vidjil.org>
Mikaël Salson's avatar
Mikaël Salson committed
9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55

  "Vidjil" is free software: you can redistribute it and/or modify
  it under the terms of the GNU General Public License as published by
  the Free Software Foundation, either version 3 of the License, or
  (at your option) any later version.

  "Vidjil" is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with "Vidjil". If not, see <http://www.gnu.org/licenses/>
*/

#include "kmeraffect.h"

int affect_strand(const affect_t &affect) {
  return (affect.c & (1 << 7)) ? 1 : -1;
}

char affect_char(const affect_t &affect) {
  return (affect.c & ((1 << 7)-1));
}

// KmerAffect class

bool operator==(const affect_t &a1, const affect_t &a2) {
  return a1.c == a2.c;
}
bool operator<(const affect_t &a1, const affect_t &a2) {
  return a1.c < a2.c;
}
bool operator>(const affect_t &a1, const affect_t &a2) {
  return a1.c > a2.c;
}
bool operator<=(const affect_t &a1, const affect_t &a2) {
  return ! (a1 > a2);
}
bool operator>=(const affect_t &a1, const affect_t &a2) {
  return ! (a1 < a2);
}
bool operator!=(const affect_t &a1, const affect_t &a2) {
  return a1.c != a2.c;
}
string toString(const affect_t &a) {
  string result;
56 57
  if((a == AFFECT_UNKNOWN) || (a == AFFECT_AMBIGUOUS))
    result = " ";
Mikaël Salson's avatar
Mikaël Salson committed
58
  else
59 60 61
    result = (affect_strand(a)==1 ? "+" : "-");

  result += string(1,affect_char(a));
Mikaël Salson's avatar
Mikaël Salson committed
62 63 64 65 66 67 68 69 70
  return result;
}
ostream &operator<<(ostream &os, const affect_t &a) {
  os << toString(a);
  return os;
}


KmerAffect::KmerAffect() {
71
  affect.c = AFFECT_UNKNOWN_CHAR;
Mikaël Salson's avatar
Mikaël Salson committed
72 73 74 75 76 77 78 79 80 81
}

KmerAffect::KmerAffect(const affect_t &a) {
  affect = a;
}

KmerAffect::KmerAffect(const KmerAffect &ka) {
  affect = ka.affect;
}

82
KmerAffect::KmerAffect(const string &label,
Mikaël Salson's avatar
Mikaël Salson committed
83 84 85 86 87 88 89 90 91 92 93 94 95
                       int strand) {
  affect.c = label[0];
  if (strand == 1)
     affect.c |= (1 << 7);
}

KmerAffect &KmerAffect::operator+=(const KmerAffect &kmer) {
  if (kmer.affect != affect) {
    if (affect == AFFECT_UNKNOWN) 
      affect = kmer.affect;
    else if (affect_char(affect) == affect_char(kmer.affect)
             && (affect_strand(affect) != affect_strand(kmer.affect)))
      // Same label but different strand
96 97 98 99
      // -> we put ambiguous, we could have something to say that
      // strand is ambiguous but not the label, but we don't have enough space
      // in 1 byte…
      *this = AFFECT_AMBIGUOUS;
Mikaël Salson's avatar
Mikaël Salson committed
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114
    else 
      *this = AFFECT_AMBIGUOUS;
  }
  return *this;
}

KmerAffect &KmerAffect::operator=(const KmerAffect &ka) {
  this->affect = ka.affect;
  return *this;
}

bool KmerAffect::hasRevcompSymetry() {
  return false;
}

115 116 117 118
KmerAffect KmerAffect::getAmbiguous() {
  return AFFECT_AMBIGUOUS;
}

Mikaël Salson's avatar
Mikaël Salson committed
119 120 121 122 123 124 125 126 127 128
int KmerAffect::getStrand() const{
  if (isUnknown() || isAmbiguous())
    return 0;
  return affect_strand(affect);
}

string KmerAffect::getLabel() const {
  return string(1, affect_char(affect));
}

129 130 131 132
KmerAffect KmerAffect::getUnknown() {
  return AFFECT_UNKNOWN;
}

Mikaël Salson's avatar
Mikaël Salson committed
133
bool KmerAffect::isAmbiguous() const {
134
  return affect_strand(affect) == 1 && affect_char(affect) == AFFECT_AMBIGUOUS_CHAR;
Mikaël Salson's avatar
Mikaël Salson committed
135 136 137
}

bool KmerAffect::isUnknown() const {
138
  return affect.c == (int) AFFECT_UNKNOWN_CHAR;
Mikaël Salson's avatar
Mikaël Salson committed
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168
}

string KmerAffect::toString() const {
  return ::toString(affect);
}

bool operator==(const KmerAffect &a1, const KmerAffect &a2) {
  return a1.affect == a2.affect;
}
bool operator<(const KmerAffect &a1, const KmerAffect &a2) {
  return a1.affect < a2.affect;
}
bool operator>(const KmerAffect &a1, const KmerAffect &a2) {
  return a1.affect > a2.affect;
              }
bool operator<=(const KmerAffect &a1, const KmerAffect &a2) {
  return a1.affect <= a2.affect;
}
bool operator>=(const KmerAffect &a1, const KmerAffect &a2) {
  return a1.affect >= a2.affect;
}
bool operator!=(const KmerAffect &a1, const KmerAffect &a2) {
  return a1.affect != a2.affect;
}

ostream &operator<<(ostream &os, const KmerAffect &kmer) {
  os << kmer.affect;
  return os;
}