<commit_before>/*
* (C) 2016 Daniel Neus
*     2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "tests.h"

#if defined(BOTAN_HAS_FILTERS)
  #include <botan/secqueue.h>
  #include <botan/pipe.h>
  #include <botan/filters.h>
  #include <botan/comp_filter.h>
  #include <botan/cipher_filter.h>
#endif

namespace Botan_Tests {

#if defined(BOTAN_HAS_FILTERS)

class Filter_Tests : public Test
   {
   public:
      std::vector<Test::Result> run() override
         {
         std::vector<Test::Result> results;

         results.push_back(test_secqueue());
         results.push_back(test_pipe_hash());
         results.push_back(test_pipe_mac());
         results.push_back(test_pipe_stream());
         results.push_back(test_pipe_cipher());
         results.push_back(test_pipe_compress());
         results.push_back(test_pipe_codec());
         results.push_back(test_fork());

#if defined(BOTAN_TARGET_OS_HAS_THREADS) && 0
         // Threaded_Fork is broken
         results.push_back(test_threaded_fork());
#endif

         return results;
         }

   private:
      Test::Result test_secqueue()
         {
         Test::Result result("SecureQueue");

         try
            {
            Botan::SecureQueue queue_a;
            std::vector<uint8_t> test_data = {0x24, 0xB2, 0xBF, 0xC2, 0xE6, 0xD4, 0x7E, 0x04, 0x67, 0xB3};
            queue_a.write(test_data.data(), test_data.size());

            result.test_eq("size of SecureQueue is correct", queue_a.size(), test_data.size());
            result.test_eq("0 bytes read so far from SecureQueue", queue_a.get_bytes_read(), 0);

            uint8_t b;
            size_t bytes_read = queue_a.read_byte(b);
            result.test_eq("1 byte read", bytes_read, 1);

            Botan::secure_vector<uint8_t> produced(b);
            Botan::secure_vector<uint8_t> expected(test_data.at(0));
            result.test_eq("byte read is correct", produced, expected);

            result.test_eq("1 bytes read so far from SecureQueue", queue_a.get_bytes_read(), 1);

            Botan::SecureQueue queue_b;
            queue_a = queue_b;
            result.test_eq("bytes_read is set correctly", queue_a.get_bytes_read(), 0);
            }
         catch (std::exception& e)
            {
            result.test_failure("SecureQueue", e.what());
            }

         return result;
         }

      Test::Result test_pipe_mac()
         {
         Test::Result result("Pipe");
         const Botan::SymmetricKey key("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         Botan::Pipe pipe(new Botan::MAC_Filter("HMAC(SHA-256)", key, 12),
                          new Botan::Base64_Encoder);

         pipe.process_msg("Hi");
         pipe.process_msg("Bye");
         pipe.process_msg("Hi");

         result.test_eq("MAC 1", pipe.read_all_as_string(0), "e7NoVbtudgU0QiCZ");
         result.test_eq("MAC 2", pipe.read_all_as_string(1), "LhPnfEG+0rk+Ej6y");
         result.test_eq("MAC 3", pipe.read_all_as_string(2), "e7NoVbtudgU0QiCZ");

         return result;
         }

      Test::Result test_pipe_hash()
         {
         Test::Result result("Pipe");
         Botan::Pipe pipe(new Botan::Hash_Filter("SHA-224"));
         pipe.pop();
         pipe.append(new Botan::Hash_Filter("SHA-256"));

         result.test_eq("Message count", pipe.message_count(), 0);

         pipe.start_msg();
         uint8_t inb = 0x41;
         pipe.write(&inb, 1);
         pipe.write(std::vector<uint8_t>(6, 0x41));
         pipe.write(inb);
         pipe.end_msg();

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Message size", pipe.remaining(), 32);

         std::vector<uint8_t> out(32), last16(16);

         result.test_eq("Bytes read", pipe.get_bytes_read(0), 0);
         result.test_eq("Expected read count", pipe.read(&out[0], 5), 5);
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 5);
         result.test_eq("Peek read", pipe.peek(last16.data(), 18, 11), 16);
         result.test_eq("Expected read count", pipe.read(&out[5], 17), 17);
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 22);
         result.test_eq("Remaining", pipe.remaining(), 10);
         result.test_eq("Remaining", pipe.remaining(), 10);
         result.test_eq("Expected read count", pipe.read(&out[22], 12), 10);
         result.test_eq("Expected read count", pipe.read(&out[0], 1), 0); // no more output
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 32);

         result.test_eq("Expected output", out, "C34AB6ABB7B2BB595BC25C3B388C872FD1D575819A8F55CC689510285E212385");
         result.test_eq("Expected last16", last16, "D1D575819A8F55CC689510285E212385");

         pipe.reset();

#if defined(BOTAN_HAS_CRC32)
         pipe.prepend(new Botan::Hash_Filter("CRC32"));
         pipe.append(new Botan::Hash_Filter("CRC32"));
         pipe.process_msg(std::vector<byte>(1024, 0));
         result.test_eq("Expected CRC32d", pipe.read_all(1), "99841F60");
#endif

         return result;
         }

      Test::Result test_pipe_cipher()
         {
         Test::Result result("Pipe");

         Botan::Cipher_Mode_Filter* cipher =
            new Botan::Cipher_Mode_Filter(Botan::get_cipher_mode("AES-128/CBC/PKCS7", Botan::ENCRYPTION));

          // takes ownership of cipher
         Botan::Pipe pipe(cipher);

         cipher->set_key(Botan::SymmetricKey("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
         cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));

         pipe.process_msg("Don't use plain CBC mode");

         auto ciphertext = pipe.read_all();

         result.test_eq("Ciphertext", ciphertext, "9BDD7300E0CB61CA71FFF957A71605DB6836159C36781246A1ADF50982757F4B");

         Botan::Cipher_Mode_Filter* dec_cipher =
            new Botan::Cipher_Mode_Filter(Botan::get_cipher_mode("AES-128/CBC/PKCS7", Botan::DECRYPTION));
         pipe.append(dec_cipher);
         dec_cipher->set_key(Botan::SymmetricKey("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
         dec_cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB"));
         cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB"));

         const std::vector<byte> zeros_in(1024);
         Botan::DataSource_Memory src(zeros_in);
         pipe.start_msg();
         pipe.write(src);
         pipe.end_msg();

         Botan::secure_vector<byte> zeros_out = pipe.read_all(1);

         result.test_eq("Cipher roundtrip", zeros_in, zeros_out);
         return result;
         }

      Test::Result test_pipe_compress()
         {
         Test::Result result("Pipe");

#if defined(BOTAN_HAS_ZLIB)
         Botan::Pipe pipe(new Botan::Compression_Filter("zlib", 9));

         const std::string input_str = "Hello there HELLO there I said is this thing on?";

         pipe.start_msg();
         pipe.write(input_str);
         pipe.end_msg();

         auto compr = pipe.read_all(0);
         // Can't do equality check on compression because output may differ
         result.test_lt("Compressed is shorter", compr.size(), input_str.size());

         pipe.append(new Botan::Decompression_Filter("zlib"));
         pipe.pop(); // remove compressor

         pipe.process_msg(compr);

         std::string decomp = pipe.read_all_as_string(1);
         result.test_eq("Decompressed ok", decomp, input_str);
#endif

         return result;
         }

      Test::Result test_pipe_codec()
         {
         Test::Result result("Pipe");

         Botan::Pipe pipe(new Botan::Base64_Encoder);

         result.test_eq("Message count", pipe.message_count(), 0);

         pipe.process_msg("ABCDX");

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Message size", pipe.remaining(), 8);

         std::string output = pipe.read_all_as_string(0);
         result.test_eq("Message size", pipe.remaining(0), 0);
         result.test_eq("Output round tripped", output, "QUJDRFg=");

         pipe.append(new Botan::Base64_Decoder);
         pipe.process_msg("FOOBAZ");

         result.test_eq("base64 roundtrip", pipe.read_all_as_string(1), "FOOBAZ");

         pipe.pop();
         pipe.pop();

         // Pipe is empty of filters, should still pass through
         pipe.process_msg("surprise plaintext");

         pipe.set_default_msg(2);
         result.test_eq("Message 2", pipe.read_all_as_string(), "surprise plaintext");

         pipe.append(new Botan::Hex_Decoder);

         pipe.process_msg("F331F00D");
         Botan::secure_vector<uint8_t> bin = pipe.read_all(3);
         result.test_eq("hex decoded", bin, "F331F00D");

         pipe.append(new Botan::Hex_Encoder);
         pipe.process_msg("F331F00D");
         result.test_eq("hex roundtrip", pipe.read_all_as_string(4), "F331F00D");

         return result;
         }

      Test::Result test_pipe_stream()
         {
         Test::Result result("Pipe");

         Botan::Keyed_Filter* aes = nullptr;
         const Botan::SymmetricKey key("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         const Botan::InitializationVector iv("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         Botan::Pipe pipe(aes = new Botan::StreamCipher_Filter("CTR-BE(AES-128)", key));

         aes->set_iv(iv);

         pipe.process_msg("ABCDEF");

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Ciphertext", pipe.read_all(), "FDFD6238F7C6");
         return result;
         }

      Test::Result test_fork()
         {
         Test::Result result("Fork");

         Botan::Pipe pipe(new Botan::Fork(new Botan::Hash_Filter("SHA-256"),
                                          new Botan::Hash_Filter("SHA-512-256")));

         result.test_eq("Message count", pipe.message_count(), 0);
         pipe.process_msg("OMG");
         result.test_eq("Message count", pipe.message_count(), 2);

         // Test reading out of order
         result.test_eq("Hash 2", pipe.read_all(1), "610480FFA82F24F6926544B976FE387878E3D973C03DFD591C2E9896EFB903E0");
         result.test_eq("Hash 1", pipe.read_all(0), "C00862D1C6C1CF7C1B49388306E7B3C1BB79D8D6EC978B41035B556DBB3797DF");

         return result;

         }

#if defined(BOTAN_TARGET_OS_HAS_THREADS)
      Test::Result test_threaded_fork()
         {
         Test::Result result("Threaded_Fork");

         Botan::Pipe pipe(new Botan::Threaded_Fork(new Botan::Hex_Encoder,
                                                   new Botan::Base64_Encoder));

         result.test_eq("Message count", pipe.message_count(), 0);
         pipe.process_msg("woo");
         result.test_eq("Message count", pipe.message_count(), 2);

         // Test reading out of order
         result.test_eq("Hash 2", pipe.read_all_as_string(1), "d29v");
         result.test_eq("Hash 1", pipe.read_all_as_string(0), "776F6F");

         return result;
         }
#endif

   };

BOTAN_REGISTER_TEST("filter", Filter_Tests);

#endif

}
<commit_msg>Add an additional test for Threaded_Fork<commit_after>/*
* (C) 2016 Daniel Neus
*     2016 Jack Lloyd
*
* Botan is released under the Simplified BSD License (see license.txt)
*/

#include "tests.h"

#if defined(BOTAN_HAS_FILTERS)
  #include <botan/secqueue.h>
  #include <botan/pipe.h>
  #include <botan/filters.h>
  #include <botan/comp_filter.h>
  #include <botan/cipher_filter.h>
#endif

namespace Botan_Tests {

#if defined(BOTAN_HAS_FILTERS)

class Filter_Tests : public Test
   {
   public:
      std::vector<Test::Result> run() override
         {
         std::vector<Test::Result> results;

         results.push_back(test_secqueue());
         results.push_back(test_pipe_hash());
         results.push_back(test_pipe_mac());
         results.push_back(test_pipe_stream());
         results.push_back(test_pipe_cipher());
         results.push_back(test_pipe_compress());
         results.push_back(test_pipe_codec());
         results.push_back(test_fork());

#if defined(BOTAN_TARGET_OS_HAS_THREADS) && 0
         // Threaded_Fork is broken
         results.push_back(test_threaded_fork());
#endif

         return results;
         }

   private:
      Test::Result test_secqueue()
         {
         Test::Result result("SecureQueue");

         try
            {
            Botan::SecureQueue queue_a;
            std::vector<uint8_t> test_data = {0x24, 0xB2, 0xBF, 0xC2, 0xE6, 0xD4, 0x7E, 0x04, 0x67, 0xB3};
            queue_a.write(test_data.data(), test_data.size());

            result.test_eq("size of SecureQueue is correct", queue_a.size(), test_data.size());
            result.test_eq("0 bytes read so far from SecureQueue", queue_a.get_bytes_read(), 0);

            uint8_t b;
            size_t bytes_read = queue_a.read_byte(b);
            result.test_eq("1 byte read", bytes_read, 1);

            Botan::secure_vector<uint8_t> produced(b);
            Botan::secure_vector<uint8_t> expected(test_data.at(0));
            result.test_eq("byte read is correct", produced, expected);

            result.test_eq("1 bytes read so far from SecureQueue", queue_a.get_bytes_read(), 1);

            Botan::SecureQueue queue_b;
            queue_a = queue_b;
            result.test_eq("bytes_read is set correctly", queue_a.get_bytes_read(), 0);
            }
         catch (std::exception& e)
            {
            result.test_failure("SecureQueue", e.what());
            }

         return result;
         }

      Test::Result test_pipe_mac()
         {
         Test::Result result("Pipe");
         const Botan::SymmetricKey key("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         Botan::Pipe pipe(new Botan::MAC_Filter("HMAC(SHA-256)", key, 12),
                          new Botan::Base64_Encoder);

         pipe.process_msg("Hi");
         pipe.process_msg("Bye");
         pipe.process_msg("Hi");

         result.test_eq("MAC 1", pipe.read_all_as_string(0), "e7NoVbtudgU0QiCZ");
         result.test_eq("MAC 2", pipe.read_all_as_string(1), "LhPnfEG+0rk+Ej6y");
         result.test_eq("MAC 3", pipe.read_all_as_string(2), "e7NoVbtudgU0QiCZ");

         return result;
         }

      Test::Result test_pipe_hash()
         {
         Test::Result result("Pipe");
         Botan::Pipe pipe(new Botan::Hash_Filter("SHA-224"));
         pipe.pop();
         pipe.append(new Botan::Hash_Filter("SHA-256"));

         result.test_eq("Message count", pipe.message_count(), 0);

         pipe.start_msg();
         uint8_t inb = 0x41;
         pipe.write(&inb, 1);
         pipe.write(std::vector<uint8_t>(6, 0x41));
         pipe.write(inb);
         pipe.end_msg();

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Message size", pipe.remaining(), 32);

         std::vector<uint8_t> out(32), last16(16);

         result.test_eq("Bytes read", pipe.get_bytes_read(0), 0);
         result.test_eq("Expected read count", pipe.read(&out[0], 5), 5);
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 5);
         result.test_eq("Peek read", pipe.peek(last16.data(), 18, 11), 16);
         result.test_eq("Expected read count", pipe.read(&out[5], 17), 17);
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 22);
         result.test_eq("Remaining", pipe.remaining(), 10);
         result.test_eq("Remaining", pipe.remaining(), 10);
         result.test_eq("Expected read count", pipe.read(&out[22], 12), 10);
         result.test_eq("Expected read count", pipe.read(&out[0], 1), 0); // no more output
         result.test_eq("Bytes read", pipe.get_bytes_read(0), 32);

         result.test_eq("Expected output", out, "C34AB6ABB7B2BB595BC25C3B388C872FD1D575819A8F55CC689510285E212385");
         result.test_eq("Expected last16", last16, "D1D575819A8F55CC689510285E212385");

         pipe.reset();

#if defined(BOTAN_HAS_CRC32)
         pipe.prepend(new Botan::Hash_Filter("CRC32"));
         pipe.append(new Botan::Hash_Filter("CRC32"));
         pipe.process_msg(std::vector<byte>(1024, 0));
         result.test_eq("Expected CRC32d", pipe.read_all(1), "99841F60");
#endif

         return result;
         }

      Test::Result test_pipe_cipher()
         {
         Test::Result result("Pipe");

         Botan::Cipher_Mode_Filter* cipher =
            new Botan::Cipher_Mode_Filter(Botan::get_cipher_mode("AES-128/CBC/PKCS7", Botan::ENCRYPTION));

          // takes ownership of cipher
         Botan::Pipe pipe(cipher);

         cipher->set_key(Botan::SymmetricKey("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
         cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));

         pipe.process_msg("Don't use plain CBC mode");

         auto ciphertext = pipe.read_all();

         result.test_eq("Ciphertext", ciphertext, "9BDD7300E0CB61CA71FFF957A71605DB6836159C36781246A1ADF50982757F4B");

         Botan::Cipher_Mode_Filter* dec_cipher =
            new Botan::Cipher_Mode_Filter(Botan::get_cipher_mode("AES-128/CBC/PKCS7", Botan::DECRYPTION));
         pipe.append(dec_cipher);
         dec_cipher->set_key(Botan::SymmetricKey("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"));
         dec_cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB"));
         cipher->set_iv(Botan::InitializationVector("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB"));

         const std::vector<byte> zeros_in(1024);
         Botan::DataSource_Memory src(zeros_in);
         pipe.start_msg();
         pipe.write(src);
         pipe.end_msg();

         Botan::secure_vector<byte> zeros_out = pipe.read_all(1);

         result.test_eq("Cipher roundtrip", zeros_in, zeros_out);
         return result;
         }

      Test::Result test_pipe_compress()
         {
         Test::Result result("Pipe");

#if defined(BOTAN_HAS_ZLIB)
         Botan::Pipe pipe(new Botan::Compression_Filter("zlib", 9));

         const std::string input_str = "Hello there HELLO there I said is this thing on?";

         pipe.start_msg();
         pipe.write(input_str);
         pipe.end_msg();

         auto compr = pipe.read_all(0);
         // Can't do equality check on compression because output may differ
         result.test_lt("Compressed is shorter", compr.size(), input_str.size());

         pipe.append(new Botan::Decompression_Filter("zlib"));
         pipe.pop(); // remove compressor

         pipe.process_msg(compr);

         std::string decomp = pipe.read_all_as_string(1);
         result.test_eq("Decompressed ok", decomp, input_str);
#endif

         return result;
         }

      Test::Result test_pipe_codec()
         {
         Test::Result result("Pipe");

         Botan::Pipe pipe(new Botan::Base64_Encoder);

         result.test_eq("Message count", pipe.message_count(), 0);

         pipe.process_msg("ABCDX");

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Message size", pipe.remaining(), 8);

         std::string output = pipe.read_all_as_string(0);
         result.test_eq("Message size", pipe.remaining(0), 0);
         result.test_eq("Output round tripped", output, "QUJDRFg=");

         pipe.append(new Botan::Base64_Decoder);
         pipe.process_msg("FOOBAZ");

         result.test_eq("base64 roundtrip", pipe.read_all_as_string(1), "FOOBAZ");

         pipe.pop();
         pipe.pop();

         // Pipe is empty of filters, should still pass through
         pipe.process_msg("surprise plaintext");

         pipe.set_default_msg(2);
         result.test_eq("Message 2", pipe.read_all_as_string(), "surprise plaintext");

         pipe.append(new Botan::Hex_Decoder);

         pipe.process_msg("F331F00D");
         Botan::secure_vector<uint8_t> bin = pipe.read_all(3);
         result.test_eq("hex decoded", bin, "F331F00D");

         pipe.append(new Botan::Hex_Encoder);
         pipe.process_msg("F331F00D");
         result.test_eq("hex roundtrip", pipe.read_all_as_string(4), "F331F00D");

         return result;
         }

      Test::Result test_pipe_stream()
         {
         Test::Result result("Pipe");

         Botan::Keyed_Filter* aes = nullptr;
         const Botan::SymmetricKey key("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         const Botan::InitializationVector iv("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF");
         Botan::Pipe pipe(aes = new Botan::StreamCipher_Filter("CTR-BE(AES-128)", key));

         aes->set_iv(iv);

         pipe.process_msg("ABCDEF");

         result.test_eq("Message count", pipe.message_count(), 1);
         result.test_eq("Ciphertext", pipe.read_all(), "FDFD6238F7C6");
         return result;
         }

      Test::Result test_fork()
         {
         Test::Result result("Fork");

         Botan::Pipe pipe(new Botan::Fork(new Botan::Hash_Filter("SHA-256"),
                                          new Botan::Hash_Filter("SHA-512-256")));

         result.test_eq("Message count", pipe.message_count(), 0);
         pipe.process_msg("OMG");
         result.test_eq("Message count", pipe.message_count(), 2);

         // Test reading out of order
         result.test_eq("Hash 2", pipe.read_all(1), "610480FFA82F24F6926544B976FE387878E3D973C03DFD591C2E9896EFB903E0");
         result.test_eq("Hash 1", pipe.read_all(0), "C00862D1C6C1CF7C1B49388306E7B3C1BB79D8D6EC978B41035B556DBB3797DF");

         return result;

         }

#if defined(BOTAN_TARGET_OS_HAS_THREADS)
      Test::Result test_threaded_fork()
         {
         Test::Result result("Threaded_Fork");

         Botan::Pipe pipe(new Botan::Threaded_Fork(new Botan::Hex_Encoder,
                                                   new Botan::Base64_Encoder));

         result.test_eq("Message count", pipe.message_count(), 0);
         pipe.process_msg("woo");
         result.test_eq("Message count", pipe.message_count(), 2);

         // Test reading out of order
         result.test_eq("Hash 2", pipe.read_all_as_string(1), "d29v");
         result.test_eq("Hash 1", pipe.read_all_as_string(0), "776F6F");

         pipe.reset();

         const size_t filter_count = 5;
         Botan::Filter* filters[filter_count];
         for(size_t i = 0; i != filter_count; ++i)
            filters[i] = new Botan::Hash_Filter("SHA-256");

         pipe.append(new Botan::Threaded_Fork(filters, filter_count));

         result.test_eq("Message count before start_msg", pipe.message_count(), 2);

         pipe.start_msg();
         for(size_t i = 0; i != 919; ++i)
            {
            std::vector<uint8_t> input(i + 5, static_cast<uint8_t>(i));
            pipe.write(input);
            }
         pipe.end_msg();

         result.test_eq("Message count after end_msg", pipe.message_count(), 2+filter_count);
         for(size_t i = 0; i != filter_count; ++i)
            result.test_eq("Output " + std::to_string(i),
                           pipe.read_all(2+i),
                           "327AD8055223F5926693D8BEA40F7B35BDEEB535647DFB93F464E40EA01939A9");

         return result;
         }
#endif

   };

BOTAN_REGISTER_TEST("filter", Filter_Tests);

#endif

}
<|endoftext|>


<commit_before>/**
 * @file posix/wait.cpp
 * @brief POSIX event/timeout handling
 *
 * (c) 2013-2014 by Mega Limited, Wellsford, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega.h"
#include "mega/thread/posixthread.h"

#ifdef USE_PTHREAD

namespace mega {

PosixThread::PosixThread()
{
    thread = new pthread_t();
}

void PosixThread::start(void *(*start_routine)(void*), void *parameter)
{
    pthread_create(thread, NULL, start_routine, parameter);
}

void PosixThread::join()
{
    pthread_join(*thread, NULL);
}

uint64_t PosixThread::currentThreadId()
{
    return (uint64_t) pthread_self();
}

PosixThread::~PosixThread()
{
    delete thread;
}

//PosixMutex
PosixMutex::PosixMutex()
{
    mutex = NULL;
    attr = NULL;
}

PosixMutex::PosixMutex(bool recursive)
{
    mutex = NULL;
    attr = NULL;

    init(recursive);
}

void PosixMutex::init(bool recursive)
{
    if (recursive)
    {
        mutex = new pthread_mutex_t();
        attr = new pthread_mutexattr_t();
        pthread_mutexattr_init(attr);
        pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
        pthread_mutex_init(mutex, attr);
    }
    else
    {
        mutex = new pthread_mutex_t();
        pthread_mutex_init(mutex, NULL);
    }
}

void PosixMutex::lock()
{
    pthread_mutex_lock(mutex);
}

void PosixMutex::unlock()
{
    pthread_mutex_unlock(mutex);
}

PosixMutex::~PosixMutex()
{
    if (mutex)
    {
        pthread_mutex_destroy(mutex);
        delete mutex;
    }

    if (attr)
    {
        pthread_mutexattr_destroy(attr);
        delete attr;
    }
}

//PosixSemaphore
PosixSemaphore::PosixSemaphore()
{
    count = 0;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutex_init(&mtx, &attr);
    pthread_mutexattr_destroy(&attr);
    pthread_cond_init(&cv, NULL);
}

void PosixSemaphore::wait()
{
    pthread_mutex_lock(&mtx);
    while (!count)
    {
        int ret = pthread_cond_wait(&cv,&mtx);
        if (ret)
        {
            pthread_mutex_unlock(&mtx);
            LOG_fatal << "Error in sem_wait: " << ret;
            return;
        }
    }
    count--;
    pthread_mutex_unlock(&mtx);
}

static inline
void timespec_add_msec(struct timespec *tv, int milliseconds)
{
    int seconds = milliseconds / 1000;
    int milliseconds_left = milliseconds % 1000;

    tv->tv_sec += seconds;
    tv->tv_nsec += milliseconds_left * 1000000;

    if (tv->tv_nsec >= 1000000000)
    {
        tv->tv_nsec -= 1000000000;
        tv->tv_sec++;
    }
}

int PosixSemaphore::timedwait(int milliseconds)
{
    struct timespec ts;
    struct timeval now;

    int ret = gettimeofday(&now, NULL); //not Y2K38 safe :-D
    if (ret)
    {
        LOG_err << "Error in gettimeofday: " << ret;
        return -2;
    }
    ts.tv_sec = now.tv_sec;
    ts.tv_nsec = now.tv_usec * 1000;
    timespec_add_msec (&ts, milliseconds);

    pthread_mutex_lock(&mtx);
    while (!count)
    {
        int ret = pthread_cond_timedwait(&cv, &mtx, &ts);
        if (ret == ETIMEDOUT)
        {
            pthread_mutex_unlock(&mtx);
            return -1;
        }

        if (ret)
        {
            pthread_mutex_unlock(&mtx);
            LOG_err << "Unexpected error in pthread_cond_timedwait: " << ret;
            return -2;
        }
    }

    count--;
    pthread_mutex_unlock(&mtx);
    return 0;
}

void PosixSemaphore::release()
{
    pthread_mutex_lock(&mtx);
    count++;
    int ret = pthread_cond_signal(&cv);
    if (ret)
    {
        LOG_fatal << "Unexpected error in pthread_cond_signal: " << ret;
    }
    pthread_mutex_unlock(&mtx);
}

PosixSemaphore::~PosixSemaphore()
{
    pthread_mutex_destroy(&mtx);
    pthread_cond_destroy(&cv);
}

}// namespace

#endif
<commit_msg>Fix for mingw<commit_after>/**
 * @file posix/wait.cpp
 * @brief POSIX event/timeout handling
 *
 * (c) 2013-2014 by Mega Limited, Wellsford, New Zealand
 *
 * This file is part of the MEGA SDK - Client Access Engine.
 *
 * Applications using the MEGA API must present a valid application key
 * and comply with the the rules set forth in the Terms of Service.
 *
 * The MEGA SDK 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.
 *
 * @copyright Simplified (2-clause) BSD License.
 *
 * You should have received a copy of the license along with this
 * program.
 */

#include "mega.h"
#include "mega/thread/posixthread.h"

#ifdef USE_PTHREAD

namespace mega {

PosixThread::PosixThread()
{
    thread = new pthread_t();
}

void PosixThread::start(void *(*start_routine)(void*), void *parameter)
{
    pthread_create(thread, NULL, start_routine, parameter);
}

void PosixThread::join()
{
    pthread_join(*thread, NULL);
}

uint64_t PosixThread::currentThreadId()
{
#ifndef __MINGW32__
    return (uint64_t) pthread_self();
#else
    return (uint64_t) pthread_self().x;
#endif
}

PosixThread::~PosixThread()
{
    delete thread;
}

//PosixMutex
PosixMutex::PosixMutex()
{
    mutex = NULL;
    attr = NULL;
}

PosixMutex::PosixMutex(bool recursive)
{
    mutex = NULL;
    attr = NULL;

    init(recursive);
}

void PosixMutex::init(bool recursive)
{
    if (recursive)
    {
        mutex = new pthread_mutex_t();
        attr = new pthread_mutexattr_t();
        pthread_mutexattr_init(attr);
        pthread_mutexattr_settype(attr, PTHREAD_MUTEX_RECURSIVE);
        pthread_mutex_init(mutex, attr);
    }
    else
    {
        mutex = new pthread_mutex_t();
        pthread_mutex_init(mutex, NULL);
    }
}

void PosixMutex::lock()
{
    pthread_mutex_lock(mutex);
}

void PosixMutex::unlock()
{
    pthread_mutex_unlock(mutex);
}

PosixMutex::~PosixMutex()
{
    if (mutex)
    {
        pthread_mutex_destroy(mutex);
        delete mutex;
    }

    if (attr)
    {
        pthread_mutexattr_destroy(attr);
        delete attr;
    }
}

//PosixSemaphore
PosixSemaphore::PosixSemaphore()
{
    count = 0;
    pthread_mutexattr_t attr;
    pthread_mutexattr_init(&attr);
    pthread_mutex_init(&mtx, &attr);
    pthread_mutexattr_destroy(&attr);
    pthread_cond_init(&cv, NULL);
}

void PosixSemaphore::wait()
{
    pthread_mutex_lock(&mtx);
    while (!count)
    {
        int ret = pthread_cond_wait(&cv,&mtx);
        if (ret)
        {
            pthread_mutex_unlock(&mtx);
            LOG_fatal << "Error in sem_wait: " << ret;
            return;
        }
    }
    count--;
    pthread_mutex_unlock(&mtx);
}

static inline
void timespec_add_msec(struct timespec *tv, int milliseconds)
{
    int seconds = milliseconds / 1000;
    int milliseconds_left = milliseconds % 1000;

    tv->tv_sec += seconds;
    tv->tv_nsec += milliseconds_left * 1000000;

    if (tv->tv_nsec >= 1000000000)
    {
        tv->tv_nsec -= 1000000000;
        tv->tv_sec++;
    }
}

int PosixSemaphore::timedwait(int milliseconds)
{
    struct timespec ts;
    struct timeval now;

    int ret = gettimeofday(&now, NULL); //not Y2K38 safe :-D
    if (ret)
    {
        LOG_err << "Error in gettimeofday: " << ret;
        return -2;
    }
    ts.tv_sec = now.tv_sec;
    ts.tv_nsec = now.tv_usec * 1000;
    timespec_add_msec (&ts, milliseconds);

    pthread_mutex_lock(&mtx);
    while (!count)
    {
        int ret = pthread_cond_timedwait(&cv, &mtx, &ts);
        if (ret == ETIMEDOUT)
        {
            pthread_mutex_unlock(&mtx);
            return -1;
        }

        if (ret)
        {
            pthread_mutex_unlock(&mtx);
            LOG_err << "Unexpected error in pthread_cond_timedwait: " << ret;
            return -2;
        }
    }

    count--;
    pthread_mutex_unlock(&mtx);
    return 0;
}

void PosixSemaphore::release()
{
    pthread_mutex_lock(&mtx);
    count++;
    int ret = pthread_cond_signal(&cv);
    if (ret)
    {
        LOG_fatal << "Unexpected error in pthread_cond_signal: " << ret;
    }
    pthread_mutex_unlock(&mtx);
}

PosixSemaphore::~PosixSemaphore()
{
    pthread_mutex_destroy(&mtx);
    pthread_cond_destroy(&cv);
}

}// namespace

#endif
<|endoftext|>


<commit_before> //DEFINITION OF A FEW CONSTANTS
//----------------------------------------------------

/* $Id$ */

AliAnalysisTaskDStarCorrelations *AddTaskDStarCorrelations(AliAnalysisTaskDStarCorrelations::CollSyst syst,
                                                                     Bool_t theMCon, Bool_t mixing, Bool_t UseReco = kTRUE, Bool_t fullmode = kFALSE ,Bool_t UseEffic = kFALSE, Bool_t UseDEffic = kFALSE ,
                                                                     Int_t trackselect =1, Int_t usedispl =0, Int_t nbins, Float_t DStarSigma, Float_t D0Sigma, Float_t D0SBSigmaLow, Float_t D0SBSigmaHigh,
                                                                     TString DStarCutsFile, TString TrackCutsFile,
                                                                     Int_t tasknumber = 0)
{

    //Float_t sigmasval[]={DStarSigma,D0Sigma,D0SBSigmaLow,D0SBSigmaHigh};
    //Float_t * sigmas = sigmasval;//new Float_t[4];
    //sigma[0] = DStarSigma;
    //sigma[1] = D0Sigma;
    //sigma[2] = D0SBSigmaLow;
    //sigma[3] = D0SBSigmaHigh;

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error(" AliAnalysisTaskDStarCorrelations", "No analysis manager to connect to.");
    return NULL;
  }

	cout << "==========================================================" << endl;
    cout << "Set Inputs : " << endl;
    cout << " " << endl;
    if(syst == AliAnalysisTaskDStarCorrelations::pp) cout << "Running on pp @ 7 TeV" << endl;
    if(syst == AliAnalysisTaskDStarCorrelations::pA) cout << "Running on pA @ 5.02 TeV" << endl;
    if(syst == AliAnalysisTaskDStarCorrelations::AA) cout << "Running on AA @ 2.76 TeV" << endl;

    if(theMCon) cout << "Analysis on MonteCarlo" << endl;
    else cout << "Analysis on Data" << endl;

    if(mixing) cout << "Analysis on Mixed Events" << endl;
    else cout << "Analysis on Single Events" << endl;

    if(UseReco) cout << "Using Reconstructed objects" << endl;
    else cout << "Using Pure MC information " << endl;

    if(fullmode) cout << "Running in full mode" << endl;
    else cout << "Running in fast mode " << endl;

    if(UseEffic) cout << "Using single track efficiency map" << endl;
    else cout << "Not Using single track efficiency map " << endl;

    if(UseDEffic) cout << "Using Dmeson efficiency map" << endl;
    else cout << "Not Using Dmeson efficiency map " << endl;

    if(trackselect == 1) cout << "Correlating with hadrons" << endl;
    if(trackselect == 2) cout << "Correlating with kaons" << endl;
    if(trackselect == 3) cout << "Correlating with kzeros" << endl;

    if(usedispl == 0) cout << "Not using displacement cut" << endl;
    if(usedispl == 1) cout << "Using absolute displacement cut" << endl;
    if(usedispl == 2) cout << "Using relative displacement cut" << endl;

    cout << "Number of bins in deltaphi = " << nbins << endl;

    cout << "N of Sigmas in D* selection =" << DStarSigma << endl;
    cout << "N of Sigmas in D0 selection = " << D0Sigma << endl;
    cout << "D0 Sidebands taken from  = " << D0SBSigmaLow << " - " << D0SBSigmaHigh << " sigmas " << endl; endl;

    cout << "DStar cut object:     " << DStarCutsFile << endl;
    cout << "Tracks cut object:    " << TrackCutsFile << endl;

    cout << "==========================================================" << endl;
    //gSystem->Sleep(2000);

//	TString DCutObjPath = "CutObjects/DStar/";

// ******************************** OPENING THE D* CUTS ************************************
    cout << "Getting D meson cut object from file \n" << DStarCutsFile.Data() << "\n " << endl;
    TFile* filecuts=new TFile(DStarCutsFile.Data());
    if(!filecuts->IsOpen()){
    cout<<"DStar cut object file not found: exit"<<endl;
    return;
    }

    AliRDHFCutsDStartoKpipi* RDHFDStartoKpipi=new AliRDHFCutsDStartoKpipi();
    RDHFDStartoKpipi = (AliRDHFCutsDStartoKpipi*)filecuts->Get("DStartoKpipiCuts");
    RDHFDStartoKpipi->SetName("DStartoKpipiCuts");

    // mm let's see if everything is ok
	if(!RDHFDStartoKpipi){
		cout<<"Specific AliRDHFCuts not found"<<endl;
		return;
	}

       // RDHFDStartoKpipi->SetTriggerClass("");
       // RDHFDStartoKpipi->SetTriggerMask(AliVEvent::kCentral);

// ******************************** OPENING THE ASSOCIATED TRACK CUTS ************************************
	cout << "Getting associated track cut object from file \n" << TrackCutsFile.Data() << "\n " << endl;
    TFile* filecuts2=new TFile(TrackCutsFile.Data());
	  if(!filecuts2->IsOpen()){
		  cout<<"Track cut object file not found: exit"<<endl;
		  return;
    }
 	AliHFAssociatedTrackCuts* corrCuts=new AliHFAssociatedTrackCuts();
	corrCuts = (AliHFAssociatedTrackCuts*)filecuts2->Get("AssociatedCuts");
	corrCuts->SetName("AssociatedCuts");
	corrCuts->PrintAll();
	if(!corrCuts){
		cout<<"Specific associated track cuts not found"<<endl;
		return;
	}

// ******************************** SELECTING THE MC PROCESS  ************************************

	TString selectMCproc = "";

	Int_t NMCevents = corrCuts->GetNofMCEventType();
	for(Int_t k=0; k<NMCevents; k++){
		Int_t * MCEventType = corrCuts->GetMCEventType();
		selectMCproc += Form("%d",MCEventType[k]);
	}

	 cout << "Select process string = " << selectMCproc << endl;

// ******************************** CREATING THE TASK ************************************

    printf("CREATE TASK \n");
  // create the task
  AliAnalysisTaskDStarCorrelations *task = new AliAnalysisTaskDStarCorrelations("AliAnalysisTaskDStarCorrelations",RDHFDStartoKpipi,corrCuts,syst,fullmode);

	// Setters

	if(!theMCon) {
		printf("Analysis on Data - reconstruction only!");
		UseReco = kTRUE;
	}

   // cout << "Adding efficiency map to Assoc track cut object \n" << endl;
  //  if(effMap) task->SetDeffMapvsPt(effMap);
  //  if(effMap2d) task->SetDeffMapvsPtvsMult(effMap2d);

    task->SetNofPhiBins(nbins);
	task->SetMonteCarlo(theMCon);
	task->SetUseMixing(mixing);
	task->SetCorrelator(trackselect) ;
	task->SetUseDisplacement(usedispl);
	//task->SetCollSys(syst);
	task->SetLevelOfDebug(2);
	task->SetUseReconstruction(UseReco); // set kTRUE for Using Reconstruction, kFALSe for MC Truth
    task->SetDMesonSigmas(DStarSigma,D0Sigma,D0SBSigmaLow,D0SBSigmaHigh);
	//task->SetDMesonSigmas(sigmas);
    //task->SetDMesonSigmas(sigmas);
    task->SetUseEfficiencyCorrection(UseEffic);
    task->SetUseDmesonEfficiencyCorrection(UseDEffic);

	if(trackselect == 1) Info(" AliAnalysisTaskDStarCorrelations","Correlating D* with charged hadrons \n");
	else if(trackselect == 2) Info(" AliAnalysisTaskDStarCorrelations","Correlating D* with charged kaons \n");
	else if(trackselect == 3) Info(" AliAnalysisTaskDStarCorrelations","Correlating D* with reconstructed K0s \n");
	else Fatal(" AliAnalysisTaskDStarCorrelations","Nothing to correlate with!");
	if(mixing) Info (" AliAnalysisTaskDStarCorrelations","Event Mixing Analysis\n");
	if(!mixing) Info (" AliAnalysisTaskDStarCorrelations","Single Event Analysis \n");

  // Create and connect containers for input/output
	//TString dcavalue = " ";
	if(!theMCon) TString contname = "Data";
	if(theMCon) TString contname = "MonteCarlo";
	TString contname2 = "MC";
	if(trackselect ==1) TString particle = "Hadron";
	if(trackselect ==2) TString particle = "Kaon";
	if(trackselect ==3) TString particle = "KZero";

	TString cutname = "cuts" ;
	TString cutname2 = "hadroncuts" ;
	TString outputfile = AliAnalysisManager::GetCommonFileName();
	TString outputfileMC = AliAnalysisManager::GetCommonFileName();
	TString counter = "NormCounter";
	outputfile += ":PWGHF_HFCJ_";
	outputfileMC += ":PWGHF_HFCJ_";

	if(!mixing) {
		outputfile += "SE";
		outputfileMC += "SE";
		contname += "SE";
		contname2 += "SE";
		cutname += "SE";
		cutname2 += "SE";
		counter+= "SE";
	}
	if(mixing){
		outputfile += "ME";
		outputfileMC += "ME";
		contname += "ME";
		contname2 += "ME";
		cutname += "ME";
		cutname2 += "ME";
		counter+= "ME";
	}

	outputfile += "Dphi_DStar";
	outputfileMC += "Dphi_DStar";
	outputfile += particle;
	outputfileMC += particle;
	cutname += particle;
	cutname2 += particle;
	contname += particle;
	contname2 += particle;
	counter+= particle;

    if(UseEffic){
        outputfile += "_EffY_";
		outputfileMC += "_EffY_";
		contname += "_EffY_";
		contname2 += "_EffY_";
		cutname += "_EffY_";
		cutname2 += "_EffY_";
		counter+= "_EffY_";
    }

    if(!UseEffic){
        outputfile += "_EffN_";
		outputfileMC += "_EffN_";
		contname += "_EffN_";
		contname2 += "_EffN_";
		cutname += "_EffN_";
		cutname2 += "_EffN_";
		counter+= "_EffN_";
    }

    if(UseDEffic){
        outputfile += "DEffY_";
		outputfileMC += "DEffY_";
		contname += "DEffY_";
		contname2 += "DEffY_";
		cutname += "DEffY_";
		cutname2 += "DEffY_";
		counter+= "DEffY_";
    }

    if(!UseDEffic){
        outputfile += "DEffN_";
		outputfileMC += "DEffN_";
		contname += "DEffN_";
		contname2 += "DEffN_";
		cutname += "DEffN_";
		cutname2 += "DEffN_";
		counter+= "DEffN_";
    }

    outputfile += Form("%d_bins_",nbins);
	outputfileMC += Form("%d_bins_",nbins);
	cutname += Form("%d_bins_",nbins);
	cutname2 += Form("%d_bins_",nbins);
	contname += Form("%d_bins_",nbins);
	contname2 += Form("%d_bins_",nbins);
	counter+= Form("%d_bins_",nbins);

	outputfile += Form("task_%d",tasknumber);
	outputfileMC += Form("task_%d",tasknumber);
	cutname += Form("task_%d",tasknumber);
	cutname2 += Form("task_%d",tasknumber);
	contname += Form("task_%d",tasknumber);
	contname2 += Form("task_%d",tasknumber);
	counter+= Form("task_%d",tasknumber);

/*	outputfile += TrackCutObjNamePrefix;
	outputfileMC += TrackCutObjNamePrefix;
	cutname += TrackCutObjNamePrefix;
	cutname2 += TrackCutObjNamePrefix;
	contname += TrackCutObjNamePrefix;
	contname2 += TrackCutObjNamePrefix;
	counter+= TrackCutObjNamePrefix;
*/
	outputfile += selectMCproc;
	outputfileMC += selectMCproc;
	cutname += selectMCproc;
	cutname2 += selectMCproc;
	contname += selectMCproc;
	contname2 += selectMCproc;
	counter+= selectMCproc;

	TString reco = "";

	if(UseReco) reco = "_reco";
	if(!UseReco) reco = "_MCTruth";

	outputfile += reco;
	outputfileMC += reco;
	cutname += reco;
	cutname2 += reco;
	contname += reco;
	contname2 += reco;
	counter+= reco;

	TString nsigma = Form("_%.0f_%.0f%.0f%.0f_sigmas",DStarSigma,D0Sigma,D0SBSigmaLow,D0SBSigmaHigh);

	//cout << "nsigma string = "<< nsigma << endl;

	outputfile += nsigma;
	outputfileMC += nsigma;
	cutname += nsigma;
	cutname2 += nsigma;
	contname += nsigma;
	contname2 += nsigma;
	counter+= nsigma;

	cout << contname << endl;
	cout << contname2 << endl;
	cout << cutname << endl;
	cout << cutname2 << endl;
	cout << counter << endl;
	cout << outputfile << endl;
	//return;

  mgr->AddTask(task);
  // ------ input data ------
  AliAnalysisDataContainer *cinput0  = mgr->GetCommonInputContainer();

  // ----- output data -----

  // output TH1I for event counting

	//TLists
  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer(contname, TList::Class(),AliAnalysisManager::kOutputContainer,outputfile.Data());
  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer(contname2, TList::Class(),AliAnalysisManager::kOutputContainer,outputfileMC.Data());
   // Cut Objects
  AliAnalysisDataContainer *coutput3 = mgr->CreateContainer(cutname,AliRDHFCutsDStartoKpipi::Class(),AliAnalysisManager::kOutputContainer, outputfile.Data()); //cuts D
  AliAnalysisDataContainer *coutput4 = mgr->CreateContainer(cutname2,AliHFAssociatedTrackCuts::Class(),AliAnalysisManager::kOutputContainer, outputfile.Data()); //cuts tracks
   // Normalization Counter
  AliAnalysisDataContainer *coutput5 = mgr->CreateContainer(counter,AliNormalizationCounter::Class(),AliAnalysisManager::kOutputContainer, outputfile.Data());

  mgr->ConnectInput(task,0,mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task,1,coutput1);
  mgr->ConnectOutput(task,2,coutput2);
  mgr->ConnectOutput(task,3,coutput3);
  mgr->ConnectOutput(task,4,coutput4);
  mgr->ConnectOutput(task,5,coutput5);

  return task ;

}

<commit_msg>Proper way of opening files<commit_after> //DEFINITION OF A FEW CONSTANTS
//----------------------------------------------------

/* $Id$ */

AliAnalysisTaskDStarCorrelations *AddTaskDStarCorrelations(AliAnalysisTaskDStarCorrelations::CollSyst syst,
                                                                     Bool_t theMCon, Bool_t mixing, Bool_t UseReco = kTRUE, Bool_t fullmode = kFALSE ,Bool_t UseEffic = kFALSE, Bool_t UseDEffic = kFALSE ,
                                                                     Int_t trackselect =1, Int_t usedispl =0, Int_t nbins, Float_t DStarSigma, Float_t D0Sigma, Float_t D0SBSigmaLow, Float_t D0SBSigmaHigh,
                                                                     TString DStarCutsFile, TString TrackCutsFile,
                                                                     Int_t tasknumber = 0)
{

    //Float_t sigmasval[]={DStarSigma,D0Sigma,D0SBSigmaLow,D0SBSigmaHigh};
    //Float_t * sigmas = sigmasval;//new Float_t[4];
    //sigma[0] = DStarSigma;
    //sigma[1] = D0Sigma;
    //sigma[2] = D0SBSigmaLow;
    //sigma[3] = D0SBSigmaHigh;

  AliAnalysisManager *mgr = AliAnalysisManager::GetAnalysisManager();
  if (!mgr) {
    ::Error(" AliAnalysisTaskDStarCorrelations", "No analysis manager to connect to.");
    return NULL;
  }

	cout << "==========================================================" << endl;
    cout << "Set Inputs : " << endl;
    cout << " " << endl;
    if(syst == AliAnalysisTaskDStarCorrelations::pp) cout << "Running on pp @ 7 TeV" << endl;
    if(syst == AliAnalysisTaskDStarCorrelations::pA) cout << "Running on pA @ 5.02 TeV" << endl;
    if(syst == AliAnalysisTaskDStarCorrelations::AA) cout << "Running on AA @ 2.76 TeV" << endl;

    if(theMCon) cout << "Analysis on MonteCarlo" << endl;
    else cout << "Analysis on Data" << endl;

    if(mixing) cout << "Analysis on Mixed Events" << endl;
    else cout << "Analysis on Single Events" << endl;

    if(UseReco) cout << "Using Reconstructed objects" << endl;
    else cout << "Using Pure MC information " << endl;

    if(fullmode) cout << "Running in full mode" << endl;
    else cout << "Running in fast mode " << endl;

    if(UseEffic) cout << "Using single track efficiency map" << endl;
    else cout << "Not Using single track efficiency map " << endl;

    if(UseDEffic) cout << "Using Dmeson efficiency map" << endl;
    else cout << "Not Using Dmeson efficiency map " << endl;

    if(trackselect == 1) cout << "Correlating with hadrons" << endl;
    if(trackselect == 2) cout << "Correlating with kaons" << endl;
    if(trackselect == 3) cout << "Correlating with kzeros" << endl;

    if(usedispl == 0) cout << "Not using displacement cut" << endl;
    if(usedispl == 1) cout << "Using absolute displacement cut" << endl;
    if(usedispl == 2) cout << "Using relative displacement cut" << endl;

    cout << "Number of bins in deltaphi = " << nbins << endl;

    cout << "N of Sigmas in D* selection =" << DStarSigma << endl;
    cout << "N of Sigmas in D0 selection = " << D0Sigma << endl;
    cout << "D0 Sidebands taken from  = " << D0SBSigmaLow << " - " << D0SBSigmaHigh << " sigmas " << endl; endl;

    cout << "DStar cut object:     " << DStarCutsFile << endl;
    cout << "Tracks cut object:    " << TrackCutsFile << endl;

    cout << "==========================================================" << endl;
    //gSystem->Sleep(2000);

//	TString DCutObjPath = "CutObjects/DStar/";

// ******************************** OPENING THE D* CUTS ************************************
    cout << "Getting D meson cut object from file \n" << DStarCutsFile.Data() << "\n " << endl;
    TFile* filecuts=TFile::Open(DStarCutsFile.Data());
    if(!filecuts->IsOpen()){
    cout<<"DStar cut object file not found: exit"<<endl;
    return;
    }

    AliRDHFCutsDStartoKpipi* RDHFDStartoKpipi=new AliRDHFCutsDStartoKpipi();
    RDHFDStartoKpipi = (AliRDHFCutsDStartoKpipi*)filecuts->Get("DStartoKpipiCuts");
    RDHFDStartoKpipi->SetName("DStartoKpipiCuts");

    // mm let's see if everything is ok
	if(!RDHFDStartoKpipi){
		cout<<"Specific AliRDHFCuts not found"<<endl;
		return;
	}

       // RDHFDStartoKpipi->SetTriggerClass("");
       // RDHFDStartoKpipi->SetTriggerMask(AliVEvent::kCentral);

// ******************************** OPENING THE ASSOCIATED TRACK CUTS ************************************
	cout << "Getting associated track cut object from file \n" << TrackCutsFile.Data() << "\n " << endl;
	TFile* filecuts2=TFile::Open(TrackCutsFile.Data());
	  if(!filecuts2->IsOpen()){
		  cout<<"Track cut object file not found: exit"<<endl;
		  return;
    }
 	AliHFAssociatedTrackCuts* corrCuts=new AliHFAssociatedTrackCuts();
	corrCuts = (AliHFAssociatedTrackCuts*)filecuts2->Get("AssociatedCuts");
	corrCuts->SetName("AssociatedCuts");
	corrCuts->PrintAll();
	if(!corrCuts){
		cout<<"Specific associated track cuts not found"<<endl;
		return;
	}

// ******************************** SELECTING THE MC PROCESS  ************************************

	TString selectMCproc = "";

	Int_t NMCevents = corrCuts->GetNofMCEventType();
	for(Int_t k=0; k<NMCevents; k++){
		Int_t * MCEventType = corrCuts->GetMCEventType();
		selectMCproc += Form("%d",MCEventType[k]);
	}

	 cout << "Select process string = " << selectMCproc << endl;

// ******************************** CREATING THE TASK ************************************

    printf("CREATE TASK \n");
  // create the task
  AliAnalysisTaskDStarCorrelations *task = new AliAnalysisTaskDStarCorrelations("AliAnalysisTaskDStarCorrelations",RDHFDStartoKpipi,corrCuts,syst,fullmode);

	// Setters

	if(!theMCon) {
		printf("Analysis on Data - reconstruction only!");
		UseReco = kTRUE;
	}

   // cout << "Adding efficiency map to Assoc track cut object \n" << endl;
  //  if(effMap) task->SetDeffMapvsPt(effMap);
  //  if(effMap2d) task->SetDeffMapvsPtvsMult(effMap2d);

    task->SetNofPhiBins(nbins);
	task->SetMonteCarlo(theMCon);
	task->SetUseMixing(mixing);
	task->SetCorrelator(trackselect) ;
	task->SetUseDisplacement(usedispl);
	//task->SetCollSys(syst);
	task->SetLevelOfDebug(2);
	task->SetUseReconstruction(UseReco); // set kTRUE for Using Reconstruction, kFALSe for MC Truth
    task->SetDMesonSigmas(DStarSigma,D0Sigma,D0SBSigmaLow,D0SBSigmaHigh);
	//task->SetDMesonSigmas(sigmas);
    //task->SetDMesonSigmas(sigmas);
    task->SetUseEfficiencyCorrection(UseEffic);
    task->SetUseDmesonEfficiencyCorrection(UseDEffic);

	if(trackselect == 1) Info(" AliAnalysisTaskDStarCorrelations","Correlating D* with charged hadrons \n");
	else if(trackselect == 2) Info(" AliAnalysisTaskDStarCorrelations","Correlating D* with charged kaons \n");
	else if(trackselect == 3) Info(" AliAnalysisTaskDStarCorrelations","Correlating D* with reconstructed K0s \n");
	else Fatal(" AliAnalysisTaskDStarCorrelations","Nothing to correlate with!");
	if(mixing) Info (" AliAnalysisTaskDStarCorrelations","Event Mixing Analysis\n");
	if(!mixing) Info (" AliAnalysisTaskDStarCorrelations","Single Event Analysis \n");

  // Create and connect containers for input/output
	//TString dcavalue = " ";
	if(!theMCon) TString contname = "Data";
	if(theMCon) TString contname = "MonteCarlo";
	TString contname2 = "MC";
	if(trackselect ==1) TString particle = "Hadron";
	if(trackselect ==2) TString particle = "Kaon";
	if(trackselect ==3) TString particle = "KZero";

	TString cutname = "cuts" ;
	TString cutname2 = "hadroncuts" ;
	TString outputfile = AliAnalysisManager::GetCommonFileName();
	TString outputfileMC = AliAnalysisManager::GetCommonFileName();
	TString counter = "NormCounter";
	outputfile += ":PWGHF_HFCJ_";
	outputfileMC += ":PWGHF_HFCJ_";

	if(!mixing) {
		outputfile += "SE";
		outputfileMC += "SE";
		contname += "SE";
		contname2 += "SE";
		cutname += "SE";
		cutname2 += "SE";
		counter+= "SE";
	}
	if(mixing){
		outputfile += "ME";
		outputfileMC += "ME";
		contname += "ME";
		contname2 += "ME";
		cutname += "ME";
		cutname2 += "ME";
		counter+= "ME";
	}

	outputfile += "Dphi_DStar";
	outputfileMC += "Dphi_DStar";
	outputfile += particle;
	outputfileMC += particle;
	cutname += particle;
	cutname2 += particle;
	contname += particle;
	contname2 += particle;
	counter+= particle;

    if(UseEffic){
        outputfile += "_EffY_";
		outputfileMC += "_EffY_";
		contname += "_EffY_";
		contname2 += "_EffY_";
		cutname += "_EffY_";
		cutname2 += "_EffY_";
		counter+= "_EffY_";
    }

    if(!UseEffic){
        outputfile += "_EffN_";
		outputfileMC += "_EffN_";
		contname += "_EffN_";
		contname2 += "_EffN_";
		cutname += "_EffN_";
		cutname2 += "_EffN_";
		counter+= "_EffN_";
    }

    if(UseDEffic){
        outputfile += "DEffY_";
		outputfileMC += "DEffY_";
		contname += "DEffY_";
		contname2 += "DEffY_";
		cutname += "DEffY_";
		cutname2 += "DEffY_";
		counter+= "DEffY_";
    }

    if(!UseDEffic){
        outputfile += "DEffN_";
		outputfileMC += "DEffN_";
		contname += "DEffN_";
		contname2 += "DEffN_";
		cutname += "DEffN_";
		cutname2 += "DEffN_";
		counter+= "DEffN_";
    }

    outputfile += Form("%d_bins_",nbins);
	outputfileMC += Form("%d_bins_",nbins);
	cutname += Form("%d_bins_",nbins);
	cutname2 += Form("%d_bins_",nbins);
	contname += Form("%d_bins_",nbins);
	contname2 += Form("%d_bins_",nbins);
	counter+= Form("%d_bins_",nbins);

	outputfile += Form("task_%d",tasknumber);
	outputfileMC += Form("task_%d",tasknumber);
	cutname += Form("task_%d",tasknumber);
	cutname2 += Form("task_%d",tasknumber);
	contname += Form("task_%d",tasknumber);
	contname2 += Form("task_%d",tasknumber);
	counter+= Form("task_%d",tasknumber);

/*	outputfile += TrackCutObjNamePrefix;
	outputfileMC += TrackCutObjNamePrefix;
	cutname += TrackCutObjNamePrefix;
	cutname2 += TrackCutObjNamePrefix;
	contname += TrackCutObjNamePrefix;
	contname2 += TrackCutObjNamePrefix;
	counter+= TrackCutObjNamePrefix;
*/
	outputfile += selectMCproc;
	outputfileMC += selectMCproc;
	cutname += selectMCproc;
	cutname2 += selectMCproc;
	contname += selectMCproc;
	contname2 += selectMCproc;
	counter+= selectMCproc;

	TString reco = "";

	if(UseReco) reco = "_reco";
	if(!UseReco) reco = "_MCTruth";

	outputfile += reco;
	outputfileMC += reco;
	cutname += reco;
	cutname2 += reco;
	contname += reco;
	contname2 += reco;
	counter+= reco;

	TString nsigma = Form("_%.0f_%.0f%.0f%.0f_sigmas",DStarSigma,D0Sigma,D0SBSigmaLow,D0SBSigmaHigh);

	//cout << "nsigma string = "<< nsigma << endl;

	outputfile += nsigma;
	outputfileMC += nsigma;
	cutname += nsigma;
	cutname2 += nsigma;
	contname += nsigma;
	contname2 += nsigma;
	counter+= nsigma;

	cout << contname << endl;
	cout << contname2 << endl;
	cout << cutname << endl;
	cout << cutname2 << endl;
	cout << counter << endl;
	cout << outputfile << endl;
	//return;

  mgr->AddTask(task);
  // ------ input data ------
  AliAnalysisDataContainer *cinput0  = mgr->GetCommonInputContainer();

  // ----- output data -----

  // output TH1I for event counting

	//TLists
  AliAnalysisDataContainer *coutput1 = mgr->CreateContainer(contname, TList::Class(),AliAnalysisManager::kOutputContainer,outputfile.Data());
  AliAnalysisDataContainer *coutput2 = mgr->CreateContainer(contname2, TList::Class(),AliAnalysisManager::kOutputContainer,outputfileMC.Data());
   // Cut Objects
  AliAnalysisDataContainer *coutput3 = mgr->CreateContainer(cutname,AliRDHFCutsDStartoKpipi::Class(),AliAnalysisManager::kOutputContainer, outputfile.Data()); //cuts D
  AliAnalysisDataContainer *coutput4 = mgr->CreateContainer(cutname2,AliHFAssociatedTrackCuts::Class(),AliAnalysisManager::kOutputContainer, outputfile.Data()); //cuts tracks
   // Normalization Counter
  AliAnalysisDataContainer *coutput5 = mgr->CreateContainer(counter,AliNormalizationCounter::Class(),AliAnalysisManager::kOutputContainer, outputfile.Data());

  mgr->ConnectInput(task,0,mgr->GetCommonInputContainer());
  mgr->ConnectOutput(task,1,coutput1);
  mgr->ConnectOutput(task,2,coutput2);
  mgr->ConnectOutput(task,3,coutput3);
  mgr->ConnectOutput(task,4,coutput4);
  mgr->ConnectOutput(task,5,coutput5);

  return task ;

}

<|endoftext|>


<commit_before>//============================================================================
// Name        : pg_async.cpp
// Author      : Sergei A. Fedorov
// Version     :
// Copyright   : Copyright (c) Sergei A. Fedorov 2015
//============================================================================

#include <iostream>
#include <memory>

#include <tip/db/pg/asio_config.hpp>
#include <tip/db/pg/detail/basic_connection.hpp>
#include <tip/db/pg/resultset.hpp>

#include <tip/db/pg/log.hpp>

#ifdef WITH_TIP_LOG
namespace {
/** Local logging facility */
using namespace tip::log;

const std::string LOG_CATEGORY = "MAIN";
logger::event_severity DEFAULT_SEVERITY = logger::TRACE;
local
local_log(logger::event_severity s = DEFAULT_SEVERITY)
{
	return local(LOG_CATEGORY, s);
}

}  // namespace
// For more convenient changing severity, eg local_log(logger::WARNING)
using tip::log::logger;
#endif

int
main(int argc, char* argv[])
{
	if (argc < 2) {
		std::cerr << "Usage: " << argv[0] << " <connection string> [query]\n";
		return 1;
	}
	try {
		using namespace tip::db::pg;
		#ifdef WITH_TIP_LOG
		logger::min_severity(logger::TRACE);
		logger::use_colors(true);
		#endif

		int query_count = 0;
		boost::asio::io_service io_service;
		connection_options opts = tip::db::pg::connection_options::parse(argv[1]);
		connection_ptr conn(connection::create(io_service,
		[&] (connection_ptr c){
			#ifdef WITH_TIP_LOG
			local_log(logger::INFO) << "Async callback when connection ready";
			#endif
			if (!query_count && argc > 2) {
				c->execute_query(argv[2],
					[](transaction_ptr c, resultset res, bool complete) {
					#ifdef WITH_TIP_LOG
					tip::log::local local = local_log(logger::INFO);
					local << "Received a result set:\n";
					for (int i = 0; i < res.columns_size(); ++i) {
						if (i > 0)
							local << "\t";
						local << "[" << res.field_name(i) << "]";
					}
					local << "\n";
					#endif
				}, [&](db_error const&){
					c->terminate();
				});
				++query_count;
			} else {
				c->terminate();
			}
		},
		[] (connection_ptr c) {
			#ifdef WITH_TIP_LOG
			local_log(logger::INFO) << "Connection gracefully terminated";
			#endif
		},
		[] (connection_ptr c, connection_error const&) {
			#ifdef WITH_TIP_LOG
			local_log(logger::ERROR) << "Async callback on connection error";
			#endif
		},
		opts,
		{
			{"client_encoding", "UTF8"},
			{"application_name", "pg_async"}
		}));
		io_service.run();
	} catch (std::exception const& e) {
		std::cerr << "Error " << e.what() << "\n";
	} catch (...) {
		std::cerr << "Non-standard exception :(\n";
		return 1;
	}
	return 0;
}
<commit_msg>Add logging facility macros<commit_after><|endoftext|>


<commit_before>#include "StdAfx.h"
#include "ParticleReadData.h"
//#include <PxParticleReadData.h>

ParticleReadData::ParticleReadData(PxParticleReadData* data)
	: LockedData(data)
{
}

void ParticleReadData::Unlock()
{
	this->UnmanagedPointer->unlock();
}

array<int>^ ParticleReadData::GetValidParticleBitmap()
{
	if (this->UnmanagedPointer->validParticleRange == 0)
		return nullptr;

	return Util::AsManagedArray<int>(this->UnmanagedPointer->validParticleBitmap, this->UnmanagedPointer->validParticleRange - 1);
}

array<Vector3>^ ParticleReadData::GetPositions()
{
	const int n = this->UnmanagedPointer->nbValidParticles;

	if (n <= 0)
		return nullptr;

	PxVec3 *p =  (PxVec3 *) malloc(n * sizeof(PxVec3));

	p = new PxVec3[n];

	for (int i = 0; i < n; i++)
		p[i] = this->UnmanagedPointer->positionBuffer[i];

	array<Vector3>^ ret = Util::AsManagedArray<Vector3>((void*)p, n);

	free(p);

	return ret;
}

array<Vector3>^ ParticleReadData::GetVelocities()
{
	const int n = this->UnmanagedPointer->nbValidParticles;

	if (n <= 0)
		return nullptr;

	PxVec3 *v =  (PxVec3 *) malloc(n * sizeof(PxVec3));

	v = new PxVec3[n];

	for (int i = 0; i < n; i++)
		v[i] = this->UnmanagedPointer->velocityBuffer[i];

	array<Vector3>^ ret = Util::AsManagedArray<Vector3>((void*)v, n);

	free(v);

	return ret;
}

array<float>^ ParticleReadData::GetRestOffsets()
{
	const int n = this->UnmanagedPointer->nbValidParticles;

	if (n <= 0)
		return nullptr;

	array<float>^ ret = gcnew array<float>(n);

	for (int i = 0; i < n; i++)
		ret[i] = this->UnmanagedPointer->restOffsetBuffer[i];

	return ret;
}

array<ParticleFlag>^ ParticleReadData::GetFlags()
{
	const int n = this->UnmanagedPointer->nbValidParticles;

	if (n <= 0)
		return nullptr;

	array<ParticleFlag>^ ret = gcnew array<ParticleFlag>(n);
	for (int i = 0; i < n; i++)
	{
		PxU16 flag = this->UnmanagedPointer->flagsBuffer[i];
		ret[i] = (ParticleFlag)flag;
	}

	return ret;
}

array<Vector3>^ ParticleReadData::GetCollisionNormals()
{
	const int n = this->UnmanagedPointer->nbValidParticles;

	if (n <= 0)
		return nullptr;

	PxVec3 *c =  (PxVec3 *) malloc(n * sizeof(PxVec3));

	c = new PxVec3[n];

	for (int i = 0; i < n; i++)
		c[i] = this->UnmanagedPointer->collisionNormalBuffer[i];

	array<Vector3>^ ret = Util::AsManagedArray<Vector3>((void*)c, n);

	free(c);

	return ret;
}

PhysX::DataAccessFlag ParticleReadData::DataAccessFlag::get()
{
	return ToManagedEnum(PhysX::DataAccessFlag, this->UnmanagedPointer->getDataAccessFlags());
}

int ParticleReadData::NumberOfValidParticles::get()
{
	return this->UnmanagedPointer->nbValidParticles;
}

int ParticleReadData::ValidParticleRange::get()
{
	return this->UnmanagedPointer->validParticleRange;
}

PxParticleReadData* ParticleReadData::UnmanagedPointer::get()
{
	return (PxParticleReadData*)LockedData::UnmanagedPointer;
}<commit_msg>Fix #6 ParticleReadData GetPositions memory leak<commit_after>#include "StdAfx.h"
#include "ParticleReadData.h"
//#include <PxParticleReadData.h>

ParticleReadData::ParticleReadData(PxParticleReadData* data)
	: LockedData(data)
{
}

void ParticleReadData::Unlock()
{
	this->UnmanagedPointer->unlock();
}

array<int>^ ParticleReadData::GetValidParticleBitmap()
{
	if (this->UnmanagedPointer->validParticleRange == 0)
		return nullptr;

	return Util::AsManagedArray<int>(this->UnmanagedPointer->validParticleBitmap, this->UnmanagedPointer->validParticleRange - 1);
}

array<Vector3>^ ParticleReadData::GetPositions()
{
	const int n = this->UnmanagedPointer->nbValidParticles;

	if (n <= 0)
		return nullptr;

	const PxVec3* p = this->UnmanagedPointer->positionBuffer.ptr();

	auto positions = Util::AsManagedArray<Vector3>(p, n);

	return positions;
}

array<Vector3>^ ParticleReadData::GetVelocities()
{
	const int n = this->UnmanagedPointer->nbValidParticles;

	if (n <= 0)
		return nullptr;

	PxVec3 *v =  (PxVec3 *) malloc(n * sizeof(PxVec3));

	v = new PxVec3[n];

	for (int i = 0; i < n; i++)
		v[i] = this->UnmanagedPointer->velocityBuffer[i];

	array<Vector3>^ ret = Util::AsManagedArray<Vector3>((void*)v, n);

	free(v);

	return ret;
}

array<float>^ ParticleReadData::GetRestOffsets()
{
	const int n = this->UnmanagedPointer->nbValidParticles;

	if (n <= 0)
		return nullptr;

	array<float>^ ret = gcnew array<float>(n);

	for (int i = 0; i < n; i++)
		ret[i] = this->UnmanagedPointer->restOffsetBuffer[i];

	return ret;
}

array<ParticleFlag>^ ParticleReadData::GetFlags()
{
	const int n = this->UnmanagedPointer->nbValidParticles;

	if (n <= 0)
		return nullptr;

	array<ParticleFlag>^ ret = gcnew array<ParticleFlag>(n);
	for (int i = 0; i < n; i++)
	{
		PxU16 flag = this->UnmanagedPointer->flagsBuffer[i];
		ret[i] = (ParticleFlag)flag;
	}

	return ret;
}

array<Vector3>^ ParticleReadData::GetCollisionNormals()
{
	const int n = this->UnmanagedPointer->nbValidParticles;

	if (n <= 0)
		return nullptr;

	PxVec3 *c =  (PxVec3 *) malloc(n * sizeof(PxVec3));

	c = new PxVec3[n];

	for (int i = 0; i < n; i++)
		c[i] = this->UnmanagedPointer->collisionNormalBuffer[i];

	array<Vector3>^ ret = Util::AsManagedArray<Vector3>((void*)c, n);

	free(c);

	return ret;
}

PhysX::DataAccessFlag ParticleReadData::DataAccessFlag::get()
{
	return ToManagedEnum(PhysX::DataAccessFlag, this->UnmanagedPointer->getDataAccessFlags());
}

int ParticleReadData::NumberOfValidParticles::get()
{
	return this->UnmanagedPointer->nbValidParticles;
}

int ParticleReadData::ValidParticleRange::get()
{
	return this->UnmanagedPointer->validParticleRange;
}

PxParticleReadData* ParticleReadData::UnmanagedPointer::get()
{
	return (PxParticleReadData*)LockedData::UnmanagedPointer;
}<|endoftext|>


<commit_before>//=============================================================================================================
/**
* @file     main.cpp
* @author   Lorenz Esch <lorenz.esch@tu-ilmenau.de>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     April, 2019
*
* @section  LICENSE
*
* Copyright (C) 2019, Lorenz Esch and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Example of using the MNE-CPP Connectivity library
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <connectivity/connectivity.h>
#include <connectivity/connectivitysettings.h>
#include <connectivity/network/network.h>
#include <connectivity/metrics/abstractmetric.h>

#include <fiff/fiff_raw_data.h>

#include <utils/ioutils.h>

#include <mne/mne_epoch_data_list.h>
#include <mne/mne.h>

#include <stdio.h>

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QDebug>
#include <QFile>
#include <QDateTime>
#include <QDir>
#include <QCoreApplication>
#include <QHostInfo>
#include <QElapsedTimer>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace Eigen;
using namespace FIFFLIB;
using namespace CONNECTIVITYLIB;
using namespace Eigen;
using namespace UTILSLIB;
using namespace MNELIB;

//*************************************************************************************************************
//=============================================================================================================
// Global Defines
//=============================================================================================================

QString m_sCurrentDir;
int m_iCurrentIteration = 0;
int m_iNumberTrials;
int m_iNumberChannels;
int m_iNumberSamples;

void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    Q_UNUSED(context);

    QString dt = QDateTime::currentDateTime().toString("dd/MM/yyyy hh:mm:ss");
    QString txt;// = QString("[%1] ").arg(dt);

    bool writeToLog = false;

    switch (type) {
        case QtWarningMsg:
            //txt += QString("{Warning} \t %1").arg(msg);
            txt += QString("%1").arg(msg);
            writeToLog=true;
            break;
    }

    if(!writeToLog) {
        return;
    }

    QString sFileName = m_sCurrentDir + "/" + QString::number(m_iNumberChannels) + "_" + QString::number(m_iNumberSamples) + "_" + QString::number(m_iNumberTrials) + ".log";

    QFile outFile(sFileName);
    outFile.open(QIODevice::WriteOnly | QIODevice::Append);

    QTextStream textStream(&outFile);
    textStream << txt << endl;
}

//*************************************************************************************************************
//=============================================================================================================
// MAIN
//=============================================================================================================

//=============================================================================================================
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    qInstallMessageHandler(customMessageHandler);

    //Parameters for performance test
    QStringList sConnectivityMethodList = QStringList() << "COR" << "XCOR" << "COH" << "IMAGCOH" << "PLI" << "WPLI" << "USPLI" << "DSWPLI" << "PLV";
    QList<int> lNumberTrials = QList<int>() << 1 << 5 << 10 << 20 << 50 << 100 << 200;
    QList<int> lNumberChannels = QList<int>() << 32 << 64 << 128 << 256;
    QList<int> lNumberSamples = QList<int>() << 100 << 200 << 300 << 400 << 500 << 600 << 700 << 800 << 900 << 1000 << 2000 << 3000 << 4000 << 5000 << 6000 << 7000 << 8000 << 9000 << 10000 << 20000 << 30000 << 40000 << 50000 << 60000 << 70000 << 80000 << 90000 << 100000;

    int iNumberRepeats = 5;
    int iStorageModeActive = 0;

    AbstractMetric::m_bStorageModeIsActive = iStorageModeActive;
    AbstractMetric::m_iNumberBins = 4;

    // Create sensor level data
    QElapsedTimer timer;
    qint64 iTime = 0;
    timer.start();

    QString sRaw = "/cluster/fusion/lesch/Git/mne-cpp-lorenze/bin/MNE-sample-data/MEG/sample/sample_audvis_raw.fif";
    MatrixXd matDataOrig, matData;
    MatrixXd times;
    QFile t_fileRaw(sRaw);
    FiffRawData raw(t_fileRaw);

    raw.read_raw_segment(matDataOrig, times, raw.first_samp, raw.first_samp+100001);

    //Perform connectivity performance tests
    Connectivity connectivityObj;

    ConnectivitySettings connectivitySettings;
    connectivitySettings.setSamplingFrequency(raw.info.sfreq);
    connectivitySettings.setWindowType("hanning");

    QMap<int, QMap<int, MatrixXd > > matInputData;

    for(int j = 0; j < lNumberChannels.size(); ++j) {
        QMap<int, MatrixXd > mapChannelsSamples;

        for(int i = 0; i < lNumberSamples.size(); ++i) {
            mapChannelsSamples[lNumberSamples.at(i)] = matDataOrig.block(0,0,lNumberChannels.at(j), lNumberSamples.at(i));
        }

        matInputData[lNumberChannels.at(j)] = mapChannelsSamples;
    }

    iTime = timer.elapsed();
    printf("Prepare data %d\n", iTime);
    timer.restart();

    qWarning() << "matInputData[256][40000].first().rows()" << matInputData[256][40000].rows();
    qWarning() << "matInputData[256][40000].first().cols()" << matInputData[256][40000].cols();
    qWarning() << "matInputData[32][500].rows()" << matInputData[32][500].rows();
    qWarning() << "matInputData[32][500].cols()" << matInputData[32][500].cols();
    qWarning() << "matInputData[64][100000].rows()" << matInputData[64][100000].rows();
    qWarning() << "matInputData[64][100000].cols()" << matInputData[64][100000].cols();

    for(int j = 0; j < lNumberSamples.size(); ++j) {
        for(int k = 0; k < lNumberChannels.size(); ++k) {
            connectivitySettings.clearAllData();

            matData = matInputData[lNumberChannels.at(k)][lNumberSamples.at(j)];

            RowVectorXi picks = RowVectorXi::LinSpaced(lNumberChannels.at(k),1,lNumberChannels.at(k)+1);
            connectivitySettings.setNodePositions(raw.info, picks);

            for(int l = 0; l < lNumberTrials.size(); ++l) {
                //Create data to work on

                while(connectivitySettings.size() < lNumberTrials.at(l)) {
                    connectivitySettings.append(matData);
                }

                for(int i = 0; i < sConnectivityMethodList.size(); ++i) {
                    m_iNumberTrials = lNumberTrials.at(l);
                    m_iNumberChannels = lNumberChannels.at(k);
                    m_iNumberSamples = lNumberSamples.at(j);

                    //Create new folder
                    m_sCurrentDir = QString("/cluster/fusion/lesch/connectivity_performance_%1_%2_%3/%4/%5_%6_%7").arg(QHostInfo::localHostName()).arg(AbstractMetric::m_iNumberBins).arg(iStorageModeActive).arg(sConnectivityMethodList.at(i)).arg(QString::number(lNumberChannels.at(k))).arg(QString::number(lNumberSamples.at(j))).arg(QString::number(lNumberTrials.at(l)));
                    QDir().mkpath(m_sCurrentDir);

                    //Write basic information to file
                    qWarning() << "sConnectivityMethod" << sConnectivityMethodList.at(i);
                    qWarning() << "sRaw" << sRaw;
                    qWarning() << "storageModeActive" << iStorageModeActive;
                    qWarning() << "iNumberSamples" << lNumberSamples.at(j);
                    qWarning() << "iNumberChannels" << lNumberChannels.at(k);
                    qWarning() << "iNumberTrials" << lNumberTrials.at(l);
                    qWarning() << "iNumberCSDFreqBins" << AbstractMetric::m_iNumberBins;
                    qWarning() << "rows" << matData.rows();
                    qWarning() << "cols" << matData.cols();
                    qWarning() << "numberNodes" << connectivitySettings.getNodePositions().rows();

                    // Check that iNfft >= signal length
                    int iSignalLength = lNumberSamples.at(j);
                    int iNfft = int(raw.info.sfreq/1.0);
                    if(iNfft > iSignalLength) {
                        iNfft = iSignalLength;
                    }

                    qWarning() << "iNfft" << iNfft;

                    int iNFreqs = int(floor(iNfft / 2.0)) + 1;
                    qWarning() << "iNFreqs" << iNFreqs;

                    connectivitySettings.setConnectivityMethods(QStringList() << sConnectivityMethodList.at(i));

                    m_iCurrentIteration = 0;
                    for(int u = 0; u < iNumberRepeats; ++u) {
                        connectivitySettings.clearIntermediateData();

                        qWarning() << "iteration" << m_iCurrentIteration;

                        //Do connectivity estimation
                        connectivityObj.calculate(connectivitySettings);

                        printf("Iteration %d: Calculating %s for %d trials, %d channels, %d samples\n", m_iCurrentIteration, sConnectivityMethodList.at(i).toLatin1().data(), connectivitySettings.size(), lNumberChannels.at(k), lNumberSamples.at(j));

                        m_iCurrentIteration++;
                    }
                }
            }
        }
    }

    return 0;
}
<commit_msg>ht support<commit_after>//=============================================================================================================
/**
* @file     main.cpp
* @author   Lorenz Esch <lorenz.esch@tu-ilmenau.de>;
*           Matti Hamalainen <msh@nmr.mgh.harvard.edu>
* @version  1.0
* @date     April, 2019
*
* @section  LICENSE
*
* Copyright (C) 2019, Lorenz Esch and Matti Hamalainen. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*     * Redistributions of source code must retain the above copyright notice, this list of conditions and the
*       following disclaimer.
*     * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
*       the following disclaimer in the documentation and/or other materials provided with the distribution.
*     * Neither the name of MNE-CPP authors nor the names of its contributors may be used
*       to endorse or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
* INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
* @brief    Example of using the MNE-CPP Connectivity library
*
*/

//*************************************************************************************************************
//=============================================================================================================
// INCLUDES
//=============================================================================================================

#include <connectivity/connectivity.h>
#include <connectivity/connectivitysettings.h>
#include <connectivity/network/network.h>
#include <connectivity/metrics/abstractmetric.h>

#include <fiff/fiff_raw_data.h>

#include <utils/ioutils.h>

#include <mne/mne_epoch_data_list.h>
#include <mne/mne.h>

#include <stdio.h>

//*************************************************************************************************************
//=============================================================================================================
// QT INCLUDES
//=============================================================================================================

#include <QDebug>
#include <QFile>
#include <QDateTime>
#include <QDir>
#include <QCoreApplication>
#include <QHostInfo>
#include <QElapsedTimer>
#include <QThreadPool>

//*************************************************************************************************************
//=============================================================================================================
// USED NAMESPACES
//=============================================================================================================

using namespace Eigen;
using namespace FIFFLIB;
using namespace CONNECTIVITYLIB;
using namespace Eigen;
using namespace UTILSLIB;
using namespace MNELIB;

//*************************************************************************************************************
//=============================================================================================================
// Global Defines
//=============================================================================================================

QString m_sCurrentDir;
int m_iCurrentIteration = 0;
int m_iNumberTrials;
int m_iNumberChannels;
int m_iNumberSamples;

void customMessageHandler(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
    Q_UNUSED(context);

    QString dt = QDateTime::currentDateTime().toString("dd/MM/yyyy hh:mm:ss");
    QString txt;// = QString("[%1] ").arg(dt);

    bool writeToLog = false;

    switch (type) {
        case QtWarningMsg:
            //txt += QString("{Warning} \t %1").arg(msg);
            txt += QString("%1").arg(msg);
            writeToLog=true;
            break;
    }

    if(!writeToLog) {
        return;
    }

    QString sFileName = m_sCurrentDir + "/" + QString::number(m_iNumberChannels) + "_" + QString::number(m_iNumberSamples) + "_" + QString::number(m_iNumberTrials) + ".log";

    QFile outFile(sFileName);
    outFile.open(QIODevice::WriteOnly | QIODevice::Append);

    QTextStream textStream(&outFile);
    textStream << txt << endl;
}

//*************************************************************************************************************
//=============================================================================================================
// MAIN
//=============================================================================================================

//=============================================================================================================
/**
* The function main marks the entry point of the program.
* By default, main has the storage class extern.
*
* @param [in] argc (argument count) is an integer that indicates how many arguments were entered on the command line when the program was started.
* @param [in] argv (argument vector) is an array of pointers to arrays of character objects. The array objects are null-terminated strings, representing the arguments that were entered on the command line when the program was started.
* @return the value that was set to exit() (which is 0 if exit() is called via quit()).
*/
int main(int argc, char *argv[])
{
    qInstallMessageHandler(customMessageHandler);

//    printf("globalInstance()->maxThreadCount(): %d\n",QThreadPool::globalInstance()->maxThreadCount());
//    QThreadPool::globalInstance()->setMaxThreadCount(24);

    //Parameters for performance test
    QStringList sConnectivityMethodList = QStringList() << "COR" << "XCOR" << "COH" << "IMAGCOH" << "PLI" << "WPLI" << "USPLI" << "DSWPLI" << "PLV";
    QList<int> lNumberTrials = QList<int>() << 1 << 5 << 10 << 20 << 50 << 100 << 200;
    QList<int> lNumberChannels = QList<int>() << 32 << 64 << 128 << 256;
    QList<int> lNumberSamples = QList<int>() << 100 << 200 << 300 << 400 << 500 << 600 << 700 << 800 << 900 << 1000 << 2000 << 3000 << 4000 << 5000 << 6000 << 7000 << 8000 << 9000 << 10000 << 20000 << 30000 << 40000 << 50000 << 60000 << 70000 << 80000 << 90000 << 100000;

    int iNumberRepeats = 5;
    int iStorageModeActive = 0;

    AbstractMetric::m_bStorageModeIsActive = iStorageModeActive;
    AbstractMetric::m_iNumberBins = 4;

    // Create sensor level data
    QElapsedTimer timer;
    qint64 iTime = 0;
    timer.start();

    QString sRaw = "/cluster/fusion/lesch/Git/mne-cpp-lorenze/bin/MNE-sample-data/MEG/sample/sample_audvis_raw.fif";
    MatrixXd matDataOrig, matData;
    MatrixXd times;
    QFile t_fileRaw(sRaw);
    FiffRawData raw(t_fileRaw);

    raw.read_raw_segment(matDataOrig, times, raw.first_samp, raw.first_samp+100001);

    //Perform connectivity performance tests
    Connectivity connectivityObj;

    ConnectivitySettings connectivitySettings;
    connectivitySettings.setSamplingFrequency(raw.info.sfreq);
    connectivitySettings.setWindowType("hanning");

    QMap<int, QMap<int, MatrixXd > > matInputData;

    for(int j = 0; j < lNumberChannels.size(); ++j) {
        QMap<int, MatrixXd > mapChannelsSamples;

        for(int i = 0; i < lNumberSamples.size(); ++i) {
            mapChannelsSamples[lNumberSamples.at(i)] = matDataOrig.block(0,0,lNumberChannels.at(j), lNumberSamples.at(i));
        }

        matInputData[lNumberChannels.at(j)] = mapChannelsSamples;
    }

    iTime = timer.elapsed();
    printf("Prepare data %d\n", iTime);
    timer.restart();

    qWarning() << "matInputData[256][40000].first().rows()" << matInputData[256][40000].rows();
    qWarning() << "matInputData[256][40000].first().cols()" << matInputData[256][40000].cols();
    qWarning() << "matInputData[32][500].rows()" << matInputData[32][500].rows();
    qWarning() << "matInputData[32][500].cols()" << matInputData[32][500].cols();
    qWarning() << "matInputData[64][100000].rows()" << matInputData[64][100000].rows();
    qWarning() << "matInputData[64][100000].cols()" << matInputData[64][100000].cols();

    for(int j = 0; j < lNumberSamples.size(); ++j) {
        for(int k = 0; k < lNumberChannels.size(); ++k) {
            connectivitySettings.clearAllData();

            matData = matInputData[lNumberChannels.at(k)][lNumberSamples.at(j)];

            RowVectorXi picks = RowVectorXi::LinSpaced(lNumberChannels.at(k),1,lNumberChannels.at(k)+1);
            connectivitySettings.setNodePositions(raw.info, picks);

            for(int l = 0; l < lNumberTrials.size(); ++l) {
                //Create data to work on

                while(connectivitySettings.size() < lNumberTrials.at(l)) {
                    connectivitySettings.append(matData);
                }

                for(int i = 0; i < sConnectivityMethodList.size(); ++i) {
                    m_iNumberTrials = lNumberTrials.at(l);
                    m_iNumberChannels = lNumberChannels.at(k);
                    m_iNumberSamples = lNumberSamples.at(j);

                    //Create new folder
                    m_sCurrentDir = QString("/cluster/fusion/lesch/connectivity_performance_%1_ht_%2_%3/%4/%5_%6_%7").arg(QHostInfo::localHostName()).arg(AbstractMetric::m_iNumberBins).arg(iStorageModeActive).arg(sConnectivityMethodList.at(i)).arg(QString::number(lNumberChannels.at(k))).arg(QString::number(lNumberSamples.at(j))).arg(QString::number(lNumberTrials.at(l)));
                    QDir().mkpath(m_sCurrentDir);

                    //Write basic information to file
                    qWarning() << "sConnectivityMethod" << sConnectivityMethodList.at(i);
                    qWarning() << "sRaw" << sRaw;
                    qWarning() << "storageModeActive" << iStorageModeActive;
                    qWarning() << "iNumberSamples" << lNumberSamples.at(j);
                    qWarning() << "iNumberChannels" << lNumberChannels.at(k);
                    qWarning() << "iNumberTrials" << lNumberTrials.at(l);
                    qWarning() << "iNumberCSDFreqBins" << AbstractMetric::m_iNumberBins;
                    qWarning() << "rows" << matData.rows();
                    qWarning() << "cols" << matData.cols();
                    qWarning() << "numberNodes" << connectivitySettings.getNodePositions().rows();

                    // Check that iNfft >= signal length
                    int iSignalLength = lNumberSamples.at(j);
                    int iNfft = int(raw.info.sfreq/1.0);
                    if(iNfft > iSignalLength) {
                        iNfft = iSignalLength;
                    }

                    qWarning() << "iNfft" << iNfft;

                    int iNFreqs = int(floor(iNfft / 2.0)) + 1;
                    qWarning() << "iNFreqs" << iNFreqs;

                    connectivitySettings.setConnectivityMethods(QStringList() << sConnectivityMethodList.at(i));

                    m_iCurrentIteration = 0;
                    for(int u = 0; u < iNumberRepeats; ++u) {
                        connectivitySettings.clearIntermediateData();

                        qWarning() << "iteration" << m_iCurrentIteration;

                        //Do connectivity estimation
                        connectivityObj.calculate(connectivitySettings);

                        printf("Iteration %d: Calculating %s for %d trials, %d channels, %d samples\n", m_iCurrentIteration, sConnectivityMethodList.at(i).toLatin1().data(), connectivitySettings.size(), lNumberChannels.at(k), lNumberSamples.at(j));

                        m_iCurrentIteration++;
                    }
                }
            }
        }
    }

    return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include <vector>
#include <mpi.h>
#include "BVshared.h"
#include "BVgene.h"

#define MASTER 0
#define TAG 0
const int MESSAGE_SIZE = 500;

int main(int argc, char *argv[]) {
  int rows = 4550, column_size = 69, i, my_rank, num_nodes, source, start_row,
      end_row, number_amount;
  double program_start = MPI_Wtime();
  std::string gene_name, message_str;
  char message[MESSAGE_SIZE];
  std::vector<std::vector<std::string>> vector =
      vectorize("NCI-60.csv", rows, column_size);
  std::vector<gene_expression> gene_expressions =
      gene_expression_vector(vector);

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  MPI_Comm_size(MPI_COMM_WORLD, &num_nodes);

  if (my_rank != MASTER) {
    // pick rows to process by rank
    end_row = my_rank * 10;
    if (end_row > rows) {
      start_row = end_row - 10;
      for (i = start_row; i < end_row; i++) {
        gene_result result = process(gene_expressions[i]);
        message_str = encode_gene_result(result);
        strcpy(message, message_str.c_str());
        MPI_Send(&message, message_str.size(), MPI_CHAR, MASTER, i,
                 MPI_COMM_WORLD);
      }
    }
  } else {
    MPI_Status status;
    std::vector<gene_result> gene_results;
    std::map<int, std::string> gene_name_index = gene_index(gene_expressions);
    for (i = 0; i < rows; i++) {
      MPI_Recv(&message, MESSAGE_SIZE, MPI_CHAR, source, i, MPI_COMM_WORLD,
               &status);
      MPI_Get_count(&status, MPI_CHAR, &number_amount);
      std::string message_str(message, number_amount);
      gene_results.push_back(decode_gene_result(message_str));
    }
    double program_end = MPI_Wtime();
    double program_elapsed = program_end - program_start;

    std::cout.precision(10);
    for (i = 0; i < gene_results.size(); i++) {
      std::cout << gene_results[i].gene_name << ", " << gene_results[i].d_score
                << std::endl;
    }

    printf("Nodes, Message Size, Program Execution Time, %d,%lu,%f\n",
           num_nodes, sizeof(double), program_elapsed);
  }

  MPI_Finalize();

  return 0;
}
<commit_msg>fix bug<commit_after>#include <iostream>
#include <string>
#include <vector>
#include <mpi.h>
#include "BVshared.h"
#include "BVgene.h"

#define MASTER 0
#define TAG 0
const int MESSAGE_SIZE = 500;

int main(int argc, char *argv[]) {
  int rows = 4550, column_size = 69, i, my_rank, num_nodes, source, start_row,
      end_row, number_amount;
  double program_start = MPI_Wtime();
  std::string gene_name, message_str;
  char message[MESSAGE_SIZE];
  std::vector<std::vector<std::string>> vector =
      vectorize("NCI-60.csv", rows, column_size);
  std::vector<gene_expression> gene_expressions =
      gene_expression_vector(vector);

  MPI_Init(&argc, &argv);
  MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
  MPI_Comm_size(MPI_COMM_WORLD, &num_nodes);

  if (my_rank != MASTER) {
    // pick rows to process by rank
    end_row = my_rank * 10;
    if (end_row < rows) {
      start_row = end_row - 10;
      for (i = start_row; i < end_row; i++) {
        gene_result result = process(gene_expressions[i]);
        message_str = encode_gene_result(result);
        strcpy(message, message_str.c_str());
        MPI_Send(&message, message_str.size(), MPI_CHAR, MASTER, i,
                 MPI_COMM_WORLD);
      }
    }
  } else {
    MPI_Status status;
    std::vector<gene_result> gene_results;
    std::map<int, std::string> gene_name_index = gene_index(gene_expressions);
    for (i = 0; i < rows; i++) {
      MPI_Recv(&message, MESSAGE_SIZE, MPI_CHAR, source, i, MPI_COMM_WORLD,
               &status);
      MPI_Get_count(&status, MPI_CHAR, &number_amount);
      std::string message_str(message, number_amount);
      gene_results.push_back(decode_gene_result(message_str));
    }
    double program_end = MPI_Wtime();
    double program_elapsed = program_end - program_start;

    std::cout.precision(10);
    for (i = 0; i < gene_results.size(); i++) {
      std::cout << gene_results[i].gene_name << ", " << gene_results[i].d_score
                << std::endl;
    }

    printf("Nodes, Message Size, Program Execution Time, %d,%lu,%f\n",
           num_nodes, sizeof(double), program_elapsed);
  }

  MPI_Finalize();

  return 0;
}
<|endoftext|>