Beispiel #1
0
    void testConstruction ()
    {
        testcase ("construction");

        {
            std::uint8_t src[16];

            for (std::uint8_t i = 0; i < 64; i++)
            {
                beast::rngfill (
                    src,
                    sizeof(src),
                    default_prng());
                Seed const seed ( {
                    src, sizeof(src)
                });
                BEAST_EXPECT(memcmp (seed.data(), src, sizeof(src)) == 0);
            }
        }

        for (int i = 0; i < 64; i++)
        {
            uint128 src;
            beast::rngfill (
                src.data(),
                src.size(),
                default_prng());
            Seed const seed (src);
            BEAST_EXPECT(memcmp (seed.data(), src.data(), src.size()) == 0);
        }
    }
Beispiel #2
0
BigInt generate_number(Seed &s, GeneratorParams &params) {
  unsigned int v = params.first;
  unsigned int w = params.second;
  std::vector<unsigned char> h;

  // step 2
  BigInt tmp = s.sha1();

  // step 3
  std::vector<unsigned char> h0 = (std::vector<unsigned char>) tmp.right_bits(w);

  h.insert(h.end(), h0.begin(), h0.end()); //step 6

  // step 4
  BigInt z = s;

  BigInt _2_e_160 = BigInt(2).pow(160);

  for(unsigned int i = 1; i < v + 1; i++) {                // step 5
    BigInt zi = z;
    zi += i;
    Seed si = (zi) % _2_e_160;              // step 5.1
    std::vector<unsigned char> hi = si.sha1();// step 5.2
    h.insert(h.end(), hi.begin(), hi.end());  // step 6
  }
  BigInt c = h;
  return c;
}
Seed * Hero::Shoot () {
  if (shootCountdown > 0)
    return 0;
  shootCountdown = cShootCooldown;
  float x = posX, y = posY;
  if (facing > 0)
    x += boxWidth*cTileSize;
  Seed * seed = new Seed(x, y, facing);
  seed->SetGameGrid(gameGrid, gridWidth, gridHeight);
  return seed;
}
//--------------------------------------------------------------
void ofApp::setup(){
    
    ofBackground(0);
    ofEnableAlphaBlending();
    ofEnableSmoothing();
    
    numSeeds = (int)ofRandom(30,50);
    for (int i = 0; i < numSeeds; i++){
        Seed tempSeed;
        tempSeed.setup();
        seeds.push_back(tempSeed);
    }
}
Beispiel #5
0
Surface::Surface(Seed seed){
    this->seed = seed;
    
    
    // TODO: DENSITY
    switch (seed.getSurfaceShape()){
        case Seed::SPHERE:
            rawShape = ofSpherePrimitive(seed.shapeSize, 64);
            break;
        case Seed::PLANE:
            rawShape = ofPlanePrimitive(seed.shapeSize, seed.shapeSize, seed.numCols, seed.numCols);
            
            //            rawShape =ofBoxPrimitive(seed.shapeSize, seed.shapeSize, seed.shapeSize);
            break;
        default:
            rawShape = ofSpherePrimitive(1,1);
            
    }
    
    if ((seed.numCols % 2) != 0){
        even = false;
    }
    else even = true;
    
    vboMesh = rawShape.getMesh();
    
    
};
Beispiel #6
0
 static
 bool equal(Seed const& lhs, Seed const& rhs)
 {
     return std::equal (
                lhs.data(), lhs.data() + lhs.size(),
                rhs.data(), rhs.data() + rhs.size());
 }
Beispiel #7
0
std::string
seedAs1751 (Seed const& seed)
{
    std::string key;

    std::reverse_copy (
        seed.data(),
        seed.data() + 16,
        std::back_inserter(key));

    std::string encodedKey;
    RFC1751::getEnglishFromKey (encodedKey, key);
    return encodedKey;
}
Beispiel #8
0
void Seed::grow(MaximumCommonSubgraph& mcs) const {
  const ROMol& qmol = mcs.getQueryMolecule();
  std::set<unsigned> newAtomsSet;  // keep track of newly added atoms

  if (!canGrowBiggerThan(mcs.getMaxNumberBonds(),
                         mcs.getMaxNumberAtoms())) {  // prune() parent
    GrowingStage = NotSet;                            // finished
#ifdef VERBOSE_STATISTICS_ON
    ++mcs.VerboseStatistics.RemainingSizeRejected;
#endif
    return;
  }

  if (0 == GrowingStage) {
    // 0. Fill out list of all directly connected outgoing bonds
    ((Seed*)this)
        ->fillNewBonds(
            qmol);  // non const method, multistage growing optimisation

    if (NewBonds.empty()) {
      GrowingStage = NotSet;  // finished
      return;
    }

    // 1. Check and add the biggest child seed with all outgoing bonds added:
    // Add all bonds at first (build the biggest child seed). All new atoms are
    // already in the seed
    Seed seed;
    seed.createFromParent(this);

    for (std::vector<NewBond>::const_iterator nbi = NewBonds.begin();
         nbi != NewBonds.end(); nbi++) {
      unsigned aIdx = nbi->EndAtomIdx;
      if (NotSet == aIdx) {  // new atom
        // check if new bonds simultaneously close a ring
        if (newAtomsSet.find(nbi->NewAtomIdx) == newAtomsSet.end()) {
          const Atom* end_atom = nbi->NewAtom;
          aIdx = seed.addAtom(end_atom);
          newAtomsSet.insert(nbi->NewAtomIdx);
        }
      }
      const Bond* src_bond = qmol.getBondWithIdx(nbi->BondIdx);
      seed.addBond(src_bond);
    }
#ifdef VERBOSE_STATISTICS_ON
    { ++mcs.VerboseStatistics.Seed; }
#endif
    seed.RemainingBonds = RemainingBonds - NewBonds.size();  // Added ALL !!!
    seed.RemainingAtoms =
        RemainingAtoms - newAtomsSet.size();  // new atoms added to seed

    // prune() Best Sizes
    if (!seed.canGrowBiggerThan(mcs.getMaxNumberBonds(),
                                mcs.getMaxNumberAtoms())) {
      GrowingStage = NotSet;
#ifdef VERBOSE_STATISTICS_ON
      ++mcs.VerboseStatistics.RemainingSizeRejected;
#endif
      return;  // the biggest possible subrgaph from this seed is too small for
               // future growing. So, skip ALL children !
    }
    seed.MatchResult = MatchResult;
    bool allMatched = mcs.checkIfMatchAndAppend(
        seed);  // this seed + all extern bonds is a part of MCS

    GrowingStage = 1;
    if (allMatched && NewBonds.size() > 1)
      return;  // grow deep first. postpone next growing steps
  }
  // 2. Check and add all 2^N-1-1 other possible seeds:
  if (1 == NewBonds.size()) {
    GrowingStage = NotSet;
    return;  // everything has been done
  }
  // OPTIMISATION:
  // check each single bond first: if (this seed + single bond) does not exist
  // in MCS, exclude this new bond from growing this seed.
  unsigned numErasedNewBonds = 0;
  for (auto& nbi : NewBonds) {
#ifdef VERBOSE_STATISTICS_ON
    { ++mcs.VerboseStatistics.Seed; }
#endif
    Seed seed;
    seed.createFromParent(this);

    // existed in this parent seed (ring) or -1
    unsigned aIdx = nbi.EndAtomIdx;
    if (NotSet == aIdx) {  // new atom
      const Atom* end_atom = nbi.NewAtom;
      aIdx = seed.addAtom(end_atom);
    }
    const Bond* src_bond = qmol.getBondWithIdx(nbi.BondIdx);
    seed.addBond(src_bond);
    seed.computeRemainingSize(qmol);

    if (seed.canGrowBiggerThan(mcs.getMaxNumberBonds(),
                               mcs.getMaxNumberAtoms())) {  // prune()
      if (!MatchResult.empty()) seed.MatchResult = MatchResult;
      if (!mcs.checkIfMatchAndAppend(seed)) {
        nbi.BondIdx = NotSet;  // exclude this new bond from growing this seed
                               // - decrease 2^^N-1 to 2^^k-1, k<N.
        ++numErasedNewBonds;
#ifdef VERBOSE_STATISTICS_ON
        ++mcs.VerboseStatistics.SingleBondExcluded;
#endif
      }
    } else {  // seed too small
#ifdef VERBOSE_STATISTICS_ON
      ++mcs.VerboseStatistics.RemainingSizeRejected;
#endif
    }
  }

  if (numErasedNewBonds > 0) {
    std::vector<NewBond> dirtyNewBonds;
    dirtyNewBonds.reserve(NewBonds.size());
    dirtyNewBonds.swap(NewBonds);
    for (std::vector<NewBond>::const_iterator nbi = dirtyNewBonds.begin();
         nbi != dirtyNewBonds.end(); nbi++)
      if (NotSet != nbi->BondIdx) NewBonds.push_back(*nbi);
  }

  // add all other from 2^k-1 possible seeds, where k=newBonds.size()
  // if just one new bond, then seed has already been created
  if (NewBonds.size() > 1) {
    if (sizeof(unsigned long long) * 8 < NewBonds.size())
      throw std::runtime_error(
          "Max number of new external bonds of a seed more than 64");
    BitSet maxCompositionValue;
    Composition2N::compute2N(NewBonds.size(), maxCompositionValue);
    maxCompositionValue -= 1;  // 2^N-1
    Composition2N composition(maxCompositionValue, maxCompositionValue);

#ifdef EXCLUDE_WRONG_COMPOSITION
    std::vector<BitSet> failedCombinations;
    BitSet failedCombinationsMask = 0uLL;
#endif
    while (composition.generateNext()) {
      // exclude already processed single external bond combinations
      if (composition.is2Power()) 
        continue;
      if (0 == numErasedNewBonds &&
          composition.getBitSet() == maxCompositionValue)
        continue;  // exclude already processed all external bonds combination
                   // 2N-1
#ifdef EXCLUDE_WRONG_COMPOSITION
      // OPTIMISATION. reduce amount of generated seeds and match calls
      // 2120 instead of 2208 match calls on small test. 43 wrongComp-s, 83
      // rejected
      if (failedCombinationsMask & composition.getBitSet()) {
        // possibly exists in the list
        bool compositionWrong = false;
        for (std::vector<BitSet>::const_iterator failed =
                 failedCombinations.begin();
             failed != failedCombinations.end(); failed++)
          if (*failed == (*failed & composition.getBitSet())) {
            // combination includes failed combination
            compositionWrong = true;
            break;
          }
        if (compositionWrong) {
#ifdef VERBOSE_STATISTICS_ON
          ++mcs.VerboseStatistics.WrongCompositionRejected;
#endif
          continue;
        }
      }
#endif
#ifdef VERBOSE_STATISTICS_ON
      { ++mcs.VerboseStatistics.Seed; }
#endif
      Seed seed;
      seed.createFromParent(this);
      newAtomsSet.clear();

      for (unsigned i = 0; i < NewBonds.size(); i++)
        if (composition.isSet(i)) {
          const NewBond* nbi = &NewBonds[i];
          unsigned aIdx =
              nbi->EndAtomIdx;   // existed in this parent seed (ring) or -1
          if (NotSet == aIdx) {  // new atom
            if (newAtomsSet.find(nbi->NewAtomIdx) == newAtomsSet.end()) {
              const Atom* end_atom = nbi->NewAtom;
              aIdx = seed.addAtom(end_atom);
              newAtomsSet.insert(nbi->NewAtomIdx);
            }
          }
          const Bond* src_bond = qmol.getBondWithIdx(nbi->BondIdx);
          seed.addBond(src_bond);
        }
      seed.computeRemainingSize(qmol);
      if (!seed.canGrowBiggerThan(
              mcs.getMaxNumberBonds(),
              mcs.getMaxNumberAtoms())) {  // prune(). // seed too small
#ifdef VERBOSE_STATISTICS_ON
        ++mcs.VerboseStatistics.RemainingSizeRejected;
#endif
      } else {
        seed.MatchResult = MatchResult;
        bool found = mcs.checkIfMatchAndAppend(seed);

        if (!found) {
#ifdef EXCLUDE_WRONG_COMPOSITION  // if seed does not matched it is possible to
                                  // exclude this mismatched combination for
                                  // performance improvement
          failedCombinations.push_back(composition.getBitSet());
          failedCombinationsMask &= composition.getBitSet();
#ifdef VERBOSE_STATISTICS_ON
          ++mcs.VerboseStatistics.WrongCompositionDetected;
#endif
#endif
        }
      }
    }
  }
  GrowingStage = NotSet;  // finished
}
void BossBot::update(Game *game){
	////////////////////////
	///////////////////////
	///////////////////////
	if(dead) {
		return;
	}
	// If hitpoints are 0, remove it
	if(hitPoints <= 0){
		setCurrentState(direction==1?DYING_RIGHT:DYING_LEFT);
		game->getGSM()->getSpriteManager()->addBotToRemovalList(this, 15);
		dead = true;
		game->getGSM()->goToLevelWon();
		return;
	}

	// Decrement frames since last attack
	cooldownCounter--;
	if(getCurrentState()==ATTACKING_RIGHT||getCurrentState()==ATTACKING_LEFT){
		if(this->getFrameIndex()==10)
			setCurrentState(direction==1?IDLE_RIGHT:IDLE_LEFT);
	}
	// If can attack, check if player in range.
	if(cooldownCounter <= 0){
		// If player is next to this bot, do something different
		int botX = getCurrentBodyX() * BOX2D_CONVERSION_FACTOR;
		int pX = game->getGSM()->getSpriteManager()->getPlayer()->getCurrentBodyX() * BOX2D_CONVERSION_FACTOR;

		// If the player is within the bots targeting area, go after the player
		if(isInBounds(pX)) {
			int botY = getCurrentBodyY() * BOX2D_CONVERSION_FACTOR;
			int pY = game->getGSM()->getSpriteManager()->getPlayer()->getCurrentBodyY() * BOX2D_CONVERSION_FACTOR;
			// Make sure the player is in the same y area
			if(std::abs(botY - pY) < 200){
				if (pX<botX)
					direction=-1;
				else 
					direction=1;
				cooldownCounter = attackCooldown;
				this->setCurrentState(direction==1?ATTACKING_RIGHT:ATTACKING_LEFT);
				// Seed
				AnimatedSpriteType *seedSpriteType = game->getGSM()->getSpriteManager()->getSpriteType(3);
				Seed *seed = new Seed(PROJECTILE_DESIGNATION, true);

				seed->setHitPoints(1);
				seed->setDamage(SEED_DAMAGE);
				seed->setSpriteType(seedSpriteType);
				seed->setAlpha(255);
				seed->setCurrentState(IDLE_LEFT);
				PhysicalProperties *seedProps = seed->getPhysicalProperties();
				seedProps->setX(botX);
				seedProps->setY(game->getGSM()->getWorld()->getWorldHeight() - botY);
				seedProps->setVelocity(0.0f, 0.0f);
				seedProps->setAccelerationX(0);
				seedProps->setAccelerationY(0);
				seed->setOnTileThisFrame(false);
				seed->setOnTileLastFrame(false);
				seed->affixTightAABBBoundingVolume();

				//create a physics object for the seed
				game->getGSM()->getBoxPhysics()->getPhysicsFactory()->createEnemyObject(game,seed,false);

				float difX = botX - pX;
				float difY = botY - pY;
				// Set the velocity of the seed
				float length = std::sqrt( (difX * difX) + (difY * difY) );

				// Normalize the distances
				difX /= length;
				difY /= length;

				// Scale distances to be x and y velocity
				difX *= PROJECTILE_VELOCITY;
				difY = difY*PROJECTILE_VELOCITY-10;
				seed->getPhysicsBody()->SetLinearVelocity(b2Vec2(-difX, -difY));

				game->getGSM()->getPhysics()->addCollidableObject(seed);
				game->getGSM()->getSpriteManager()->addBot(seed);
			}
		}
	}
	
	
	
	
	
	
	//////////////////////
	///////////////////////
	///////////////////////
	/*
	if(dead) {
		return;
	}
	// If hitpoints are 0, remove it
	if(hitPoints <= 0){
		game->getGSM()->goToLevelWon();
		game->getGSM()->getSpriteManager()->addBotToRemovalList(this, 0);
		dead = true;
		return;
	}

	// Decrement frames since last attack
	cooldownCounter--;
	// If can attack, check if player in range.
	if(cooldownCounter <= 0){
		// If player is next to this bot, do something different
		int botX = getCurrentBodyX() * BOX2D_CONVERSION_FACTOR;
		int pX = game->getGSM()->getSpriteManager()->getPlayer()->getCurrentBodyX() * BOX2D_CONVERSION_FACTOR;

		// If the player is within the bots targeting area, go after the player
		if(isInBounds(pX)) {
			int botY = getCurrentBodyY() * BOX2D_CONVERSION_FACTOR;
			int pY = game->getGSM()->getSpriteManager()->getPlayer()->getCurrentBodyY() * BOX2D_CONVERSION_FACTOR;
			// Make sure the player is in the same y area
			if(std::abs(botY - pY) < 200){
				cooldownCounter = attackCooldown;

				// Seed
				AnimatedSpriteType *seedSpriteType = game->getGSM()->getSpriteManager()->getSpriteType(3);
				Seed *seed = new Seed(PROJECTILE_DESIGNATION, true);
				seed->setHitPoints(1);
				seed->setDamage(SEED_DAMAGE);
				seed->setSpriteType(seedSpriteType);
				seed->setAlpha(255);
				seed->setCurrentState(IDLE_LEFT);
				PhysicalProperties *seedProps = seed->getPhysicalProperties();
				seedProps->setX(botX);
				seedProps->setY(game->getGSM()->getWorld()->getWorldHeight() - botY);
				seedProps->setVelocity(0.0f, 0.0f);
				seedProps->setAccelerationX(0);
				seedProps->setAccelerationY(0);
				seed->setOnTileThisFrame(false);
				seed->setOnTileLastFrame(false);
				seed->affixTightAABBBoundingVolume();

				//create a physics object for the seed
				game->getGSM()->getBoxPhysics()->getPhysicsFactory()->createEnemyObject(game,seed,true);

				// Set the velocity of the seed
				seed->getPhysicsBody()->SetLinearVelocity(b2Vec2(attackSpeed, 0.5));

				game->getGSM()->getPhysics()->addCollidableObject(seed);
				game->getGSM()->getSpriteManager()->addBot(seed);
			}
		}
	}
	*/
}
Beispiel #10
0
int rnasequel::build_transcriptome(int argc, char * argv[]) {
    Timer ti("Total time building the transcriptome");
    po::variables_map vm;
    tx_init_options(argc,argv,vm);

    FastaIndex fi(vm["ref"].as<string>());
    fi.load_all(false);
    unsigned int read_size  = vm["read-size"].as<unsigned int>();

    std::vector<bool>   tskips(fi.size(), false);
    bool skip_nc = vm.count("skip-non-canonical") > 0;

    {
	string skip = vm["skip"].as<string>();
	Tokenizer::token_t skips;
	Tokenizer::get(skip, ',', skips);
	for(size_t i = 0; i < skips.size(); i++){
	    FastaIndex::const_iterator it = fi.get_entry(skips[i]);
	    if(it != fi.end()) tskips[it->tid] = true;
	}
    }

    JunctionSet pjuncs, mjuncs, ajuncs;
    std::map<Junction, Strand> strand_map;
    SpliceSiteStrand strander;
    SpliceSiteMap splice_sites;

    if(vm.count("gtf") > 0) {
        int min_intron = vm["min-intron"].as<unsigned int>();
	Model m;
	GTF::parse(vm["gtf"].as<string>(), m);
        splice_sites.build_from_model(m);
        size_t kept = 0;
	for(Model::iterator it = m.begin(); it != m.end(); it++){
	    unsigned int tid = fi.tid(it->first);
	    if(tskips[tid]) continue;
	    for(size_t i = 0; i < it->second.size(); i++){
		for(Gene::iterator it2 = it->second[i].begin(); it2 != it->second[i].end(); it2++){
		    Transcript::junc_iterator jit = it2->junc_it();
		    while(jit.next()){
                        int isize = jit->rgt() - jit->lft() - 1;
                        if(isize < min_intron) continue;
                        Junction j(tid, jit->lft(), jit->rgt(), jit->strand());
			if(it2->strand() == PLUS){
                            strander.add_junction(j);
			    if(pjuncs.insert(j).second) kept++;
			}else{
                            strander.add_junction(j);
			    if(mjuncs.insert(j).second) kept++;
			}
		    }
		}
	    }
	}

        cout << "  Kept " << kept << " annotated junctions from the gtf file\n";
    }

    if(vm.count("bam") > 0){
        bool use_repeats = vm.count("use-repeats") > 0;
        SpliceStrand infer_strand(vm["canonical"].as<string>());
        std::map<Junction, JunctionCount> counts;
        BamReader bin(vm["bam"].as<string>());
        BamRead r;

        size_t min_length = vm["min-length"].as<unsigned int>();
        unsigned int end_cutoff = vm["end-cutoff"].as<unsigned int>();

        std::vector<int> tidmap(bin.header().size());
        for(size_t i = 0; i < bin.header().size(); i++){
            tidmap[i] = fi[bin.header()[i]].tid;
        }

        cout << "Extracting novel splice junctions" << endl;
        Timer ti2("Time extracting junctions");
        size_t total = 0;
        while(bin.get_read(r)){
            total++;
            if(total % 0x40000 == 0){
                time_t e = ti2.elapsed();
                if(e > 0){
                    std::cerr << "\33[2K\rTotal processed: " << total 
                        << ",  reads / second: " << (total / e);
                    std::cerr.flush();
                }
            }

            if(!r.aligned() || !r.flag.paired || !r.flag.proper_pair || r.flag.secondary){
                continue;
            }
            
            size_t num_juncs = std::count_if(r.cigar.begin(), r.cigar.end(), is_skip);
            if(num_juncs == 0 || (!use_repeats && r.repeat())) continue;

            uint64_t block = 0;
            if(r.flag.paired && r.flag.proper_pair){
                int tlen = r.tlen();
                if(tlen < 0){
                    block = (static_cast<uint64_t>(r.rgt() + r.cigar.back_clipped() - (tlen - 1)) << 32) | static_cast<uint64_t>(r.lft() - r.cigar.front_clipped() + tlen - 1);
                }else{
                    block = (static_cast<uint64_t>(r.lft()) << 32) | static_cast<uint64_t>(r.lft() + tlen - 1);
                }
            }

            size_t junc_num = 1;
            SeedIterator<Cigar::const_iterator> bit(r.cigar.begin(), r.cigar.end(), r.lft(), 0);
            Seed l = bit();

            int tid = tidmap[r.tid()];
            const PackedSequence & ref = fi[tid].seq;
            unsigned int qrgt = r.qrgt();

            while(bit.next()){
                Junction j(tid, l.rrgt(), bit().rlft(), UNKNOWN);
                Strand s1 = splice_sites.find(r.tname(), j.lft).infer();
                Strand s2 = splice_sites.find(r.tname(), j.rgt).infer();
                Strand strand;

                if((s1 == UNKNOWN && s2 == UNKNOWN) || (s1 != UNKNOWN && s2 != UNKNOWN && s1 != s2)){
                    strand = infer_strand.strand(ref[j.lft + 1], ref[j.lft + 2], ref[j.rgt - 2], ref[j.rgt - 1]);
                }else{
                    strand = s1 == UNKNOWN ? s2 : s1;
                }

                bool end = l.qrgt() < end_cutoff || r.qlft() >= (qrgt - end_cutoff);

                j.strand = strand;

                if((junc_num != 1 || l.score() >= static_cast<int>(min_length)) 
                    && (junc_num != num_juncs || bit().score() >= static_cast<int>(min_length))){

                    JunctionCount & jc = counts[j];
                    jc.count++;
                    jc.positions.insert(block);
                    if(end) jc.ends++;
                }
                l = bit();
                junc_num++;
            }
        }


        unsigned int min_intron    = vm["min-intron"].as<unsigned int>();
        unsigned int max_intron    = vm["max-intron"].as<unsigned int>();
        unsigned int min_unique    = vm["min-unique"].as<unsigned int>();
        unsigned int min_count     = vm["min-count"].as<unsigned int>();
        unsigned int end_count     = vm["end-count"].as<unsigned int>();
        unsigned int min_nc_unique    = vm["min-nc-unique"].as<unsigned int>();
        unsigned int min_nc_count     = vm["min-nc-count"].as<unsigned int>();

        size_t kept = 0, total_novel = 0;
        size_t nc_kept = 0, nc_total_novel = 0;

        for(auto const & j : counts){
            const Junction & junc    = j.first;
            const JunctionCount & jc = j.second;
            unsigned int isize = junc.isize();
            const PackedSequence & ref = fi[junc.tid].seq;
            bool canonical = infer_strand.canonical(ref[junc.lft + 1], ref[junc.lft + 2], ref[junc.rgt - 2], ref[junc.rgt - 1]);

            bool found = false;
            if(junc.strand == PLUS){
                found = pjuncs.find(junc) != pjuncs.end();
            }else if(junc.strand == MINUS){
                found = mjuncs.find(junc) != mjuncs.end();
            }else{
                found = ajuncs.find(junc) != ajuncs.end();
            }
            
            if(!found) {
                if(canonical) total_novel++;
                else          nc_total_novel++;
            }

            if((canonical && (jc.count < min_count || jc.positions.size() < min_unique)) ||
               (!canonical && (jc.count < min_nc_count || jc.positions.size() < min_nc_unique)) || 
                isize < min_intron || isize > max_intron || (jc.count - jc.ends) < end_count){
                continue;
            }

            if(!found) {
                if(junc.strand == PLUS){
                    pjuncs.insert(junc);
                }else if(junc.strand == MINUS){
                    mjuncs.insert(junc);
                }else{
                    ajuncs.insert(junc);
                }
                if(canonical) kept++;
                else          nc_kept++;
            }
        }
        cout << "\n\nKept " << kept << " out of " << total_novel << " novel junctions\n";
        if(!skip_nc) cout << "Kept " << nc_kept << " out of " << nc_total_novel << " non-canonical novel junctions\n";
    }

    if(!skip_nc){
        for(auto const & j : ajuncs){
            Strand lft = strander.find_lft(j.tid, j.lft);
            Strand rgt = strander.find_rgt(j.tid, j.rgt);
            Strand strand = BOTH;

            if(lft != BOTH && rgt != BOTH && lft == rgt){
                strand = lft;
            }else if(lft == BOTH && rgt != BOTH){
                strand = rgt;
            }else if(lft != BOTH && rgt == BOTH){
                strand = lft;
            }

            if(strand == PLUS){
                pjuncs.insert(j);
            }else if(strand == MINUS){
                mjuncs.insert(j);
            }else{
                pjuncs.insert(j);
                mjuncs.insert(j);
            }
        }
    }

    Transcriptome builder(vm["out"].as<string>(), fi, read_size, vm["max-iter"].as<unsigned int>(), false);
    builder.process_junctions(pjuncs, PLUS);
    builder.process_junctions(mjuncs, MINUS);

    return 0;
}