void Utility::Yuv422FileSaver::savePlanar() {
	for(std::size_t k=0; k<video_->getNumberOfFrames()&&isRunning_; k++) {
		QVector<unsigned char> uBuffer;
		QVector<unsigned char> vBuffer;
		auto frame=video_->getFrame(k);
		for(int i=0; i<width_*height_; i+=2) {
			int y1=i/width_;
			int x1=i%width_;
			int y2=(i+1)/width_;
			int x2=(i+1)%width_;

			if(!frame->valid(x1,y1)||!frame->valid(x2,y2)) {
				qDebug()<<"Wrong pixel coordinates";
				continue;
			}

			auto vec=Rgb888ToYuv422(frame->pixel(x1,y1),frame->pixel(x2,y2));
			dataStream_<<vec.getY1()<<vec.getY2();
			uBuffer.push_back(vec.getU());
			vBuffer.push_back(vec.getV());
		}
		while (!uBuffer.isEmpty()) {
			dataStream_<<uBuffer.takeFirst();
		}
		while (!vBuffer.isEmpty()) {
			dataStream_<<vBuffer.takeFirst();
		}
	}
}
Example #2
0
void Model::modifyLastAdded(QVector<QVector3D> &guidePoints)
{
    if (guidePoints.size() < 2 || activeNode == nullptr) return;

    Structure::Curve* curve = dynamic_cast<Structure::Curve*>(activeNode);
    Structure::Sheet* sheet = dynamic_cast<Structure::Sheet*>(activeNode);

    auto fp = guidePoints.takeFirst();
    Vector3 axis(fp.x(),fp.y(),fp.z());

    int skipAxis = -1;
    if (axis.isApprox(-Vector3::UnitX())) skipAxis = 0;
    if (axis.isApprox(-Vector3::UnitY())) skipAxis = 1;
    if (axis.isApprox(Vector3::UnitZ())) skipAxis = 2;

    // Smooth curve
    guidePoints = GeometryHelper::smooth(GeometryHelper::uniformResampleCount(guidePoints, 20), 5);

    // Convert to Vector3
    Array1D_Vector3 gpoint;
    for(auto p : guidePoints) gpoint.push_back(Vector3(p[0],p[1],p[2]));

    if(curve)
    {
        auto oldPoints = curve->controlPoints();
        auto newPoints = oldPoints;

        for(size_t i = 0; i < oldPoints.size(); i++){
            for(int j = 0; j < 3; j++){
                if(j == skipAxis) newPoints[i][j] = oldPoints[i][j];
                else newPoints[i][j] = gpoint[i][j];
            }
        }

        curve->setControlPoints(newPoints);
    }

    if(sheet)
    {
        auto oldPoints = sheet->controlPoints();
        auto newPoints = oldPoints;

        Vector3 centroid = sheet->position(Eigen::Vector4d(0.5, 0.5, 0, 0));
        Vector3 delta = gpoint.front() - centroid;

        for(size_t i = 0; i < oldPoints.size(); i++){
            for (int j = 0; j < 3; j++){
                if (j == skipAxis) continue;
                newPoints[i][j] += delta[j];
            }
        }

        sheet->setControlPoints(newPoints);
        sheet->surface.quads.clear();
    }

    generateSurface();
}
QVariantMap QgsSplitWithLinesAlgorithm::processAlgorithm( const QVariantMap &parameters, QgsProcessingContext &context, QgsProcessingFeedback *feedback )
{
  std::unique_ptr< QgsFeatureSource > source( parameterAsSource( parameters, QStringLiteral( "INPUT" ), context ) );
  if ( !source )
    throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "INPUT" ) ) );

  std::unique_ptr< QgsFeatureSource > linesSource( parameterAsSource( parameters, QStringLiteral( "LINES" ), context ) );
  if ( !linesSource )
    throw QgsProcessingException( invalidSourceError( parameters, QStringLiteral( "LINES" ) ) );

  bool sameLayer = parameters.value( QStringLiteral( "INPUT" ) ) == parameters.value( QStringLiteral( "LINES" ) );

  QString dest;
  std::unique_ptr< QgsFeatureSink > sink( parameterAsSink( parameters, QStringLiteral( "OUTPUT" ), context, dest, source->fields(),
                                          QgsWkbTypes::multiType( source->wkbType() ),  source->sourceCrs() ) );
  if ( !sink )
    throw QgsProcessingException( invalidSinkError( parameters, QStringLiteral( "OUTPUT" ) ) );

  QgsSpatialIndex spatialIndex;
  QMap< QgsFeatureId, QgsGeometry > splitGeoms;
  QgsFeatureRequest request;
  request.setSubsetOfAttributes( QgsAttributeList() );
  request.setDestinationCrs( source->sourceCrs(), context.transformContext() );

  QgsFeatureIterator splitLines = linesSource->getFeatures( request );
  QgsFeature aSplitFeature;
  while ( splitLines.nextFeature( aSplitFeature ) )
  {
    if ( feedback->isCanceled() )
    {
      break;
    }

    splitGeoms.insert( aSplitFeature.id(), aSplitFeature.geometry() );
    spatialIndex.addFeature( aSplitFeature );
  }

  QgsFeature outFeat;
  QgsFeatureIterator features = source->getFeatures();

  double step = source->featureCount() > 0 ? 100.0 / source->featureCount() : 1;
  int i = 0;
  QgsFeature inFeatureA;
  while ( features.nextFeature( inFeatureA ) )
  {
    i++;
    if ( feedback->isCanceled() )
    {
      break;
    }

    if ( !inFeatureA.hasGeometry() )
    {
      sink->addFeature( inFeatureA, QgsFeatureSink::FastInsert );
      continue;
    }

    QgsGeometry inGeom = inFeatureA.geometry();
    outFeat.setAttributes( inFeatureA.attributes() );

    QVector< QgsGeometry > inGeoms = inGeom.asGeometryCollection();

    const QgsFeatureIds lines = spatialIndex.intersects( inGeom.boundingBox() ).toSet();
    if ( !lines.empty() ) // has intersection of bounding boxes
    {
      QVector< QgsGeometry > splittingLines;

      // use prepared geometries for faster intersection tests
      std::unique_ptr< QgsGeometryEngine > engine;

      for ( QgsFeatureId line : lines )
      {
        // check if trying to self-intersect
        if ( sameLayer && inFeatureA.id() == line )
          continue;

        QgsGeometry splitGeom = splitGeoms.value( line );
        if ( !engine )
        {
          engine.reset( QgsGeometry::createGeometryEngine( inGeom.constGet() ) );
          engine->prepareGeometry();
        }

        if ( engine->intersects( splitGeom.constGet() ) )
        {
          QVector< QgsGeometry > splitGeomParts = splitGeom.asGeometryCollection();
          splittingLines.append( splitGeomParts );
        }
      }

      if ( !splittingLines.empty() )
      {
        for ( const QgsGeometry &splitGeom : qgis::as_const( splittingLines ) )
        {
          QVector<QgsPointXY> splitterPList;
          QVector< QgsGeometry > outGeoms;

          // use prepared geometries for faster intersection tests
          std::unique_ptr< QgsGeometryEngine > splitGeomEngine( QgsGeometry::createGeometryEngine( splitGeom.constGet() ) );
          splitGeomEngine->prepareGeometry();
          while ( !inGeoms.empty() )
          {
            if ( feedback->isCanceled() )
            {
              break;
            }

            QgsGeometry inGeom = inGeoms.takeFirst();
            if ( !inGeom )
              continue;

            if ( splitGeomEngine->intersects( inGeom.constGet() ) )
            {
              QgsGeometry before = inGeom;
              if ( splitterPList.empty() )
              {
                const QgsCoordinateSequence sequence = splitGeom.constGet()->coordinateSequence();
                for ( const QgsRingSequence &part : sequence )
                {
                  for ( const QgsPointSequence &ring : part )
                  {
                    for ( const QgsPoint &pt : ring )
                    {
                      splitterPList << QgsPointXY( pt );
                    }
                  }
                }
              }

              QVector< QgsGeometry > newGeometries;
              QVector<QgsPointXY> topologyTestPoints;
              QgsGeometry::OperationResult result = inGeom.splitGeometry( splitterPList, newGeometries, false, topologyTestPoints );

              // splitGeometry: If there are several intersections
              // between geometry and splitLine, only the first one is considered.
              if ( result == QgsGeometry::Success ) // split occurred
              {
                if ( inGeom.isGeosEqual( before ) )
                {
                  // bug in splitGeometry: sometimes it returns 0 but
                  // the geometry is unchanged
                  outGeoms.append( inGeom );
                }
                else
                {
                  inGeoms.append( inGeom );
                  inGeoms.append( newGeometries );
                }
              }
              else
              {
                outGeoms.append( inGeom );
              }
            }
            else
            {
              outGeoms.append( inGeom );
            }

          }
          inGeoms = outGeoms;
        }
      }
    }

    QVector< QgsGeometry > parts;
    for ( const QgsGeometry &aGeom : qgis::as_const( inGeoms ) )
    {
      if ( feedback->isCanceled() )
      {
        break;
      }

      bool passed = true;
      if ( QgsWkbTypes::geometryType( aGeom.wkbType() ) == QgsWkbTypes::LineGeometry )
      {
        int numPoints = aGeom.constGet()->nCoordinates();

        if ( numPoints <= 2 )
        {
          if ( numPoints == 2 )
            passed = !static_cast< const QgsCurve * >( aGeom.constGet() )->isClosed(); // tests if vertex 0 = vertex 1
          else
            passed = false; // sometimes splitting results in lines of zero length
        }
      }

      if ( passed )
        parts.append( aGeom );
    }

    for ( const QgsGeometry &g : parts )
    {
      outFeat.setGeometry( g );
      sink->addFeature( outFeat, QgsFeatureSink::FastInsert );
    }

    feedback->setProgress( i * step );
  }

  QVariantMap outputs;
  outputs.insert( QStringLiteral( "OUTPUT" ), dest );
  return outputs;
}
Example #4
0
PostingIterator* SearchStore::constructQuery(Transaction* tr, const Term& term)
{
    Q_ASSERT(tr);

    if (term.operation() == Term::And || term.operation() == Term::Or) {
        const QList<Term> subTerms = term.subTerms();
        QVector<PostingIterator*> vec;
        vec.reserve(subTerms.size());

        for (const Term& t : subTerms) {
            auto iterator = constructQuery(tr, t);
            // constructQuery returns a nullptr to signal an empty list
            if (iterator) {
                vec << iterator;
            } else if (term.operation() == Term::And) {
                return nullptr;
            }
        }

        if (vec.isEmpty()) {
            return nullptr;
        } else if (vec.size() == 1) {
            return vec.takeFirst();
        }

        if (term.operation() == Term::And) {
            return new AndPostingIterator(vec);
        } else {
            return new OrPostingIterator(vec);
        }
    }

    if (term.value().isNull()) {
        return nullptr;
    }
    Q_ASSERT(term.value().isValid());
    Q_ASSERT(term.comparator() != Term::Auto);
    Q_ASSERT(term.comparator() == Term::Contains ? term.value().type() == QVariant::String : true);

    const QVariant value = term.value();
    const QByteArray property = term.property().toLower().toUtf8();

    if (property == "type" || property == "kind") {
        EngineQuery q = constructTypeQuery(value.toString());
        return tr->postingIterator(q);
    }
    else if (property == "includefolder") {
        const QByteArray folder = QFile::encodeName(QFileInfo(value.toString()).canonicalFilePath());

        Q_ASSERT(!folder.isEmpty());
        Q_ASSERT(folder.startsWith('/'));

        quint64 id = filePathToId(folder);
        if (!id) {
            qDebug() << "Folder" << value.toString() << "does not exist";
            return nullptr;
        }

        return tr->docUrlIter(id);
    }
    else if (property == "modified" || property == "mtime") {
        if (value.type() == QVariant::ByteArray) {
            QByteArray ba = value.toByteArray();
            Q_ASSERT(ba.size() >= 4);

            int year = ba.mid(0, 4).toInt();
            int month = ba.mid(4, 2).toInt();
            int day = ba.mid(6, 2).toInt();

            Q_ASSERT(year);

            // uses 0 to represent whole month or whole year
            month = month >= 0 && month <= 12 ? month : 0;
            day = day >= 0 && day <= 31 ? day : 0;

            QDate startDate(year, month ? month : 1, day ? day : 1);
            QDate endDate(startDate);

            if (month == 0) {
                endDate.setDate(endDate.year(), 12, 31);
            } else if (day == 0) {
                endDate.setDate(endDate.year(), endDate.month(), endDate.daysInMonth());
            }

            return tr->mTimeRangeIter(QDateTime(startDate).toTime_t(), QDateTime(endDate, QTime(23, 59, 59)).toTime_t());
        }
        else if (value.type() == QVariant::Date || value.type() == QVariant::DateTime) {
            const QDateTime dt = value.toDateTime();
            return constructMTimeQuery(tr, dt, term.comparator());
        }
        else {
            Q_ASSERT_X(0, "SearchStore::constructQuery", "modified property must contain date/datetime values");
        }
    }
    else if (property == "rating") {
        bool okay = false;
        int rating = value.toInt(&okay);
        if (!okay) {
            qDebug() << "Rating comparisons must be with an integer";
            return nullptr;
        }

        PostingDB::Comparator pcom;
        if (term.comparator() == Term::Greater || term.comparator() == Term::GreaterEqual) {
            pcom = PostingDB::GreaterEqual;
            if (term.comparator() == Term::Greater && rating)
                rating++;
        }
        else if (term.comparator() == Term::Less || term.comparator() == Term::LessEqual) {
            pcom = PostingDB::LessEqual;
            if (term.comparator() == Term::Less)
                rating--;
        }
        else if (term.comparator() == Term::Equal) {
            EngineQuery q = constructEqualsQuery("R", value.toString());
            return tr->postingIterator(q);
        }
        else {
            Q_ASSERT(0);
            return nullptr;
        }

        const QByteArray prefix = "R";
        const QByteArray val = QByteArray::number(rating);
        return tr->postingCompIterator(prefix, val, pcom);
    } else if (property == "tag") {
        if (term.comparator() == Term::Equal) {
            const QByteArray prefix = "TAG-";
            EngineQuery q = EngineQuery(prefix + value.toByteArray());
            return tr->postingIterator(q);
        } else if (term.comparator() == Term::Contains) {
            const QByteArray prefix = "TA";
            EngineQuery q = constructEqualsQuery(prefix, value.toString());
            return tr->postingIterator(q);
        } else {
            Q_ASSERT(0);
            return nullptr;
        }
    }

    QByteArray prefix;
    if (!property.isEmpty()) {
        prefix = fetchPrefix(property);
        if (prefix.isEmpty()) {
            return nullptr;
        }
    }

    auto com = term.comparator();
    if (com == Term::Contains) {
        EngineQuery q = constructContainsQuery(prefix, value.toString());
        return tr->postingIterator(q);
    }

    if (com == Term::Equal) {
        EngineQuery q = constructEqualsQuery(prefix, value.toString());
        return tr->postingIterator(q);
    }

    QVariant val = term.value();
    if (val.type() == QVariant::Int) {
        int intVal = value.toInt();

        PostingDB::Comparator pcom;
        if (term.comparator() == Term::Greater || term.comparator() == Term::GreaterEqual) {
            pcom = PostingDB::GreaterEqual;
            if (term.comparator() == Term::Greater && intVal)
                intVal++;
        }
        else if (term.comparator() == Term::Less || term.comparator() == Term::LessEqual) {
            pcom = PostingDB::LessEqual;
            if (term.comparator() == Term::Less)
                intVal--;
        }
        else {
            Q_ASSERT(0);
            return nullptr;
        }

        return tr->postingCompIterator(prefix, QByteArray::number(intVal), pcom);
    }

    return nullptr;
}
/*
 * Load the file with chosen filename and emit the signal sendFileData() when the file is read.
 */
void ConvertEcgToIbi::run()
{
	QFile myFile(fname);
	if (myFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
		time.start();
		QTextStream ecgInfo(&myFile);
		QVector<int > ecgVals;
        QVector<double> timeData;
		int iterations;
		if (!ecgInfo.atEnd()) {
			QString strVals = ecgInfo.readLine();
			ecgInfo.readLine();
			ecgInfo.readLine();
			double tmp;
			int i=0;
			while (!ecgInfo.atEnd()) {

				strVals = ecgInfo.readLine();
				QStringList strPieces = strVals.split(QRegularExpression("\\s+"));


				if (strPieces.length()==4) {
                    tmp=strPieces[2].toDouble();
                    ecgVals.append((tmp*500)); ///< @todo normalize input to work with more files

				}
				else if (strPieces.length()==3) {
                                    tmp=strPieces[2].toDouble();
                                    ecgVals.append((tmp*500));
                                                    }
				else if (strPieces.length()==5){

					tmp=strPieces[2].toDouble();
                    ecgVals.append((tmp*500));
                    }
				else {
					std::cerr << "Wrong File" << std::endl;
					return;
				}
				i++;
                }
            QVector<double> qrsPeaks;
			extractRtoR(&ecgVals, &qrsPeaks);
            qrsPeaks.takeFirst();// Remove the influense of the QRS-detectors learning period
            qrsPeaks.takeFirst();// Remove the influense of the QRS-detectors learning period
            qrsPeaks.takeFirst();// Remove the influense of the QRS-detectors learning period
            tmp=0;
            for (int i; i<qrsPeaks.length(); i++){
                tmp=tmp+(qrsPeaks.at(i));
                timeData.append(tmp);
            }
            if (qrsPeaks.length()>10){   ///@todo FIX this check neater
                emit sendFileData(qrsPeaks,timeData);
                saveAsIbiFile(&qrsPeaks);
            }
            else
                std::cerr << "Not enough R peaks detected" << std::endl;
            qDebug("Time elapsed: %d ms", time.elapsed());

		}
		ecgInfo.flush();
		myFile.close();



	}

}
Example #6
0
void main_loop_spe( struct plan7_s * hmm, const char * seq, int seqlen, struct threshold_s *thresh, int do_forward,
            	    int do_null2, int do_xnu, struct histogram_s * histogram, struct tophit_s * ghit, struct tophit_s * dhit, 
                    int * ret_nseq, U2::TaskStateInfo & ti)
{
    Q_UNUSED( do_xnu );
    Q_UNUSED( ret_nseq );
    Q_UNUSED( ti );
//    using namespace U2;

    int initBufSize = 1;
    int cushBufSize = initBufSize;
    struct dpmatrix_s * mx;               
    struct p7trace_s * tr;                

    float  sc = .0f;
    double pvalue = 0.;
    double evalue = 0.;		   
        
    int SPE_THREADS = 8;
    int i = 0;
    int l = 0;

#ifdef USE_SDK30
    spe_context_ptr_t spe_ids[SPE_THREADS];
    pthread_t threads[SPE_THREADS];
#else
    speid_t spe_ids[SPE_THREADS];
    spe_gid_t spe_gid;
#endif

    spe_initContextSB *  spe_contexts;
    spe_jobEntity     *  jobQueue;
    int                  jobQueueIndex;

    volatile int    nomoreSeqs_var    __attribute__ ((aligned (128)));
    atomic_ea_t     nomoreSeqs;
    addr64          long_addr_nomoreSeqs;

    volatile int    lastConsumed_var    __attribute__ ((aligned (128)));
    atomic_ea_t     lastConsumed;
    addr64          long_addr_lastConsumed;

    volatile int    bufferEntries_var    __attribute__ ((aligned (128)));
    atomic_ea_t     bufferEntries;
    addr64          long_addr_bufferEntries;

    volatile int    bufferMutex_var    __attribute__ ((aligned (128)));
    mutex_ea_t      bufferMutex;
    addr64          long_addr_bufferMutex;

    volatile int    bufferEmptyCond_var    __attribute__ ((aligned (128)));
    cond_ea_t       bufferEmptyCond;
    addr64          long_addr_bufferEmptyCond;

    int * scratchBuffer;
    hmm_offsets * offsets;

    int * sequencesMatrix;
    int * lengthMatrix;
    int   numSeqs = 0;
    int   numTracebacks = 0;

    char * mem_addr = NULL;
    unsigned char  * seqAddr;

    int   seqsFinished  = 0;
    int   numCushion    = 0;

    /*--------------1 - SETUP: ALLOCATE MEMORY FOR DATA STRUCTURES---------------------*/
    nomoreSeqs_var = 0;
    long_addr_nomoreSeqs.ui[0] = 0;
    long_addr_nomoreSeqs.ui[1] = (unsigned int) (&nomoreSeqs_var);
    nomoreSeqs = (atomic_ea_t) long_addr_nomoreSeqs.ull;

    lastConsumed_var = 0;
    long_addr_lastConsumed.ui[0] = 0;
    long_addr_lastConsumed.ui[1] = (unsigned int) (&lastConsumed_var);
    lastConsumed = (atomic_ea_t) long_addr_lastConsumed.ull;

    bufferEntries_var = 0;
    long_addr_bufferEntries.ui[0] = 0;
    long_addr_bufferEntries.ui[1] = (unsigned int) (&bufferEntries_var);
    bufferEntries = (atomic_ea_t) long_addr_bufferEntries.ull;

    bufferMutex_var = 0;
    long_addr_bufferMutex.ui[0] = 0;
    long_addr_bufferMutex.ui[1] = (unsigned int) (&bufferMutex_var);
    bufferMutex = (mutex_ea_t) long_addr_bufferMutex.ull;

    bufferEmptyCond_var = 0;
    long_addr_bufferEmptyCond.ui[0] = 0;
    long_addr_bufferEmptyCond.ui[1] = (unsigned int) (&bufferEmptyCond_var);
    bufferEmptyCond = (cond_ea_t) long_addr_bufferEmptyCond.ull;

#ifndef NO_HUGE_PAGES
    assert( false && "correct huge pages realization is not implemented yet" );
    //FIXME: implement correct 'huge pages' memory allocation    
#else
    mem_addr = (char *) memalign( 128, 0x09000000 );
    memset( mem_addr, 0, 0x09000000 );
#endif

    assert( NULL != mem_addr );
    //Allocate all data structures on mapped area
    scratchBuffer   = (int*)               (mem_addr + 0x0000000);
    offsets         = (hmm_offsets*)       (mem_addr + 0x0050000);
    spe_contexts    = (spe_initContextSB*) (mem_addr + 0x0051000);
    sequencesMatrix = (int*)               (mem_addr + 0x0400000);
    lengthMatrix    = (int*)               ((unsigned long)((char *)sequencesMatrix + NUM_OF_SEQS_UPPER_LIMIT * 4 + 127)&~0x7F);
    MakeHMMBuffer_Aligned(hmm, (void*) scratchBuffer, 0x0050000, offsets);  
        
    /*--------------2 - CREATE INITIAL BUFFER---------------------*/
    /* This stage is where we create a small preliminary buffer that will hold
    enough sequences to get the SPEs started. Once the SPE threads start fetching
    and processing sequences, we will be populating the buffer fully in Stage 4. */

    jobQueue = (spe_jobEntity*) ((unsigned long)((char*)lengthMatrix + NUM_OF_SEQS_UPPER_LIMIT * 4 + 127)&~0x7F);
    seqAddr  = (unsigned char *)jobQueue + NUM_OF_SEQS_UPPER_LIMIT * 128;

    jobQueueIndex = -1;
    atomic_set(bufferEntries,0);
    //Initialize mutexes etc.
    mutex_init(bufferMutex);
    cond_init(bufferEmptyCond);

    //FIXME refactoring needed
    //FIXME use non-constant chunk size
    U2Region wholeSeq( 0, seqlen );
//    int veryMaxChunkSize = MAX_SEQ_LENGTH - 100;
//    int approxChunkSize = seqlen / 24;
//    int maxChunkSize = qBound( hmm->M, approxChunkSize, veryMaxChunkSize );
    assert( hmm->M < MAX_HMM_LENGTH );
    int overlap = hmm->M * 2;
    int exOverlap = 0;
//    int chunkSize = qMax( hmm->M+2, maxChunkSize-1 - overlap );
    int chunkSize = qBound( hmm->M+2, MAX_SEQ_LENGTH-100, seqlen );
    if( chunkSize + overlap > MAX_SEQ_LENGTH - 100 ) {
	chunkSize -= overlap;
    }    
    int maxChunkSize = MAX_SEQ_LENGTH-100;

    QVector<U2Region> regions;
    regions = SequenceWalkerTask::splitRange( wholeSeq, chunkSize, overlap, 0, 1, false );
    assert( !regions.empty() );
    
    //hack caused by splitRange behaviour
    if( regions.first().length > maxChunkSize ) {
//        assert( 1 == regions.size() );
        U2Region r1st = regions.takeFirst();
        assert( r1st.length < 2 * maxChunkSize );
        
//        int len = chunkSize + overlap / 2;
	int len = chunkSize;
        int tail = r1st.length - len;
        int z = overlap/2 - tail;
        len -= qMax( 0, z );
                
        assert( 0 == r1st.startPos );
        U2Region r1( r1st.startPos, len );
        U2Region r2( len - overlap/2,  r1st.length-(len-overlap/2) );
        regions.push_front( r2 );
        regions.push_front( r1 );
    }

    foreach( U2Region r, regions ) {
        assert( r.length <= MAX_SEQ_LENGTH-100 );
    }