<commit_before>/*
 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
 *
 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
 *
 * Other contributors:
 *   Robert O'Callahan <roc+@cs.cmu.edu>
 *   David Baron <dbaron@fas.harvard.edu>
 *   Christian Biesinger <cbiesinger@web.de>
 *   Randall Jesup <rjesup@wgate.com>
 *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
 *   Josh Soref <timeless@mac.com>
 *   Boris Zbarsky <bzbarsky@mit.edu>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Alternatively, the contents of this file may be used under the terms
 * of either the Mozilla Public License Version 1.1, found at
 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
 * (the "GPL"), in which case the provisions of the MPL or the GPL are
 * applicable instead of those above.  If you wish to allow use of your
 * version of this file only under the terms of one of those two
 * licenses (the MPL or the GPL) and not to allow others to use your
 * version of this file under the LGPL, indicate your decision by
 * deletingthe provisions above and replace them with the notice and
 * other provisions required by the MPL or the GPL, as the case may be.
 * If you do not delete the provisions above, a recipient may use your
 * version of this file under any of the LGPL, the MPL or the GPL.
 */

#include "config.h"
#include "core/rendering/RenderLayerRepainter.h"

#include "core/rendering/FilterEffectRenderer.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/compositing/CompositedLayerMapping.h"

namespace WebCore {

RenderLayerRepainter::RenderLayerRepainter(RenderLayerModelObject* renderer)
    : m_renderer(renderer)
    , m_repaintStatus(NeedsNormalRepaint)
{
}

void RenderLayerRepainter::repaintAfterLayout(bool shouldCheckForRepaint)
{
    if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
        return;

    // FIXME: really, we're in the repaint phase here, and the following queries are legal.
    // Until those states are fully fledged, I'll just disable the ASSERTS.
    DisableCompositingQueryAsserts disabler;
    if (m_renderer->layer()->hasVisibleContent()) {
        RenderView* view = m_renderer->view();
        ASSERT(view);
        // FIXME: LayoutState does not work with RenderLayers as there is not a 1-to-1
        // mapping between them and the RenderObjects. It would be neat to enable
        // LayoutState outside the layout() phase and use it here.
        ASSERT(!view->layoutStateEnabled());

        RenderLayerModelObject* repaintContainer = m_renderer->containerForRepaint();
        LayoutRect oldRepaintRect = m_repaintRect;
        computeRepaintRects(repaintContainer);
        shouldCheckForRepaint &= shouldRepaintLayer();

        if (shouldCheckForRepaint) {
            if (view && !view->document().printing()) {
                if (m_repaintStatus & NeedsFullRepaint) {
                    m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldRepaintRect), InvalidationLayer);
                    if (m_repaintRect != oldRepaintRect)
                        m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_repaintRect), InvalidationLayer);
                } else {
                    m_renderer->repaintAfterLayoutIfNeeded(repaintContainer, m_renderer->selfNeedsLayout(), oldRepaintRect, &m_repaintRect);
                }
            }
        }
    } else {
        clearRepaintRects();
    }

    m_repaintStatus = NeedsNormalRepaint;

}

void RenderLayerRepainter::clearRepaintRects()
{
    ASSERT(!m_renderer->layer()->hasVisibleContent());

    m_repaintRect = IntRect();
}

void RenderLayerRepainter::computeRepaintRects(const RenderLayerModelObject* repaintContainer)
{
    if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
        return;

    m_repaintRect = m_renderer->clippedOverflowRectForRepaint(repaintContainer);
}

void RenderLayerRepainter::computeRepaintRectsIncludingDescendants()
{
    if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
        // FIXME: We want RenderLayerRepainter to go away when
        // repaint-after-layout is on by default so we need to figure out how to
        // handle this update.
        m_renderer->setPreviousRepaintRect(m_renderer->clippedOverflowRectForRepaint(m_renderer->containerForRepaint()));
    } else {
        // FIXME: computeRepaintRects() has to walk up the parent chain for every layer to compute the rects.
        // We should make this more efficient.
        // FIXME: it's wrong to call this when layout is not up-to-date, which we do.
        computeRepaintRects(m_renderer->containerForRepaint());
    }

    for (RenderLayer* layer = m_renderer->layer()->firstChild(); layer; layer = layer->nextSibling())
        layer->repainter().computeRepaintRectsIncludingDescendants();
}

inline bool RenderLayerRepainter::shouldRepaintLayer() const
{
    if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
        return false;

    if (m_repaintStatus != NeedsFullRepaintForPositionedMovementLayout)
        return true;

    // Composited layers that were moved during a positioned movement only
    // layout, don't need to be repainted. They just need to be recomposited.
    return m_renderer->compositingState() != PaintsIntoOwnBacking;
}

// Since we're only painting non-composited layers, we know that they all share the same repaintContainer.
void RenderLayerRepainter::repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer)
{
    m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_renderer->clippedOverflowRectForRepaint(repaintContainer)), InvalidationLayer);

    for (RenderLayer* curr = m_renderer->layer()->firstChild(); curr; curr = curr->nextSibling()) {
        if (!curr->hasCompositedLayerMapping())
            curr->repainter().repaintIncludingNonCompositingDescendants(repaintContainer);
    }
}

LayoutRect RenderLayerRepainter::repaintRectIncludingNonCompositingDescendants() const
{
    LayoutRect repaintRect;
    if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
        repaintRect = m_renderer->previousRepaintRect();
    else
        repaintRect = m_repaintRect;

    for (RenderLayer* child = m_renderer->layer()->firstChild(); child; child = child->nextSibling()) {
        // Don't include repaint rects for composited child layers; they will paint themselves and have a different origin.
        if (child->hasCompositedLayerMapping())
            continue;

        repaintRect.unite(child->repainter().repaintRectIncludingNonCompositingDescendants());
    }
    return repaintRect;
}

void RenderLayerRepainter::setBackingNeedsRepaint()
{
    ASSERT(m_renderer->compositingState() != NotComposited);

    if (m_renderer->compositingState() == PaintsIntoGroupedBacking) {
        // FIXME: should probably setNeedsDisplayInRect for this layer's bounds only.
        m_renderer->groupedMapping()->squashingLayer()->setNeedsDisplay();
    } else {
        m_renderer->compositedLayerMapping()->setContentsNeedDisplay();
    }
}

void RenderLayerRepainter::setBackingNeedsRepaintInRect(const LayoutRect& r)
{
    // https://bugs.webkit.org/show_bug.cgi?id=61159 describes an unreproducible crash here,
    // so assert but check that the layer is composited.
    ASSERT(m_renderer->compositingState() != NotComposited);
    if (m_renderer->compositingState() == NotComposited) {
        // If we're trying to repaint the placeholder document layer, propagate the
        // repaint to the native view system.
        LayoutRect absRect(r);
        LayoutPoint delta;
        m_renderer->layer()->convertToLayerCoords(m_renderer->layer()->root(), delta);
        absRect.moveBy(delta);

        RenderView* view = m_renderer->view();
        if (view)
            view->repaintViewRectangle(absRect);
        return;
    }
    IntRect repaintRect = pixelSnappedIntRect(r);
    if (m_renderer->compositingState() == PaintsIntoGroupedBacking) {
        // FIXME: Add a LayoutTest that hits this code path.
        // See https://code.google.com/p/chromium/issues/detail?id=365597 for real-world
        // examples that can execute this code.
        repaintRect.move(-m_renderer->layer()->offsetFromSquashingLayerOrigin());
        m_renderer->groupedMapping()->squashingLayer()->setNeedsDisplayInRect(repaintRect);
    } else {
        m_renderer->compositedLayerMapping()->setContentsNeedDisplayInRect(repaintRect);
    }
}

void RenderLayerRepainter::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect)
{
    if (rect.isEmpty())
        return;

    LayoutRect rectForRepaint = rect;
    m_renderer->style()->filterOutsets().expandRect(rectForRepaint);

    RenderLayerFilterInfo* filterInfo = m_renderer->layer()->filterInfo();
    ASSERT(filterInfo);
    filterInfo->expandDirtySourceRect(rectForRepaint);

    RenderLayer* parentLayer = enclosingFilterRepaintLayer();
    ASSERT(parentLayer);
    FloatQuad repaintQuad(rectForRepaint);
    LayoutRect parentLayerRect = m_renderer->localToContainerQuad(repaintQuad, parentLayer->renderer()).enclosingBoundingBox();

    if (parentLayer->hasCompositedLayerMapping()) {
        parentLayer->repainter().setBackingNeedsRepaintInRect(parentLayerRect);
        return;
    }

    if (parentLayer->paintsWithFilters()) {
        parentLayer->repainter().setFilterBackendNeedsRepaintingInRect(parentLayerRect);
        return;
    }

    if (parentLayer->isRootLayer()) {
        RenderView* view = toRenderView(parentLayer->renderer());
        view->repaintViewRectangle(parentLayerRect);
        return;
    }

    ASSERT_NOT_REACHED();
}

RenderLayer* RenderLayerRepainter::enclosingFilterRepaintLayer() const
{
    for (const RenderLayer* curr = m_renderer->layer(); curr; curr = curr->parent()) {
        if ((curr != m_renderer->layer() && curr->requiresFullLayerImageForFilters()) || curr->compositingState() == PaintsIntoOwnBacking || curr->isRootLayer())
            return const_cast<RenderLayer*>(curr);
    }
    return 0;
}

} // Namespace WebCore
<commit_msg>Don't bail in RenderLayerRepainter::computeRepaintRects with RAL<commit_after>/*
 * Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012 Apple Inc. All rights reserved.
 *
 * Portions are Copyright (C) 1998 Netscape Communications Corporation.
 *
 * Other contributors:
 *   Robert O'Callahan <roc+@cs.cmu.edu>
 *   David Baron <dbaron@fas.harvard.edu>
 *   Christian Biesinger <cbiesinger@web.de>
 *   Randall Jesup <rjesup@wgate.com>
 *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
 *   Josh Soref <timeless@mac.com>
 *   Boris Zbarsky <bzbarsky@mit.edu>
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
 *
 * Alternatively, the contents of this file may be used under the terms
 * of either the Mozilla Public License Version 1.1, found at
 * http://www.mozilla.org/MPL/ (the "MPL") or the GNU General Public
 * License Version 2.0, found at http://www.fsf.org/copyleft/gpl.html
 * (the "GPL"), in which case the provisions of the MPL or the GPL are
 * applicable instead of those above.  If you wish to allow use of your
 * version of this file only under the terms of one of those two
 * licenses (the MPL or the GPL) and not to allow others to use your
 * version of this file under the LGPL, indicate your decision by
 * deletingthe provisions above and replace them with the notice and
 * other provisions required by the MPL or the GPL, as the case may be.
 * If you do not delete the provisions above, a recipient may use your
 * version of this file under any of the LGPL, the MPL or the GPL.
 */

#include "config.h"
#include "core/rendering/RenderLayerRepainter.h"

#include "core/rendering/FilterEffectRenderer.h"
#include "core/rendering/RenderLayer.h"
#include "core/rendering/RenderView.h"
#include "core/rendering/compositing/CompositedLayerMapping.h"

namespace WebCore {

RenderLayerRepainter::RenderLayerRepainter(RenderLayerModelObject* renderer)
    : m_renderer(renderer)
    , m_repaintStatus(NeedsNormalRepaint)
{
}

void RenderLayerRepainter::repaintAfterLayout(bool shouldCheckForRepaint)
{
    if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
        return;

    // FIXME: really, we're in the repaint phase here, and the following queries are legal.
    // Until those states are fully fledged, I'll just disable the ASSERTS.
    DisableCompositingQueryAsserts disabler;
    if (m_renderer->layer()->hasVisibleContent()) {
        RenderView* view = m_renderer->view();
        ASSERT(view);
        // FIXME: LayoutState does not work with RenderLayers as there is not a 1-to-1
        // mapping between them and the RenderObjects. It would be neat to enable
        // LayoutState outside the layout() phase and use it here.
        ASSERT(!view->layoutStateEnabled());

        RenderLayerModelObject* repaintContainer = m_renderer->containerForRepaint();
        LayoutRect oldRepaintRect = m_repaintRect;
        computeRepaintRects(repaintContainer);
        shouldCheckForRepaint &= shouldRepaintLayer();

        if (shouldCheckForRepaint) {
            if (view && !view->document().printing()) {
                if (m_repaintStatus & NeedsFullRepaint) {
                    m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(oldRepaintRect), InvalidationLayer);
                    if (m_repaintRect != oldRepaintRect)
                        m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_repaintRect), InvalidationLayer);
                } else {
                    m_renderer->repaintAfterLayoutIfNeeded(repaintContainer, m_renderer->selfNeedsLayout(), oldRepaintRect, &m_repaintRect);
                }
            }
        }
    } else {
        clearRepaintRects();
    }

    m_repaintStatus = NeedsNormalRepaint;

}

void RenderLayerRepainter::clearRepaintRects()
{
    ASSERT(!m_renderer->layer()->hasVisibleContent());

    m_repaintRect = IntRect();
}

void RenderLayerRepainter::computeRepaintRects(const RenderLayerModelObject* repaintContainer)
{
    if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled()) {
        // FIXME: We want RenderLayerRepainter to go away when
        // repaint-after-layout is on by default so we need to figure out how to
        // handle this update.
        m_renderer->setPreviousRepaintRect(m_renderer->clippedOverflowRectForRepaint(m_renderer->containerForRepaint()));
    } else {
        m_repaintRect = m_renderer->clippedOverflowRectForRepaint(repaintContainer);
    }
}

void RenderLayerRepainter::computeRepaintRectsIncludingDescendants()
{
    // FIXME: computeRepaintRects() has to walk up the parent chain for every layer to compute the rects.
    // We should make this more efficient.
    // FIXME: it's wrong to call this when layout is not up-to-date, which we do.
    computeRepaintRects(m_renderer->containerForRepaint());

    for (RenderLayer* layer = m_renderer->layer()->firstChild(); layer; layer = layer->nextSibling())
        layer->repainter().computeRepaintRectsIncludingDescendants();
}

inline bool RenderLayerRepainter::shouldRepaintLayer() const
{
    if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
        return false;

    if (m_repaintStatus != NeedsFullRepaintForPositionedMovementLayout)
        return true;

    // Composited layers that were moved during a positioned movement only
    // layout, don't need to be repainted. They just need to be recomposited.
    return m_renderer->compositingState() != PaintsIntoOwnBacking;
}

// Since we're only painting non-composited layers, we know that they all share the same repaintContainer.
void RenderLayerRepainter::repaintIncludingNonCompositingDescendants(RenderLayerModelObject* repaintContainer)
{
    m_renderer->repaintUsingContainer(repaintContainer, pixelSnappedIntRect(m_renderer->clippedOverflowRectForRepaint(repaintContainer)), InvalidationLayer);

    for (RenderLayer* curr = m_renderer->layer()->firstChild(); curr; curr = curr->nextSibling()) {
        if (!curr->hasCompositedLayerMapping())
            curr->repainter().repaintIncludingNonCompositingDescendants(repaintContainer);
    }
}

LayoutRect RenderLayerRepainter::repaintRectIncludingNonCompositingDescendants() const
{
    LayoutRect repaintRect;
    if (RuntimeEnabledFeatures::repaintAfterLayoutEnabled())
        repaintRect = m_renderer->previousRepaintRect();
    else
        repaintRect = m_repaintRect;

    for (RenderLayer* child = m_renderer->layer()->firstChild(); child; child = child->nextSibling()) {
        // Don't include repaint rects for composited child layers; they will paint themselves and have a different origin.
        if (child->hasCompositedLayerMapping())
            continue;

        repaintRect.unite(child->repainter().repaintRectIncludingNonCompositingDescendants());
    }
    return repaintRect;
}

void RenderLayerRepainter::setBackingNeedsRepaint()
{
    ASSERT(m_renderer->compositingState() != NotComposited);

    if (m_renderer->compositingState() == PaintsIntoGroupedBacking) {
        // FIXME: should probably setNeedsDisplayInRect for this layer's bounds only.
        m_renderer->groupedMapping()->squashingLayer()->setNeedsDisplay();
    } else {
        m_renderer->compositedLayerMapping()->setContentsNeedDisplay();
    }
}

void RenderLayerRepainter::setBackingNeedsRepaintInRect(const LayoutRect& r)
{
    // https://bugs.webkit.org/show_bug.cgi?id=61159 describes an unreproducible crash here,
    // so assert but check that the layer is composited.
    ASSERT(m_renderer->compositingState() != NotComposited);
    if (m_renderer->compositingState() == NotComposited) {
        // If we're trying to repaint the placeholder document layer, propagate the
        // repaint to the native view system.
        LayoutRect absRect(r);
        LayoutPoint delta;
        m_renderer->layer()->convertToLayerCoords(m_renderer->layer()->root(), delta);
        absRect.moveBy(delta);

        RenderView* view = m_renderer->view();
        if (view)
            view->repaintViewRectangle(absRect);
        return;
    }
    IntRect repaintRect = pixelSnappedIntRect(r);
    if (m_renderer->compositingState() == PaintsIntoGroupedBacking) {
        // FIXME: Add a LayoutTest that hits this code path.
        // See https://code.google.com/p/chromium/issues/detail?id=365597 for real-world
        // examples that can execute this code.
        repaintRect.move(-m_renderer->layer()->offsetFromSquashingLayerOrigin());
        m_renderer->groupedMapping()->squashingLayer()->setNeedsDisplayInRect(repaintRect);
    } else {
        m_renderer->compositedLayerMapping()->setContentsNeedDisplayInRect(repaintRect);
    }
}

void RenderLayerRepainter::setFilterBackendNeedsRepaintingInRect(const LayoutRect& rect)
{
    if (rect.isEmpty())
        return;

    LayoutRect rectForRepaint = rect;
    m_renderer->style()->filterOutsets().expandRect(rectForRepaint);

    RenderLayerFilterInfo* filterInfo = m_renderer->layer()->filterInfo();
    ASSERT(filterInfo);
    filterInfo->expandDirtySourceRect(rectForRepaint);

    RenderLayer* parentLayer = enclosingFilterRepaintLayer();
    ASSERT(parentLayer);
    FloatQuad repaintQuad(rectForRepaint);
    LayoutRect parentLayerRect = m_renderer->localToContainerQuad(repaintQuad, parentLayer->renderer()).enclosingBoundingBox();

    if (parentLayer->hasCompositedLayerMapping()) {
        parentLayer->repainter().setBackingNeedsRepaintInRect(parentLayerRect);
        return;
    }

    if (parentLayer->paintsWithFilters()) {
        parentLayer->repainter().setFilterBackendNeedsRepaintingInRect(parentLayerRect);
        return;
    }

    if (parentLayer->isRootLayer()) {
        RenderView* view = toRenderView(parentLayer->renderer());
        view->repaintViewRectangle(parentLayerRect);
        return;
    }

    ASSERT_NOT_REACHED();
}

RenderLayer* RenderLayerRepainter::enclosingFilterRepaintLayer() const
{
    for (const RenderLayer* curr = m_renderer->layer(); curr; curr = curr->parent()) {
        if ((curr != m_renderer->layer() && curr->requiresFullLayerImageForFilters()) || curr->compositingState() == PaintsIntoOwnBacking || curr->isRootLayer())
            return const_cast<RenderLayer*>(curr);
    }
    return 0;
}

} // Namespace WebCore
<|endoftext|>


<commit_before>// Copyright (c) 1997-2019 The CSE Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.

///////////////////////////////////////////////////////////////////////////////
// DHWSolar.cpp -- Solar Hot Water model implementation
///////////////////////////////////////////////////////////////////////////////

#include "cnglob.h"

#include "cse.h"
#include "ancrec.h" 	// record: base class for rccn.h classes
#include "rccn.h"
#include "irats.h"
#include "cnguts.h"
#include "SLPAK.H"
#include "solarflatplatecollector.h"

RC DHWSOLARSYS::sw_CkF() {
	RC rc = RCOK;

	// tank surrounding zone or temp: zone illegal if temp given
	if (IsSet(DHWSOLARSYS_TANKTEX))
		rc |= disallowN("when 'swTankTEx' is specified", DHWSOLARSYS_TANKZNTI, 0);

	if (!rc)
	{
		if (!IsSet(DHWSOLARSYS_TANKUA))
		{
			float tsa = DHWTANK::TankSurfArea_CEC(sw_tankVol);
			if (sw_tankInsulR < 0.01f)
			{
				rc |= ooer(DHWSOLARSYS_TANKINSULR, "swTankInsulR must be >= 0.01 so valid wtUA can be calculated");
				sw_tankInsulR = 0.01;
			}
			sw_tankUA = tsa / sw_tankInsulR;
		}
	}
	return rc;
}

RC DHWSOLARSYS::sw_Init() {
	RC rc = RCOK;

	sw_pMtrElec = MtrB.GetAtSafe(sw_elecMtri);

	sw_tankT = 60.f;  // F initial guess
	sw_tankTInlet = sw_tankT;
	sw_tankTOutlet = sw_tankT;
	sw_tInlet = sw_tankT;
	sw_tOutlet = sw_tankT;

	sw_tickVol = 0.f;
	sw_tickVolT = 0.f;

	DHWSYS* pWS;
	DHWHEATER* pWH;
	RLUPC(WsR, pWS, pWS->ws_pDHWSOLARSYS)
	{
		if (pWS->ws_pDHWSOLARSYS->ss == ss)
		{
			sw_lastWS = pWS->ss;
			RLUPC(WhR, pWH, pWH->ownTi == pWS->ss)
			{
				sw_lastWH = pWH->ss;
			}
		}
	}

	return rc;
}

RC DHWSOLARSYS::sw_DoHour()
{
	RC rc = RCOK;

	DHWSOLARCOLLECTOR* pSC;
	RLUPC(ScR, pSC, pSC->ownTi == ss)
	{
		rc |= pSC->sc_DoHour();
	}
	return rc;
}

RC DHWSOLARSYS::sw_DoHourEnd()
{
	RC rc = RCOK;

	// Add parasitics to meter
	if (sw_pMtrElec)
	{
		sw_pMtrElec->H.mtr_Accum(sw_endUse, sw_parElec);
	}

	DHWSOLARCOLLECTOR* pSC;
	RLUPC(ScR, pSC, pSC->ownTi == ss)
	{
		rc |= pSC->sc_DoHourEnd();
	}
	return rc;
}

FLOAT DHWSOLARSYS::sw_GetAvailableTemp()
{
	return sw_tankTOutlet;
}

RC DHWSOLARSYS::sw_DoSubhrTick(
	double vol,  // Volume of draw, gal
	float tInlet,  // inlet temperature (after DWHR), F
	TI ws_ss,  // subscript of calling DHWSYS
	TI wh_ss,  // subscript of calling DHWHEATER
	float& tOutlet)  // calculated outlet temperature, F
{
	RC rc = RCOK;

	sw_tickVol += vol;
	sw_tickVolT += vol * tInlet;

	// if not the last DHWSYS and DHWHEATER calling, just aggregate
	if (ws_ss != sw_lastWS || wh_ss != sw_lastWH) {
		return rc;
	}

	// Calculate outlet temperature of all collectors
	// Using volume weighted average
	DHWSOLARCOLLECTOR* pSC;

	float sumVolT = 0.f;
	float sumVol = 0.f;
	RLUPC(ScR, pSC, pSC->ownTi == ss)
	{
		rc |= pSC->sc_DoSubhrTick();
		sumVolT += pSC->sc_tickVol*pSC->sc_tOutlet;
		sumVol += pSC->sc_tickVol;
	}

	if (sumVol > 0.f) {
		sw_tOutlet = sumVolT / sumVol;
		float heat_gain = sw_tankHXEff * sumVol*sw_fluidSpHtVol*(sw_tOutlet - sw_tankT); // Btu
		sw_tankT = sw_tankT + heat_gain / (sw_tankVol*waterRhoCp);
		sw_tInlet = sw_tOutlet - heat_gain / (sumVol*sw_fluidSpHtVol);
	}
	else
	{
		sw_tOutlet = sw_tankT;
		sw_tInlet = sw_tankT;
	}

	// Calculate tank changes
	if (sw_tickVolT > 0)
	{
		sw_tankTInlet = sw_tickVolT / sw_tickVol;
	}

	// First order tank approximation:
	if (sw_tickVol > sw_tankVol)
	{
		// Entire tank contents (plus some)
		sw_tankT = (sw_tankT * sw_tankVol + sw_tankTInlet * (sw_tickVol - sw_tankVol))/ sw_tickVol;
		sw_tankTOutlet = sw_tankT;
	}
	else
	{
		// skimming off the top
		sw_tankTOutlet = sw_tankT;
		// then mix for next tick
		sw_tankT = (sw_tankT * (sw_tankVol - sw_tickVol) + sw_tankTInlet * sw_tickVol)/ sw_tankVol;
	}

	tOutlet = sw_tankTOutlet;
	sw_tickVol = 0.f;
	sw_tickVolT = 0.f;

	return rc;
}

DHWSOLARCOLLECTOR::~DHWSOLARCOLLECTOR() {
	delete sc_collector;
	sc_collector = NULL;
}

RC DHWSOLARCOLLECTOR::sc_CkF() {
	RC rc = RCOK;
	if (!IsSet(DHWSOLARCOLLECTOR_PUMPFLOW))
	{
		sc_pumpFlow = 0.04*sc_area;  // initial rule of thumb: 0.04 gpm per ft2s
	}
	if (!IsSet(DHWSOLARCOLLECTOR_PUMPPWR))
	{
		sc_pumpPwr = 400.f*sc_pumpFlow;  // roughly 120 W / gpm -- don't know how good this assumption is
	}

	return rc;
}

RC DHWSOLARCOLLECTOR::sc_Init() {
	RC rc = RCOK;

	sc_collector = new SolarFlatPlateCollector(AIPtoSI(sc_area),
		                                         sc_tilt,
		                                         sc_azm,
		                                         sc_FRTA,
		                                         UIPtoSI(sc_FRUL));

	sc_tickOp = false;

	return rc;
}

RC DHWSOLARCOLLECTOR::sc_DoHour() {
	RC rc = RCOK;
	sc_pumpInElec = 0.f;
	return rc;
}

RC DHWSOLARCOLLECTOR::sc_DoHourEnd() {
	RC rc = RCOK;

	DHWSOLARSYS* pSWHSys = SwhR.GetAtSafe(ownTi);

	// Add pump energy to meter
	if (pSWHSys->sw_pMtrElec)
	{
		pSWHSys->sw_pMtrElec->H.mtr_Accum(pSWHSys->sw_endUse, sc_pumpInElec);
	}

	return rc;
}

RC DHWSOLARCOLLECTOR::sc_DoSubhrTick() {
	RC rc = RCOK;

	DHWSOLARSYS* pSWHSys = SwhR.GetAtSafe(ownTi);

	float tInlet = pSWHSys->sw_tInlet;

	float pump_energy = sc_pumpPwr * Top.tp_subhrTickDur / 60.f;  // Btu/h * min / 60 min/h
	float pump_vol = sc_pumpFlow * Top.tp_subhrTickDur;  // gal
	float pump_dt = pump_energy / (pump_vol * pSWHSys->sw_fluidSpHtVol);  // delta F

	// Calculate potential outlet temperature

	sc_tOutletP = sc_CalculateOutletTemp(pump_dt);

	// Collector status

	// Already running
	bool runningAboveShutOff = sc_tickOp && (sc_tOutletP > tInlet + sc_pumpOffDeltaT);
	bool offAboveTurnOn = !sc_tickOp && (sc_tOutletP > tInlet + sc_pumpOnDeltaT);

	if (runningAboveShutOff || offAboveTurnOn) {
		sc_tickVol = pump_vol;
		sc_pumpInElec += pump_energy;
		sc_tOutlet = sc_tOutletP;
		sc_tickOp = true;
	}
	else
	{
		sc_tickVol = 0.f;
		sc_pumpInElec = 0.f;
		sc_tOutlet = tInlet;
		sc_tickOp = false;
	}

	return rc;
}

FLOAT DHWSOLARCOLLECTOR::sc_CalculateOutletTemp(float pump_dt) {
	// Calculate incidence
	double plane_incidence {0.0f};
	slPerezSkyModel(sc_tilt, sc_azm, Top.iHrST, Top.radBeamHrAv, Top.radDiffHrAv, Top.grndRefl, plane_incidence);
	sc_poa = static_cast<FLOAT>(plane_incidence);

	// Collector inlet temperature (from tank heat exchanger)
	double tInlet = SwhR.GetAtSafe(ownTi)->sw_tInlet + pump_dt;

	// Mass flow rate
	static const double gpmTom3ps = 0.00006309;
	static const double m3tokg = 1000;
	double m_dot_SI = sc_pumpFlow * gpmTom3ps* m3tokg;

	// Calculate outlet temperature
	sc_collector->calculate(IrIPtoSI(plane_incidence), m_dot_SI, DegFtoK(Top.tDbOHrAv), DegFtoK(tInlet));
	return static_cast<FLOAT>(DegKtoF(sc_collector->outlet_temp()));
}<commit_msg>Hookup Solar Collector multiplier.<commit_after>// Copyright (c) 1997-2019 The CSE Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license
// that can be found in the LICENSE file.

///////////////////////////////////////////////////////////////////////////////
// DHWSolar.cpp -- Solar Hot Water model implementation
///////////////////////////////////////////////////////////////////////////////

#include "cnglob.h"

#include "cse.h"
#include "ancrec.h" 	// record: base class for rccn.h classes
#include "rccn.h"
#include "irats.h"
#include "cnguts.h"
#include "SLPAK.H"
#include "solarflatplatecollector.h"

RC DHWSOLARSYS::sw_CkF() {
	RC rc = RCOK;

	// tank surrounding zone or temp: zone illegal if temp given
	if (IsSet(DHWSOLARSYS_TANKTEX))
		rc |= disallowN("when 'swTankTEx' is specified", DHWSOLARSYS_TANKZNTI, 0);

	if (!rc)
	{
		if (!IsSet(DHWSOLARSYS_TANKUA))
		{
			float tsa = DHWTANK::TankSurfArea_CEC(sw_tankVol);
			if (sw_tankInsulR < 0.01f)
			{
				rc |= ooer(DHWSOLARSYS_TANKINSULR, "swTankInsulR must be >= 0.01 so valid wtUA can be calculated");
				sw_tankInsulR = 0.01;
			}
			sw_tankUA = tsa / sw_tankInsulR;
		}
	}
	return rc;
}

RC DHWSOLARSYS::sw_Init() {
	RC rc = RCOK;

	sw_pMtrElec = MtrB.GetAtSafe(sw_elecMtri);

	sw_tankT = 60.f;  // F initial guess
	sw_tankTInlet = sw_tankT;
	sw_tankTOutlet = sw_tankT;
	sw_tInlet = sw_tankT;
	sw_tOutlet = sw_tankT;

	sw_tickVol = 0.f;
	sw_tickVolT = 0.f;

	DHWSYS* pWS;
	DHWHEATER* pWH;
	RLUPC(WsR, pWS, pWS->ws_pDHWSOLARSYS)
	{
		if (pWS->ws_pDHWSOLARSYS->ss == ss)
		{
			sw_lastWS = pWS->ss;
			RLUPC(WhR, pWH, pWH->ownTi == pWS->ss)
			{
				sw_lastWH = pWH->ss;
			}
		}
	}

	return rc;
}

RC DHWSOLARSYS::sw_DoHour()
{
	RC rc = RCOK;

	DHWSOLARCOLLECTOR* pSC;
	RLUPC(ScR, pSC, pSC->ownTi == ss)
	{
		rc |= pSC->sc_DoHour();
	}
	return rc;
}

RC DHWSOLARSYS::sw_DoHourEnd()
{
	RC rc = RCOK;

	// Add parasitics to meter
	if (sw_pMtrElec)
	{
		sw_pMtrElec->H.mtr_Accum(sw_endUse, sw_parElec);
	}

	DHWSOLARCOLLECTOR* pSC;
	RLUPC(ScR, pSC, pSC->ownTi == ss)
	{
		rc |= pSC->sc_DoHourEnd();
	}
	return rc;
}

FLOAT DHWSOLARSYS::sw_GetAvailableTemp()
{
	return sw_tankTOutlet;
}

RC DHWSOLARSYS::sw_DoSubhrTick(
	double vol,  // Volume of draw, gal
	float tInlet,  // inlet temperature (after DWHR), F
	TI ws_ss,  // subscript of calling DHWSYS
	TI wh_ss,  // subscript of calling DHWHEATER
	float& tOutlet)  // calculated outlet temperature, F
{
	RC rc = RCOK;

	sw_tickVol += vol;
	sw_tickVolT += vol * tInlet;

	// if not the last DHWSYS and DHWHEATER calling, just aggregate
	if (ws_ss != sw_lastWS || wh_ss != sw_lastWH) {
		return rc;
	}

	// Calculate outlet temperature of all collectors
	// Using volume weighted average
	DHWSOLARCOLLECTOR* pSC;

	float sumVolT = 0.f;
	float sumVol = 0.f;
	RLUPC(ScR, pSC, pSC->ownTi == ss)
	{
		rc |= pSC->sc_DoSubhrTick();
		sumVolT += pSC->sc_tickVol*pSC->sc_tOutlet;
		sumVol += pSC->sc_tickVol;
	}

	if (sumVol > 0.f) {
		sw_tOutlet = sumVolT / sumVol;
		float heat_gain = sw_tankHXEff * sumVol*sw_fluidSpHtVol*(sw_tOutlet - sw_tankT); // Btu
		sw_tankT = sw_tankT + heat_gain / (sw_tankVol*waterRhoCp);
		sw_tInlet = sw_tOutlet - heat_gain / (sumVol*sw_fluidSpHtVol);
	}
	else
	{
		sw_tOutlet = sw_tankT;
		sw_tInlet = sw_tankT;
	}

	// Calculate tank changes
	if (sw_tickVolT > 0)
	{
		sw_tankTInlet = sw_tickVolT / sw_tickVol;
	}

	// First order tank approximation:
	if (sw_tickVol > sw_tankVol)
	{
		// Entire tank contents (plus some)
		sw_tankT = (sw_tankT * sw_tankVol + sw_tankTInlet * (sw_tickVol - sw_tankVol))/ sw_tickVol;
		sw_tankTOutlet = sw_tankT;
	}
	else
	{
		// skimming off the top
		sw_tankTOutlet = sw_tankT;
		// then mix for next tick
		sw_tankT = (sw_tankT * (sw_tankVol - sw_tickVol) + sw_tankTInlet * sw_tickVol)/ sw_tankVol;
	}

	tOutlet = sw_tankTOutlet;
	sw_tickVol = 0.f;
	sw_tickVolT = 0.f;

	return rc;
}

DHWSOLARCOLLECTOR::~DHWSOLARCOLLECTOR() {
	delete sc_collector;
	sc_collector = NULL;
}

RC DHWSOLARCOLLECTOR::sc_CkF() {
	RC rc = RCOK;
	if (!IsSet(DHWSOLARCOLLECTOR_PUMPFLOW))
	{
		sc_pumpFlow = 0.04*sc_area*sc_mult;  // initial rule of thumb: 0.04 gpm per ft2s
	}
	if (!IsSet(DHWSOLARCOLLECTOR_PUMPPWR))
	{
		sc_pumpPwr = 400.f*sc_pumpFlow;  // roughly 120 W / gpm -- don't know how good this assumption is
	}

	return rc;
}

RC DHWSOLARCOLLECTOR::sc_Init() {
	RC rc = RCOK;

	sc_collector = new SolarFlatPlateCollector(AIPtoSI(sc_area*sc_mult),
		                                         sc_tilt,
		                                         sc_azm,
		                                         sc_FRTA,
		                                         UIPtoSI(sc_FRUL));

	sc_tickOp = false;

	return rc;
}

RC DHWSOLARCOLLECTOR::sc_DoHour() {
	RC rc = RCOK;
	sc_pumpInElec = 0.f;
	return rc;
}

RC DHWSOLARCOLLECTOR::sc_DoHourEnd() {
	RC rc = RCOK;

	DHWSOLARSYS* pSWHSys = SwhR.GetAtSafe(ownTi);

	// Add pump energy to meter
	if (pSWHSys->sw_pMtrElec)
	{
		pSWHSys->sw_pMtrElec->H.mtr_Accum(pSWHSys->sw_endUse, sc_pumpInElec);
	}

	return rc;
}

RC DHWSOLARCOLLECTOR::sc_DoSubhrTick() {
	RC rc = RCOK;

	DHWSOLARSYS* pSWHSys = SwhR.GetAtSafe(ownTi);

	float tInlet = pSWHSys->sw_tInlet;

	float pump_energy = sc_pumpPwr * Top.tp_subhrTickDur / 60.f;  // Btu/h * min / 60 min/h
	float pump_vol = sc_pumpFlow * Top.tp_subhrTickDur;  // gal
	float pump_dt = pump_energy / (pump_vol * pSWHSys->sw_fluidSpHtVol);  // delta F

	// Calculate potential outlet temperature

	sc_tOutletP = sc_CalculateOutletTemp(pump_dt);

	// Collector status

	// Already running
	bool runningAboveShutOff = sc_tickOp && (sc_tOutletP > tInlet + sc_pumpOffDeltaT);
	bool offAboveTurnOn = !sc_tickOp && (sc_tOutletP > tInlet + sc_pumpOnDeltaT);

	if (runningAboveShutOff || offAboveTurnOn) {
		sc_tickVol = pump_vol;
		sc_pumpInElec += pump_energy;
		sc_tOutlet = sc_tOutletP;
		sc_tickOp = true;
	}
	else
	{
		sc_tickVol = 0.f;
		sc_pumpInElec = 0.f;
		sc_tOutlet = tInlet;
		sc_tickOp = false;
	}

	return rc;
}

FLOAT DHWSOLARCOLLECTOR::sc_CalculateOutletTemp(float pump_dt) {
	// Calculate incidence
	double plane_incidence {0.0f};
	slPerezSkyModel(sc_tilt, sc_azm, Top.iHrST, Top.radBeamHrAv, Top.radDiffHrAv, Top.grndRefl, plane_incidence);
	sc_poa = static_cast<FLOAT>(plane_incidence);

	// Collector inlet temperature (from tank heat exchanger)
	double tInlet = SwhR.GetAtSafe(ownTi)->sw_tInlet + pump_dt;

	// Mass flow rate
	static const double gpmTom3ps = 0.00006309;
	static const double m3tokg = 1000;
	double m_dot_SI = sc_pumpFlow * gpmTom3ps* m3tokg;

	// Calculate outlet temperature
	sc_collector->calculate(IrIPtoSI(plane_incidence), m_dot_SI, DegFtoK(Top.tDbOHrAv), DegFtoK(tInlet));
	return static_cast<FLOAT>(DegKtoF(sc_collector->outlet_temp()));
}<|endoftext|>


<commit_before>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <grpc/support/port_platform.h>

#ifdef GPR_CPU_POSIX

#include <errno.h>
#include <string.h>
#include <unistd.h>

#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>

static __thread char magic_thread_local;

static long ncpus = 0;

static void init_ncpus() {
  ncpus = sysconf(_SC_NPROCESSORS_ONLN);
  if (ncpus < 1 || ncpus > INT32_MAX) {
    gpr_log(GPR_ERROR, "Cannot determine number of CPUs: assuming 1");
    ncpus = 1;
  }
}

unsigned gpr_cpu_num_cores(void) {
  static gpr_once once = GPR_ONCE_INIT;
  gpr_once_init(&once, init_ncpus);
  return (unsigned)ncpus;
}

unsigned gpr_cpu_current_cpu(void) {
  /* NOTE: there's no way I know to return the actual cpu index portably...
     most code that's using this is using it to shard across work queues though,
     so here we use thread identity instead to achieve a similar though not
     identical effect */
  return (unsigned)GPR_HASH_POINTER(&magic_thread_local, gpr_cpu_num_cores());
}

#endif /* GPR_CPU_POSIX */
<commit_msg>Use pthreads on posix<commit_after>/*
 *
 * Copyright 2015 gRPC authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 */

#include <grpc/support/port_platform.h>

#if defined(GPR_CPU_POSIX)

#include <errno.h>
#include <pthread.h>
#include <string.h>
#include <unistd.h>

#include <atomic>

#include <grpc/support/cpu.h>
#include <grpc/support/log.h>
#include <grpc/support/sync.h>
#include <grpc/support/useful.h>

static long ncpus = 0;

static void init_ncpus() {
  ncpus = sysconf(_SC_NPROCESSORS_ONLN);
  if (ncpus < 1 || ncpus > INT32_MAX) {
    gpr_log(GPR_ERROR, "Cannot determine number of CPUs: assuming 1");
    ncpus = 1;
  }
}

unsigned gpr_cpu_num_cores(void) {
  static gpr_once once = GPR_ONCE_INIT;
  gpr_once_init(&once, init_ncpus);
  return (unsigned)ncpus;
}

unsigned gpr_cpu_current_cpu(void) {
  /* NOTE: there's no way I know to return the actual cpu index portably...
     most code that's using this is using it to shard across work queues though,
     so here we use thread identity instead to achieve a similar though not
     identical effect */
  static auto DeleteValue = [](void *value_ptr) {
    unsigned int *value = static_cast<unsigned int *>(value_ptr);
    if (value) {
      delete value;
    }
  };
  static pthread_key_t thread_id_key;
  static int thread_id_key_create_result __attribute__((unused)) =
      pthread_key_create(&thread_id_key, DeleteValue);
  // pthread_t isn't portably defined to map to an integral type. So keep track
  // of thread identity explicitly so hashing works reliably.
  static std::atomic<unsigned int> thread_counter(0);

  unsigned int *thread_id =
      static_cast<unsigned int *>(pthread_getspecific(thread_id_key));
  if (thread_id == nullptr) {
    thread_id = new unsigned int(thread_counter++);
    pthread_setspecific(thread_id_key, thread_id);
  }

  return (unsigned)GPR_HASH_POINTER(*thread_id, gpr_cpu_num_cores());
}

#endif /* GPR_CPU_POSIX */
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkImageMapperTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include "itkImage.h"
#include "itkImageMapper.h"
#include "itkGaussianImageSource.h"
#include "itkCommandIterationUpdate.h"
#include "itkVersorRigid3DTransform.h"

/**
 *  This program test one instantiation of the itk::ImageMapper class
 */

int main()
{

  // Image Type
  typedef itk::Image<float,2>                             ImageType;

  // Transform Type
  typedef itk::VersorRigid3DTransform< double >           TransformType;

  // Image Mapper Type
  typedef itk::ImageMapper<  ImageType, TransformType >   ImageMapperType;

  // Image Source Type
  typedef itk::GaussianImageSource< ImageType >           ImageSourceType;

  // Image Iterator Type
  typedef itk::ImageIterator< ImageType >               ImageIteratorType;

  // Image Region Type
  typedef ImageType::RegionType                               RegionType;

  ImageSourceType::Pointer    imageSource = ImageSourceType::New();

  ImageMapperType::Pointer    imageMapper = ImageMapperType::New();

  TransformType::Pointer      transform   = TransformType::New();

  float spacing[3];
  spacing[0] = 1.0f;
  spacing[1] = 1.0f;
  spacing[2] = 1.0f;

  float origin[3];
  origin[0] = 0.0f;
  origin[1] = 0.0f;
  origin[2] = 0.0f;

  unsigned long size[3];
  size[0] = 200;
  size[1] = 200;
  size[2] = 200;

  ImageSourceType::TArrayType sigma;
  sigma[0] = 50.0f;
  sigma[1] = 50.0f;
  sigma[2] = 50.0f;

  ImageSourceType::TArrayType mean;
  mean[0] = size[0] / 2.0;
  mean[1] = size[1] / 2.0;
  mean[2] = size[2] / 2.0;

  // Image parameters for the Gaussian source
  imageSource->SetSize( size );
  imageSource->SetOrigin( origin );
  imageSource->SetSpacing( spacing );

  // Gaussian parameters for the Gaussian source
  imageSource->SetSigma( sigma );
  imageSource->SetMean( mean );

  // Initialize the transform
  TransformType::OffsetType offset;
  offset[0] = 23;
  offset[1] = 37;
  offset[3] = 51;

  transform->SetOffset( offset );

  typedef TransformType::VersorType   VersorType;

  VersorType::VectorType axis;
  axis[0] = 1.0;
  axis[1] = 2.0;
  axis[2] = 3.0;

  VersorType::ValueType angle;
  angle = 30.0 * ( atan(1) / 45.0 );

  VersorType versor;

  versor.Set( axis, angle );

  transform->SetRotation( versor );

  // Connect the Image source to the Image mapper
  imageMapper->SetDomain( imageSource->GetOutput() );

  // Create the domain image
  imageSource->Update();

  bool pass = true;

  if( !pass )
    {
    std::cout << "Test failed." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;

}
<commit_msg>ENH: Test of a region added. The mapper is contrasted with a direct transform      and a closest point interpolator.<commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit (ITK)
  Module:    itkImageMapperTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/
#include "itkImage.h"
#include "itkImageMapper.h"
#include "itkGaussianImageSource.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkVersorRigid3DTransform.h"

/**
 *  This program test one instantiation of the itk::ImageMapper class
 */

int main()
{

  // Image Type
  typedef itk::Image<float,3>                             ImageType;

  // Transform Type
  typedef itk::VersorRigid3DTransform< double >           TransformType;

  // Image Mapper Type
  typedef itk::ImageMapper<  ImageType, TransformType >   ImageMapperType;

  // Image Source Type
  typedef itk::GaussianImageSource< ImageType >           ImageSourceType;

  // Image Iterator Type
  typedef itk::ImageRegionIteratorWithIndex< ImageType >  ImageIteratorType;

  // Image Region Type
  typedef ImageType::RegionType                           RegionType;

  // Image Index Type
  typedef RegionType::IndexType                           IndexType;

  // Image Size Type
  typedef RegionType::SizeType                            SizeType;

  //  Point Types
  typedef TransformType::InputPointType                   InputPointType;
  typedef TransformType::OutputPointType                  OutputPointType;

  //  Pixel Type
  typedef ImageType::PixelType                            PixelType;

  ImageSourceType::Pointer    imageSource = ImageSourceType::New();

  ImageMapperType::Pointer    imageMapper = ImageMapperType::New();

  TransformType::Pointer      transform   = TransformType::New();

  float spacing[3];
  spacing[0] = 1.0f;
  spacing[1] = 1.0f;
  spacing[2] = 1.0f;

  float origin[3];
  origin[0] = 0.0f;
  origin[1] = 0.0f;
  origin[2] = 0.0f;

  unsigned long size[3];
  size[0] = 100;
  size[1] = 100;
  size[2] = 100;

  ImageSourceType::TArrayType sigma;
  sigma[0] = 50.0f;
  sigma[1] = 50.0f;
  sigma[2] = 50.0f;

  ImageSourceType::TArrayType mean;
  mean[0] = size[0] / 2.0;
  mean[1] = size[1] / 2.0;
  mean[2] = size[2] / 2.0;

  // Image parameters for the Gaussian source
  imageSource->SetSize( size );
  imageSource->SetOrigin( origin );
  imageSource->SetSpacing( spacing );

  // Gaussian parameters for the Gaussian source
  imageSource->SetSigma( sigma );
  imageSource->SetMean( mean );

  // Initialize the transform
  TransformType::OffsetType offset;
  offset[0] = 23;
  offset[1] = 17;
  offset[2] = 19;

  transform->SetOffset( offset );

  typedef TransformType::VersorType   VersorType;

  VersorType::VectorType axis;
  axis[0] = 1.0;
  axis[1] = 2.0;
  axis[2] = 3.0;

  VersorType::ValueType angle;
  angle = 30 * ( atan(1) / 45.0 );

  VersorType versor;

  versor.Set( axis, angle );

  transform->SetRotation( versor );

  // Create the domain image
  imageSource->Update();

  // Connect the Image source to the Image mapper
  // NOTE: That must be done AFTER the image source has been
  // updated because the mapper take data from the image and
  // compute internal values with it.
  imageMapper->SetDomain( imageSource->GetOutput() );
  imageMapper->SetTransform( transform );

  ImageType::Pointer image = imageSource->GetOutput();

  bool pass = true;

  RegionType testRegion;
  SizeType testSize;
  testSize[0] = size[0] / 2;
  testSize[1] = size[1] / 2;
  testSize[2] = size[2] / 2;

  testRegion.SetSize( testSize );

  IndexType testOrigin;
  testOrigin[0] = size[0] / 4;
  testOrigin[1] = size[1] / 4;
  testOrigin[2] = size[2] / 4;

  testRegion.SetIndex( testOrigin );

  ImageIteratorType it( image, testRegion );

  it.GoToBegin();

  const float tolerance = 5.0;

  while( !it.IsAtEnd() )
    {
    const IndexType index = it.GetIndex();
    InputPointType point;
    point[0] = index[0];
    point[1] = index[1];
    point[2] = index[2];

    if( imageMapper->IsInside( point ) )
      {
      const PixelType mappedPixel  = imageMapper->Evaluate();
      const OutputPointType opoint = transform->TransformPoint( point );
      IndexType oindex;
      oindex[0] = static_cast< unsigned long >( opoint[0] );
      oindex[1] = static_cast< unsigned long >( opoint[1] );
      oindex[2] = static_cast< unsigned long >( opoint[2] );
      const PixelType transformedPixel = image->GetPixel( oindex );
      if( fabs( transformedPixel - mappedPixel ) > tolerance )
        {
        itkGenericOutputMacro( << "Mapped value != Transformed Value "
            << mappedPixel << " != " << transformedPixel << "  "
            << "Point = " << point << " mapped to " << opoint );
        pass = false;
        }
      }
    ++it;
    }

  if( !pass )
    {
    std::cout << "Test failed." << std::endl;
    return EXIT_FAILURE;
    }

  std::cout << "Test passed." << std::endl;
  return EXIT_SUCCESS;

}
<|endoftext|>


<commit_before>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkInterpolateTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/

#include <iostream>

#include "itkPhysicalImage.h"
#include "itkIndex.h"
#include "itkSize.h"

#include "itkLinearInterpolateImageFunction.h"

#include "vnl/vnl_math.h"

typedef itk::Size<3>                               SizeType;
typedef itk::PhysicalImage<unsigned short, 3>              ImageType;
typedef itk::LinearInterpolateImageFunction<ImageType>  InterpolatorType;
typedef InterpolatorType::IndexType                 IndexType;
typedef InterpolatorType::PointType                 PointType;

/* Define the image size and physical coordinates */
SizeType size = {{20, 40, 80}};
double origin [3] = { 0.5,   0.5,   0.5};
double spacing[3] = { 0.1,   0.05 , 0.025};

/**
 * This function convert points from Image space to
 * geometric space
 */
PointType ConvertImageToGeometricPoint( PointType& ipoint )
{
	PointType opoint;
  for( int j = 0; j < PointType::PointDimension; j++ )
		{
		opoint[j] = ipoint[j] * spacing[j] + origin[j];
		}

  return opoint;
}

/**
 * Test a geometric point. Returns true if test has passed,
 * returns false otherwise
 */
bool TestGeometricPoint(
InterpolatorType * interp,
PointType& point,
bool isInside,
double trueValue )
{

  std::cout << " Point: " << point;

  bool bvalue = interp->IsInsideBuffer( point );
  std::cout << " Inside: " << bvalue;

  if( bvalue != isInside )
		{
    std::cout << "*** Error: inside should be " << isInside << std::endl;
    return false;
    }

  if( isInside )
		{
		double value = interp->Evaluate( point );
    std::cout << " Value: " << value;

    if( vnl_math_abs( value - trueValue ) > 1e-9 )
			{
			std::cout << "*** Error: value should be " << trueValue << std::endl;
      return false;
			}
		}

  std::cout << std::endl;
  return true;

}

int
main(
    int argc,
    char *argv[])
{
    int flag = 0;           /* Did this test program work? */

    std::cout << "Testing image interpolation methods:\n";

    /* Allocate a simple test image */
    ImageType::Pointer image = ImageType::New();
    ImageType::RegionType region;
    region.SetSize(size);
    image->SetLargestPossibleRegion(region);
    image->SetBufferedRegion(region);
    image->Allocate();

    /* Set origin and spacing of physical coordinates */
    image->SetOrigin(origin);
    image->SetSpacing(spacing);

    /* Initialize the image contents */
    IndexType index;
    for (int slice = 0; slice < 80; slice++) {
        index[2] = slice;
        for (int row = 0; row < 40; row++) {
            index[1] = row;
            for (int col = 0; col < 20; col++) {
                index[0] = col;
                image->SetPixel(index, slice+row+col);
            }
        }
    }

    /* Create and initialize the interpolator */
    InterpolatorType::Pointer interp = InterpolatorType::New();
    interp->SetInputImage(image);

    //
    // FIXME: remove these when GetSpacing/GetOrigin has been
    // added to itk::Image
    interp->SetImageSpacing( image->GetSpacing() );
    interp->SetImageOrigin( image->GetOrigin() );

    /* Test evaluation at geometric points */
    std::cout << "Evaluate at geometric points: " << std::endl;
    PointType point;
    bool passed;

    // an integer position inside the image
    double darray1[3] = { 10, 20, 40};
    point = ConvertImageToGeometricPoint( PointType(darray1) );
    passed = TestGeometricPoint( interp, point, true, 70 );

    if( !passed ) flag = 1;

    // position at the image border
    double darray2[3] = {0, 20, 40};
    point = ConvertImageToGeometricPoint( PointType(darray2) );
    passed = TestGeometricPoint( interp, point, true, 60 );

    if( !passed ) flag = 1;

    // position near image border
    double darray3[3] = {19, 20, 40};
    point = ConvertImageToGeometricPoint( PointType(darray3) );
    passed = TestGeometricPoint( interp, point, true, 79 );

    if( !passed ) flag = 1;

    // position outside the image
    double darray4[3] = {20, 20, 40};
    point = ConvertImageToGeometricPoint( PointType(darray4) );
    passed = TestGeometricPoint( interp, point, false, 0 );

    if( !passed ) flag = 1;

    // at non-integer position
    double darray5[3] = {5.25, 12.5, 42.0};
    point = ConvertImageToGeometricPoint( PointType(darray5) );
    passed = TestGeometricPoint( interp, point, true, 59.75 );

    if( !passed ) flag = 1;

    //
    // FIXME: added test for image point
    // after it has been implemented
    ///

    /* Return results of test */
    if (flag != 0) {
        std::cout << "*** Some test failed" << std::endl;
        return flag; }
    else {
        std::cout << "All tests successfully passed" << std::endl;
        return 0; }

}

<commit_msg><commit_after>/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkInterpolateTest.cxx
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

Copyright (c) 2001 Insight Consortium
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

 * Redistributions of source code must retain the above copyright notice,
   this list of conditions and the following disclaimer.

 * Redistributions in binary form must reproduce the above copyright notice,
   this list of conditions and the following disclaimer in the documentation
   and/or other materials provided with the distribution.

 * The name of the Insight Consortium, nor the names of any consortium members,
   nor of any contributors, may be used to endorse or promote products derived
   from this software without specific prior written permission.

  * Modified source versions must be plainly marked as such, and must not be
    misrepresented as being the original software.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER AND CONTRIBUTORS ``AS IS''
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

=========================================================================*/

#include <iostream>

#include "itkPhysicalImage.h"
#include "itkIndex.h"
#include "itkSize.h"

#include "itkLinearInterpolateImageFunction.h"

#include "vnl/vnl_math.h"

typedef itk::Size<3>                               SizeType;
typedef itk::PhysicalImage<unsigned short, 3>              ImageType;
typedef itk::LinearInterpolateImageFunction<ImageType>  InterpolatorType;
typedef InterpolatorType::IndexType                 IndexType;
typedef InterpolatorType::PointType                 PointType;

/* Define the image size and physical coordinates */
SizeType size = {{20, 40, 80}};
double origin [3] = { 0.5,   0.5,   0.5};
double spacing[3] = { 0.1,   0.05 , 0.025};

/**
 * This function convert points from Image space to
 * geometric space
 */
PointType ConvertImageToGeometricPoint( const PointType& ipoint )
{
	PointType opoint;
  for( int j = 0; j < PointType::PointDimension; j++ )
		{
		opoint[j] = ipoint[j] * spacing[j] + origin[j];
		}

  return opoint;
}

/**
 * Test a geometric point. Returns true if test has passed,
 * returns false otherwise
 */
bool TestGeometricPoint(
const InterpolatorType * interp,
const PointType& point,
bool isInside,
double trueValue )
{

  std::cout << " Point: " << point;

  bool bvalue = interp->IsInsideBuffer( point );
  std::cout << " Inside: " << bvalue;

  if( bvalue != isInside )
		{
    std::cout << "*** Error: inside should be " << isInside << std::endl;
    return false;
    }

  if( isInside )
		{
		double value = interp->Evaluate( point );
    std::cout << " Value: " << value;

    if( vnl_math_abs( value - trueValue ) > 1e-9 )
			{
			std::cout << "*** Error: value should be " << trueValue << std::endl;
      return false;
			}
		}

  std::cout << std::endl;
  return true;

}

int
main(
    int argc,
    char *argv[])
{
    int flag = 0;           /* Did this test program work? */

    std::cout << "Testing image interpolation methods:\n";

    /* Allocate a simple test image */
    ImageType::Pointer image = ImageType::New();
    ImageType::RegionType region;
    region.SetSize(size);
    image->SetLargestPossibleRegion(region);
    image->SetBufferedRegion(region);
    image->Allocate();

    /* Set origin and spacing of physical coordinates */
    image->SetOrigin(origin);
    image->SetSpacing(spacing);

    /* Initialize the image contents */
    IndexType index;
    for (int slice = 0; slice < 80; slice++) {
        index[2] = slice;
        for (int row = 0; row < 40; row++) {
            index[1] = row;
            for (int col = 0; col < 20; col++) {
                index[0] = col;
                image->SetPixel(index, slice+row+col);
            }
        }
    }

    /* Create and initialize the interpolator */
    InterpolatorType::Pointer interp = InterpolatorType::New();
    interp->SetInputImage(image);

    //
    // FIXME: remove these when GetSpacing/GetOrigin has been
    // added to itk::Image
    interp->SetImageSpacing( image->GetSpacing() );
    interp->SetImageOrigin( image->GetOrigin() );

    /* Test evaluation at geometric points */
    std::cout << "Evaluate at geometric points: " << std::endl;
    PointType point, ipoint;
    bool passed;

    // an integer position inside the image
    double darray1[3] = { 10, 20, 40};
    ipoint = PointType(darray1);
    point = ConvertImageToGeometricPoint( ipoint );
    passed = TestGeometricPoint( interp, point, true, 70 );

    if( !passed ) flag = 1;

    // position at the image border
    double darray2[3] = {0, 20, 40};
    ipoint = PointType(darray2);
    point = ConvertImageToGeometricPoint( ipoint );
    passed = TestGeometricPoint( interp, point, true, 60 );

    if( !passed ) flag = 1;

    // position near image border
    double darray3[3] = {19, 20, 40};
    ipoint = PointType(darray3);
    point = ConvertImageToGeometricPoint( ipoint );
    passed = TestGeometricPoint( interp, point, true, 79 );

    if( !passed ) flag = 1;

    // position outside the image
    double darray4[3] = {20, 20, 40};
    ipoint = PointType(darray4);
    point = ConvertImageToGeometricPoint( ipoint );
    passed = TestGeometricPoint( interp, point, false, 0 );

    if( !passed ) flag = 1;

    // at non-integer position
    double darray5[3] = {5.25, 12.5, 42.0};
    ipoint = PointType(darray5);
    point = ConvertImageToGeometricPoint( ipoint );
    passed = TestGeometricPoint( interp, point, true, 59.75 );

    if( !passed ) flag = 1;

    //
    // FIXME: added test for image point
    // after it has been implemented
    ///

    /* Return results of test */
    if (flag != 0) {
        std::cout << "*** Some test failed" << std::endl;
        return flag; }
    else {
        std::cout << "All tests successfully passed" << std::endl;
        return 0; }

}

<|endoftext|>


<commit_before>#include "doofit/plotting/Plot/Plot.h"

// STL
#include <string>
#include <sstream>
#include <vector>

// boost
#include <boost/regex.hpp>

// ROOT
#include "TIterator.h"
#include "TString.h"
#include "TAxis.h"

// from RooFit
#include "RooArgList.h"
#include "RooAbsRealLValue.h"
#include "RooAbsData.h"
#include "RooAbsPdf.h"
#include "RooPlot.h"
#include "RooHist.h"
#include "RooBinning.h"

// from Project
#include "doocore/io/MsgStream.h"
#include "doocore/lutils/lutils.h"
#include "doofit/plotting/Plot/PlotConfig.h"

using namespace ROOT;
using namespace RooFit;
using namespace doocore::io;

namespace doofit {
namespace plotting {

Plot::Plot(const PlotConfig& cfg_plot, const RooAbsRealLValue& dimension, const RooAbsData& dataset, const RooArgList& pdfs, const std::string& plot_name)
: config_plot_(cfg_plot),
  dimension_(dimension),
  datasets_(),
  plot_name_(plot_name)
{
  datasets_.push_back(&dataset);
  pdf_ = dynamic_cast<RooAbsPdf*>(pdfs.first());

  if (&dimension_ == NULL) {
    serr << "Plot::Plot(): Dimension is invalid." << endmsg;
    throw 1;
  }
  if (datasets_.front() == NULL) {
    serr << "Plot::Plot(): Dataset is invalid." << endmsg;
    throw 1;
  }
  if (plot_name_ == "") {
    plot_name_ = dimension_.GetName();
  }

  for (int i=1; i<pdfs.getSize(); ++i) {
    RooAbsArg* sub_arg = pdfs.at(i);
    const RooAbsPdf* sub_pdf = dynamic_cast<RooAbsPdf*>(sub_arg);

    if (sub_pdf != NULL) {
      components_.push_back(RooArgSet(*sub_pdf));
    }
  }
}

Plot::Plot(const PlotConfig& cfg_plot, const RooAbsRealLValue& dimension, const RooAbsData& dataset, const RooAbsPdf& pdf, const std::vector<std::string>& components, const std::string& plot_name)
: config_plot_(cfg_plot),
  dimension_(dimension),
  datasets_(),
  plot_name_(plot_name)
{
  datasets_.push_back(&dataset);
  pdf_ = &pdf;

  if (pdf_ == NULL) {
    serr << "Plot::Plot(): Main PDF is invalid." << endmsg;
    throw 1;
  }
  if (&dimension_ == NULL) {
    serr << "Plot::Plot(): Dimension is invalid." << endmsg;
    throw 1;
  }
  if (datasets_.front() == NULL) {
    serr << "Plot::Plot(): Dataset is invalid." << endmsg;
    throw 1;
  }
  if (plot_name_ == "") {
    plot_name_ = dimension_.GetName();
  }

  // iterate over sub PDFs and match supplied regular expressions
  RooArgSet nodes;
  pdf.branchNodeServerList(&nodes);

  for (std::vector<std::string>::const_iterator it = components.begin();
       it != components.end(); ++it) {
    boost::regex r(*it);
    components_.push_back(RooArgSet());

    TIterator* it_nodes = nodes.createIterator();
    RooAbsArg* node = NULL;

    while ((node = dynamic_cast<RooAbsArg*>(it_nodes->Next()))) {
      RooAbsPdf* pdf_node = dynamic_cast<RooAbsPdf*>(node);
      if (pdf_node != NULL) {
        std::string pdf_name = pdf_node->GetName();

        // exclude resolution models generated by RooFit and match the rest
        if (pdf_name.find("_conv_") == -1 && regex_match(pdf_name,r)) {
          components_.back().add(*pdf_node);
        }
      }
    }
    delete it_nodes;
  }
}

void Plot::PlotHandler(ScaleType sc_y, std::string suffix) const {
  if (suffix == "") suffix = "_log";

  std::string plot_name = plot_name_;

  std::stringstream log_plot_name_sstr;
  log_plot_name_sstr << plot_name << suffix;
  std::string log_plot_name = log_plot_name_sstr.str();

  std::stringstream pull_plot_sstr;
  pull_plot_sstr << plot_name << "_pull";
  std::string pull_plot_name = pull_plot_sstr.str();

  std::stringstream log_pull_plot_sstr;
  log_pull_plot_sstr << plot_name << "_pull" << suffix;
  std::string log_pull_plot_name = log_pull_plot_sstr.str();

  sinfo << "Plotting " << dimension_.GetName() << " into directory " << config_plot_.plot_directory() << " as " << plot_name << endmsg;

  doocore::lutils::setStyle("LHCb");

  RooCmdArg range_arg;

  // x range
  if (!dimension_.hasMin() && !dimension_.hasMax()) {
    double min, max;

    // ugly const_cast because RooFit is stupid (RooDataSet::getRange needs non-const RooRealVar)
    RooRealVar* dimension_non_const = const_cast<RooRealVar*>(dynamic_cast<const RooRealVar*>(&dimension_));
    datasets_.front()->getRange(*dimension_non_const, min, max);

    double min_t, max_t;
    for (std::vector<const RooAbsData*>::const_iterator it = datasets_.begin()+1;
         it != datasets_.end(); ++it) {
      (*it)->getRange(*dimension_non_const, min_t, max_t);
      if (min_t < min) min = min_t;
      if (max_t > max) max = max_t;
    }

    range_arg = Range(min, max);
  }

  RooCmdArg cut_range_arg, projection_range_arg, frame_range_arg;
  RooBinning* binning = NULL;
  RooAbsData* dataset_reduced = NULL;
  if (plot_range_.length() > 0) {
    sinfo << "doofit::plotting: Plotting on named range " << plot_range_ << endmsg;
    cut_range_arg = CutRange(plot_range_.c_str());
    projection_range_arg = ProjectionRange(plot_range_.c_str());
    range_arg = Range(plot_range_.c_str());
    binning = new RooBinning(dimension_.getBinning().numBins(), dimension_.getMin(plot_range_.c_str()), dimension_.getMax(plot_range_.c_str()));

    // ugly const cast as RooFit (once again) gives a shit about const correctness
    RooAbsData* dataset = const_cast<RooAbsData*>(datasets_.front());
    //dataset_reduced = dataset->reduce(cut_range_arg);
    dataset_reduced = dataset->reduce(CutRange(plot_range_.c_str()));

//    serr << "obsMass has range cbkg_sideband: " << dataset->get()->find("obsMass")->hasRange("cbkg_sideband") << endmsg;

    sinfo << "Created reduced dataset with " << dataset_reduced->numEntries() << " (original dataset has " << dataset->numEntries() << ")" << endmsg;
    dataset_reduced->Print();
  }

  RooPlot* plot_frame = dimension_.frame(range_arg);

  if (dataset_reduced != NULL) {
    if (binning != NULL) {
      dataset_reduced->plotOn(plot_frame, Binning(*binning), cut_range_arg/*, Rescale(1.0/(*it)->sumEntries())*/);
    } else {
      dataset_reduced->plotOn(plot_frame, Binning(dimension_.getBinning()), cut_range_arg/*, Rescale(1.0/(*it)->sumEntries())*/);
    }
  } else {
    for (std::vector<const RooAbsData*>::const_iterator it = datasets_.begin();
         it != datasets_.end(); ++it) {
      if (binning != NULL) {
        (*it)->plotOn(plot_frame, Binning(*binning), cut_range_arg/*, Rescale(1.0/(*it)->sumEntries())*/);
      } else {
        (*it)->plotOn(plot_frame, Binning(dimension_.getBinning()), cut_range_arg/*, Rescale(1.0/(*it)->sumEntries())*/);
      }
    }
  }

  // y range adaptively for log scale
  RooHist * data = (RooHist*) plot_frame->findObject(0,RooHist::Class());
  double x,y;
  data->GetPoint(0,x,y);
  double min_data_entry = y;
  for (unsigned int i = 1; i < data->GetN(); ++i) {
    data->GetPoint(i,x,y);
    if (min_data_entry > y) min_data_entry = y;
  }
  if (min_data_entry == 0.0) min_data_entry = 1.0;
  if (min_data_entry < 0.0) min_data_entry = 0.01;
//  sdebug << "minimum data entry in dataset: " << min_data_entry << endmsg;
  double min_plot = TMath::Power(10.0,TMath::Log10(min_data_entry)-0.9);

//  sdebug << "minimum entry in histogram: " << min_data_entry << endmsg;
//  sdebug << "minimum for plot range: " << min_plot << endmsg;

  TLatex label(0.65,0.85,"LHCb");

  config_plot_.OnDemandOpenPlotStack();
  if (pdf_ != NULL) {
    RooPlot* plot_frame_pull = dimension_.frame(range_arg);

    // I feel so stupid doing this but apparently RooFit leaves me no other way...
    RooCmdArg arg1, arg2, arg3, arg4, arg5, arg6, arg7;
    if (plot_args_.size() > 0) arg1 = plot_args_[0];
    if (plot_args_.size() > 1) arg2 = plot_args_[1];
    if (plot_args_.size() > 2) arg3 = plot_args_[2];
    if (plot_args_.size() > 3) arg4 = plot_args_[3];
    if (plot_args_.size() > 4) arg5 = plot_args_[4];
//    if (plot_args_.size() > 5) arg6 = plot_args_[5];
//    if (plot_args_.size() > 6) arg7 = plot_args_[6];

    if (dataset_reduced != NULL) {
      serr << "Reduced dataset available. Plotting this." << endmsg;
      if (binning != NULL) {
        dataset_reduced->plotOn(plot_frame_pull, Binning(*binning), cut_range_arg);
      } else {
        dataset_reduced->plotOn(plot_frame_pull, Binning(dimension_.getBinning()), cut_range_arg);
      }
    } else {
      for (std::vector<const RooAbsData*>::const_iterator it = datasets_.begin();
           it != datasets_.end(); ++it) {
        if (binning != NULL) {
          (*it)->plotOn(plot_frame_pull, Binning(*binning), cut_range_arg);
        } else {
          (*it)->plotOn(plot_frame_pull, Binning(dimension_.getBinning()), cut_range_arg);
        }
      }
    }

    int i=1;
    for (std::vector<RooArgSet>::const_iterator it = components_.begin();
         it != components_.end(); ++it) {
      if (it->getSize() > 0) {
        sinfo << "Plotting component " << it->first()->GetName() << endmsg;
        pdf_->plotOn(plot_frame, Components(*it), LineColor(config_plot_.GetPdfLineColor(i)), LineStyle(config_plot_.GetPdfLineStyle(i)), projection_range_arg, NumCPU(8), arg1, arg2, arg3, arg4, arg5);
        pdf_->plotOn(plot_frame_pull, Components(*it), LineColor(config_plot_.GetPdfLineColor(i)), LineStyle(config_plot_.GetPdfLineStyle(i)), projection_range_arg, NumCPU(8), arg1, arg2, arg3, arg4, arg5);
        ++i;
      }
    }

    pdf_->plotOn(plot_frame, LineColor(config_plot_.GetPdfLineColor(0)), LineStyle(config_plot_.GetPdfLineStyle(0)), projection_range_arg, NumCPU(8), arg1, arg2, arg3, arg4, arg5);
    pdf_->plotOn(plot_frame_pull, LineColor(config_plot_.GetPdfLineColor(0)), LineStyle(config_plot_.GetPdfLineStyle(0)), projection_range_arg, NumCPU(8), arg1, arg2, arg3, arg4, arg5);

    // =10^(ln(11)/ln(10)-0.5)
    //plot_frame_pull->SetMinimum(0.5);

    plot_frame_pull->SetMinimum(0.5);
    plot_frame_pull->SetMaximum(1.3*plot_frame_pull->GetMaximum());

    TString ylabel = plot_frame_pull->GetYaxis()->GetTitle();
    ylabel.ReplaceAll("Events","Candidates");
    plot_frame_pull->GetYaxis()->SetTitle(ylabel);

    if (sc_y == kLinear || sc_y == kBoth) {
      doocore::lutils::PlotPulls(pull_plot_name, plot_frame_pull, label, config_plot_.plot_directory(), false, false, true);
      doocore::lutils::PlotPulls("AllPlots", plot_frame_pull, label, config_plot_.plot_directory(), false, false, true, "");
    }

//    sdebug << "Plot y axis minimum for log scale plot: " << min_plot << endmsg;
    plot_frame_pull->SetMinimum(min_plot);
    if (sc_y == kLogarithmic || sc_y == kBoth) {
      doocore::lutils::PlotPulls(log_pull_plot_name, plot_frame_pull, label, config_plot_.plot_directory(), true, false, true);
      doocore::lutils::PlotPulls("AllPlots", plot_frame_pull, label, config_plot_.plot_directory(), true, false, true, "");
    }

    delete plot_frame_pull;
  }

  plot_frame->SetMinimum(0.0);
  plot_frame->SetMaximum(1.3*plot_frame->GetMaximum());

  TString ylabel = plot_frame->GetYaxis()->GetTitle();
  ylabel.ReplaceAll("Events","Candidates");
  plot_frame->GetYaxis()->SetTitle(ylabel);

  if (sc_y == kLinear || sc_y == kBoth) {
    doocore::lutils::PlotSimple(plot_name, plot_frame, label, config_plot_.plot_directory(), false);
    doocore::lutils::PlotSimple("AllPlots", plot_frame, label, config_plot_.plot_directory(), false);
  }

  plot_frame->SetMinimum(min_plot);
  if (sc_y == kLogarithmic || sc_y == kBoth) {
    doocore::lutils::PlotSimple(log_plot_name, plot_frame, label, config_plot_.plot_directory(), true);
    doocore::lutils::PlotSimple("AllPlots", plot_frame, label, config_plot_.plot_directory(), true);
  }

  if (dataset_reduced != NULL) delete dataset_reduced;
  if (binning != NULL) delete binning;
  delete plot_frame;
}

Plot::~Plot() {}

} // namespace plotting
} // namespace doofit
<commit_msg>Plotting: reverting multi CPU plotting as it is broken<commit_after>#include "doofit/plotting/Plot/Plot.h"

// STL
#include <string>
#include <sstream>
#include <vector>

// boost
#include <boost/regex.hpp>

// ROOT
#include "TIterator.h"
#include "TString.h"
#include "TAxis.h"

// from RooFit
#include "RooArgList.h"
#include "RooAbsRealLValue.h"
#include "RooAbsData.h"
#include "RooAbsPdf.h"
#include "RooPlot.h"
#include "RooHist.h"
#include "RooBinning.h"

// from Project
#include "doocore/io/MsgStream.h"
#include "doocore/lutils/lutils.h"
#include "doofit/plotting/Plot/PlotConfig.h"

using namespace ROOT;
using namespace RooFit;
using namespace doocore::io;

namespace doofit {
namespace plotting {

Plot::Plot(const PlotConfig& cfg_plot, const RooAbsRealLValue& dimension, const RooAbsData& dataset, const RooArgList& pdfs, const std::string& plot_name)
: config_plot_(cfg_plot),
  dimension_(dimension),
  datasets_(),
  plot_name_(plot_name)
{
  datasets_.push_back(&dataset);
  pdf_ = dynamic_cast<RooAbsPdf*>(pdfs.first());

  if (&dimension_ == NULL) {
    serr << "Plot::Plot(): Dimension is invalid." << endmsg;
    throw 1;
  }
  if (datasets_.front() == NULL) {
    serr << "Plot::Plot(): Dataset is invalid." << endmsg;
    throw 1;
  }
  if (plot_name_ == "") {
    plot_name_ = dimension_.GetName();
  }

  for (int i=1; i<pdfs.getSize(); ++i) {
    RooAbsArg* sub_arg = pdfs.at(i);
    const RooAbsPdf* sub_pdf = dynamic_cast<RooAbsPdf*>(sub_arg);

    if (sub_pdf != NULL) {
      components_.push_back(RooArgSet(*sub_pdf));
    }
  }
}

Plot::Plot(const PlotConfig& cfg_plot, const RooAbsRealLValue& dimension, const RooAbsData& dataset, const RooAbsPdf& pdf, const std::vector<std::string>& components, const std::string& plot_name)
: config_plot_(cfg_plot),
  dimension_(dimension),
  datasets_(),
  plot_name_(plot_name)
{
  datasets_.push_back(&dataset);
  pdf_ = &pdf;

  if (pdf_ == NULL) {
    serr << "Plot::Plot(): Main PDF is invalid." << endmsg;
    throw 1;
  }
  if (&dimension_ == NULL) {
    serr << "Plot::Plot(): Dimension is invalid." << endmsg;
    throw 1;
  }
  if (datasets_.front() == NULL) {
    serr << "Plot::Plot(): Dataset is invalid." << endmsg;
    throw 1;
  }
  if (plot_name_ == "") {
    plot_name_ = dimension_.GetName();
  }

  // iterate over sub PDFs and match supplied regular expressions
  RooArgSet nodes;
  pdf.branchNodeServerList(&nodes);

  for (std::vector<std::string>::const_iterator it = components.begin();
       it != components.end(); ++it) {
    boost::regex r(*it);
    components_.push_back(RooArgSet());

    TIterator* it_nodes = nodes.createIterator();
    RooAbsArg* node = NULL;

    while ((node = dynamic_cast<RooAbsArg*>(it_nodes->Next()))) {
      RooAbsPdf* pdf_node = dynamic_cast<RooAbsPdf*>(node);
      if (pdf_node != NULL) {
        std::string pdf_name = pdf_node->GetName();

        // exclude resolution models generated by RooFit and match the rest
        if (pdf_name.find("_conv_") == -1 && regex_match(pdf_name,r)) {
          components_.back().add(*pdf_node);
        }
      }
    }
    delete it_nodes;
  }
}

void Plot::PlotHandler(ScaleType sc_y, std::string suffix) const {
  if (suffix == "") suffix = "_log";

  std::string plot_name = plot_name_;

  std::stringstream log_plot_name_sstr;
  log_plot_name_sstr << plot_name << suffix;
  std::string log_plot_name = log_plot_name_sstr.str();

  std::stringstream pull_plot_sstr;
  pull_plot_sstr << plot_name << "_pull";
  std::string pull_plot_name = pull_plot_sstr.str();

  std::stringstream log_pull_plot_sstr;
  log_pull_plot_sstr << plot_name << "_pull" << suffix;
  std::string log_pull_plot_name = log_pull_plot_sstr.str();

  sinfo << "Plotting " << dimension_.GetName() << " into directory " << config_plot_.plot_directory() << " as " << plot_name << endmsg;

  doocore::lutils::setStyle("LHCb");

  RooCmdArg range_arg;

  // x range
  if (!dimension_.hasMin() && !dimension_.hasMax()) {
    double min, max;

    // ugly const_cast because RooFit is stupid (RooDataSet::getRange needs non-const RooRealVar)
    RooRealVar* dimension_non_const = const_cast<RooRealVar*>(dynamic_cast<const RooRealVar*>(&dimension_));
    datasets_.front()->getRange(*dimension_non_const, min, max);

    double min_t, max_t;
    for (std::vector<const RooAbsData*>::const_iterator it = datasets_.begin()+1;
         it != datasets_.end(); ++it) {
      (*it)->getRange(*dimension_non_const, min_t, max_t);
      if (min_t < min) min = min_t;
      if (max_t > max) max = max_t;
    }

    range_arg = Range(min, max);
  }

  RooCmdArg cut_range_arg, projection_range_arg, frame_range_arg;
  RooBinning* binning = NULL;
  RooAbsData* dataset_reduced = NULL;
  if (plot_range_.length() > 0) {
    sinfo << "doofit::plotting: Plotting on named range " << plot_range_ << endmsg;
    cut_range_arg = CutRange(plot_range_.c_str());
    projection_range_arg = ProjectionRange(plot_range_.c_str());
    range_arg = Range(plot_range_.c_str());
    binning = new RooBinning(dimension_.getBinning().numBins(), dimension_.getMin(plot_range_.c_str()), dimension_.getMax(plot_range_.c_str()));

    // ugly const cast as RooFit (once again) gives a shit about const correctness
    RooAbsData* dataset = const_cast<RooAbsData*>(datasets_.front());
    //dataset_reduced = dataset->reduce(cut_range_arg);
    dataset_reduced = dataset->reduce(CutRange(plot_range_.c_str()));

    sinfo << "Created reduced dataset with " << dataset_reduced->numEntries() << " (original dataset has " << dataset->numEntries() << ")" << endmsg;
    dataset_reduced->Print();
  }

  RooPlot* plot_frame = dimension_.frame(range_arg);

  if (dataset_reduced != NULL) {
    if (binning != NULL) {
      dataset_reduced->plotOn(plot_frame, Binning(*binning), cut_range_arg/*, Rescale(1.0/(*it)->sumEntries())*/);
    } else {
      dataset_reduced->plotOn(plot_frame, Binning(dimension_.getBinning()), cut_range_arg/*, Rescale(1.0/(*it)->sumEntries())*/);
    }
  } else {
    for (std::vector<const RooAbsData*>::const_iterator it = datasets_.begin();
         it != datasets_.end(); ++it) {
      if (binning != NULL) {
        (*it)->plotOn(plot_frame, Binning(*binning), cut_range_arg/*, Rescale(1.0/(*it)->sumEntries())*/);
      } else {
        (*it)->plotOn(plot_frame, Binning(dimension_.getBinning()), cut_range_arg/*, Rescale(1.0/(*it)->sumEntries())*/);
      }
    }
  }

  // y range adaptively for log scale
  RooHist * data = (RooHist*) plot_frame->findObject(0,RooHist::Class());
  double x,y;
  data->GetPoint(0,x,y);
  double min_data_entry = y;
  for (unsigned int i = 1; i < data->GetN(); ++i) {
    data->GetPoint(i,x,y);
    if (min_data_entry > y) min_data_entry = y;
  }
  if (min_data_entry == 0.0) min_data_entry = 1.0;
  if (min_data_entry < 0.0) min_data_entry = 0.01;
//  sdebug << "minimum data entry in dataset: " << min_data_entry << endmsg;
  double min_plot = TMath::Power(10.0,TMath::Log10(min_data_entry)-0.9);

//  sdebug << "minimum entry in histogram: " << min_data_entry << endmsg;
//  sdebug << "minimum for plot range: " << min_plot << endmsg;

  TLatex label(0.65,0.85,"LHCb");

  config_plot_.OnDemandOpenPlotStack();
  if (pdf_ != NULL) {
    RooPlot* plot_frame_pull = dimension_.frame(range_arg);

    // I feel so stupid doing this but apparently RooFit leaves me no other way...
    RooCmdArg arg1, arg2, arg3, arg4, arg5, arg6, arg7;
    if (plot_args_.size() > 0) arg1 = plot_args_[0];
    if (plot_args_.size() > 1) arg2 = plot_args_[1];
    if (plot_args_.size() > 2) arg3 = plot_args_[2];
    if (plot_args_.size() > 3) arg4 = plot_args_[3];
    if (plot_args_.size() > 4) arg5 = plot_args_[4];
    if (plot_args_.size() > 5) arg6 = plot_args_[5];
//    if (plot_args_.size() > 6) arg7 = plot_args_[6];

    if (dataset_reduced != NULL) {
      serr << "Reduced dataset available. Plotting this." << endmsg;
      if (binning != NULL) {
        dataset_reduced->plotOn(plot_frame_pull, Binning(*binning), cut_range_arg);
      } else {
        dataset_reduced->plotOn(plot_frame_pull, Binning(dimension_.getBinning()), cut_range_arg);
      }
    } else {
      for (std::vector<const RooAbsData*>::const_iterator it = datasets_.begin();
           it != datasets_.end(); ++it) {
        if (binning != NULL) {
          (*it)->plotOn(plot_frame_pull, Binning(*binning), cut_range_arg);
        } else {
          (*it)->plotOn(plot_frame_pull, Binning(dimension_.getBinning()), cut_range_arg);
        }
      }
    }

    int i=1;
    for (std::vector<RooArgSet>::const_iterator it = components_.begin();
         it != components_.end(); ++it) {
      if (it->getSize() > 0) {
        sinfo << "Plotting component " << it->first()->GetName() << endmsg;
        pdf_->plotOn(plot_frame, Components(*it), LineColor(config_plot_.GetPdfLineColor(i)), LineStyle(config_plot_.GetPdfLineStyle(i)), projection_range_arg/*, NumCPU(8)*/, arg1, arg2, arg3, arg4, arg5, arg6);
        pdf_->plotOn(plot_frame_pull, Components(*it), LineColor(config_plot_.GetPdfLineColor(i)), LineStyle(config_plot_.GetPdfLineStyle(i)), projection_range_arg/*, NumCPU(8)*/, arg1, arg2, arg3, arg4, arg5, arg6);
        ++i;
      }
    }

    pdf_->plotOn(plot_frame, LineColor(config_plot_.GetPdfLineColor(0)), LineStyle(config_plot_.GetPdfLineStyle(0)), projection_range_arg/*, NumCPU(8)*/, arg1, arg2, arg3, arg4, arg5, arg6);
    pdf_->plotOn(plot_frame_pull, LineColor(config_plot_.GetPdfLineColor(0)), LineStyle(config_plot_.GetPdfLineStyle(0)), projection_range_arg/*, NumCPU(8)*/, arg1, arg2, arg3, arg4, arg5, arg6);

    // =10^(ln(11)/ln(10)-0.5)
    //plot_frame_pull->SetMinimum(0.5);

    plot_frame_pull->SetMinimum(0.5);
    plot_frame_pull->SetMaximum(1.3*plot_frame_pull->GetMaximum());

    TString ylabel = plot_frame_pull->GetYaxis()->GetTitle();
    ylabel.ReplaceAll("Events","Candidates");
    plot_frame_pull->GetYaxis()->SetTitle(ylabel);

    if (sc_y == kLinear || sc_y == kBoth) {
      doocore::lutils::PlotPulls(pull_plot_name, plot_frame_pull, label, config_plot_.plot_directory(), false, false, true);
      doocore::lutils::PlotPulls("AllPlots", plot_frame_pull, label, config_plot_.plot_directory(), false, false, true, "");
    }

//    sdebug << "Plot y axis minimum for log scale plot: " << min_plot << endmsg;
    plot_frame_pull->SetMinimum(min_plot);
    if (sc_y == kLogarithmic || sc_y == kBoth) {
      doocore::lutils::PlotPulls(log_pull_plot_name, plot_frame_pull, label, config_plot_.plot_directory(), true, false, true);
      doocore::lutils::PlotPulls("AllPlots", plot_frame_pull, label, config_plot_.plot_directory(), true, false, true, "");
    }

    delete plot_frame_pull;
  }

  plot_frame->SetMinimum(0.0);
  plot_frame->SetMaximum(1.3*plot_frame->GetMaximum());

  TString ylabel = plot_frame->GetYaxis()->GetTitle();
  ylabel.ReplaceAll("Events","Candidates");
  plot_frame->GetYaxis()->SetTitle(ylabel);

  if (sc_y == kLinear || sc_y == kBoth) {
    doocore::lutils::PlotSimple(plot_name, plot_frame, label, config_plot_.plot_directory(), false);
    doocore::lutils::PlotSimple("AllPlots", plot_frame, label, config_plot_.plot_directory(), false);
  }

  plot_frame->SetMinimum(min_plot);
  if (sc_y == kLogarithmic || sc_y == kBoth) {
    doocore::lutils::PlotSimple(log_plot_name, plot_frame, label, config_plot_.plot_directory(), true);
    doocore::lutils::PlotSimple("AllPlots", plot_frame, label, config_plot_.plot_directory(), true);
  }

  if (dataset_reduced != NULL) delete dataset_reduced;
  if (binning != NULL) delete binning;
  delete plot_frame;
}

Plot::~Plot() {}

} // namespace plotting
} // namespace doofit
<|endoftext|>


<commit_before>#include "neural_network_trainer.hpp"
#include "InputData/sentence.hpp"
#include "Learning/learning_method.hpp"
#include "InputData/image.hpp"
#include "Layer/fully_connected_neural_network.hpp"
#include "Layer/filters.hpp"

using namespace Convolutional;

enum class Categories {
	Cat,
	NotCat,

	CategoryCount
};

int main() {
	TrainingData<Categories> trainingData;
	InputData::Image someCat("https://www.cs.toronto.edu/~kriz/cifar-10-sample/cat1.png");
	//InputData::Image someCat("../../image.png");
	trainingData.AddData(std::move(someCat), Categories::Cat);

	Layer::Layers layers {
		Layer::Filters{3},
		Layer::Pooler::MaxPooler{},
		Layer::FullyConnectedNeuralNetwork{static_cast<std::size_t>(Categories::CategoryCount)}
	};

	NeuralNetworktrainer<Categories> networktrainer {
		50,
		std::move(trainingData),
		std::move(layers)
	};

	auto trainedNetwork = networktrainer.Train();

	//Learning::memes<Categories> m(trainedNetwork, trainingData);
	return 0;
}

<commit_msg>Fuck web<commit_after>#include "neural_network_trainer.hpp"
#include "InputData/sentence.hpp"
#include "Learning/learning_method.hpp"
#include "InputData/image.hpp"
#include "Layer/fully_connected_neural_network.hpp"
#include "Layer/filters.hpp"

using namespace Convolutional;

enum class Categories {
	Cat,
	NotCat,

	CategoryCount
};

int main() {
	TrainingData<Categories> trainingData;
	InputData::Image someCat("../../image.png");
	trainingData.AddData(std::move(someCat), Categories::Cat);

	Layer::Layers layers {
		Layer::Filters{3},
		Layer::Pooler::MaxPooler{},
		Layer::FullyConnectedNeuralNetwork{static_cast<std::size_t>(Categories::CategoryCount)}
	};

	NeuralNetworktrainer<Categories> networktrainer {
		50,
		std::move(trainingData),
		std::move(layers)
	};

	auto trainedNetwork = networktrainer.Train();

	//Learning::memes<Categories> m(trainedNetwork, trainingData);
	return 0;
}

<|endoftext|>