bool RenderLayerCompositor::overlapsCompositedLayers(OverlapMap& overlapMap, const IntRect& layerBounds)
{
    RenderLayerCompositor::OverlapMap::const_iterator end = overlapMap.end();
    for (RenderLayerCompositor::OverlapMap::const_iterator it = overlapMap.begin(); it != end; ++it) {
        const IntRect& bounds = it->second;
        if (layerBounds.intersects(bounds))
            return true;
    }
    
    return false;
}
예제 #2
0
파일: PathOverlap.cpp 프로젝트: bcgsc/abyss
/** Return the number of contigs by which the two paths overlap. */
static unsigned getOverlap(const OverlapMap& pmap,
		graph_traits<Graph>::vertex_descriptor u,
		graph_traits<Graph>::vertex_descriptor v)
{
	if (isPath(u) && isPath(v)) {
		// Both vertices are paths.
		OverlapMap::const_iterator it = pmap.find(
				edge_descriptor(u, v));
		return it == pmap.end() ? 0 : it->second;
	} else {
		// One of the two vertices is a contig.
		return 0;
	}
}
예제 #3
0
파일: PathOverlap.cpp 프로젝트: bcgsc/abyss
/** Assemble overlapping paths. */
static void assembleOverlappingPaths(Graph& g,
		Paths& paths, vector<string>& pathIDs)
{
	if (paths.empty())
		return;

	// Find overlapping paths.
	Overlaps overlaps = findOverlaps(g, paths);
	addPathOverlapEdges(g, paths, pathIDs, overlaps);

	// Create a property map of path overlaps.
	OverlapMap overlapMap;
	for (Overlaps::const_iterator it = overlaps.begin();
			it != overlaps.end(); ++it)
		overlapMap.insert(OverlapMap::value_type(
				OverlapMap::key_type(
					it->source.descriptor(),
					it->target.descriptor()),
				it->overlap));

	// Assemble unambiguously overlapping paths.
	Paths merges;
	assemble_if(g, back_inserter(merges),
			IsPathOverlap(g, overlapMap, IsPositive<Graph>(g)));

	// Merge overlapping paths.
	g_contigNames.unlock();
	assert(!pathIDs.empty());
	setNextContigName(pathIDs.back());
	for (Paths::const_iterator it = merges.begin();
			it != merges.end(); ++it) {
		string name = createContigName();
		if (opt::verbose > 0)
			cerr << name << '\t' << *it << '\n';
		Vertex u(paths.size(), false);
		put(vertex_name, g, u.descriptor(), name);
		pathIDs.push_back(name);
		paths.push_back(mergePaths(paths, overlapMap, *it));

		// Remove the merged paths.
		for (ContigPath::const_iterator it2 = it->begin();
				it2 != it->end(); ++it2) {
			if (isPath(*it2))
				paths[it2->id() - Vertex::s_offset].clear();
		}
	}
	g_contigNames.lock();
}
void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
{
    if (layer->isRootLayer())
        return;

    if (!boundsComputed) {
        layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
        boundsComputed = true;
    }

    overlapMap.add(layer, layerBounds);
}
void RenderLayerCompositor::addToOverlapMap(OverlapMap& overlapMap, RenderLayer* layer, IntRect& layerBounds, bool& boundsComputed)
{
    if (layer->isRootLayer())
        return;

    if (!boundsComputed) {
        layerBounds = layer->renderer()->localToAbsoluteQuad(FloatRect(layer->localBoundingBox())).enclosingBoundingBox();
        // Empty rects never intersect, but we need them to for the purposes of overlap testing.
        if (layerBounds.isEmpty())
            layerBounds.setSize(IntSize(1, 1));
        boundsComputed = true;
    }

    overlapMap.add(layer, layerBounds);
}
예제 #6
0
IGeometryChecker::ReturnVal OverlappedUVWFacesChecker::GeometryCheckWithUVMesh(UVWChannel &uvmesh,TimeValue t,INode *nodeToCheck, BitArray &arrayOfFaces)
{
	LARGE_INTEGER	ups,startTime;
	QueryPerformanceFrequency(&ups);
	QueryPerformanceCounter(&startTime); //used to see if we need to pop up a dialog 
	bool checkTime = GetIGeometryCheckerManager()->GetAutoUpdate();//only check time for the dialog if auto update is active!
	//get our bounding box
	Box3 bounds;
	bounds.Init();

	int numVerts = uvmesh.GetNumTVVerts();
	int i;
	for (i = 0; i < numVerts; ++i)
	{
		Point3 tv = uvmesh.GetTVVert(i);
		if(_isnan(tv.x) || !_finite(tv.x)||_isnan(tv.y) || !_finite(tv.y)||_isnan(tv.z) || !_finite(tv.z))
			return IGeometryChecker::eFail; //if we have a bad tvert bail out...
		bounds += uvmesh.GetTVVert(i);
	}
	//put a small fudge to keep faces off the edge
	bounds.EnlargeBy(0.05f);
	//build our transform

	float xScale = bounds.pmax.x - bounds.pmin.x;
	float yScale = bounds.pmax.y - bounds.pmin.y;
	Point3 offset = bounds.pmin;

	//create our buffer
	OverlapMap overlapMap;
	overlapMap.Init();
	
	Interface *ip = GetCOREInterface();
	int numProcsToUse = omp_get_num_procs()-1;
	if(numProcsToUse<0)
		numProcsToUse = 1;
	TCHAR buf[256];
	TCHAR tmpBuf[64];
	_tcscpy(tmpBuf,GetString(IDS_CHECK_TIME_USED));
	_tcscpy(buf,GetString(IDS_RUNNING_GEOMETRY_CHECKER));
	ip->PushPrompt(buf);
	int total = 0;
	bool compute = true;
	EscapeChecker::theEscapeChecker.Setup();
	for (int i = 0; i < uvmesh.GetNumOfFaces(); ++i)
	{
		if(compute==true)
		{
			//loop through the faces
			int deg = uvmesh.GetFaceDegree(i);
			int index[4];
			index[0] = uvmesh.GetFaceTVVert(i,0);
			Point3 pa = uvmesh.GetTVVert(index[0]);
			pa.x -= offset.x;
			pa.x /= xScale;

			pa.y -= offset.y;
			pa.y /= yScale;

			for (int j = 0; j < deg -2; j++)
			{
				index[1] = uvmesh.GetFaceTVVert(i,j+1);
				index[2] = uvmesh.GetFaceTVVert(i,j+2);
				Point3 pb = uvmesh.GetTVVert(index[1]);
				Point3 pc = uvmesh.GetTVVert(index[2]);

				pb.x -= offset.x;
				pb.x /= xScale;
				pb.y -= offset.y;
				pb.y /= yScale;

				pc.x -= offset.x;
				pc.x /= xScale;
				pc.y -= offset.y;
				pc.y /= yScale;

				//add face to buffer
				//select anything that overlaps
				overlapMap.Map(uvmesh,i,pa,pb,pc,arrayOfFaces);
			}
		}
		total += 1;
		
		if(compute==true)
		{
			if(EscapeChecker::theEscapeChecker.Check())
			{
				compute = false;
				_tcscpy(buf,GetString(IDS_EXITING_GEOMETRY_CHECKER));
				ip->ReplacePrompt(buf);
				break; //can now break, no omp
			}
		
			if((total%100)==0)
			{
				{
					float percent = (float)total/(float)uvmesh.GetNumOfFaces()*100.0f;
					_stprintf(buf,tmpBuf,percent);
					ip->ReplacePrompt(buf);
				}     
			}
			if(checkTime==true)
			{
				DialogChecker::Check(checkTime,compute,uvmesh.GetNumOfFaces(),startTime,ups);
				if(compute==false)
					break;
			}
		}
		
	}
	ip->PopPrompt();
	

	return TypeReturned();

}
void CompositingRequirementsUpdater::updateRecursive(PaintLayer* ancestorLayer, PaintLayer* layer, OverlapMap& overlapMap, RecursionData& currentRecursionData,
    bool& descendantHas3DTransform, Vector<PaintLayer*>& unclippedDescendants, IntRect& absoluteDescendantBoundingBox)
{
    PaintLayerCompositor* compositor = m_layoutView.compositor();

    layer->stackingNode()->updateLayerListsIfNeeded();

    CompositingReasons reasonsToComposite = CompositingReasonNone;
    CompositingReasons directReasons = m_compositingReasonFinder.directReasons(layer);

    // Video is special. It's the only PaintLayer type that can both have
    // PaintLayer children and whose children can't use its backing to render
    // into. These children (the controls) always need to be promoted into their
    // own layers to draw on top of the accelerated video.
    if (currentRecursionData.m_compositingAncestor && currentRecursionData.m_compositingAncestor->layoutObject()->isVideo())
        directReasons |= CompositingReasonVideoOverlay;

    if (currentRecursionData.m_hasCompositedScrollingAncestor && layer->layoutObject()->styleRef().hasViewportConstrainedPosition())
        directReasons |= CompositingReasonPositionFixed;

    bool canBeComposited = compositor->canBeComposited(layer);
    if (canBeComposited) {
        reasonsToComposite |= directReasons;

        if (layer->isRootLayer() && compositor->rootShouldAlwaysComposite())
            reasonsToComposite |= CompositingReasonRoot;

        if (reasonsToComposite && layer->scrollsOverflow() && !layer->needsCompositedScrolling()) {
            // We will only set needsCompositedScrolling if we don't care about
            // the LCD text hit, we may be able to switch to the compositor
            // driven path if we're alread composited for other reasons and are
            // therefore using grayscale AA.
            //
            // FIXME: it should also be possible to promote if the layer can
            // still use LCD text when promoted, but detecting when the
            // compositor can do this is tricky. Currently, the layer must be
            // both opaque and may only have an integer translation as its
            // transform. Both opacity and screen space transform are inherited
            // properties, so this cannot be determined from local information.
            layer->scrollableArea()->updateNeedsCompositedScrolling(PaintLayerScrollableArea::IgnoreLCDText);
            if (layer->needsCompositedScrolling())
                reasonsToComposite |= CompositingReasonOverflowScrollingTouch;
        }
    }

    if ((reasonsToComposite & CompositingReasonOverflowScrollingTouch) && !layer->isRootLayer())
        currentRecursionData.m_hasCompositedScrollingAncestor = true;

    // Next, accumulate reasons related to overlap.
    // If overlap testing is used, this reason will be overridden. If overlap testing is not
    // used, we must assume we overlap if there is anything composited behind us in paint-order.
    CompositingReasons overlapCompositingReason = currentRecursionData.m_subtreeIsCompositing ? CompositingReasonAssumedOverlap : CompositingReasonNone;

    if (currentRecursionData.m_hasCompositedScrollingAncestor) {
        Vector<size_t> unclippedDescendantsToRemove;
        for (size_t i = 0; i < unclippedDescendants.size(); i++) {
            PaintLayer* unclippedDescendant = unclippedDescendants.at(i);
            // If we've reached the containing block of one of the unclipped
            // descendants, that element is no longer relevant to whether or not we
            // should opt in. Unfortunately we can't easily remove from the list
            // while we're iterating, so we have to store it for later removal.
            if (unclippedDescendant->layoutObject()->containingBlock() == layer->layoutObject()) {
                unclippedDescendantsToRemove.append(i);
                continue;
            }
            if (layer->scrollsWithRespectTo(unclippedDescendant))
                reasonsToComposite |= CompositingReasonAssumedOverlap;
        }

        // Remove irrelevant unclipped descendants in reverse order so our stored
        // indices remain valid.
        for (size_t i = 0; i < unclippedDescendantsToRemove.size(); i++)
            unclippedDescendants.remove(unclippedDescendantsToRemove.at(unclippedDescendantsToRemove.size() - i - 1));

        if (reasonsToComposite & CompositingReasonOutOfFlowClipping)
            unclippedDescendants.append(layer);
    }

    const IntRect& absBounds = layer->clippedAbsoluteBoundingBox();
    absoluteDescendantBoundingBox = absBounds;

    if (currentRecursionData.m_testingOverlap && !requiresCompositingOrSquashing(directReasons))
        overlapCompositingReason = overlapMap.overlapsLayers(absBounds) ? CompositingReasonOverlap : CompositingReasonNone;

    reasonsToComposite |= overlapCompositingReason;

    // The children of this layer don't need to composite, unless there is
    // a compositing layer among them, so start by inheriting the compositing
    // ancestor with m_subtreeIsCompositing set to false.
    RecursionData childRecursionData = currentRecursionData;
    childRecursionData.m_subtreeIsCompositing = false;

    bool willBeCompositedOrSquashed = canBeComposited && requiresCompositingOrSquashing(reasonsToComposite);
    if (willBeCompositedOrSquashed) {
        // This layer now acts as the ancestor for kids.
        childRecursionData.m_compositingAncestor = layer;

        // Here we know that all children and the layer's own contents can blindly paint into
        // this layer's backing, until a descendant is composited. So, we don't need to check
        // for overlap with anything behind this layer.
        overlapMap.beginNewOverlapTestingContext();
        // This layer is going to be composited, so children can safely ignore the fact that there's an
        // animation running behind this layer, meaning they can rely on the overlap map testing again.
        childRecursionData.m_testingOverlap = true;
    }

#if ENABLE(ASSERT)
    LayerListMutationDetector mutationChecker(layer->stackingNode());
#endif

    bool anyDescendantHas3DTransform = false;
    bool willHaveForegroundLayer = false;

    if (layer->stackingNode()->isStackingContext()) {
        PaintLayerStackingNodeIterator iterator(*layer->stackingNode(), NegativeZOrderChildren);
        while (PaintLayerStackingNode* curNode = iterator.next()) {
            IntRect absoluteChildDescendantBoundingBox;
            updateRecursive(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants, absoluteChildDescendantBoundingBox);
            absoluteDescendantBoundingBox.unite(absoluteChildDescendantBoundingBox);

            // If we have to make a layer for this child, make one now so we can have a contents layer
            // (since we need to ensure that the -ve z-order child renders underneath our contents).
            if (childRecursionData.m_subtreeIsCompositing) {
                reasonsToComposite |= CompositingReasonNegativeZIndexChildren;

                if (!willBeCompositedOrSquashed) {
                    // make layer compositing
                    childRecursionData.m_compositingAncestor = layer;
                    overlapMap.beginNewOverlapTestingContext();
                    willBeCompositedOrSquashed = true;
                    willHaveForegroundLayer = true;

                    // FIXME: temporary solution for the first negative z-index composited child:
                    //        re-compute the absBounds for the child so that we can add the
                    //        negative z-index child's bounds to the new overlap context.
                    overlapMap.beginNewOverlapTestingContext();
                    overlapMap.add(curNode->layer(), curNode->layer()->clippedAbsoluteBoundingBox());
                    overlapMap.finishCurrentOverlapTestingContext();
                }
            }
        }
    }

    if (willHaveForegroundLayer) {
        ASSERT(willBeCompositedOrSquashed);
        // A foreground layer effectively is a new backing for all subsequent children, so
        // we don't need to test for overlap with anything behind this. So, we can finish
        // the previous context that was accumulating rects for the negative z-index
        // children, and start with a fresh new empty context.
        overlapMap.finishCurrentOverlapTestingContext();
        overlapMap.beginNewOverlapTestingContext();
        // This layer is going to be composited, so children can safely ignore the fact that there's an
        // animation running behind this layer, meaning they can rely on the overlap map testing again
        childRecursionData.m_testingOverlap = true;
    }

    PaintLayerStackingNodeIterator iterator(*layer->stackingNode(), NormalFlowChildren | PositiveZOrderChildren);
    while (PaintLayerStackingNode* curNode = iterator.next()) {
        IntRect absoluteChildDescendantBoundingBox;
        updateRecursive(layer, curNode->layer(), overlapMap, childRecursionData, anyDescendantHas3DTransform, unclippedDescendants, absoluteChildDescendantBoundingBox);
        absoluteDescendantBoundingBox.unite(absoluteChildDescendantBoundingBox);
    }

    // Now that the subtree has been traversed, we can check for compositing reasons that depended on the state of the subtree.

    if (layer->stackingNode()->isStackingContext()) {
        layer->setShouldIsolateCompositedDescendants(childRecursionData.m_hasUnisolatedCompositedBlendingDescendant);
    } else {
        layer->setShouldIsolateCompositedDescendants(false);
        currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = childRecursionData.m_hasUnisolatedCompositedBlendingDescendant;
    }

    // Subsequent layers in the parent's stacking context may also need to composite.
    if (childRecursionData.m_subtreeIsCompositing)
        currentRecursionData.m_subtreeIsCompositing = true;

    // Set the flag to say that this SC has compositing children.
    layer->setHasCompositingDescendant(childRecursionData.m_subtreeIsCompositing);

    if (layer->isRootLayer()) {
        // The root layer needs to be composited if anything else in the tree is composited.
        // Otherwise, we can disable compositing entirely.
        if (childRecursionData.m_subtreeIsCompositing || requiresCompositingOrSquashing(reasonsToComposite) || compositor->rootShouldAlwaysComposite()) {
            reasonsToComposite |= CompositingReasonRoot;
            currentRecursionData.m_subtreeIsCompositing = true;
        } else {
            compositor->setCompositingModeEnabled(false);
            reasonsToComposite = CompositingReasonNone;
        }
    } else {
        // All layers (even ones that aren't being composited) need to get added to
        // the overlap map. Layers that are not separately composited will paint into their
        // compositing ancestor's backing, and so are still considered for overlap.
        if (childRecursionData.m_compositingAncestor && !childRecursionData.m_compositingAncestor->isRootLayer())
            overlapMap.add(layer, absBounds);

        // Now check for reasons to become composited that depend on the state of descendant layers.
        CompositingReasons subtreeCompositingReasons = subtreeReasonsForCompositing(layer, childRecursionData.m_subtreeIsCompositing, anyDescendantHas3DTransform);
        reasonsToComposite |= subtreeCompositingReasons;
        if (!willBeCompositedOrSquashed && canBeComposited && requiresCompositingOrSquashing(subtreeCompositingReasons)) {
            childRecursionData.m_compositingAncestor = layer;
            // FIXME: this context push is effectively a no-op but needs to exist for
            // now, because the code is designed to push overlap information to the
            // second-from-top context of the stack.
            overlapMap.beginNewOverlapTestingContext();
            overlapMap.add(layer, absoluteDescendantBoundingBox);
            willBeCompositedOrSquashed = true;
        }

        if (willBeCompositedOrSquashed)
            reasonsToComposite |= layer->potentialCompositingReasonsFromStyle() & CompositingReasonInlineTransform;

        // If the original layer is composited, the reflection needs to be, too.
        if (layer->reflectionInfo()) {
            // FIXME: Shouldn't we call computeCompositingRequirements to handle a reflection overlapping with another layoutObject?
            PaintLayer* reflectionLayer = layer->reflectionInfo()->reflectionLayer();
            CompositingReasons reflectionCompositingReason = willBeCompositedOrSquashed ? CompositingReasonReflectionOfCompositedParent : CompositingReasonNone;
            reflectionLayer->setCompositingReasons(reflectionCompositingReason, CompositingReasonReflectionOfCompositedParent);
        }

        if (willBeCompositedOrSquashed && layer->layoutObject()->style()->hasBlendMode())
            currentRecursionData.m_hasUnisolatedCompositedBlendingDescendant = true;

        // Tell the parent it has compositing descendants.
        if (willBeCompositedOrSquashed)
            currentRecursionData.m_subtreeIsCompositing = true;

        // Turn overlap testing off for later layers if it's already off, or if we have an animating transform.
        // Note that if the layer clips its descendants, there's no reason to propagate the child animation to the parent layers. That's because
        // we know for sure the animation is contained inside the clipping rectangle, which is already added to the overlap map.
        bool isCompositedClippingLayer = canBeComposited && (reasonsToComposite & CompositingReasonClipsCompositingDescendants);
        bool isCompositedWithInlineTransform = reasonsToComposite & CompositingReasonInlineTransform;
        if ((!childRecursionData.m_testingOverlap && !isCompositedClippingLayer) || layer->layoutObject()->style()->hasCurrentTransformAnimation() || isCompositedWithInlineTransform)
            currentRecursionData.m_testingOverlap = false;

        if (childRecursionData.m_compositingAncestor == layer)
            overlapMap.finishCurrentOverlapTestingContext();

        descendantHas3DTransform |= anyDescendantHas3DTransform || layer->has3DTransform();
    }

    // At this point we have finished collecting all reasons to composite this layer.
    layer->setCompositingReasons(reasonsToComposite);
}
예제 #8
0
int main(int argc, char* argv[])
{
	bool   showHelp    = false;
	int    readLen     = 20;
	string REFile;
	string firstFile;
	string secondFile;

    // Show help when has no options
    if(argc <= 1)
    {   
        Help();
        return 0;
    }   

    // Parsing options 
    for(int i = 1; i < argc; i++)
    {   
        int parameterLength = (int)strlen(argv[i]);
        if((PARAMETER_CHECK("-h", 2, parameterLength)) || (PARAMETER_CHECK("--help", 5, parameterLength)))
            showHelp=true;
        else if ((PARAMETER_CHECK("-b", 2, parameterLength)) || (PARAMETER_CHECK("--bed", 5, parameterLength)))
		{
			if ((++i) < argc)
				REFile=argv[i];
		}
		else if ((PARAMETER_CHECK("-1", 2, parameterLength)) || (PARAMETER_CHECK("--first", 7, parameterLength)))
		{
			if ((++i) < argc)
				firstFile=argv[i];
		}
		else if ((PARAMETER_CHECK("-2", 2, parameterLength)) || (PARAMETER_CHECK("--second", 8, parameterLength)))
		{
			if ((++i) < argc)
				secondFile=argv[i];
		}
		else if ((PARAMETER_CHECK("-r", 2, parameterLength)) || (PARAMETER_CHECK("--readlen", 9, parameterLength)))
		{
			if ((++i) < argc)
				readLen=StringUtils::toValue<int>(argv[i]);
		}
		else
		{
			cerr << endl << "*****ERROR: Unrecognized parameter: " << argv[i] << " *****" << endl << endl;
			showHelp = true;
		}
	}

    // Show help if no proper auguments.
    if (showHelp)
    {
        Help();
        return 0;
    }

	// RE bed file
	BedMap REMap;
	LINE_ELEMS elems;
	ColumnReader REReader(REFile);

	// Read RE fragment ends into BedMap.
	REReader.open();
	while(REReader.getNext(elems)!=LINE_INVALID)
	{
		Bed tbed(elems);
		Bed tbed2(tbed.chrom, tbed.start,       tbed.start+readLen, tbed.name, tbed.score);
		Bed tbed3(tbed.chrom, tbed.end-readLen, tbed.end,           tbed.name, tbed.score);
		REMap[tbed.chrom][tbed2.getBIN()].push_back(tbed2);
		REMap[tbed.chrom][tbed3.getBIN()].push_back(tbed3);
	}
	REReader.close();

	// File handles
	ColumnReader firstHitsReader(firstFile);
	ColumnReader secondHitsReader(secondFile);

	// Open files
	firstHitsReader.open();
	secondHitsReader.open();

	// Find Pair from pair-end hits
	BedVec *vec1,*vec2;
	pBedVec REVecs1,REVecs2;
	OverlapMap overlaps; // <CHRPOS, pBedVec>
	map<string,float> contactMap;
	
	while(ids.size() || findPairs(firstHitsReader, secondHitsReader))
	{
		if (ids.size())
		{
			vec1=&(hitsmap[ids[0]][0]);
			vec2=&(hitsmap[ids[0]][1]);
			for(BedVec::iterator it=vec1->begin();it!=vec1->end();it++)
			{
				BedUtils::intersectBed(*it,REMap,overlaps);
				if(overlaps.size())
					REVecs1.push_back(&(*(overlaps.begin()->second[0])));
			}
			
			for(BedVec::iterator it=vec2->begin();it!=vec2->end();it++)
			{
				BedUtils::intersectBed(*it,REMap,overlaps);
				if(overlaps.size())
					REVecs2.push_back(&(*(overlaps.begin()->second[0])));
			}
			
			for(pBedVec::iterator it1=REVecs1.begin();it1!=REVecs1.end();it1++)
				for(pBedVec::iterator it2=REVecs2.begin();it2!=REVecs2.end();it2++)
				{
					contactMap[(*it1)->chrom+"\t"+(*it1)->name+"\t"+(*it2)->chrom+"\t"+(*it2)->name]+=((*it1)->score+(*it2)->score)/2;
				}
			REVecs1.clear();
			REVecs2.clear();
			ids.erase(ids.begin());
		}
	}
	
	// Close files
	firstHitsReader.close();
	secondHitsReader.close();

	// Print contact map
	for(map<string,float>::iterator it=contactMap.begin();it!=contactMap.end();it++)
			cout << it->first << "\t" << it->second << endl;

    return 0;
}