00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifndef NCL_NXSTAXABLOCK_H
00020 #define NCL_NXSTAXABLOCK_H
00021
00022 #include "ncl/nxsdefs.h"
00023 #include "ncl/nxsblock.h"
00024
00034 class NxsTaxaBlockAPI
00035 : public NxsBlock, public NxsLabelToIndicesMapper
00036 {
00037 public:
00042 virtual unsigned AddTaxonLabel(const std::string & s) = 0;
00049 virtual void ChangeTaxonLabel(unsigned i, NxsString s) = 0;
00056 virtual unsigned FindTaxon(const NxsString & label) const = 0;
00059 virtual bool IsAlreadyDefined(const std::string & label) = 0;
00065 virtual unsigned GetMaxTaxonLabelLength() = 0;
00068 virtual unsigned GetNumTaxonLabels() const = 0;
00071 virtual unsigned GetNTax() const = 0;
00075 virtual unsigned GetNTaxTotal() const = 0;
00081 virtual NxsString GetTaxonLabel(unsigned i) const = 0;
00082
00084 virtual std::vector<std::string> GetAllLabels() const;
00085
00095 virtual unsigned TaxLabelToNumber(const std::string &label) const = 0;
00096
00098 virtual void HandleTaxLabels(NxsToken &token) = 0;
00100 virtual void WriteTaxLabelsCommand(std::ostream &out) const = 0;
00105 virtual void SetNtax(unsigned n) = 0;
00106
00109 virtual unsigned GetNumActiveTaxa() const = 0;
00114 virtual bool IsActiveTaxon(unsigned i) const = 0;
00119 virtual unsigned InactivateTaxa(const std::set<unsigned> &s) = 0;
00124 virtual unsigned ActivateTaxa(const std::set<unsigned> &) = 0;
00129 virtual unsigned InactivateTaxon(unsigned ) = 0;
00134 virtual unsigned ActivateTaxon(unsigned ) = 0;
00135
00136 };
00137
00142 class NxsTaxaBlock
00143 : public NxsTaxaBlockAPI
00144 {
00145 friend class NxsDataBlock;
00146 friend class NxsAllelesBlock;
00147 friend class NxsCharactersBlock;
00148 friend class NxsDistancesBlock;
00149
00150 public:
00151 NxsTaxaBlock();
00152 virtual ~NxsTaxaBlock();
00153
00154 virtual unsigned AddTaxonLabel(const std::string & s);
00155 void ChangeTaxonLabel(unsigned i, NxsString s);
00156 unsigned TaxLabelToNumber(const std::string &label) const;
00157 unsigned FindTaxon(const NxsString & label) const;
00158 bool IsAlreadyDefined(const std::string &label);
00159 unsigned GetIndexSet(const std::string &label, NxsUnsignedSet * toFill) const
00160 {
00161 return NxsLabelToIndicesMapper::GetIndicesFromSets(label, toFill, taxSets);
00162 }
00163 unsigned GetMaxTaxonLabelLength();
00164 unsigned GetNTax() const;
00165 unsigned GetNTaxTotal() const;
00166 unsigned GetNumTaxonLabels() const;
00167 NxsString GetTaxonLabel(unsigned i) const;
00168 void HandleTaxLabels(NxsToken &token);
00169 bool NeedsQuotes(unsigned i);
00170 virtual void Report(std::ostream &out) NCL_COULD_BE_CONST ;
00171 virtual void Reset();
00172 void SetNtax(unsigned n);
00173 void WriteAsNexus(std::ostream &out) const;
00174
00175
00176 virtual unsigned GetNumActiveTaxa() const;
00177 virtual bool IsActiveTaxon(unsigned i) const;
00178 virtual unsigned InactivateTaxa(const std::set<unsigned> &);
00179 virtual unsigned ActivateTaxa(const std::set<unsigned> &);
00180 virtual unsigned InactivateTaxon(unsigned );
00181 virtual unsigned ActivateTaxon(unsigned );
00182
00183 class NxsX_NoSuchTaxon {};
00184
00185 void WriteTaxLabelsCommand(std::ostream &out) const;
00186
00187 unsigned GetMaxIndex() const;
00188 unsigned GetIndicesForLabel(const std::string &label, NxsUnsignedSet *inds) const;
00189 bool AddNewIndexSet(const std::string &label, const NxsUnsignedSet & inds);
00190 bool AddNewPartition(const std::string &label, const NxsPartition & inds);
00191
00192
00193
00194
00195
00196 virtual unsigned AppendNewLabel(std::string &label)
00197 {
00198 while (dimNTax <= taxLabels.size())
00199 dimNTax++;
00200 return AddTaxonLabel(label);
00201 }
00202
00203 NxsTaxaBlock &operator=(const NxsTaxaBlock &other)
00204 {
00205 Reset();
00206 CopyBaseBlockContents(static_cast<const NxsBlock &>(other));
00207 CopyTaxaContents(other);
00208 return *this;
00209 }
00210
00211 void CopyTaxaContents(const NxsTaxaBlock &other)
00212 {
00213 taxLabels = other.taxLabels;
00214 labelToIndex = other.labelToIndex;
00215 dimNTax = other.dimNTax;
00216 taxSets = taxSets;
00217 taxPartitions = other.taxPartitions;
00218 inactiveTaxa = other.inactiveTaxa;
00219 }
00220 NxsTaxaBlock * Clone() const
00221 {
00222 NxsTaxaBlock *taxa = new NxsTaxaBlock();
00223 *taxa = *this;
00224 return taxa;
00225 }
00226 protected:
00227 NxsStringVector taxLabels;
00228 std::map<std::string, unsigned> labelToIndex;
00229 unsigned dimNTax;
00230 NxsUnsignedSetMap taxSets;
00231 NxsPartitionsByName taxPartitions;
00232 std::set<unsigned> inactiveTaxa;
00233
00234 virtual void Read(NxsToken &token);
00235 void CheckCapitalizedTaxonLabel(const std::string &s) const;
00236 unsigned CapitalizedTaxLabelToNumber(const std::string & s) const;
00237 void RemoveTaxonLabel(unsigned taxInd);
00238 };
00239
00240
00252 class NxsTaxaBlockSurrogate
00253 {
00254 public:
00255 void SetCreateImpliedBlock(bool v)
00256 {
00257 createImpliedBlock = v;
00258 }
00259
00261 int GetTaxaLinkStatus() const
00262 {
00263 return taxaLinkStatus;
00264 }
00265
00266 void SetTaxaLinkStatus(NxsBlock::NxsBlockLinkStatus s);
00267 NxsTaxaBlockAPI * GetTaxaBlockPtr(int *status) const;
00268 NxsTaxaBlockAPI * GetTaxaBlockPtr() {return GetTaxaBlockPtr(0L);}
00269
00270 virtual const std::string & GetBlockName() const = 0;
00271
00272 virtual unsigned GetNTax() const;
00273 virtual unsigned GetNTaxTotal() const;
00274 virtual unsigned GetNumActiveTaxa() const;
00275 virtual bool IsActiveTaxon(unsigned i) const;
00276 virtual unsigned InactivateTaxa(const std::set<unsigned> &);
00277 virtual unsigned ActivateTaxa(const std::set<unsigned> &);
00278 virtual unsigned InactivateTaxon(unsigned );
00279 virtual unsigned ActivateTaxon(unsigned );
00280
00281 NxsTaxaBlockSurrogate &operator=(const NxsTaxaBlockSurrogate &other)
00282 {
00283 ResetSurrogate();
00284 CopyTaxaBlockSurrogateContents(other);
00285 return *this;
00286 }
00287
00288
00289
00290
00291 virtual void CopyTaxaBlockSurrogateContents(const NxsTaxaBlockSurrogate &other)
00292 {
00293 ResetSurrogate();
00294 taxa = other.taxa;
00295 taxaLinkStatus = other.taxaLinkStatus;
00296 newtaxa = other.newtaxa;
00297 ownsTaxaBlock = false;
00298 passedRefOfOwnedBlock = other.passedRefOfOwnedBlock;
00299 createImpliedBlock = other.createImpliedBlock;
00300 nxsReader = other.nxsReader;
00301 }
00302
00303 protected:
00304 NxsTaxaBlockSurrogate(NxsTaxaBlockAPI *tb, NxsReader * reader)
00305 :taxa(tb),
00306 newtaxa(false),
00307 ownsTaxaBlock(false),
00308 passedRefOfOwnedBlock(false),
00309 createImpliedBlock(false),
00310 nxsReader(reader)
00311 {
00312 taxaLinkStatus = (tb == NULL ? NxsBlock::BLOCK_LINK_UNINITIALIZED : NxsBlock::BLOCK_LINK_TO_ONLY_CHOICE);
00313 }
00314 virtual ~NxsTaxaBlockSurrogate()
00315 {
00316 ResetSurrogate();
00317 }
00318
00319 void SetTaxaBlockPtr(NxsTaxaBlockAPI *c, NxsBlock::NxsBlockLinkStatus s);
00320
00321 VecBlockPtr GetCreatedTaxaBlocks();
00322 void FlagTaxaBlockAsUsed()
00323 {
00324 taxaLinkStatus |= NxsBlock::BLOCK_LINK_USED;
00325 }
00326
00327 void AssureTaxaBlock(bool allocBlock, NxsToken &, const char *cmd);
00328 void ResetSurrogate();
00329 void SetNexusReader(NxsReader *nxsptr)
00330 {
00331 nxsReader = nxsptr;
00332 }
00333 virtual void HandleTaxLabels(NxsToken & token);
00334 virtual void HandleLinkTaxaCommand(NxsToken & );
00335 virtual void WriteLinkTaxaCommand(std::ostream &out) const;
00336 bool SurrogateSwapEquivalentTaxaBlock(NxsTaxaBlockAPI * tb);
00337
00338 NxsTaxaBlockAPI *taxa;
00339 int taxaLinkStatus;
00340 bool newtaxa;
00341 bool ownsTaxaBlock;
00342 bool passedRefOfOwnedBlock;
00343 bool createImpliedBlock;
00344 NxsReader *nxsReader;
00345 };
00346
00347
00348
00349 typedef NxsTaxaBlock TaxaBlock;
00350 class NxsTaxaBlockFactory
00351 :public NxsBlockFactory
00352 {
00353 public:
00354 virtual NxsTaxaBlock * GetBlockReaderForID(const std::string & id, NxsReader *reader, NxsToken *token);
00355 };
00356
00357 inline unsigned NxsTaxaBlock::GetNTax() const
00358 {
00359 return dimNTax;
00360 }
00361
00362 inline unsigned NxsTaxaBlock::GetNTaxTotal() const
00363 {
00364 return dimNTax;
00365 }
00366
00376 inline unsigned NxsTaxaBlock::CapitalizedTaxLabelToNumber(const std::string &r) const
00377 {
00378 std::map<std::string, unsigned>::const_iterator rIt = labelToIndex.find(r);
00379 if (rIt == labelToIndex.end())
00380 return 0;
00381 return rIt->second + 1;
00382 }
00383
00384
00389 inline bool NxsTaxaBlockSurrogate::IsActiveTaxon(
00390 unsigned taxInd) const
00391 {
00392 if (!taxa)
00393 throw NxsNCLAPIException("Calling IsActiveTaxon on uninitialized block");
00394 return taxa->IsActiveTaxon(taxInd);
00395 }
00396 inline unsigned NxsTaxaBlockSurrogate::GetNumActiveTaxa() const
00397 {
00398 if (!taxa)
00399 throw NxsNCLAPIException("Calling GetNumActiveTaxa on uninitialized block");
00400 return taxa->GetNumActiveTaxa();
00401 }
00402 inline unsigned NxsTaxaBlockSurrogate::InactivateTaxa(const std::set<unsigned> &s)
00403 {
00404 if (!taxa)
00405 throw NxsNCLAPIException("Calling InactivateTaxa on uninitialized block");
00406 return taxa->InactivateTaxa(s);
00407 }
00408 inline unsigned NxsTaxaBlockSurrogate::ActivateTaxa(const std::set<unsigned> &s)
00409 {
00410 if (!taxa)
00411 throw NxsNCLAPIException("Calling ActivateTaxa on uninitialized block");
00412 return taxa->ActivateTaxa(s);
00413 }
00414
00415 inline unsigned NxsTaxaBlockSurrogate::InactivateTaxon(unsigned i)
00416 {
00417 if (!taxa)
00418 throw NxsNCLAPIException("Calling InactivateTaxon on uninitialized block");
00419 return taxa->InactivateTaxon(i);
00420 }
00421
00422 inline unsigned NxsTaxaBlockSurrogate::ActivateTaxon(unsigned i)
00423 {
00424 if (!taxa)
00425 throw NxsNCLAPIException("Calling ActivateTaxon on uninitialized block");
00426 return taxa->ActivateTaxon(i);
00427 }
00428
00429 inline unsigned NxsTaxaBlockSurrogate::GetNTax() const
00430 {
00431 if (!taxa)
00432 throw NxsNCLAPIException("Calling GetNTax on uninitialized block");
00433 return taxa->GetNTax();
00434 }
00435
00436 inline unsigned NxsTaxaBlockSurrogate::GetNTaxTotal() const
00437 {
00438 if (!taxa)
00439 throw NxsNCLAPIException("Calling GetNTaxTotal on uninitialized block");
00440 return taxa->GetNTaxTotal();
00441 }
00442
00443
00444 inline unsigned NxsTaxaBlock::GetNumActiveTaxa() const
00445 {
00446 return GetNTax() - inactiveTaxa.size();
00447 }
00448
00449 inline bool NxsTaxaBlock::IsActiveTaxon(unsigned i) const
00450 {
00451 return i < GetNTax() && (inactiveTaxa.count(i) == 0);
00452 }
00453
00454 inline unsigned NxsTaxaBlock::InactivateTaxa(const std::set<unsigned> &s)
00455 {
00456 for (std::set<unsigned>::const_iterator sIt = s.begin(); sIt != s.end(); ++sIt)
00457 InactivateTaxon(*sIt);
00458 return GetNumActiveTaxa();
00459 }
00460
00461 inline unsigned NxsTaxaBlock::ActivateTaxa(const std::set<unsigned> &s)
00462 {
00463 for (std::set<unsigned>::const_iterator sIt = s.begin(); sIt != s.end(); ++sIt)
00464 ActivateTaxon(*sIt);
00465 return GetNumActiveTaxa();
00466 }
00467 inline unsigned NxsTaxaBlock::InactivateTaxon(unsigned i)
00468 {
00469 if (i > GetNTax())
00470 throw NxsNCLAPIException("Taxon index out of range in InactivateTaxon");
00471 inactiveTaxa.insert(i);
00472 return GetNumActiveTaxa();
00473 }
00474 inline unsigned NxsTaxaBlock::ActivateTaxon(unsigned i)
00475 {
00476 if (i > GetNTax())
00477 throw NxsNCLAPIException("Taxon index out of range in InactivateTaxon");
00478 inactiveTaxa.erase(i);
00479 return GetNumActiveTaxa();
00480 }
00481
00482
00483 #endif