<commit_before>// Copyright (c) 2017 Pierre Fourgeaud
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include <bandit/bandit.h>
#include "core/utils.h"

using namespace bandit;
using namespace snowhouse;
using namespace CodeHero;

go_bandit([]() {
    describe("::StartsWith", [] {
        it("should return true if starts we correct prefix", [] {
            AssertThat(StartsWith("This is a test", "This"), IsTrue());
            AssertThat(StartsWith("This is a test", "This is a test"), IsTrue());
        });

        it("should return true if the prefix is empty", [] {
            AssertThat(StartsWith("This is a test", ""), IsTrue());
        });

        it("should return false if the prefix doesn't match the start of the string", [] {
            AssertThat(StartsWith("This is a test", "Wrong"), IsFalse());
            AssertThat(StartsWith("This is a test", "This iz"), IsFalse());
            AssertThat(StartsWith("This is a test", "Zhis is"), IsFalse());
        });
    });

    describe("::EndsWith", [] {
        it("should return true if ends with correct suffix", [] {
            AssertThat(EndsWith("This is a test", "test"), IsTrue());
            AssertThat(EndsWith("This is a test", "This is a test"), IsTrue());
        });

        it("should return true if suffix is empty", [] {
            AssertThat(EndsWith("This is a test", ""), IsTrue());
        });

        it("should return false if the suffix doesn't match the end of the string", [] {
            AssertThat(EndsWith("This is a test", "wrong"), IsFalse());
            AssertThat(EndsWith("This is a test", "tesz"), IsFalse());
            AssertThat(EndsWith("This is a test", "zest"), IsFalse());
        });
    });

    describe("::Trim", [] {
        it("should trim on the left side", [] {
            std::string test("  \t This is a test");
            std::string result("This is a test");

            Trim(test);
            AssertThat(test, Equals(result));
        });

        it("should trim on the right side", [] {
            std::string test("This is a test    \t   ");
            std::string result("This is a test");

            Trim(test);
            AssertThat(test, Equals(result));
        });

        it("should trim on the both side", [] {
            std::string test("  \t This is a test    \t   ");
            std::string result("This is a test");

            Trim(test);
            AssertThat(test, Equals(result));
        });

        it("should not modify the string if not needed", [] {
            std::string test("This is a test");
            std::string result = test;

            Trim(test);
            AssertThat(test, Equals(result));
        });
    });

    describe("::ToLowerCase", [] {
        it("should lower case properly a string regardless of special chars", [] {
            std::string test("Th1s 1S pr377Y W31RD !!@#$   ");
            std::string result("th1s 1s pr377y w31rd !!@#$   ");

            ToLowerCase(test);
            AssertThat(test, Equals(result));
        });

        it("should not do anything on an empty string", [] {
            std::string test;
            std::string result;

            ToLowerCase(test);
            AssertThat(test, Equals(result));
        });
    });

    describe("::LowerCased", [] {
        it("should lower case properly a string regardless of special chars", [] {
            std::string test("Th1s 1S pr377Y W31RD !!@#$   ");
            std::string result("th1s 1s pr377y w31rd !!@#$   ");

            test = LowerCased(test);
            AssertThat(test, Equals(result));
        });

        it("should not do anything on an empty string", [] {
            std::string test;
            std::string result;

            test = LowerCased(test);
            AssertThat(test, Equals(result));
        });
    });

    describe("::Join", [] {
        it("should return empty string if the input vector is empty", [] {
            std::string test = Join({});
            std::string result;

            AssertThat(test, Equals(result));
        });

        it("should return the proper string if delimiter wasn't passed", [] {
            std::string test = Join({"This", "is", "a", "test."});
            std::string result = "This is a test.";

            AssertThat(test, Equals(result));
        });

        it("should properly join the vector into a string with correct delimiter", [] {
            std::string test = Join({"This", "is", "a", "test."}, ' ');
            std::string result = "This is a test.";

            AssertThat(test, Equals(result));
        });
    });

    describe("::IsIn", [] {
        it("should return true if the searched term is inside the array", [] {
            AssertThat(IsIn("test", {"test", "is", "in"}), IsTrue());
        });

        it("should return false if the searched term is not in the array", [] {
            AssertThat(IsIn("test", {"is", "not", "in"}), IsFalse());
        });

        it("should return false if the array is empty", [] {
            AssertThat(IsIn("test", {}), IsFalse());
        });
    });
});<commit_msg>Fixed small type deduction issues in previous change<commit_after>// Copyright (c) 2017 Pierre Fourgeaud
// Use of this source code is governed by the MIT license that can be
// found in the LICENSE file.

#include <bandit/bandit.h>
#include "core/utils.h"

using namespace bandit;
using namespace snowhouse;
using namespace CodeHero;

go_bandit([]() {
    describe("::StartsWith", [] {
        it("should return true if starts we correct prefix", [] {
            AssertThat(StartsWith("This is a test", "This"), IsTrue());
            AssertThat(StartsWith("This is a test", "This is a test"), IsTrue());
        });

        it("should return true if the prefix is empty", [] {
            AssertThat(StartsWith("This is a test", ""), IsTrue());
        });

        it("should return false if the prefix doesn't match the start of the string", [] {
            AssertThat(StartsWith("This is a test", "Wrong"), IsFalse());
            AssertThat(StartsWith("This is a test", "This iz"), IsFalse());
            AssertThat(StartsWith("This is a test", "Zhis is"), IsFalse());
        });
    });

    describe("::EndsWith", [] {
        it("should return true if ends with correct suffix", [] {
            AssertThat(EndsWith("This is a test", "test"), IsTrue());
            AssertThat(EndsWith("This is a test", "This is a test"), IsTrue());
        });

        it("should return true if suffix is empty", [] {
            AssertThat(EndsWith("This is a test", ""), IsTrue());
        });

        it("should return false if the suffix doesn't match the end of the string", [] {
            AssertThat(EndsWith("This is a test", "wrong"), IsFalse());
            AssertThat(EndsWith("This is a test", "tesz"), IsFalse());
            AssertThat(EndsWith("This is a test", "zest"), IsFalse());
        });
    });

    describe("::Trim", [] {
        it("should trim on the left side", [] {
            std::string test("  \t This is a test");
            std::string result("This is a test");

            Trim(test);
            AssertThat(test, Equals(result));
        });

        it("should trim on the right side", [] {
            std::string test("This is a test    \t   ");
            std::string result("This is a test");

            Trim(test);
            AssertThat(test, Equals(result));
        });

        it("should trim on the both side", [] {
            std::string test("  \t This is a test    \t   ");
            std::string result("This is a test");

            Trim(test);
            AssertThat(test, Equals(result));
        });

        it("should not modify the string if not needed", [] {
            std::string test("This is a test");
            std::string result = test;

            Trim(test);
            AssertThat(test, Equals(result));
        });
    });

    describe("::ToLowerCase", [] {
        it("should lower case properly a string regardless of special chars", [] {
            std::string test("Th1s 1S pr377Y W31RD !!@#$   ");
            std::string result("th1s 1s pr377y w31rd !!@#$   ");

            ToLowerCase(test);
            AssertThat(test, Equals(result));
        });

        it("should not do anything on an empty string", [] {
            std::string test;
            std::string result;

            ToLowerCase(test);
            AssertThat(test, Equals(result));
        });
    });

    describe("::LowerCased", [] {
        it("should lower case properly a string regardless of special chars", [] {
            std::string test("Th1s 1S pr377Y W31RD !!@#$   ");
            std::string result("th1s 1s pr377y w31rd !!@#$   ");

            test = LowerCased(test);
            AssertThat(test, Equals(result));
        });

        it("should not do anything on an empty string", [] {
            std::string test;
            std::string result;

            test = LowerCased(test);
            AssertThat(test, Equals(result));
        });
    });

    describe("::Join", [] {
        it("should return empty string if the input vector is empty", [] {
            std::string test = Join({});
            std::string result;

            AssertThat(test, Equals(result));
        });

        it("should return the proper string if delimiter wasn't passed", [] {
            std::string test = Join({"This", "is", "a", "test."});
            std::string result = "This is a test.";

            AssertThat(test, Equals(result));
        });

        it("should properly join the vector into a string with correct delimiter", [] {
            std::string test = Join({"This", "is", "a", "test."}, ' ');
            std::string result = "This is a test.";

            AssertThat(test, Equals(result));
        });
    });

    describe("::IsIn", [] {
        it("should return true if the searched term is inside the array", [] {
            std::string toFind = "test";
            std::vector<std::string> list = {"test", "is", "in"};
            AssertThat(IsIn(toFind, list), IsTrue());
        });

        it("should return false if the searched term is not in the array", [] {
            std::string toFind = "test";
            std::vector<std::string> list = {"is", "not", "in"};
            AssertThat(IsIn(toFind, list), IsFalse());
        });

        it("should return false if the array is empty", [] {
            std::string toFind = "test";
            std::vector<std::string> list = {};
            AssertThat(IsIn(toFind, list), IsFalse());
        });
    });
});<|endoftext|>


<commit_before>//
//  ex10_30.cpp
//  Exercise 10.30
//
//  Created by pezy on 12/13/14.
//  Copyright (c) 2014 pezy. All rights reserved.
//
//  Use stream iterators, sort, and copy to read a sequence of integers from the
//  standard input,
//  sort them, and then write them back to the standard output.

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>

int main()
{
    std::istream_iterator<int> in_iter(std::cin), eof;
    std::vector<int> vec;
    while (in_iter != eof) vec.push_back(*in_iter++);
    std::sort(vec.begin(), vec.end());
    std::copy(vec.cbegin(), vec.cend(),
              std::ostream_iterator<int>(std::cout, " "));
}<commit_msg>Update ex10_30.cpp<commit_after>//
//  ex10_30.cpp
//  Exercise 10.30
//
//  Created by pezy on 12/13/14.
//  Copyright (c) 2014 pezy. All rights reserved.
//
//  Use stream iterators, sort, and copy to read a sequence of integers from the
//  standard input, sort them, and then write them back to the standard output.

#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
using namespace std;

int main()
{
    istream_iterator<int> in_iter(cin), eof;
    vector<int> ivec;
    copy(in_iter, eof, back_inserter(ivec));
    sort(ivec.begin(), ivec.end());
    copy(ivec.cbegin(), ivec.cend(), ostream_iterator<int>(cout, " "));
}
<|endoftext|>


<commit_before>//
//  ex10_32.cpp
//  Exercise 10.32
//
//  Created by pezy on 12/13/14.
//  Copyright (c) 2014 pezy. All rights reserved.
//
//  Rewrite the bookstore problem from 1.6 (p. 24) using a vector to hold the
//  transactions
//  and various algorithms to do the processing.
//  Use sort with your compareIsbn function from 10.3.1 (p. 387) to arrange the
//  transactions in order,
//  and then use find and accumulate to do the sum.

#include <iostream>
#include <vector>
#include <algorithm>
#include <iterator>
#include <numeric>
#include "../include/Sales_item.h"

int main()
{
    std::istream_iterator<Sales_item> in_iter(std::cin), in_eof;
    std::vector<Sales_item> vec;

    while (in_iter != in_eof) vec.push_back(*in_iter++);
    sort(vec.begin(), vec.end(),
         [](Sales_item const& lhs, Sales_item const& rhs) {
             return lhs.isbn() < rhs.isbn();
         });
    for (auto beg = vec.cbegin(), end = beg; beg != vec.cend(); beg = end) {
        end = find_if(beg, vec.cend(), [beg](const Sales_item& item) {
            return item.isbn() != beg->isbn();
        });
        std::cout << std::accumulate(beg, end, Sales_item(beg->isbn()))
                  << std::endl;
    }
}
<commit_msg>Update ex10_32.cpp<commit_after>//
//  ex10_32.cpp
//  Exercise 10.32
//
//  Created by pezy on 12/13/14.
//  Copyright (c) 2014 pezy. All rights reserved.
//
//  Rewrite the bookstore program from 1.6 (p. 24) using a vector to hold the
//  transactions and various algorithms to do the processing.
//  Use sort with your compareIsbn function from 10.3.1 (p. 387) to arrange the
//  transactions in order, and then use find and accumulate to do the sum.
//

#include <iostream>
#include <vector>
#include <iterator>
#include <numeric>
#include <algorithm>
#include "Sales_item.h"
#include "Version_test.h"
using namespace std;

int main()
{
    istream_iterator<Sales_item> in_iter(cin), in_eof;
    vector<Sales_item> vec;
    while(in_iter!=in_eof)
        vec.push_back(*in_iter++);

    sort(vec.begin(), vec.end(), [](const Sales_item &lhs, const Sales_item &rhs) {return lhs.isbn()<rhs.isbn();});

    for(auto beg=vec.cbegin(), end=beg; beg!=vec.cend(); beg=end)
    {
        end=find_if(beg, vec.cend(), [beg](const Sales_item &item) {return item.isbn()!=beg->isbn();});
        cout<<accumulate(beg, end, Sales_item(beg->isbn()))<<endl;
    }
}
<|endoftext|>


<commit_before>// Copyright Hugh Perkins 2015 hughperkins at gmail
//
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.

#include <iostream>
#include <string>

#include "net/NeuralNet.h"
#include "layer/LayerMakers.h"
#include "util/stringhelper.h"
#include "netdef/NetdefToNet.h"
#include "activate/ActivationFunction.h"
#include "weights/WeightsInitializer.h"

using namespace std;

#undef STATIC
#undef VIRTUAL
#define STATIC
#define VIRTUAL

// string is structured like:
// prefix-nn*(inner)-postfix
// or:
// prefix-nn*inner-postfix
STATIC std::string expandMultipliers(std::string netdef) {
    int starPos = netdef.find("*");
    if(starPos != (int)string::npos) {
        int prefixEnd = netdef.rfind("-", starPos);
        string prefix = "";
        string nnString = "";
        if(prefixEnd == (int)string::npos) {
            prefixEnd = -1;
            nnString = netdef.substr(0, starPos);
        } else {
            prefixEnd--;
            prefix = netdef.substr(0, prefixEnd + 1);
            cout << "prefix: [" << prefix << "]" << endl;
            nnString = netdef.substr(prefixEnd + 2, starPos - prefixEnd - 2);
        }
        cout << "nnString: [" << nnString << "]" << endl;
        int repeatNum = atoi(nnString);
        cout << "repeatNum " << repeatNum << endl;
        string remainderString = netdef.substr(starPos + 1);
        cout << "remainderString [" << remainderString << "]" << endl;
        string inner = "";
        string postfix = "";
        if(remainderString.substr(0, 1) == "(") {
            // need to find other ')', assume not nested for now...
            int rhBracket = remainderString.find(")");
            if(rhBracket == (int)string::npos) {
                throw runtime_error("matching bracket not found in " + remainderString);
//                return false;
            }
            inner = remainderString.substr(1, rhBracket - 1);
            cout << "inner [" << inner << "]" << endl;
            string newRemainder = remainderString.substr(rhBracket + 1);
            cout << "newRemainder [" << newRemainder << "]" << endl;
            if(newRemainder != "") {
                if(newRemainder[0] != '-') {
                    throw runtime_error("expect '-' after ')' in " + remainderString);
    //                return false;
                }
                postfix = newRemainder.substr(1);
                cout << "postfix [" << postfix << "]" << endl;
            }
        } else {
            int innerEnd = remainderString.find("-");
            if(innerEnd == (int)string::npos) {
                innerEnd = remainderString.length();
            } else {
//                innerEnd;
                postfix = remainderString.substr(innerEnd + 1);
                cout << "postfix [" << postfix << "]" << endl;
            }
            inner = remainderString.substr(0, innerEnd);
            cout << "inner [" << inner << "]" << endl;
//            if(remainderString.find("-") != string::npos) {
//                sectionEndPos = remainderString.find("-");
//            }
        }
//        return "";
        // if remainderString starts with (, then repeat up to next)
        // otherwise, repeat up to next -
//        int sectionEndPos = remainderString.length();
//        remainderString =
        string newString = prefix;
        for(int i = 0; i < repeatNum; i++) {
            if(newString != "") {
                newString += "-";
            }
            newString += expandMultipliers(inner);
        }
        if(postfix != "") {
            newString += "-" + expandMultipliers(postfix);
        }
        cout << "multiplied string: " << newString << endl;
        return newString;
    } else {
        return netdef;
    }
}

STATIC bool NetdefToNet::parseSubstring(WeightsInitializer *weightsInitializer, NeuralNet *net, std::string substring, bool isLast) {
//    cout << "substring [" << substring << "]" << endl;
    vector<string>splitLayerDef = split(substring, "{");
    string baseLayerDef = splitLayerDef[0];
//         optionsDef = "";
    vector<string> splitOptionsDef;
//    cout << "splitlayerdef.size() " << splitLayerDef.size() << endl;
    if(splitLayerDef.size() == 2) {
        string  optionsDef = split(splitLayerDef[1], "}")[0];
//        cout << "optionsDef [" << optionsDef << "]" << endl;
        splitOptionsDef = split(optionsDef, ",");
    }
    if(baseLayerDef.find("c") != string::npos) {
        vector<string> splitConvDef = split(baseLayerDef, "c");
        int numFilters = atoi(splitConvDef[0]);
        vector<string> splitConvDef1 = split(splitConvDef[1], "z");
        int filterSize = atoi(splitConvDef1[0]);
        int skip = 0;
        ActivationFunction *fn = 0;
        bool padZeros = splitConvDef1.size() == 2 ? true : false;

        for(int i = 0; i < (int)splitOptionsDef.size(); i++) {
            string optionDef = splitOptionsDef[i];
//            cout << "optionDef [" << optionDef << "]" << endl;
            vector<string> splitOptionDef = split(optionDef, "=");
            string optionName = splitOptionDef[0];
            if(splitOptionDef.size() == 2) {
                string optionValue = splitOptionDef[1];
                if(optionName == "skip") {
                    skip = atoi(optionValue);
                    cout << "got skip: " << skip << endl;
                }
            } else if(splitOptionDef.size() == 1) {
                if(optionName == "tanh") {
                    fn = new TanhActivation();
                } else if(optionName == "scaledtanh") {
                    fn = new ScaledTanhActivation();
                } else if(optionName == "sigmoid") {
                    fn = new SigmoidActivation();
                } else if(optionName == "relu") {
                    fn = new ReluActivation();
                } else if(optionName == "elu") {
                    fn = new EluActivation();
                } else if(optionName == "linear") {
                    fn = new LinearActivation();
                } else if(optionName == "padzeros" || optionName == "z") {
                    padZeros = true;
                } else {
                    cout << "Error: unknown subkey: [" << splitOptionsDef[i] << "]" << endl;
                    return false;
                }
            } else {
                cout << "Error: unknown subkey: [" << splitOptionsDef[i] << "]" << endl;
                return false;
            }
        }
        net->addLayer(ConvolutionalMaker::instance()->numFilters(numFilters)->filterSize(filterSize)->padZeros(padZeros)->biased()->weightsInitializer(weightsInitializer) );
        if(fn != 0) {
            net->addLayer(ActivationMaker::instance()->fn(fn) );
        }
    } else if(baseLayerDef.find("mp") != string::npos) {
        vector<string> splitPoolDef = split(baseLayerDef, "mp");
        int poolingSize = atoi(splitPoolDef[1]);
        net->addLayer(PoolingMaker::instance()->poolingSize(poolingSize));
    } else if(baseLayerDef.find("drop") != string::npos) {
        net->addLayer(DropoutMaker::instance()->dropRatio(0.5f));
    } else if(baseLayerDef.find("relu") != string::npos) {
        net->addLayer(ActivationMaker::instance()->relu());
    } else if(baseLayerDef.find("elu") != string::npos) {
        net->addLayer(ActivationMaker::instance()->elu());
    } else if(baseLayerDef.find("tanh") != string::npos) {
        net->addLayer(ActivationMaker::instance()->tanh());
    } else if(baseLayerDef.find("sigmoid") != string::npos) {
        net->addLayer(ActivationMaker::instance()->sigmoid());
    } else if(baseLayerDef.find("linear") != string::npos) {
        net->addLayer(ActivationMaker::instance()->linear()); // kind of pointless nop, but useful for testing
    } else if(baseLayerDef.find("rp") != string::npos) {
        int patchSize = atoi(split(baseLayerDef, "rp")[1]);
        net->addLayer(RandomPatchesMaker::instance()->patchSize(patchSize) );
    } else if(baseLayerDef.find("rt") != string::npos) {
        int translateSize = atoi(split(baseLayerDef, "rt")[1]);
        net->addLayer(RandomTranslationsMaker::instance()->translateSize(translateSize) );
    } else if(baseLayerDef.find("n") != string::npos) {
        vector<string> fullDef = split(baseLayerDef, "n");
        int numPlanes = atoi(fullDef[0]);
        ActivationFunction *fn = 0;
//        if(isLast) {
//            fn = new LinearActivation();
//        }
//        int padZeros = 0;
        bool biased = true;
        for(int i = 0; i < (int)splitOptionsDef.size(); i++) {
            string optionDef = splitOptionsDef[i];
//                cout << "optionDef: " << optionDef << endl;
            vector<string> splitOptionDef = split(optionDef, "=");
            string optionName = splitOptionDef[0];
            if(splitOptionDef.size() == 1) {
                if(optionName == "tanh") {
                    fn = new TanhActivation();
                } else if(optionName == "scaledtanh") {
                    fn = new ScaledTanhActivation();
                } else if(optionName == "sigmoid") {
                    fn = new SigmoidActivation();
                } else if(optionName == "relu") {
                    fn = new ReluActivation();
                } else if(optionName == "nobias") {
                    biased = false;
                } else if(optionName == "linear") {
                    fn = new LinearActivation();
                } else {
                    cout << "Error: unknown subkey: [" << splitOptionsDef[i] << "]" << endl;
                    return false;
                }
            } else {
                cout << "Error: unknown subkey: [" << splitOptionsDef[i] << "]" << endl;
                return false;
            }
        }
        if(isLast && fn != 0) {
            cout << "Last fullyconnectedlayer must be linear (because softmax is the 'activationlayer' for this layer)" << endl;
            return false;
        }
        net->addLayer(FullyConnectedMaker::instance()->numPlanes(numPlanes)->imageSize(1)->biased(biased)->weightsInitializer(weightsInitializer) );
        if(fn != 0) {
            net->addLayer(ActivationMaker::instance()->fn(fn) );
        }
    } else {
        cout << "network definition " << baseLayerDef << " not recognised" << endl;
        return false;
    }
    return true;
}

PUBLICAPI STATIC bool NetdefToNet::createNetFromNetdef(NeuralNet *net, std::string netdef) {
    OriginalInitializer originalInitializer;
    return createNetFromNetdef(net, netdef, &originalInitializer);
}
PUBLICAPI STATIC bool NetdefToNet::createNetFromNetdefCharStar(NeuralNet *net, const char *netdef) {
    OriginalInitializer originalInitializer;
    return createNetFromNetdef(net, netdef, &originalInitializer);
}

STATIC bool NetdefToNet::createNetFromNetdef(NeuralNet *net, std::string netdef, WeightsInitializer *weightsInitializer) {
    string netDefLower = toLower(netdef);
//    cout << "netDefLower [" << netDefLower << "]" << endl;
    try {
        netDefLower = expandMultipliers(netDefLower);
    } catch(runtime_error &e) {
        cout << e.what() << endl;
        return false;
    }
//    cout << "netDefLower [" << netDefLower << "]" << endl;
    vector<string> splitNetDef = split(netDefLower, "-");
    if(netdef != "") {
        for(int i = 0; i < (int)splitNetDef.size(); i++) {
            string thisLayerDef = splitNetDef[i];
//            cout << "thisLayerDef [" << thisLayerDef << "]" << endl;
            if(!parseSubstring(weightsInitializer, net, thisLayerDef, i == (int)splitNetDef.size() - 1) ) {
                return false;
            }
        }
    }
    net->addLayer(SoftMaxMaker::instance());
    return true;
}<commit_msg>Removed 5 warnings<commit_after>// Copyright Hugh Perkins 2015 hughperkins at gmail
//
// This Source Code Form is subject to the terms of the Mozilla Public License,
// v. 2.0. If a copy of the MPL was not distributed with this file, You can
// obtain one at http://mozilla.org/MPL/2.0/.

#include <iostream>
#include <string>

#include "net/NeuralNet.h"
#include "layer/LayerMakers.h"
#include "util/stringhelper.h"
#include "netdef/NetdefToNet.h"
#include "activate/ActivationFunction.h"
#include "weights/WeightsInitializer.h"

using namespace std;

#undef STATIC
#undef VIRTUAL
#define STATIC
#define VIRTUAL

// string is structured like:
// prefix-nn*(inner)-postfix
// or:
// prefix-nn*inner-postfix
STATIC std::string expandMultipliers(std::string netdef) {
    size_t starPos = netdef.find("*");
    if(starPos != string::npos) {
        size_t prefixEnd = netdef.rfind("-", starPos);
        string prefix = "";
        string nnString = "";
        if(prefixEnd == string::npos) {
            prefixEnd = -1;
            nnString = netdef.substr(0, starPos);
        } else {
            prefixEnd--;
            prefix = netdef.substr(0, prefixEnd + 1);
            cout << "prefix: [" << prefix << "]" << endl;
            nnString = netdef.substr(prefixEnd + 2, starPos - prefixEnd - 2);
        }
        cout << "nnString: [" << nnString << "]" << endl;
        int repeatNum = atoi(nnString);
        cout << "repeatNum " << repeatNum << endl;
        string remainderString = netdef.substr(starPos + 1);
        cout << "remainderString [" << remainderString << "]" << endl;
        string inner = "";
        string postfix = "";
        if(remainderString.substr(0, 1) == "(") {
            // need to find other ')', assume not nested for now...
            size_t rhBracket = remainderString.find(")");
            if(rhBracket == string::npos) {
                throw runtime_error("matching bracket not found in " + remainderString);
            }
            inner = remainderString.substr(1, rhBracket - 1);
            cout << "inner [" << inner << "]" << endl;
            string newRemainder = remainderString.substr(rhBracket + 1);
            cout << "newRemainder [" << newRemainder << "]" << endl;
            if(newRemainder != "") {
                if(newRemainder[0] != '-') {
                    throw runtime_error("expect '-' after ')' in " + remainderString);
                }
                postfix = newRemainder.substr(1);
                cout << "postfix [" << postfix << "]" << endl;
            }
        } else {
            size_t innerEnd = remainderString.find("-");
            if(innerEnd == string::npos) {
                innerEnd = remainderString.length();
            } else {
//                innerEnd;
                postfix = remainderString.substr(innerEnd + 1);
                cout << "postfix [" << postfix << "]" << endl;
            }
            inner = remainderString.substr(0, innerEnd);
            cout << "inner [" << inner << "]" << endl;
//            if(remainderString.find("-") != string::npos) {
//                sectionEndPos = remainderString.find("-");
//            }
        }
//        return "";
        // if remainderString starts with (, then repeat up to next)
        // otherwise, repeat up to next -
//        int sectionEndPos = remainderString.length();
//        remainderString =
        string newString = prefix;
        for(int i = 0; i < repeatNum; i++) {
            if(newString != "") {
                newString += "-";
            }
            newString += expandMultipliers(inner);
        }
        if(postfix != "") {
            newString += "-" + expandMultipliers(postfix);
        }
        cout << "multiplied string: " << newString << endl;
        return newString;
    } else {
        return netdef;
    }
}

STATIC bool NetdefToNet::parseSubstring(WeightsInitializer *weightsInitializer, NeuralNet *net, std::string substring, bool isLast) {
//    cout << "substring [" << substring << "]" << endl;
    vector<string>splitLayerDef = split(substring, "{");
    string baseLayerDef = splitLayerDef[0];
//         optionsDef = "";
    vector<string> splitOptionsDef;
//    cout << "splitlayerdef.size() " << splitLayerDef.size() << endl;
    if(splitLayerDef.size() == 2) {
        string  optionsDef = split(splitLayerDef[1], "}")[0];
//        cout << "optionsDef [" << optionsDef << "]" << endl;
        splitOptionsDef = split(optionsDef, ",");
    }
    if(baseLayerDef.find("c") != string::npos) {
        vector<string> splitConvDef = split(baseLayerDef, "c");
        int numFilters = atoi(splitConvDef[0]);
        vector<string> splitConvDef1 = split(splitConvDef[1], "z");
        int filterSize = atoi(splitConvDef1[0]);
        int skip = 0;
        ActivationFunction *fn = 0;
        bool padZeros = splitConvDef1.size() == 2 ? true : false;

        for(int i = 0; i < (int)splitOptionsDef.size(); i++) {
            string optionDef = splitOptionsDef[i];
//            cout << "optionDef [" << optionDef << "]" << endl;
            vector<string> splitOptionDef = split(optionDef, "=");
            string optionName = splitOptionDef[0];
            if(splitOptionDef.size() == 2) {
                string optionValue = splitOptionDef[1];
                if(optionName == "skip") {
                    skip = atoi(optionValue);
                    cout << "got skip: " << skip << endl;
                }
            } else if(splitOptionDef.size() == 1) {
                if(optionName == "tanh") {
                    fn = new TanhActivation();
                } else if(optionName == "scaledtanh") {
                    fn = new ScaledTanhActivation();
                } else if(optionName == "sigmoid") {
                    fn = new SigmoidActivation();
                } else if(optionName == "relu") {
                    fn = new ReluActivation();
                } else if(optionName == "elu") {
                    fn = new EluActivation();
                } else if(optionName == "linear") {
                    fn = new LinearActivation();
                } else if(optionName == "padzeros" || optionName == "z") {
                    padZeros = true;
                } else {
                    cout << "Error: unknown subkey: [" << optionName << "]" << endl;
                    return false;
                }
            } else {
                cout << "Error: unknown subkey: [" << optionName << "]" << endl;
                return false;
            }
        }
        net->addLayer(ConvolutionalMaker::instance()->numFilters(numFilters)->filterSize(filterSize)->padZeros(padZeros)->biased()->weightsInitializer(weightsInitializer) );
        if(fn != 0) {
            net->addLayer(ActivationMaker::instance()->fn(fn) );
        }
    } else if(baseLayerDef.find("mp") != string::npos) {
        vector<string> splitPoolDef = split(baseLayerDef, "mp");
        int poolingSize = atoi(splitPoolDef[1]);
        net->addLayer(PoolingMaker::instance()->poolingSize(poolingSize));
    } else if(baseLayerDef.find("drop") != string::npos) {
        net->addLayer(DropoutMaker::instance()->dropRatio(0.5f));
    } else if(baseLayerDef.find("relu") != string::npos) {
        net->addLayer(ActivationMaker::instance()->relu());
    } else if(baseLayerDef.find("elu") != string::npos) {
        net->addLayer(ActivationMaker::instance()->elu());
    } else if(baseLayerDef.find("tanh") != string::npos) {
        net->addLayer(ActivationMaker::instance()->tanh());
    } else if(baseLayerDef.find("sigmoid") != string::npos) {
        net->addLayer(ActivationMaker::instance()->sigmoid());
    } else if(baseLayerDef.find("linear") != string::npos) {
        net->addLayer(ActivationMaker::instance()->linear()); // kind of pointless nop, but useful for testing
    } else if(baseLayerDef.find("rp") != string::npos) {
        int patchSize = atoi(split(baseLayerDef, "rp")[1]);
        net->addLayer(RandomPatchesMaker::instance()->patchSize(patchSize) );
    } else if(baseLayerDef.find("rt") != string::npos) {
        int translateSize = atoi(split(baseLayerDef, "rt")[1]);
        net->addLayer(RandomTranslationsMaker::instance()->translateSize(translateSize) );
    } else if(baseLayerDef.find("n") != string::npos) {
        vector<string> fullDef = split(baseLayerDef, "n");
        int numPlanes = atoi(fullDef[0]);
        ActivationFunction *fn = 0;
//        if(isLast) {
//            fn = new LinearActivation();
//        }
//        int padZeros = 0;
        bool biased = true;
        for(int i = 0; i < (int)splitOptionsDef.size(); i++) {
            string optionDef = splitOptionsDef[i];
//                cout << "optionDef: " << optionDef << endl;
            vector<string> splitOptionDef = split(optionDef, "=");
            string optionName = splitOptionDef[0];
            if(splitOptionDef.size() == 1) {
                if(optionName == "tanh") {
                    fn = new TanhActivation();
                } else if(optionName == "scaledtanh") {
                    fn = new ScaledTanhActivation();
                } else if(optionName == "sigmoid") {
                    fn = new SigmoidActivation();
                } else if(optionName == "relu") {
                    fn = new ReluActivation();
                } else if(optionName == "nobias") {
                    biased = false;
                } else if(optionName == "linear") {
                    fn = new LinearActivation();
                } else {
                    cout << "Error: unknown subkey: [" << splitOptionsDef[i] << "]" << endl;
                    return false;
                }
            } else {
                cout << "Error: unknown subkey: [" << splitOptionsDef[i] << "]" << endl;
                return false;
            }
        }
        if(isLast && fn != 0) {
            cout << "Last fullyconnectedlayer must be linear (because softmax is the 'activationlayer' for this layer)" << endl;
            return false;
        }
        net->addLayer(FullyConnectedMaker::instance()->numPlanes(numPlanes)->imageSize(1)->biased(biased)->weightsInitializer(weightsInitializer) );
        if(fn != 0) {
            net->addLayer(ActivationMaker::instance()->fn(fn) );
        }
    } else {
        cout << "network definition " << baseLayerDef << " not recognised" << endl;
        return false;
    }
    return true;
}

PUBLICAPI STATIC bool NetdefToNet::createNetFromNetdef(NeuralNet *net, std::string netdef) {
    OriginalInitializer originalInitializer;
    return createNetFromNetdef(net, netdef, &originalInitializer);
}
PUBLICAPI STATIC bool NetdefToNet::createNetFromNetdefCharStar(NeuralNet *net, const char *netdef) {
    OriginalInitializer originalInitializer;
    return createNetFromNetdef(net, netdef, &originalInitializer);
}

STATIC bool NetdefToNet::createNetFromNetdef(NeuralNet *net, std::string netdef, WeightsInitializer *weightsInitializer) {
    string netDefLower = toLower(netdef);
//    cout << "netDefLower [" << netDefLower << "]" << endl;
    try {
        netDefLower = expandMultipliers(netDefLower);
    } catch(runtime_error &e) {
        cout << e.what() << endl;
        return false;
    }
//    cout << "netDefLower [" << netDefLower << "]" << endl;
    vector<string> splitNetDef = split(netDefLower, "-");
    if(netdef != "") {
        for(int i = 0; i < (int)splitNetDef.size(); i++) {
            string thisLayerDef = splitNetDef[i];
//            cout << "thisLayerDef [" << thisLayerDef << "]" << endl;
            if(!parseSubstring(weightsInitializer, net, thisLayerDef, i == (int)splitNetDef.size() - 1) ) {
                return false;
            }
        }
    }
    net->addLayer(SoftMaxMaker::instance());
    return true;
}<|endoftext|>


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

 Program:   Visualization Toolkit
 Module:    vtkAMRBaseReader.cxx

 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 All rights reserved.
 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notice for more information.

 =========================================================================*/
#include "vtkAMRBaseReader.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkDataObject.h"
#include "vtkMultiProcessController.h"
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkDataArraySelection.h"
#include "vtkCallbackCommand.h"
#include "vtkIndent.h"
#include "vtkSmartPointer.h"
#include "vtkCompositeDataPipeline.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkAMRDataSetCache.h"
#include "vtkUniformGrid.h"
#include "vtkDataArray.h"
#include "vtkCellData.h"
#include "vtkPointData.h"
#include "vtkAMRUtilities.h"

#include <cassert>

vtkAMRBaseReader::vtkAMRBaseReader()
{

}

//------------------------------------------------------------------------------
vtkAMRBaseReader::~vtkAMRBaseReader()
{
  this->PointDataArraySelection->RemoveObserver( this->SelectionObserver );
  this->CellDataArraySelection->RemoveObserver( this->SelectionObserver );
  this->SelectionObserver->Delete( );
  this->CellDataArraySelection->Delete( );
  this->PointDataArraySelection->Delete( );
  if( this->metadata != NULL )
    this->metadata->Delete();
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::FillOutputPortInformation(
    int vtkNotUsed(port),vtkInformation *info )
{
  info->Set( vtkDataObject::DATA_TYPE_NAME(), "vtkHierarchicalBoxDataSet" );
  return 1;
}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::PrintSelf( std::ostream &os, vtkIndent indent )
{
  this->Superclass::PrintSelf( os, indent );
}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::Initialize()
{
  this->SetNumberOfInputPorts( 0 );
  this->FileName       = NULL;
  this->MaxLevel       = 0;
  this->metadata       = NULL;
  this->Controller     = vtkMultiProcessController::GetGlobalController();
  this->InitialRequest = true;

  this->CellDataArraySelection  = vtkDataArraySelection::New();
  this->PointDataArraySelection = vtkDataArraySelection::New();
  this->SelectionObserver       = vtkCallbackCommand::New();
  this->SelectionObserver->SetCallback(
      &vtkAMRBaseReader::SelectionModifiedCallback);
  this->SelectionObserver->SetClientData( this );
  this->CellDataArraySelection->AddObserver(
     vtkCommand::ModifiedEvent,this->SelectionObserver );
  this->PointDataArraySelection->AddObserver(
     vtkCommand::ModifiedEvent, this->SelectionObserver );

}

//----------------------------------------------------------------------------
void vtkAMRBaseReader::SelectionModifiedCallback(
    vtkObject*, unsigned long, void* clientdata, void*)
{
  static_cast<vtkAMRBaseReader*>(clientdata)->Modified();
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::GetNumberOfPointArrays()
{
  return( this->PointDataArraySelection->GetNumberOfArrays() );
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::GetNumberOfCellArrays()
{
  return( this->CellDataArraySelection->GetNumberOfArrays() );
}

//------------------------------------------------------------------------------
const char* vtkAMRBaseReader::GetPointArrayName(int index)
{
  return( this->PointDataArraySelection->GetArrayName( index ) );
}

//------------------------------------------------------------------------------
const char* vtkAMRBaseReader::GetCellArrayName(int index)
{
  return( this->CellDataArraySelection->GetArrayName( index )  );
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::GetPointArrayStatus(const char* name)
{
  return( this->PointDataArraySelection->ArrayIsEnabled( name ) );
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::GetCellArrayStatus(const char* name)
{
  return( this->CellDataArraySelection->ArrayIsEnabled( name ) );
}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::SetPointArrayStatus(const char* name, int status)
{

  if( status )
    {
    this->PointDataArraySelection->EnableArray(name);
    }
  else
    {
    this->PointDataArraySelection->DisableArray(name);
    }

}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::SetCellArrayStatus(const char* name, int status)
{
  if( status )
    {
    this->CellDataArraySelection->EnableArray( name );
    }
  else
    {
    this->CellDataArraySelection->DisableArray( name );
    }
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::GetBlockProcessId( const int blockIdx )
{
  // If this is reader instance is serial, return Process 0
  // as the Process ID for the corresponding block.
  if( !this->IsParallel() )
    return 0;

  int N = this->Controller->GetNumberOfProcesses();
  return( blockIdx%N );
}

//------------------------------------------------------------------------------
bool vtkAMRBaseReader::IsBlockMine( const int blockIdx )
{
  // If this reader instance does not run in parallel, then,
  // all blocks are owned by this reader.
  if( !this->IsParallel() )
    return true;

  int myRank = this->Controller->GetLocalProcessId();
  if( myRank == this->GetBlockProcessId( blockIdx ) )
    return true;
  return false;
}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::InitializeArraySelections()
{
  if( this->InitialRequest )
    {
      this->PointDataArraySelection->DisableAllArrays();
      this->CellDataArraySelection->DisableAllArrays();
      this->InitialRequest=false;
    }
}

//------------------------------------------------------------------------------
bool vtkAMRBaseReader::IsParallel( )
{
  if( this->Controller == NULL )
    return false;

  if( this->Controller->GetNumberOfProcesses() > 1 )
    return true;

  return false;
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::RequestInformation(
    vtkInformation *rqst,
    vtkInformationVector **inputVector,
    vtkInformationVector *outputVector )
{
  this->Superclass::RequestInformation( rqst, inputVector, outputVector );

  if( this->metadata == NULL )
    {
      this->metadata = vtkHierarchicalBoxDataSet::New();
      vtkInformation* info = outputVector->GetInformationObject(0);
      assert( "pre: output information object is NULL" && (info != NULL) );
      this->FillMetaData( );
      info->Set( vtkCompositeDataPipeline::COMPOSITE_DATA_META_DATA(),
          this->metadata );
    }

  this->Modified();
  return 1;
}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::SetupBlockRequest( vtkInformation *outInf )
{
  assert( "pre: output information is NULL" && (outInf != NULL) );

  if( outInf->Has(
      vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES() ) )
    {
      assert( "Metadata should not be null" && (this->metadata!=NULL) );
      this->ReadMetaData();

      int size =
       outInf->Length(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES() );
      int *indices =
        outInf->Get(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES() );

      this->BlockMap.clear();
      this->BlockMap.resize( size );

      for( int i=0; i < size; ++i )
        {
          this->BlockMap[ i ] = indices[ i ];
        }
    }
  else
    {
     this->ReadMetaData();
     this->GenerateBlockMap();
    }

}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::GetAMRData(
    const int blockIdx, vtkUniformGrid *block, const char *fieldName )
{
  assert( "pre: AMR block is NULL" && (block != NULL) );
  assert( "pre: field name is NULL" && (fieldName != NULL) );

  // If caching is disabled load the data from file
  if( !this->IsCachingEnabled() )
    {
      this->GetAMRGridData( blockIdx, block, fieldName );
      return;
    }

  // Caching is enabled.
  // Check the cache to see if the data has already been read.
  // Otherwise, read it and cache it.
  if( this->amrCache->HasAMRBlockCellData( blockIdx, fieldName ) )
    {
     vtkDataArray *data =
         this->amrCache->GetAMRBlockCellData( blockIdx, fieldName );
     assert( "pre: cached data is NULL!" && (data != NULL) );

     block->GetCellData()->AddArray( data );
    }
  else
    {
      this->GetAMRGridData( blockIdx, block, fieldName );
      std::cout << "Inserting data to cache....\n";
      std::cout.flush();
      this->amrCache->InsertAMRBlockCellData(
          blockIdx, block->GetCellData()->GetArray( fieldName ) );
    }

  assert( "Code should never reach here!" && (false) );
}

//------------------------------------------------------------------------------
vtkUniformGrid* vtkAMRBaseReader::GetAMRBlock( const int blockIdx )
{

  // If caching is disabled load the data from file
  if( !this->IsCachingEnabled() )
    {
      vtkUniformGrid *gridPtr = this->GetAMRGrid( blockIdx );
      assert( "pre: grid pointer is NULL" && (gridPtr != NULL) );
      return( gridPtr );
    }

  // Caching is enabled.
  // Check the cache to see if the block has already been read.
  // Otherwise, read it and cache it.
  if( this->amrCache->HasAMRBlock( blockIdx ) )
    {
      vtkUniformGrid *gridPtr    = vtkUniformGrid::New();
      vtkUniformGrid *cachedGrid = this->amrCache->GetAMRBlock( blockIdx );
      gridPtr->CopyStructure( cachedGrid );
      return( gridPtr );
    }
  else
    {
      vtkUniformGrid *cachedGrid = vtkUniformGrid::New();
      vtkUniformGrid *gridPtr    = this->GetAMRGrid( blockIdx );
      assert( "pre: grid pointer is NULL" && (gridPtr != NULL) );
      cachedGrid->CopyStructure( gridPtr );

      std::cout << "Inserting block to cache...";
      std::cout.flush();
      this->amrCache->InsertAMRBlock( blockIdx, cachedGrid );
      return( gridPtr );
    }

  assert( "Code should never reach here!" && (false) );
  return NULL;
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::RequestData(
        vtkInformation* vtkNotUsed(request),
        vtkInformationVector** vtkNotUsed(inputVector),
        vtkInformationVector* outputVector )
{

  vtkInformation            *outInf = outputVector->GetInformationObject( 0 );
  vtkHierarchicalBoxDataSet *output =
    vtkHierarchicalBoxDataSet::SafeDownCast(
     outInf->Get( vtkDataObject::DATA_OBJECT() ) );
  assert( "pre: output AMR dataset is NULL" && ( output != NULL ) );

  // Setup the block request
  this->SetupBlockRequest( outInf );

  // Initialize counter of the number of blocks at each level.
  // This counter is used to compute the block index w.r.t. the
  // hierarchical box data-structure. Note that then number of blocks
  // can change based on user constraints, e.g., the number of levels
  // visible.
  vtkstd::vector< int > idxcounter;
  idxcounter.resize(this->GetNumberOfLevels()+1, 0);

  // Find the number of blocks to be processed. BlockMap.size()
  // has all the blocks that are to be processesed and may be
  // less than or equal to this->GetNumberOfBlocks(), i.e., the
  // total number of blocks.
  int numBlocks = static_cast< int >( this->BlockMap.size() );
  for( int block=0; block < numBlocks; ++block )
    {

      int blockIdx = this->BlockMap[ block ];
      int level    = this->GetBlockLevel( blockIdx );

      if( this->IsBlockMine(block) )
        {

          // STEP 0: Get the AMR block
          vtkUniformGrid *amrBlock = this->GetAMRBlock( blockIdx );
          assert( "pre: AMR block is NULL" && (amrBlock != NULL) );

          // STEP 2: Load any point-data
          for( int i=0; i < this->GetNumberOfPointArrays(); ++i )
            {
              if( this->GetPointArrayStatus( this->GetPointArrayName(i) ) )
                {
                  // TODO: load point data
                }
            }

          // STEP 3: Load any cell-data
          for( int i=0; i < this->GetNumberOfCellArrays(); ++i )
            {
              if( this->GetCellArrayStatus( this->GetCellArrayName( i ) ) )
                {
                  this->GetAMRData(
                      blockIdx,amrBlock,this->GetCellArrayName( i ) );
                }
            }

          output->SetDataSet( level,idxcounter[level],amrBlock );
          idxcounter[level]++;
        } // END if the block belongs to this process
      else
        {
          output->SetDataSet( idxcounter[level],level,NULL );
          idxcounter[level]++;
        }

    } // END for all blocks

  // Generate all the AMR metadata & the visibility arrays
  vtkAMRUtilities::GenerateMetaData( output, this->Controller );
  output->GenerateVisibilityArrays();

  // If this instance of the reader is not parallel, block until all processes
  // read their blocks.
  if( this->IsParallel() )
    this->Controller->Barrier();

  outInf = NULL;
  output = NULL;
  this->Modified();
  return 1;
}
<commit_msg>BUGFIX: Allocate AMR cache in vtkAMRBaseReader<commit_after>/*=========================================================================

 Program:   Visualization Toolkit
 Module:    vtkAMRBaseReader.cxx

 Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
 All rights reserved.
 See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

 This software is distributed WITHOUT ANY WARRANTY; without even
 the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
 PURPOSE.  See the above copyright notice for more information.

 =========================================================================*/
#include "vtkAMRBaseReader.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkDataObject.h"
#include "vtkMultiProcessController.h"
#include "vtkHierarchicalBoxDataSet.h"
#include "vtkDataArraySelection.h"
#include "vtkCallbackCommand.h"
#include "vtkIndent.h"
#include "vtkSmartPointer.h"
#include "vtkCompositeDataPipeline.h"
#include "vtkStreamingDemandDrivenPipeline.h"
#include "vtkAMRDataSetCache.h"
#include "vtkUniformGrid.h"
#include "vtkDataArray.h"
#include "vtkCellData.h"
#include "vtkPointData.h"
#include "vtkAMRUtilities.h"

#include <cassert>

vtkAMRBaseReader::vtkAMRBaseReader()
{

}

//------------------------------------------------------------------------------
vtkAMRBaseReader::~vtkAMRBaseReader()
{
  this->PointDataArraySelection->RemoveObserver( this->SelectionObserver );
  this->CellDataArraySelection->RemoveObserver( this->SelectionObserver );
  this->SelectionObserver->Delete( );
  this->CellDataArraySelection->Delete( );
  this->PointDataArraySelection->Delete( );
  if( this->metadata != NULL )
    this->metadata->Delete();
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::FillOutputPortInformation(
    int vtkNotUsed(port),vtkInformation *info )
{
  info->Set( vtkDataObject::DATA_TYPE_NAME(), "vtkHierarchicalBoxDataSet" );
  return 1;
}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::PrintSelf( std::ostream &os, vtkIndent indent )
{
  this->Superclass::PrintSelf( os, indent );
}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::Initialize()
{
  this->SetNumberOfInputPorts( 0 );
  this->FileName       = NULL;
  this->MaxLevel       = 0;
  this->metadata       = NULL;
  this->Controller     = vtkMultiProcessController::GetGlobalController();
  this->InitialRequest = true;
  this->amrCache       = vtkAMRDataSetCache::New();

  this->CellDataArraySelection  = vtkDataArraySelection::New();
  this->PointDataArraySelection = vtkDataArraySelection::New();
  this->SelectionObserver       = vtkCallbackCommand::New();
  this->SelectionObserver->SetCallback(
      &vtkAMRBaseReader::SelectionModifiedCallback);
  this->SelectionObserver->SetClientData( this );
  this->CellDataArraySelection->AddObserver(
     vtkCommand::ModifiedEvent,this->SelectionObserver );
  this->PointDataArraySelection->AddObserver(
     vtkCommand::ModifiedEvent, this->SelectionObserver );

}

//----------------------------------------------------------------------------
void vtkAMRBaseReader::SelectionModifiedCallback(
    vtkObject*, unsigned long, void* clientdata, void*)
{
  static_cast<vtkAMRBaseReader*>(clientdata)->Modified();
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::GetNumberOfPointArrays()
{
  return( this->PointDataArraySelection->GetNumberOfArrays() );
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::GetNumberOfCellArrays()
{
  return( this->CellDataArraySelection->GetNumberOfArrays() );
}

//------------------------------------------------------------------------------
const char* vtkAMRBaseReader::GetPointArrayName(int index)
{
  return( this->PointDataArraySelection->GetArrayName( index ) );
}

//------------------------------------------------------------------------------
const char* vtkAMRBaseReader::GetCellArrayName(int index)
{
  return( this->CellDataArraySelection->GetArrayName( index )  );
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::GetPointArrayStatus(const char* name)
{
  return( this->PointDataArraySelection->ArrayIsEnabled( name ) );
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::GetCellArrayStatus(const char* name)
{
  return( this->CellDataArraySelection->ArrayIsEnabled( name ) );
}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::SetPointArrayStatus(const char* name, int status)
{

  if( status )
    {
    this->PointDataArraySelection->EnableArray(name);
    }
  else
    {
    this->PointDataArraySelection->DisableArray(name);
    }

}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::SetCellArrayStatus(const char* name, int status)
{
  if( status )
    {
    this->CellDataArraySelection->EnableArray( name );
    }
  else
    {
    this->CellDataArraySelection->DisableArray( name );
    }
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::GetBlockProcessId( const int blockIdx )
{
  // If this is reader instance is serial, return Process 0
  // as the Process ID for the corresponding block.
  if( !this->IsParallel() )
    return 0;

  int N = this->Controller->GetNumberOfProcesses();
  return( blockIdx%N );
}

//------------------------------------------------------------------------------
bool vtkAMRBaseReader::IsBlockMine( const int blockIdx )
{
  // If this reader instance does not run in parallel, then,
  // all blocks are owned by this reader.
  if( !this->IsParallel() )
    return true;

  int myRank = this->Controller->GetLocalProcessId();
  if( myRank == this->GetBlockProcessId( blockIdx ) )
    return true;
  return false;
}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::InitializeArraySelections()
{
  if( this->InitialRequest )
    {
      this->PointDataArraySelection->DisableAllArrays();
      this->CellDataArraySelection->DisableAllArrays();
      this->InitialRequest=false;
    }
}

//------------------------------------------------------------------------------
bool vtkAMRBaseReader::IsParallel( )
{
  if( this->Controller == NULL )
    return false;

  if( this->Controller->GetNumberOfProcesses() > 1 )
    return true;

  return false;
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::RequestInformation(
    vtkInformation *rqst,
    vtkInformationVector **inputVector,
    vtkInformationVector *outputVector )
{
  this->Superclass::RequestInformation( rqst, inputVector, outputVector );

  if( this->metadata == NULL )
    {
      this->metadata = vtkHierarchicalBoxDataSet::New();
      vtkInformation* info = outputVector->GetInformationObject(0);
      assert( "pre: output information object is NULL" && (info != NULL) );
      this->FillMetaData( );
      info->Set( vtkCompositeDataPipeline::COMPOSITE_DATA_META_DATA(),
          this->metadata );
    }

  this->Modified();
  return 1;
}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::SetupBlockRequest( vtkInformation *outInf )
{
  assert( "pre: output information is NULL" && (outInf != NULL) );

  if( outInf->Has(
      vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES() ) )
    {
      assert( "Metadata should not be null" && (this->metadata!=NULL) );
      this->ReadMetaData();

      int size =
       outInf->Length(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES() );
      int *indices =
        outInf->Get(vtkCompositeDataPipeline::UPDATE_COMPOSITE_INDICES() );

      this->BlockMap.clear();
      this->BlockMap.resize( size );

      for( int i=0; i < size; ++i )
        {
          this->BlockMap[ i ] = indices[ i ];
        }
    }
  else
    {
     this->ReadMetaData();
     this->GenerateBlockMap();
    }

}

//------------------------------------------------------------------------------
void vtkAMRBaseReader::GetAMRData(
    const int blockIdx, vtkUniformGrid *block, const char *fieldName )
{
  assert( "pre: AMR block is NULL" && (block != NULL) );
  assert( "pre: field name is NULL" && (fieldName != NULL) );

  // If caching is disabled load the data from file
  if( !this->IsCachingEnabled() )
    {
      this->GetAMRGridData( blockIdx, block, fieldName );
      return;
    }

  // Caching is enabled.
  // Check the cache to see if the data has already been read.
  // Otherwise, read it and cache it.
  if( this->amrCache->HasAMRBlockCellData( blockIdx, fieldName ) )
    {
     vtkDataArray *data =
         this->amrCache->GetAMRBlockCellData( blockIdx, fieldName );
     assert( "pre: cached data is NULL!" && (data != NULL) );

     block->GetCellData()->AddArray( data );
    }
  else
    {
      this->GetAMRGridData( blockIdx, block, fieldName );
      std::cout << "Inserting data to cache....\n";
      std::cout.flush();
      this->amrCache->InsertAMRBlockCellData(
          blockIdx, block->GetCellData()->GetArray( fieldName ) );
    }

}

//------------------------------------------------------------------------------
vtkUniformGrid* vtkAMRBaseReader::GetAMRBlock( const int blockIdx )
{

  // If caching is disabled load the data from file
  if( !this->IsCachingEnabled() )
    {
      vtkUniformGrid *gridPtr = this->GetAMRGrid( blockIdx );
      assert( "pre: grid pointer is NULL" && (gridPtr != NULL) );
      return( gridPtr );
    }

  // Caching is enabled.
  // Check the cache to see if the block has already been read.
  // Otherwise, read it and cache it.
  if( this->amrCache->HasAMRBlock( blockIdx ) )
    {
      vtkUniformGrid *gridPtr    = vtkUniformGrid::New();
      vtkUniformGrid *cachedGrid = this->amrCache->GetAMRBlock( blockIdx );
      gridPtr->CopyStructure( cachedGrid );
      return( gridPtr );
    }
  else
    {
      vtkUniformGrid *cachedGrid = vtkUniformGrid::New();
      vtkUniformGrid *gridPtr    = this->GetAMRGrid( blockIdx );
      assert( "pre: grid pointer is NULL" && (gridPtr != NULL) );
      cachedGrid->CopyStructure( gridPtr );

      std::cout << "Inserting block to cache...";
      std::cout.flush();
      this->amrCache->InsertAMRBlock( blockIdx, cachedGrid );
      return( gridPtr );
    }

  assert( "Code should never reach here!" && (false) );
  return NULL;
}

//------------------------------------------------------------------------------
int vtkAMRBaseReader::RequestData(
        vtkInformation* vtkNotUsed(request),
        vtkInformationVector** vtkNotUsed(inputVector),
        vtkInformationVector* outputVector )
{

  vtkInformation            *outInf = outputVector->GetInformationObject( 0 );
  vtkHierarchicalBoxDataSet *output =
    vtkHierarchicalBoxDataSet::SafeDownCast(
     outInf->Get( vtkDataObject::DATA_OBJECT() ) );
  assert( "pre: output AMR dataset is NULL" && ( output != NULL ) );

  // Setup the block request
  this->SetupBlockRequest( outInf );

  // Initialize counter of the number of blocks at each level.
  // This counter is used to compute the block index w.r.t. the
  // hierarchical box data-structure. Note that then number of blocks
  // can change based on user constraints, e.g., the number of levels
  // visible.
  vtkstd::vector< int > idxcounter;
  idxcounter.resize(this->GetNumberOfLevels()+1, 0);

  // Find the number of blocks to be processed. BlockMap.size()
  // has all the blocks that are to be processesed and may be
  // less than or equal to this->GetNumberOfBlocks(), i.e., the
  // total number of blocks.
  int numBlocks = static_cast< int >( this->BlockMap.size() );
  for( int block=0; block < numBlocks; ++block )
    {

      int blockIdx = this->BlockMap[ block ];
      int level    = this->GetBlockLevel( blockIdx );

      if( this->IsBlockMine(block) )
        {

          // STEP 0: Get the AMR block
          vtkUniformGrid *amrBlock = this->GetAMRBlock( blockIdx );
          assert( "pre: AMR block is NULL" && (amrBlock != NULL) );

          // STEP 2: Load any point-data
          for( int i=0; i < this->GetNumberOfPointArrays(); ++i )
            {
              if( this->GetPointArrayStatus( this->GetPointArrayName(i) ) )
                {
                  // TODO: load point data
                }
            }

          // STEP 3: Load any cell-data
          for( int i=0; i < this->GetNumberOfCellArrays(); ++i )
            {
              if( this->GetCellArrayStatus( this->GetCellArrayName( i ) ) )
                {
                  this->GetAMRData(
                      blockIdx,amrBlock,this->GetCellArrayName( i ) );
                }
            }

          output->SetDataSet( level,idxcounter[level],amrBlock );
          idxcounter[level]++;
        } // END if the block belongs to this process
      else
        {
          output->SetDataSet( idxcounter[level],level,NULL );
          idxcounter[level]++;
        }

    } // END for all blocks

  // Generate all the AMR metadata & the visibility arrays
  vtkAMRUtilities::GenerateMetaData( output, this->Controller );
  output->GenerateVisibilityArrays();

  // If this instance of the reader is not parallel, block until all processes
  // read their blocks.
  if( this->IsParallel() )
    this->Controller->Barrier();

  outInf = NULL;
  output = NULL;
  this->Modified();
  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.                  *
 **************************************************************************/

//-------------------------------------------------------------------------
//     Implementation of the Analysis Oriented Data (AOD) event summary
//     Purpose : container of event important information for soft analysis
//     Author : Renaud Vernet, IPHC, Strasbourg
//-------------------------------------------------------------------------

#include "AliAODevent.h"
#include "AliESDVertex.h"
#include "AliESD.h"
#include "AliAODv0.h"
#include "AliAODxi.h"

ClassImp(AliAODevent);

AliAODevent::AliAODevent() {
  fV0s      = new TClonesArray("AliAODv0");
  fCascades = new TClonesArray("AliAODxi");
}

AliAODevent::~AliAODevent() {
  delete fV0s;
}

AliAODevent::AliAODevent(AliESD* e) {
  fV0s      = new TClonesArray("AliAODv0");
  fCascades = new TClonesArray("AliAODxi");
  fRunNumber        = (UInt_t)e->GetRunNumber();
  fEventNumber      = (UInt_t)e->GetEventNumber();
  fNumberOfTracks   = (UInt_t)e->GetNumberOfTracks();

  const AliESDVertex* V = e->GetVertex();
  fPrimVertexX = V->GetXv();
  fPrimVertexY = V->GetYv();
  fPrimVertexZ = V->GetZv();

  for (Int_t i=0; i<e->GetNumberOfV0s(); i++) {
    AliAODv0* v=new AliAODv0(e->GetV0(i),e);
    this->AddV0(v);
    delete v;
  }

  for (Int_t i=0; i<e->GetNumberOfCascades(); i++) {
    AliAODxi* c=new AliAODxi(e->GetCascade(i),e);
    this->AddCascade(c);
    delete c;
  }
}

AliAODevent::AliAODevent(const AliAODevent& aod) :
  TObject(aod),
  fV0s((TClonesArray*)aod.fV0s->Clone()),
  fCascades((TClonesArray*)aod.fCascades->Clone()),
  fPrimVertexX(aod.fPrimVertexX),
  fPrimVertexY(aod.fPrimVertexY),
  fPrimVertexZ(aod.fPrimVertexZ),
  fRunNumber(aod.fRunNumber),
  fEventNumber(aod.fEventNumber),
  fNumberOfTracks(aod.fNumberOfTracks)
{
  //copy constructor
}

AliAODevent& AliAODevent::operator=(const AliAODevent& aod){
  // assignment operator
  if(this!=&aod) {
    fPrimVertexX    = aod.fPrimVertexX;
    fPrimVertexY    = aod.fPrimVertexY;
    fPrimVertexZ    = aod.fPrimVertexZ;
    fRunNumber      = aod.fRunNumber;
    fEventNumber    = aod.fEventNumber;
    fNumberOfTracks = aod.fNumberOfTracks;

    delete fV0s;
    delete fCascades;
    fV0s=(TClonesArray*)aod.fV0s->Clone();
    fCascades=(TClonesArray*)aod.fCascades->Clone();
  }
  return *this;
}

void AliAODevent::AddV0(AliAODv0* v0) {
  Int_t idx=fV0s->GetEntries();
  TClonesArray& arr=*fV0s;
  new(arr[idx]) AliAODv0(*v0);
}

void AliAODevent::AddCascade(AliAODxi* xi) {
  Int_t idx=fCascades->GetEntries();
  TClonesArray& arr=*fCascades;
  new(arr[idx]) AliAODxi(*xi);
}
<commit_msg>Extra ; removed.<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.                  *
 **************************************************************************/

//-------------------------------------------------------------------------
//     Implementation of the Analysis Oriented Data (AOD) event summary
//     Purpose : container of event important information for soft analysis
//     Author : Renaud Vernet, IPHC, Strasbourg
//-------------------------------------------------------------------------

#include "AliAODevent.h"
#include "AliESDVertex.h"
#include "AliESD.h"
#include "AliAODv0.h"
#include "AliAODxi.h"

ClassImp(AliAODevent)

AliAODevent::AliAODevent() {
  fV0s      = new TClonesArray("AliAODv0");
  fCascades = new TClonesArray("AliAODxi");
}

AliAODevent::~AliAODevent() {
  delete fV0s;
}

AliAODevent::AliAODevent(AliESD* e) {
  fV0s      = new TClonesArray("AliAODv0");
  fCascades = new TClonesArray("AliAODxi");
  fRunNumber        = (UInt_t)e->GetRunNumber();
  fEventNumber      = (UInt_t)e->GetEventNumber();
  fNumberOfTracks   = (UInt_t)e->GetNumberOfTracks();

  const AliESDVertex* V = e->GetVertex();
  fPrimVertexX = V->GetXv();
  fPrimVertexY = V->GetYv();
  fPrimVertexZ = V->GetZv();

  for (Int_t i=0; i<e->GetNumberOfV0s(); i++) {
    AliAODv0* v=new AliAODv0(e->GetV0(i),e);
    this->AddV0(v);
    delete v;
  }

  for (Int_t i=0; i<e->GetNumberOfCascades(); i++) {
    AliAODxi* c=new AliAODxi(e->GetCascade(i),e);
    this->AddCascade(c);
    delete c;
  }
}

AliAODevent::AliAODevent(const AliAODevent& aod) :
  TObject(aod),
  fV0s((TClonesArray*)aod.fV0s->Clone()),
  fCascades((TClonesArray*)aod.fCascades->Clone()),
  fPrimVertexX(aod.fPrimVertexX),
  fPrimVertexY(aod.fPrimVertexY),
  fPrimVertexZ(aod.fPrimVertexZ),
  fRunNumber(aod.fRunNumber),
  fEventNumber(aod.fEventNumber),
  fNumberOfTracks(aod.fNumberOfTracks)
{
  //copy constructor
}

AliAODevent& AliAODevent::operator=(const AliAODevent& aod){
  // assignment operator
  if(this!=&aod) {
    fPrimVertexX    = aod.fPrimVertexX;
    fPrimVertexY    = aod.fPrimVertexY;
    fPrimVertexZ    = aod.fPrimVertexZ;
    fRunNumber      = aod.fRunNumber;
    fEventNumber    = aod.fEventNumber;
    fNumberOfTracks = aod.fNumberOfTracks;

    delete fV0s;
    delete fCascades;
    fV0s=(TClonesArray*)aod.fV0s->Clone();
    fCascades=(TClonesArray*)aod.fCascades->Clone();
  }
  return *this;
}

void AliAODevent::AddV0(AliAODv0* v0) {
  Int_t idx=fV0s->GetEntries();
  TClonesArray& arr=*fV0s;
  new(arr[idx]) AliAODv0(*v0);
}

void AliAODevent::AddCascade(AliAODxi* xi) {
  Int_t idx=fCascades->GetEntries();
  TClonesArray& arr=*fCascades;
  new(arr[idx]) AliAODxi(*xi);
}
<|endoftext|>


<commit_before>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   ConsoleAPI.cpp
 *  @brief  Console core API.
 */

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "ConsoleAPI.h"
#include "ConsoleWidget.h"
#include "ShellInputThread.h"
#include "Application.h"
#include "Profiler.h"
#include "Framework.h"
#include "InputAPI.h"
#include "UiAPI.h"
#include "UiGraphicsView.h"
#include "LoggingFunctions.h"
#include "FunctionInvoker.h"

#include <stdlib.h>

#include <QFile>
#include <QTextStream>

#include "MemoryLeakCheck.h"

ConsoleAPI::ConsoleAPI(Framework *fw) :
    QObject(fw),
    framework(fw),
    enabledLogChannels(LogLevelErrorWarnInfo),
    logFile(0),
    logFileText(0)
{
    if (!fw->IsHeadless())
        consoleWidget = new ConsoleWidget(framework);

    inputContext = framework->Input()->RegisterInputContext("Console", 100);
    inputContext->SetTakeKeyboardEventsOverQt(true);
    connect(inputContext.get(), SIGNAL(KeyEventReceived(KeyEvent *)), SLOT(HandleKeyEvent(KeyEvent *)));

    RegisterCommand("help", "Lists all registered commands.", this, SLOT(ListCommands()));
    RegisterCommand("clear", "Clears the console log.", this, SLOT(ClearLog()));
    RegisterCommand("loglevel", "Sets the current log level. Call with one of the parameters \"error\", \"warning\", \"info\", or \"debug\".",
        this, SLOT(SetLogLevel(const QString &)));

    shellInputThread = boost::shared_ptr<ShellInputThread>(new ShellInputThread);

    QStringList logLevel = fw->CommandLineParameters("--loglevel");
    if (logLevel.size() >= 1)
        SetLogLevel(logLevel[logLevel.size()-1]);
    if (logLevel.size() > 1)
        LogWarning("Ignoring multiple --loglevel command line parameters!");

    QStringList logFile = fw->CommandLineParameters("--logfile");
    if (logFile.size() >= 1)
        SetLogFile(logFile[logFile.size()-1]);
    if (logFile.size() > 1)
        LogWarning("Ignoring multiple --logfile command line parameters!");
}

ConsoleAPI::~ConsoleAPI()
{
    Reset();
}

void ConsoleAPI::Reset()
{
    commands.clear();
    inputContext.reset();
    SAFE_DELETE(consoleWidget);
    shellInputThread.reset();
    SAFE_DELETE(logFileText);
    SAFE_DELETE(logFile);
}

QVariant ConsoleCommand::Invoke(const QStringList &params)
{
    QVariant returnValue;

    // If we have a target QObject, invoke it.
    if (target)
    {
        FunctionInvoker fi;
        QString errorMessage;
        fi.Invoke(target, functionName, params, &returnValue, &errorMessage);
        if (!errorMessage.isEmpty())
            LogError("ConsoleCommand::Invoke returned an error: " + errorMessage);
    }

    // Also, there may exist a script-registered handler that implements this console command - invoke it.
    emit Invoked(params);

    return returnValue;
}

ConsoleCommand *ConsoleAPI::RegisterCommand(const QString &name, const QString &desc)
{
    if (commands.find(name) != commands.end())
    {
        LogWarning("ConsoleAPI: Command " + name + " is already registered.");
        return commands[name].get();
    }

    boost::shared_ptr<ConsoleCommand> command = boost::shared_ptr<ConsoleCommand>(new ConsoleCommand(name, desc, 0, ""));
    commands[name] = command;
    return command.get();
}

void ConsoleAPI::RegisterCommand(const QString &name, const QString &desc, QObject *receiver, const char *memberSlot)
{
    if (commands.find(name) != commands.end())
    {
        LogWarning("ConsoleAPI: Command " + name + " is already registered.");
        return;
    }

    boost::shared_ptr<ConsoleCommand> command = boost::shared_ptr<ConsoleCommand>(new ConsoleCommand(name, desc, receiver, memberSlot+1));
    commands[name] = command;
}

/// Splits a string of form "MyFunctionName(param1, param2, param3, ...)" into
/// a commandName = "MyFunctionName" and a list of parameters as a StringList.
void ParseCommand(QString command, QString &commandName, QStringList &parameterList)
{
    command = command.trimmed();
    if (command.isEmpty())
        return;

    int split = command.indexOf("(");
    if (split == -1)
    {
        commandName = command;
        return;
    }

    commandName = command.left(split).trimmed();
    parameterList = command.mid(split+1).split(",");
}

void ConsoleAPI::ExecuteCommand(const QString &command)
{
    PROFILE(ConsoleAPI_ExecuteCommand);

    QString commandName;
    QStringList parameterList;
    ParseCommand(command, commandName, parameterList);
    if (commandName.isEmpty())
        return;

    CommandMap::iterator iter = commands.find(commandName);
    if (iter == commands.end())
    {
        LogError("Cannot find a console command \"" + commandName + "\"!");
        return;
    }

    iter->second->Invoke(parameterList);
}

void ConsoleAPI::Print(const QString &message)
{
    if (consoleWidget)
        consoleWidget->PrintToConsole(message);
    ///\todo Temporary hack which appends line ending in case it's not there (output of console commands in headless mode)
    if (!message.endsWith("\n"))
    {
        printf("%s\n", message.toStdString().c_str());
        if (logFileText)
        {
            (*logFileText) << message << "\n";
            /// \note If we want to guarantee that each message gets to the log even in the presence of a crash, we must flush()
            /// after each write. Tested that on Windows 7, if you kill the process using Ctrl-C on command line, or from
            /// task manager, the log will not contain all the text, so this is required for correctness.
            /// But this flush() after each message also causes a *serious* performance drawback.
            /// One way to try avoiding this issue is to move to using C API for file writing, and at atexit() and other crash
            /// handlers, close the file handle gracefully.
            logFileText->flush();
        }
    }
    else
    {
        printf("%s", message.toStdString().c_str());
        if (logFileText)
        {
            (*logFileText) << message;
            logFileText->flush(); // See comment about flush() above.
        }
    }
}

void ConsoleAPI::ListCommands()
{
    Print("Available console commands:");
    for(CommandMap::iterator iter = commands.begin(); iter != commands.end(); ++iter)
        Print(iter->first + " - " + iter->second->Description());
}

void ConsoleAPI::ClearLog()
{
    if (consoleWidget)
        consoleWidget->ClearLog();
#ifdef _WINDOWS
    system("cls");
#else
    system("clear");
#endif
}

void ConsoleAPI::SetLogLevel(const QString &level)
{
    if (level.compare("error", Qt::CaseInsensitive) == 0)
        SetEnabledLogChannels(LogLevelErrorsOnly);
    else if (level.compare("warning", Qt::CaseInsensitive) == 0)
        SetEnabledLogChannels(LogLevelErrorWarning);
    else if (level.compare("info", Qt::CaseInsensitive) == 0)
        SetEnabledLogChannels(LogLevelErrorWarnInfo);
    else if (level.compare("debug", Qt::CaseInsensitive) == 0)
        SetEnabledLogChannels(LogLevelErrorWarnInfoDebug);
    else
        LogError("Unknown parameter \"" + level + "\" specified to ConsoleAPI::SetLogLevel!");
}

void ConsoleAPI::SetLogFile(const QString &wildCardFilename)
{
    QString filename = Application::ParseWildCardFilename(wildCardFilename);

    // An empty log file closes the log output writing.
    if (filename.isEmpty())
    {
        SAFE_DELETE(logFileText);
        SAFE_DELETE(logFile);
        return;
    }
    logFile = new QFile(filename);
    bool isOpen = logFile->open(QIODevice::WriteOnly | QIODevice::Text);
    if (!isOpen)
    {
        LogError("Failed to open file \"" + filename + "\" for logging! (parsed from string \"" + wildCardFilename + "\")");
        SAFE_DELETE(logFile);
    }
    else
    {
        printf("Opened logging file \"%s\".\n", filename.toStdString().c_str());
        logFileText = new QTextStream(logFile);
    }
}

void ConsoleAPI::Update(f64 frametime)
{
    PROFILE(ConsoleAPI_Update);

    std::string input = shellInputThread->GetLine();
    if (input.length() > 0)
        ExecuteCommand(input.c_str());
}

void ConsoleAPI::ToggleConsole()
{
    if (consoleWidget)
        consoleWidget->ToggleConsole();
}

void ConsoleAPI::HandleKeyEvent(KeyEvent *e)
{
    const QKeySequence &toggleConsole = framework->Input()->KeyBinding("ToggleConsole", QKeySequence(Qt::Key_F1));
    if (e->sequence == toggleConsole)
        ToggleConsole();
}

void ConsoleAPI::LogInfo(const QString &message)
{
    ::LogInfo(message);
    Print(message);
}

void ConsoleAPI::LogWarning(const QString &message)
{
    ::LogWarning(message);
    Print("Warning: " + message);
}

void ConsoleAPI::LogError(const QString &message)
{
    ::LogError(message);
    Print("Error: " + message);
}

void ConsoleAPI::LogDebug(const QString &message)
{
#ifdef _DEBUG
    ::LogDebug(message);
    Print("Debug: " + message);
#endif
}

void ConsoleAPI::Log(u32 logChannel, const QString &message)
{
    if (!IsLogChannelEnabled(logChannel))
        return;

    Print(message);
}

void ConsoleAPI::SetEnabledLogChannels(u32 newChannels)
{
    enabledLogChannels = newChannels;
}

bool ConsoleAPI::IsLogChannelEnabled(u32 logChannel) const
{
    return (enabledLogChannels & logChannel) != 0;
}

u32 ConsoleAPI::EnabledLogChannels() const
{
    return enabledLogChannels;
}

<commit_msg>ParseCommand: Take into account the possible ending ")" and strip it away from the parameter list. Fixes issue #91, https://github.com/realXtend/naali/issues/91<commit_after>/**
 *  For conditions of distribution and use, see copyright notice in license.txt
 *
 *  @file   ConsoleAPI.cpp
 *  @brief  Console core API.
 */

#include "StableHeaders.h"
#include "DebugOperatorNew.h"

#include "ConsoleAPI.h"
#include "ConsoleWidget.h"
#include "ShellInputThread.h"
#include "Application.h"
#include "Profiler.h"
#include "Framework.h"
#include "InputAPI.h"
#include "UiAPI.h"
#include "UiGraphicsView.h"
#include "LoggingFunctions.h"
#include "FunctionInvoker.h"

#include <stdlib.h>

#include <QFile>
#include <QTextStream>

#include "MemoryLeakCheck.h"

ConsoleAPI::ConsoleAPI(Framework *fw) :
    QObject(fw),
    framework(fw),
    enabledLogChannels(LogLevelErrorWarnInfo),
    logFile(0),
    logFileText(0)
{
    if (!fw->IsHeadless())
        consoleWidget = new ConsoleWidget(framework);

    inputContext = framework->Input()->RegisterInputContext("Console", 100);
    inputContext->SetTakeKeyboardEventsOverQt(true);
    connect(inputContext.get(), SIGNAL(KeyEventReceived(KeyEvent *)), SLOT(HandleKeyEvent(KeyEvent *)));

    RegisterCommand("help", "Lists all registered commands.", this, SLOT(ListCommands()));
    RegisterCommand("clear", "Clears the console log.", this, SLOT(ClearLog()));
    RegisterCommand("loglevel", "Sets the current log level. Call with one of the parameters \"error\", \"warning\", \"info\", or \"debug\".",
        this, SLOT(SetLogLevel(const QString &)));

    shellInputThread = boost::shared_ptr<ShellInputThread>(new ShellInputThread);

    QStringList logLevel = fw->CommandLineParameters("--loglevel");
    if (logLevel.size() >= 1)
        SetLogLevel(logLevel[logLevel.size()-1]);
    if (logLevel.size() > 1)
        LogWarning("Ignoring multiple --loglevel command line parameters!");

    QStringList logFile = fw->CommandLineParameters("--logfile");
    if (logFile.size() >= 1)
        SetLogFile(logFile[logFile.size()-1]);
    if (logFile.size() > 1)
        LogWarning("Ignoring multiple --logfile command line parameters!");
}

ConsoleAPI::~ConsoleAPI()
{
    Reset();
}

void ConsoleAPI::Reset()
{
    commands.clear();
    inputContext.reset();
    SAFE_DELETE(consoleWidget);
    shellInputThread.reset();
    SAFE_DELETE(logFileText);
    SAFE_DELETE(logFile);
}

QVariant ConsoleCommand::Invoke(const QStringList &params)
{
    QVariant returnValue;

    // If we have a target QObject, invoke it.
    if (target)
    {
        FunctionInvoker fi;
        QString errorMessage;
        fi.Invoke(target, functionName, params, &returnValue, &errorMessage);
        if (!errorMessage.isEmpty())
            LogError("ConsoleCommand::Invoke returned an error: " + errorMessage);
    }

    // Also, there may exist a script-registered handler that implements this console command - invoke it.
    emit Invoked(params);

    return returnValue;
}

ConsoleCommand *ConsoleAPI::RegisterCommand(const QString &name, const QString &desc)
{
    if (commands.find(name) != commands.end())
    {
        LogWarning("ConsoleAPI: Command " + name + " is already registered.");
        return commands[name].get();
    }

    boost::shared_ptr<ConsoleCommand> command = boost::shared_ptr<ConsoleCommand>(new ConsoleCommand(name, desc, 0, ""));
    commands[name] = command;
    return command.get();
}

void ConsoleAPI::RegisterCommand(const QString &name, const QString &desc, QObject *receiver, const char *memberSlot)
{
    if (commands.find(name) != commands.end())
    {
        LogWarning("ConsoleAPI: Command " + name + " is already registered.");
        return;
    }

    boost::shared_ptr<ConsoleCommand> command = boost::shared_ptr<ConsoleCommand>(new ConsoleCommand(name, desc, receiver, memberSlot+1));
    commands[name] = command;
}

/// Splits a string of form "MyFunctionName(param1, param2, param3, ...)" into
/// a commandName = "MyFunctionName" and a list of parameters as a StringList.
void ParseCommand(QString command, QString &commandName, QStringList &parameterList)
{
    command = command.trimmed();
    if (command.isEmpty())
        return;

    int split = command.indexOf("(");
    if (split == -1)
    {
        commandName = command;
        return;
    }

    commandName = command.left(split).trimmed();
    // Take into account the possible ending ")" and strip it away from the parameter list.
    // Remove it only if it's the last character in the string, as f.ex. some code execution console
    // command could contain ')' in the syntax.
    int endOfSplit = command.lastIndexOf(")");
    if (endOfSplit != -1 && endOfSplit == command.length()-1)
        command.remove(endOfSplit, 1);
    parameterList = command.mid(split+1).split(",");
}

void ConsoleAPI::ExecuteCommand(const QString &command)
{
    PROFILE(ConsoleAPI_ExecuteCommand);

    QString commandName;
    QStringList parameterList;
    ParseCommand(command, commandName, parameterList);
    if (commandName.isEmpty())
        return;

    CommandMap::iterator iter = commands.find(commandName);
    if (iter == commands.end())
    {
        LogError("Cannot find a console command \"" + commandName + "\"!");
        return;
    }

    iter->second->Invoke(parameterList);
}

void ConsoleAPI::Print(const QString &message)
{
    if (consoleWidget)
        consoleWidget->PrintToConsole(message);
    ///\todo Temporary hack which appends line ending in case it's not there (output of console commands in headless mode)
    if (!message.endsWith("\n"))
    {
        printf("%s\n", message.toStdString().c_str());
        if (logFileText)
        {
            (*logFileText) << message << "\n";
            /// \note If we want to guarantee that each message gets to the log even in the presence of a crash, we must flush()
            /// after each write. Tested that on Windows 7, if you kill the process using Ctrl-C on command line, or from
            /// task manager, the log will not contain all the text, so this is required for correctness.
            /// But this flush() after each message also causes a *serious* performance drawback.
            /// One way to try avoiding this issue is to move to using C API for file writing, and at atexit() and other crash
            /// handlers, close the file handle gracefully.
            logFileText->flush();
        }
    }
    else
    {
        printf("%s", message.toStdString().c_str());
        if (logFileText)
        {
            (*logFileText) << message;
            logFileText->flush(); // See comment about flush() above.
        }
    }
}

void ConsoleAPI::ListCommands()
{
    Print("Available console commands:");
    for(CommandMap::iterator iter = commands.begin(); iter != commands.end(); ++iter)
        Print(iter->first + " - " + iter->second->Description());
}

void ConsoleAPI::ClearLog()
{
    if (consoleWidget)
        consoleWidget->ClearLog();
#ifdef _WINDOWS
    system("cls");
#else
    system("clear");
#endif
}

void ConsoleAPI::SetLogLevel(const QString &level)
{
    if (level.compare("error", Qt::CaseInsensitive) == 0)
        SetEnabledLogChannels(LogLevelErrorsOnly);
    else if (level.compare("warning", Qt::CaseInsensitive) == 0)
        SetEnabledLogChannels(LogLevelErrorWarning);
    else if (level.compare("info", Qt::CaseInsensitive) == 0)
        SetEnabledLogChannels(LogLevelErrorWarnInfo);
    else if (level.compare("debug", Qt::CaseInsensitive) == 0)
        SetEnabledLogChannels(LogLevelErrorWarnInfoDebug);
    else
        LogError("Unknown parameter \"" + level + "\" specified to ConsoleAPI::SetLogLevel!");
}

void ConsoleAPI::SetLogFile(const QString &wildCardFilename)
{
    QString filename = Application::ParseWildCardFilename(wildCardFilename);

    // An empty log file closes the log output writing.
    if (filename.isEmpty())
    {
        SAFE_DELETE(logFileText);
        SAFE_DELETE(logFile);
        return;
    }
    logFile = new QFile(filename);
    bool isOpen = logFile->open(QIODevice::WriteOnly | QIODevice::Text);
    if (!isOpen)
    {
        LogError("Failed to open file \"" + filename + "\" for logging! (parsed from string \"" + wildCardFilename + "\")");
        SAFE_DELETE(logFile);
    }
    else
    {
        printf("Opened logging file \"%s\".\n", filename.toStdString().c_str());
        logFileText = new QTextStream(logFile);
    }
}

void ConsoleAPI::Update(f64 frametime)
{
    PROFILE(ConsoleAPI_Update);

    std::string input = shellInputThread->GetLine();
    if (input.length() > 0)
        ExecuteCommand(input.c_str());
}

void ConsoleAPI::ToggleConsole()
{
    if (consoleWidget)
        consoleWidget->ToggleConsole();
}

void ConsoleAPI::HandleKeyEvent(KeyEvent *e)
{
    const QKeySequence &toggleConsole = framework->Input()->KeyBinding("ToggleConsole", QKeySequence(Qt::Key_F1));
    if (e->sequence == toggleConsole)
        ToggleConsole();
}

void ConsoleAPI::LogInfo(const QString &message)
{
    ::LogInfo(message);
    Print(message);
}

void ConsoleAPI::LogWarning(const QString &message)
{
    ::LogWarning(message);
    Print("Warning: " + message);
}

void ConsoleAPI::LogError(const QString &message)
{
    ::LogError(message);
    Print("Error: " + message);
}

void ConsoleAPI::LogDebug(const QString &message)
{
#ifdef _DEBUG
    ::LogDebug(message);
    Print("Debug: " + message);
#endif
}

void ConsoleAPI::Log(u32 logChannel, const QString &message)
{
    if (!IsLogChannelEnabled(logChannel))
        return;

    Print(message);
}

void ConsoleAPI::SetEnabledLogChannels(u32 newChannels)
{
    enabledLogChannels = newChannels;
}

bool ConsoleAPI::IsLogChannelEnabled(u32 logChannel) const
{
    return (enabledLogChannels & logChannel) != 0;
}

u32 ConsoleAPI::EnabledLogChannels() const
{
    return enabledLogChannels;
}

<|endoftext|>


<commit_before>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

/** @file
    Random Number Generator implementation
*/
#include <iostream> // for istream, ostream

#include <nupic/utils/Log.hpp>
#include <nupic/utils/Random.hpp>

using namespace nupic;

bool Random::operator==(const Random &o) const {
  return seed_ == o.seed_ && \
	 steps_ == o.steps_ && \
	 gen == o.gen;
}

Random::Random(UInt64 seed) {
  if (seed == 0) {
    seed_ = gen(); //generate random value from HW RNG
  } else {
    seed_ = seed;
  }
  // if seed is zero at this point, there is a logic error.
  NTA_CHECK(seed_ != 0);
  gen.seed(seed_); //seed the generator
  steps_ = 0;
}

namespace nupic {
std::ostream &operator<<(std::ostream &outStream, const Random &r) {
  outStream << "random-v2" << " ";
  outStream << r.seed_ << " ";
  outStream << r.steps_ << " ";
  outStream << "endrandom-v2" << " ";
  return outStream;
}

std::istream &operator>>(std::istream &inStream, Random &r) {
  std::string version;

  inStream >> version;
  NTA_CHECK(version == "random-v2") << "Random() deserializer -- found unexpected version string '"
              << version << "'";
  inStream >> r.seed_;
  r.gen.seed(r.seed_); //reseed
  inStream >> r.steps_;
  r.gen.discard(r.steps_); //advance n steps
  //FIXME we could de/serialize directly RNG gen, it should be multi-platform according to standard,
  //but on OSX CI it wasn't (25/11/2018). So "hacking" the above instead.
  std::string endtag;
  inStream >> endtag;
  NTA_CHECK(endtag == "endrandom-v2") << "Random() deserializer -- found unexpected end tag '" << endtag  << "'";
  inStream.ignore(1);

  return inStream;
}

// helper function for seeding RNGs across the plugin barrier
// Unless there is a logic error, should not be called if
// the Random singleton has not been initialized.
UInt32 GetRandomSeed() {
  return nupic::Random().getUInt32();
}
} // namespace nupic
<commit_msg>Fix for Random default seed.<commit_after>/* ---------------------------------------------------------------------
 * Numenta Platform for Intelligent Computing (NuPIC)
 * Copyright (C) 2013, Numenta, Inc.  Unless you have an agreement
 * with Numenta, Inc., for a separate license for this software code, the
 * following terms and conditions apply:
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero Public License version 3 as
 * published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
 * See the GNU Affero Public License for more details.
 *
 * You should have received a copy of the GNU Affero Public License
 * along with this program.  If not, see http://www.gnu.org/licenses.
 *
 * http://numenta.org/licenses/
 * ---------------------------------------------------------------------
 */

/** @file
    Random Number Generator implementation
*/
#include <iostream> // for istream, ostream

#include <nupic/utils/Log.hpp>
#include <nupic/utils/Random.hpp>

using namespace nupic;

bool Random::operator==(const Random &o) const {
  return seed_ == o.seed_ && \
	 steps_ == o.steps_ && \
	 gen == o.gen;
}

std::mt19937 static_gen;

Random::Random(UInt64 seed) {
  if (seed == 0) {
    seed_ = static_gen(); //generate random value from HW RNG
  } else {
    seed_ = seed;
  }
  // if seed is zero at this point, there is a logic error.
  NTA_CHECK(seed_ != 0);
  gen.seed(seed_); //seed the generator
  steps_ = 0;
}

namespace nupic {
std::ostream &operator<<(std::ostream &outStream, const Random &r) {
  outStream << "random-v2" << " ";
  outStream << r.seed_ << " ";
  outStream << r.steps_ << " ";
  outStream << "endrandom-v2" << " ";
  return outStream;
}

std::istream &operator>>(std::istream &inStream, Random &r) {
  std::string version;

  inStream >> version;
  NTA_CHECK(version == "random-v2") << "Random() deserializer -- found unexpected version string '"
              << version << "'";
  inStream >> r.seed_;
  r.gen.seed(r.seed_); //reseed
  inStream >> r.steps_;
  r.gen.discard(r.steps_); //advance n steps
  //FIXME we could de/serialize directly RNG gen, it should be multi-platform according to standard,
  //but on OSX CI it wasn't (25/11/2018). So "hacking" the above instead.
  std::string endtag;
  inStream >> endtag;
  NTA_CHECK(endtag == "endrandom-v2") << "Random() deserializer -- found unexpected end tag '" << endtag  << "'";
  inStream.ignore(1);

  return inStream;
}

// helper function for seeding RNGs across the plugin barrier
// Unless there is a logic error, should not be called if
// the Random singleton has not been initialized.
UInt32 GetRandomSeed() {
  return nupic::Random().getUInt32();
}
} // namespace nupic
<|endoftext|>