<commit_before>/*{{{
    Copyright © 2015 Matthias Kretz <kretz@kde.org>

    Permission to use, copy, modify, and distribute this software
    and its documentation for any purpose and without fee is hereby
    granted, provided that the above copyright notice appear in all
    copies and that both that the copyright notice and this
    permission notice and warranty disclaimer appear in supporting
    documentation, and that the name of the author not be used in
    advertising or publicity pertaining to distribution of the
    software without specific, written prior permission.

    The author disclaim all warranties with regard to this
    software, including all implied warranties of merchantability
    and fitness.  In no event shall the author be liable for any
    special, indirect or consequential damages or any damages
    whatsoever resulting from loss of use, data or profits, whether
    in an action of contract, negligence or other tortious action,
    arising out of or in connection with the use or performance of
    this software.

This work is derived from a class in ALICE with the following copyright notice:
    **************************************************************************
    * This file is property of and copyright by the ALICE HLT Project        *
    * ALICE Experiment at CERN, All rights reserved.                         *
    *                                                                        *
    * Primary Authors: Sergey Gorbunov <sergey.gorbunov@cern.ch>             *
    *                  for The ALICE HLT Project.                            *
    *                                                                        *
    * Permission to use, copy, modify and distribute this software and its   *
    * documentation strictly for non-commercial purposes is hereby granted   *
    * without fee, provided that the above copyright notice appears in all   *
    * copies and that both the copyright notice and this permission notice   *
    * appear in the supporting documentation. The authors make no claims     *
    * about the suitability of this software for any purpose. It is          *
    * provided "as is" without express or implied warranty.                  *
    **************************************************************************
}}}*/

#include "spline.h"
#include <Vc/Vc>
#include "../kdtree/simdize.h"

#include <iostream>
#include <iomanip>

using namespace std;

Spline::Spline(float minA, float maxA, int nBinsA, float minB, float maxB,  //{{{1
               int nBinsB)
    : fNA(nBinsA < 4 ? 4 : nBinsA)
    , fNB(nBinsB < 4 ? 4 : nBinsB)
    , fN(fNA * fNB)
    , fMinA(minA)
    , fMinB(minB)
    , fStepA(((maxA <= minA ? minA + 1 : maxA) - minA) / (fNA - 1))
    , fStepB(((maxB <= minB ? minB + 1 : maxB) - minB) / (fNB - 1))
    , fScaleA(1.f / fStepA)
    , fScaleB(1.f / fStepB)
    , fXYZ(fN, DataPoint::Zero())
{
}

// spline 3-st order,  4 points, da = a - point 1 {{{1
template <typename T> static inline T GetSpline3(T v0, T v1, T v2, T v3, T x)
{
    const T dv = v2 - v1;
    const T z0 = 0.5f * (v2 - v0);
    const T z1 = 0.5f * (v3 - v1);
    return (x * x) * ((z1 - dv) * (x - 1) + (z0 - dv) * (x - 2)) + (z0 * x + v1);
    //return x * x * ((z1 - dv + z0 - dv) * (x - 1) - (z0 - dv)) + z0 * x + v1;
}

template <typename T> static inline T GetSpline3(const T *v, T x)
{
    return GetSpline3(v[0], v[1], v[2], v[3], x);
}

std::array<float, 3> Spline::GetValue(std::array<float, 2> ab) const  //{{{1
{
    float da1, db1;
    unsigned iA, iB;
    std::tie(iA, iB, da1, db1) =
        evaluatePosition(ab, {fMinA, fMinB}, {fScaleA, fScaleB}, fNA, fNB);
    unsigned ind = iA * fNB + iB;

    typedef Vc::simdarray<float, 4> float4;
    const float4 da = da1;
    const float4 db = db1;

    float4 v[4];
    const float4 *m = &fXYZ[0];

    for (int i = 0; i < 4; i++) {
        v[i] = GetSpline3(m[ind + 0], m[ind + 1], m[ind + 2], m[ind + 3], db);
        ind += fNB;
    }
    float4 res = GetSpline3(v[0], v[1], v[2], v[3], da);
    std::array<float, 3> XYZ;
    XYZ[0] = res[0];
    XYZ[1] = res[1];
    XYZ[2] = res[2];
    return XYZ;
}

std::array<float, 3> Spline::GetValue16(std::array<float, 2> ab) const  //{{{1
{
    float da1, db1;
    unsigned iA, iB;
    std::tie(iA, iB, da1, db1) =
        evaluatePosition(ab, {fMinA, fMinB}, {fScaleA, fScaleB}, fNA, fNB);

    typedef Vc::simdarray<float, 4> float4;
    typedef Vc::simdarray<float, 16> float16;
    const float4 da = da1;
    const float16 db = db1;

    const float4 *m0 = &fXYZ[iA * fNB + iB];
    const float4 *m1 = m0 + fNB;
    const float4 *m2 = m1 + fNB;
    const float4 *m3 = m2 + fNB;
    const float16 v0123 =
        GetSpline3(Vc::simd_cast<float16>(m0[0], m1[0], m2[0], m3[0]),
                   Vc::simd_cast<float16>(m0[1], m1[1], m2[1], m3[1]),
                   Vc::simd_cast<float16>(m0[2], m1[2], m2[2], m3[2]),
                   Vc::simd_cast<float16>(m0[3], m1[3], m2[3], m3[3]), db);
    const float4 res =
        GetSpline3(Vc::simd_cast<float4, 0>(v0123), Vc::simd_cast<float4, 1>(v0123),
                   Vc::simd_cast<float4, 2>(v0123), Vc::simd_cast<float4, 3>(v0123), da);
    std::array<float, 3> XYZ;
    XYZ[0] = res[0];
    XYZ[1] = res[1];
    XYZ[2] = res[2];
    return XYZ;
}

std::array<float, 3> Spline::GetValueScalar(std::array<float, 2> ab) const  //{{{1
{
    float da, db;
    unsigned iA, iB;
    std::tie(iA, iB, da, db) =
        evaluatePosition(ab, {fMinA, fMinB}, {fScaleA, fScaleB}, fNA, fNB);
    unsigned ind = iA * fNB + iB;

    float vx[4];
    float vy[4];
    float vz[4];
    for (int i = 0; i < 4; i++) {
        vx[i] = GetSpline3(fXYZ[ind][0], fXYZ[ind + 1][0], fXYZ[ind + 2][0],
                           fXYZ[ind + 3][0], db);
        vy[i] = GetSpline3(fXYZ[ind][1], fXYZ[ind + 1][1], fXYZ[ind + 2][1],
                           fXYZ[ind + 3][1], db);
        vz[i] = GetSpline3(fXYZ[ind][2], fXYZ[ind + 1][2], fXYZ[ind + 2][2],
                           fXYZ[ind + 3][2], db);
        ind += fNB;
    }
    std::array<float, 3> XYZ;
    XYZ[0] = GetSpline3(vx, da);
    XYZ[1] = GetSpline3(vy, da);
    XYZ[2] = GetSpline3(vz, da);
    return XYZ;
}

Point3V Spline::GetValue(const Point2V &ab) const  //{{{1
{
    float_v iA, iB, da, db;
    std::tie(iA, iB, da, db) =
        evaluatePosition(ab, {fMinA, fMinB}, {fScaleA, fScaleB}, fNA, fNB);

    float_v vx[4];
    float_v vy[4];
    float_v vz[4];
    auto ind = static_cast<float_v::IndexType>(iA * fNB + iB);
    const auto map = Vc::make_interleave_wrapper<float_v>(&fXYZ[0]);
    //std::cerr << typeid(map).name() << std::endl; exit(1);
    for (int i = 0; i < 4; i++) {
        float_v x[4], y[4], z[4];
        Vc::tie(x[0], y[0], z[0]) = map[ind + 0];
        Vc::tie(x[1], y[1], z[1]) = map[ind + 1];
        Vc::tie(x[2], y[2], z[2]) = map[ind + 2];
        Vc::tie(x[3], y[3], z[3]) = map[ind + 3];
        vx[i] = GetSpline3<float_v>(x[0], x[1], x[2], x[3], db);
        vy[i] = GetSpline3<float_v>(y[0], y[1], y[2], y[3], db);
        vz[i] = GetSpline3<float_v>(z[0], z[1], z[2], z[3], db);
        ind += fNB;
    }
    Point3V XYZ;
    XYZ[0] = GetSpline3<float_v>(vx, da);
    XYZ[1] = GetSpline3<float_v>(vy, da);
    XYZ[2] = GetSpline3<float_v>(vz, da);
    return XYZ;
}

// vim: foldmethod=marker
<commit_msg>spline: minor code cleanup, avoiding +0<commit_after>/*{{{
    Copyright © 2015 Matthias Kretz <kretz@kde.org>

    Permission to use, copy, modify, and distribute this software
    and its documentation for any purpose and without fee is hereby
    granted, provided that the above copyright notice appear in all
    copies and that both that the copyright notice and this
    permission notice and warranty disclaimer appear in supporting
    documentation, and that the name of the author not be used in
    advertising or publicity pertaining to distribution of the
    software without specific, written prior permission.

    The author disclaim all warranties with regard to this
    software, including all implied warranties of merchantability
    and fitness.  In no event shall the author be liable for any
    special, indirect or consequential damages or any damages
    whatsoever resulting from loss of use, data or profits, whether
    in an action of contract, negligence or other tortious action,
    arising out of or in connection with the use or performance of
    this software.

This work is derived from a class in ALICE with the following copyright notice:
    **************************************************************************
    * This file is property of and copyright by the ALICE HLT Project        *
    * ALICE Experiment at CERN, All rights reserved.                         *
    *                                                                        *
    * Primary Authors: Sergey Gorbunov <sergey.gorbunov@cern.ch>             *
    *                  for The ALICE HLT Project.                            *
    *                                                                        *
    * Permission to use, copy, modify and distribute this software and its   *
    * documentation strictly for non-commercial purposes is hereby granted   *
    * without fee, provided that the above copyright notice appears in all   *
    * copies and that both the copyright notice and this permission notice   *
    * appear in the supporting documentation. The authors make no claims     *
    * about the suitability of this software for any purpose. It is          *
    * provided "as is" without express or implied warranty.                  *
    **************************************************************************
}}}*/

#include "spline.h"
#include <Vc/Vc>
#include "../kdtree/simdize.h"

#include <iostream>
#include <iomanip>

using namespace std;

Spline::Spline(float minA, float maxA, int nBinsA, float minB, float maxB,  //{{{1
               int nBinsB)
    : fNA(nBinsA < 4 ? 4 : nBinsA)
    , fNB(nBinsB < 4 ? 4 : nBinsB)
    , fN(fNA * fNB)
    , fMinA(minA)
    , fMinB(minB)
    , fStepA(((maxA <= minA ? minA + 1 : maxA) - minA) / (fNA - 1))
    , fStepB(((maxB <= minB ? minB + 1 : maxB) - minB) / (fNB - 1))
    , fScaleA(1.f / fStepA)
    , fScaleB(1.f / fStepB)
    , fXYZ(fN, DataPoint::Zero())
{
}

// spline 3-st order,  4 points, da = a - point 1 {{{1
template <typename T> static inline T GetSpline3(T v0, T v1, T v2, T v3, T x)
{
    const T dv = v2 - v1;
    const T z0 = 0.5f * (v2 - v0);
    const T z1 = 0.5f * (v3 - v1);
    return (x * x) * ((z1 - dv) * (x - 1) + (z0 - dv) * (x - 2)) + (z0 * x + v1);
    //return x * x * ((z1 - dv + z0 - dv) * (x - 1) - (z0 - dv)) + z0 * x + v1;
}

template <typename T> static inline T GetSpline3(const T *v, T x)
{
    return GetSpline3(v[0], v[1], v[2], v[3], x);
}

std::array<float, 3> Spline::GetValue(std::array<float, 2> ab) const  //{{{1
{
    float da1, db1;
    unsigned iA, iB;
    std::tie(iA, iB, da1, db1) =
        evaluatePosition(ab, {fMinA, fMinB}, {fScaleA, fScaleB}, fNA, fNB);
    unsigned ind = iA * fNB + iB;

    typedef Vc::simdarray<float, 4> float4;
    const float4 da = da1;
    const float4 db = db1;

    float4 v[4];
    const float4 *m = &fXYZ[0];

    for (int i = 0; i < 4; i++) {
        v[i] = GetSpline3(m[ind + 0], m[ind + 1], m[ind + 2], m[ind + 3], db);
        ind += fNB;
    }
    float4 res = GetSpline3(v[0], v[1], v[2], v[3], da);
    std::array<float, 3> XYZ;
    XYZ[0] = res[0];
    XYZ[1] = res[1];
    XYZ[2] = res[2];
    return XYZ;
}

std::array<float, 3> Spline::GetValue16(std::array<float, 2> ab) const  //{{{1
{
    float da1, db1;
    unsigned iA, iB;
    std::tie(iA, iB, da1, db1) =
        evaluatePosition(ab, {fMinA, fMinB}, {fScaleA, fScaleB}, fNA, fNB);

    typedef Vc::simdarray<float, 4> float4;
    typedef Vc::simdarray<float, 16> float16;
    const float4 da = da1;
    const float16 db = db1;

    const float4 *m0 = &fXYZ[iA * fNB + iB];
    const float4 *m1 = m0 + fNB;
    const float4 *m2 = m1 + fNB;
    const float4 *m3 = m2 + fNB;
    const float16 v0123 =
        GetSpline3(Vc::simd_cast<float16>(m0[0], m1[0], m2[0], m3[0]),
                   Vc::simd_cast<float16>(m0[1], m1[1], m2[1], m3[1]),
                   Vc::simd_cast<float16>(m0[2], m1[2], m2[2], m3[2]),
                   Vc::simd_cast<float16>(m0[3], m1[3], m2[3], m3[3]), db);
    const float4 res =
        GetSpline3(Vc::simd_cast<float4, 0>(v0123), Vc::simd_cast<float4, 1>(v0123),
                   Vc::simd_cast<float4, 2>(v0123), Vc::simd_cast<float4, 3>(v0123), da);
    std::array<float, 3> XYZ;
    XYZ[0] = res[0];
    XYZ[1] = res[1];
    XYZ[2] = res[2];
    return XYZ;
}

std::array<float, 3> Spline::GetValueScalar(std::array<float, 2> ab) const  //{{{1
{
    float da, db;
    unsigned iA, iB;
    std::tie(iA, iB, da, db) =
        evaluatePosition(ab, {fMinA, fMinB}, {fScaleA, fScaleB}, fNA, fNB);
    unsigned ind = iA * fNB + iB;

    float vx[4];
    float vy[4];
    float vz[4];
    for (int i = 0; i < 4; i++) {
        vx[i] = GetSpline3(fXYZ[ind][0], fXYZ[ind + 1][0], fXYZ[ind + 2][0],
                           fXYZ[ind + 3][0], db);
        vy[i] = GetSpline3(fXYZ[ind][1], fXYZ[ind + 1][1], fXYZ[ind + 2][1],
                           fXYZ[ind + 3][1], db);
        vz[i] = GetSpline3(fXYZ[ind][2], fXYZ[ind + 1][2], fXYZ[ind + 2][2],
                           fXYZ[ind + 3][2], db);
        ind += fNB;
    }
    std::array<float, 3> XYZ;
    XYZ[0] = GetSpline3(vx, da);
    XYZ[1] = GetSpline3(vy, da);
    XYZ[2] = GetSpline3(vz, da);
    return XYZ;
}

Point3V Spline::GetValue(const Point2V &ab) const  //{{{1
{
    float_v iA, iB, da, db;
    std::tie(iA, iB, da, db) =
        evaluatePosition(ab, {fMinA, fMinB}, {fScaleA, fScaleB}, fNA, fNB);

    float_v vx[4];
    float_v vy[4];
    float_v vz[4];
    auto ind = static_cast<float_v::IndexType>(iA * fNB + iB);
    const auto map = Vc::make_interleave_wrapper<float_v>(&fXYZ[0]);
    for (int i = 0; i < 4; i++) {
        float_v x[4], y[4], z[4];
        Vc::tie(x[0], y[0], z[0]) = map[ind];
        Vc::tie(x[1], y[1], z[1]) = map[ind + 1];
        Vc::tie(x[2], y[2], z[2]) = map[ind + 2];
        Vc::tie(x[3], y[3], z[3]) = map[ind + 3];
        vx[i] = GetSpline3<float_v>(x[0], x[1], x[2], x[3], db);
        vy[i] = GetSpline3<float_v>(y[0], y[1], y[2], y[3], db);
        vz[i] = GetSpline3<float_v>(z[0], z[1], z[2], z[3], db);
        ind += fNB;
    }
    Point3V XYZ;
    XYZ[0] = GetSpline3<float_v>(vx, da);
    XYZ[1] = GetSpline3<float_v>(vy, da);
    XYZ[2] = GetSpline3<float_v>(vz, da);
    return XYZ;
}

// vim: foldmethod=marker
<|endoftext|>


<commit_before>#include "MMAcquisition.h"
#include "../MMDevice/ImageMetadata.h"
#include "boost/foreach.hpp"

///////////////////////////////////
// MMAquisitionEngine::ImageTask //
///////////////////////////////////

ImageTask::ImageTask(MMAcquisitionEngine * eng, ImageRequest imageRequest)
{
	eng_ = eng;
	imageRequest_ = imageRequest;
	type = IMAGE;
}

void ImageTask::run()
{
	updatePosition();
	updateSlice();
	updateChannel();
	wait();
	autofocus();
	acquireImage();

}

void ImageTask::updateSlice()
{
	eng_->coreCallback_->SetFocusPosition(imageRequest_.slicePosition);
	printf("slice set\n");
}

void ImageTask::updatePosition()
{
	map<string, double>::iterator it1;

	MultiAxisPosition pos = imageRequest_.multiAxisPosition;
	for (it1 = pos.singleAxisPositions.begin(); it1 != pos.singleAxisPositions.end(); ++it1)
	{
		eng_->core_->setPosition(it1->first.c_str(), it1->second);
	}

	map<string, pair<double, double> >::iterator it2;

	for (it2 = pos.doubleAxisPositions.begin(); it2 != pos.doubleAxisPositions.end(); ++it2)
	{
		point2D xy = it2->second;
		eng_->core_->setXYPosition(it2->first.c_str(), xy.first, xy.second);
	}
	printf("position set\n");
}

void ImageTask::updateChannel() {
	eng_->coreCallback_->SetExposure(imageRequest_.channel.exposure);
	eng_->coreCallback_->SetConfig(imageRequest_.channel.group.c_str(), imageRequest_.channel.name.c_str());
	printf("channel set\n");
}

void ImageTask::wait() {
	if (eng_->lastWakeTime_ > 0)
	{
		MM::MMTime sleepTime = (eng_->lastWakeTime_ + imageRequest_.waitTime) - eng_->coreCallback_->GetCurrentMMTime();
		if (sleepTime > MM::MMTime(0, 0))
			eng_->coreCallback_->Sleep(NULL, sleepTime.getMsec());
		printf("waited\n");
	}

	eng_->lastWakeTime_ = eng_->coreCallback_->GetCurrentMMTime();
}

void ImageTask::autofocus() {
	if (imageRequest_.runAutofocus)
		eng_->core_->fullFocus();
}

void ImageTask::acquireImage() {
	int w, h, d;
	const char * img = eng_->coreCallback_->GetImage(); // Snaps and retrieves image.

	Metadata md;
   md.sliceIndex = imageRequest_.sliceIndex;
   md.channelIndex = imageRequest_.channelIndex;
   md.positionIndex = imageRequest_.positionIndex;
   md.frameIndex = imageRequest_.timeIndex;

	eng_->coreCallback_->GetImageDimensions(w, h, d);
	eng_->coreCallback_->InsertImage(NULL, (const unsigned char *) img, w, h, d, &md);
	printf("Grabbed image.\n");
}

/////////////////////////
// MMAcquisitionRunner //
/////////////////////////

void MMAcquisitionEngine::Start() {
	stopRequested_ = false;
	pauseRequested_ = false;
	finished_ = false;

	activate();
}

void MMAcquisitionEngine::Run() {
	for (unsigned int i = 0; i < tasks_.size(); ++i) {
		if (stopRequested_)
			break;
		printf("Task #%d started, type %d\n", i, tasks_[i]->type);
		tasks_[i]->run();
	}
	finished_ = true;
}

bool MMAcquisitionEngine::IsFinished() {
	return finished_;
}

void MMAcquisitionEngine::Stop() {
	stopRequested_ = true;
}

void MMAcquisitionEngine::Pause() {
	pauseRequested_ = true;
}

void MMAcquisitionEngine::Resume() {
	pauseRequested_ = false;
}

void MMAcquisitionEngine::Step() {
}

void MMAcquisitionEngine::SetTasks(TaskVector tasks) {
	tasks_ = tasks;
}

void MMAcquisitionEngine::GenerateSequence(AcquisitionSettings acquisitionSettings)
{

   ImageRequest imageRequest;
   imageRequest.runAutofocus = acquisitionSettings.useAutofocus;

   if (acquisitionSettings.positionsFirst)
   {
      for(imageRequest.timeIndex = 0; imageRequest.timeIndex < acquisitionSettings.timeSeries.size(); ++imageRequest.timeIndex)
      {
         imageRequest.waitTime = MM::MMTime(acquisitionSettings.timeSeries[imageRequest.timeIndex] * 1000);
         for(imageRequest.positionIndex = 0; imageRequest.positionIndex < acquisitionSettings.positionList.size(); ++imageRequest.positionIndex)
         {
            imageRequest.multiAxisPosition = acquisitionSettings.positionList[imageRequest.positionIndex];
            GenerateSlicesAndChannelsSubsequence(acquisitionSettings, imageRequest);
         }
      }
   }
   else
   {
      for(imageRequest.positionIndex = 0; imageRequest.positionIndex < acquisitionSettings.positionList.size(); ++imageRequest.positionIndex)
      {
         imageRequest.multiAxisPosition = acquisitionSettings.positionList[imageRequest.positionIndex];
         for(imageRequest.timeIndex = 0; imageRequest.timeIndex < acquisitionSettings.timeSeries.size(); ++imageRequest.timeIndex)
         {
            imageRequest.waitTime = MM::MMTime(acquisitionSettings.timeSeries[imageRequest.timeIndex] * 1000);
            GenerateSlicesAndChannelsSubsequence(acquisitionSettings, imageRequest);
         }
      }
   }
}

void MMAcquisitionEngine::GenerateSlicesAndChannelsSubsequence(AcquisitionSettings acquisitionSettings, ImageRequest imageRequest)
{
   if (acquisitionSettings.channelsFirst)
   {
      for(imageRequest.sliceIndex; imageRequest.sliceIndex < acquisitionSettings.zStack.size(); ++imageRequest.sliceIndex)
      {
         imageRequest.slicePosition = acquisitionSettings.zStack[imageRequest.sliceIndex];
         for(imageRequest.channelIndex; imageRequest.channelIndex < acquisitionSettings.channelList.size(); ++imageRequest.channelIndex)
         {
            imageRequest.channel = acquisitionSettings.channelList[imageRequest.channelIndex];
            tasks_.push_back(new ImageTask(this, imageRequest));
         }
      }
   }
   else
   {
      for(imageRequest.channelIndex; imageRequest.channelIndex < acquisitionSettings.channelList.size(); ++imageRequest.channelIndex)
      {
         imageRequest.channel = acquisitionSettings.channelList[imageRequest.channelIndex];
         for(imageRequest.sliceIndex; imageRequest.sliceIndex < acquisitionSettings.zStack.size(); ++imageRequest.sliceIndex)
         {
            imageRequest.slicePosition = acquisitionSettings.zStack[imageRequest.sliceIndex];
            tasks_.push_back(new ImageTask(this, imageRequest));
         }
      }
   }
}

<commit_msg>fix bug in channels and slices loops<commit_after>#include "MMAcquisition.h"
#include "../MMDevice/ImageMetadata.h"
#include "boost/foreach.hpp"

///////////////////////////////////
// MMAquisitionEngine::ImageTask //
///////////////////////////////////

ImageTask::ImageTask(MMAcquisitionEngine * eng, ImageRequest imageRequest)
{
	eng_ = eng;
	imageRequest_ = imageRequest;
	type = IMAGE;
}

void ImageTask::run()
{
	updatePosition();
	updateSlice();
	updateChannel();
	wait();
	autofocus();
	acquireImage();

}

void ImageTask::updateSlice()
{
	eng_->coreCallback_->SetFocusPosition(imageRequest_.slicePosition);
	printf("slice set\n");
}

void ImageTask::updatePosition()
{
	map<string, double>::iterator it1;

	MultiAxisPosition pos = imageRequest_.multiAxisPosition;
	for (it1 = pos.singleAxisPositions.begin(); it1 != pos.singleAxisPositions.end(); ++it1)
	{
		eng_->core_->setPosition(it1->first.c_str(), it1->second);
	}

	map<string, pair<double, double> >::iterator it2;

	for (it2 = pos.doubleAxisPositions.begin(); it2 != pos.doubleAxisPositions.end(); ++it2)
	{
		point2D xy = it2->second;
		eng_->core_->setXYPosition(it2->first.c_str(), xy.first, xy.second);
	}
	printf("position set\n");
}

void ImageTask::updateChannel() {
	eng_->coreCallback_->SetExposure(imageRequest_.channel.exposure);
	eng_->coreCallback_->SetConfig(imageRequest_.channel.group.c_str(), imageRequest_.channel.name.c_str());
	printf("channel set\n");
}

void ImageTask::wait() {
	if (eng_->lastWakeTime_ > 0)
	{
		MM::MMTime sleepTime = (eng_->lastWakeTime_ + imageRequest_.waitTime) - eng_->coreCallback_->GetCurrentMMTime();
		if (sleepTime > MM::MMTime(0, 0))
			eng_->coreCallback_->Sleep(NULL, sleepTime.getMsec());
		printf("waited\n");
	}

	eng_->lastWakeTime_ = eng_->coreCallback_->GetCurrentMMTime();
}

void ImageTask::autofocus() {
	if (imageRequest_.runAutofocus)
		eng_->core_->fullFocus();
}

void ImageTask::acquireImage() {
	int w, h, d;
	const char * img = eng_->coreCallback_->GetImage(); // Snaps and retrieves image.

	Metadata md;
   md.sliceIndex = imageRequest_.sliceIndex;
   md.channelIndex = imageRequest_.channelIndex;
   md.positionIndex = imageRequest_.positionIndex;
   md.frameIndex = imageRequest_.timeIndex;

	eng_->coreCallback_->GetImageDimensions(w, h, d);
	eng_->coreCallback_->InsertImage(NULL, (const unsigned char *) img, w, h, d, &md);
	printf("Grabbed image.\n");
}

/////////////////////////
// MMAcquisitionRunner //
/////////////////////////

void MMAcquisitionEngine::Start() {
	stopRequested_ = false;
	pauseRequested_ = false;
	finished_ = false;

	activate();
}

void MMAcquisitionEngine::Run() {
	for (unsigned int i = 0; i < tasks_.size(); ++i) {
		if (stopRequested_)
			break;
		printf("Task #%d started, type %d\n", i, tasks_[i]->type);
		tasks_[i]->run();
	}
	finished_ = true;
}

bool MMAcquisitionEngine::IsFinished() {
	return finished_;
}

void MMAcquisitionEngine::Stop() {
	stopRequested_ = true;
}

void MMAcquisitionEngine::Pause() {
	pauseRequested_ = true;
}

void MMAcquisitionEngine::Resume() {
	pauseRequested_ = false;
}

void MMAcquisitionEngine::Step() {
}

void MMAcquisitionEngine::SetTasks(TaskVector tasks) {
	tasks_ = tasks;
}

void MMAcquisitionEngine::GenerateSequence(AcquisitionSettings acquisitionSettings)
{

   ImageRequest imageRequest;
   imageRequest.runAutofocus = acquisitionSettings.useAutofocus;

   if (acquisitionSettings.positionsFirst)
   {
      for(imageRequest.timeIndex = 0; imageRequest.timeIndex < acquisitionSettings.timeSeries.size(); ++imageRequest.timeIndex)
      {
         imageRequest.waitTime = MM::MMTime(acquisitionSettings.timeSeries[imageRequest.timeIndex] * 1000);
         for(imageRequest.positionIndex = 0; imageRequest.positionIndex < acquisitionSettings.positionList.size(); ++imageRequest.positionIndex)
         {
            imageRequest.multiAxisPosition = acquisitionSettings.positionList[imageRequest.positionIndex];
            GenerateSlicesAndChannelsSubsequence(acquisitionSettings, imageRequest);
         }
      }
   }
   else
   {
      for(imageRequest.positionIndex = 0; imageRequest.positionIndex < acquisitionSettings.positionList.size(); ++imageRequest.positionIndex)
      {
         imageRequest.multiAxisPosition = acquisitionSettings.positionList[imageRequest.positionIndex];
         for(imageRequest.timeIndex = 0; imageRequest.timeIndex < acquisitionSettings.timeSeries.size(); ++imageRequest.timeIndex)
         {
            imageRequest.waitTime = MM::MMTime(acquisitionSettings.timeSeries[imageRequest.timeIndex] * 1000);
            GenerateSlicesAndChannelsSubsequence(acquisitionSettings, imageRequest);
         }
      }
   }
}

void MMAcquisitionEngine::GenerateSlicesAndChannelsSubsequence(AcquisitionSettings acquisitionSettings, ImageRequest imageRequest)
{
   if (acquisitionSettings.channelsFirst)
   {
      for(imageRequest.sliceIndex = 0; imageRequest.sliceIndex < acquisitionSettings.zStack.size(); ++imageRequest.sliceIndex)
      {
         imageRequest.slicePosition = acquisitionSettings.zStack[imageRequest.sliceIndex];
         for(imageRequest.channelIndex = 0; imageRequest.channelIndex < acquisitionSettings.channelList.size(); ++imageRequest.channelIndex)
         {
            imageRequest.channel = acquisitionSettings.channelList[imageRequest.channelIndex];
            tasks_.push_back(new ImageTask(this, imageRequest));
         }
      }
   }
   else
   {
      for(imageRequest.channelIndex = 0; imageRequest.channelIndex < acquisitionSettings.channelList.size(); ++imageRequest.channelIndex)
      {
         imageRequest.channel = acquisitionSettings.channelList[imageRequest.channelIndex];
         for(imageRequest.sliceIndex = 0; imageRequest.sliceIndex < acquisitionSettings.zStack.size(); ++imageRequest.sliceIndex)
         {
            imageRequest.slicePosition = acquisitionSettings.zStack[imageRequest.sliceIndex];
            tasks_.push_back(new ImageTask(this, imageRequest));
         }
      }
   }
}

<|endoftext|>


<commit_before>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Manasij Mukherjee  <manasij7479@gmail.com>
// author:  Vassil Vassilev <vvasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Path.h"
#include "clang/Sema/Sema.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/AST.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/CompilerInstance.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/AutoloadCallback.h"
#include "cling/Interpreter/Transaction.h"

using namespace clang;

namespace cling {

  void AutoloadCallback::report(clang::SourceLocation l,std::string name,std::string header) {
    Sema& sema= m_Interpreter->getSema();

    unsigned id
      = sema.getDiagnostics().getCustomDiagID (DiagnosticsEngine::Level::Warning,
                                                 "Note: '%0' can be found in %1");
/*    unsigned idn //TODO: To be enabled after we have a way to get the full path
      = sema.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Level::Note,
                                                "Type : %0 , Full Path: %1")*/;

    sema.Diags.Report(l, id) << name << header;

  }

  bool AutoloadCallback::LookupObject (TagDecl *t) {
    if (t->hasAttr<AnnotateAttr>())
      report(t->getLocation(),t->getNameAsString(),t->getAttr<AnnotateAttr>()->getAnnotation());
    return false;
  }

  class DefaultArgVisitor: public RecursiveASTVisitor<DefaultArgVisitor> {
  private:
    bool m_IsStoringState;
    AutoloadCallback::FwdDeclsMap* m_Map;
    clang::Preprocessor* m_PP;
  private:
    void InsertIntoAutoloadingState (Decl* decl, std::string annotation) {

      assert(annotation != "" && "Empty annotation!");
      assert(m_PP);

      const FileEntry* FE = 0;
      SourceLocation fileNameLoc;
      bool isAngled = false;
      const DirectoryLookup* LookupFrom = 0;
      const DirectoryLookup* CurDir = 0;

      FE = m_PP->LookupFile(fileNameLoc, annotation, isAngled, LookupFrom,
                            CurDir, /*SearchPath*/0, /*RelativePath*/ 0,
                            /*suggestedModule*/0, /*SkipCache*/false,
                            /*OpenFile*/ false, /*CacheFail*/ false);

      assert(FE && "Must have a valid FileEntry");

      if (m_Map->find(FE) == m_Map->end())
        (*m_Map)[FE] = std::vector<Decl*>();

      (*m_Map)[FE].push_back(decl);
    }

  public:
    DefaultArgVisitor() : m_IsStoringState(false), m_Map(0) {}
    void RemoveDefaultArgsOf(Decl* D) {
      //D = D->getMostRecentDecl();
      TraverseDecl(D);
      //while ((D = D->getPreviousDecl()))
      //  TraverseDecl(D);
    }

    void TrackDefaultArgStateOf(Decl* D, AutoloadCallback::FwdDeclsMap& map,
                                Preprocessor& PP) {
      m_IsStoringState = true;
      m_Map = ↦
      m_PP = &PP;
      TraverseDecl(D);
      m_PP = 0;
      m_Map = 0;
      m_IsStoringState = false;
    }

    bool shouldVisitTemplateInstantiations() { return true; }
    bool TraverseTemplateTypeParmDecl(TemplateTypeParmDecl* D) {
      if (m_IsStoringState)
        return true;

      if (D->hasDefaultArgument())
        D->removeDefaultArgument();
      return true;
    }

    bool VisitDecl(Decl* D) {
      if (m_IsStoringState)
        return true;

      if (!D->hasAttr<AnnotateAttr>())
        return false;

      AnnotateAttr* attr = D->getAttr<AnnotateAttr>();
      if (!attr)
        return true;

      switch (D->getKind()) {
      default:
        InsertIntoAutoloadingState(D, attr->getAnnotation());
        break;
      case Decl::Enum:
        // EnumDecls have extra information 2 chars after the filename used
        // for extra fixups.
        InsertIntoAutoloadingState(D, attr->getAnnotation().drop_back(2));
        break;
      }

      return true;
    }

    bool TraverseTemplateDecl(TemplateDecl* D) {
      if (!D->getTemplatedDecl()->hasAttr<AnnotateAttr>())
        return true;
      for(auto P: D->getTemplateParameters()->asArray())
        TraverseDecl(P);
      return true;
    }

    bool TraverseNonTypeTemplateParmDecl(NonTypeTemplateParmDecl* D) {
      if (m_IsStoringState)
        return true;

      if (D->hasDefaultArgument())
        D->removeDefaultArgument();
      return true;
    }

    bool TraverseParmVarDecl(ParmVarDecl* D) {
      if (m_IsStoringState)
        return true;

      if (D->hasDefaultArg())
        D->setDefaultArg(nullptr);
      return true;
    }
  };

  void AutoloadCallback::InclusionDirective(clang::SourceLocation HashLoc,
                          const clang::Token &IncludeTok,
                          llvm::StringRef FileName,
                          bool IsAngled,
                          clang::CharSourceRange FilenameRange,
                          const clang::FileEntry *File,
                          llvm::StringRef SearchPath,
                          llvm::StringRef RelativePath,
                          const clang::Module *Imported) {
    assert(File && "Must have a valid File");

    auto found = m_Map.find(File);
    if (found == m_Map.end())
     return; // nothing to do, file not referred in any annotation

    DefaultArgVisitor defaultArgsCleaner;
    for (auto D : found->second) {
      defaultArgsCleaner.RemoveDefaultArgsOf(D);
    }
    // Don't need to keep track of cleaned up decls from file.
    m_Map.erase(found);
  }

  AutoloadCallback::AutoloadCallback(Interpreter* interp) :
    InterpreterCallbacks(interp,true,false,true), m_Interpreter(interp){
//#ifdef _POSIX_C_SOURCE
//      //Workaround for differnt expansion of macros to typedefs
//      m_Interpreter->parse("#include <sys/types.h>");
//#endif
  }

  AutoloadCallback::~AutoloadCallback() {
  }

  void AutoloadCallback::TransactionCommitted(const Transaction &T) {
    if (T.decls_begin() == T.decls_end())
      return;
    if (T.decls_begin()->m_DGR.isNull())
      return;

    if (const NamedDecl* ND = dyn_cast<NamedDecl>(*T.decls_begin()->m_DGR.begin()))
      if (ND->getIdentifier() && ND->getName().equals("__Cling_Autoloading_Map")) {
        DefaultArgVisitor defaultArgsStateCollector;
        Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
        for (Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
             I != E; ++I) {
          Transaction::DelayCallInfo DCI = *I;

          // if (DCI.m_Call != Transaction::kCCIHandleTopLevelDecl)
          //   continue;
          if (DCI.m_DGR.isNull())
            continue;

          for (DeclGroupRef::iterator J = DCI.m_DGR.begin(),
                 JE = DCI.m_DGR.end(); J != JE; ++J) {
            defaultArgsStateCollector.TrackDefaultArgStateOf(*J, m_Map, PP);
          }
        }
      }
  }

} //end namespace cling
<commit_msg>Enter here only if we are collecting autoloading checkpoints.<commit_after>//------------------------------------------------------------------------------
// CLING - the C++ LLVM-based InterpreterG :)
// author:  Manasij Mukherjee  <manasij7479@gmail.com>
// author:  Vassil Vassilev <vvasilev@cern.ch>
//
// This file is dual-licensed: you can choose to license it under the University
// of Illinois Open Source License or the GNU Lesser General Public License. See
// LICENSE.TXT for details.
//------------------------------------------------------------------------------

#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/Path.h"
#include "clang/Sema/Sema.h"
#include "clang/Basic/Diagnostic.h"
#include "clang/AST/AST.h"
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Lex/Preprocessor.h"
#include "clang/Frontend/CompilerInstance.h"

#include "cling/Interpreter/Interpreter.h"
#include "cling/Interpreter/InterpreterCallbacks.h"
#include "cling/Interpreter/AutoloadCallback.h"
#include "cling/Interpreter/Transaction.h"

using namespace clang;

namespace cling {

  void AutoloadCallback::report(clang::SourceLocation l,std::string name,std::string header) {
    Sema& sema= m_Interpreter->getSema();

    unsigned id
      = sema.getDiagnostics().getCustomDiagID (DiagnosticsEngine::Level::Warning,
                                                 "Note: '%0' can be found in %1");
/*    unsigned idn //TODO: To be enabled after we have a way to get the full path
      = sema.getDiagnostics().getCustomDiagID(DiagnosticsEngine::Level::Note,
                                                "Type : %0 , Full Path: %1")*/;

    sema.Diags.Report(l, id) << name << header;

  }

  bool AutoloadCallback::LookupObject (TagDecl *t) {
    if (t->hasAttr<AnnotateAttr>())
      report(t->getLocation(),t->getNameAsString(),t->getAttr<AnnotateAttr>()->getAnnotation());
    return false;
  }

  class DefaultArgVisitor: public RecursiveASTVisitor<DefaultArgVisitor> {
  private:
    bool m_IsStoringState;
    AutoloadCallback::FwdDeclsMap* m_Map;
    clang::Preprocessor* m_PP;
  private:
    void InsertIntoAutoloadingState (Decl* decl, std::string annotation) {

      assert(annotation != "" && "Empty annotation!");
      assert(m_PP);

      const FileEntry* FE = 0;
      SourceLocation fileNameLoc;
      bool isAngled = false;
      const DirectoryLookup* LookupFrom = 0;
      const DirectoryLookup* CurDir = 0;

      FE = m_PP->LookupFile(fileNameLoc, annotation, isAngled, LookupFrom,
                            CurDir, /*SearchPath*/0, /*RelativePath*/ 0,
                            /*suggestedModule*/0, /*SkipCache*/false,
                            /*OpenFile*/ false, /*CacheFail*/ false);

      assert(FE && "Must have a valid FileEntry");

      if (m_Map->find(FE) == m_Map->end())
        (*m_Map)[FE] = std::vector<Decl*>();

      (*m_Map)[FE].push_back(decl);
    }

  public:
    DefaultArgVisitor() : m_IsStoringState(false), m_Map(0) {}
    void RemoveDefaultArgsOf(Decl* D) {
      //D = D->getMostRecentDecl();
      TraverseDecl(D);
      //while ((D = D->getPreviousDecl()))
      //  TraverseDecl(D);
    }

    void TrackDefaultArgStateOf(Decl* D, AutoloadCallback::FwdDeclsMap& map,
                                Preprocessor& PP) {
      m_IsStoringState = true;
      m_Map = ↦
      m_PP = &PP;
      TraverseDecl(D);
      m_PP = 0;
      m_Map = 0;
      m_IsStoringState = false;
    }

    bool shouldVisitTemplateInstantiations() { return true; }
    bool TraverseTemplateTypeParmDecl(TemplateTypeParmDecl* D) {
      if (m_IsStoringState)
        return true;

      if (D->hasDefaultArgument())
        D->removeDefaultArgument();
      return true;
    }

    bool VisitDecl(Decl* D) {
      if (!m_IsStoringState)
        return true;

      if (!D->hasAttr<AnnotateAttr>())
        return false;

      AnnotateAttr* attr = D->getAttr<AnnotateAttr>();
      if (!attr)
        return true;

      switch (D->getKind()) {
      default:
        InsertIntoAutoloadingState(D, attr->getAnnotation());
        break;
      case Decl::Enum:
        // EnumDecls have extra information 2 chars after the filename used
        // for extra fixups.
        InsertIntoAutoloadingState(D, attr->getAnnotation().drop_back(2));
        break;
      }

      return true;
    }

    bool TraverseTemplateDecl(TemplateDecl* D) {
      if (!D->getTemplatedDecl()->hasAttr<AnnotateAttr>())
        return true;
      for(auto P: D->getTemplateParameters()->asArray())
        TraverseDecl(P);
      return true;
    }

    bool TraverseNonTypeTemplateParmDecl(NonTypeTemplateParmDecl* D) {
      if (m_IsStoringState)
        return true;

      if (D->hasDefaultArgument())
        D->removeDefaultArgument();
      return true;
    }

    bool TraverseParmVarDecl(ParmVarDecl* D) {
      if (m_IsStoringState)
        return true;

      if (D->hasDefaultArg())
        D->setDefaultArg(nullptr);
      return true;
    }
  };

  void AutoloadCallback::InclusionDirective(clang::SourceLocation HashLoc,
                          const clang::Token &IncludeTok,
                          llvm::StringRef FileName,
                          bool IsAngled,
                          clang::CharSourceRange FilenameRange,
                          const clang::FileEntry *File,
                          llvm::StringRef SearchPath,
                          llvm::StringRef RelativePath,
                          const clang::Module *Imported) {
    assert(File && "Must have a valid File");

    auto found = m_Map.find(File);
    if (found == m_Map.end())
     return; // nothing to do, file not referred in any annotation

    DefaultArgVisitor defaultArgsCleaner;
    for (auto D : found->second) {
      defaultArgsCleaner.RemoveDefaultArgsOf(D);
    }
    // Don't need to keep track of cleaned up decls from file.
    m_Map.erase(found);
  }

  AutoloadCallback::AutoloadCallback(Interpreter* interp) :
    InterpreterCallbacks(interp,true,false,true), m_Interpreter(interp){
//#ifdef _POSIX_C_SOURCE
//      //Workaround for differnt expansion of macros to typedefs
//      m_Interpreter->parse("#include <sys/types.h>");
//#endif
  }

  AutoloadCallback::~AutoloadCallback() {
  }

  void AutoloadCallback::TransactionCommitted(const Transaction &T) {
    if (T.decls_begin() == T.decls_end())
      return;
    if (T.decls_begin()->m_DGR.isNull())
      return;

    if (const NamedDecl* ND = dyn_cast<NamedDecl>(*T.decls_begin()->m_DGR.begin()))
      if (ND->getIdentifier() && ND->getName().equals("__Cling_Autoloading_Map")) {
        DefaultArgVisitor defaultArgsStateCollector;
        Preprocessor& PP = m_Interpreter->getCI()->getPreprocessor();
        for (Transaction::const_iterator I = T.decls_begin(), E = T.decls_end();
             I != E; ++I) {
          Transaction::DelayCallInfo DCI = *I;

          // if (DCI.m_Call != Transaction::kCCIHandleTopLevelDecl)
          //   continue;
          if (DCI.m_DGR.isNull())
            continue;

          for (DeclGroupRef::iterator J = DCI.m_DGR.begin(),
                 JE = DCI.m_DGR.end(); J != JE; ++J) {
            defaultArgsStateCollector.TrackDefaultArgStateOf(*J, m_Map, PP);
          }
        }
      }
  }

} //end namespace cling
<|endoftext|>


<commit_before>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "EC_OgreMovableTextOverlay.h"
#include "Renderer.h"
#include "OgreRenderingModule.h"

#include <Ogre.h>
#include <OgreTextAreaOverlayElement.h>
#include <OgreFontManager.h>

// Code adapted from http://www.ogre3d.org/wiki/index.php/ObjectTextDisplay and
// http://www.ogre3d.org/wiki/index.php/ObjectTitle

namespace OgreRenderer
{
    EC_OgreMovableTextOverlay::EC_OgreMovableTextOverlay(Foundation::ModuleInterface* module) :
        Foundation::ComponentInterface(module->GetFramework()),
        text_element_(NULL),
        container_(NULL),
        overlay_(NULL),
        camera_(NULL),
        font_(NULL),
        renderer_(checked_static_cast<OgreRenderingModule*>(module)->GetRenderer()),
//        char_height_(2*0.0175f),
        visible_(false),
        overlayName_(""),
        containerName_(""),
        text_("")

    {
        camera_ = renderer_.lock()->GetCurrentCamera();
        CreateOverlay();
    }

    // virtual
    EC_OgreMovableTextOverlay::~EC_OgreMovableTextOverlay()
    {
        if (!renderer_.expired())
        {
	        overlay_->hide();
	        container_->removeChild(overlayName_);
	        overlay_->remove2D(container_);

            Ogre::OverlayManager *overlayManager = Ogre::OverlayManager::getSingletonPtr();
	        overlayManager->destroyOverlayElement(text_element_);
	        overlayManager->destroyOverlayElement(container_);
	        overlayManager->destroy(overlay_);
        }
    }

    void EC_OgreMovableTextOverlay::Update()
    {
        if (!visible_)
	        return;

	    if(!node_->isInSceneGraph())
	    {
		    overlay_->hide();
		    return;
	    }

        Ogre::Vector3 point = node_->_getDerivedPosition();

	    // Is the camera facing that point? If not, hide the overlay and return.
	    Ogre::Plane cameraPlane = Ogre::Plane(Ogre::Vector3(camera_->getDerivedOrientation().zAxis()), camera_->getDerivedPosition());
	    if(cameraPlane.getSide(point) != Ogre::Plane::NEGATIVE_SIDE)
	    {
		    overlay_->hide();
		    return;
	    }

	    // Derive the 2D screen-space coordinates for that point
	    point = camera_->getProjectionMatrix() * (camera_->getViewMatrix() * point);

	    // Transform from coordinate space [-1, 1] to [0, 1]
	    float x = (point.x / 2) + 0.5f;
	    float y = 1 - ((point.y / 2) + 0.5f);

	    // Update the position (centering the text)
	    float offset = y / 9;
	    container_->setPosition(x - (textDim_.x / 2), y);
//        text_element_->setPosition(textDim_.x / 2, 0.1);

        ///\todo Scale the text and width and height of the container.

//        text_element_->setPosition(textDim_.x / 10, 0.01);
//        text_element_->setCharHeight(max_x - min_x/*2*0.0175f*///);

	    ///\todo Update container's width and height.
//        container_->setDimensions(textDim_.x, textDim_.y);
	    overlay_->show();
    }

    void EC_OgreMovableTextOverlay::SetVisible(bool visible)
    {
	    visible_ = visible;
	    if (visible)
		    overlay_->show();
	    else
		    overlay_->hide();
    }

    void EC_OgreMovableTextOverlay::SetParentNode(Ogre::SceneNode *parent_node)
    {
        parent_node->addChild(node_);
    }

    void EC_OgreMovableTextOverlay::SetText(const std::string& text)
    {
	    text_ = text;
	    text_element_->setCaption(text_);
        textDim_ = GetTextDimensions(text_);
	    container_->setDimensions(textDim_.x, textDim_.y);
    }

    void EC_OgreMovableTextOverlay::CreateOverlay()
    {
        if (renderer_.expired())
            return;

        // Create SceneNode
        Ogre::SceneManager *scene_mgr = renderer_.lock()->GetSceneManager();
        node_ = scene_mgr->createSceneNode();

        // Set the node position above the parent node.
        node_->setPosition(0, 0, 1);

	    // Overlay
	    overlayName_ = renderer_.lock()->GetUniqueObjectName();
	    overlay_ = Ogre::OverlayManager::getSingleton().create(overlayName_);

	    // Container
	    containerName_ = renderer_.lock()->GetUniqueObjectName();
	    container_ = static_cast<Ogre::OverlayContainer*>
	        (Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", containerName_));
        container_->setMaterialName("RedTransparent");
	    overlay_->add2D(container_);

	    // Font
	    ///\todo user-defined font
	    std::string fontName = "Console";
        Ogre::FontManager::getSingleton().load(fontName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
        font_ = (Ogre::Font*)Ogre::FontManager::getSingleton().getByName(fontName).getPointer();
        font_->setParameter("size", "16");

        // Overlay text
        text_element_ = checked_static_cast<Ogre::TextAreaOverlayElement*>
            (Ogre::OverlayManager::getSingleton().createOverlayElement("TextArea", overlayName_));
//	    text_element_ = Ogre::OverlayManager::getSingleton().createOverlayElement("TextArea", "shapeNameText");

        text_element_->setDimensions(0.8, 0.8);
        text_element_->setMetricsMode(Ogre::GMM_PIXELS);
        text_element_->setPosition(1, 1);
        text_element_->setParameter("font_name", fontName);
        text_element_->setParameter("char_height", font_->getParameter("size"));
//        text_element_->setCharHeight(0.035f);
        text_element_->setParameter("horz_align", "left");
	    text_element_->setColour(Ogre::ColourValue::Black);
	    container_->addChild(text_element_);

        textDim_ = GetTextDimensions(text_);
        container_->setDimensions(textDim_.x, textDim_.y);

        if (visible_)
            overlay_->show();
        else
            overlay_->hide();

        overlay_->setZOrder(500);
    }

    Ogre::Vector2 EC_OgreMovableTextOverlay::GetTextDimensions(const std::string &text)
    {
	    float charHeight = Ogre::StringConverter::parseReal(font_->getParameter("size"));

	    Ogre::Vector2 result(0, 0);

	    for(std::string::const_iterator it = text.begin(); it < text.end(); ++it)
	    {
		    if (*it == 0x0020)
			    result.x += font_->getGlyphAspectRatio(0x0030);
		    else
			    result.x += font_->getGlyphAspectRatio(*it);
	    }

	    result.x = (result.x * charHeight) / (float)camera_->getViewport()->getActualWidth();
	    result.y = charHeight / (float)camera_->getViewport()->getActualHeight();

	    return result;
    }
}
<commit_msg>Fix: If the main window is resized, the text overlay container box is resized also.<commit_after>// For conditions of distribution and use, see copyright notice in license.txt

#include "StableHeaders.h"
#include "EC_OgreMovableTextOverlay.h"
#include "Renderer.h"
#include "OgreRenderingModule.h"

#include <Ogre.h>
#include <OgreTextAreaOverlayElement.h>
#include <OgreFontManager.h>

// Code adapted from http://www.ogre3d.org/wiki/index.php/ObjectTextDisplay and
// http://www.ogre3d.org/wiki/index.php/ObjectTitle

namespace OgreRenderer
{
    EC_OgreMovableTextOverlay::EC_OgreMovableTextOverlay(Foundation::ModuleInterface* module) :
        Foundation::ComponentInterface(module->GetFramework()),
        text_element_(NULL),
        container_(NULL),
        overlay_(NULL),
        camera_(NULL),
        font_(NULL),
        renderer_(checked_static_cast<OgreRenderingModule*>(module)->GetRenderer()),
//        char_height_(2*0.0175f),
        visible_(false),
        overlayName_(""),
        containerName_(""),
        text_("")

    {
        camera_ = renderer_.lock()->GetCurrentCamera();
        CreateOverlay();
    }

    // virtual
    EC_OgreMovableTextOverlay::~EC_OgreMovableTextOverlay()
    {
        if (!renderer_.expired())
        {
	        overlay_->hide();
	        container_->removeChild(overlayName_);
	        overlay_->remove2D(container_);

            Ogre::OverlayManager *overlayManager = Ogre::OverlayManager::getSingletonPtr();
	        overlayManager->destroyOverlayElement(text_element_);
	        overlayManager->destroyOverlayElement(container_);
	        overlayManager->destroy(overlay_);
        }
    }

    void EC_OgreMovableTextOverlay::Update()
    {
        if (!visible_)
	        return;

	    if(!node_->isInSceneGraph())
	    {
		    overlay_->hide();
		    return;
	    }

        Ogre::Vector3 point = node_->_getDerivedPosition();

	    // Is the camera facing that point? If not, hide the overlay and return.
	    Ogre::Plane cameraPlane = Ogre::Plane(Ogre::Vector3(camera_->getDerivedOrientation().zAxis()), camera_->getDerivedPosition());
	    if(cameraPlane.getSide(point) != Ogre::Plane::NEGATIVE_SIDE)
	    {
		    overlay_->hide();
		    return;
	    }

	    // Derive the 2D screen-space coordinates for that point
	    point = camera_->getProjectionMatrix() * (camera_->getViewMatrix() * point);

	    // Transform from coordinate space [-1, 1] to [0, 1]
	    float x = (point.x / 2) + 0.5f;
	    float y = 1 - ((point.y / 2) + 0.5f);

	    // Update the position (centering the text)
	    container_->setPosition(x - (textDim_.x / 2), y);

        // Update the dimensions also, in case that the window is resized.
	    textDim_ = GetTextDimensions(text_);
	    container_->setDimensions(textDim_.x, textDim_.y);

        ///\todo Scale the text and width and height of the container?
//        text_element_->setMetricsMode(Ogre::GMM_RELATIVE);
//        text_element_->setPosition(textDim_.x, textDim_.y);
//        text_element_->setPosition(textDim_.x / 10, 0.01);
//        text_element_->setCharHeight(max_x - min_x/*2*0.0175f*///);

	    overlay_->show();
    }

    void EC_OgreMovableTextOverlay::SetVisible(bool visible)
    {
	    visible_ = visible;
	    if (visible)
		    overlay_->show();
	    else
		    overlay_->hide();
    }

    void EC_OgreMovableTextOverlay::SetParentNode(Ogre::SceneNode *parent_node)
    {
        parent_node->addChild(node_);
    }

    void EC_OgreMovableTextOverlay::SetText(const std::string& text)
    {
	    text_ = text;
	    text_element_->setCaption(text_);
        textDim_ = GetTextDimensions(text_);
	    container_->setDimensions(textDim_.x, textDim_.y);
    }

    void EC_OgreMovableTextOverlay::CreateOverlay()
    {
        if (renderer_.expired())
            return;

        // Create SceneNode
        Ogre::SceneManager *scene_mgr = renderer_.lock()->GetSceneManager();
        node_ = scene_mgr->createSceneNode();

        // Set the node position above the parent node.
        node_->setPosition(0, 0, 1);

	    // Overlay
	    overlayName_ = renderer_.lock()->GetUniqueObjectName();
	    overlay_ = Ogre::OverlayManager::getSingleton().create(overlayName_);

	    // Container
	    containerName_ = renderer_.lock()->GetUniqueObjectName();
	    container_ = static_cast<Ogre::OverlayContainer*>
	        (Ogre::OverlayManager::getSingleton().createOverlayElement("Panel", containerName_));
        container_->setMaterialName("RedTransparent");
	    overlay_->add2D(container_);

	    // Font
	    ///\todo user-defined font
	    std::string fontName = "Console";
        Ogre::FontManager::getSingleton().load(fontName, Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME);
        font_ = (Ogre::Font*)Ogre::FontManager::getSingleton().getByName(fontName).getPointer();
        font_->setParameter("size", "16");

        // Overlay text
        text_element_ = checked_static_cast<Ogre::TextAreaOverlayElement*>
            (Ogre::OverlayManager::getSingleton().createOverlayElement("TextArea", overlayName_));
//	    text_element_ = Ogre::OverlayManager::getSingleton().createOverlayElement("TextArea", "shapeNameText");

        text_element_->setDimensions(0.8, 0.8);
        text_element_->setMetricsMode(Ogre::GMM_PIXELS);
        text_element_->setPosition(1, 2);
        text_element_->setParameter("font_name", fontName);
        text_element_->setParameter("char_height", font_->getParameter("size"));
//        text_element_->setCharHeight(0.035f);
        text_element_->setParameter("horz_align", "left");
	    text_element_->setColour(Ogre::ColourValue::Black);
	    container_->addChild(text_element_);

        textDim_ = GetTextDimensions(text_);
        container_->setDimensions(textDim_.x, textDim_.y);

        if (visible_)
            overlay_->show();
        else
            overlay_->hide();

        overlay_->setZOrder(500);
    }

    Ogre::Vector2 EC_OgreMovableTextOverlay::GetTextDimensions(const std::string &text)
    {
	    float charHeight = Ogre::StringConverter::parseReal(font_->getParameter("size"));

	    Ogre::Vector2 result(0, 0);

	    for(std::string::const_iterator it = text.begin(); it < text.end(); ++it)
	    {
		    if (*it == 0x0020)
			    result.x += font_->getGlyphAspectRatio(0x0030);
		    else
			    result.x += font_->getGlyphAspectRatio(*it);
	    }

	    result.x = (result.x * charHeight) / (float)camera_->getViewport()->getActualWidth();
	    result.y = charHeight / (float)camera_->getViewport()->getActualHeight();

	    return result;
    }
}
<|endoftext|>


<commit_before>//Create by Christine Nattrass, Rebecca Scott, Irakli Martashvili
//University of Tennessee at Knoxville

//by default this runs locally
//With the argument true this submits jobs to the grid
//As written this requires an xml script tag.xml in the ~/et directory on the grid to submit jobs
void runCaloEt(bool submit = false, // true or false
	       const char *dataType="realPbPb", // "sim" or "real" etc.
	       const char *pluginRunMode="test", // "test" or "full" or "terminate"
	       const char *det = "PHOS") // "PHOS" or "EMCAL" or EMCalDetail
{
  TStopwatch timer;
  timer.Start();
  gSystem->Load("libTree");
  gSystem->Load("libGeom");
  gSystem->Load("libVMC");
  gSystem->Load("libPhysics");
  gSystem->Load("libMinuit");

  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
  gSystem->AddIncludePath("-I. -I$ALICE_ROOT/EMCAL -I$ALICE_ROOT/ANALYSIS");

  gSystem->Load("libSTEERBase");
  gSystem->Load("libESD");
  gSystem->Load("libAOD");

  gSystem->Load("libANALYSIS");
  gSystem->Load("libANALYSISalice");
  gSystem->Load("libCORRFW");

  if (!submit) {
    cout << "local - no submitting" << endl;
  }
  else {
    cout << "submitting to grid" << endl;
  }

  gROOT->ProcessLine(".L AliAnalysisEtCuts.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisHadEtCorrections.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtCommon.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtSelector.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtSelectorPhos.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtSelectorEmcal.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEt.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtMonteCarlo.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtMonteCarloPhos.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtMonteCarloEmcal.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtReconstructed.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtReconstructedPhos.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtReconstructedEmcal.cxx+g");
  //gROOT->ProcessLine(".L AliAnalysisEtSelectionContainer.cxx+g");
  //gROOT->ProcessLine(".L AliAnalysisEtSelectionHandler.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisTaskTransverseEnergy.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEmEtMonteCarlo.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEmEtReconstructed.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisTaskTotEt.cxx+g");

  char *kTreeName = "esdTree" ;
  TChain * chain   = new TChain(kTreeName,"myESDTree") ;

  if(submit){
    gSystem->Load("libNetx") ;
    gSystem->Load("libgapiUI");
    gSystem->Load("libRAliEn");
    TGrid::Connect("alien://") ;
  }

  // Make the analysis manager
  AliAnalysisManager *mgr = new AliAnalysisManager("TotEtManager");

  TString detStr(det);
  TString taskName = "TaskTotEt" + detStr;
  TString dataStr(dataType);
  TString dataStrName(dataType);
  dataStrName.ReplaceAll("/",".");
  TString outputName = "Et.ESD." + dataStrName + "." + detStr + ".root";
  TString outputDir = "totEt" + dataStr;

  cout << " taskName " << taskName
       << " outputName " << outputName
       << " outputDir (alien) " << outputDir << endl;
  mgr->SetCommonFileName(outputName.Data());
  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("out1", TList::Class(), AliAnalysisManager::kOutputContainer, outputName);
  if (submit) {
    gROOT->LoadMacro("CreateAlienHandlerCaloEtSim.C");
    AliAnalysisGrid *alienHandler = CreateAlienHandlerCaloEtSim(outputDir, outputName, pluginRunMode);
    if (!alienHandler) return;
    mgr->SetGridHandler(alienHandler);
  }

  AliVEventHandler* esdH = new AliESDInputHandler;
  mgr->SetInputEventHandler(esdH);
  AliMCEventHandler* handler = new AliMCEventHandler;
  Bool_t isMc = kTRUE;
  Bool_t isPb = kFALSE;
  if ( dataStr.Contains("PbPb") ) { isPb = kTRUE;}
  if ( dataStr.Contains("sim") ) {
    cout << " MC " << endl;
    if ( dataStr.Contains("PbPb") ) { // a la: simPbPb/LHC10e18a
      cout << " PbPb " << endl;
      TString fileLocation = "/home/dsilverm/data/E_T/" + dataStr + "/dir/AliESDs.root";
      cout << "fileLocation " << fileLocation.Data() << endl;
      chain->Add(fileLocation.Data()); // link to local test file
    }
    else { // pp
      cout<<"adding pp simulation file"<<endl;
      chain->Add("/data/LHC10d15/1821/AliESDs.root");
      //chain->Add("/data/LHC10dpass2/10000126403050.70/AliESDs.root");//data
      //chain->Add("/home/dsilverm/data/E_T/sim/LHC10d1/117222/100/AliESDs.root"); // link to local test file
    }
    handler->SetReadTR(kFALSE);
    mgr->SetMCtruthEventHandler(handler);
  }
  else { // real data
    isMc = kFALSE;
    chain->Add("/data/LHC10dpass2/10000126403050.70/AliESDs.root");//data
    //chain->Add("/home/dsilverm/data/E_T/data/2010/LHC10b/000117222/ESDs/pass2/10000117222021.30/AliESDs.root"); // link to local test file
    cout << " not MC " << endl;
  }

  if(!isMc && detStr.Contains("EMC")){
    cout<<"You are running over EMCal data and using the tender supply"<<endl;
    gSystem->Load("libTENDER.so");
    gSystem->Load("libTENDERSupplies.so");
    gROOT->ProcessLine(".include $ALICE_ROOT/Tender/");
    gSystem->AddIncludePath("-I$ALICE_ROOT/ANALYSIS ");

    //this macro is downloaded from the EMCal tender supply twiki
    //hopefully it will be replaced by something checked in to aliroot
    //I have added the function from GetOCDBRecParam.C in Jiri's example to this so that we don't add gobs of macros to the code
    //I set the defaults to the golden run for PbPb because we are focusing on the golden run, however, this should be thought through!!
    gROOT->LoadMacro("AddTaskEMCALTenderForEtAnalysis.C");
    cout<<"WARNING: YOU ARE USING CALIBRATION FACTORS FROM PbPb RUN 137161!!"<<endl;
//  	// get reco params from grid OCDB
//    gROOT->LoadMacro("./GetOCDBRecParam.C");
//  	// run num, data type pp/PbPb, from grid
//Gets calibration factors from grid if jobs are to be submitted to the grid
  	AliEMCALRecParam* pars = GetOCDBRecParam( 137161, "PbPb", submit);

    AliTender *tender = AddTaskEMCALTender( "EMCAL_COMPLETEV1", 0);
    //this also likely needs modification
    tender->SelectCollisionCandidates( AliVEvent::kMB | AliVEvent::kEMCEGA | AliVEvent::kEMC1 | AliVEvent::kEMC7 );
    if(submit){tender->SetDefaultCDBStorage("raw://");} //uncomment if you work on grid
    else{tender->SetDefaultCDBStorage("local://$ALICE_ROOT/OCDB");} //uncomment if you work local

    if(submit){
      cout<<"Setting tender to run on grid"<<endl;
      tender->SetDefaultCDBStorage("raw://"); //uncomment if you work on grid
    }
    else{
      cout<<"Setting tender to run locally"<<endl;
      tender->SetDefaultCDBStorage("local://$ALICE_ROOT/OCDB"); //uncomment if you work local
    }
    // one can sellect what collision candidates to use
    // triggered sample only: L1 = AliVEvent::kEMCEGA, AliVEvent::kEMCEJE; L0 = AliVEvent::kEMC1, AliVEvent::kEMC7
    tender->SelectCollisionCandidates( AliVEvent::kAny );
    tender->SetDebugLevel(2);

    //AliAnalysisDataContainer *coutput3 = mgr->CreateContainer("histosTrgContam", TList::Class(), AliAnalysisManager::kOutputContainer,"AnalysisResults.root");
    //mgr->ConnectOutput(tender,1,coutput3);
    cout<<"Output container name "<<AliAnalysisManager::GetCommonFileName()<<endl;
  }

  if(isMc) cout<<"I am a MC"<<endl;
  gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");

  AliPhysicsSelectionTask *physicsSelectionTask = AddTaskPhysicsSelection(isMc);//isMC is true when processing monte carlo
  if(isPb){
    cout<<"Adding centrality selection task"<<endl;
    gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
    //gROOT->ProcessLine(".L AliCentralitySelectionTask.cxx++g");
    AliCentralitySelectionTask *centTask = AddTaskCentrality();
  }

  AliAnalysisDataContainer *cinput1 = mgr->GetCommonInputContainer();

  AliAnalysisTaskTotEt *task1 = new AliAnalysisTaskTotEt(taskName);
  task1->SetMcData(isMc);//necessary to tell the task to basically accept all MC events.
  mgr->AddTask(task1);

  //____________________________________________//
  mgr->ConnectInput(task1,0,cinput1);
  mgr->ConnectOutput(task1,1,coutput1);

  mgr->SetDebugLevel(0);

  if (!mgr->InitAnalysis()) return;
  mgr->PrintStatus();
  if(submit){
    mgr->StartAnalysis("grid");
  }
  else{
    mgr->StartAnalysis("local",chain);
  }

  timer.Stop();
  timer.Print();
}
<commit_msg>Adding lines to compile new classes<commit_after>//Create by Christine Nattrass, Rebecca Scott, Irakli Martashvili
//University of Tennessee at Knoxville

//by default this runs locally
//With the argument true this submits jobs to the grid
//As written this requires an xml script tag.xml in the ~/et directory on the grid to submit jobs
void runCaloEt(bool submit = false, // true or false
	       const char *dataType="realPbPb", // "sim" or "real" etc.
	       const char *pluginRunMode="test", // "test" or "full" or "terminate"
	       const char *det = "EMCalDetail") // "PHOS" or "EMCAL" or EMCalDetail
{
  TStopwatch timer;
  timer.Start();
  gSystem->Load("libTree");
  gSystem->Load("libGeom");
  gSystem->Load("libVMC");
  gSystem->Load("libPhysics");
  gSystem->Load("libMinuit");

  gSystem->AddIncludePath("-I$ALICE_ROOT/include");
  gSystem->AddIncludePath("-I. -I$ALICE_ROOT/EMCAL -I$ALICE_ROOT/ANALYSIS");

  gSystem->Load("libSTEERBase");
  gSystem->Load("libESD");
  gSystem->Load("libAOD");

  gSystem->Load("libANALYSIS");
  gSystem->Load("libANALYSISalice");
  gSystem->Load("libCORRFW");

  if (!submit) {
    cout << "local - no submitting" << endl;
  }
  else {
    cout << "submitting to grid" << endl;
  }

  gROOT->ProcessLine(".L AliAnalysisEtCuts.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisHadEtCorrections.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtCommon.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtSelector.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtSelectorPhos.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtSelectorEmcal.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtTrackMatchCorrections.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtRecEffCorrection.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEt.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtMonteCarlo.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtMonteCarloPhos.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtMonteCarloEmcal.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtReconstructed.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtReconstructedPhos.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEtReconstructedEmcal.cxx+g");
  //gROOT->ProcessLine(".L AliAnalysisEtSelectionContainer.cxx+g");
  //gROOT->ProcessLine(".L AliAnalysisEtSelectionHandler.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisTaskTransverseEnergy.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEmEtMonteCarlo.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisEmEtReconstructed.cxx+g");
  gROOT->ProcessLine(".L AliAnalysisTaskTotEt.cxx+g");

  char *kTreeName = "esdTree" ;
  TChain * chain   = new TChain(kTreeName,"myESDTree") ;

  if(submit){
    gSystem->Load("libNetx") ;
    gSystem->Load("libgapiUI");
    gSystem->Load("libRAliEn");
    TGrid::Connect("alien://") ;
  }

  // Make the analysis manager
  AliAnalysisManager *mgr = new AliAnalysisManager("TotEtManager");

  TString detStr(det);
  TString taskName = "TaskTotEt" + detStr;
  TString dataStr(dataType);
  TString dataStrName(dataType);
  dataStrName.ReplaceAll("/",".");
  TString outputName = "Et.ESD." + dataStrName + "." + detStr + ".root";
  TString outputDir = "totEt" + dataStr;

  cout << " taskName " << taskName
       << " outputName " << outputName
       << " outputDir (alien) " << outputDir << endl;
  mgr->SetCommonFileName(outputName.Data());
  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer("out1", TList::Class(), AliAnalysisManager::kOutputContainer, outputName);
  if (submit) {
    gROOT->LoadMacro("CreateAlienHandlerCaloEtSim.C");
    AliAnalysisGrid *alienHandler = CreateAlienHandlerCaloEtSim(outputDir, outputName, pluginRunMode);
    if (!alienHandler) return;
    mgr->SetGridHandler(alienHandler);
  }

  AliVEventHandler* esdH = new AliESDInputHandler;
  mgr->SetInputEventHandler(esdH);
  AliMCEventHandler* handler = new AliMCEventHandler;
  Bool_t isMc = kTRUE;
  Bool_t isPb = kFALSE;
  if ( dataStr.Contains("PbPb") ) { isPb = kTRUE;}
  if ( dataStr.Contains("sim") ) {
    cout << " MC " << endl;
    if ( dataStr.Contains("PbPb") ) { // a la: simPbPb/LHC10e18a
      cout << " PbPb " << endl;
      TString fileLocation = "/home/dsilverm/data/E_T/" + dataStr + "/dir/AliESDs.root";
      cout << "fileLocation " << fileLocation.Data() << endl;
      chain->Add(fileLocation.Data()); // link to local test file
    }
    else { // pp
      cout<<"adding pp simulation file"<<endl;
      chain->Add("/data/LHC10d15/1821/AliESDs.root");
      //chain->Add("/data/LHC10dpass2/10000126403050.70/AliESDs.root");//data
      //chain->Add("/home/dsilverm/data/E_T/sim/LHC10d1/117222/100/AliESDs.root"); // link to local test file
    }
    handler->SetReadTR(kFALSE);
    mgr->SetMCtruthEventHandler(handler);
  }
  else { // real data
    isMc = kFALSE;
    chain->Add("/data/LHC10dpass2/10000126403050.70/AliESDs.root");//data
    //chain->Add("/home/dsilverm/data/E_T/data/2010/LHC10b/000117222/ESDs/pass2/10000117222021.30/AliESDs.root"); // link to local test file
    cout << " not MC " << endl;
  }

  if(!isMc && detStr.Contains("EMC")){
    cout<<"You are running over EMCal data and using the tender supply"<<endl;
    gSystem->Load("libTENDER.so");
    gSystem->Load("libTENDERSupplies.so");
    gROOT->ProcessLine(".include $ALICE_ROOT/Tender/");
    gSystem->AddIncludePath("-I$ALICE_ROOT/ANALYSIS ");

    //this macro is downloaded from the EMCal tender supply twiki
    //hopefully it will be replaced by something checked in to aliroot
    //I have added the function from GetOCDBRecParam.C in Jiri's example to this so that we don't add gobs of macros to the code
    //I set the defaults to the golden run for PbPb because we are focusing on the golden run, however, this should be thought through!!
    gROOT->LoadMacro("AddTaskEMCALTenderForEtAnalysis.C");
    cout<<"WARNING: YOU ARE USING CALIBRATION FACTORS FROM PbPb RUN 137161!!"<<endl;
//  	// get reco params from grid OCDB
//    gROOT->LoadMacro("./GetOCDBRecParam.C");
//  	// run num, data type pp/PbPb, from grid
//Gets calibration factors from grid if jobs are to be submitted to the grid
  	AliEMCALRecParam* pars = GetOCDBRecParam( 137161, "PbPb", submit);

    AliTender *tender = AddTaskEMCALTender( "EMCAL_COMPLETEV1", 0);
    //this also likely needs modification
    tender->SelectCollisionCandidates( AliVEvent::kMB | AliVEvent::kEMCEGA | AliVEvent::kEMC1 | AliVEvent::kEMC7 );
    if(submit){tender->SetDefaultCDBStorage("raw://");} //uncomment if you work on grid
    else{tender->SetDefaultCDBStorage("local://$ALICE_ROOT/OCDB");} //uncomment if you work local

    if(submit){
      cout<<"Setting tender to run on grid"<<endl;
      tender->SetDefaultCDBStorage("raw://"); //uncomment if you work on grid
    }
    else{
      cout<<"Setting tender to run locally"<<endl;
      tender->SetDefaultCDBStorage("local://$ALICE_ROOT/OCDB"); //uncomment if you work local
    }
    // one can sellect what collision candidates to use
    // triggered sample only: L1 = AliVEvent::kEMCEGA, AliVEvent::kEMCEJE; L0 = AliVEvent::kEMC1, AliVEvent::kEMC7
    tender->SelectCollisionCandidates( AliVEvent::kAny );
    tender->SetDebugLevel(2);

    //AliAnalysisDataContainer *coutput3 = mgr->CreateContainer("histosTrgContam", TList::Class(), AliAnalysisManager::kOutputContainer,"AnalysisResults.root");
    //mgr->ConnectOutput(tender,1,coutput3);
    cout<<"Output container name "<<AliAnalysisManager::GetCommonFileName()<<endl;
  }

  if(isMc) cout<<"I am a MC"<<endl;
  gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskPhysicsSelection.C");

  AliPhysicsSelectionTask *physicsSelectionTask = AddTaskPhysicsSelection(isMc);//isMC is true when processing monte carlo
  if(isPb){
    cout<<"Adding centrality selection task"<<endl;
    gROOT->ProcessLine(".L $ALICE_ROOT/ANALYSIS/macros/AddTaskCentrality.C");
    //gROOT->ProcessLine(".L AliCentralitySelectionTask.cxx++g");
    AliCentralitySelectionTask *centTask = AddTaskCentrality();
  }

  AliAnalysisDataContainer *cinput1 = mgr->GetCommonInputContainer();

  AliAnalysisTaskTotEt *task1 = new AliAnalysisTaskTotEt(taskName);
  task1->SetMcData(isMc);//necessary to tell the task to basically accept all MC events.
  mgr->AddTask(task1);

  //____________________________________________//
  mgr->ConnectInput(task1,0,cinput1);
  mgr->ConnectOutput(task1,1,coutput1);

  mgr->SetDebugLevel(0);

  if (!mgr->InitAnalysis()) return;
  mgr->PrintStatus();
  if(submit){
    mgr->StartAnalysis("grid");
  }
  else{
    mgr->StartAnalysis("local",chain);
  }

  timer.Stop();
  timer.Print();
}
<|endoftext|>


<commit_before>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "dll/neural/conv_layer.hpp"
#include "dll/neural/dense_layer.hpp"
#include "dll/pooling/mp_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/datasets.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

int main(int /*argc*/, char* /*argv*/ []) {
    // Load the dataset
    auto dataset = dll::make_mnist_dataset(0, dll::batch_size<100>{}, dll::scale_pre<255>{});

    // Build the network

    using network_t = dll::dyn_dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 8, 5, 5>::layer_t,
            dll::mp_layer_2d_desc<8, 24, 24, 2, 2>::layer_t,
            dll::conv_desc<8, 12, 12, 8, 5, 5>::layer_t,
            dll::mp_layer_2d_desc<8, 8, 8, 2, 2>::layer_t,
            dll::dense_desc<8 * 4 * 4, 150>::layer_t,
            dll::dense_desc<150, 10, dll::activation<dll::function::SOFTMAX>>::layer_t>
        , dll::updater<dll::updater_type::MOMENTUM>     // Momentum
        , dll::batch_size<100>                          // The mini-batch size
        , dll::shuffle                                  // Shuffle the dataset before each epoch
    >::dbn_t;

    auto net = std::make_unique<network_t>();

    net->learning_rate = 0.1;

    // Display the network and dataset
    net->display();
    dataset.display();

    // Train the network for performance sake
    net->fine_tune(dataset.train(), 25);

    // Test the network on test set
    net->evaluate(dataset.test());

    cpp_unused(dataset);

    return 0;
}
<commit_msg>Review example<commit_after>//=======================================================================
// Copyright (c) 2014-2017 Baptiste Wicht
// Distributed under the terms of the MIT License.
// (See accompanying file LICENSE or copy at
//  http://opensource.org/licenses/MIT)
//=======================================================================

#include "dll/neural/conv_layer.hpp"
#include "dll/neural/dense_layer.hpp"
#include "dll/pooling/mp_layer.hpp"
#include "dll/dbn.hpp"
#include "dll/datasets.hpp"

#include "mnist/mnist_reader.hpp"
#include "mnist/mnist_utils.hpp"

int main(int /*argc*/, char* /*argv*/ []) {
    // Load the dataset
    auto dataset = dll::make_mnist_dataset(0, dll::batch_size<100>{}, dll::scale_pre<255>{});

    // Build the network

    using network_t = dll::dyn_dbn_desc<
        dll::dbn_layers<
            dll::conv_desc<1, 28, 28, 8, 5, 5>::layer_t,
            dll::mp_layer_2d_desc<8, 24, 24, 2, 2>::layer_t,
            dll::conv_desc<8, 12, 12, 8, 5, 5>::layer_t,
            dll::mp_layer_2d_desc<8, 8, 8, 2, 2>::layer_t,
            dll::dense_desc<8 * 4 * 4, 150>::layer_t,
            dll::dense_desc<150, 10, dll::activation<dll::function::SOFTMAX>>::layer_t>
        , dll::updater<dll::updater_type::MOMENTUM>     // Momentum
        , dll::batch_size<100>                          // The mini-batch size
        , dll::shuffle                                  // Shuffle the dataset before each epoch
    >::dbn_t;

    auto net = std::make_unique<network_t>();

    net->learning_rate = 0.1;

    // Display the network and dataset
    net->display();
    dataset.display();

    // Train the network
    net->fine_tune(dataset.train(), 25);

    // Test the network on test set
    net->evaluate(dataset.test());

    cpp_unused(dataset);

    return 0;
}
<|endoftext|>


<commit_before>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "ExecutionContext.h"

#include "cling/Interpreter/StoredValueRef.h"

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/DynamicLibrary.h"

using namespace cling;

namespace {
  class JITtedFunctionCollector : public llvm::JITEventListener {
  private:
    llvm::SmallVector<llvm::Function*, 24> m_functions;
    llvm::ExecutionEngine *m_engine;

  public:
    JITtedFunctionCollector(): m_functions(), m_engine(0) { }
    virtual ~JITtedFunctionCollector() { }

    virtual void NotifyFunctionEmitted(const llvm::Function& F, void *, size_t,
                              const JITEventListener::EmittedFunctionDetails&) {
      m_functions.push_back(const_cast<llvm::Function *>(&F));
    }
    virtual void NotifyFreeingMachineCode(void* /*OldPtr*/) {}

    void UnregisterFunctionMapping(llvm::ExecutionEngine&);
  };
}

void JITtedFunctionCollector::UnregisterFunctionMapping(
                                                  llvm::ExecutionEngine &engine)
{
  for (llvm::SmallVectorImpl<llvm::Function *>::reverse_iterator
         it = m_functions.rbegin(), et = m_functions.rend();
       it != et; ++it) {
    llvm::Function *ff = *it;
    engine.freeMachineCodeForFunction(ff);
    engine.updateGlobalMapping(ff, 0);
  }
  m_functions.clear();
}

std::set<std::string> ExecutionContext::m_unresolvedSymbols;
std::vector<ExecutionContext::LazyFunctionCreatorFunc_t>
  ExecutionContext::m_lazyFuncCreator;

bool ExecutionContext::m_LazyFuncCreatorEnabled = true;

ExecutionContext::ExecutionContext():
  m_engine(0),
  m_RunningStaticInits(false),
  m_CxaAtExitRemapped(false)
{
}

void
ExecutionContext::InitializeBuilder(llvm::Module* m)
{
  //
  //  Create an execution engine to use.
  //
  // Note: Engine takes ownership of the module.
  assert(m && "Module cannot be null");

  llvm::EngineBuilder builder(m);
  builder.setOptLevel(llvm::CodeGenOpt::Less);
  std::string errMsg;
  builder.setErrorStr(&errMsg);
  builder.setEngineKind(llvm::EngineKind::JIT);
  builder.setAllocateGVsWithCode(false);
  m_engine = builder.create();
  assert(m_engine && "Cannot initialize builder without module!");

  //m_engine->addModule(m); // Note: The engine takes ownership of the module.

  // install lazy function
  m_engine->InstallLazyFunctionCreator(NotifyLazyFunctionCreators);
}

ExecutionContext::~ExecutionContext()
{
}

void unresolvedSymbol()
{
  // throw exception?
  llvm::errs() << "ExecutionContext: calling unresolved symbol (should never happen)!\n";
}

void* ExecutionContext::HandleMissingFunction(const std::string& mangled_name)
{
  // Not found in the map, add the symbol in the list of unresolved symbols
  if (m_unresolvedSymbols.insert(mangled_name).second) {
    llvm::errs() << "ExecutionContext: use of undefined symbol '"
                 << mangled_name << "'!\n";
  }

  // Avoid "ISO C++ forbids casting between pointer-to-function and
  // pointer-to-object":
  return (void*)reinterpret_cast<size_t>(unresolvedSymbol);
}

void*
ExecutionContext::NotifyLazyFunctionCreators(const std::string& mangled_name)
{
  if (!m_LazyFuncCreatorEnabled)
    return 0;

  for (std::vector<LazyFunctionCreatorFunc_t>::iterator it
         = m_lazyFuncCreator.begin(), et = m_lazyFuncCreator.end();
       it != et; ++it) {
    void* ret = (void*)((LazyFunctionCreatorFunc_t)*it)(mangled_name);
    if (ret) return ret;
  }
  return HandleMissingFunction(mangled_name);
}

void
ExecutionContext::executeFunction(llvm::StringRef funcname,
                                  const clang::ASTContext& Ctx,
                                  clang::QualType retType,
                                  StoredValueRef* returnValue)
{
  // Call a function without arguments, or with an SRet argument, see SRet below

  if (!m_CxaAtExitRemapped) {
    // Rewire atexit:
    llvm::Function* atExit = m_engine->FindFunctionNamed("__cxa_atexit");
    llvm::Function* clingAtExit = m_engine->FindFunctionNamed("cling_cxa_atexit");
    if (atExit && clingAtExit) {
      void* clingAtExitAddr = m_engine->getPointerToFunction(clingAtExit);
      assert(clingAtExitAddr && "cannot find cling_cxa_atexit");
      m_engine->updateGlobalMapping(atExit, clingAtExitAddr);
      m_CxaAtExitRemapped = true;
    }
  }

  // We don't care whether something was unresolved before.
  m_unresolvedSymbols.clear();

  llvm::Function* f = m_engine->FindFunctionNamed(funcname.data());
  if (!f) {
    llvm::errs() << "ExecutionContext::executeFunction: could not find function named " << funcname << '\n';
    return;
  }
  JITtedFunctionCollector listener;
  // register the listener
  m_engine->RegisterJITEventListener(&listener);
  m_engine->getPointerToFunction(f);
  // check if there is any unresolved symbol in the list
  if (!m_unresolvedSymbols.empty()) {
    for (std::set<std::string>::const_iterator i = m_unresolvedSymbols.begin(),
           e = m_unresolvedSymbols.end(); i != e; ++i) {
      llvm::errs() << "ExecutionContext::executeFunction: symbol \'" << *i << "\' unresolved!\n";
      llvm::Function *ff = m_engine->FindFunctionNamed(i->c_str());
      assert(ff && "cannot find function to free");
      m_engine->updateGlobalMapping(ff, 0);
      m_engine->freeMachineCodeForFunction(ff);
    }
    m_unresolvedSymbols.clear();
    // cleanup functions
    listener.UnregisterFunctionMapping(*m_engine);
    m_engine->UnregisterJITEventListener(&listener);
    return;
  }
  // cleanup list and unregister our listener
  m_engine->UnregisterJITEventListener(&listener);

  std::vector<llvm::GenericValue> args;
  bool wantReturn = (returnValue);
  StoredValueRef aggregateRet;

  if (f->hasStructRetAttr()) {
    // Function expects to receive the storage for the returned aggregate as
    // first argument. Allocate returnValue:
    aggregateRet = StoredValueRef::allocate(Ctx, retType);
    if (returnValue) {
      *returnValue = aggregateRet;
    } else {
      returnValue = &aggregateRet;
    }
    args.push_back(returnValue->get().value);
    // will get set as arg0, must not assign.
    wantReturn = false;
  }

  if (wantReturn) {
    llvm::GenericValue gvRet = m_engine->runFunction(f, args);
    // rescue the ret value (which might be aggregate) from the stack
    *returnValue = StoredValueRef::bitwiseCopy(Ctx, Value(gvRet, retType));
  } else {
    m_engine->runFunction(f, args);
  }

  m_engine->freeMachineCodeForFunction(f);
}

void
ExecutionContext::runStaticInitializersOnce(llvm::Module* m) {
  assert(m && "Module must not be null");

  if (!m_engine)
    InitializeBuilder(m);

  assert(m_engine && "Code generation did not create an engine!");

  if (!m_RunningStaticInits) {
    m_RunningStaticInits = true;

    llvm::GlobalVariable* gctors
      = m->getGlobalVariable("llvm.global_ctors", true);
    if (gctors) {
      m_engine->runStaticConstructorsDestructors(false);
      gctors->eraseFromParent();
    }

    m_RunningStaticInits = false;
  }
}

void
ExecutionContext::runStaticDestructorsOnce(llvm::Module* m) {
  assert(m && "Module must not be null");
  assert(m_engine && "Code generation did not create an engine!");

  llvm::GlobalVariable* gdtors
    = m->getGlobalVariable("llvm.global_dtors", true);
  if (gdtors) {
    m_engine->runStaticConstructorsDestructors(true);
  }

}

int
ExecutionContext::verifyModule(llvm::Module* m)
{
  //
  //  Verify generated module.
  //
  bool mod_has_errs = llvm::verifyModule(*m, llvm::PrintMessageAction);
  if (mod_has_errs) {
    return 1;
  }
  return 0;
}

void
ExecutionContext::printModule(llvm::Module* m)
{
  //
  //  Print module LLVM code in human-readable form.
  //
  llvm::PassManager PM;
  PM.add(llvm::createPrintModulePass(&llvm::outs()));
  PM.run(*m);
}

void
ExecutionContext::installLazyFunctionCreator(LazyFunctionCreatorFunc_t fp)
{
  m_lazyFuncCreator.push_back(fp);
}

bool ExecutionContext::addSymbol(const char* symbolName,  void* symbolAddress) {

  void* actualAddress
    = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(symbolName);
  if (actualAddress)
    return false;

  llvm::sys::DynamicLibrary::AddSymbol(symbolName, symbolAddress);
  return true;
}

void* ExecutionContext::getAddressOfGlobal(llvm::Module* m,
                                           const char* symbolName,
                                           bool* fromJIT /*=0*/) const {
    // Return a symbol's address, and whether it was jitted.
    void* address
      = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(symbolName);
    if (address) {
      if (fromJIT) *fromJIT = false;
    } else {
      if (fromJIT) *fromJIT = true;
      llvm::GlobalVariable* gvar
        = m->getGlobalVariable(symbolName, true);
      if (!gvar)
        return 0;

      address = m_engine->getPointerToGlobal(gvar);
    }
    return address;
  }
<commit_msg>Give a chance to the eventual lazy function creators to do their job. (Thanks Philippe)<commit_after>//--------------------------------------------------------------------*- C++ -*-
// CLING - the C++ LLVM-based InterpreterG :)
// version: $Id$
// author:  Axel Naumann <axel@cern.ch>
//------------------------------------------------------------------------------

#include "ExecutionContext.h"

#include "cling/Interpreter/StoredValueRef.h"

#include "llvm/Module.h"
#include "llvm/PassManager.h"
#include "llvm/Analysis/Verifier.h"
#include "llvm/Assembly/PrintModulePass.h"
#include "llvm/ExecutionEngine/JIT.h"
#include "llvm/ExecutionEngine/JITEventListener.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/DynamicLibrary.h"

using namespace cling;

namespace {
  class JITtedFunctionCollector : public llvm::JITEventListener {
  private:
    llvm::SmallVector<llvm::Function*, 24> m_functions;
    llvm::ExecutionEngine *m_engine;

  public:
    JITtedFunctionCollector(): m_functions(), m_engine(0) { }
    virtual ~JITtedFunctionCollector() { }

    virtual void NotifyFunctionEmitted(const llvm::Function& F, void *, size_t,
                              const JITEventListener::EmittedFunctionDetails&) {
      m_functions.push_back(const_cast<llvm::Function *>(&F));
    }
    virtual void NotifyFreeingMachineCode(void* /*OldPtr*/) {}

    void UnregisterFunctionMapping(llvm::ExecutionEngine&);
  };
}

void JITtedFunctionCollector::UnregisterFunctionMapping(
                                                  llvm::ExecutionEngine &engine)
{
  for (llvm::SmallVectorImpl<llvm::Function *>::reverse_iterator
         it = m_functions.rbegin(), et = m_functions.rend();
       it != et; ++it) {
    llvm::Function *ff = *it;
    engine.freeMachineCodeForFunction(ff);
    engine.updateGlobalMapping(ff, 0);
  }
  m_functions.clear();
}

std::set<std::string> ExecutionContext::m_unresolvedSymbols;
std::vector<ExecutionContext::LazyFunctionCreatorFunc_t>
  ExecutionContext::m_lazyFuncCreator;

bool ExecutionContext::m_LazyFuncCreatorEnabled = true;

ExecutionContext::ExecutionContext():
  m_engine(0),
  m_RunningStaticInits(false),
  m_CxaAtExitRemapped(false)
{
}

void
ExecutionContext::InitializeBuilder(llvm::Module* m)
{
  //
  //  Create an execution engine to use.
  //
  // Note: Engine takes ownership of the module.
  assert(m && "Module cannot be null");

  llvm::EngineBuilder builder(m);
  builder.setOptLevel(llvm::CodeGenOpt::Less);
  std::string errMsg;
  builder.setErrorStr(&errMsg);
  builder.setEngineKind(llvm::EngineKind::JIT);
  builder.setAllocateGVsWithCode(false);
  m_engine = builder.create();
  assert(m_engine && "Cannot initialize builder without module!");

  //m_engine->addModule(m); // Note: The engine takes ownership of the module.

  // install lazy function
  m_engine->InstallLazyFunctionCreator(NotifyLazyFunctionCreators);
}

ExecutionContext::~ExecutionContext()
{
}

void unresolvedSymbol()
{
  // throw exception?
  llvm::errs() << "ExecutionContext: calling unresolved symbol (should never happen)!\n";
}

void* ExecutionContext::HandleMissingFunction(const std::string& mangled_name)
{
  // Not found in the map, add the symbol in the list of unresolved symbols
  if (m_unresolvedSymbols.insert(mangled_name).second) {
    llvm::errs() << "ExecutionContext: use of undefined symbol '"
                 << mangled_name << "'!\n";
  }

  // Avoid "ISO C++ forbids casting between pointer-to-function and
  // pointer-to-object":
  return (void*)reinterpret_cast<size_t>(unresolvedSymbol);
}

void*
ExecutionContext::NotifyLazyFunctionCreators(const std::string& mangled_name)
{
  for (std::vector<LazyFunctionCreatorFunc_t>::iterator it
         = m_lazyFuncCreator.begin(), et = m_lazyFuncCreator.end();
       it != et; ++it) {
    void* ret = (void*)((LazyFunctionCreatorFunc_t)*it)(mangled_name);
    if (ret)
      return ret;
  }

  if (!m_LazyFuncCreatorEnabled)
    return 0;

  return HandleMissingFunction(mangled_name);
}

void
ExecutionContext::executeFunction(llvm::StringRef funcname,
                                  const clang::ASTContext& Ctx,
                                  clang::QualType retType,
                                  StoredValueRef* returnValue)
{
  // Call a function without arguments, or with an SRet argument, see SRet below

  if (!m_CxaAtExitRemapped) {
    // Rewire atexit:
    llvm::Function* atExit = m_engine->FindFunctionNamed("__cxa_atexit");
    llvm::Function* clingAtExit = m_engine->FindFunctionNamed("cling_cxa_atexit");
    if (atExit && clingAtExit) {
      void* clingAtExitAddr = m_engine->getPointerToFunction(clingAtExit);
      assert(clingAtExitAddr && "cannot find cling_cxa_atexit");
      m_engine->updateGlobalMapping(atExit, clingAtExitAddr);
      m_CxaAtExitRemapped = true;
    }
  }

  // We don't care whether something was unresolved before.
  m_unresolvedSymbols.clear();

  llvm::Function* f = m_engine->FindFunctionNamed(funcname.data());
  if (!f) {
    llvm::errs() << "ExecutionContext::executeFunction: could not find function named " << funcname << '\n';
    return;
  }
  JITtedFunctionCollector listener;
  // register the listener
  m_engine->RegisterJITEventListener(&listener);
  m_engine->getPointerToFunction(f);
  // check if there is any unresolved symbol in the list
  if (!m_unresolvedSymbols.empty()) {
    for (std::set<std::string>::const_iterator i = m_unresolvedSymbols.begin(),
           e = m_unresolvedSymbols.end(); i != e; ++i) {
      llvm::errs() << "ExecutionContext::executeFunction: symbol \'" << *i << "\' unresolved!\n";
      llvm::Function *ff = m_engine->FindFunctionNamed(i->c_str());
      assert(ff && "cannot find function to free");
      m_engine->updateGlobalMapping(ff, 0);
      m_engine->freeMachineCodeForFunction(ff);
    }
    m_unresolvedSymbols.clear();
    // cleanup functions
    listener.UnregisterFunctionMapping(*m_engine);
    m_engine->UnregisterJITEventListener(&listener);
    return;
  }
  // cleanup list and unregister our listener
  m_engine->UnregisterJITEventListener(&listener);

  std::vector<llvm::GenericValue> args;
  bool wantReturn = (returnValue);
  StoredValueRef aggregateRet;

  if (f->hasStructRetAttr()) {
    // Function expects to receive the storage for the returned aggregate as
    // first argument. Allocate returnValue:
    aggregateRet = StoredValueRef::allocate(Ctx, retType);
    if (returnValue) {
      *returnValue = aggregateRet;
    } else {
      returnValue = &aggregateRet;
    }
    args.push_back(returnValue->get().value);
    // will get set as arg0, must not assign.
    wantReturn = false;
  }

  if (wantReturn) {
    llvm::GenericValue gvRet = m_engine->runFunction(f, args);
    // rescue the ret value (which might be aggregate) from the stack
    *returnValue = StoredValueRef::bitwiseCopy(Ctx, Value(gvRet, retType));
  } else {
    m_engine->runFunction(f, args);
  }

  m_engine->freeMachineCodeForFunction(f);
}

void
ExecutionContext::runStaticInitializersOnce(llvm::Module* m) {
  assert(m && "Module must not be null");

  if (!m_engine)
    InitializeBuilder(m);

  assert(m_engine && "Code generation did not create an engine!");

  if (!m_RunningStaticInits) {
    m_RunningStaticInits = true;

    llvm::GlobalVariable* gctors
      = m->getGlobalVariable("llvm.global_ctors", true);
    if (gctors) {
      m_engine->runStaticConstructorsDestructors(false);
      gctors->eraseFromParent();
    }

    m_RunningStaticInits = false;
  }
}

void
ExecutionContext::runStaticDestructorsOnce(llvm::Module* m) {
  assert(m && "Module must not be null");
  assert(m_engine && "Code generation did not create an engine!");

  llvm::GlobalVariable* gdtors
    = m->getGlobalVariable("llvm.global_dtors", true);
  if (gdtors) {
    m_engine->runStaticConstructorsDestructors(true);
  }

}

int
ExecutionContext::verifyModule(llvm::Module* m)
{
  //
  //  Verify generated module.
  //
  bool mod_has_errs = llvm::verifyModule(*m, llvm::PrintMessageAction);
  if (mod_has_errs) {
    return 1;
  }
  return 0;
}

void
ExecutionContext::printModule(llvm::Module* m)
{
  //
  //  Print module LLVM code in human-readable form.
  //
  llvm::PassManager PM;
  PM.add(llvm::createPrintModulePass(&llvm::outs()));
  PM.run(*m);
}

void
ExecutionContext::installLazyFunctionCreator(LazyFunctionCreatorFunc_t fp)
{
  m_lazyFuncCreator.push_back(fp);
}

bool ExecutionContext::addSymbol(const char* symbolName,  void* symbolAddress) {

  void* actualAddress
    = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(symbolName);
  if (actualAddress)
    return false;

  llvm::sys::DynamicLibrary::AddSymbol(symbolName, symbolAddress);
  return true;
}

void* ExecutionContext::getAddressOfGlobal(llvm::Module* m,
                                           const char* symbolName,
                                           bool* fromJIT /*=0*/) const {
    // Return a symbol's address, and whether it was jitted.
    void* address
      = llvm::sys::DynamicLibrary::SearchForAddressOfSymbol(symbolName);
    if (address) {
      if (fromJIT) *fromJIT = false;
    } else {
      if (fromJIT) *fromJIT = true;
      llvm::GlobalVariable* gvar
        = m->getGlobalVariable(symbolName, true);
      if (!gvar)
        return 0;

      address = m_engine->getPointerToGlobal(gvar);
    }
    return address;
  }
<|endoftext|>