bpp-core3  3.0.0
PolymorphismSequenceContainerTools.cpp
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: The Bio++ Development Group
2 //
3 // SPDX-License-Identifier: CECILL-2.1
4 
6 
7 #include <Bpp/Seq/CodonSiteTools.h>
8 
9 using namespace bpp;
10 using namespace std;
11 
13 
14 /******************************************************************************/
15 
16 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::read(
17  const std::string& path,
18  shared_ptr<const Alphabet> alpha)
19 {
20  Mase ms;
21  string key;
22  auto seqc = ms.readSequences(path, alpha);
23  auto psc = make_unique<PolymorphismSequenceContainer>(*seqc);
24  Comments maseFileHeader = seqc->getComments();
25  auto groupMap = MaseTools::getAvailableSequenceSelections(maseFileHeader);
26  for (auto& mi : groupMap)
27  {
28  key = mi.first;
29  if (key.compare(0, 8, "OUTGROUP") == 0)
30  {
31  auto ss = MaseTools::getSequenceSet(maseFileHeader, key);
32  for (size_t i = 0; i != ss.size(); ++i)
33  {
34  psc->setAsOutgroupMember(ss[i]);
35  }
36  }
37  }
38  return psc;
39 }
40 
41 /******************************************************************************/
42 
43 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::extractIngroup(
45 {
46  SequenceSelection ss;
47  auto psci = make_unique<PolymorphismSequenceContainer>(psc);
48  for (size_t i = 0; i < psc.getNumberOfSequences(); ++i)
49  {
50  if (!psc.isIngroupMember(i))
51  ss.push_back(i);
52  }
53  if (ss.size() == psc.getNumberOfSequences())
54  {
55  throw Exception("PolymorphismSequenceContainerTools::extractIngroup: no Ingroup sequences found.");
56  }
57  for (size_t i = ss.size(); i > 0; --i)
58  {
59  psci->deleteSequence(ss[i - 1]);
60  }
61  return psci;
62 }
63 
64 /******************************************************************************/
65 
66 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::extractOutgroup(
68 {
69  SequenceSelection ss;
70  auto psci = make_unique<PolymorphismSequenceContainer>(psc);
71  for (size_t i = 0; i < psc.getNumberOfSequences(); ++i)
72  {
73  if (psc.isIngroupMember(i) )
74  ss.push_back(i);
75  }
76  if (ss.size() == psc.getNumberOfSequences())
77  {
78  throw Exception("PolymorphismSequenceContainerTools::extractOutgroup: no Outgroup sequences found.");
79  }
80  for (size_t i = ss.size(); i > 0; i--)
81  {
82  psci->deleteSequence(ss[i - 1]);
83  }
84  return psci;
85 }
86 
87 /******************************************************************************/
88 
89 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::extractGroup(
91  size_t groupId)
92 {
93  SequenceSelection ss;
94  auto psci = make_unique<PolymorphismSequenceContainer>(psc);
95  for (size_t i = 0; i < psc.getNumberOfSequences(); ++i)
96  {
97  if (psc.getGroupId(i) != groupId)
98  ss.push_back(i);
99  }
100  if (ss.size() == psc.getNumberOfSequences())
101  {
102  throw GroupNotFoundException("PolymorphismSequenceContainerTools::extractGroup: group_id not found.", groupId);
103  }
104  for (size_t i = ss.size(); i > 0; i--)
105  {
106  psci->deleteSequence(ss[i - 1]);
107  }
108  return psci;
109 }
110 
111 /******************************************************************************/
112 
113 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::getSelectedSequences(
115  const SequenceSelection& ss)
116 {
117  auto newpsc = make_unique<PolymorphismSequenceContainer>(psc.getAlphabet());
118  for (size_t i = 0; i < ss.size(); ++i)
119  {
120  auto tmpSeq = make_unique<Sequence>(psc.sequence(ss[i]));
121  newpsc->addSequenceWithFrequency(tmpSeq->getName(), tmpSeq, psc.getSequenceCount(i));
122  if (psc.isIngroupMember(i))
123  newpsc->setAsIngroupMember(i);
124  else
125  {
126  newpsc->setAsOutgroupMember(i);
127  newpsc->setGroupId(i, psc.getGroupId(i));
128  }
129  }
130  newpsc->setComments(psc.getComments());
131  return newpsc;
132 }
133 
134 /******************************************************************************/
135 
136 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::sample(
138  size_t n,
139  bool replace)
140 {
141  size_t nbSeq = psc.getNumberOfSequences();
142  vector<size_t> v;
143  for (size_t i = 0; i < nbSeq; ++i)
144  {
145  v.push_back(i);
146  }
147  vector<size_t> vv(n);
148  RandomTools::getSample(v, vv, replace);
150  return newpsc;
151 }
152 
153 /******************************************************************************/
154 
155 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::getSitesWithoutGaps(
157 {
158  auto seqNames = psc.getSequenceNames();
159  auto noGapCont = make_unique<PolymorphismSequenceContainer>(psc.getNumberOfSequences(), psc.getAlphabet());
160  noGapCont->setSequenceNames(seqNames, false);
161  size_t nbSeq = psc.getNumberOfSequences();
162  for (size_t i = 0; i < nbSeq; ++i)
163  {
164  noGapCont->setSequenceCount(i, psc.getSequenceCount(i));
165  if (psc.isIngroupMember(i))
166  noGapCont->setAsIngroupMember(i);
167  else
168  {
169  noGapCont->setAsOutgroupMember(i);
170  noGapCont->setGroupId(i, psc.getGroupId(i));
171  }
172  }
173  NoGapSiteContainerIterator ngsi(psc);
174  while (ngsi.hasMoreSites())
175  {
176  auto tmpSite = make_unique<Site>(ngsi.nextSite());
177  noGapCont->addSite(tmpSite);
178  }
179  return noGapCont;
180 }
181 
182 /******************************************************************************/
183 
186  bool ingroup)
187 {
188  size_t count = psc.getNumberOfSites();
189  unique_ptr<PolymorphismSequenceContainer> npsc = nullptr;
190  unique_ptr<SimpleSiteContainerIterator> ssi = nullptr;
191  if (ingroup)
192  {
193  npsc = extractIngroup(psc);
194  ssi.reset(new SimpleSiteContainerIterator(*npsc));
195  }
196  else
197  ssi.reset(new SimpleTemplateSiteContainerIterator<Site, Sequence, string>(psc));
198  while (ssi->hasMoreSites())
199  if (SiteTools::hasGap(ssi->nextSite()))
200  count--;
201  return count;
202 }
203 
204 /******************************************************************************/
205 
208  bool ingroup)
209 {
210  size_t count = psc.getNumberOfSites();
211  unique_ptr<PolymorphismSequenceContainer> npsc = nullptr;
212  unique_ptr<SimpleSiteContainerIterator> ssi = nullptr;
213  if (ingroup)
214  {
215  npsc = extractIngroup(psc);
216  ssi.reset(new SimpleSiteContainerIterator(*npsc));
217  }
218  else
219  ssi.reset(new SimpleSiteContainerIterator(psc));
220  while (ssi->hasMoreSites())
221  if (!SiteTools::isComplete(ssi->nextSite()))
222  count--;
223  return count;
224 }
225 
226 /******************************************************************************/
227 
228 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::getCompleteSites(
230 {
231  auto seqNames = psc.getSequenceNames();
232  auto complete = make_unique<PolymorphismSequenceContainer>(psc.getNumberOfSequences(), psc.getAlphabet());
233  complete->setSequenceNames(seqNames, false);
234  size_t nbSeq = psc.getNumberOfSequences();
235  for (size_t i = 0; i < nbSeq; ++i)
236  {
237  complete->setSequenceCount(i, psc.getSequenceCount(i));
238  if (psc.isIngroupMember(i))
239  complete->setAsIngroupMember(i);
240  else
241  {
242  complete->setAsOutgroupMember(i);
243  complete->setGroupId(i, psc.getGroupId(i));
244  }
245  }
247  while (csi.hasMoreSites())
248  {
249  auto tmpSite = make_unique<Site>(csi.nextSite());
250  complete->addSite(tmpSite);
251  }
252  return complete;
253 }
254 
255 /******************************************************************************/
256 
257 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::excludeFlankingGap(
259 {
260  auto psci = make_unique<PolymorphismSequenceContainer>(psc);
261  while (SiteTools::hasGap(psci->site(0)))
262  psci->deleteSite(0);
263  size_t i = 0;
264  size_t n = psci->getNumberOfSites();
265  while (SiteTools::hasGap(psci->site(n - i - 1)))
266  {
267  psci->deleteSite(n - i - 1);
268  i++;
269  }
270  return psci;
271 }
272 
273 /******************************************************************************/
274 
275 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::getSelectedSites(
277  const string& setName,
278  bool phase)
279 {
280  auto pscc = MaseTools::getSelectedSites(psc, setName);
281  auto maseFileHeader = psc.getComments();
282  if (phase)
283  {
284  for (size_t i = 1; i < MaseTools::getPhase(maseFileHeader, setName); ++i)
285  {
286  pscc->deleteSite(0);
287  }
288  }
289  auto psci = make_unique<PolymorphismSequenceContainer>(*pscc);
290  for (size_t i = 0; i < psc.getNumberOfSequences(); ++i)
291  {
292  if (psc.isIngroupMember(i))
293  psci->setAsIngroupMember(i);
294  else
295  {
296  psci->setAsOutgroupMember(i);
297  psci->setGroupId(i, psc.getGroupId(i));
298  }
299  }
300  psci->clearComments();
301  return psci;
302 }
303 
304 /******************************************************************************/
305 
306 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::getNonCodingSites(
308  const string& setName)
309 {
310  SiteSelection ss;
311  auto maseFileHeader = psc.getComments();
312  auto codss = MaseTools::getSiteSet(maseFileHeader, setName);
313  for (size_t i = 0; i < psc.getNumberOfSites(); ++i)
314  {
315  if (find(codss.begin(), codss.end(), i) == codss.end())
316  ss.push_back(i);
317  }
318  auto sc = SiteContainerTools::getSelectedSites(psc, ss);
319  auto psci = make_unique<PolymorphismSequenceContainer>(*sc);
320  for (size_t i = 0; i < psc.getNumberOfSequences(); ++i)
321  {
322  if (psc.isIngroupMember(i))
323  psci->setAsIngroupMember(i);
324  else
325  {
326  psci->setAsOutgroupMember(i);
327  psci->setGroupId(i, psc.getGroupId(i));
328  }
329  }
330  return psci;
331 }
332 
333 /******************************************************************************/
334 
335 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::getOnePosition(
337  const string& setName,
338  size_t pos)
339 {
340  auto maseFileHeader = psc.getComments();
341  size_t start;
342  try
343  {
344  start = MaseTools::getPhase(maseFileHeader, setName);
345  }
346  catch (Exception& e)
347  {
348  start = 1;
349  }
350  SiteSelection ss;
351  size_t i;
352  if (static_cast<int>(pos) - static_cast<int>(start) >= 0)
353  i = pos - start;
354  else
355  i = pos - start + 3;
356  while (i < psc.getNumberOfSites())
357  {
358  ss.push_back(i);
359  i += 3;
360  }
361  auto sc = SiteContainerTools::getSelectedSites(psc, ss);
362  auto newpsc = make_unique<PolymorphismSequenceContainer>(*sc);
363  for (size_t j = 0; j < psc.getNumberOfSequences(); ++j)
364  {
365  if (psc.isIngroupMember(j))
366  newpsc->setAsIngroupMember(j);
367  else
368  {
369  newpsc->setAsOutgroupMember(j);
370  newpsc->setGroupId(i, psc.getGroupId(j));
371  }
372  }
373  return newpsc;
374 }
375 
376 /******************************************************************************/
377 
378 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::getIntrons(
380  const string& setName,
381  const GeneticCode& gCode)
382 {
383  auto maseFileHeader = psc.getComments();
384  SiteSelection ss;
385  auto codss = MaseTools::getSiteSet(maseFileHeader, setName);
386  size_t start = MaseTools::getPhase(maseFileHeader, setName);
387  size_t first = 0, last = psc.getNumberOfSites();
388  // Check if the first codon is AUG
389  if (start == 1 &&
390  psc.site(codss[0]).getValue(0) == 0 &&
391  psc.site(codss[1]).getValue(0) == 3 &&
392  psc.site(codss[2]).getValue(0) == 2)
393  first = codss[0];
394  // Check if the last codon is a STOP one
395  int c1 = psc.site(codss[codss.size() - 3]).getValue(0);
396  int c2 = psc.site(codss[codss.size() - 2]).getValue(0);
397  int c3 = psc.site(codss[codss.size() - 1]).getValue(0);
398  if (gCode.isStop(gCode.codonAlphabet().getCodon(c1, c2, c3)))
399  last = codss[codss.size() - 1];
400  // Keep sites between AUG and STOP
401  for (size_t i = first; i < last; i++)
402  {
403  if (find(codss.begin(), codss.end(), i) == codss.end())
404  {
405  ss.push_back(i);
406  }
407  }
408  auto sc = SiteContainerTools::getSelectedSites(psc, ss);
409  auto psci = make_unique<PolymorphismSequenceContainer>(*sc);
410  for (size_t i = 0; i < psc.getNumberOfSequences(); ++i)
411  {
412  if (psc.isIngroupMember(i))
413  psci->setAsIngroupMember(i);
414  else
415  {
416  psci->setAsOutgroupMember(i);
417  psci->setGroupId(i, psc.getGroupId(i));
418  }
419  }
420  return psci;
421 }
422 
423 /******************************************************************************/
424 
425 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::get5Prime(
427  const string& setName)
428 {
429  auto maseFileHeader = psc.getComments();
430  SiteSelection ss;
431  auto codss = MaseTools::getSiteSet(maseFileHeader, setName);
432  size_t start = MaseTools::getPhase(maseFileHeader, setName);
433  size_t last = 0;
434  // Check if the first Codon is AUG
435  if (start == 1 &&
436  psc.site(codss[0]).getValue(0) == 0 &&
437  psc.site(codss[1]).getValue(0) == 3 &&
438  psc.site(codss[2]).getValue(0) == 2)
439  last = codss[0];
440  for (size_t i = 0; i < last; ++i)
441  {
442  if (find(codss.begin(), codss.end(), i) == codss.end())
443  {
444  ss.push_back(i);
445  }
446  }
447  auto sc = SiteContainerTools::getSelectedSites(psc, ss);
448  auto psci = make_unique<PolymorphismSequenceContainer>(*sc);
449  for (size_t i = 0; i < psc.getNumberOfSequences(); ++i)
450  {
451  if (psc.isIngroupMember(i))
452  psci->setAsIngroupMember(i);
453  else
454  {
455  psci->setAsOutgroupMember(i);
456  psci->setGroupId(i, psc.getGroupId(i));
457  }
458  }
459  return psci;
460 }
461 
462 /******************************************************************************/
463 
464 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::get3Prime(
466  const string& setName,
467  const GeneticCode& gCode)
468 {
469  auto maseFileHeader = psc.getComments();
470  SiteSelection ss;
471  auto codss = MaseTools::getSiteSet(maseFileHeader, setName);
472  size_t first = psc.getNumberOfSites() - 1;
473  // Check if the last codon is a STOP one
474  int c1 = psc.site(codss[codss.size() - 3]).getValue(0);
475  int c2 = psc.site(codss[codss.size() - 2]).getValue(0);
476  int c3 = psc.site(codss[codss.size() - 1]).getValue(0);
477  if (gCode.isStop(gCode.codonAlphabet().getCodon(c1, c2, c3)))
478  first = codss[codss.size() - 1];
479  for (size_t i = first; i < psc.getNumberOfSites(); ++i)
480  {
481  if (find(codss.begin(), codss.end(), i) == codss.end())
482  {
483  ss.push_back(i);
484  }
485  }
486  auto sc = SiteContainerTools::getSelectedSites(psc, ss);
487  auto psci = make_unique<PolymorphismSequenceContainer>(*sc);
488  for (size_t i = 0; i < psc.getNumberOfSequences(); ++i)
489  {
490  if (psc.isIngroupMember(i))
491  psci->setAsIngroupMember(i);
492  else
493  {
494  psci->setAsOutgroupMember(i);
495  psci->setGroupId(i, psc.getGroupId(i));
496  }
497  }
498  return psci;
499 }
500 
501 /******************************************************************************/
502 
504 {
505  string key;
506  string speciesName;
507  auto maseFileHeader = psc.getComments();
508  if (!maseFileHeader.size())
509  return speciesName;
510  auto groupMap = MaseTools::getAvailableSequenceSelections(maseFileHeader);
511  for (auto& mi : groupMap)
512  {
513  key = mi.first;
514  if (key.compare(0, 7, "INGROUP") == 0)
515  {
516  StringTokenizer sptk(key, "_");
517  speciesName = sptk.getToken(1) + " " + sptk.getToken(2);
518  }
519  }
520  return speciesName;
521 }
522 
523 /******************************************************************************/
524 
525 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::getSynonymousSites(
527  const GeneticCode& gCode)
528 {
529  auto psco = make_unique<PolymorphismSequenceContainer>(psc.getSequenceNames(), psc.getAlphabet());
530  for (size_t i = 0; i < psc.getNumberOfSites(); ++i)
531  {
532  const Site& site = psc.site(i);
533  if (CodonSiteTools::isSynonymousPolymorphic(site, gCode))
534  {
535  auto tmpSite = make_unique<Site>(site);
536  psco->addSite(tmpSite);
537  }
538  }
539  for (size_t i = 0; i < psc.getNumberOfSequences(); ++i)
540  {
541  psco->setSequenceCount(i, psc.getSequenceCount(i));
542  if (psc.isIngroupMember(i))
543  psco->setAsIngroupMember(i);
544  else
545  {
546  psco->setAsOutgroupMember(i);
547  psco->setGroupId(i, psc.getGroupId(i));
548  }
549  }
550  return psco;
551 }
552 
553 /******************************************************************************/
554 
555 unique_ptr<PolymorphismSequenceContainer> PolymorphismSequenceContainerTools::getNonSynonymousSites(
557  const GeneticCode& gCode)
558 {
559  auto psco = make_unique<PolymorphismSequenceContainer>(psc.getSequenceNames(), psc.getAlphabet());
560  for (size_t i = 0; i < psc.getNumberOfSites(); ++i)
561  {
562  const Site& site = psc.site(i);
563  if (!CodonSiteTools::isSynonymousPolymorphic(site, gCode))
564  {
565  auto tmpSite = make_unique<Site>(site);
566  psco->addSite(tmpSite);
567  }
568  }
569  for (size_t i = 0; i < psc.getNumberOfSequences(); ++i)
570  {
571  psco->setSequenceCount(i, psc.getSequenceCount(i));
572  if (psc.isIngroupMember(i))
573  psco->setAsIngroupMember(i);
574  else
575  {
576  psco->setAsOutgroupMember(i);
577  psco->setGroupId(i, psc.getGroupId(i));
578  }
579  }
580  return psco;
581 }
582 
583 /******************************************************************************/
The GroupNotFoundException class.
SimpleTemplateSiteContainerIterator< Site, Sequence, std::string > SimpleSiteContainerIterator
Definition: AlleleInfo.h:13
static std::unique_ptr< PolymorphismSequenceContainer > getCompleteSites(const PolymorphismSequenceContainer &psc)
Retrieves complete sites from a PolymorphismSequenceContainer.
static std::unique_ptr< PolymorphismSequenceContainer > getSynonymousSites(const PolymorphismSequenceContainer &psc, const GeneticCode &gCode)
Retrieve synonymous codon sites.
static std::unique_ptr< PolymorphismSequenceContainer > get3Prime(const PolymorphismSequenceContainer &psc, const std::string &setName, const GeneticCode &gCode)
Retrieve 3&#39; sites.
static std::unique_ptr< PolymorphismSequenceContainer > getNonCodingSites(const PolymorphismSequenceContainer &psc, const std::string &setName)
Retrieve non-coding sites defined in the mase file header.
static std::unique_ptr< PolymorphismSequenceContainer > getSitesWithoutGaps(const PolymorphismSequenceContainer &psc)
Retrieves sites without gaps from PolymorphismSequenceContainer.
STL namespace.
static std::unique_ptr< PolymorphismSequenceContainer > get5Prime(const PolymorphismSequenceContainer &psc, const std::string &setName)
Retrieve 5&#39; sites.
static size_t getNumberOfCompleteSites(const PolymorphismSequenceContainer &psc, bool ingroup)
Return number of completely resolved sites in a PolymorphismSequenceContainer.
size_t getGroupId(size_t index) const
Get the group identifier of the sequence.
static std::unique_ptr< PolymorphismSequenceContainer > extractOutgroup(const PolymorphismSequenceContainer &psc)
Extract outgroup sequences from a PolymorphismSequenceContainer and create a new one.
NoGapTemplateSiteContainerIterator< Site, Sequence, std::string > NoGapSiteContainerIterator
static std::unique_ptr< PolymorphismSequenceContainer > getIntrons(const PolymorphismSequenceContainer &psc, const std::string &setName, const GeneticCode &gCode)
Retrieve intron sites.
static std::unique_ptr< PolymorphismSequenceContainer > getOnePosition(const PolymorphismSequenceContainer &psc, const std::string &setName, size_t pos)
Retrieve sites at one codon position (1,2,3)
static std::unique_ptr< PolymorphismSequenceContainer > excludeFlankingGap(const PolymorphismSequenceContainer &psc)
exclude flanking sites with gap but keep gap sites within the alignment
static std::unique_ptr< PolymorphismSequenceContainer > getSelectedSites(const PolymorphismSequenceContainer &psc, const std::string &setName, bool phase)
Get a PolymorphismSequenceContainer corresponding to a site selection annotated in the mase comments...
unsigned int getSequenceCount(size_t index) const
Get the count of a sequence by index.
static std::unique_ptr< PolymorphismSequenceContainer > extractGroup(const PolymorphismSequenceContainer &psc, size_t groupId)
Extract a special group from the PolymorphismSequenceContainer.
CompleteTemplateSiteContainerIterator< Site, Sequence, std::string > CompleteSiteContainerIterator
void setAsIngroupMember(size_t index)
Set a sequence as ingroup member by index.
static std::unique_ptr< PolymorphismSequenceContainer > getNonSynonymousSites(const PolymorphismSequenceContainer &psc, const GeneticCode &gCode)
Retrieve non-synonymous codon sites.
static std::unique_ptr< PolymorphismSequenceContainer > sample(const PolymorphismSequenceContainer &psc, size_t n, bool replace=true)
Get a random set of sequences.
static size_t getNumberOfNonGapSites(const PolymorphismSequenceContainer &psc, bool ingroup)
Return number of sites without gaps in a PolymorphismSequenceContainer.
void setSequenceCount(size_t index, unsigned int count)
Set the count of a sequence by index.
static std::unique_ptr< PolymorphismSequenceContainer > extractIngroup(const PolymorphismSequenceContainer &psc)
Extract ingroup sequences from a PolymorphismSequenceContainer and create a new one.
The PolymorphismSequenceContainer class.
static std::unique_ptr< PolymorphismSequenceContainer > read(const std::string &path, std::shared_ptr< const Alphabet > alpha)
Read a Mase+ file and return a PolymorphismSequenceContainer. Toggle Sequence when selection tag begi...
static std::string getIngroupSpeciesName(const PolymorphismSequenceContainer &psc)
Get the species name of the ingroup.
static std::unique_ptr< PolymorphismSequenceContainer > getSelectedSequences(const PolymorphismSequenceContainer &psc, const SequenceSelection &ss)
Extract selected sequences.
bool isIngroupMember(size_t index) const
Tell if the sequence is ingroup by index.