<commit_before>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkPath.h"
#include "SkRandom.h"
#include "SkTArray.h"

namespace skiagm {

// This GM tests a grab-bag of convex and concave polygons. They are triangles,
// trapezoid, diamond, polygons with lots of edges, several concave polygons...
// But rectangles are excluded.
class PolygonsGM: public GM {
public:
    PolygonsGM() {}

protected:
    virtual SkString onShortName() SK_OVERRIDE {
        return SkString("polygons");
    }

    virtual SkISize onISize() SK_OVERRIDE {
        size_t width = kNumPolygons * kCellSize + 40;
        size_t height = (kNumJoins * kNumStrokeWidths + kNumExtraStyles) * kCellSize + 40;
        return SkISize::Make(width, height);
    }

    // Construct all polygons
    virtual void onOnceBeforeDraw() SK_OVERRIDE {
        SkPoint p0[] = {{0, 0}, {60, 0}, {90, 40}};  // triangle
        SkPoint p1[] = {{0, 0}, {0, 40}, {60, 40}, {40, 0}};  // trapezoid
        SkPoint p2[] = {{0, 0}, {40, 40}, {80, 40}, {40, 0}};  // diamond
        SkPoint p3[] = {{10, 0}, {50, 0}, {60, 10}, {60, 30}, {50, 40},
                        {10, 40}, {0, 30}, {0, 10}};  // octagon
        SkPoint p4[32];  // circle-like polygons with 32-edges.
        SkPoint p5[] = {{0, 0}, {20, 20}, {0, 40}, {60, 20}};  // concave polygon with 4 edges
        SkPoint p6[] = {{0, 40}, {0, 30}, {15, 30}, {15, 20}, {30, 20},
                        {30, 10}, {45, 10}, {45, 0}, {60, 0}, {60, 40}};  // stairs-like polygon
        SkPoint p7[] = {{0, 20}, {20, 20}, {30, 0}, {40, 20}, {60, 20},
                        {45, 30}, {55, 50}, {30, 40}, {5, 50}, {15, 30}};  // five-point stars

        for (size_t i = 0; i < SK_ARRAY_COUNT(p4); ++i) {
            SkScalar angle = 2 * SK_ScalarPI * i / SK_ARRAY_COUNT(p4);
            p4[i].set(20 * cos(angle) + 20, 20 * sin(angle) + 20);
        }

        struct Polygons {
            SkPoint* fPoints;
            size_t fPointNum;
        } pgs[] = {
            { p0, SK_ARRAY_COUNT(p0) },
            { p1, SK_ARRAY_COUNT(p1) },
            { p2, SK_ARRAY_COUNT(p2) },
            { p3, SK_ARRAY_COUNT(p3) },
            { p4, SK_ARRAY_COUNT(p4) },
            { p5, SK_ARRAY_COUNT(p5) },
            { p6, SK_ARRAY_COUNT(p6) },
            { p7, SK_ARRAY_COUNT(p7) }
        };

        SkASSERT(SK_ARRAY_COUNT(pgs) == kNumPolygons);
        for (size_t pgIndex = 0; pgIndex < SK_ARRAY_COUNT(pgs); ++pgIndex) {
            fPolygons.push_back().moveTo(pgs[pgIndex].fPoints[0].fX,
                                         pgs[pgIndex].fPoints[0].fY);
            for (size_t ptIndex = 1; ptIndex < pgs[pgIndex].fPointNum; ++ptIndex) {
                fPolygons.back().lineTo(pgs[pgIndex].fPoints[ptIndex].fX,
                                        pgs[pgIndex].fPoints[ptIndex].fY);
            }
            fPolygons.back().close();
        }
    }

    // Set the location for the current test on the canvas
    static void SetLocation(SkCanvas* canvas, int counter, int lineNum) {
        SkScalar x = SK_Scalar1 * kCellSize * (counter % lineNum) + 30 + SK_Scalar1 / 4;
        SkScalar y = SK_Scalar1 * kCellSize * (counter / lineNum) + 30 + 3 * SK_Scalar1 / 4;
        canvas->translate(x, y);
    }

    static void SetColorAndAlpha(SkPaint* paint, SkLCGRandom* rand) {
        SkColor color = rand->nextU();
        color |= 0xff000000;
        paint->setColor(color);
        if (40 == paint->getStrokeWidth()) {
            paint->setAlpha(0xA0);
        }
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        // Stroke widths are:
        // 0(may use hairline rendering), 10(common case for stroke-style)
        // 40(>= geometry width/height, make the contour filled in fact)
        static const int kStrokeWidths[] = {0, 10, 40};
        SkASSERT(kNumStrokeWidths == SK_ARRAY_COUNT(kStrokeWidths));

        static const SkPaint::Join kJoins[] = {
            SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join
        };
        SkASSERT(kNumJoins == SK_ARRAY_COUNT(kJoins));

        int counter = 0;
        SkPaint paint;
        paint.setAntiAlias(true);

        SkLCGRandom rand;
        // For stroke style painter
        paint.setStyle(SkPaint::kStroke_Style);
        for (int join = 0; join < kNumJoins; ++join) {
            for (int width = 0; width < kNumStrokeWidths; ++width) {
                for (int i = 0; i < fPolygons.count(); ++i) {
                    canvas->save();
                    SetLocation(canvas, counter, fPolygons.count());

                    SetColorAndAlpha(&paint, &rand);
                    paint.setStrokeJoin(kJoins[join]);
                    paint.setStrokeWidth(SkIntToScalar(kStrokeWidths[width]));

                    canvas->drawPath(fPolygons[i], paint);
                    canvas->restore();
                    ++counter;
                }
            }
        }

        // For stroke-and-fill style painter and fill style painter
        static const SkPaint::Style kStyles[] = {
            SkPaint::kStrokeAndFill_Style, SkPaint::kFill_Style
        };
        SkASSERT(kNumExtraStyles == SK_ARRAY_COUNT(kStyles));

        paint.setStrokeJoin(SkPaint::kMiter_Join);
        paint.setStrokeWidth(SkIntToScalar(20));
        for (int style = 0; style < kNumExtraStyles; ++style) {
            paint.setStyle(kStyles[style]);
            for (int i = 0; i < fPolygons.count(); ++i) {
                canvas->save();
                SetLocation(canvas, counter, fPolygons.count());
                SetColorAndAlpha(&paint, &rand);
                canvas->drawPath(fPolygons[i], paint);
                canvas->restore();
                ++counter;
            }
        }
    }

private:
    static const int kNumPolygons = 8;
    static const int kCellSize = 100;
    static const int kNumExtraStyles = 2;
    static const int kNumStrokeWidths = 3;
    static const int kNumJoins = 3;

    SkTArray<SkPath> fPolygons;
    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

DEF_GM(return new PolygonsGM;)

}
<commit_msg>Fix warning as error on Mac for implicit narrowing conversion from r12413.<commit_after>/*
 * Copyright 2013 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "gm.h"
#include "SkCanvas.h"
#include "SkPath.h"
#include "SkRandom.h"
#include "SkScalar.h"
#include "SkTArray.h"

namespace skiagm {

// This GM tests a grab-bag of convex and concave polygons. They are triangles,
// trapezoid, diamond, polygons with lots of edges, several concave polygons...
// But rectangles are excluded.
class PolygonsGM: public GM {
public:
    PolygonsGM() {}

protected:
    virtual SkString onShortName() SK_OVERRIDE {
        return SkString("polygons");
    }

    virtual SkISize onISize() SK_OVERRIDE {
        size_t width = kNumPolygons * kCellSize + 40;
        size_t height = (kNumJoins * kNumStrokeWidths + kNumExtraStyles) * kCellSize + 40;
        return SkISize::Make(width, height);
    }

    // Construct all polygons
    virtual void onOnceBeforeDraw() SK_OVERRIDE {
        SkPoint p0[] = {{0, 0}, {60, 0}, {90, 40}};  // triangle
        SkPoint p1[] = {{0, 0}, {0, 40}, {60, 40}, {40, 0}};  // trapezoid
        SkPoint p2[] = {{0, 0}, {40, 40}, {80, 40}, {40, 0}};  // diamond
        SkPoint p3[] = {{10, 0}, {50, 0}, {60, 10}, {60, 30}, {50, 40},
                        {10, 40}, {0, 30}, {0, 10}};  // octagon
        SkPoint p4[32];  // circle-like polygons with 32-edges.
        SkPoint p5[] = {{0, 0}, {20, 20}, {0, 40}, {60, 20}};  // concave polygon with 4 edges
        SkPoint p6[] = {{0, 40}, {0, 30}, {15, 30}, {15, 20}, {30, 20},
                        {30, 10}, {45, 10}, {45, 0}, {60, 0}, {60, 40}};  // stairs-like polygon
        SkPoint p7[] = {{0, 20}, {20, 20}, {30, 0}, {40, 20}, {60, 20},
                        {45, 30}, {55, 50}, {30, 40}, {5, 50}, {15, 30}};  // five-point stars

        for (size_t i = 0; i < SK_ARRAY_COUNT(p4); ++i) {
            SkScalar angle = 2 * SK_ScalarPI * i / SK_ARRAY_COUNT(p4);
            p4[i].set(20 * SkScalarCos(angle) + 20, 20 * SkScalarSin(angle) + 20);
        }

        struct Polygons {
            SkPoint* fPoints;
            size_t fPointNum;
        } pgs[] = {
            { p0, SK_ARRAY_COUNT(p0) },
            { p1, SK_ARRAY_COUNT(p1) },
            { p2, SK_ARRAY_COUNT(p2) },
            { p3, SK_ARRAY_COUNT(p3) },
            { p4, SK_ARRAY_COUNT(p4) },
            { p5, SK_ARRAY_COUNT(p5) },
            { p6, SK_ARRAY_COUNT(p6) },
            { p7, SK_ARRAY_COUNT(p7) }
        };

        SkASSERT(SK_ARRAY_COUNT(pgs) == kNumPolygons);
        for (size_t pgIndex = 0; pgIndex < SK_ARRAY_COUNT(pgs); ++pgIndex) {
            fPolygons.push_back().moveTo(pgs[pgIndex].fPoints[0].fX,
                                         pgs[pgIndex].fPoints[0].fY);
            for (size_t ptIndex = 1; ptIndex < pgs[pgIndex].fPointNum; ++ptIndex) {
                fPolygons.back().lineTo(pgs[pgIndex].fPoints[ptIndex].fX,
                                        pgs[pgIndex].fPoints[ptIndex].fY);
            }
            fPolygons.back().close();
        }
    }

    // Set the location for the current test on the canvas
    static void SetLocation(SkCanvas* canvas, int counter, int lineNum) {
        SkScalar x = SK_Scalar1 * kCellSize * (counter % lineNum) + 30 + SK_Scalar1 / 4;
        SkScalar y = SK_Scalar1 * kCellSize * (counter / lineNum) + 30 + 3 * SK_Scalar1 / 4;
        canvas->translate(x, y);
    }

    static void SetColorAndAlpha(SkPaint* paint, SkLCGRandom* rand) {
        SkColor color = rand->nextU();
        color |= 0xff000000;
        paint->setColor(color);
        if (40 == paint->getStrokeWidth()) {
            paint->setAlpha(0xA0);
        }
    }

    virtual void onDraw(SkCanvas* canvas) SK_OVERRIDE {
        // Stroke widths are:
        // 0(may use hairline rendering), 10(common case for stroke-style)
        // 40(>= geometry width/height, make the contour filled in fact)
        static const int kStrokeWidths[] = {0, 10, 40};
        SkASSERT(kNumStrokeWidths == SK_ARRAY_COUNT(kStrokeWidths));

        static const SkPaint::Join kJoins[] = {
            SkPaint::kMiter_Join, SkPaint::kRound_Join, SkPaint::kBevel_Join
        };
        SkASSERT(kNumJoins == SK_ARRAY_COUNT(kJoins));

        int counter = 0;
        SkPaint paint;
        paint.setAntiAlias(true);

        SkLCGRandom rand;
        // For stroke style painter
        paint.setStyle(SkPaint::kStroke_Style);
        for (int join = 0; join < kNumJoins; ++join) {
            for (int width = 0; width < kNumStrokeWidths; ++width) {
                for (int i = 0; i < fPolygons.count(); ++i) {
                    canvas->save();
                    SetLocation(canvas, counter, fPolygons.count());

                    SetColorAndAlpha(&paint, &rand);
                    paint.setStrokeJoin(kJoins[join]);
                    paint.setStrokeWidth(SkIntToScalar(kStrokeWidths[width]));

                    canvas->drawPath(fPolygons[i], paint);
                    canvas->restore();
                    ++counter;
                }
            }
        }

        // For stroke-and-fill style painter and fill style painter
        static const SkPaint::Style kStyles[] = {
            SkPaint::kStrokeAndFill_Style, SkPaint::kFill_Style
        };
        SkASSERT(kNumExtraStyles == SK_ARRAY_COUNT(kStyles));

        paint.setStrokeJoin(SkPaint::kMiter_Join);
        paint.setStrokeWidth(SkIntToScalar(20));
        for (int style = 0; style < kNumExtraStyles; ++style) {
            paint.setStyle(kStyles[style]);
            for (int i = 0; i < fPolygons.count(); ++i) {
                canvas->save();
                SetLocation(canvas, counter, fPolygons.count());
                SetColorAndAlpha(&paint, &rand);
                canvas->drawPath(fPolygons[i], paint);
                canvas->restore();
                ++counter;
            }
        }
    }

private:
    static const int kNumPolygons = 8;
    static const int kCellSize = 100;
    static const int kNumExtraStyles = 2;
    static const int kNumStrokeWidths = 3;
    static const int kNumJoins = 3;

    SkTArray<SkPath> fPolygons;
    typedef GM INHERITED;
};

//////////////////////////////////////////////////////////////////////////////

DEF_GM(return new PolygonsGM;)

}
<|endoftext|>


<commit_before>#include "MainWindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      currentState(NotConnected),
      sshProcess(NULL),
      sshAskPassFile(NULL),
      timer(NULL)
{
    setWindowTitle(qApp->applicationName());

    layout = new QFormLayout();

    sshServerLayout = new QHBoxLayout();
    sshServerAddrEdit = new QLineEdit();
    sshServerLayout->addWidget(sshServerAddrEdit);
    sshServerColon = new QLabel(":");
    sshServerLayout->addWidget(sshServerColon);
    sshServerPortEdit = new QLineEdit();
    sshServerPortEdit->setMaxLength(5);
    sshServerPortEdit->setFixedWidth(50);
    sshServerLayout->addWidget(sshServerPortEdit);
    layout->addRow(tr("SSH Server:"), sshServerLayout);

    usernameEdit = new QLineEdit();
    layout->addRow(tr("Username:"), usernameEdit);

    passwordLayout = new QHBoxLayout();
    passwordEdit = new QLineEdit();
    passwordEdit->setEchoMode(QLineEdit::Password);
    passwordLayout->addWidget(passwordEdit);
    remberPasswordCheckBox = new QCheckBox(tr("Rember"));
    passwordLayout->addWidget(remberPasswordCheckBox);
    layout->addRow(tr("Password:"), passwordLayout);

    socksServerLayout = new QHBoxLayout();
    socksServerAddrEdit = new QLineEdit();
    socksServerLayout->addWidget(socksServerAddrEdit);
    socksServerColon = new QLabel(":");
    socksServerLayout->addWidget(socksServerColon);
    socksServerPortEdit = new QLineEdit();
    socksServerPortEdit->setMaxLength(5);
    socksServerPortEdit->setFixedWidth(50);
    socksServerLayout->addWidget(socksServerPortEdit);
    layout->addRow(tr("SOCKS Server:"), socksServerLayout);

    statusLabel = new QLabel();
    layout->addRow(tr("Status:"), statusLabel);

    connectBtn = new QPushButton();
    connect(connectBtn, SIGNAL(clicked()), this, SLOT(connectBtnClicked()));
    layout->addRow(connectBtn);

    QWidget *widget = new QWidget(this);
    widget->setLayout(layout);
    setCentralWidget(widget);

    prepareMenuBar();
    prepareTrayIcon();

    loadSettings();

    setCurrentState(NotConnected);
}

MainWindow::~MainWindow()
{

}

void
MainWindow::connectBtnClicked()
{
    if (!this->validateForm()) {
        return;
    }

    connectBtn->setDisabled(true);
    if (currentState == NotConnected) {
        connectSSH();
    } else {
        disconnectSSH();
    }
}

void
MainWindow::operationActionTriggered()
{
    if (!this->validateForm()) {
        return;
    }

    if (currentState == NotConnected) {
        connectSSH();
    } else if (currentState == Connected) {
        disconnectSSH();
    }
}

void
MainWindow::sshReadyReadStdout()
{
    QString data(sshProcess->readAllStandardOutput());
    qDebug() << "stdout:" << data;
}

void
MainWindow::sshReadyReadStderr()
{
    QString data(sshProcess->readAllStandardError());
    qDebug() << "stderr:" << data;

    if (data.contains("Permission denied")) {
        /* Connect failed, maybe incorrect username or password */
        setCurrentState(NotConnected);
        statusLabel->setText(tr("Connect failed (permission denied)"));
        if (sshAskPassFile != NULL) {
            delete sshAskPassFile;
            sshAskPassFile = NULL;
        }
    } else if (data.contains("Operation timed out")) {
        /* Connect failed, maybe incorrect IP/port */
        setCurrentState(NotConnected);
        statusLabel->setText(tr("Connect failed (Operation timed out)"));
    } else if (data.contains("Entering interactive session.")) {
        /* Connect success */
        setCurrentState(Connected);
    } else {
        /* If output is not key information, then return, don't remove
         * sshAskPassFile */
        return;
    }
    if (sshAskPassFile != NULL) {
        delete sshAskPassFile;
        sshAskPassFile = NULL;
    }
}

void
MainWindow::updateTime()
{
    QTime t(0, 0, 0);
    t = t.addMSecs(elapsedTimer.elapsed());
    QString status = tr("Connected (%1)").arg(t.toString("hh:mm:ss"));
    statusLabel->setText(status);
    statusAction->setText(status);
}

void
MainWindow::closeEvent(QCloseEvent *event)
{
    settings.setValue("ssh_server/addr", sshServerAddrEdit->text());
    settings.setValue("ssh_server/port", sshServerPortEdit->text());
    settings.setValue("username", usernameEdit->text());
    if (remberPasswordCheckBox->isChecked()) {
        settings.setValue("password/value", passwordEdit->text());
        settings.setValue("password/rember",
                          remberPasswordCheckBox->isChecked());
    } else {
        settings.remove("password");
    }
    settings.setValue("socks_server/addr", socksServerAddrEdit->text());
    settings.setValue("socks_server/port", socksServerPortEdit->text());
    event->accept();
}

void
MainWindow::prepareMenuBar()
{
}

void
MainWindow::prepareTrayIcon()
{
    trayIcon = new QSystemTrayIcon(QIcon(":/images/images/icon_16x16@2x.png"),
                                   this);
    trayMenu = new QMenu(this);

    /* Add status and operation action */
    statusAction = new QAction(this);
    statusAction->setDisabled(true);
    trayMenu->addAction(statusAction);
    operationAction = new QAction(this);
    connect(operationAction, SIGNAL(triggered()),
            this, SLOT(operationActionTriggered()));
    trayMenu->addAction(operationAction);

    /* Separator */
    trayMenu->addSeparator();

    /* Quit action */
    trayMenu->addAction(tr("Quit %1").arg(qApp->applicationName()),
                        qApp, SLOT(quit()));

    trayIcon->setContextMenu(trayMenu);
    trayIcon->show();
}

void
MainWindow::loadSettings()
{
    sshServerAddrEdit->setText(settings.value("ssh_server/addr").toString());
    sshServerPortEdit->setText(settings.value("ssh_server/port",
                                              "22").toString());
    usernameEdit->setText(settings.value("username").toString());
    passwordEdit->setText(settings.value("password/value").toString());
    remberPasswordCheckBox->setChecked(settings.value("password/rember",
                                                      false).toBool());
    socksServerAddrEdit->setText(settings.value("socks_server/addr",
                                                "127.0.0.1").toString());
    socksServerPortEdit->setText(settings.value("socks_server/port",
                                                "7070").toString());
}

bool
MainWindow::validateForm()
{
    if (sshServerAddrEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SSH server address"));
        return false;
    }
    if (sshServerPortEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SSH server address"));
        return false;
    }
    if (usernameEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SSH username"));
        return false;
    }
    if (passwordEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SSH password"));
        return false;
    }
    if (socksServerAddrEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SOCKS server address"));
        return false;
    }
    if (socksServerPortEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SOCKS server address"));
        return false;
    }
    return true;
}

void
MainWindow::connectSSH()
{
    setCurrentState(Connecting);

    /* Create SSH process object */
    sshProcess = new QProcess(this);
    connect(sshProcess, SIGNAL(readyReadStandardOutput()),
            this, SLOT(sshReadyReadStdout()));
    connect(sshProcess, SIGNAL(readyReadStandardError()),
            this, SLOT(sshReadyReadStderr()));

    /* Generate SSH_ASKPASS file with right permission and content */
    sshAskPassFile = new QTemporaryFile();
    if (!sshAskPassFile->open()) {
        setCurrentState(NotConnected);
        statusLabel->setText(tr("Connect failed (SSH_ASKPASS error)"));
        return;
    }
    QFile::Permissions perm = sshAskPassFile->permissions();
    qDebug() << sshAskPassFile->fileName();
    perm |= QFile::ExeOwner | QFile::ExeUser;
    sshAskPassFile->setPermissions(perm);
    QTextStream out(sshAskPassFile);
    out << "#!/usr/bin/env bash\n";
    out << "echo '" << passwordEdit->text() << "'\n";
    sshAskPassFile->close();

    /* Set SSH_ASKPASS enviroment variable */
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    env.insert("SSH_ASKPASS", sshAskPassFile->fileName());
    sshProcess->setProcessEnvironment(env);

    /* Assemble arguments and start SSH process */
    QStringList arguments;
    arguments << "-qTnN";
    arguments << "-v";
    arguments << "-D" << QString("%1:%2").arg(socksServerAddrEdit->text(),
                                              socksServerPortEdit->text());
    arguments << "-p" << sshServerPortEdit->text();
    arguments << "-o" << "ConnectTimeout=10";
    arguments << QString("%1@%2").arg(usernameEdit->text(),
                                      sshServerAddrEdit->text());
    sshProcess->start("ssh", arguments);
    if (!sshProcess->waitForStarted(1000)) {
        setCurrentState(NotConnected);
        statusLabel->setText(tr("SSH start failed"));
        return;
    }
}

void
MainWindow::disconnectSSH()
{
    setCurrentState(Disconnecting);

    sshProcess->kill();
    delete sshProcess;
    sshProcess = NULL;

    setCurrentState(NotConnected);
}

void
MainWindow::setCurrentState(CurrentState state)
{
    currentState = state;

    if (currentState != Connected && timer != NULL) {
        delete timer;
        timer = NULL;
    }

    if (currentState == NotConnected) {
        statusLabel->setText(tr("Not connected"));
        connectBtn->setText(tr("Connect"));
        connectBtn->setEnabled(true);
        statusAction->setText(tr("Not connected"));
        operationAction->setText(tr("Connect"));
        operationAction->setVisible(true);
    } else if (currentState == Connecting) {
        statusLabel->setText(tr("Connecting..."));
        connectBtn->setEnabled(false);
        statusAction->setText(tr("Connecting..."));
        operationAction->setVisible(false);
    } else if (currentState == Connected) {
        /* Start timer to update elapsed time in status label */
        elapsedTimer.restart();
        updateTime();
        timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(updateTime()));
        timer->start(1000);

        connectBtn->setText(tr("Disconnect"));
        connectBtn->setEnabled(true);
        operationAction->setText(tr("Disconnect"));
        operationAction->setVisible(true);
    } else if (currentState == Disconnecting) {
        statusLabel->setText(tr("Disconnecting..."));
        connectBtn->setEnabled(false);
        statusAction->setText(tr("Disconnecting..."));
        operationAction->setVisible(false);
    }
}
<commit_msg>add disable user input area when connecting<commit_after>#include "MainWindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent),
      currentState(NotConnected),
      sshProcess(NULL),
      sshAskPassFile(NULL),
      timer(NULL)
{
    setWindowTitle(qApp->applicationName());

    layout = new QFormLayout();

    sshServerLayout = new QHBoxLayout();
    sshServerAddrEdit = new QLineEdit();
    sshServerLayout->addWidget(sshServerAddrEdit);
    sshServerColon = new QLabel(":");
    sshServerLayout->addWidget(sshServerColon);
    sshServerPortEdit = new QLineEdit();
    sshServerPortEdit->setMaxLength(5);
    sshServerPortEdit->setFixedWidth(50);
    sshServerLayout->addWidget(sshServerPortEdit);
    layout->addRow(tr("SSH Server:"), sshServerLayout);

    usernameEdit = new QLineEdit();
    layout->addRow(tr("Username:"), usernameEdit);

    passwordLayout = new QHBoxLayout();
    passwordEdit = new QLineEdit();
    passwordEdit->setEchoMode(QLineEdit::Password);
    passwordLayout->addWidget(passwordEdit);
    remberPasswordCheckBox = new QCheckBox(tr("Rember"));
    passwordLayout->addWidget(remberPasswordCheckBox);
    layout->addRow(tr("Password:"), passwordLayout);

    socksServerLayout = new QHBoxLayout();
    socksServerAddrEdit = new QLineEdit();
    socksServerLayout->addWidget(socksServerAddrEdit);
    socksServerColon = new QLabel(":");
    socksServerLayout->addWidget(socksServerColon);
    socksServerPortEdit = new QLineEdit();
    socksServerPortEdit->setMaxLength(5);
    socksServerPortEdit->setFixedWidth(50);
    socksServerLayout->addWidget(socksServerPortEdit);
    layout->addRow(tr("SOCKS Server:"), socksServerLayout);

    statusLabel = new QLabel();
    layout->addRow(tr("Status:"), statusLabel);

    connectBtn = new QPushButton();
    connect(connectBtn, SIGNAL(clicked()), this, SLOT(connectBtnClicked()));
    layout->addRow(connectBtn);

    QWidget *widget = new QWidget(this);
    widget->setLayout(layout);
    setCentralWidget(widget);

    prepareMenuBar();
    prepareTrayIcon();

    loadSettings();

    setCurrentState(NotConnected);
}

MainWindow::~MainWindow()
{

}

void
MainWindow::connectBtnClicked()
{
    if (!this->validateForm()) {
        return;
    }

    connectBtn->setDisabled(true);
    if (currentState == NotConnected) {
        connectSSH();
    } else {
        disconnectSSH();
    }
}

void
MainWindow::operationActionTriggered()
{
    if (!this->validateForm()) {
        return;
    }

    if (currentState == NotConnected) {
        connectSSH();
    } else if (currentState == Connected) {
        disconnectSSH();
    }
}

void
MainWindow::sshReadyReadStdout()
{
    QString data(sshProcess->readAllStandardOutput());
    qDebug() << "stdout:" << data;
}

void
MainWindow::sshReadyReadStderr()
{
    QString data(sshProcess->readAllStandardError());
    qDebug() << "stderr:" << data;

    if (data.contains("Permission denied")) {
        /* Connect failed, maybe incorrect username or password */
        setCurrentState(NotConnected);
        statusLabel->setText(tr("Connect failed (permission denied)"));
        if (sshAskPassFile != NULL) {
            delete sshAskPassFile;
            sshAskPassFile = NULL;
        }
    } else if (data.contains("Operation timed out")) {
        /* Connect failed, maybe incorrect IP/port */
        setCurrentState(NotConnected);
        statusLabel->setText(tr("Connect failed (Operation timed out)"));
    } else if (data.contains("Entering interactive session.")) {
        /* Connect success */
        setCurrentState(Connected);
    } else {
        /* If output is not key information, then return, don't remove
         * sshAskPassFile */
        return;
    }
    if (sshAskPassFile != NULL) {
        delete sshAskPassFile;
        sshAskPassFile = NULL;
    }
}

void
MainWindow::updateTime()
{
    QTime t(0, 0, 0);
    t = t.addMSecs(elapsedTimer.elapsed());
    QString status = tr("Connected (%1)").arg(t.toString("hh:mm:ss"));
    statusLabel->setText(status);
    statusAction->setText(status);
}

void
MainWindow::closeEvent(QCloseEvent *event)
{
    settings.setValue("ssh_server/addr", sshServerAddrEdit->text());
    settings.setValue("ssh_server/port", sshServerPortEdit->text());
    settings.setValue("username", usernameEdit->text());
    if (remberPasswordCheckBox->isChecked()) {
        settings.setValue("password/value", passwordEdit->text());
        settings.setValue("password/rember",
                          remberPasswordCheckBox->isChecked());
    } else {
        settings.remove("password");
    }
    settings.setValue("socks_server/addr", socksServerAddrEdit->text());
    settings.setValue("socks_server/port", socksServerPortEdit->text());
    event->accept();
}

void
MainWindow::prepareMenuBar()
{
}

void
MainWindow::prepareTrayIcon()
{
    trayIcon = new QSystemTrayIcon(QIcon(":/images/images/icon_16x16@2x.png"),
                                   this);
    trayMenu = new QMenu(this);

    /* Add status and operation action */
    statusAction = new QAction(this);
    statusAction->setDisabled(true);
    trayMenu->addAction(statusAction);
    operationAction = new QAction(this);
    connect(operationAction, SIGNAL(triggered()),
            this, SLOT(operationActionTriggered()));
    trayMenu->addAction(operationAction);

    /* Separator */
    trayMenu->addSeparator();

    /* Quit action */
    trayMenu->addAction(tr("Quit %1").arg(qApp->applicationName()),
                        qApp, SLOT(quit()));

    trayIcon->setContextMenu(trayMenu);
    trayIcon->show();
}

void
MainWindow::loadSettings()
{
    sshServerAddrEdit->setText(settings.value("ssh_server/addr").toString());
    sshServerPortEdit->setText(settings.value("ssh_server/port",
                                              "22").toString());
    usernameEdit->setText(settings.value("username").toString());
    passwordEdit->setText(settings.value("password/value").toString());
    remberPasswordCheckBox->setChecked(settings.value("password/rember",
                                                      false).toBool());
    socksServerAddrEdit->setText(settings.value("socks_server/addr",
                                                "127.0.0.1").toString());
    socksServerPortEdit->setText(settings.value("socks_server/port",
                                                "7070").toString());
}

bool
MainWindow::validateForm()
{
    if (sshServerAddrEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SSH server address"));
        return false;
    }
    if (sshServerPortEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SSH server address"));
        return false;
    }
    if (usernameEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SSH username"));
        return false;
    }
    if (passwordEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SSH password"));
        return false;
    }
    if (socksServerAddrEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SOCKS server address"));
        return false;
    }
    if (socksServerPortEdit->text().length() == 0) {
        QMessageBox::warning(this, tr("Warning"),
                             tr("Invalid SOCKS server address"));
        return false;
    }
    return true;
}

void
MainWindow::connectSSH()
{
    setCurrentState(Connecting);

    /* Create SSH process object */
    sshProcess = new QProcess(this);
    connect(sshProcess, SIGNAL(readyReadStandardOutput()),
            this, SLOT(sshReadyReadStdout()));
    connect(sshProcess, SIGNAL(readyReadStandardError()),
            this, SLOT(sshReadyReadStderr()));

    /* Generate SSH_ASKPASS file with right permission and content */
    sshAskPassFile = new QTemporaryFile();
    if (!sshAskPassFile->open()) {
        setCurrentState(NotConnected);
        statusLabel->setText(tr("Connect failed (SSH_ASKPASS error)"));
        return;
    }
    QFile::Permissions perm = sshAskPassFile->permissions();
    qDebug() << sshAskPassFile->fileName();
    perm |= QFile::ExeOwner | QFile::ExeUser;
    sshAskPassFile->setPermissions(perm);
    QTextStream out(sshAskPassFile);
    out << "#!/usr/bin/env bash\n";
    out << "echo '" << passwordEdit->text() << "'\n";
    sshAskPassFile->close();

    /* Set SSH_ASKPASS enviroment variable */
    QProcessEnvironment env = QProcessEnvironment::systemEnvironment();
    env.insert("SSH_ASKPASS", sshAskPassFile->fileName());
    sshProcess->setProcessEnvironment(env);

    /* Assemble arguments and start SSH process */
    QStringList arguments;
    arguments << "-qTnN";
    arguments << "-v";
    arguments << "-D" << QString("%1:%2").arg(socksServerAddrEdit->text(),
                                              socksServerPortEdit->text());
    arguments << "-p" << sshServerPortEdit->text();
    arguments << "-o" << "ConnectTimeout=10";
    arguments << QString("%1@%2").arg(usernameEdit->text(),
                                      sshServerAddrEdit->text());
    sshProcess->start("ssh", arguments);
    if (!sshProcess->waitForStarted(1000)) {
        setCurrentState(NotConnected);
        statusLabel->setText(tr("SSH start failed"));
        return;
    }
}

void
MainWindow::disconnectSSH()
{
    setCurrentState(Disconnecting);

    sshProcess->kill();
    delete sshProcess;
    sshProcess = NULL;

    setCurrentState(NotConnected);
}

void
MainWindow::setCurrentState(CurrentState state)
{
    currentState = state;

    if (currentState != Connected && timer != NULL) {
        delete timer;
        timer = NULL;
    }

    if (currentState == NotConnected) {
        /* Enable user input area */
        sshServerAddrEdit->setEnabled(true);
        sshServerPortEdit->setEnabled(true);
        usernameEdit->setEnabled(true);
        passwordEdit->setEnabled(true);
        remberPasswordCheckBox->setEnabled(true);
        socksServerAddrEdit->setEnabled(true);
        socksServerPortEdit->setEnabled(true);

        statusLabel->setText(tr("Not connected"));
        connectBtn->setText(tr("Connect"));
        connectBtn->setEnabled(true);
        statusAction->setText(tr("Not connected"));
        operationAction->setText(tr("Connect"));
        operationAction->setVisible(true);
    } else if (currentState == Connecting) {
        /* Disable user input area */
        sshServerAddrEdit->setDisabled(true);
        sshServerPortEdit->setDisabled(true);
        usernameEdit->setDisabled(true);
        passwordEdit->setDisabled(true);
        remberPasswordCheckBox->setDisabled(true);
        socksServerAddrEdit->setDisabled(true);
        socksServerPortEdit->setDisabled(true);

        statusLabel->setText(tr("Connecting..."));
        connectBtn->setEnabled(false);
        statusAction->setText(tr("Connecting..."));
        operationAction->setVisible(false);
    } else if (currentState == Connected) {
        /* Start timer to update elapsed time in status label */
        elapsedTimer.restart();
        updateTime();
        timer = new QTimer(this);
        connect(timer, SIGNAL(timeout()), this, SLOT(updateTime()));
        timer->start(1000);

        connectBtn->setText(tr("Disconnect"));
        connectBtn->setEnabled(true);
        operationAction->setText(tr("Disconnect"));
        operationAction->setVisible(true);
    } else if (currentState == Disconnecting) {
        statusLabel->setText(tr("Disconnecting..."));
        connectBtn->setEnabled(false);
        statusAction->setText(tr("Disconnecting..."));
        operationAction->setVisible(false);
    }
}
<|endoftext|>


<commit_before>/////////////////////////////////////////////////////////////////
/*
 *  Template of a read routine
 */
/////////////////////////////////////////////////////////////////
#include <NrrdIO/NrrdIOAPI.h>

#include <hxfield/HxUniformScalarField3.h>
#include <Amira/HxMessage.h>
#include <teem/nrrd.h>

NRRDIO_API
int NrrdReader(const char* filename)
{

	Nrrd *nrrd = nrrdNew();
	if ( nrrdLoad( nrrd, filename, NULL ) )
		throw biffGetDone(NRRD);

    if ( nrrd->dim > 3 )
	{
		theMsg->printf("ERROR: for now, nrrd input can only handle data with dimension 3 or less.");
		return 0;
	}

    const int dims[3] =
	{
		(nrrd->dim > 0) ? nrrd->axis[0].size : 1,
		(nrrd->dim > 1) ? nrrd->axis[1].size : 1,
		(nrrd->dim > 2) ? nrrd->axis[2].size : 1
	};

	if(nrrd->type != nrrdTypeUChar)
	{
		theMsg->printf("ERROR: for now, nrrd input can only uchar data.");
		return 0;
	}

	// Create a new scalar field (assume byte for now)
	HxUniformScalarField3* field =
		new HxUniformScalarField3(dims,McPrimType::mc_uint8,nrrd->data);

	// Shouldn't need to check for data loading
	HxData::registerData(field, filename);

    return 1;
}

<commit_msg>Whitespace<commit_after>/////////////////////////////////////////////////////////////////
/*
 *  Template of a read routine
 */
/////////////////////////////////////////////////////////////////
#include <NrrdIO/NrrdIOAPI.h>

#include <hxfield/HxUniformScalarField3.h>
#include <Amira/HxMessage.h>
#include <teem/nrrd.h>

NRRDIO_API
int NrrdReader(const char* filename)
{

	Nrrd *nrrd = nrrdNew();
	if ( nrrdLoad( nrrd, filename, NULL ) )
		throw biffGetDone(NRRD);

    if ( nrrd->dim > 3 )
	{
		theMsg->printf("ERROR: for now, nrrd input can only handle data with dimension 3 or less.");
		return 0;
	}

    const int dims[3] =
	{
		(nrrd->dim > 0) ? nrrd->axis[0].size : 1,
		(nrrd->dim > 1) ? nrrd->axis[1].size : 1,
		(nrrd->dim > 2) ? nrrd->axis[2].size : 1
	};

	if(nrrd->type != nrrdTypeUChar)
	{
		theMsg->printf("ERROR: for now, nrrd input can only uchar data.");
		return 0;
	}

	// Create a new scalar field (assume byte for now)
	HxUniformScalarField3* field =
		new HxUniformScalarField3(dims,McPrimType::mc_uint8,nrrd->data);

	// Shouldn't need to check for data loading
	HxData::registerData(field, filename);

    return 1;
}

<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * 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.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//
//                                                                           //
//  Photon Multiplicity Detector                                             //
//  This class contains the basic functions for the Photon Multiplicity      //
//  Detector. Functions specific to one particular geometry are              //
//  contained in the derived classes                                         //
//                                                                           //
//Begin_Html
/*

The responsible person for this module is
Subhasis Chattopadhyay.

*/
//End_Html
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include <TBRIK.h>
#include <TClonesArray.h>
#include <TGeometry.h>
#include <TNode.h>
#include <TTree.h>
#include <TVirtualMC.h>

#include "AliLog.h"
#include "AliLoader.h"
#include "AliPMDLoader.h"
#include "AliPMD.h"
#include "AliRun.h"
#include "AliMC.h"
#include "AliPMDDigitizer.h"
#include "AliPMDhit.h"
#include "AliPMDDDLRawData.h"

ClassImp(AliPMD)

//_____________________________________________________________________________
AliPMD::AliPMD()
{
  //
  // Default constructor
  //
  fIshunt = 0;

}

//_____________________________________________________________________________
AliPMD::AliPMD(const char *name, const char *title)
  : AliDetector(name,title)
{
  //
  // Default constructor
  //

  //
  // Allocate the array of hits
  fHits   = new TClonesArray("AliPMDhit",  405);
  gAlice->GetMCApp()->AddHitList(fHits);

  fIshunt =  0;

  fPar[0] = 1;
  fPar[1] = 1;
  fPar[2] = 0.8;
  fPar[3] = 0.02;
  fIn[0]  = 6;
  fIn[1]  = 20;
  fIn[2]  = 600;
  fIn[3]  = 27;
  fIn[4]  = 27;
  fGeo[0] = 0;
  fGeo[1] = 0.2;
  fGeo[2] = 4;
  fPadSize[0] = 0.8;
  fPadSize[1] = 1.0;
  fPadSize[2] = 1.2;
  fPadSize[3] = 1.5;
}

AliLoader* AliPMD::MakeLoader(const char* topfoldername)
{
  // Makes PMD Loader

  fLoader = new AliPMDLoader(GetName(),topfoldername);

  if (fLoader)
    {
      AliDebug(100,"Success");
    }
  else
    {
      AliError("Failure");
    }

  return fLoader;
}

AliPMD::~AliPMD()
{
  //
  // Destructor
  //
}

//_____________________________________________________________________________
void AliPMD::AddHit(Int_t track, Int_t *vol, Float_t *hits)
{
  //
  // Add a PMD hit
  //
  TClonesArray &lhits = *fHits;
  AliPMDhit *newcell, *curcell;
  //  printf("PMD++ Adding energy %f, prim %d, vol %d %d %d %d %d %d %d %d\n",
  // hits[3],gAlice->GetPrimary(track-1),vol[0],vol[1],vol[2],vol[3],
  // vol[4],vol[5],vol[6],vol[7]);

  newcell = new AliPMDhit(fIshunt, track, vol, hits);
  Int_t i;
  for (i=0; i<fNhits; i++) {
    //
    // See if this cell has already been hit
    curcell=(AliPMDhit*) lhits[i];
    if (*curcell==*newcell) {
//        printf("Cell with same numbers found\n") ; curcell->Print();
      *curcell = *curcell+*newcell;
//        printf("Cell after addition\n") ; curcell->Print();
      delete newcell;
      return;
    }
  }
  new(lhits[fNhits++]) AliPMDhit(newcell);
  delete newcell;
}

//_____________________________________________________________________________
void AliPMD::BuildGeometry()
{
  //
  // Build simple ROOT TNode geometry for event display
  //

  TNode *node, *top;
  const int kColorPMD  = kRed;

  //
  top=gAlice->GetGeometry()->GetNode("alice");

  // PMD
  new TBRIK("S_PMD","PMD box","void",300,300,5);
  top->cd();
  node = new TNode("PMD","PMD","S_PMD",0,0,-600,"");
  node->SetLineColor(kColorPMD);
  fNodes->Add(node);
}

//_____________________________________________________________________________
void AliPMD::SetPAR(Float_t p1, Float_t p2, Float_t p3,Float_t p4)
{
  //
  // Set PMD parameters
  //
  fPar[0] = p1;
  fPar[1] = p2;
  fPar[2] = p3;
  fPar[3] = p4;
}

//_____________________________________________________________________________
void AliPMD::SetIN(Float_t p1, Float_t p2, Float_t p3,Float_t p4,Float_t p5)
{
  //
  // Set PMD parameters
  //
  fIn[0] = p1;
  fIn[1] = p2;
  fIn[2] = p3;
  fIn[3] = p4;
  fIn[4] = p5;
}

//_____________________________________________________________________________
void AliPMD::SetGEO(Float_t p1, Float_t p2, Float_t p3)
{
  //
  // Set geometry parameters
  //
  fGeo[0] = p1;
  fGeo[1] = p2;
  fGeo[2] = p3;
}

//_____________________________________________________________________________
void AliPMD::SetPadSize(Float_t p1, Float_t p2, Float_t p3,Float_t p4)
{
  //
  // Set pad size
  //
  fPadSize[0] = p1;
  fPadSize[1] = p2;
  fPadSize[2] = p3;
  fPadSize[3] = p4;
}

//_____________________________________________________________________________
void AliPMD::StepManager()
{
  //
  // Called at every step in PMD
  //
}

void AliPMD::MakeBranch(Option_t* option)
{
    // Create Tree branches for the PMD

    const char *cH = strstr(option,"H");
    if (cH && fLoader->TreeH() && (fHits == 0x0))
      fHits   = new TClonesArray("AliPMDhit",  405);

    AliDetector::MakeBranch(option);
}

void AliPMD::SetTreeAddress()
{
  // Set branch address

    if (fLoader->TreeH() && fHits==0x0)
      fHits   = new TClonesArray("AliPMDhit",  405);

    AliDetector::SetTreeAddress();
}

//____________________________________________________________________________
void AliPMD::Hits2SDigits()
{
// create summable digits

  AliRunLoader* runLoader = fLoader->GetRunLoader();
  AliPMDDigitizer* pmdDigitizer = new AliPMDDigitizer;
  pmdDigitizer->OpengAliceFile(fLoader->GetRunLoader()->GetFileName().Data(),
			       "HS");
  pmdDigitizer->SetZPosition(361.5);

  for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
    pmdDigitizer->Hits2SDigits(iEvent);
  }
  fLoader->UnloadHits();
  fLoader->UnloadSDigits();
  delete pmdDigitizer;
}
//____________________________________________________________________________
void AliPMD::SDigits2Digits()
{
  // creates sdigits to digits
}
//____________________________________________________________________________
void AliPMD::Hits2Digits()
{
// create digits

  AliRunLoader* runLoader = fLoader->GetRunLoader();
  AliPMDDigitizer* pmdDigitizer = new AliPMDDigitizer;
  pmdDigitizer->OpengAliceFile(fLoader->GetRunLoader()->GetFileName().Data(),
			       "HD");
  pmdDigitizer->SetZPosition(361.5);

  for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
    pmdDigitizer->Hits2Digits(iEvent);
  }
  fLoader->UnloadHits();
  fLoader->UnloadDigits();
  delete pmdDigitizer;

}
// ---------------------------------------------------------------------------
AliDigitizer* AliPMD::CreateDigitizer(AliRunDigitizer* manager) const
{
  return new AliPMDDigitizer(manager);
}
// ---------------------------------------------------------------------------
void AliPMD::Digits2Raw()
{
// convert digits of the current event to raw data

  fLoader->LoadDigits();
  TTree* digits = fLoader->TreeD();
  if (!digits) {
    AliError("No digits tree");
    return;
  }

  AliPMDDDLRawData rawWriter;
  rawWriter.WritePMDRawData(digits);

  fLoader->UnloadDigits();
}
Bool_t AliPMD::Raw2SDigits()
{

}

<commit_msg>Dummy return<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * 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.                  *
 **************************************************************************/

/* $Id$ */

///////////////////////////////////////////////////////////////////////////////
//
//                                                                           //
//  Photon Multiplicity Detector                                             //
//  This class contains the basic functions for the Photon Multiplicity      //
//  Detector. Functions specific to one particular geometry are              //
//  contained in the derived classes                                         //
//                                                                           //
//Begin_Html
/*

The responsible person for this module is
Subhasis Chattopadhyay.

*/
//End_Html
//                                                                           //
///////////////////////////////////////////////////////////////////////////////

#include <TBRIK.h>
#include <TClonesArray.h>
#include <TGeometry.h>
#include <TNode.h>
#include <TTree.h>
#include <TVirtualMC.h>

#include "AliLog.h"
#include "AliLoader.h"
#include "AliPMDLoader.h"
#include "AliPMD.h"
#include "AliRun.h"
#include "AliMC.h"
#include "AliPMDDigitizer.h"
#include "AliPMDhit.h"
#include "AliPMDDDLRawData.h"

ClassImp(AliPMD)

//_____________________________________________________________________________
AliPMD::AliPMD()
{
  //
  // Default constructor
  //
  fIshunt = 0;

}

//_____________________________________________________________________________
AliPMD::AliPMD(const char *name, const char *title)
  : AliDetector(name,title)
{
  //
  // Default constructor
  //

  //
  // Allocate the array of hits
  fHits   = new TClonesArray("AliPMDhit",  405);
  gAlice->GetMCApp()->AddHitList(fHits);

  fIshunt =  0;

  fPar[0] = 1;
  fPar[1] = 1;
  fPar[2] = 0.8;
  fPar[3] = 0.02;
  fIn[0]  = 6;
  fIn[1]  = 20;
  fIn[2]  = 600;
  fIn[3]  = 27;
  fIn[4]  = 27;
  fGeo[0] = 0;
  fGeo[1] = 0.2;
  fGeo[2] = 4;
  fPadSize[0] = 0.8;
  fPadSize[1] = 1.0;
  fPadSize[2] = 1.2;
  fPadSize[3] = 1.5;
}

AliLoader* AliPMD::MakeLoader(const char* topfoldername)
{
  // Makes PMD Loader

  fLoader = new AliPMDLoader(GetName(),topfoldername);

  if (fLoader)
    {
      AliDebug(100,"Success");
    }
  else
    {
      AliError("Failure");
    }

  return fLoader;
}

AliPMD::~AliPMD()
{
  //
  // Destructor
  //
}

//_____________________________________________________________________________
void AliPMD::AddHit(Int_t track, Int_t *vol, Float_t *hits)
{
  //
  // Add a PMD hit
  //
  TClonesArray &lhits = *fHits;
  AliPMDhit *newcell, *curcell;
  //  printf("PMD++ Adding energy %f, prim %d, vol %d %d %d %d %d %d %d %d\n",
  // hits[3],gAlice->GetPrimary(track-1),vol[0],vol[1],vol[2],vol[3],
  // vol[4],vol[5],vol[6],vol[7]);

  newcell = new AliPMDhit(fIshunt, track, vol, hits);
  Int_t i;
  for (i=0; i<fNhits; i++) {
    //
    // See if this cell has already been hit
    curcell=(AliPMDhit*) lhits[i];
    if (*curcell==*newcell) {
//        printf("Cell with same numbers found\n") ; curcell->Print();
      *curcell = *curcell+*newcell;
//        printf("Cell after addition\n") ; curcell->Print();
      delete newcell;
      return;
    }
  }
  new(lhits[fNhits++]) AliPMDhit(newcell);
  delete newcell;
}

//_____________________________________________________________________________
void AliPMD::BuildGeometry()
{
  //
  // Build simple ROOT TNode geometry for event display
  //

  TNode *node, *top;
  const int kColorPMD  = kRed;

  //
  top=gAlice->GetGeometry()->GetNode("alice");

  // PMD
  new TBRIK("S_PMD","PMD box","void",300,300,5);
  top->cd();
  node = new TNode("PMD","PMD","S_PMD",0,0,-600,"");
  node->SetLineColor(kColorPMD);
  fNodes->Add(node);
}

//_____________________________________________________________________________
void AliPMD::SetPAR(Float_t p1, Float_t p2, Float_t p3,Float_t p4)
{
  //
  // Set PMD parameters
  //
  fPar[0] = p1;
  fPar[1] = p2;
  fPar[2] = p3;
  fPar[3] = p4;
}

//_____________________________________________________________________________
void AliPMD::SetIN(Float_t p1, Float_t p2, Float_t p3,Float_t p4,Float_t p5)
{
  //
  // Set PMD parameters
  //
  fIn[0] = p1;
  fIn[1] = p2;
  fIn[2] = p3;
  fIn[3] = p4;
  fIn[4] = p5;
}

//_____________________________________________________________________________
void AliPMD::SetGEO(Float_t p1, Float_t p2, Float_t p3)
{
  //
  // Set geometry parameters
  //
  fGeo[0] = p1;
  fGeo[1] = p2;
  fGeo[2] = p3;
}

//_____________________________________________________________________________
void AliPMD::SetPadSize(Float_t p1, Float_t p2, Float_t p3,Float_t p4)
{
  //
  // Set pad size
  //
  fPadSize[0] = p1;
  fPadSize[1] = p2;
  fPadSize[2] = p3;
  fPadSize[3] = p4;
}

//_____________________________________________________________________________
void AliPMD::StepManager()
{
  //
  // Called at every step in PMD
  //
}

void AliPMD::MakeBranch(Option_t* option)
{
    // Create Tree branches for the PMD

    const char *cH = strstr(option,"H");
    if (cH && fLoader->TreeH() && (fHits == 0x0))
      fHits   = new TClonesArray("AliPMDhit",  405);

    AliDetector::MakeBranch(option);
}

void AliPMD::SetTreeAddress()
{
  // Set branch address

    if (fLoader->TreeH() && fHits==0x0)
      fHits   = new TClonesArray("AliPMDhit",  405);

    AliDetector::SetTreeAddress();
}

//____________________________________________________________________________
void AliPMD::Hits2SDigits()
{
// create summable digits

  AliRunLoader* runLoader = fLoader->GetRunLoader();
  AliPMDDigitizer* pmdDigitizer = new AliPMDDigitizer;
  pmdDigitizer->OpengAliceFile(fLoader->GetRunLoader()->GetFileName().Data(),
			       "HS");
  pmdDigitizer->SetZPosition(361.5);

  for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
    pmdDigitizer->Hits2SDigits(iEvent);
  }
  fLoader->UnloadHits();
  fLoader->UnloadSDigits();
  delete pmdDigitizer;
}
//____________________________________________________________________________
void AliPMD::SDigits2Digits()
{
  // creates sdigits to digits
}
//____________________________________________________________________________
void AliPMD::Hits2Digits()
{
// create digits

  AliRunLoader* runLoader = fLoader->GetRunLoader();
  AliPMDDigitizer* pmdDigitizer = new AliPMDDigitizer;
  pmdDigitizer->OpengAliceFile(fLoader->GetRunLoader()->GetFileName().Data(),
			       "HD");
  pmdDigitizer->SetZPosition(361.5);

  for (Int_t iEvent = 0; iEvent < runLoader->GetNumberOfEvents(); iEvent++) {
    pmdDigitizer->Hits2Digits(iEvent);
  }
  fLoader->UnloadHits();
  fLoader->UnloadDigits();
  delete pmdDigitizer;

}
// ---------------------------------------------------------------------------
AliDigitizer* AliPMD::CreateDigitizer(AliRunDigitizer* manager) const
{
  return new AliPMDDigitizer(manager);
}
// ---------------------------------------------------------------------------
void AliPMD::Digits2Raw()
{
// convert digits of the current event to raw data

  fLoader->LoadDigits();
  TTree* digits = fLoader->TreeD();
  if (!digits) {
    AliError("No digits tree");
    return;
  }

  AliPMDDDLRawData rawWriter;
  rawWriter.WritePMDRawData(digits);

  fLoader->UnloadDigits();
}
Bool_t AliPMD::Raw2SDigits()
{
  return kTRUE;
}

<|endoftext|>


<commit_before>#ifndef POPULATION_HPP
#define POPULATION_HPP

namespace galgo {

//=================================================================================================

template <typename T, int N = 16>
class Population
{
   static_assert(std::is_same<float,T>::value || std::is_same<double,T>::value, "variable type can only be float or double, please amend.");
   static_assert(N > 0 && N <= 64, "number of bits cannot be ouside interval [1,64], please amend N");

   template <typename K, int S>
   friend class GeneticAlgorithm;

public:
   // nullary constructor
   Population() {}
   // constructor
   Population(const GeneticAlgorithm<T,N>& ga);
   // create a population of chromosomes
   void creation();
   // evolve population, get next generation
   void evolution();

   // access element in current population at position pos
   const CHR<T,N>& operator()(int pos) const;
   // access element in mating population at position pos
   const CHR<T,N>& operator[](int pos) const;
   // return iterator at current population beginning
   typename std::vector<CHR<T,N>>::iterator begin();
   // return const iterator at current population beginning
   typename std::vector<CHR<T,N>>::const_iterator cbegin() const;
   // return iterator at current population ending
   typename std::vector<CHR<T,N>>::iterator end();
   // return const iterator at current population ending
   typename std::vector<CHR<T,N>>::const_iterator cend() const;
   // select element at position pos in current population and copy it into mating population
   void select(int pos);
   // set all fitness to positive values
   void adjustFitness();
   // compute fitness sum of current population
   T getSumFitness() const;
   // get worst objective function total result from current population
   T getWorstTotal() const;
   // return population size
   int popsize() const;
   // return mating population size
   int matsize() const;
   // return tournament size
   int tntsize() const;
   // return numero of generation
   int nogen() const;
   // return number of generations
   int nbgen() const;
   // return selection pressure
   T SP() const;

private:
   std::vector<CHR<T,N>> curpop;               // current population
   std::vector<CHR<T,N>> matpop;               // mating population
   std::vector<CHR<T,N>> newpop;               // new population

   const GeneticAlgorithm<T,N>* ptr = nullptr; // pointer to genetic algorithm
   int nbrcrov;                                // number of cross-over
   int matidx;                                 // mating population index

   // elitism => saving best chromosomes in new population
   void elitism();
   // create new population from recombination of the old one
   void recombination();
   // complete new population randomly
   void completion();
   // update population (adapting, sorting)
   void updating();
};

/*-------------------------------------------------------------------------------------------------*/

// constructor
template <typename T, int N>
Population<T,N>::Population(const GeneticAlgorithm<T,N>& ga)
{
   ptr = &ga;
   nbrcrov = floor(ga.covrate * (ga.popsize - ga.elitpop));
   // adjusting nbrcrov (must be an even number)
   if (nbrcrov % 2 != 0) nbrcrov -= 1;
   // for convenience, we add elitpop to nbrcrov
   nbrcrov += ga.elitpop;
   // allocating memory
   curpop.resize(ga.popsize);
   matpop.resize(ga.matsize);
}

/*-------------------------------------------------------------------------------------------------*/

// create a population of chromosomes
template <typename T, int N>
void Population<T,N>::creation()
{
   // initializing first chromosome
   curpop[0] = std::make_shared<Chromosome<T,N>>(*ptr);
   if (!ptr->initialSet.empty()) {
      curpop[0]->initialize();
   } else {
      curpop[0]->create();
   }
   curpop[0]->evaluate();

   // getting the rest
   #ifdef _OPENMP
   #pragma omp parallel for num_threads(MAX_THREADS)
   #endif
   for (int i = 1; i < ptr->popsize; ++i) {
      curpop[i] = std::make_shared<Chromosome<T,N>>(*ptr);
      curpop[i]->create();
      curpop[i]->evaluate();
   }
   // updating population
   this->updating();
}

/*-------------------------------------------------------------------------------------------------*/

// population evolution (selection, recombination, completion, mutation), get next generation
template <typename T, int N>
void Population<T,N>::evolution()
{
   // initializing mating population index
   matidx = 0;
   // selecting mating population
   ptr->Selection(*this);
   // applying elitism if required
   this->elitism();
   // crossing-over mating population
   this->recombination();
   // completing new population
   this->completion();
   // moving new population into current population for next generation
   curpop = std::move(newpop);
   // updating population
   this->updating();
}

/*-------------------------------------------------------------------------------------------------*/

// elitism => saving best chromosomes in new population, making a copy of each elit chromosome
template <typename T, int N>
void Population<T,N>::elitism()
{
   // (re)allocating new population
   newpop.resize(ptr->popsize);

   if (ptr->elitpop > 0) {
      // copying elit chromosomes into new population
      std::transform(curpop.cbegin(), curpop.cend(), newpop.begin(), [](const CHR<T,N>& chr)->CHR<T,N>{return std::make_shared<Chromosome<T,N>>(*chr);});
   }
}

/*-------------------------------------------------------------------------------------------------*/

// create new population from recombination of the old one
template <typename T, int N>
void Population<T,N>::recombination()
{
   // creating a new population by cross-over
   #ifdef _OPENMP
   #pragma omp parallel for num_threads(MAX_THREADS)
   #endif
   for (int i = ptr->elitpop; i < nbrcrov; i = i + 2) {
      // initializing 2 new chromosome
      newpop[i] = std::make_shared<Chromosome<T,N>>(*ptr);
      newpop[i+1] = std::make_shared<Chromosome<T,N>>(*ptr);
      // crossing-over mating population to create 2 new chromosomes
      ptr->CrossOver(*this, newpop[i], newpop[i+1]);
      // mutating new chromosomes
      ptr->Mutation(newpop[i]);
      ptr->Mutation(newpop[i+1]);
      // evaluating new chromosomes
      newpop[i]->evaluate();
      newpop[i+1]->evaluate();
   }
}

/*-------------------------------------------------------------------------------------------------*/

// complete new population
template <typename T, int N>
void Population<T,N>::completion()
{
   #ifdef _OPENMP
   #pragma omp parallel for num_threads(MAX_THREADS)
   #endif
   for (int i = nbrcrov; i < ptr->popsize; ++i) {
      // selecting chromosome randomly from mating population
      newpop[i] = std::make_shared<Chromosome<T,N>>(*matpop[uniform<int>(0, ptr->matsize)]);
      // mutating chromosome
      ptr->Mutation(newpop[i]);
      // evaluating chromosome
      newpop[i]->evaluate();
   }
}

/*-------------------------------------------------------------------------------------------------*/

// update population (adapting, sorting)
template <typename T, int N>
void Population<T,N>::updating()
{
   // adapting population to constraints
   if (ptr->Constraint != nullptr) {
      ptr->Adaptation(*this);
   }
   // sorting chromosomes from best to worst fitness
   std::sort(curpop.begin(),curpop.end(),[](const CHR<T,N>& chr1,const CHR<T,N>& chr2)->bool{return chr1->fitness > chr2->fitness;});
}

/*-------------------------------------------------------------------------------------------------*/

// access element in current population at position pos
template <typename T, int N>
const CHR<T,N>& Population<T,N>::operator()(int pos) const
{
   #ifndef NDEBUG
   if (pos > ptr->popsize - 1) {
      throw std::invalid_argument("Error: in galgo::Population<T>::operator()(int), exceeding current population memory.");
   }
   #endif

   return curpop[pos];
}

/*-------------------------------------------------------------------------------------------------*/

// access element in mating population at position pos
template <typename T, int N>
const CHR<T,N>& Population<T,N>::operator[](int pos) const
{
   #ifndef NDEBUG
   if (pos > ptr->matsize - 1) {
      throw std::invalid_argument("Error: in galgo::Population<T>::operator[](int), exceeding mating population memory.");
   }
   #endif

   return matpop[pos];
}

/*-------------------------------------------------------------------------------------------------*/

// return iterator at current population beginning
template <typename T, int N>
inline typename std::vector<CHR<T,N>>::iterator Population<T,N>::begin()
{
   return curpop.begin();
}

/*-------------------------------------------------------------------------------------------------*/

// return const iterator at current population beginning
template <typename T, int N>
inline typename std::vector<CHR<T,N>>::const_iterator Population<T,N>::cbegin() const
{
   return curpop.cbegin();
}

/*-------------------------------------------------------------------------------------------------*/

// return iterator at current population ending
template <typename T, int N>
inline typename std::vector<CHR<T,N>>::iterator Population<T,N>::end()
{
   return curpop.end();
}

/*-------------------------------------------------------------------------------------------------*/

// return const iterator at current population ending
template <typename T, int N>
inline typename std::vector<CHR<T,N>>::const_iterator Population<T,N>::cend() const
{
   return curpop.cend();
}

/*-------------------------------------------------------------------------------------------------*/

// select element at position pos in current population and copy it into mating population
template <typename T, int N>
inline void Population<T,N>::select(int pos)
{
   #ifndef NDEBUG
   if (pos > ptr->popsize - 1) {
      throw std::invalid_argument("Error: in galgo::Population<T>::select(int), exceeding current population memory.");
   }
   if (matidx == ptr->matsize) {
      throw std::invalid_argument("Error: in galgo::Population<T>::select(int), exceeding mating population memory.");
   }
   #endif

   matpop[matidx] = curpop[pos];
   matidx++;
}

/*-------------------------------------------------------------------------------------------------*/

// set all fitness to positive values (used in RWS and SUS selection methods)
template <typename T, int N>
void Population<T,N>::adjustFitness()
{
   // getting worst population fitness
   T worstFitness = curpop.back()->fitness;

   if (worstFitness < 0) {
      // getting best fitness
      T bestFitness = curpop.front()->fitness;
      // case where all fitness are equal and negative
      if (worstFitness == bestFitness) {
         std::for_each(curpop.begin(), curpop.end(), [](CHR<T,N>& chr)->void{chr->fitness *= -1;});
       } else {
         std::for_each(curpop.begin(), curpop.end(), [worstFitness](CHR<T,N>& chr)->void{chr->fitness -= worstFitness;});
      }
   }
}

/*-------------------------------------------------------------------------------------------------*/

// compute population fitness sum (used in TRS, RWS and SUS selection methods)
template <typename T, int N>
inline T Population<T,N>::getSumFitness() const
{
   return std::accumulate(curpop.cbegin(), curpop.cend(), 0.0, [](T sum, const CHR<T,N>& chr)->T{return sum + T(chr->fitness);});
}

/*-------------------------------------------------------------------------------------------------*/

// get worst objective function total result from current population (used in constraint(s) adaptation)
template <typename T, int N>
inline T Population<T,N>::getWorstTotal() const
{
   auto it = std::min_element(curpop.begin(), curpop.end(), [](const CHR<T,N>& chr1, const CHR<T,N>& chr2)->bool{return chr1->getTotal() < chr2->getTotal();});

   return (*it)->getTotal();
}

/*-------------------------------------------------------------------------------------------------*/

// return population size
template <typename T, int N>
inline int Population<T,N>::popsize() const
{
   return ptr->popsize;
}

/*-------------------------------------------------------------------------------------------------*/

// return mating population size
template <typename T, int N>
inline int Population<T,N>::matsize() const
{
   return ptr->matsize;
}

/*-------------------------------------------------------------------------------------------------*/

// return tournament size
template <typename T, int N>
inline int Population<T,N>::tntsize() const
{
   return ptr->tntsize;
}

/*-------------------------------------------------------------------------------------------------*/

// return numero of generation
template <typename T, int N>
inline int Population<T,N>::nogen() const
{
   return ptr->nogen;
}

/*-------------------------------------------------------------------------------------------------*/

// return number of generations
template <typename T, int N>
inline int Population<T,N>::nbgen() const
{
   return ptr->nbgen;
}

/*-------------------------------------------------------------------------------------------------*/

// return selection pressure
template <typename T, int N>
inline T Population<T,N>::SP() const
{
   return ptr->SP;
}

//=================================================================================================

}

#endif

<commit_msg>Delete Population.hpp<commit_after><|endoftext|>


<commit_before>#include "RestClient.h"

#ifdef HTTP_DEBUG
#define HTTP_DEBUG_PRINT(string) (Serial.print(string))
#endif

#ifndef HTTP_DEBUG
#define HTTP_DEBUG_PRINT(string)
#endif

RestClient::RestClient(const char* _host){
  host = _host;
  port = 80;
  num_headers = 0;
  contentType = "x-www-form-urlencoded";	// default
}

RestClient::RestClient(const char* _host, int _port){
  host = _host;
  port = _port;
  num_headers = 0;
  contentType = "x-www-form-urlencoded";	// default
}

void RestClient::dhcp(){
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
  if (begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
  }
  //give it time to initialize
  delay(1000);
}

int RestClient::begin(byte mac[]){
  return Ethernet.begin(mac);
  //give it time to initialize
  delay(1000);
}

// GET path
int RestClient::get(const char* path){
  return request("GET", path, NULL, NULL);
}

//GET path with response
int RestClient::get(const char* path, String* response){
  return request("GET", path, NULL, response);
}

// POST path and body
int RestClient::post(const char* path, const char* body){
  return request("POST", path, body, NULL);
}

// POST path and body with response
int RestClient::post(const char* path, const char* body, String* response){
  return request("POST", path, body, response);
}

// PUT path and body
int RestClient::put(const char* path, const char* body){
  return request("PUT", path, body, NULL);
}

// PUT path and body with response
int RestClient::put(const char* path, const char* body, String* response){
  return request("PUT", path, body, response);
}

// DELETE path
int RestClient::del(const char* path){
  return request("DELETE", path, NULL, NULL);
}

// DELETE path and response
int RestClient::del(const char* path, String* response){
  return request("DELETE", path, NULL, response);
}

// DELETE path and body
int RestClient::del(const char* path, const char* body ){
  return request("DELETE", path, body, NULL);
}

// DELETE path and body with response
int RestClient::del(const char* path, const char* body, String* response){
  return request("DELETE", path, body, response);
}

void RestClient::write(const char* string){
  HTTP_DEBUG_PRINT(string);
  client.print(string);
}

void RestClient::setHeader(const char* header){
  headers[num_headers] = header;
  num_headers++;
}

void RestClient::setContentType(const char* contentTypeValue){
  contentType = contentTypeValue;
}

// The mother- generic request method.
//
int RestClient::request(const char* method, const char* path,
                  const char* body, String* response){

  HTTP_DEBUG_PRINT("HTTP: connect\n");

  if(client.connect(host, port)){
    HTTP_DEBUG_PRINT("HTTP: connected\n");
    HTTP_DEBUG_PRINT("REQUEST: \n");
    // Make a HTTP request line:
    write(method);
    write(" ");
    write(path);
    write(" HTTP/1.1\r\n");
    for(int i=0; i<num_headers; i++){
      write(headers[i]);
      write("\r\n");
    }
    write("Host: ");
    write(host);
    write("\r\n");
    write("Connection: close\r\n");

    if(body != NULL){
      char contentLength[30];
      sprintf(contentLength, "Content-Length: %d\r\n", strlen(body));
      write(contentLength);

	  write("Content-Type: ");
	  write(contentType);
	  write("\r\n");
    }

    write("\r\n");

    if(body != NULL){
      write(body);
      write("\r\n");
      write("\r\n");
    }

    //make sure you write all those bytes.
    delay(100);

    HTTP_DEBUG_PRINT("HTTP: call readResponse\n");
    int statusCode = readResponse(response);
    HTTP_DEBUG_PRINT("HTTP: return readResponse\n");

    //cleanup
    HTTP_DEBUG_PRINT("HTTP: stop client\n");
    num_headers = 0;
    client.stop();
    delay(50);
    HTTP_DEBUG_PRINT("HTTP: client stopped\n");

    return statusCode;
  }else{
    HTTP_DEBUG_PRINT("HTTP Connection failed\n");
    return 0;
  }
}

int RestClient::readResponse(String* response) {

  // an http request ends with a blank line
  boolean currentLineIsBlank = true;
  boolean httpBody = false;
  boolean inStatus = false;

  char statusCode[4];
  int i = 0;
  int code = 0;

  if(response == NULL){
    HTTP_DEBUG_PRINT("HTTP: NULL RESPONSE POINTER: \n");
  }else{
    HTTP_DEBUG_PRINT("HTTP: NON-NULL RESPONSE POINTER: \n");
  }

  HTTP_DEBUG_PRINT("HTTP: RESPONSE: \n");
  while (client.connected()) {
    HTTP_DEBUG_PRINT(".");

    if (client.available()) {
      HTTP_DEBUG_PRINT(",");

      char c = client.read();
      HTTP_DEBUG_PRINT(c);

      if(c == ' ' && !inStatus){
        inStatus = true;
      }

      if(inStatus && i < 3 && c != ' '){
        statusCode[i] = c;
        i++;
      }
      if(i == 3){
        statusCode[i] = '\0';
        code = atoi(statusCode);
      }

      if(httpBody){
        //only write response if its not null
        if(response != NULL) response->concat(c);
      }
      else
      {
          if (c == '\n' && currentLineIsBlank) {
            httpBody = true;
          }

          if (c == '\n') {
            // you're starting a new line
            currentLineIsBlank = true;
          }
          else if (c != '\r') {
            // you've gotten a character on the current line
            currentLineIsBlank = false;
          }
      }
    }
  }

  HTTP_DEBUG_PRINT("HTTP: return readResponse3\n");
  return code;
}
<commit_msg>Fix Default contentType<commit_after>#include "RestClient.h"

#ifdef HTTP_DEBUG
#define HTTP_DEBUG_PRINT(string) (Serial.print(string))
#endif

#ifndef HTTP_DEBUG
#define HTTP_DEBUG_PRINT(string)
#endif

RestClient::RestClient(const char* _host){
  host = _host;
  port = 80;
  num_headers = 0;
  contentType = "application/x-www-form-urlencoded";	// default
}

RestClient::RestClient(const char* _host, int _port){
  host = _host;
  port = _port;
  num_headers = 0;
  contentType = "application/x-www-form-urlencoded";	// default
}

void RestClient::dhcp(){
  byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
  if (begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
  }
  //give it time to initialize
  delay(1000);
}

int RestClient::begin(byte mac[]){
  return Ethernet.begin(mac);
  //give it time to initialize
  delay(1000);
}

// GET path
int RestClient::get(const char* path){
  return request("GET", path, NULL, NULL);
}

//GET path with response
int RestClient::get(const char* path, String* response){
  return request("GET", path, NULL, response);
}

// POST path and body
int RestClient::post(const char* path, const char* body){
  return request("POST", path, body, NULL);
}

// POST path and body with response
int RestClient::post(const char* path, const char* body, String* response){
  return request("POST", path, body, response);
}

// PUT path and body
int RestClient::put(const char* path, const char* body){
  return request("PUT", path, body, NULL);
}

// PUT path and body with response
int RestClient::put(const char* path, const char* body, String* response){
  return request("PUT", path, body, response);
}

// DELETE path
int RestClient::del(const char* path){
  return request("DELETE", path, NULL, NULL);
}

// DELETE path and response
int RestClient::del(const char* path, String* response){
  return request("DELETE", path, NULL, response);
}

// DELETE path and body
int RestClient::del(const char* path, const char* body ){
  return request("DELETE", path, body, NULL);
}

// DELETE path and body with response
int RestClient::del(const char* path, const char* body, String* response){
  return request("DELETE", path, body, response);
}

void RestClient::write(const char* string){
  HTTP_DEBUG_PRINT(string);
  client.print(string);
}

void RestClient::setHeader(const char* header){
  headers[num_headers] = header;
  num_headers++;
}

void RestClient::setContentType(const char* contentTypeValue){
  contentType = contentTypeValue;
}

// The mother- generic request method.
//
int RestClient::request(const char* method, const char* path,
                  const char* body, String* response){

  HTTP_DEBUG_PRINT("HTTP: connect\n");

  if(client.connect(host, port)){
    HTTP_DEBUG_PRINT("HTTP: connected\n");
    HTTP_DEBUG_PRINT("REQUEST: \n");
    // Make a HTTP request line:
    write(method);
    write(" ");
    write(path);
    write(" HTTP/1.1\r\n");
    for(int i=0; i<num_headers; i++){
      write(headers[i]);
      write("\r\n");
    }
    write("Host: ");
    write(host);
    write("\r\n");
    write("Connection: close\r\n");

    if(body != NULL){
      char contentLength[30];
      sprintf(contentLength, "Content-Length: %d\r\n", strlen(body));
      write(contentLength);

	  write("Content-Type: ");
	  write(contentType);
	  write("\r\n");
    }

    write("\r\n");

    if(body != NULL){
      write(body);
      write("\r\n");
      write("\r\n");
    }

    //make sure you write all those bytes.
    delay(100);

    HTTP_DEBUG_PRINT("HTTP: call readResponse\n");
    int statusCode = readResponse(response);
    HTTP_DEBUG_PRINT("HTTP: return readResponse\n");

    //cleanup
    HTTP_DEBUG_PRINT("HTTP: stop client\n");
    num_headers = 0;
    client.stop();
    delay(50);
    HTTP_DEBUG_PRINT("HTTP: client stopped\n");

    return statusCode;
  }else{
    HTTP_DEBUG_PRINT("HTTP Connection failed\n");
    return 0;
  }
}

int RestClient::readResponse(String* response) {

  // an http request ends with a blank line
  boolean currentLineIsBlank = true;
  boolean httpBody = false;
  boolean inStatus = false;

  char statusCode[4];
  int i = 0;
  int code = 0;

  if(response == NULL){
    HTTP_DEBUG_PRINT("HTTP: NULL RESPONSE POINTER: \n");
  }else{
    HTTP_DEBUG_PRINT("HTTP: NON-NULL RESPONSE POINTER: \n");
  }

  HTTP_DEBUG_PRINT("HTTP: RESPONSE: \n");
  while (client.connected()) {
    HTTP_DEBUG_PRINT(".");

    if (client.available()) {
      HTTP_DEBUG_PRINT(",");

      char c = client.read();
      HTTP_DEBUG_PRINT(c);

      if(c == ' ' && !inStatus){
        inStatus = true;
      }

      if(inStatus && i < 3 && c != ' '){
        statusCode[i] = c;
        i++;
      }
      if(i == 3){
        statusCode[i] = '\0';
        code = atoi(statusCode);
      }

      if(httpBody){
        //only write response if its not null
        if(response != NULL) response->concat(c);
      }
      else
      {
          if (c == '\n' && currentLineIsBlank) {
            httpBody = true;
          }

          if (c == '\n') {
            // you're starting a new line
            currentLineIsBlank = true;
          }
          else if (c != '\r') {
            // you've gotten a character on the current line
            currentLineIsBlank = false;
          }
      }
    }
  }

  HTTP_DEBUG_PRINT("HTTP: return readResponse3\n");
  return code;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <cassert>

#include "KDTree.hpp"
#include "KDTreeNode.hpp"
#include "Point.hpp"
#include "MWC.hpp"

using namespace std;

//#define VERBOSE

void BenchMark(const int numPoints, const int repetitions, ostream& out);
const Point& BruteForceNearestNeighbour(const vector<Point*>& pointList, const Point& point);
void InternetExample1(vector<Point*>& points);

//______________________________________________________________________________
int main(int argc, char **argv) {
   ofstream out("benchmark_data.txt");
   out << "Num Points" << "\t" << "Brute Force Time" << "\t" << "Tree Search Time" << "\t";
   out << "Std Dev Brute Force" << "\t" << "Std Dev Tree Search" << endl;
   BenchMark(10, 10, out);
   BenchMark(100, 10, out);
   BenchMark(1000, 10, out);
   BenchMark(10000, 10, out);
   BenchMark(100000, 10, out);
//   BenchMark(1000000, 10, out);
//   BenchMark(10000000, 10, out);
   return 0;
}

//______________________________________________________________________________
void BenchMark(const int numPoints, const int repetitions, ostream& out) {
   // -- Benchmark builds 'numPoints' random points, constructs a kd-tree of these points
   // -- then tests how long it takes to calculate the nearest neighbour of some random search point
   // -- against an brute-force search
   #ifdef VERBOSE
      cout << "Benchmarking kd-tree nearest neighbour search, against brute-force search" << endl;
   #endif
   //-----------------------------------------------------------
   // -- Generate random points
   MWC rng;
   vector<Point*> points;
   for (int i=0; i<numPoints; i++) {
      points.push_back(new Point(rng.rnd(),rng.rnd(),rng.rnd()));
   }
   // Print points
   #ifdef VERBOSE
      cout << "--------------------" << endl;
      cout << "Input Points" << endl;
      vector<Point*>::iterator it;
      for (it = points.begin(); it != points.end(); it++) {
         cout << it - points.begin() << "\t" << (*it)->ToString() << endl;
      }
      cout << "--------------------" << endl;
   #endif
   //-----------------------------------------------------------
   // -- Build Tree
   // Set up timing
   clock_t start, end;
   start = clock();
   KDTree tree(points);
   // Output time to build tree
   end = clock();
   const double treeBuildTime = (double)(end-start)/CLOCKS_PER_SEC;
   cout << "--------------------" << endl;
   cout << "Number of points in Tree: " << numPoints << endl;
   cout << "Time required to build Tree: ";
   cout << treeBuildTime;
   cout << " seconds." << endl;
   //-----------------------------------------------------------
   // Repeat search for number of times defined by 'repetitions'
   // Store all times in vector for averaging and std dev
   double totBruteForceTime = 0.;
   double totTreeSearchTime = 0.;
   vector<double> bruteForceTimes;
   vector<double> treeSearchTimes;
   for (int iter = 0; iter < repetitions; iter++) {
      Point searchPoint(rng.rnd(),rng.rnd(),rng.rnd());
      #ifdef VERBOSE
         cout << "--------------------" << endl;
         cout << "Search Point: " << searchPoint.ToString() << endl;
      #endif
      //-----------------------------------------------------------
      // -- Perform Brute force search for point
      // Set up timing
      start = clock();
      #ifdef VERBOSE
         cout << "--------------------" << endl;
         cout << "Performing Brute Force Search..." << endl;
      #endif
      const Point& brutePoint = BruteForceNearestNeighbour(points, searchPoint);
      // Output time to build tree
      end = clock();
      const double bruteForceTime = (double)(end-start)/CLOCKS_PER_SEC;
      //-----------------------------------------------------------
      // -- Perform Tree-based search for point
      // Set up timing
      start = clock();
      #ifdef VERBOSE
         cout << "--------------------" << endl;
         cout << "Performing Tree-based Search..." << endl;
      #endif
      const Point& treePoint = tree.NearestNeighbour(searchPoint);
      // calculate time to build tree
      end = clock();
      const double treeSearchTime = (double)(end-start)/CLOCKS_PER_SEC;
      //-----------------------------------------------------------
      #ifdef VERBOSE
         cout << "--------------------" << endl;
         cout << "Brute force solution: " << brutePoint.ToString() << endl;
         cout << "Time required for Brute force search: ";
         cout << bruteForceTime;
         cout << " seconds." << endl;
         cout << "--------------------" << endl;
         cout << "Tree solution: " << treePoint.ToString() << endl;
         cout << "Time required for Tree search: ";
         cout << treeSearchTime;
         cout << " seconds." << endl;
         cout << "--------------------" << endl;
      #endif
      assert(treePoint == brutePoint);
      bruteForceTimes.push_back(bruteForceTime);
      treeSearchTimes.push_back(treeSearchTime);
      totBruteForceTime += bruteForceTime;
      totTreeSearchTime += treeSearchTime;

   }
   // Calculate mean search times
   double avgBruteForceTime = totBruteForceTime/repetitions;
   double avgTreeSearchTime = totTreeSearchTime/repetitions;
   // Calculate Std Dev
   double sumBrute = 0.;
   double sumTree = 0.;
   for (int iter = 0; iter < repetitions; iter++) {
      sumBrute += pow((bruteForceTimes[iter] - avgBruteForceTime), 2.0);
      sumTree += pow((treeSearchTimes[iter] - avgTreeSearchTime), 2.0);
   }
   double stdDevBrute = sqrt(sumBrute/(repetitions-1));
   double stdDevTree = sqrt(sumTree/(repetitions-1));
   #ifdef VERBOSE
      cout << "--------------------" << endl;
      cout << "Average Time required for Brute force search: ";
      cout << avgBruteForceTime;
      cout << " seconds." << endl;
      cout << "--------------------" << endl;
      cout << "Average Time required for Tree search: ";
      cout << avgTreeSearchTime;
      cout << " seconds." << endl;
      cout << "--------------------" << endl;
   #endif
   out << numPoints << "\t" << avgBruteForceTime << "\t" << avgTreeSearchTime << "\t";
   out << stdDevBrute << "\t" << stdDevTree << endl;
   return;
}

//______________________________________________________________________________
const Point& BruteForceNearestNeighbour(const vector<Point*>& pointList, const Point& point)
{
   // Take list of points and do a brute force search to find the nearest neighbour
   // Return nearest neighbour
   double currentBestDist = 0.0;
   int currentBestPoint = 0;
   vector<Point*>::const_iterator it;
   for (it = pointList.begin(); it != pointList.end(); it++) {
      double dist = (*it)->DistanceTo(point);
      #ifdef VERBOSE
         cout << setfill(' ') << setw(20);
         cout << (*it)->ToString();
         cout << "\t" << dist << endl;
      #endif
      if (currentBestDist == 0.0 || dist < currentBestDist) {
         currentBestDist = dist;
         currentBestPoint = it - pointList.begin();
      }
   }
   return *(pointList[currentBestPoint]);
}

//______________________________________________________________________________
void InternetExample1(vector<Point*>& points)
{
 //http://syntaxandsemantic.blogspot.com/2010/03/knn-algorithm-and-kd-trees.html
   points.push_back(new Point(5,9,10));
   points.push_back(new Point(2,6,8));
   points.push_back(new Point(14,3,7));
   points.push_back(new Point(3,4,9));
   points.push_back(new Point(4,13,5));
   points.push_back(new Point(8,2,1));
   points.push_back(new Point(7,9,6));
   points.push_back(new Point(4,1,6));
   points.push_back(new Point(2,2,10));
}
<commit_msg>Updated TestKDTree to use new nth-NN-search<commit_after>#include <iostream>
#include <iomanip>
#include <fstream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <time.h>
#include <string>
#include <cassert>

#include "KDTree.hpp"
#include "KDTreeNode.hpp"
#include "Point.hpp"
#include "MWC.hpp"

using namespace std;

//#define VERBOSE

void BenchMark(const int numPoints, const int repetitions, const int numNeighbours, ostream& out);
NodeStack* BruteForceNearestNeighbours(const vector<Point*>& pointList, const Point& point, const int nearestNeighbours);

void InternetExample1(vector<Point*>& points);

//______________________________________________________________________________
int main(int argc, char **argv) {
   ofstream out("benchmark_data.txt");
   out << "Num Points" << "\t" << "Brute Force Time" << "\t" << "Tree Search Time" << "\t";
   out << "Std Dev Brute Force" << "\t" << "Std Dev Tree Search" << endl;
   const int repetitions = 10;
   const int numNeighbours = 6;
   BenchMark(10, repetitions, numNeighbours, out);
   BenchMark(100, repetitions, numNeighbours, out);
   BenchMark(1000, repetitions, numNeighbours, out);
   BenchMark(10000, repetitions, numNeighbours, out);
   BenchMark(100000, repetitions, numNeighbours, out);
   BenchMark(1000000, repetitions, numNeighbours, out);
//   BenchMark(10000000, repetitions, numNeighbours, out);
   return 0;
}

//______________________________________________________________________________
void BenchMark(const int numPoints, const int repetitions, const int numNeighbours, ostream& out) {
   // -- Benchmark builds 'numPoints' random points, constructs a kd-tree of these points
   // -- then tests how long it takes to calculate the 'n' nearest neighbours of some random point
   // -- against a brute-force search approach
   #ifdef VERBOSE
      cout << "Benchmarking kd-tree nearest neighbour search, against brute-force search" << endl;
   #endif
   //-----------------------------------------------------------
   // -- Generate random points
   MWC rng;
   vector<Point*> points;
   for (int i=0; i<numPoints; i++) {
      points.push_back(new Point(rng.rnd(),rng.rnd(),rng.rnd()));
   }
   // Print points
   #ifdef VERBOSE
      cout << "--------------------" << endl;
      cout << "Input Points" << endl;
      vector<Point*>::iterator it;
      for (it = points.begin(); it != points.end(); it++) {
         cout << it - points.begin() << "\t" << (*it)->ToString() << endl;
      }
      cout << "--------------------" << endl;
   #endif
   //-----------------------------------------------------------
   // -- Build Tree
   // Set up timing
   clock_t start, end;
   start = clock();
   KDTree tree(points);
   // Output time to build tree
   end = clock();
   const double treeBuildTime = (double)(end-start)/CLOCKS_PER_SEC;
   cout << "--------------------" << endl;
   cout << "Number of points in Tree: " << numPoints << endl;
   cout << "Time required to build Tree: ";
   cout << treeBuildTime;
   cout << " seconds." << endl;
   //-----------------------------------------------------------
   // Repeat search for number of times defined by 'repetitions'
   // Store all times in vector for averaging and std dev
   double totBruteForceTime = 0.;
   double totTreeSearchTime = 0.;
   vector<double> bruteForceTimes;
   vector<double> treeSearchTimes;
   for (int iter = 0; iter < repetitions; iter++) {
      Point searchPoint(rng.rnd(),rng.rnd(),rng.rnd());
      #ifdef VERBOSE
         cout << "--------------------" << endl;
         cout << "Search Point: " << searchPoint.ToString() << endl;
      #endif
      //-----------------------------------------------------------
      // -- Perform Brute force search for point
      // Set up timing
      start = clock();
      #ifdef VERBOSE
         cout << "--------------------" << endl;
         cout << "Performing Brute Force Search..." << endl;
      #endif
      const NodeStack* bruteList = BruteForceNearestNeighbours(points, searchPoint, numNeighbours);
      // Output time to build tree
      end = clock();
      const double bruteForceTime = (double)(end-start)/CLOCKS_PER_SEC;
      //-----------------------------------------------------------
      // -- Perform Tree-based search for point
      // Set up timing
      start = clock();
      #ifdef VERBOSE
         cout << "--------------------" << endl;
         cout << "Performing Tree-based Search..." << endl;
      #endif
      const NodeStack* treeList = tree.NearestNeighbours(searchPoint, numNeighbours);
      // calculate time to build tree
      end = clock();
      const double treeSearchTime = (double)(end-start)/CLOCKS_PER_SEC;
      //-----------------------------------------------------------
      #ifdef VERBOSE
         cout << "--------------------" << endl;
         cout << "Time required for Brute force search: ";
         cout << bruteForceTime;
         cout << " seconds." << endl;
         cout << "--------------------" << endl;
         cout << "Time required for Tree search: ";
         cout << treeSearchTime;
         cout << " seconds." << endl;
         cout << "--------------------" << endl;
         cout << "Nearest Neighbours found: " << endl;
         cout << "Brute" << "\t";
         cout << bruteList->size() << endl;
         list<StackElement>::const_iterator stackIter;
         for (stackIter = bruteList->begin(); stackIter != bruteList->end(); stackIter++) {
            cout << setfill(' ') << setw(10) << stackIter->first->GetPoint().ToString() << endl;
         }
         cout << endl;
         cout << "Tree" << "\t";
         cout << treeList->size() << endl;
         for (stackIter = treeList->begin(); stackIter != treeList->end(); stackIter++) {
            cout << setfill(' ') << setw(10) << stackIter->first->GetPoint().ToString() << endl;
         }
         cout << "--------------------" << endl;
      #endif
      assert(*treeList == *bruteList);
      bruteForceTimes.push_back(bruteForceTime);
      treeSearchTimes.push_back(treeSearchTime);
      totBruteForceTime += bruteForceTime;
      totTreeSearchTime += treeSearchTime;
      delete treeList;
      delete bruteList;
   }
   // Calculate mean search times
   double avgBruteForceTime = totBruteForceTime/repetitions;
   double avgTreeSearchTime = totTreeSearchTime/repetitions;
   // Calculate Std Dev
   double sumBrute = 0.;
   double sumTree = 0.;
   for (int iter = 0; iter < repetitions; iter++) {
      sumBrute += pow((bruteForceTimes[iter] - avgBruteForceTime), 2.0);
      sumTree += pow((treeSearchTimes[iter] - avgTreeSearchTime), 2.0);
   }
   double stdDevBrute = sqrt(sumBrute/(repetitions-1));
   double stdDevTree = sqrt(sumTree/(repetitions-1));
   #ifdef VERBOSE
      cout << "--------------------" << endl;
      cout << "Average Time required for Brute force search: ";
      cout << avgBruteForceTime;
      cout << " seconds." << endl;
      cout << "--------------------" << endl;
      cout << "Average Time required for Tree search: ";
      cout << avgTreeSearchTime;
      cout << " seconds." << endl;
      cout << "--------------------" << endl;
   #endif
   out << numPoints << "\t" << avgBruteForceTime << "\t" << avgTreeSearchTime << "\t";
   out << stdDevBrute << "\t" << stdDevTree << endl;
   return;
}

//______________________________________________________________________________
NodeStack* BruteForceNearestNeighbours(const vector<Point*>& pointList, const Point& point, const int nearestNeighbours)
{
   // Take list of points and do a brute force search to find the nearest neighbour
   // Return nearest neighbour
   NodeStack* neighbours = new NodeStack(nearestNeighbours);
   vector<Point*>::const_iterator it;
   for (it = pointList.begin(); it != pointList.end(); it++) {
      double dist = (*it)->DistanceTo(point);
      #ifdef VERBOSE
         cout << setfill(' ') << setw(20);
         cout << (*it)->ToString();
         cout << "\t" << dist << endl;
      #endif
      KDTreeNode* node = new KDTreeNode();
      node->SetPoint(*it);
      neighbours->AddNode(node,dist);
   }
   return neighbours;
}

/*
//______________________________________________________________________________
const Point& BruteForceNearestNeighbour(const vector<Point*>& pointList, const Point& point)
{
   // Take list of points and do a brute force search to find the nearest neighbour
   // Return nearest neighbour
   double currentBestDist = 0.0;
   int currentBestPoint = 0;
   vector<Point*>::const_iterator it;
   for (it = pointList.begin(); it != pointList.end(); it++) {
      double dist = (*it)->DistanceTo(point);
      #ifdef VERBOSE
         cout << setfill(' ') << setw(20);
         cout << (*it)->ToString();
         cout << "\t" << dist << endl;
      #endif
      if (currentBestDist == 0.0 || dist < currentBestDist) {
         currentBestDist = dist;
         currentBestPoint = it - pointList.begin();
      }
   }
   return *(pointList[currentBestPoint]);
}
*/
//______________________________________________________________________________
void InternetExample1(vector<Point*>& points)
{
 //http://syntaxandsemantic.blogspot.com/2010/03/knn-algorithm-and-kd-trees.html
   points.push_back(new Point(5,9,10));
   points.push_back(new Point(2,6,8));
   points.push_back(new Point(14,3,7));
   points.push_back(new Point(3,4,9));
   points.push_back(new Point(4,13,5));
   points.push_back(new Point(8,2,1));
   points.push_back(new Point(7,9,6));
   points.push_back(new Point(4,1,6));
   points.push_back(new Point(2,2,10));
}
<|endoftext|>