<commit_before>// Copyright (c) 2010 Google Inc.
// 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 Google Inc. 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.

#include <unistd.h>
#include <sys/poll.h>
#include <sys/stat.h>
#include <sys/syscall.h>

#include "breakpad_googletest_includes.h"
#include "client/linux/handler/exception_handler.h"
#include "client/linux/minidump_writer/linux_dumper.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
#include "common/linux/file_id.h"
#include "google_breakpad/processor/minidump.h"

using namespace google_breakpad;

#if !defined(__ANDROID__)
#define TEMPDIR "/tmp"
#else
#define TEMPDIR "/data/local/tmp"
#endif

// Length of a formatted GUID string =
// sizeof(MDGUID) * 2 + 4 (for dashes) + 1 (null terminator)
const int kGUIDStringSize = 37;

namespace {
typedef testing::Test MinidumpWriterTest;
}

TEST(MinidumpWriterTest, Setup) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
    close(fds[0]);
    syscall(__NR_exit);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));

  char templ[] = TEMPDIR "/minidump-writer-unittest-XXXXXX";
  mktemp(templ);
  // Set a non-zero tid to avoid tripping asserts.
  context.tid = 1;
  ASSERT_TRUE(WriteMinidump(templ, child, &context, sizeof(context)));
  struct stat st;
  ASSERT_EQ(stat(templ, &st), 0);
  ASSERT_GT(st.st_size, 0u);
  unlink(templ);

  close(fds[1]);
}

// Test that mapping info can be specified when writing a minidump,
// and that it ends up in the module list of the minidump.
TEST(MinidumpWriterTest, MappingInfo) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  // These are defined here so the parent can use them to check the
  // data from the minidump afterwards.
  const u_int32_t kMemorySize = sysconf(_SC_PAGESIZE);
  const char* kMemoryName = "a fake module";
  const u_int8_t kModuleGUID[sizeof(MDGUID)] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
  };
  char module_identifier_buffer[kGUIDStringSize];
  FileID::ConvertIdentifierToString(kModuleGUID,
                                    module_identifier_buffer,
                                    sizeof(module_identifier_buffer));
  string module_identifier(module_identifier_buffer);
  // Strip out dashes
  size_t pos;
  while ((pos = module_identifier.find('-')) != string::npos) {
    module_identifier.erase(pos, 1);
  }
  // And append a zero, because module IDs include an "age" field
  // which is always zero on Linux.
  module_identifier += "0";

  // Get some memory.
  char* memory =
    reinterpret_cast<char*>(mmap(NULL,
                                 kMemorySize,
                                 PROT_READ | PROT_WRITE,
                                 MAP_PRIVATE | MAP_ANON,
                                 -1,
                                 0));
  const u_int64_t kMemoryAddress = reinterpret_cast<u_int64_t>(memory);
  ASSERT_TRUE(memory);

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
    close(fds[0]);
    syscall(__NR_exit);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));
  context.tid = 1;

  char templ[] = TEMPDIR "/minidump-writer-unittest-XXXXXX";
  mktemp(templ);

  // Add information about the mapped memory.
  MappingInfo info;
  info.start_addr = kMemoryAddress;
  info.size = kMemorySize;
  info.offset = 0;
  strcpy(info.name, kMemoryName);

  MappingList mappings;
  MappingEntry mapping;
  mapping.first = info;
  memcpy(mapping.second, kModuleGUID, sizeof(MDGUID));
  mappings.push_back(mapping);
  ASSERT_TRUE(WriteMinidump(templ, child, &context, sizeof(context), mappings));

  // Read the minidump. Load the module list, and ensure that
  // the mmap'ed |memory| is listed with the given module name
  // and debug ID.
  Minidump minidump(templ);
  ASSERT_TRUE(minidump.Read());

  MinidumpModuleList* module_list = minidump.GetModuleList();
  ASSERT_TRUE(module_list);
  const MinidumpModule* module =
    module_list->GetModuleForAddress(kMemoryAddress);
  ASSERT_TRUE(module);

  EXPECT_EQ(kMemoryAddress, module->base_address());
  EXPECT_EQ(kMemorySize, module->size());
  EXPECT_EQ(kMemoryName, module->code_file());
  EXPECT_EQ(module_identifier, module->debug_identifier());

  unlink(templ);
  close(fds[1]);
}

// Test that mapping info can be specified, and that it overrides
// existing mappings that are wholly contained within the specified
// range.
TEST(MinidumpWriterTest, MappingInfoContained) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  // These are defined here so the parent can use them to check the
  // data from the minidump afterwards.
  const u_int32_t kMemorySize = sysconf(_SC_PAGESIZE);
  const char* kMemoryName = "a fake module";
  const u_int8_t kModuleGUID[sizeof(MDGUID)] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
  };
  char module_identifier_buffer[kGUIDStringSize];
  FileID::ConvertIdentifierToString(kModuleGUID,
                                    module_identifier_buffer,
                                    sizeof(module_identifier_buffer));
  string module_identifier(module_identifier_buffer);
  // Strip out dashes
  size_t pos;
  while ((pos = module_identifier.find('-')) != string::npos) {
    module_identifier.erase(pos, 1);
  }
  // And append a zero, because module IDs include an "age" field
  // which is always zero on Linux.
  module_identifier += "0";

  // mmap a file
  char tempfile[] = TEMPDIR "/minidump-writer-unittest-temp-XXXXXX";
  mktemp(tempfile);
  int fd = open(tempfile, O_RDWR | O_CREAT, 0);
  ASSERT_NE(-1, fd);
  unlink(tempfile);
  // fill with zeros
  char buffer[kMemorySize];
  memset(buffer, 0, kMemorySize);
  ASSERT_EQ(kMemorySize, write(fd, buffer, kMemorySize));
  lseek(fd, 0, SEEK_SET);

  char* memory =
    reinterpret_cast<char*>(mmap(NULL,
                                 kMemorySize,
                                 PROT_READ | PROT_WRITE,
                                 MAP_PRIVATE,
                                 fd,
                                 0));
  const u_int64_t kMemoryAddress = reinterpret_cast<u_int64_t>(memory);
  ASSERT_TRUE(memory);
  close(fd);

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
    close(fds[0]);
    syscall(__NR_exit);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));
  context.tid = 1;

  char dumpfile[] = TEMPDIR "/minidump-writer-unittest-XXXXXX";
  mktemp(dumpfile);

  // Add information about the mapped memory. Report it as being larger than
  // it actually is.
  MappingInfo info;
  info.start_addr = kMemoryAddress - kMemorySize;
  info.size = kMemorySize * 3;
  info.offset = 0;
  strcpy(info.name, kMemoryName);

  MappingList mappings;
  MappingEntry mapping;
  mapping.first = info;
  memcpy(mapping.second, kModuleGUID, sizeof(MDGUID));
  mappings.push_back(mapping);
  ASSERT_TRUE(WriteMinidump(dumpfile, child, &context, sizeof(context), mappings));

  // Read the minidump. Load the module list, and ensure that
  // the mmap'ed |memory| is listed with the given module name
  // and debug ID.
  Minidump minidump(dumpfile);
  ASSERT_TRUE(minidump.Read());

  MinidumpModuleList* module_list = minidump.GetModuleList();
  ASSERT_TRUE(module_list);
  const MinidumpModule* module =
    module_list->GetModuleForAddress(kMemoryAddress);
  ASSERT_TRUE(module);

  EXPECT_EQ(info.start_addr, module->base_address());
  EXPECT_EQ(info.size, module->size());
  EXPECT_EQ(kMemoryName, module->code_file());
  EXPECT_EQ(module_identifier, module->debug_identifier());

  unlink(dumpfile);
  close(fds[1]);
}

TEST(MinidumpWriterTest, DeletedBinary) {
  static const int kNumberOfThreadsInHelperProgram = 1;
  char kNumberOfThreadsArgument[2];
  sprintf(kNumberOfThreadsArgument, "%d", kNumberOfThreadsInHelperProgram);

  // Locate helper binary next to the current binary.
  char self_path[PATH_MAX];
  if (readlink("/proc/self/exe", self_path, sizeof(self_path) - 1) == -1) {
    FAIL() << "readlink failed: " << strerror(errno);
    exit(1);
  }
  string helper_path(self_path);
  size_t pos = helper_path.rfind('/');
  if (pos == string::npos) {
    FAIL() << "no trailing slash in path: " << helper_path;
    exit(1);
  }
  helper_path.erase(pos + 1);
  helper_path += "linux_dumper_unittest_helper";

  // Copy binary to a temp file.
  char binpath[] = TEMPDIR "/linux-dumper-unittest-helper-XXXXXX";
  mktemp(binpath);
  char cmdline[2 * PATH_MAX];
  sprintf(cmdline, "/bin/cp \"%s\" \"%s\"", helper_path.c_str(), binpath);
  ASSERT_EQ(0, system(cmdline));
  ASSERT_EQ(0, chmod(binpath, 0755));

  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  pid_t child_pid = fork();
  if (child_pid == 0) {
    // In child process.
    close(fds[0]);

    // Pass the pipe fd and the number of threads as arguments.
    char pipe_fd_string[8];
    sprintf(pipe_fd_string, "%d", fds[1]);
    execl(binpath,
          binpath,
          pipe_fd_string,
          kNumberOfThreadsArgument,
          NULL);
  }
  close(fds[1]);
  // Wait for the child process to signal that it's ready.
  struct pollfd pfd;
  memset(&pfd, 0, sizeof(pfd));
  pfd.fd = fds[0];
  pfd.events = POLLIN | POLLERR;

  const int r = HANDLE_EINTR(poll(&pfd, 1, 1000));
  ASSERT_EQ(1, r);
  ASSERT_TRUE(pfd.revents & POLLIN);
  uint8_t junk;
  read(fds[0], &junk, sizeof(junk));
  close(fds[0]);

  // Child is ready now.
  // Unlink the test binary.
  unlink(binpath);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));

  char templ[] = TEMPDIR "/minidump-writer-unittest-XXXXXX";
  mktemp(templ);
  // Set a non-zero tid to avoid tripping asserts.
  context.tid = 1;
  ASSERT_TRUE(WriteMinidump(templ, child_pid, &context, sizeof(context)));
  kill(child_pid, SIGKILL);

  struct stat st;
  ASSERT_EQ(stat(templ, &st), 0);
  ASSERT_GT(st.st_size, 0u);

  Minidump minidump(templ);
  ASSERT_TRUE(minidump.Read());

  // Check that the main module filename is correct.
  MinidumpModuleList* module_list = minidump.GetModuleList();
  ASSERT_TRUE(module_list);
  const MinidumpModule* module = module_list->GetMainModule();
  EXPECT_STREQ(binpath, module->code_file().c_str());
  // Check that the file ID is correct.
  FileID fileid(helper_path.c_str());
  uint8_t identifier[sizeof(MDGUID)];
  EXPECT_TRUE(fileid.ElfFileIdentifier(identifier));
  char identifier_string[kGUIDStringSize];
  FileID::ConvertIdentifierToString(identifier,
                                    identifier_string,
                                    kGUIDStringSize);
  string module_identifier(identifier_string);
  // Strip out dashes
  while ((pos = module_identifier.find('-')) != string::npos) {
    module_identifier.erase(pos, 1);
  }
  // And append a zero, because module IDs include an "age" field
  // which is always zero on Linux.
  module_identifier += "0";
  EXPECT_EQ(module_identifier, module->debug_identifier());

  unlink(templ);
}
<commit_msg>Fix compile by adding needed includes. Review URL: http://breakpad.appspot.com/253001<commit_after>// Copyright (c) 2011 Google Inc.
// 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 Google Inc. 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.

#include <fcntl.h>
#include <sys/poll.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/types.h>
#include <unistd.h>

#include <string>

#include "breakpad_googletest_includes.h"
#include "client/linux/handler/exception_handler.h"
#include "client/linux/minidump_writer/linux_dumper.h"
#include "client/linux/minidump_writer/minidump_writer.h"
#include "common/linux/eintr_wrapper.h"
#include "common/linux/file_id.h"
#include "google_breakpad/processor/minidump.h"

using namespace google_breakpad;

#if !defined(__ANDROID__)
#define TEMPDIR "/tmp"
#else
#define TEMPDIR "/data/local/tmp"
#endif

// Length of a formatted GUID string =
// sizeof(MDGUID) * 2 + 4 (for dashes) + 1 (null terminator)
const int kGUIDStringSize = 37;

namespace {
typedef testing::Test MinidumpWriterTest;
}

TEST(MinidumpWriterTest, Setup) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
    close(fds[0]);
    syscall(__NR_exit);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));

  char templ[] = TEMPDIR "/minidump-writer-unittest-XXXXXX";
  mktemp(templ);
  // Set a non-zero tid to avoid tripping asserts.
  context.tid = 1;
  ASSERT_TRUE(WriteMinidump(templ, child, &context, sizeof(context)));
  struct stat st;
  ASSERT_EQ(stat(templ, &st), 0);
  ASSERT_GT(st.st_size, 0u);
  unlink(templ);

  close(fds[1]);
}

// Test that mapping info can be specified when writing a minidump,
// and that it ends up in the module list of the minidump.
TEST(MinidumpWriterTest, MappingInfo) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  // These are defined here so the parent can use them to check the
  // data from the minidump afterwards.
  const u_int32_t kMemorySize = sysconf(_SC_PAGESIZE);
  const char* kMemoryName = "a fake module";
  const u_int8_t kModuleGUID[sizeof(MDGUID)] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
  };
  char module_identifier_buffer[kGUIDStringSize];
  FileID::ConvertIdentifierToString(kModuleGUID,
                                    module_identifier_buffer,
                                    sizeof(module_identifier_buffer));
  string module_identifier(module_identifier_buffer);
  // Strip out dashes
  size_t pos;
  while ((pos = module_identifier.find('-')) != string::npos) {
    module_identifier.erase(pos, 1);
  }
  // And append a zero, because module IDs include an "age" field
  // which is always zero on Linux.
  module_identifier += "0";

  // Get some memory.
  char* memory =
    reinterpret_cast<char*>(mmap(NULL,
                                 kMemorySize,
                                 PROT_READ | PROT_WRITE,
                                 MAP_PRIVATE | MAP_ANON,
                                 -1,
                                 0));
  const u_int64_t kMemoryAddress = reinterpret_cast<u_int64_t>(memory);
  ASSERT_TRUE(memory);

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
    close(fds[0]);
    syscall(__NR_exit);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));
  context.tid = 1;

  char templ[] = TEMPDIR "/minidump-writer-unittest-XXXXXX";
  mktemp(templ);

  // Add information about the mapped memory.
  MappingInfo info;
  info.start_addr = kMemoryAddress;
  info.size = kMemorySize;
  info.offset = 0;
  strcpy(info.name, kMemoryName);

  MappingList mappings;
  MappingEntry mapping;
  mapping.first = info;
  memcpy(mapping.second, kModuleGUID, sizeof(MDGUID));
  mappings.push_back(mapping);
  ASSERT_TRUE(WriteMinidump(templ, child, &context, sizeof(context), mappings));

  // Read the minidump. Load the module list, and ensure that
  // the mmap'ed |memory| is listed with the given module name
  // and debug ID.
  Minidump minidump(templ);
  ASSERT_TRUE(minidump.Read());

  MinidumpModuleList* module_list = minidump.GetModuleList();
  ASSERT_TRUE(module_list);
  const MinidumpModule* module =
    module_list->GetModuleForAddress(kMemoryAddress);
  ASSERT_TRUE(module);

  EXPECT_EQ(kMemoryAddress, module->base_address());
  EXPECT_EQ(kMemorySize, module->size());
  EXPECT_EQ(kMemoryName, module->code_file());
  EXPECT_EQ(module_identifier, module->debug_identifier());

  unlink(templ);
  close(fds[1]);
}

// Test that mapping info can be specified, and that it overrides
// existing mappings that are wholly contained within the specified
// range.
TEST(MinidumpWriterTest, MappingInfoContained) {
  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  // These are defined here so the parent can use them to check the
  // data from the minidump afterwards.
  const u_int32_t kMemorySize = sysconf(_SC_PAGESIZE);
  const char* kMemoryName = "a fake module";
  const u_int8_t kModuleGUID[sizeof(MDGUID)] = {
    0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
    0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD, 0xEE, 0xFF
  };
  char module_identifier_buffer[kGUIDStringSize];
  FileID::ConvertIdentifierToString(kModuleGUID,
                                    module_identifier_buffer,
                                    sizeof(module_identifier_buffer));
  string module_identifier(module_identifier_buffer);
  // Strip out dashes
  size_t pos;
  while ((pos = module_identifier.find('-')) != string::npos) {
    module_identifier.erase(pos, 1);
  }
  // And append a zero, because module IDs include an "age" field
  // which is always zero on Linux.
  module_identifier += "0";

  // mmap a file
  char tempfile[] = TEMPDIR "/minidump-writer-unittest-temp-XXXXXX";
  mktemp(tempfile);
  int fd = open(tempfile, O_RDWR | O_CREAT, 0);
  ASSERT_NE(-1, fd);
  unlink(tempfile);
  // fill with zeros
  char buffer[kMemorySize];
  memset(buffer, 0, kMemorySize);
  ASSERT_EQ(kMemorySize, write(fd, buffer, kMemorySize));
  lseek(fd, 0, SEEK_SET);

  char* memory =
    reinterpret_cast<char*>(mmap(NULL,
                                 kMemorySize,
                                 PROT_READ | PROT_WRITE,
                                 MAP_PRIVATE,
                                 fd,
                                 0));
  const u_int64_t kMemoryAddress = reinterpret_cast<u_int64_t>(memory);
  ASSERT_TRUE(memory);
  close(fd);

  const pid_t child = fork();
  if (child == 0) {
    close(fds[1]);
    char b;
    HANDLE_EINTR(read(fds[0], &b, sizeof(b)));
    close(fds[0]);
    syscall(__NR_exit);
  }
  close(fds[0]);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));
  context.tid = 1;

  char dumpfile[] = TEMPDIR "/minidump-writer-unittest-XXXXXX";
  mktemp(dumpfile);

  // Add information about the mapped memory. Report it as being larger than
  // it actually is.
  MappingInfo info;
  info.start_addr = kMemoryAddress - kMemorySize;
  info.size = kMemorySize * 3;
  info.offset = 0;
  strcpy(info.name, kMemoryName);

  MappingList mappings;
  MappingEntry mapping;
  mapping.first = info;
  memcpy(mapping.second, kModuleGUID, sizeof(MDGUID));
  mappings.push_back(mapping);
  ASSERT_TRUE(
      WriteMinidump(dumpfile, child, &context, sizeof(context), mappings));

  // Read the minidump. Load the module list, and ensure that
  // the mmap'ed |memory| is listed with the given module name
  // and debug ID.
  Minidump minidump(dumpfile);
  ASSERT_TRUE(minidump.Read());

  MinidumpModuleList* module_list = minidump.GetModuleList();
  ASSERT_TRUE(module_list);
  const MinidumpModule* module =
    module_list->GetModuleForAddress(kMemoryAddress);
  ASSERT_TRUE(module);

  EXPECT_EQ(info.start_addr, module->base_address());
  EXPECT_EQ(info.size, module->size());
  EXPECT_EQ(kMemoryName, module->code_file());
  EXPECT_EQ(module_identifier, module->debug_identifier());

  unlink(dumpfile);
  close(fds[1]);
}

TEST(MinidumpWriterTest, DeletedBinary) {
  static const int kNumberOfThreadsInHelperProgram = 1;
  char kNumberOfThreadsArgument[2];
  sprintf(kNumberOfThreadsArgument, "%d", kNumberOfThreadsInHelperProgram);

  // Locate helper binary next to the current binary.
  char self_path[PATH_MAX];
  if (readlink("/proc/self/exe", self_path, sizeof(self_path) - 1) == -1) {
    FAIL() << "readlink failed: " << strerror(errno);
    exit(1);
  }
  string helper_path(self_path);
  size_t pos = helper_path.rfind('/');
  if (pos == string::npos) {
    FAIL() << "no trailing slash in path: " << helper_path;
    exit(1);
  }
  helper_path.erase(pos + 1);
  helper_path += "linux_dumper_unittest_helper";

  // Copy binary to a temp file.
  char binpath[] = TEMPDIR "/linux-dumper-unittest-helper-XXXXXX";
  mktemp(binpath);
  char cmdline[2 * PATH_MAX];
  sprintf(cmdline, "/bin/cp \"%s\" \"%s\"", helper_path.c_str(), binpath);
  ASSERT_EQ(0, system(cmdline));
  ASSERT_EQ(0, chmod(binpath, 0755));

  int fds[2];
  ASSERT_NE(-1, pipe(fds));

  pid_t child_pid = fork();
  if (child_pid == 0) {
    // In child process.
    close(fds[0]);

    // Pass the pipe fd and the number of threads as arguments.
    char pipe_fd_string[8];
    sprintf(pipe_fd_string, "%d", fds[1]);
    execl(binpath,
          binpath,
          pipe_fd_string,
          kNumberOfThreadsArgument,
          NULL);
  }
  close(fds[1]);
  // Wait for the child process to signal that it's ready.
  struct pollfd pfd;
  memset(&pfd, 0, sizeof(pfd));
  pfd.fd = fds[0];
  pfd.events = POLLIN | POLLERR;

  const int r = HANDLE_EINTR(poll(&pfd, 1, 1000));
  ASSERT_EQ(1, r);
  ASSERT_TRUE(pfd.revents & POLLIN);
  uint8_t junk;
  read(fds[0], &junk, sizeof(junk));
  close(fds[0]);

  // Child is ready now.
  // Unlink the test binary.
  unlink(binpath);

  ExceptionHandler::CrashContext context;
  memset(&context, 0, sizeof(context));

  char templ[] = TEMPDIR "/minidump-writer-unittest-XXXXXX";
  mktemp(templ);
  // Set a non-zero tid to avoid tripping asserts.
  context.tid = 1;
  ASSERT_TRUE(WriteMinidump(templ, child_pid, &context, sizeof(context)));
  kill(child_pid, SIGKILL);

  struct stat st;
  ASSERT_EQ(stat(templ, &st), 0);
  ASSERT_GT(st.st_size, 0u);

  Minidump minidump(templ);
  ASSERT_TRUE(minidump.Read());

  // Check that the main module filename is correct.
  MinidumpModuleList* module_list = minidump.GetModuleList();
  ASSERT_TRUE(module_list);
  const MinidumpModule* module = module_list->GetMainModule();
  EXPECT_STREQ(binpath, module->code_file().c_str());
  // Check that the file ID is correct.
  FileID fileid(helper_path.c_str());
  uint8_t identifier[sizeof(MDGUID)];
  EXPECT_TRUE(fileid.ElfFileIdentifier(identifier));
  char identifier_string[kGUIDStringSize];
  FileID::ConvertIdentifierToString(identifier,
                                    identifier_string,
                                    kGUIDStringSize);
  string module_identifier(identifier_string);
  // Strip out dashes
  while ((pos = module_identifier.find('-')) != string::npos) {
    module_identifier.erase(pos, 1);
  }
  // And append a zero, because module IDs include an "age" field
  // which is always zero on Linux.
  module_identifier += "0";
  EXPECT_EQ(module_identifier, module->debug_identifier());

  unlink(templ);
}
<|endoftext|>


<commit_before>/*

*/

#include<iostream>
#include<string>
#include<fstream>
#include"../include/HashTable.h"

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main(int argc, char* argv[])
{
	HashTable* hash = new HashTable(10);

	std::ifstream in_file;	//might actually be useless.
	in_file.open(argv[1]);
	if (in_file.is_open())
	{
		int rating, year, quantity;
		string title, buffer;
		while (!in_file.eof())
		{
			getline(in_file, buffer, ',');
			rating = stoi(buffer);
			getline(in_file, buffer, ',');
			title = buffer;
			getline(in_file, buffer, ',');
			year = stoi(buffer);
			getline(in_file, buffer);
			quantity = stoi(buffer);

		}
	}
	else
	{
		//nothing for now.
	}

	int select = 0;

	while (select != 6)
	{

		cout << "======Main Menu=====" << endl
			<< "1. Insert Movie" << endl
			<< "2. Delete Movie" << endl
			<< "3. Find Movie" << endl
			<< "4. Pritn Table of Contents" << endl
			<< "5. Quit" << endl;

		cin >> select;

		if (select == 1)	//Insert Movie
		{

		}

		if (select == 2)	//Delete Movie
		{

		}

		if (select == 3)	//Find Movie
		{

		}

		if (select == 4)	//Print Table of Contents
		{

		}

		if (select == 5)	//Quit
			cout << "Goodbye!" << endl;
		if (select > 5)
			cout << "---That was not an option.---\n\n";
	}

	return 0;
}<commit_msg>refined add, made hash table 53 in size, need to basically rewrite header file because I hate using ones provided. They don't agree with my ideas. Even though someone significantly more qualified made them. Granted, they also made the header file for the lowest common denominator... (-sincerely, my ego)<commit_after>/*
// Derek Prince
// Assignment 9
// Hashing Movies (Perfectly)
// Just kidding.
// Still hashing though.
//
*/

#ifndef H_TABLE_SIZE
#define H_TABLE_SIZE 53
#endif	//H_TABLE_SIZE

#include<iostream>
#include<string>
#include<fstream>
#include"../include/HashTable.h"

using std::cin;
using std::cout;
using std::endl;
using std::string;

int main(int argc, char* argv[])
{
	HashTable* hash = new HashTable(10);

	std::ifstream in_file;	//might actually be useless.
	in_file.open(argv[1]);
	if (in_file.is_open())
	{
		int year;
		string title, buffer;
		while (!in_file.eof())
		{
			getline(in_file, buffer, ',');	//rating - ditch
			getline(in_file, buffer, ',');
			title = buffer;
			getline(in_file, buffer, ',');
			year = stoi(buffer);
			getline(in_file, buffer);		//quantity - ditch

			//add movie or hash then add

		}
	}
	else
	{
		//nothing for now.
	}

	int select = 0;

	while (select != 6)
	{

		cout << "======Main Menu=====" << endl
			<< "1. Insert Movie" << endl
			<< "2. Delete Movie" << endl
			<< "3. Find Movie" << endl
			<< "4. Pritn Table of Contents" << endl
			<< "5. Quit" << endl;

		cin >> select;

		if (select == 1)	//Insert Movie
		{

		}

		if (select == 2)	//Delete Movie
		{

		}

		if (select == 3)	//Find Movie
		{

		}

		if (select == 4)	//Print Table of Contents
		{

		}

		if (select == 5)	//Quit
			cout << "Goodbye!" << endl;
		if (select > 5)
			cout << "---That was not an option.---\n\n";
	}

	return 0;
}<|endoftext|>


<commit_before><commit_msg>Use attrtype_t enumerations to Actor::getAttr<commit_after><|endoftext|>


<commit_before><commit_msg>check json parsing error in binpickingtaskzmq.cpp<commit_after><|endoftext|>


<commit_before><commit_msg>Connect to the server when you click the button. Added a hardcoded localhost button.<commit_after><|endoftext|>


<commit_before>#include <OpenSim/Tools/Array.h>
#include <OpenSim/Tools/Storage.h>
#include <OpenSim/SQP/rdFSQP.h>
#include <OpenSim/Simulation/SIMM/SimmIKTrialParams.h>
#include <OpenSim/Simulation/SIMM/SimmKinematicsEngine.h>
#include <OpenSim/Simulation/SIMM/SimmModel.h>
#include "SimmIKSolverImpl.h"
#include "SimmInverseKinematicsTarget.h"

using namespace OpenSim;
using namespace std;
//______________________________________________________________________________
/**
 * An implementation of the IKSolverInterface specific to simm classes/dynamicsEngine.
 *
 * @param aOptimizationTarget The target that IK will minimize
 * @param aIKParams Parameters specified in input file to control IK.
 */
SimmIKSolverImpl::
SimmIKSolverImpl(SimmInverseKinematicsTarget& aOptimizationTarget):
IKSolverInterface(aOptimizationTarget)
{
}
//______________________________________________________________________________
/**
 * This is the heart of the IK solver, this method solves a specific motion trial
 * given an input storage object for input, one for output.

 * @param aIKOptions Pass along to the method attributes specified by end-user in input file.
 * @param inputData Set of frames to solve packaged as a storage fle.
 * @param outputData the frames solved by the solver represented as a storage onbject.
 */
void SimmIKSolverImpl::solveFrames(const SimmIKTrialParams& aIKOptions, Storage& inputData, Storage& outputData)
{
	int i;

	// Instantiate the optimizer
	rdFSQP *optimizer = new rdFSQP(&_ikTarget);

	// Set optimization convergence criteria/tolerance
	// Enable some Debugging here if needed
	optimizer->setPrintLevel(0);
	optimizer->setConvergenceCriterion(1.0E-4);	// Error in markers of .01
	optimizer->setMaxIterations(1000);

	/* Get names for unconstrained Qs (ones that will be solved). */
	Array<const string*> unconstrainedCoordinateNames(NULL);
   _ikTarget.getUnconstrainedCoordinateNames(unconstrainedCoordinateNames);

	/* Get names for prescribed Qs (specified in input file). */
	Array<const string*> prescribedCoordinateNames(NULL);
   _ikTarget.getPrescribedCoordinateNames(prescribedCoordinateNames);

	/* Get names for markers used for solving. */
	Array<const string*> markerNames(NULL);
	_ikTarget.getOutputMarkerNames(markerNames);

	string resultsHeader = "time\t";
	for (i = 0; i < unconstrainedCoordinateNames.getSize(); i++)
	{
		resultsHeader += *(unconstrainedCoordinateNames[i]);
		resultsHeader += "\t";
	}

	for (i = 0; i < prescribedCoordinateNames.getSize(); i++)
	{
		resultsHeader += *(prescribedCoordinateNames[i]);
		resultsHeader += "\t";
	}

	string markerComponentNames[] = {"_px", "_py", "_pz"};
	// Include markers for visual verification in SIMM
	if (aIKOptions.getIncludeMarkers())
	{
		for (i = 0; i < markerNames.getSize(); i++)
		{
			for (int j = 0; j < 3; j++)
			{
				resultsHeader += *(markerNames[i]);
				resultsHeader += markerComponentNames[j];
				resultsHeader += "\t";
			}
		}
	}
	// User data (colummns that are in input storage file but not used by IK,
	// to be passed along for later processing.
	const Array<string> &inputColumnNames	 = inputData.getColumnLabelsArray();
	Array<int> userDataColumnIndices(0);
	string userHeaders;
	collectUserData(inputColumnNames, resultsHeader, userHeaders, userDataColumnIndices);
	resultsHeader += userHeaders;

	outputData.setColumnLabels(resultsHeader.c_str());

	// Set the lower and upper bounds on the unconstrained Q array
	// TODO: shouldn't have to search for coordinates by name
	SimmKinematicsEngine &eng = (SimmKinematicsEngine&)_ikTarget.getModel().getSimmKinematicsEngine();
	for (i = 0; i < unconstrainedCoordinateNames.getSize(); i++)
	{
		Coordinate* coord = eng.getCoordinate(*(unconstrainedCoordinateNames[i]));
		optimizer->setLowerBound(i, coord->getRangeMin());
		optimizer->setUpperBound(i, coord->getRangeMax());
	}

	// Main loop to set initial conditions and solve snapshots
	// At every step we use experimental data as a starting guess
	Array<double> unconstrainedQGuess(0.0, unconstrainedCoordinateNames.getSize());	// Initial guess and work array
	Array<double> unconstrainedQSol(0.0, unconstrainedCoordinateNames.getSize());	// Solution array
	Array<double> experimentalMarkerLocations(0.0, markerNames.getSize() * 3);

	int startFrame = 0, endFrame = 1;
	double currentTime;

	/* Get the indices of the starting frame and the ending frame,
	 * based on the user-defined start/end times stored in
	 * the simmIKTrialOptions.
	 */
	aIKOptions.findFrameRange(inputData, startFrame, endFrame);

	if (endFrame - startFrame > 1)
		cout << "Solving frames " << startFrame + 1 << " to " << endFrame + 1 << " (time = " <<
		aIKOptions.getStartTime() << " to " << aIKOptions.getEndTime() << ")" << endl;

	for (int index = startFrame; index <= endFrame; index++)
	{
		// Get time associated with index
		double timeT = inputData.getStateVector(index)->getTime();

		/* This sets the values of the prescribed coordinates, which
		 * are coordinates that are:
		 *   (a) specified in the input data, and
		 *   (b) locked at that specified value.
		 * These coordinates are not variables in the IK solving.
		 * If a coordinate is specified in the file but not
		 * locked, it is an unconstrained coordinate and it is
		 * variable in the IK solving.
		 */
		_ikTarget.setPrescribedCoordinates(index);

		// This sets the guess of unconstrained generalized coordinates
		// and marker data from recordedDataStorage
		_ikTarget.setIndexToSolve(index, &unconstrainedQGuess[0]);

		// Invoke optimization mechanism to solve for Qs
		int optimizerReturn = optimizer->computeOptimalControls(&unconstrainedQGuess[0], &unconstrainedQSol[0]);

		/* Output variables include unconstrained (solved) Qs... */
		Array<double> qsAndMarkersArray = unconstrainedQSol;

		/* ... then prescribed Qs... */
		Array<double> prescribedQValues(0.0);
		_ikTarget.getPrescribedQValues(prescribedQValues);
		qsAndMarkersArray.append(prescribedQValues);

		/* ... then, optionally, computed marker locations. */
		if (aIKOptions.getIncludeMarkers())
		{
			_ikTarget.getExperimentalMarkerLocations(experimentalMarkerLocations);
			qsAndMarkersArray.append(experimentalMarkerLocations);
		}

		inputData.getTime(index, currentTime);
		cout << "Solved frame " << index + 1 << " at time " << currentTime << ", Optimizer returned = " << optimizerReturn << endl;
		// Allocate new row (StateVector) and add it to ikStorage
		StateVector *nextDataRow = new StateVector();

		// Append user data to qsAndMarkersArray
		Array<double> dataRow(qsAndMarkersArray);
		appendUserData(dataRow, userDataColumnIndices, inputData.getStateVector(index));

		nextDataRow->setStates(timeT, dataRow.getSize(), &dataRow[0]);

		outputData.append(*nextDataRow);
	}

	delete optimizer;
}
//______________________________________________________________________________
/**
 * UserData is the set of columns that are not used directly by the IK problem (for example
 * ground reaction forces). This UserData needs to be carried along in IK.
 */
void SimmIKSolverImpl::collectUserData(const Array<string> &inputColumnLabels,
									   string& resultsHeader,
									   string& userHeaders,
									   Array<int>& userDataColumnIndices)
{
	// Find columns that are none of the above to append them to the end of the list
	int i;
	for(i=0; i< inputColumnLabels.getSize(); i++){
		string nextLabel = inputColumnLabels[i];
		// We'll find out if the column is already there by doing string search for
		// either \t$column or $column\t to account for substrings
		string searchString1(nextLabel+"\t");
		string searchString2("\t"+nextLabel);
		if (strstr(resultsHeader.c_str(), searchString1.c_str())==0 &&
			strstr(resultsHeader.c_str(), searchString2.c_str())==0 ){
			// Append to userHeaders
			userHeaders += nextLabel+"\t";
			// Keep track of indices to match data with labels
			userDataColumnIndices.append(i);

			// cout << "Column:" << nextLabel << " index" << i << endl;
		}
	}
}
//______________________________________________________________________________
/**
 * Companion helper function to (collectUserData) responsible for appending user columns
 * to outputRow.
 */
void SimmIKSolverImpl::appendUserData(Array<double>& outputRow, Array<int>& indices, StateVector* inputRow)
{
	int i;
	for(i=0; i< indices.getSize(); i++){
		double userValue=rdMath::NAN;
		int index = indices[i]-1;
		inputRow->getDataValue(index, userValue);
		outputRow.append(userValue);
	}
}
<commit_msg>Call IntegCallback and Analysis callbacks after each IK frame is solved.<commit_after>#include <OpenSim/Tools/Array.h>
#include <OpenSim/Tools/Storage.h>
#include <OpenSim/SQP/rdFSQP.h>
#include <OpenSim/Simulation/SIMM/SimmIKTrialParams.h>
#include <OpenSim/Simulation/SIMM/SimmKinematicsEngine.h>
#include <OpenSim/Simulation/SIMM/SimmModel.h>
#include <OpenSim/Simulation/Model/IntegCallbackSet.h>
#include <OpenSim/Simulation/Model/AnalysisSet.h>
#include "SimmIKSolverImpl.h"
#include "SimmInverseKinematicsTarget.h"

using namespace OpenSim;
using namespace std;
//______________________________________________________________________________
/**
 * An implementation of the IKSolverInterface specific to simm classes/dynamicsEngine.
 *
 * @param aOptimizationTarget The target that IK will minimize
 * @param aIKParams Parameters specified in input file to control IK.
 */
SimmIKSolverImpl::
SimmIKSolverImpl(SimmInverseKinematicsTarget& aOptimizationTarget):
IKSolverInterface(aOptimizationTarget)
{
}
//______________________________________________________________________________
/**
 * This is the heart of the IK solver, this method solves a specific motion trial
 * given an input storage object for input, one for output.

 * @param aIKOptions Pass along to the method attributes specified by end-user in input file.
 * @param inputData Set of frames to solve packaged as a storage fle.
 * @param outputData the frames solved by the solver represented as a storage onbject.
 */
void SimmIKSolverImpl::solveFrames(const SimmIKTrialParams& aIKOptions, Storage& inputData, Storage& outputData)
{
	int i;

	// Instantiate the optimizer
	rdFSQP *optimizer = new rdFSQP(&_ikTarget);

	// Set optimization convergence criteria/tolerance
	// Enable some Debugging here if needed
	optimizer->setPrintLevel(0);
	optimizer->setConvergenceCriterion(1.0E-4);	// Error in markers of .01
	optimizer->setMaxIterations(1000);

	/* Get names for unconstrained Qs (ones that will be solved). */
	Array<const string*> unconstrainedCoordinateNames(NULL);
   _ikTarget.getUnconstrainedCoordinateNames(unconstrainedCoordinateNames);

	/* Get names for prescribed Qs (specified in input file). */
	Array<const string*> prescribedCoordinateNames(NULL);
   _ikTarget.getPrescribedCoordinateNames(prescribedCoordinateNames);

	/* Get names for markers used for solving. */
	Array<const string*> markerNames(NULL);
	_ikTarget.getOutputMarkerNames(markerNames);

	string resultsHeader = "time\t";
	for (i = 0; i < unconstrainedCoordinateNames.getSize(); i++)
	{
		resultsHeader += *(unconstrainedCoordinateNames[i]);
		resultsHeader += "\t";
	}

	for (i = 0; i < prescribedCoordinateNames.getSize(); i++)
	{
		resultsHeader += *(prescribedCoordinateNames[i]);
		resultsHeader += "\t";
	}

	string markerComponentNames[] = {"_px", "_py", "_pz"};
	// Include markers for visual verification in SIMM
	if (aIKOptions.getIncludeMarkers())
	{
		for (i = 0; i < markerNames.getSize(); i++)
		{
			for (int j = 0; j < 3; j++)
			{
				resultsHeader += *(markerNames[i]);
				resultsHeader += markerComponentNames[j];
				resultsHeader += "\t";
			}
		}
	}
	// User data (colummns that are in input storage file but not used by IK,
	// to be passed along for later processing.
	const Array<string> &inputColumnNames	 = inputData.getColumnLabelsArray();
	Array<int> userDataColumnIndices(0);
	string userHeaders;
	collectUserData(inputColumnNames, resultsHeader, userHeaders, userDataColumnIndices);
	resultsHeader += userHeaders;

	outputData.setColumnLabels(resultsHeader.c_str());

	// Set the lower and upper bounds on the unconstrained Q array
	// TODO: shouldn't have to search for coordinates by name
	SimmKinematicsEngine &eng = (SimmKinematicsEngine&)_ikTarget.getModel().getSimmKinematicsEngine();
	for (i = 0; i < unconstrainedCoordinateNames.getSize(); i++)
	{
		Coordinate* coord = eng.getCoordinate(*(unconstrainedCoordinateNames[i]));
		optimizer->setLowerBound(i, coord->getRangeMin());
		optimizer->setUpperBound(i, coord->getRangeMax());
	}

	// Main loop to set initial conditions and solve snapshots
	// At every step we use experimental data as a starting guess
	Array<double> unconstrainedQGuess(0.0, unconstrainedCoordinateNames.getSize());	// Initial guess and work array
	Array<double> unconstrainedQSol(0.0, unconstrainedCoordinateNames.getSize());	// Solution array
	Array<double> experimentalMarkerLocations(0.0, markerNames.getSize() * 3);

	int startFrame = 0, endFrame = 1;
	double currentTime;

	/* Get the indices of the starting frame and the ending frame,
	 * based on the user-defined start/end times stored in
	 * the simmIKTrialOptions.
	 */
	aIKOptions.findFrameRange(inputData, startFrame, endFrame);

	if (endFrame - startFrame > 1)
		cout << "Solving frames " << startFrame + 1 << " to " << endFrame + 1 << " (time = " <<
		aIKOptions.getStartTime() << " to " << aIKOptions.getEndTime() << ")" << endl;

	for (int index = startFrame; index <= endFrame; index++)
	{
		// Get time associated with index
		double timeT = inputData.getStateVector(index)->getTime();

		/* This sets the values of the prescribed coordinates, which
		 * are coordinates that are:
		 *   (a) specified in the input data, and
		 *   (b) locked at that specified value.
		 * These coordinates are not variables in the IK solving.
		 * If a coordinate is specified in the file but not
		 * locked, it is an unconstrained coordinate and it is
		 * variable in the IK solving.
		 */
		_ikTarget.setPrescribedCoordinates(index);

		// This sets the guess of unconstrained generalized coordinates
		// and marker data from recordedDataStorage
		_ikTarget.setIndexToSolve(index, &unconstrainedQGuess[0]);

		// Invoke optimization mechanism to solve for Qs
		int optimizerReturn = optimizer->computeOptimalControls(&unconstrainedQGuess[0], &unconstrainedQSol[0]);

		/* Output variables include unconstrained (solved) Qs... */
		Array<double> qsAndMarkersArray = unconstrainedQSol;

		/* ... then prescribed Qs... */
		Array<double> prescribedQValues(0.0);
		_ikTarget.getPrescribedQValues(prescribedQValues);
		qsAndMarkersArray.append(prescribedQValues);

		/* ... then, optionally, computed marker locations. */
		if (aIKOptions.getIncludeMarkers())
		{
			_ikTarget.getExperimentalMarkerLocations(experimentalMarkerLocations);
			qsAndMarkersArray.append(experimentalMarkerLocations);
		}

		inputData.getTime(index, currentTime);
		cout << "Solved frame " << index + 1 << " at time " << currentTime << ", Optimizer returned = " << optimizerReturn << endl;

		// INTEGRATION CALLBACKS
		// TODO: pass callback a reasonable "dt" value
		double emptyX, emptyY;
		IntegCallbackSet *callbackSet = _ikTarget.getModel().getIntegCallbackSet();
		if(callbackSet!=NULL)
			callbackSet->step(&emptyX,&emptyY,index-startFrame-1,0,currentTime,&emptyX,&emptyY);

		// ANALYSES
		// TODO: pass callback a reasonable "dt" value
		AnalysisSet *analysisSet = _ikTarget.getModel().getAnalysisSet();
		if(analysisSet!=NULL)
			analysisSet->step(&emptyX,&emptyY,index-startFrame-1,0,currentTime,&emptyX,&emptyY);

		// Append user data to qsAndMarkersArray
		Array<double> dataRow(qsAndMarkersArray);
		appendUserData(dataRow, userDataColumnIndices, inputData.getStateVector(index));

		// Allocate new row (StateVector) and add it to outputData
		StateVector *nextDataRow = new StateVector();
		nextDataRow->setStates(timeT, dataRow.getSize(), &dataRow[0]);
		outputData.append(*nextDataRow);
	}

	delete optimizer;
}
//______________________________________________________________________________
/**
 * UserData is the set of columns that are not used directly by the IK problem (for example
 * ground reaction forces). This UserData needs to be carried along in IK.
 */
void SimmIKSolverImpl::collectUserData(const Array<string> &inputColumnLabels,
									   string& resultsHeader,
									   string& userHeaders,
									   Array<int>& userDataColumnIndices)
{
	// Find columns that are none of the above to append them to the end of the list
	int i;
	for(i=0; i< inputColumnLabels.getSize(); i++){
		string nextLabel = inputColumnLabels[i];
		// We'll find out if the column is already there by doing string search for
		// either \t$column or $column\t to account for substrings
		string searchString1(nextLabel+"\t");
		string searchString2("\t"+nextLabel);
		if (strstr(resultsHeader.c_str(), searchString1.c_str())==0 &&
			strstr(resultsHeader.c_str(), searchString2.c_str())==0 ){
			// Append to userHeaders
			userHeaders += nextLabel+"\t";
			// Keep track of indices to match data with labels
			userDataColumnIndices.append(i);

			// cout << "Column:" << nextLabel << " index" << i << endl;
		}
	}
}
//______________________________________________________________________________
/**
 * Companion helper function to (collectUserData) responsible for appending user columns
 * to outputRow.
 */
void SimmIKSolverImpl::appendUserData(Array<double>& outputRow, Array<int>& indices, StateVector* inputRow)
{
	int i;
	for(i=0; i< indices.getSize(); i++){
		double userValue=rdMath::NAN;
		int index = indices[i]-1;
		inputRow->getDataValue(index, userValue);
		outputRow.append(userValue);
	}
}
<|endoftext|>


<commit_before>//
// CVector_fwd.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2014 Rick Yang (rick68 at gmail dot com)
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

#ifndef EIGENJS_CVECTOR_FWD_HPP
#define EIGENJS_CVECTOR_FWD_HPP

#include <boost/config.hpp>

#include <eigen3/Eigen/Dense>

#include <complex>

namespace EigenJS {

BOOST_CONSTEXPR char cvector_class_name[] = "CVector";

template <
  typename ScalarType = double
, typename ValueType = Eigen::Matrix<
    std::complex<ScalarType>
  , Eigen::Dynamic
  , 1
  >
, const char* ClassName = cvector_class_name
> class CVector;

}  // namespace EigenJS

#endif  // EIGENJS_CVECTOR_FWD_HPP
<commit_msg>src: fixed a mistake<commit_after>//
// CVector_fwd.hpp
// ~~~~~~~~~~~~~~~
//
// Copyright (c) 2014 Rick Yang (rick68 at gmail dot com)
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
//

#ifndef EIGENJS_CVECTOR_FWD_HPP
#define EIGENJS_CVECTOR_FWD_HPP

#include <boost/config.hpp>

#include <eigen3/Eigen/Dense>

#include <complex>

namespace EigenJS {

BOOST_CONSTEXPR char cvector_class_name[] = "CVector";

template <
  typename ScalarType = double
, typename ValueType = Eigen::Matrix<
    std::complex<ScalarType>
  , 1
  , Eigen::Dynamic
  >
, const char* ClassName = cvector_class_name
> class CVector;

}  // namespace EigenJS

#endif  // EIGENJS_CVECTOR_FWD_HPP
<|endoftext|>


<commit_before>#include "dispatch_queue.h"

#include <thread>
#include <queue>

struct dispatch_queue_t::impl
{
    impl();
    static void dispatch_thread_proc(impl *self);

    std::queue< std::function< void() > > queue;
    std::mutex queue_mtx;
    std::condition_variable queue_cond;
    std::atomic< bool > quit;
    std::thread queue_thread;

    using queue_lock_t = std::unique_lock< decltype(queue_mtx) >;
};

void dispatch_queue_t::impl::dispatch_thread_proc(dispatch_queue_t::impl *self)
{
    using queue_size_t = decltype(self->queue)::size_type;

    while (self->quit == false)
    {
        queue_lock_t queue_lock(self->queue_mtx);
        queue_size_t n = self->queue.size();

        self->queue_cond.wait(queue_lock, [&self] { return self->queue.size() > 0; });

        for (queue_size_t i = 0; i < n; ++i) {
            auto dispatch_func = self->queue.front();
            self->queue.pop();

            queue_lock.unlock();
            dispatch_func();
            queue_lock.lock();
        }
    }
}

dispatch_queue_t::impl::impl()
    : quit(false)
    , queue_thread(&dispatch_thread_proc, this)
{
}

dispatch_queue_t::dispatch_queue_t()
    : m(new impl)
{
}

dispatch_queue_t::~dispatch_queue_t()
{
    dispatch_async([this] { m->quit = true; });
    m->queue_thread.join();
}

void dispatch_queue_t::dispatch_async(std::function< void() > func)
{
    impl::queue_lock_t queue_lock(m->queue_mtx);
    m->queue.push(func);
    m->queue_cond.notify_one();
}

void dispatch_queue_t::dispatch_sync(std::function< void() > func)
{
    std::mutex sync_mtx;
    impl::queue_lock_t sync_lock(sync_mtx);
    std::condition_variable sync_cond;
    auto completed = false;

    {
        impl::queue_lock_t queue_lock(m->queue_mtx);
        m->queue.push(func);
        m->queue.push([&]() {
            std::unique_lock< decltype(sync_mtx) > sync_cb_lock(sync_mtx);
            completed = true;
            sync_cond.notify_one();
        });

        m->queue_cond.notify_one();
    }

    sync_cond.wait(sync_lock, [&completed] { return completed; });
}

void dispatch_queue_t::dispatch_flush()
{
    dispatch_sync([]{});
}

<commit_msg>calculate n after queue_size > 0, remove parens for empty lambda<commit_after>#include "dispatch_queue.h"

#include <thread>
#include <queue>

struct dispatch_queue_t::impl
{
    impl();
    static void dispatch_thread_proc(impl *self);

    std::queue< std::function< void() > > queue;
    std::mutex queue_mtx;
    std::condition_variable queue_cond;
    std::atomic< bool > quit;
    std::thread queue_thread;

    using queue_lock_t = std::unique_lock< decltype(queue_mtx) >;
};

void dispatch_queue_t::impl::dispatch_thread_proc(dispatch_queue_t::impl *self)
{
    using queue_size_t = decltype(self->queue)::size_type;

    while (self->quit == false)
    {
        queue_lock_t queue_lock(self->queue_mtx);
        self->queue_cond.wait(queue_lock, [&self] { return self->queue.size() > 0; });

        queue_size_t n = self->queue.size();

        for (queue_size_t i = 0; i < n; ++i) {
            auto dispatch_func = self->queue.front();
            self->queue.pop();

            queue_lock.unlock();
            dispatch_func();
            queue_lock.lock();
        }
    }
}

dispatch_queue_t::impl::impl()
    : quit(false)
    , queue_thread(&dispatch_thread_proc, this)
{
}

dispatch_queue_t::dispatch_queue_t()
    : m(new impl)
{
}

dispatch_queue_t::~dispatch_queue_t()
{
    dispatch_async([this] { m->quit = true; });
    m->queue_thread.join();
}

void dispatch_queue_t::dispatch_async(std::function< void() > func)
{
    impl::queue_lock_t queue_lock(m->queue_mtx);
    m->queue.push(func);
    m->queue_cond.notify_one();
}

void dispatch_queue_t::dispatch_sync(std::function< void() > func)
{
    std::mutex sync_mtx;
    impl::queue_lock_t sync_lock(sync_mtx);
    std::condition_variable sync_cond;
    auto completed = false;

    {
        impl::queue_lock_t queue_lock(m->queue_mtx);
        m->queue.push(func);
        m->queue.push([&] {
            std::unique_lock< decltype(sync_mtx) > sync_cb_lock(sync_mtx);
            completed = true;
            sync_cond.notify_one();
        });

        m->queue_cond.notify_one();
    }

    sync_cond.wait(sync_lock, [&completed] { return completed; });
}

void dispatch_queue_t::dispatch_flush()
{
    dispatch_sync([]{});
}

<|endoftext|>


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

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "ImageStackDialog.h"

#include "ui_ImageStackDialog.h"

#include "LoadStackReaction.h"

#include <QDropEvent>
#include <QFileDialog>
#include <QFileInfo>
#include <QMimeData>

#include <algorithm>
#include <chrono>
#include <thread>

#include <vtkImageData.h>
#include <vtkNew.h>
#include <vtkTIFFReader.h>

extern "C" {
#include "vtk_tiff.h"
}

namespace tomviz {

ImageStackDialog::ImageStackDialog(QWidget* parent)
  : QDialog(parent), m_ui(new Ui::ImageStackDialog)
{
  m_ui->setupUi(this);
  m_ui->tableView->setModel(&m_tableModel);
  QObject::connect(this, &ImageStackDialog::summaryChanged, &m_tableModel,
                   &ImageStackModel::onFilesInfoChanged);

  QObject::connect(this, &ImageStackDialog::stackTypeChanged, &m_tableModel,
                   &ImageStackModel::onStackTypeChanged);

  QObject::connect(m_ui->openFile, &QPushButton::clicked, this,
                   &ImageStackDialog::onOpenFileClick);

  QObject::connect(m_ui->openFolder, &QPushButton::clicked, this,
                   &ImageStackDialog::onOpenFolderClick);

  QObject::connect(&m_tableModel, &ImageStackModel::toggledSelected, this,
                   &ImageStackDialog::onImageToggled);

  m_ui->loadedContainer->hide();
  m_ui->stackTypeCombo->setDisabled(true);
  m_ui->stackTypeCombo->insertItem(DataSource::DataSourceType::Volume,
                                   QString("Volume"));
  m_ui->stackTypeCombo->insertItem(DataSource::DataSourceType::TiltSeries,
                                   QString("Tilt Series"));

  // Due to an overloaded signal I am force to use static_cast here.
  QObject::connect(m_ui->stackTypeCombo, static_cast<void (QComboBox::*)(int)>(
                                           &QComboBox::currentIndexChanged),
                   this, &ImageStackDialog::onStackTypeChanged);

  setAcceptDrops(true);
}

ImageStackDialog::~ImageStackDialog() = default;

void ImageStackDialog::setStackSummary(const QList<ImageInfo>& summary,
                                       bool sort)
{
  m_summary = summary;
  if (sort) {
    std::sort(m_summary.begin(), m_summary.end(),
              [](const ImageInfo& a, const ImageInfo& b) -> bool {
                // Place the inconsistent images at the top, so the user will
                // notice them.
                if (a.consistent == b.consistent) {
                  return a.pos < b.pos;
                } else {
                  return !a.consistent;
                }
              });
  }
  emit summaryChanged(m_summary);
  m_ui->emptyContainer->hide();
  m_ui->loadedContainer->show();
  m_ui->stackTypeCombo->setEnabled(true);
  m_ui->tableView->resizeColumnsToContents();
  m_ui->tableView->horizontalHeader()->setSectionResizeMode(
    1, QHeaderView::Stretch);
  setAcceptDrops(false);
}

void ImageStackDialog::setStackType(const DataSource::DataSourceType& stackType)
{
  if (m_stackType != stackType) {
    m_stackType = stackType;
    emit stackTypeChanged(m_stackType);
    m_ui->stackTypeCombo->setCurrentIndex(m_stackType);
  }
}

void ImageStackDialog::onOpenFileClick()
{
  openFileDialog(QFileDialog::ExistingFiles);
}

void ImageStackDialog::onOpenFolderClick()
{
  openFileDialog(QFileDialog::Directory);
}

void ImageStackDialog::openFileDialog(int mode)
{
  QStringList filters;
  filters << "TIFF Image files (*.tiff *.tif)";

  QFileDialog dialog(nullptr);
  if (mode == QFileDialog::ExistingFiles) {
    dialog.setFileMode(QFileDialog::ExistingFiles);
    dialog.setNameFilters(filters);
  } else if (mode == QFileDialog::Directory) {
    dialog.setFileMode(QFileDialog::Directory);
    dialog.setOption(QFileDialog::ShowDirsOnly, true);
  }

  if (dialog.exec()) {
    QStringList fileNames;
    if (mode == QFileDialog::ExistingFiles) {
      processFiles(dialog.selectedFiles());
    } else if (mode == QFileDialog::Directory) {
      processDirectory(dialog.selectedFiles()[0]);
    }
  }
}

void ImageStackDialog::processDirectory(const QString& path)
{
  QStringList fileNames;
  QDir directory(path);
  foreach (auto file, directory.entryList(QDir::Files)) {
    fileNames << directory.absolutePath() + QDir::separator() + file;
  }
  processFiles(fileNames);
}

void ImageStackDialog::processFiles(const QStringList& fileNames)
{
  QStringList fNames;
  foreach (auto file, fileNames) {
    if (file.endsWith(".tif") || file.endsWith(".tiff")) {
      fNames << file;
    }
  }
  QList<ImageInfo> summary = initStackSummary(fNames);

  bool isVolume = false;
  bool isTilt = false;
  bool isNumbered = false;
  DataSource::DataSourceType stackType = DataSource::DataSourceType::Volume;

  isVolume = detectVolume(fNames, summary);
  if (!isVolume) {
    isTilt = detectTilt(fNames, summary);
    if (isTilt) {
      stackType = DataSource::DataSourceType::TiltSeries;
    } else {
      isNumbered = detectVolume(fNames, summary, false);
      if (!isNumbered) {
        defaultOrder(fNames, summary);
      }
    }
  }
  setStackType(stackType);

  auto readImage = [this](QStringList files, int me, int n,
                          QList<ImageInfo>* s) {
    for (auto i = me; i < files.size(); i += n) {
      uint32_t w;
      uint32_t h;
      TIFF* tif = TIFFOpen(files[i].toLatin1().data(), "r");
      TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
      TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
      TIFFClose(tif);
      (*s)[i].m = w;
      (*s)[i].n = h;
    }
  };

  const unsigned int minCores = 1;
  const unsigned int nCores =
    std::max(std::thread::hardware_concurrency(), minCores);
  const unsigned int maxThreads = 8;
  const unsigned int nThreads = std::min(nCores, maxThreads);
  std::vector<std::thread> threads(nThreads);

  for (unsigned int i = 0; i < nThreads; ++i) {
    threads[i] = std::thread(readImage, fNames, i, nThreads, &summary);
  }

  for (unsigned int i = 0; i < nThreads; ++i) {
    threads[i].join();
  }

  // check consistency
  if (summary.size() > 0) {
    const auto m = summary[0].m;
    const auto n = summary[1].n;
    for (auto i = 0; i < summary.size(); ++i) {
      if (summary[i].m == m && summary[i].n == n) {
        summary[i].consistent = true;
        summary[i].selected = true;
      }
    }
  }

  setStackSummary(summary, true);
}

bool ImageStackDialog::detectVolume(QStringList fileNames,
                                    QList<ImageInfo>& summary, bool matchPrefix)
{
  if (fileNames.size() < 1) {
    return false;
  }
  QString thePrefix;
  QString prefix;
  int num;
  QRegExp volRegExp("^(.*[^\\d]{1})(\\d+)(\\.(tif|tiff))$");

  for (int i = 0; i < fileNames.size(); ++i) {
    if (volRegExp.exactMatch(fileNames[i])) {
      prefix = volRegExp.cap(1);
      if (i == 0) {
        thePrefix = prefix;
      }
      if (prefix == thePrefix || !matchPrefix) {
        num = volRegExp.cap(2).toInt();
        summary[i].pos = num;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
  return true;
}

bool ImageStackDialog::detectTilt(QStringList fileNames,
                                  QList<ImageInfo>& summary, bool matchPrefix)
{
  if (fileNames.size() < 1) {
    return false;
  }
  QString thePrefix;
  QString prefix;
  int num;
  QString sign;
  QString numStr;
  QString ext;

  QRegExp tiltRegExp("^.*([p+]|[n-])?(\\d+)(\\.(tif|tiff))$");

  for (int i = 0; i < fileNames.size(); ++i) {
    if (tiltRegExp.exactMatch(fileNames[i])) {
      sign = tiltRegExp.cap(1);
      numStr = tiltRegExp.cap(2);
      ext = tiltRegExp.cap(3);
      prefix = fileNames[i];
      prefix.replace(sign + numStr + ext, QString());
      if (i == 0) {
        thePrefix = prefix;
      }
      if (prefix == thePrefix || !matchPrefix) {
        if (sign == "p") {
          sign = "+";
        } else if (sign == "n") {
          sign = "-";
        }
        num = (sign + numStr).toInt();
        summary[i].pos = num;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
  return true;
}

void ImageStackDialog::defaultOrder(QStringList fileNames,
                                    QList<ImageInfo>& summary)
{
  if (fileNames.size() != summary.size()) {
    return;
  }
  for (int i = 0; i < fileNames.size(); ++i) {
    summary[i].pos = i;
  }
}

void ImageStackDialog::dragEnterEvent(QDragEnterEvent* event)
{
  if (event->mimeData()->hasUrls()) {
    event->acceptProposedAction();
  }
}

void ImageStackDialog::dropEvent(QDropEvent* event)
{
  if (event->mimeData()->hasUrls()) {
    QStringList pathList;
    QString path;
    QList<QUrl> urlList = event->mimeData()->urls();
    bool openDirs = true;
    for (int i = 0; i < urlList.size(); ++i) {
      path = urlList.at(i).toLocalFile();
      QFileInfo fileInfo(path);
      if (fileInfo.exists()) {
        if (fileInfo.isDir() && openDirs) {
          processDirectory(path);
          return;
        } else if (fileInfo.isFile()) {
          pathList.append(path);
        }
        // only open the first directory being dropped
        openDirs = false;
      }
    }
    processFiles(pathList);
  }
}

QList<ImageInfo> ImageStackDialog::initStackSummary(
  const QStringList& fileNames)
{
  QList<ImageInfo> summary;
  int n = -1;
  int m = -1;
  bool consistent = false;
  foreach (QString file, fileNames) {
    summary.push_back(ImageInfo(file, 0, m, n, consistent));
  }
  return summary;
}

QList<ImageInfo> ImageStackDialog::getStackSummary() const
{
  return m_summary;
}

DataSource::DataSourceType ImageStackDialog::getStackType() const
{
  return m_stackType;
}

void ImageStackDialog::onImageToggled(int row, bool value)
{
  m_summary[row].selected = value;
  emit summaryChanged(m_summary);
}

void ImageStackDialog::onStackTypeChanged(int stackType)
{
  if (stackType == DataSource::DataSourceType::Volume) {
    setStackType(DataSource::DataSourceType::Volume);
  } else if (stackType == DataSource::DataSourceType::TiltSeries) {
    setStackType(DataSource::DataSourceType::TiltSeries);
  }
}

} // namespace tomviz
<commit_msg>Suppress libTiff warning output<commit_after>/******************************************************************************

  This source file is part of the tomviz project.

  Copyright Kitware, Inc.

  This source code is released under the New BSD License, (the "License").

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

******************************************************************************/

#include "ImageStackDialog.h"

#include "ui_ImageStackDialog.h"

#include "LoadStackReaction.h"

#include <QDropEvent>
#include <QFileDialog>
#include <QFileInfo>
#include <QMimeData>

#include <algorithm>
#include <chrono>
#include <thread>

#include <vtkImageData.h>
#include <vtkNew.h>
#include <vtkTIFFReader.h>

extern "C" {
#include "vtk_tiff.h"
}

namespace tomviz {

ImageStackDialog::ImageStackDialog(QWidget* parent)
  : QDialog(parent), m_ui(new Ui::ImageStackDialog)
{
  m_ui->setupUi(this);
  m_ui->tableView->setModel(&m_tableModel);
  QObject::connect(this, &ImageStackDialog::summaryChanged, &m_tableModel,
                   &ImageStackModel::onFilesInfoChanged);

  QObject::connect(this, &ImageStackDialog::stackTypeChanged, &m_tableModel,
                   &ImageStackModel::onStackTypeChanged);

  QObject::connect(m_ui->openFile, &QPushButton::clicked, this,
                   &ImageStackDialog::onOpenFileClick);

  QObject::connect(m_ui->openFolder, &QPushButton::clicked, this,
                   &ImageStackDialog::onOpenFolderClick);

  QObject::connect(&m_tableModel, &ImageStackModel::toggledSelected, this,
                   &ImageStackDialog::onImageToggled);

  m_ui->loadedContainer->hide();
  m_ui->stackTypeCombo->setDisabled(true);
  m_ui->stackTypeCombo->insertItem(DataSource::DataSourceType::Volume,
                                   QString("Volume"));
  m_ui->stackTypeCombo->insertItem(DataSource::DataSourceType::TiltSeries,
                                   QString("Tilt Series"));

  // Due to an overloaded signal I am force to use static_cast here.
  QObject::connect(m_ui->stackTypeCombo, static_cast<void (QComboBox::*)(int)>(
                                           &QComboBox::currentIndexChanged),
                   this, &ImageStackDialog::onStackTypeChanged);

  setAcceptDrops(true);
}

ImageStackDialog::~ImageStackDialog() = default;

void ImageStackDialog::setStackSummary(const QList<ImageInfo>& summary,
                                       bool sort)
{
  m_summary = summary;
  if (sort) {
    std::sort(m_summary.begin(), m_summary.end(),
              [](const ImageInfo& a, const ImageInfo& b) -> bool {
                // Place the inconsistent images at the top, so the user will
                // notice them.
                if (a.consistent == b.consistent) {
                  return a.pos < b.pos;
                } else {
                  return !a.consistent;
                }
              });
  }
  emit summaryChanged(m_summary);
  m_ui->emptyContainer->hide();
  m_ui->loadedContainer->show();
  m_ui->stackTypeCombo->setEnabled(true);
  m_ui->tableView->resizeColumnsToContents();
  m_ui->tableView->horizontalHeader()->setSectionResizeMode(
    1, QHeaderView::Stretch);
  setAcceptDrops(false);
}

void ImageStackDialog::setStackType(const DataSource::DataSourceType& stackType)
{
  if (m_stackType != stackType) {
    m_stackType = stackType;
    emit stackTypeChanged(m_stackType);
    m_ui->stackTypeCombo->setCurrentIndex(m_stackType);
  }
}

void ImageStackDialog::onOpenFileClick()
{
  openFileDialog(QFileDialog::ExistingFiles);
}

void ImageStackDialog::onOpenFolderClick()
{
  openFileDialog(QFileDialog::Directory);
}

void ImageStackDialog::openFileDialog(int mode)
{
  QStringList filters;
  filters << "TIFF Image files (*.tiff *.tif)";

  QFileDialog dialog(nullptr);
  if (mode == QFileDialog::ExistingFiles) {
    dialog.setFileMode(QFileDialog::ExistingFiles);
    dialog.setNameFilters(filters);
  } else if (mode == QFileDialog::Directory) {
    dialog.setFileMode(QFileDialog::Directory);
    dialog.setOption(QFileDialog::ShowDirsOnly, true);
  }

  if (dialog.exec()) {
    QStringList fileNames;
    if (mode == QFileDialog::ExistingFiles) {
      processFiles(dialog.selectedFiles());
    } else if (mode == QFileDialog::Directory) {
      processDirectory(dialog.selectedFiles()[0]);
    }
  }
}

void ImageStackDialog::processDirectory(const QString& path)
{
  QStringList fileNames;
  QDir directory(path);
  foreach (auto file, directory.entryList(QDir::Files)) {
    fileNames << directory.absolutePath() + QDir::separator() + file;
  }
  processFiles(fileNames);
}

void ImageStackDialog::processFiles(const QStringList& fileNames)
{
  QStringList fNames;
  foreach (auto file, fileNames) {
    if (file.endsWith(".tif") || file.endsWith(".tiff")) {
      fNames << file;
    }
  }
  QList<ImageInfo> summary = initStackSummary(fNames);

  bool isVolume = false;
  bool isTilt = false;
  bool isNumbered = false;
  DataSource::DataSourceType stackType = DataSource::DataSourceType::Volume;

  isVolume = detectVolume(fNames, summary);
  if (!isVolume) {
    isTilt = detectTilt(fNames, summary);
    if (isTilt) {
      stackType = DataSource::DataSourceType::TiltSeries;
    } else {
      isNumbered = detectVolume(fNames, summary, false);
      if (!isNumbered) {
        defaultOrder(fNames, summary);
      }
    }
  }
  setStackType(stackType);

  auto readImage = [this](QStringList files, int me, int n,
                          QList<ImageInfo>* s) {
    TIFFSetWarningHandler(nullptr);
    for (auto i = me; i < files.size(); i += n) {
      uint32_t w = -1;
      uint32_t h = -1;
      TIFF* tif = TIFFOpen(files[i].toLatin1().data(), "r");
      if (tif) {
        TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &w);
        TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &h);
        TIFFClose(tif);
      }
      (*s)[i].m = w;
      (*s)[i].n = h;
    }
  };

  const unsigned int minCores = 1;
  const unsigned int nCores =
    std::max(std::thread::hardware_concurrency(), minCores);
  const unsigned int maxThreads = 4;
  const unsigned int nThreads = std::min(nCores, maxThreads);
  std::vector<std::thread> threads(nThreads);

  for (unsigned int i = 0; i < nThreads; ++i) {
    threads[i] = std::thread(readImage, fNames, i, nThreads, &summary);
  }

  for (unsigned int i = 0; i < nThreads; ++i) {
    threads[i].join();
  }

  // check consistency
  if (summary.size() > 0) {
    const auto m = summary[0].m;
    const auto n = summary[1].n;
    for (auto i = 0; i < summary.size(); ++i) {
      if (summary[i].m == m && summary[i].n == n) {
        summary[i].consistent = true;
        summary[i].selected = true;
      }
    }
  }

  setStackSummary(summary, true);
}

bool ImageStackDialog::detectVolume(QStringList fileNames,
                                    QList<ImageInfo>& summary, bool matchPrefix)
{
  if (fileNames.size() < 1) {
    return false;
  }
  QString thePrefix;
  QString prefix;
  int num;
  QRegExp volRegExp("^(.*[^\\d]{1})(\\d+)(\\.(tif|tiff))$");

  for (int i = 0; i < fileNames.size(); ++i) {
    if (volRegExp.exactMatch(fileNames[i])) {
      prefix = volRegExp.cap(1);
      if (i == 0) {
        thePrefix = prefix;
      }
      if (prefix == thePrefix || !matchPrefix) {
        num = volRegExp.cap(2).toInt();
        summary[i].pos = num;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
  return true;
}

bool ImageStackDialog::detectTilt(QStringList fileNames,
                                  QList<ImageInfo>& summary, bool matchPrefix)
{
  if (fileNames.size() < 1) {
    return false;
  }
  QString thePrefix;
  QString prefix;
  int num;
  QString sign;
  QString numStr;
  QString ext;

  QRegExp tiltRegExp("^.*([p+]|[n-])?(\\d+)(\\.(tif|tiff))$");

  for (int i = 0; i < fileNames.size(); ++i) {
    if (tiltRegExp.exactMatch(fileNames[i])) {
      sign = tiltRegExp.cap(1);
      numStr = tiltRegExp.cap(2);
      ext = tiltRegExp.cap(3);
      prefix = fileNames[i];
      prefix.replace(sign + numStr + ext, QString());
      if (i == 0) {
        thePrefix = prefix;
      }
      if (prefix == thePrefix || !matchPrefix) {
        if (sign == "p") {
          sign = "+";
        } else if (sign == "n") {
          sign = "-";
        }
        num = (sign + numStr).toInt();
        summary[i].pos = num;
      } else {
        return false;
      }
    } else {
      return false;
    }
  }
  return true;
}

void ImageStackDialog::defaultOrder(QStringList fileNames,
                                    QList<ImageInfo>& summary)
{
  if (fileNames.size() != summary.size()) {
    return;
  }
  for (int i = 0; i < fileNames.size(); ++i) {
    summary[i].pos = i;
  }
}

void ImageStackDialog::dragEnterEvent(QDragEnterEvent* event)
{
  if (event->mimeData()->hasUrls()) {
    event->acceptProposedAction();
  }
}

void ImageStackDialog::dropEvent(QDropEvent* event)
{
  if (event->mimeData()->hasUrls()) {
    QStringList pathList;
    QString path;
    QList<QUrl> urlList = event->mimeData()->urls();
    bool openDirs = true;
    for (int i = 0; i < urlList.size(); ++i) {
      path = urlList.at(i).toLocalFile();
      QFileInfo fileInfo(path);
      if (fileInfo.exists()) {
        if (fileInfo.isDir() && openDirs) {
          processDirectory(path);
          return;
        } else if (fileInfo.isFile()) {
          pathList.append(path);
        }
        // only open the first directory being dropped
        openDirs = false;
      }
    }
    processFiles(pathList);
  }
}

QList<ImageInfo> ImageStackDialog::initStackSummary(
  const QStringList& fileNames)
{
  QList<ImageInfo> summary;
  int n = -1;
  int m = -1;
  bool consistent = false;
  foreach (QString file, fileNames) {
    summary.push_back(ImageInfo(file, 0, m, n, consistent));
  }
  return summary;
}

QList<ImageInfo> ImageStackDialog::getStackSummary() const
{
  return m_summary;
}

DataSource::DataSourceType ImageStackDialog::getStackType() const
{
  return m_stackType;
}

void ImageStackDialog::onImageToggled(int row, bool value)
{
  m_summary[row].selected = value;
  emit summaryChanged(m_summary);
}

void ImageStackDialog::onStackTypeChanged(int stackType)
{
  if (stackType == DataSource::DataSourceType::Volume) {
    setStackType(DataSource::DataSourceType::Volume);
  } else if (stackType == DataSource::DataSourceType::TiltSeries) {
    setStackType(DataSource::DataSourceType::TiltSeries);
  }
}

} // namespace tomviz
<|endoftext|>


<commit_before>/// Simple sockets buffer output client test
/// This test cover if simple socket client can send message to a boost based
/// server application.

#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <thread>
#include <memory>
#include <list>
#include <assert.h>
#include <sstream>

using boost::asio::ip::tcp;

size_t bytesReaded;
std::string message;
std::string expectedMessage = "I'm here!";
boost::system::error_code error;

/// Server side, boost pure implementation
/**
 * Open port listening for a connection,
 * when someone connects waits for a message.
 */
void server(void) {
	boost::asio::io_service io_service;

	const unsigned short port = 12345;
	tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port));

	tcp::socket socket(io_service);
	acceptor.accept(socket);

	std::array<char, 100> buffer;

	bytesReaded = socket.read_some(
			boost::asio::buffer(buffer.data(), buffer.size()),
			error);
	message = std::string(buffer.begin(), buffer.begin() + bytesReaded);
}

#include "../../src/Socket.hpp"
#include <ostream>

/// Client side using simple sockets
/**
 * Connect to server and send a message.
 */
void client(void) {
	using namespace simple;

	SocketBuffer buffer("localhost", 12345);
	std::ostream out(&buffer);

	out << expectedMessage << std::endl;
}

#include <thread>

/// Main test
/**
 * Start server take a while and start client.
 * Then test if communication is ok.
 */
int main(void) {
	std::thread serverRun(server);
	std::this_thread::sleep_for(std::chrono::milliseconds(100));
	client();
	serverRun.join();

	assert(error == 0);
	assert(bytesReaded == expectedMessage.size() + 1);
	assert(message == expectedMessage + "\n");

	return 0;
}
<commit_msg>Fix output client test<commit_after>/// Simple sockets buffer output client test
/// This test cover if simple socket client can send message to a boost based
/// server application.

#include <string>
#include <iostream>
#include <boost/asio.hpp>
#include <thread>
#include <memory>
#include <list>
#include <assert.h>
#include <sstream>

using boost::asio::ip::tcp;

size_t bytesReaded;
std::string message;
std::string expectedMessage = "I'm here!";
boost::system::error_code error;

/// Server side, boost pure implementation
/**
 * Open port listening for a connection,
 * when someone connects waits for a message.
 */
void server(void) {
	boost::asio::io_service io_service;

	const unsigned short port = 12345;
	tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), port));

	tcp::socket socket(io_service);
	acceptor.accept(socket);

	std::array<char, 100> buffer;

	bytesReaded = socket.read_some(
			boost::asio::buffer(buffer.data(), buffer.size()),
			error);
	message = std::string(buffer.begin(), buffer.begin() + bytesReaded);
}

#include "../../src/SocketBuffer.hpp"
#include <ostream>

/// Client side using simple sockets
/**
 * Connect to server and send a message.
 */
void client(void) {
	using namespace simple;

	SocketBuffer buffer("localhost", 12345);
	std::ostream out(&buffer);

	out << expectedMessage << std::endl;
}

#include <thread>

/// Main test
/**
 * Start server take a while and start client.
 * Then test if communication is ok.
 */
int main(void) {
	std::thread serverRun(server);
	std::this_thread::sleep_for(std::chrono::milliseconds(100));
	client();
	serverRun.join();

	assert(error == 0);
	assert(bytesReaded == expectedMessage.size() + 1);
	assert(message == expectedMessage + "\n");

	return 0;
}
<|endoftext|>


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

#include <CommandLine.hpp>

void processCommandLineOptions(isa::utils::ArgumentList & argumentList, Options & options, DeviceOptions & deviceOptions, DataOptions & dataOptions, KernelConfigurations & kernelConfigurations, GeneratorOptions & generatorOptions, AstroData::Observation & observation) {
  try {
    options.debug = argumentList.getSwitch("-debug");
    options.print = argumentList.getSwitch("-print");
    options.splitBatchesDedispersion = argumentList.getSwitch("-splitbatches_dedispersion");
    options.subbandDedispersion = argumentList.getSwitch("-subband_dedispersion");
    options.compactResults = argumentList.getSwitch("-compact_results");
    options.threshold = argumentList.getSwitchArgument<float>("-threshold");
    deviceOptions.platformID = argumentList.getSwitchArgument<unsigned int>("-opencl_platform");
    deviceOptions.deviceID = argumentList.getSwitchArgument<unsigned int>("-opencl_device");
    deviceOptions.deviceName = argumentList.getSwitchArgument<std::string>("-device_name");
    deviceOptions.synchronized = argumentList.getSwitch("-sync");
    AstroData::readPaddingConf(deviceOptions.padding, argumentList.getSwitchArgument<std::string>("-padding_file"));
    dataOptions.dataLOFAR = argumentList.getSwitch("-lofar");
#ifndef HAVE_HDF5
    if (dataOptions.dataLOFAR) {
      std::cerr << "Not compiled with HDF5 support." << std::endl;
      throw std::exception();
    };
#endif // HAVE_HDF5
    dataOptions.dataPSRDADA = argumentList.getSwitch("-dada");
#ifndef HAVE_PSRDADA
    if (dataOptions.dataPSRDADA) {
      std::cerr << "Not compiled with PSRDADA support." << std::endl;
      throw std::exception();
    };
#endif // HAVE_PSRDADA
    dataOptions.dataSIGPROC = argumentList.getSwitch("-sigproc");
    if ( !((((!(dataOptions.dataLOFAR && dataOptions.dataSIGPROC) && dataOptions.dataPSRDADA)
        || (!(dataOptions.dataLOFAR && dataOptions.dataPSRDADA) && dataOptions.dataSIGPROC))
        || (!(dataOptions.dataSIGPROC && dataOptions.dataPSRDADA) && dataOptions.dataLOFAR))
        || ((!dataOptions.dataLOFAR && !dataOptions.dataSIGPROC) && !dataOptions.dataPSRDADA)) ) {
      std::cerr << "-lofar -sigproc and -dada are mutually exclusive." << std::endl;
      throw std::exception();
    }
    dataOptions.channelsFile = argumentList.getSwitchArgument<std::string>("-zapped_channels");
    dataOptions.integrationFile = argumentList.getSwitchArgument<std::string>("-integration_steps");
    if ( !options.subbandDedispersion ) {
      Dedispersion::readTunedDedispersionConf(kernelConfigurations.dedispersionSingleStepParameters,
                                              argumentList.getSwitchArgument<std::string>("-dedispersion_file"));
    } else {
      Dedispersion::readTunedDedispersionConf(kernelConfigurations.dedispersionStepOneParameters,
                                              argumentList.getSwitchArgument<std::string>("-dedispersion_stepone_file"));
      Dedispersion::readTunedDedispersionConf(kernelConfigurations.dedispersionStepTwoParameters,
                                              argumentList.getSwitchArgument<std::string>("-dedispersion_steptwo_file"));
    }
    Integration::readTunedIntegrationConf(kernelConfigurations.integrationParameters,
                                          argumentList.getSwitchArgument<std::string>("-integration_file"));
    SNR::readTunedSNRConf(kernelConfigurations.snrParameters, argumentList.getSwitchArgument<std::string>("-snr_file"));
    if ( dataOptions.dataLOFAR ) {
#ifdef HAVE_HDF5
      observation.setNrBeams(1);
      observation.setNrSynthesizedBeams(1);
      dataOptions.headerFile = argumentList.getSwitchArgument<std::string>("-header");
      dataOptions.dataFile = argumentList.getSwitchArgument<std::string>("-data");
      dataOptions.limit = argumentList.getSwitch("-limit");
      if ( dataOptions.limit ) {
        observation.setNrBatches(argumentList.getSwitchArgument<unsigned int>("-batches"));
      }
#endif // HAVE_HDF5
    } else if ( dataOptions.dataSIGPROC ) {
      observation.setNrBeams(1);
      observation.setNrSynthesizedBeams(1);
      dataOptions.streamingMode = argumentList.getSwitch("-stream");
      dataOptions.headerSizeSIGPROC = argumentList.getSwitchArgument<unsigned int>("-header");
      dataOptions.dataFile = argumentList.getSwitchArgument<std::string>("-data");
      observation.setNrBatches(argumentList.getSwitchArgument<unsigned int>("-batches"));
      if ( options.subbandDedispersion ) {
        observation.setFrequencyRange(argumentList.getSwitchArgument<unsigned int>("-subbands"),
                                      argumentList.getSwitchArgument<unsigned int>("-channels"),
                                      argumentList.getSwitchArgument<float>("-min_freq"),
                                      argumentList.getSwitchArgument<float>("-channel_bandwidth"));
      } else {
        observation.setFrequencyRange(1, argumentList.getSwitchArgument<unsigned int>("-channels"),
                                      argumentList.getSwitchArgument<float>("-min_freq"),
                                      argumentList.getSwitchArgument<float>("-channel_bandwidth"));
      }
      observation.setNrSamplesPerBatch(argumentList.getSwitchArgument<unsigned int>("-samples"));
      observation.setSamplingTime(argumentList.getSwitchArgument<float>("-sampling_time"));
    } else if ( dataOptions.dataPSRDADA ) {
#ifdef HAVE_PSRDADA
      dataOptions.dadaKey = std::stoi("0x" + argumentList.getSwitchArgument<std::string>("-dada_key"), 0, 16);
      if ( options.subbandDedispersion ) {
        observation.setFrequencyRange(argumentList.getSwitchArgument<unsigned int>("-subbands"), 1, 1.0f, 1.0f);
      } else {
        observation.setFrequencyRange(1, 1, 1.0f, 1.0f);
      }
      observation.setNrBeams(argumentList.getSwitchArgument<unsigned int>("-beams"));
      observation.setNrSynthesizedBeams(argumentList.getSwitchArgument<unsigned int>("-synthesized_beams"));
      observation.setNrBatches(argumentList.getSwitchArgument<unsigned int>("-batches"));
#endif // HAVE_PSRDADA
    } else {
      observation.setNrBeams(argumentList.getSwitchArgument<unsigned int>("-beams"));
      observation.setNrSynthesizedBeams(argumentList.getSwitchArgument<unsigned int>("-synthesized_beams"));
      observation.setNrBatches(argumentList.getSwitchArgument<unsigned int>("-batches"));
      if ( options.subbandDedispersion ) {
        observation.setFrequencyRange(argumentList.getSwitchArgument<unsigned int>("-subbands"),
                                      argumentList.getSwitchArgument<unsigned int>("-channels"),
                                      argumentList.getSwitchArgument<float>("-min_freq"),
                                      argumentList.getSwitchArgument<float>("-channel_bandwidth"));
      } else {
        observation.setFrequencyRange(1, argumentList.getSwitchArgument<unsigned int>("-channels"),
                                      argumentList.getSwitchArgument<float>("-min_freq"),
                                      argumentList.getSwitchArgument<float>("-channel_bandwidth"));
      }
      observation.setNrSamplesPerBatch(argumentList.getSwitchArgument<unsigned int>("-samples"));
      observation.setSamplingTime(argumentList.getSwitchArgument<float>("-sampling_time"));
      generatorOptions.random = argumentList.getSwitch("-random");
      generatorOptions.width = argumentList.getSwitchArgument<unsigned int>("-width");
      generatorOptions.DM = argumentList.getSwitchArgument<float>("-dm");
    }
    dataOptions.outputFile = argumentList.getSwitchArgument<std::string>("-output");
    if ( options.subbandDedispersion ) {
      observation.setDMRange(argumentList.getSwitchArgument<unsigned int>("-subbanding_dms"),
                             argumentList.getSwitchArgument<float>("-subbanding_dm_first"),
                             argumentList.getSwitchArgument<float>("-subbanding_dm_step"), true);
    }
    observation.setDMRange(argumentList.getSwitchArgument<unsigned int>("-dms"),
                           argumentList.getSwitchArgument<float>("-dm_first"),
                           argumentList.getSwitchArgument<float>("-dm_step"));
  } catch ( isa::utils::EmptyCommandLine & err ) {
    usage(argumentList.getName());
    throw;
  } catch ( isa::utils::SwitchNotFound & err ) {
    std::cerr << err.what() << std::endl;
    throw;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    throw;
  }
}

void usage(std::string & program) {
  std::cerr << program << " -opencl_platform ... -opencl_device ... -device_name ... [-sync] -padding_file ...";
  std::cerr << "-zapped_channels ... -integration_steps ... -integration_file ... -snr_file ...";
  std::cerr << "[-splitbatches_dedispersion] [-subband_dedispersion] [-debug] [-print] [-compact_results] -output ...";
  std::cerr << "-dms ... -dm_first ... -dm_step ... -threshold ... [-sigproc]";
#ifdef HAVE_HDF5
  std::cerr << " [-lofar]";
#endif // HAVE_HDF5
#ifdef HAVE_PSRDADA
  std::cerr << " [-dada]";
#endif // HAVE_PSRDADA
  std::cerr << std::endl;
  std::cerr << "\tDedispersion: -dedispersion_file ..." << std::endl;
  std::cerr << "\tSubband Dedispersion: -subband_dedispersion -dedispersion_stepone_file ...";
  std::cerr << "-dedispersion_steptwo_file ... -subbands ... -subbanding_dms ... -subbanding_dm_first ...";
  std::cerr << "-subbanding_dm_step ..." << std::endl;
#ifdef HAVE_HDF5
  std::cerr << "\tLOFAR: -lofar -header ... -data ... [-limit]" << std::endl;
  std::cerr << "\t\t -limit -batches ..." << std::endl;
#endif // HAVE_HDF5
  std::cerr << "\tSIGPROC: -sigproc [-stream] -header ... -data ... -batches ... -channels ... -min_freq ...";
  std::cerr << "-channel_bandwidth ... -samples ... -sampling_time ..." << std::endl;
#ifdef HAVE_PSRDADA
  std::cerr << "\tPSRDADA: -dada -dada_key ... -beams ... -synthesized_beams ... -batches ..." << std::endl;
#endif // HAVE_PSRDADA
  std::cerr << "\t [-random] -width ... -dm ... -beams ... -synthesized_beams ... -batches ... -channels ...";
  std::cerr << "-min_freq ... -channel_bandwidth ... -samples ... -sampling_time ..." << std::endl;
}
<commit_msg>const qualifier in declarations and definitions.<commit_after>// Copyright 2017 Netherlands Institute for Radio Astronomy (ASTRON)
// Copyright 2017 Netherlands eScience Center
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include <CommandLine.hpp>

void processCommandLineOptions(const isa::utils::ArgumentList & argumentList, const Options & options, const DeviceOptions & deviceOptions, const DataOptions & dataOptions, const KernelConfigurations & kernelConfigurations, const GeneratorOptions & generatorOptions, const AstroData::Observation & observation) {
  try {
    options.debug = argumentList.getSwitch("-debug");
    options.print = argumentList.getSwitch("-print");
    options.splitBatchesDedispersion = argumentList.getSwitch("-splitbatches_dedispersion");
    options.subbandDedispersion = argumentList.getSwitch("-subband_dedispersion");
    options.compactResults = argumentList.getSwitch("-compact_results");
    options.threshold = argumentList.getSwitchArgument<float>("-threshold");
    deviceOptions.platformID = argumentList.getSwitchArgument<unsigned int>("-opencl_platform");
    deviceOptions.deviceID = argumentList.getSwitchArgument<unsigned int>("-opencl_device");
    deviceOptions.deviceName = argumentList.getSwitchArgument<std::string>("-device_name");
    deviceOptions.synchronized = argumentList.getSwitch("-sync");
    AstroData::readPaddingConf(deviceOptions.padding, argumentList.getSwitchArgument<std::string>("-padding_file"));
    dataOptions.dataLOFAR = argumentList.getSwitch("-lofar");
#ifndef HAVE_HDF5
    if (dataOptions.dataLOFAR) {
      std::cerr << "Not compiled with HDF5 support." << std::endl;
      throw std::exception();
    };
#endif // HAVE_HDF5
    dataOptions.dataPSRDADA = argumentList.getSwitch("-dada");
#ifndef HAVE_PSRDADA
    if (dataOptions.dataPSRDADA) {
      std::cerr << "Not compiled with PSRDADA support." << std::endl;
      throw std::exception();
    };
#endif // HAVE_PSRDADA
    dataOptions.dataSIGPROC = argumentList.getSwitch("-sigproc");
    if ( !((((!(dataOptions.dataLOFAR && dataOptions.dataSIGPROC) && dataOptions.dataPSRDADA)
        || (!(dataOptions.dataLOFAR && dataOptions.dataPSRDADA) && dataOptions.dataSIGPROC))
        || (!(dataOptions.dataSIGPROC && dataOptions.dataPSRDADA) && dataOptions.dataLOFAR))
        || ((!dataOptions.dataLOFAR && !dataOptions.dataSIGPROC) && !dataOptions.dataPSRDADA)) ) {
      std::cerr << "-lofar -sigproc and -dada are mutually exclusive." << std::endl;
      throw std::exception();
    }
    dataOptions.channelsFile = argumentList.getSwitchArgument<std::string>("-zapped_channels");
    dataOptions.integrationFile = argumentList.getSwitchArgument<std::string>("-integration_steps");
    if ( !options.subbandDedispersion ) {
      Dedispersion::readTunedDedispersionConf(kernelConfigurations.dedispersionSingleStepParameters,
                                              argumentList.getSwitchArgument<std::string>("-dedispersion_file"));
    } else {
      Dedispersion::readTunedDedispersionConf(kernelConfigurations.dedispersionStepOneParameters,
                                              argumentList.getSwitchArgument<std::string>("-dedispersion_stepone_file"));
      Dedispersion::readTunedDedispersionConf(kernelConfigurations.dedispersionStepTwoParameters,
                                              argumentList.getSwitchArgument<std::string>("-dedispersion_steptwo_file"));
    }
    Integration::readTunedIntegrationConf(kernelConfigurations.integrationParameters,
                                          argumentList.getSwitchArgument<std::string>("-integration_file"));
    SNR::readTunedSNRConf(kernelConfigurations.snrParameters, argumentList.getSwitchArgument<std::string>("-snr_file"));
    if ( dataOptions.dataLOFAR ) {
#ifdef HAVE_HDF5
      observation.setNrBeams(1);
      observation.setNrSynthesizedBeams(1);
      dataOptions.headerFile = argumentList.getSwitchArgument<std::string>("-header");
      dataOptions.dataFile = argumentList.getSwitchArgument<std::string>("-data");
      dataOptions.limit = argumentList.getSwitch("-limit");
      if ( dataOptions.limit ) {
        observation.setNrBatches(argumentList.getSwitchArgument<unsigned int>("-batches"));
      }
#endif // HAVE_HDF5
    } else if ( dataOptions.dataSIGPROC ) {
      observation.setNrBeams(1);
      observation.setNrSynthesizedBeams(1);
      dataOptions.streamingMode = argumentList.getSwitch("-stream");
      dataOptions.headerSizeSIGPROC = argumentList.getSwitchArgument<unsigned int>("-header");
      dataOptions.dataFile = argumentList.getSwitchArgument<std::string>("-data");
      observation.setNrBatches(argumentList.getSwitchArgument<unsigned int>("-batches"));
      if ( options.subbandDedispersion ) {
        observation.setFrequencyRange(argumentList.getSwitchArgument<unsigned int>("-subbands"),
                                      argumentList.getSwitchArgument<unsigned int>("-channels"),
                                      argumentList.getSwitchArgument<float>("-min_freq"),
                                      argumentList.getSwitchArgument<float>("-channel_bandwidth"));
      } else {
        observation.setFrequencyRange(1, argumentList.getSwitchArgument<unsigned int>("-channels"),
                                      argumentList.getSwitchArgument<float>("-min_freq"),
                                      argumentList.getSwitchArgument<float>("-channel_bandwidth"));
      }
      observation.setNrSamplesPerBatch(argumentList.getSwitchArgument<unsigned int>("-samples"));
      observation.setSamplingTime(argumentList.getSwitchArgument<float>("-sampling_time"));
    } else if ( dataOptions.dataPSRDADA ) {
#ifdef HAVE_PSRDADA
      dataOptions.dadaKey = std::stoi("0x" + argumentList.getSwitchArgument<std::string>("-dada_key"), 0, 16);
      if ( options.subbandDedispersion ) {
        observation.setFrequencyRange(argumentList.getSwitchArgument<unsigned int>("-subbands"), 1, 1.0f, 1.0f);
      } else {
        observation.setFrequencyRange(1, 1, 1.0f, 1.0f);
      }
      observation.setNrBeams(argumentList.getSwitchArgument<unsigned int>("-beams"));
      observation.setNrSynthesizedBeams(argumentList.getSwitchArgument<unsigned int>("-synthesized_beams"));
      observation.setNrBatches(argumentList.getSwitchArgument<unsigned int>("-batches"));
#endif // HAVE_PSRDADA
    } else {
      observation.setNrBeams(argumentList.getSwitchArgument<unsigned int>("-beams"));
      observation.setNrSynthesizedBeams(argumentList.getSwitchArgument<unsigned int>("-synthesized_beams"));
      observation.setNrBatches(argumentList.getSwitchArgument<unsigned int>("-batches"));
      if ( options.subbandDedispersion ) {
        observation.setFrequencyRange(argumentList.getSwitchArgument<unsigned int>("-subbands"),
                                      argumentList.getSwitchArgument<unsigned int>("-channels"),
                                      argumentList.getSwitchArgument<float>("-min_freq"),
                                      argumentList.getSwitchArgument<float>("-channel_bandwidth"));
      } else {
        observation.setFrequencyRange(1, argumentList.getSwitchArgument<unsigned int>("-channels"),
                                      argumentList.getSwitchArgument<float>("-min_freq"),
                                      argumentList.getSwitchArgument<float>("-channel_bandwidth"));
      }
      observation.setNrSamplesPerBatch(argumentList.getSwitchArgument<unsigned int>("-samples"));
      observation.setSamplingTime(argumentList.getSwitchArgument<float>("-sampling_time"));
      generatorOptions.random = argumentList.getSwitch("-random");
      generatorOptions.width = argumentList.getSwitchArgument<unsigned int>("-width");
      generatorOptions.DM = argumentList.getSwitchArgument<float>("-dm");
    }
    dataOptions.outputFile = argumentList.getSwitchArgument<std::string>("-output");
    if ( options.subbandDedispersion ) {
      observation.setDMRange(argumentList.getSwitchArgument<unsigned int>("-subbanding_dms"),
                             argumentList.getSwitchArgument<float>("-subbanding_dm_first"),
                             argumentList.getSwitchArgument<float>("-subbanding_dm_step"), true);
    }
    observation.setDMRange(argumentList.getSwitchArgument<unsigned int>("-dms"),
                           argumentList.getSwitchArgument<float>("-dm_first"),
                           argumentList.getSwitchArgument<float>("-dm_step"));
  } catch ( isa::utils::EmptyCommandLine & err ) {
    usage(argumentList.getName());
    throw;
  } catch ( isa::utils::SwitchNotFound & err ) {
    std::cerr << err.what() << std::endl;
    throw;
  } catch ( std::exception & err ) {
    std::cerr << err.what() << std::endl;
    throw;
  }
}

void usage(const std::string & program) {
  std::cerr << program << " -opencl_platform ... -opencl_device ... -device_name ... [-sync] -padding_file ...";
  std::cerr << "-zapped_channels ... -integration_steps ... -integration_file ... -snr_file ...";
  std::cerr << "[-splitbatches_dedispersion] [-subband_dedispersion] [-debug] [-print] [-compact_results] -output ...";
  std::cerr << "-dms ... -dm_first ... -dm_step ... -threshold ... [-sigproc]";
#ifdef HAVE_HDF5
  std::cerr << " [-lofar]";
#endif // HAVE_HDF5
#ifdef HAVE_PSRDADA
  std::cerr << " [-dada]";
#endif // HAVE_PSRDADA
  std::cerr << std::endl;
  std::cerr << "\tDedispersion: -dedispersion_file ..." << std::endl;
  std::cerr << "\tSubband Dedispersion: -subband_dedispersion -dedispersion_stepone_file ...";
  std::cerr << "-dedispersion_steptwo_file ... -subbands ... -subbanding_dms ... -subbanding_dm_first ...";
  std::cerr << "-subbanding_dm_step ..." << std::endl;
#ifdef HAVE_HDF5
  std::cerr << "\tLOFAR: -lofar -header ... -data ... [-limit]" << std::endl;
  std::cerr << "\t\t -limit -batches ..." << std::endl;
#endif // HAVE_HDF5
  std::cerr << "\tSIGPROC: -sigproc [-stream] -header ... -data ... -batches ... -channels ... -min_freq ...";
  std::cerr << "-channel_bandwidth ... -samples ... -sampling_time ..." << std::endl;
#ifdef HAVE_PSRDADA
  std::cerr << "\tPSRDADA: -dada -dada_key ... -beams ... -synthesized_beams ... -batches ..." << std::endl;
#endif // HAVE_PSRDADA
  std::cerr << "\t [-random] -width ... -dm ... -beams ... -synthesized_beams ... -batches ... -channels ...";
  std::cerr << "-min_freq ... -channel_bandwidth ... -samples ... -sampling_time ..." << std::endl;
}
<|endoftext|>