<commit_before>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/site_instance.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_details.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "content/common/notification_type.h"
#include "net/base/net_util.h"
#include "net/test/test_server.h"

class RenderViewHostManagerTest : public InProcessBrowserTest {
 public:
  RenderViewHostManagerTest() {
    EnableDOMAutomation();
  }

  static bool GetFilePathWithHostAndPortReplacement(
      const std::string& original_file_path,
      const net::HostPortPair& host_port_pair,
      std::string* replacement_path) {
    std::vector<net::TestServer::StringPair> replacement_text;
    replacement_text.push_back(
        make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
    return net::TestServer::GetFilePathWithReplacements(
        original_file_path, replacement_text, replacement_path);
  }
};

// Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
// and target=_blank should create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       SwapProcessWithRelNoreferrerAndTargetBlank) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a rel=noreferrer + target=blank link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefTargetBlankLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the tab to open.
  if (browser()->tab_count() < 2)
    ui_test_utils::WaitForNewTab(browser());

  // Opens in new tab.
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(1, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Wait for the cross-site transition in the new tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());
  EXPECT_FALSE(browser()->GetSelectedTabContents()->render_manager()->
                   pending_render_view_host());

  // Should have a new SiteInstance.
  scoped_refptr<SiteInstance> noref_blank_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_NE(orig_site_instance, noref_blank_site_instance);
}

// Test for crbug.com/24447.  Following a cross-site link with just
// target=_blank should not create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DontSwapProcessWithOnlyTargetBlank) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a target=blank link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickTargetBlankLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the tab to open.
  if (browser()->tab_count() < 2)
    ui_test_utils::WaitForNewTab(browser());

  // Opens in new tab.
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(1, browser()->selected_index());

  // Wait for the cross-site transition in the new tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> blank_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, blank_site_instance);
}

// Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
// and no target=_blank should not create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DontSwapProcessWithOnlyRelNoreferrer) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a rel=noreferrer link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the cross-site transition in the current tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());

  // Opens in same tab.
  EXPECT_EQ(1, browser()->tab_count());
  EXPECT_EQ(0, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> noref_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, noref_site_instance);
}

// Hangs flakily in Win, http://crbug.com/45040.
#if defined(OS_WIN)
#define MAYBE_ChromeURLAfterDownload DISABLED_ChromeURLAfterDownload
#else
// Started failing on Linux and Mac too, http://crbug.com/77762.
#define MAYBE_ChromeURLAfterDownload FLAKY_ChromeURLAfterDownload
#endif  // defined(OS_WIN)

// Test for crbug.com/14505. This tests that chrome:// urls are still functional
// after download of a file while viewing another chrome://.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       MAYBE_ChromeURLAfterDownload) {
  GURL downloads_url("chrome://downloads");
  GURL extensions_url("chrome://extensions");
  FilePath zip_download;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &zip_download));
  zip_download = zip_download.AppendASCII("zip").AppendASCII("test.zip");
  GURL zip_url = net::FilePathToFileURL(zip_download);

  ui_test_utils::NavigateToURL(browser(), downloads_url);
  ui_test_utils::NavigateToURL(browser(), zip_url);
  ui_test_utils::WaitForDownloadCount(
      browser()->profile()->GetDownloadManager(), 1);
  ui_test_utils::NavigateToURL(browser(), extensions_url);

  TabContents *contents = browser()->GetSelectedTabContents();
  ASSERT_TRUE(contents);
  bool webui_responded = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      contents->render_view_host(),
      L"",
      L"window.domAutomationController.send(window.webui_responded_);",
      &webui_responded));
  EXPECT_TRUE(webui_responded);
}

class BrowserClosedObserver : public NotificationObserver {
 public:
  explicit BrowserClosedObserver(Browser* browser) {
    registrar_.Add(this, NotificationType::BROWSER_CLOSED,
        Source<Browser>(browser));
    ui_test_utils::RunMessageLoop();
  }

  // NotificationObserver
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    switch (type.value) {
      case NotificationType::BROWSER_CLOSED:
        MessageLoopForUI::current()->Quit();
        break;
      default:
        NOTREACHED();
        break;
    }
  }

 private:
  NotificationRegistrar registrar_;
};

// Test for crbug.com/12745. This tests that if a download is initiated from
// a chrome:// page that has registered and onunload handler, the browser
// will be able to close.
// TODO(rafaelw): The fix for 12745 has now also been reverted. Another fix
// must be found before this can be re-enabled.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DISABLED_BrowserCloseAfterDownload) {
  GURL downloads_url("chrome://downloads");
  FilePath zip_download;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &zip_download));
  zip_download = zip_download.AppendASCII("zip").AppendASCII("test.zip");
  ASSERT_TRUE(file_util::PathExists(zip_download));
  GURL zip_url = net::FilePathToFileURL(zip_download);

  ui_test_utils::NavigateToURL(browser(), downloads_url);
  TabContents *contents = browser()->GetSelectedTabContents();
  ASSERT_TRUE(contents);
  bool result = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      contents->render_view_host(),
      L"",
      L"window.onunload = function() { var do_nothing = 0; }; "
      L"window.domAutomationController.send(true);",
      &result));
  EXPECT_TRUE(result);
  ui_test_utils::NavigateToURL(browser(), zip_url);

  ui_test_utils::WaitForDownloadCount(
    browser()->profile()->GetDownloadManager(), 1);

  browser()->CloseWindow();
  BrowserClosedObserver wait_for_close(browser());
}

// Test for crbug.com/76666.  A cross-site navigation that fails with a 204
// error should not make us ignore future renderer-initiated navigations.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, ClickLinkAfter204Error) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  // The links will point to the HTTPS server.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Load a cross-site page that fails with a 204 error.
  ui_test_utils::NavigateToURL(browser(), https_server.GetURL("nocontent"));

  // We should still be looking at the normal page.
  scoped_refptr<SiteInstance> post_nav_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, post_nav_site_instance);
  EXPECT_EQ("/files/click-noreferrer-links.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Renderer-initiated navigations should work.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the cross-site transition in the current tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());

  // Opens in same tab.
  EXPECT_EQ(1, browser()->tab_count());
  EXPECT_EQ(0, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> noref_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, noref_site_instance);
}
<commit_msg>Revert 79703 - Revert 79690 - Disable RenderViewHostManagerTest.ChromeURLAfterDownload due to hangs.<commit_after>// Copyright (c) 2011 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "base/file_util.h"
#include "base/memory/ref_counted.h"
#include "base/path_service.h"
#include "chrome/browser/download/download_manager.h"
#include "chrome/browser/extensions/extension_error_reporter.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/common/chrome_paths.h"
#include "chrome/test/in_process_browser_test.h"
#include "chrome/test/ui_test_utils.h"
#include "content/browser/site_instance.h"
#include "content/browser/tab_contents/tab_contents.h"
#include "content/common/notification_details.h"
#include "content/common/notification_observer.h"
#include "content/common/notification_registrar.h"
#include "content/common/notification_type.h"
#include "net/base/net_util.h"
#include "net/test/test_server.h"

class RenderViewHostManagerTest : public InProcessBrowserTest {
 public:
  RenderViewHostManagerTest() {
    EnableDOMAutomation();
  }

  static bool GetFilePathWithHostAndPortReplacement(
      const std::string& original_file_path,
      const net::HostPortPair& host_port_pair,
      std::string* replacement_path) {
    std::vector<net::TestServer::StringPair> replacement_text;
    replacement_text.push_back(
        make_pair("REPLACE_WITH_HOST_AND_PORT", host_port_pair.ToString()));
    return net::TestServer::GetFilePathWithReplacements(
        original_file_path, replacement_text, replacement_path);
  }
};

// Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
// and target=_blank should create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       SwapProcessWithRelNoreferrerAndTargetBlank) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a rel=noreferrer + target=blank link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefTargetBlankLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the tab to open.
  if (browser()->tab_count() < 2)
    ui_test_utils::WaitForNewTab(browser());

  // Opens in new tab.
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(1, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Wait for the cross-site transition in the new tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());
  EXPECT_FALSE(browser()->GetSelectedTabContents()->render_manager()->
                   pending_render_view_host());

  // Should have a new SiteInstance.
  scoped_refptr<SiteInstance> noref_blank_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_NE(orig_site_instance, noref_blank_site_instance);
}

// Test for crbug.com/24447.  Following a cross-site link with just
// target=_blank should not create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DontSwapProcessWithOnlyTargetBlank) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a target=blank link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickTargetBlankLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the tab to open.
  if (browser()->tab_count() < 2)
    ui_test_utils::WaitForNewTab(browser());

  // Opens in new tab.
  EXPECT_EQ(2, browser()->tab_count());
  EXPECT_EQ(1, browser()->selected_index());

  // Wait for the cross-site transition in the new tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> blank_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, blank_site_instance);
}

// Test for crbug.com/24447.  Following a cross-site link with rel=noreferrer
// and no target=_blank should not create a new SiteInstance.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DontSwapProcessWithOnlyRelNoreferrer) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Test clicking a rel=noreferrer link.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the cross-site transition in the current tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());

  // Opens in same tab.
  EXPECT_EQ(1, browser()->tab_count());
  EXPECT_EQ(0, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> noref_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, noref_site_instance);
}

// Test for crbug.com/14505. This tests that chrome:// urls are still functional
// after download of a file while viewing another chrome://.
// Hangs flakily in Win, http://crbug.com/45040, and started hanging on Linux,
// Mac and ChromeOS, http://crbug.com/77762.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DISABLED_ChromeURLAfterDownload) {
  GURL downloads_url("chrome://downloads");
  GURL extensions_url("chrome://extensions");
  FilePath zip_download;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &zip_download));
  zip_download = zip_download.AppendASCII("zip").AppendASCII("test.zip");
  GURL zip_url = net::FilePathToFileURL(zip_download);

  ui_test_utils::NavigateToURL(browser(), downloads_url);
  ui_test_utils::NavigateToURL(browser(), zip_url);
  ui_test_utils::WaitForDownloadCount(
      browser()->profile()->GetDownloadManager(), 1);
  ui_test_utils::NavigateToURL(browser(), extensions_url);

  TabContents *contents = browser()->GetSelectedTabContents();
  ASSERT_TRUE(contents);
  bool webui_responded = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      contents->render_view_host(),
      L"",
      L"window.domAutomationController.send(window.webui_responded_);",
      &webui_responded));
  EXPECT_TRUE(webui_responded);
}

class BrowserClosedObserver : public NotificationObserver {
 public:
  explicit BrowserClosedObserver(Browser* browser) {
    registrar_.Add(this, NotificationType::BROWSER_CLOSED,
        Source<Browser>(browser));
    ui_test_utils::RunMessageLoop();
  }

  // NotificationObserver
  virtual void Observe(NotificationType type,
                       const NotificationSource& source,
                       const NotificationDetails& details) {
    switch (type.value) {
      case NotificationType::BROWSER_CLOSED:
        MessageLoopForUI::current()->Quit();
        break;
      default:
        NOTREACHED();
        break;
    }
  }

 private:
  NotificationRegistrar registrar_;
};

// Test for crbug.com/12745. This tests that if a download is initiated from
// a chrome:// page that has registered and onunload handler, the browser
// will be able to close.
// TODO(rafaelw): The fix for 12745 has now also been reverted. Another fix
// must be found before this can be re-enabled.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest,
                       DISABLED_BrowserCloseAfterDownload) {
  GURL downloads_url("chrome://downloads");
  FilePath zip_download;
  ASSERT_TRUE(PathService::Get(chrome::DIR_TEST_DATA, &zip_download));
  zip_download = zip_download.AppendASCII("zip").AppendASCII("test.zip");
  ASSERT_TRUE(file_util::PathExists(zip_download));
  GURL zip_url = net::FilePathToFileURL(zip_download);

  ui_test_utils::NavigateToURL(browser(), downloads_url);
  TabContents *contents = browser()->GetSelectedTabContents();
  ASSERT_TRUE(contents);
  bool result = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      contents->render_view_host(),
      L"",
      L"window.onunload = function() { var do_nothing = 0; }; "
      L"window.domAutomationController.send(true);",
      &result));
  EXPECT_TRUE(result);
  ui_test_utils::NavigateToURL(browser(), zip_url);

  ui_test_utils::WaitForDownloadCount(
    browser()->profile()->GetDownloadManager(), 1);

  browser()->CloseWindow();
  BrowserClosedObserver wait_for_close(browser());
}

// Test for crbug.com/76666.  A cross-site navigation that fails with a 204
// error should not make us ignore future renderer-initiated navigations.
IN_PROC_BROWSER_TEST_F(RenderViewHostManagerTest, ClickLinkAfter204Error) {
  // Start two servers with different sites.
  ASSERT_TRUE(test_server()->Start());
  net::TestServer https_server(
      net::TestServer::TYPE_HTTPS,
      FilePath(FILE_PATH_LITERAL("chrome/test/data")));
  ASSERT_TRUE(https_server.Start());

  // Load a page with links that open in a new window.
  // The links will point to the HTTPS server.
  std::string replacement_path;
  ASSERT_TRUE(GetFilePathWithHostAndPortReplacement(
      "files/click-noreferrer-links.html",
      https_server.host_port_pair(),
      &replacement_path));
  ui_test_utils::NavigateToURL(browser(),
                               test_server()->GetURL(replacement_path));

  // Get the original SiteInstance for later comparison.
  scoped_refptr<SiteInstance> orig_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_TRUE(orig_site_instance != NULL);

  // Load a cross-site page that fails with a 204 error.
  ui_test_utils::NavigateToURL(browser(), https_server.GetURL("nocontent"));

  // We should still be looking at the normal page.
  scoped_refptr<SiteInstance> post_nav_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, post_nav_site_instance);
  EXPECT_EQ("/files/click-noreferrer-links.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Renderer-initiated navigations should work.
  bool success = false;
  EXPECT_TRUE(ui_test_utils::ExecuteJavaScriptAndExtractBool(
      browser()->GetSelectedTabContents()->render_view_host(), L"",
      L"window.domAutomationController.send(clickNoRefLink());",
      &success));
  EXPECT_TRUE(success);

  // Wait for the cross-site transition in the current tab to finish.
  ui_test_utils::WaitForLoadStop(browser()->GetSelectedTabContents());

  // Opens in same tab.
  EXPECT_EQ(1, browser()->tab_count());
  EXPECT_EQ(0, browser()->selected_index());
  EXPECT_EQ("/files/title2.html",
            browser()->GetSelectedTabContents()->GetURL().path());

  // Should have the same SiteInstance.
  scoped_refptr<SiteInstance> noref_site_instance(
      browser()->GetSelectedTabContents()->GetSiteInstance());
  EXPECT_EQ(orig_site_instance, noref_site_instance);
}
<|endoftext|>


<commit_before>#include "testing/testing.hpp"

#include "storage/country_tree.hpp"

namespace
{
template <class Node>
struct Calculator
{
  size_t count;
  Calculator() : count(0) {}
  void operator()(Node const &) { ++count; }
};
} // namespace

UNIT_TEST(CountryTree_Smoke)
{
  using Tree = storage::CountryTree::Node;
  using Value = storage::Country;

  Tree tree(Value("0"), nullptr);

  tree.AddAtDepth(1, Value("4"));
  tree.AddAtDepth(1, Value("3"));
  tree.AddAtDepth(1, Value("5"));
  tree.AddAtDepth(1, Value("2"));
  tree.AddAtDepth(1, Value("1"));
  tree.AddAtDepth(2, Value("20"));
  tree.AddAtDepth(2, Value("10"));
  tree.AddAtDepth(2, Value("30"));

  // children test
  TEST_EQUAL(tree.Child(0).Value().Name(), "4", ());
  TEST_EQUAL(tree.Child(1).Value().Name(), "3", ());
  TEST_EQUAL(tree.Child(2).Value().Name(), "5", ());
  TEST_EQUAL(tree.Child(3).Value().Name(), "2", ());
  TEST_EQUAL(tree.Child(4).Value().Name(), "1", ());
  TEST_EQUAL(tree.Child(4).Child(0).Value().Name(), "20", ());
  TEST_EQUAL(tree.Child(4).Child(1).Value().Name(), "10", ());
  TEST_EQUAL(tree.Child(4).Child(2).Value().Name(), "30", ());

  // parent test
  TEST(!tree.HasParent(), ());
  TEST(!tree.Child(0).Parent().HasParent(), ());
  TEST_EQUAL(tree.Child(4).Child(0).Parent().Value().Name(), "1", ());
  TEST_EQUAL(tree.Child(4).Child(2).Parent().Value().Name(), "1", ());

  Calculator<Tree> c1;
  tree.ForEachChild(c1);
  TEST_EQUAL(c1.count, 5, ());

  Calculator<Tree> c2;
  tree.ForEachDescendant(c2);
  TEST_EQUAL(c2.count, 8, ());

  Calculator<Tree> c3;
  tree.Child(4).Child(0).ForEachAncestorExceptForTheRoot(c3);
  TEST_EQUAL(c3.count, 1, ());
}
<commit_msg>[storage] Fix CountryTree_Smoke test<commit_after>#include "testing/testing.hpp"

#include "storage/country_tree.hpp"

UNIT_TEST(CountryTree_Smoke)
{
  using Tree = storage::CountryTree::Node;
  using Value = storage::Country;

  Tree tree(Value("0"), nullptr);

  tree.AddAtDepth(1, Value("4"));
  tree.AddAtDepth(1, Value("3"));
  tree.AddAtDepth(1, Value("5"));
  tree.AddAtDepth(1, Value("2"));
  tree.AddAtDepth(1, Value("1"));
  tree.AddAtDepth(2, Value("20"));
  tree.AddAtDepth(2, Value("10"));
  tree.AddAtDepth(2, Value("30"));

  // children test
  TEST_EQUAL(tree.Child(0).Value().Name(), "4", ());
  TEST_EQUAL(tree.Child(1).Value().Name(), "3", ());
  TEST_EQUAL(tree.Child(2).Value().Name(), "5", ());
  TEST_EQUAL(tree.Child(3).Value().Name(), "2", ());
  TEST_EQUAL(tree.Child(4).Value().Name(), "1", ());
  TEST_EQUAL(tree.Child(4).Child(0).Value().Name(), "20", ());
  TEST_EQUAL(tree.Child(4).Child(1).Value().Name(), "10", ());
  TEST_EQUAL(tree.Child(4).Child(2).Value().Name(), "30", ());

  // parent test
  TEST(!tree.HasParent(), ());
  TEST(!tree.Child(0).Parent().HasParent(), ());
  TEST_EQUAL(tree.Child(4).Child(0).Parent().Value().Name(), "1", ());
  TEST_EQUAL(tree.Child(4).Child(2).Parent().Value().Name(), "1", ());

  size_t count = 0;
  auto countCallback = [&count](Tree const &) { ++count; };
  tree.ForEachChild(countCallback);
  TEST_EQUAL(count, 5, ());

  count = 0;
  tree.ForEachDescendant(countCallback);
  TEST_EQUAL(count, 8, ());

  count = 0;
  tree.Child(4).Child(0).ForEachAncestorExceptForTheRoot(countCallback);
  TEST_EQUAL(count, 1, ());
}
<|endoftext|>


<commit_before> //
 // This file is part of Easylogging++ samples
 // Very basic sample - log using multiple loggers
 //
 // Revision 1.0
 // @author mkhan3189
 //

// You can also uncomment this line and achieve same result using LOG(..) macro
// #define _LOGGER "default", "network"

#include "easylogging++.h"

_INITIALIZE_EASYLOGGINGPP

int main(void) {

    el::Loggers::addFlag(el::LoggingFlag::MultiLoggerSupport); // Enables support for multiple loggers

    el::Loggers::getLogger("network"); // Register 'network' logger

    CLOG(INFO, "default", "network") << "My first log message that writes with network and default loggers";

    return 0;
}
<commit_msg>update sample<commit_after> //
 // This file is part of Easylogging++ samples
 // Very basic sample - log using multiple loggers
 //
 // Revision 1.0
 // @author mkhan3189
 //

#include "easylogging++.h"

_INITIALIZE_EASYLOGGINGPP

int main(void) {

    el::Loggers::addFlag(el::LoggingFlag::MultiLoggerSupport); // Enables support for multiple loggers

    el::Loggers::getLogger("network"); // Register 'network' logger

    CLOG(INFO, "default", "network") << "My first log message that writes with network and default loggers";

    // Another way of doing this may be
    #define _LOGGER "default", "network"
    CLOG(INFO, _LOGGER) << "This is done by _LOGGER";

    // More practical way of doing this
    #define NETWORK_LOG(LEVEL) CLOG(LEVEL, _LOGGER)
    NETWORK_LOG(INFO) << "This is achieved by NETWORK_LOG macro";

    return 0;
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: replace.cxx,v $
 *
 *  $Revision: 1.1 $
 *
 *  last change: $Author: nf $ $Date: 2000-12-11 14:00:04 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>
#include "string.hxx"

/****************************************************************************/
#if defined( UNX ) || defined( MAC )
int main( int argc, char *argv[] )
#else
int _cdecl main( int argc, char *argv[] )
#endif
/****************************************************************************/
{
    ByteString aText( argv[ 1 ] );
    ByteString aSearch( argv[ 2 ] );
    ByteString aReplace( argv[ 3 ] );

    aText.SearchAndReplaceAll( aSearch, aReplace );
    fprintf( stdout, "%s\n", aText.GetBuffer());
}
<commit_msg>compare case insensitive<commit_after>/*************************************************************************
 *
 *  $RCSfile: replace.cxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: hjs $ $Date: 2000-12-18 13:13:20 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 by Sun Microsystems, Inc.
 *  901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *  This library is free software; you can redistribute it and/or
 *  modify it under the terms of the GNU Lesser General Public
 *  License version 2.1, as published by the Free Software Foundation.
 *
 *  This library is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *  Lesser General Public License for more details.
 *
 *  You should have received a copy of the GNU Lesser General Public
 *  License along with this library; if not, write to the Free Software
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *  MA  02111-1307  USA
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (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.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#include <stdio.h>
#include "string.hxx"

/****************************************************************************/
#if defined( UNX ) || defined( MAC )
int main( int argc, char *argv[] )
#else
int _cdecl main( int argc, char *argv[] )
#endif
/****************************************************************************/
{
    if ( argc < 4 )
    {
        fprintf( stderr, "ERROR: too few parameters. \n\n");
        fprintf( stderr, "usage: txtrep.exe EnvironmentVariable Searchstring replacestring\n");
        return 1;
    }
    ByteString aText( getenv( argv[ 1 ] ));
    if ( aText.Len() == 0 )
    {
        fprintf( stderr, "ERROR: Variable not set. \n\n");
        fprintf( stderr, "usage: txtrep.exe EnvironmentVariable Searchstring replacestring\n");
        return 2;
    }
    ByteString aSearch( argv[ 2 ] );
    ByteString aReplace( argv[ 3 ] );

    ByteString aUpperText( aText );
    aUpperText.ToUpperAscii();

    ULONG nIndex;
    aSearch.ToUpperAscii();

    nIndex = aUpperText.Search( aSearch.GetBuffer(), 0);
    while ( nIndex != STRING_NOTFOUND )
    {
        aText.Replace( nIndex, aSearch.Len(), aReplace.GetBuffer());
        aUpperText.Replace( nIndex, aSearch.Len(), aReplace.GetBuffer());
        nIndex = aUpperText.Search( aSearch.GetBuffer(), 0);
    }

    fprintf( stdout, "%s\n", aText.GetBuffer());
    return 0;
}
<|endoftext|>


<commit_before>
#include <OpenSim/OpenSim.h>

using SimTK::Inertia;
using SimTK::Pi;
using SimTK::Vec3;

using OpenSim::Body;
using OpenSim::CoordinateSet;
using OpenSim::DisplayGeometry;
using OpenSim::Model;
using OpenSim::PinJoint;

/**
 * Creates an OpenSim model of a three-legged animal. The animal has only one
 * hind leg, centered mediolaterally.
 *
 * Axis orientations, in rough terms:
 * +x: direction of forward travel.
 * +y: up.
 * +z: out of the screen.
 * */

/** Helper functions. **/
void addCylinderDisplayGeometry(Body * body,
        const double & diam, const double & length)
{
    DisplayGeometry * geom = new DisplayGeometry("cylinder.vtp");
    SimTK::Rotation rot;
    // Rotate the cylinder's symmetry (Y) axis to align with the body's X axis:
    rot.setRotationFromAngleAboutZ(-0.5 * Pi);
    geom->setTransform(
            SimTK::Transform(rot, Vec3(0.5 * length, 0, 0)));

    geom->setScaleFactors(Vec3(0.5 * diam, length, 0.5 * diam));
    body->updDisplayer()->setShowAxes(true);
    body->updDisplayer()->updGeometrySet().adoptAndAppend(geom);
};

void addThighCoordinateLimitForce(Model & model, const std::string & coord)
{
    OpenSim::CoordinateLimitForce * force = new OpenSim::CoordinateLimitForce(
                coord, 90, 1.0E2, -90, 1.0E2, 1.0E1, 2.0, false);
	model.addForce(force);
};

void addShankCoordinateLimitForce(Model & model, const std::string & coord)
{
    OpenSim::CoordinateLimitForce * force = new OpenSim::CoordinateLimitForce(
                coord, 10, 1.0E2, -160, 1.0E2, 1.0E1, 2.0, false);
	model.addForce(force);
};

void addCoordinateActuator(Model & model, const std::string & coord)
{
    OpenSim::CoordinateActuator * act = new OpenSim::CoordinateActuator(coord);
    act->setName(coord + "_actuator");
    act->setMinControl(-1000.0);
    act->setMaxControl(1000.0);
    model.addForce(act);
};

int main(int argc, char * argv[])
{
    // Preliminaries.
    // --------------
    Model tripod;
    tripod.setName("tripod");

    // Properties.
    // -----------
    // Lengths, in meters.
    double torsoX = 0.5;
    double torsoY = 0.1;
    double torsoZ = 0.3;
    double thighLength = 0.1;
    double thighDiameter = 0.07;
    double shankLength = 0.1;
    double shankDiameter = 0.05;

    // Masses, in kilograms.
    double torsoMass = 1.0;
    double thighMass = 1.0;
    double shankMass = 1.0;

    // Center of mass, in meters.
    // This really just chooses the origin of our bodies.
    Vec3 torsoCOM(0, 0, 0);
    // We choose the x direction to be the axis of the leg segments, with +x
    // pointing toward the ground.
    Vec3 thighCOM(0.5 * thighLength, 0, 0);
    Vec3 shankCOM(0.5 * shankLength, 0, 0);

    // Moments of inertia, in kilograms-meters^2.
    // These are about the center of mass of the body, expressed in the frame
    // of the body.
    Inertia torsoInertia = Inertia::brick(
            0.5 * torsoX, 0.5 * torsoY, 0.5 * torsoZ);
    Inertia thighInertia = Inertia::cylinderAlongX(0.5 * thighDiameter,
            thighLength);
    Inertia shankInertia = Inertia::cylinderAlongX(0.5 * shankDiameter,
            shankLength);

    // Bodies.
    // -------
    Body * torso = new Body("torso",
            torsoMass, torsoCOM, torsoInertia);
    Body * hindThigh = new Body("hind_thigh",
            thighMass, thighCOM, thighInertia);
    Body * hindShank = new Body("hind_shank",
            shankMass, shankCOM, shankInertia);
    Body * frontLeftThigh = new Body("front_left_thigh",
            thighMass, thighCOM, thighInertia);
    Body * frontLeftShank = new Body("front_left_shank",
            shankMass, shankCOM, shankInertia);
    Body * frontRightThigh = new Body("front_right_thigh",
            thighMass, thighCOM, thighInertia);
    Body * frontRightShank = new Body("front_right_shank",
            shankMass, shankCOM, shankInertia);

    // Joints.
    // -------
    Body & ground = tripod.getGroundBody();

    // Ground -> Torso.
    // ````````````````
    // The torso has no constraints with respect to the ground.
    // By default, the tripod's feet are on the ground.
    Vec3 locGTinG(0, thighLength + shankLength, 0);
    Vec3 orientGTinG(0, 0, 0);
    Vec3 locGTinT(0, 0, 0);
    Vec3 orientGTinT(0, 0, 0);
    OpenSim::FreeJoint * groundTorso = new OpenSim::FreeJoint("torso",
            ground, locGTinG, orientGTinG, *torso, locGTinT, orientGTinT);

    CoordinateSet & groundTorsoCS = groundTorso->upd_CoordinateSet();

    // Rotation about x.
    groundTorsoCS[0].setName("torso_rx");
    double groundTorsoCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    groundTorsoCS[0].setRange(groundTorsoCS0range);

    groundTorsoCS[1].setName("torso_ry");
    double groundTorsoCS1range[2] = {-0.5 * Pi, 0.5 * Pi};
    groundTorsoCS[1].setRange(groundTorsoCS1range);

    groundTorsoCS[2].setName("torso_rz");
    double groundTorsoCS2range[2] = {-0.5 * Pi, 0.5 * Pi};
    groundTorsoCS[2].setRange(groundTorsoCS2range);

    // Translation in x.
    groundTorsoCS[3].setName("torso_tx");
    double groundTorsoCS3range[2] = {-1.0, 10.0};
    groundTorsoCS[3].setRange(groundTorsoCS3range);

    groundTorsoCS[4].setName("torso_ty");
    double groundTorsoCS4range[2] = {0.0, 2.0};
    groundTorsoCS[4].setRange(groundTorsoCS4range);

    groundTorsoCS[5].setName("torso_tz");
    double groundTorsoCS5range[2] = {-1.0, 1.0};
    groundTorsoCS[5].setRange(groundTorsoCS5range);

    // Torso -> hind thigh.
    // ````````````````````
    Vec3 locTHinT(-0.5 * torsoX, 0, 0);
    // By default, the leg is extended.
    Vec3 orientTHinT(0, 0, -0.5 * Pi);
    Vec3 locTHinH(0, 0, 0);
    Vec3 orientTHinH(0, 0, 0);
    PinJoint * torsoHindThigh = new PinJoint("hind_thigh",
            *torso, locTHinT, orientTHinT, *hindThigh, locTHinH, orientTHinH);

    CoordinateSet & torsoHindThighCS = torsoHindThigh->upd_CoordinateSet();
    torsoHindThighCS[0].setName("hind_thigh_flexion");
    double torsoHindThighCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    torsoHindThighCS[0].setRange(torsoHindThighCS0range);

    // Hind thigh -> hind shank.
    // `````````````````````````
    Vec3 locHTSinT(thighLength, 0, 0);
    Vec3 orientHTSinT(0, 0, 0);
    Vec3 locHTSinS(0, 0, 0);
    Vec3 orientHTSinS(0, 0, 0);
    PinJoint * hindThighShank = new PinJoint("hind_shank",
            *hindThigh, locHTSinT, orientHTSinT,
            *hindShank, locHTSinS, orientHTSinS);

    CoordinateSet & hindThighShankCS = hindThighShank->upd_CoordinateSet();
    hindThighShankCS[0].setName("hind_knee_extension");
    double hindThighShankCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    hindThighShankCS[0].setRange(hindThighShankCS0range);

    // Torso -> front left thigh.
    // ``````````````````````````
    Vec3 locTFLinT(0.5 * torsoX, 0, -0.5 * torsoZ);
    // By default, the leg is extended.
    Vec3 orientTFLinT(0, 0, -0.5 * Pi);
    Vec3 locTFLinFL(0, 0, 0);
    Vec3 orientTFLinFL(0, 0, 0);
    PinJoint * torsoFrontLeftThigh = new PinJoint("front_left_thigh",
            *torso, locTFLinT, orientTFLinT,
            *frontLeftThigh, locTFLinFL, orientTFLinFL);

    CoordinateSet & torsoFrontLeftThighCS =
        torsoFrontLeftThigh->upd_CoordinateSet();
    torsoFrontLeftThighCS[0].setName("front_left_thigh_flexion");
    double torsoFrontLeftThighCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    torsoFrontLeftThighCS[0].setRange(torsoFrontLeftThighCS0range);

    // Front left thigh -> front left shank.
    // `````````````````````````````````````
    Vec3 locFLTSinT(thighLength, 0, 0);
    Vec3 orientFLTSinT(0, 0, 0);
    Vec3 locFLTSinS(0, 0, 0);
    Vec3 orientFLTSinS(0, 0, 0);
    PinJoint * frontLeftThighShank = new PinJoint("front_left_shank",
            *frontLeftThigh, locFLTSinT, orientFLTSinT,
            *frontLeftShank, locFLTSinS, orientFLTSinS);

    CoordinateSet & frontLeftThighShankCS =
        frontLeftThighShank->upd_CoordinateSet();
    frontLeftThighShankCS[0].setName("front_left_knee_extension");
    double frontLeftThighShankCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    frontLeftThighShankCS[0].setRange(frontLeftThighShankCS0range);

    // Torso -> front right thigh.
    // ```````````````````````````
    Vec3 locTFRinT(0.5 * torsoX, 0, 0.5 * torsoZ);
    // By default, the leg is extended.
    Vec3 orientTFRinT(0, 0, -0.5 * Pi);
    Vec3 locTFRinFR(0, 0, 0);
    Vec3 orientTFRinFR(0, 0, 0);
    PinJoint * torsoFrontRightThigh = new PinJoint("front_right_thigh",
            *torso, locTFRinT, orientTFRinT,
            *frontRightThigh, locTFRinFR, orientTFRinFR);

    CoordinateSet & torsoFrontRightThighCS =
        torsoFrontRightThigh->upd_CoordinateSet();
    torsoFrontRightThighCS[0].setName("front_right_thigh_flexion");
    double torsoFrontRightThighCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    torsoFrontRightThighCS[0].setRange(torsoFrontRightThighCS0range);

    // Front right thigh -> front right shank.
    // ```````````````````````````````````````
    Vec3 locFRTSinT(thighLength, 0, 0);
    Vec3 orientFRTSinT(0, 0, 0);
    Vec3 locFRTSinS(0, 0, 0);
    Vec3 orientFRTSinS(0, 0, 0);
    PinJoint * frontRightThighShank = new PinJoint("front_right_shank",
            *frontRightThigh, locFRTSinT, orientFRTSinT,
            *frontRightShank, locFRTSinS, orientFRTSinS);

    CoordinateSet & frontRightThighShankCS =
        frontRightThighShank->upd_CoordinateSet();
    frontRightThighShankCS[0].setName("front_right_knee_extension");
    double frontRightThighShankCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    frontRightThighShankCS[0].setRange(frontRightThighShankCS0range);

    // Add bodies to the model.
    // ------------------------
    // Now that we've define the joints.
    tripod.addBody(torso);
    tripod.addBody(hindThigh);
    tripod.addBody(hindShank);
    tripod.addBody(frontLeftThigh);
    tripod.addBody(frontLeftShank);
    tripod.addBody(frontRightThigh);
    tripod.addBody(frontRightShank);

    // Display geometry.
    // -----------------

    // Torso.
    // ``````
    DisplayGeometry * torsoDisplay = new DisplayGeometry("box.vtp");
    torsoDisplay->setScaleFactors(
            Vec3(torsoX, torsoY,  torsoZ));
    torso->updDisplayer()->updGeometrySet().adoptAndAppend(torsoDisplay);
    torso->updDisplayer()->setShowAxes(true);

    addCylinderDisplayGeometry(hindThigh, thighDiameter, thighLength);
    addCylinderDisplayGeometry(hindShank, shankDiameter, shankLength);
    addCylinderDisplayGeometry(frontLeftThigh, thighDiameter, thighLength);
    addCylinderDisplayGeometry(frontLeftShank, shankDiameter, shankLength);
    addCylinderDisplayGeometry(frontRightThigh, thighDiameter, thighLength);
    addCylinderDisplayGeometry(frontRightShank, shankDiameter, shankLength);

    // Enforce joint limits on the legs.
    // ---------------------------------
    addThighCoordinateLimitForce(tripod, "hind_thigh_flexion");
    addThighCoordinateLimitForce(tripod, "front_left_thigh_flexion");
    addThighCoordinateLimitForce(tripod, "front_right_thigh_flexion");
    addShankCoordinateLimitForce(tripod, "hind_knee_extension");
    addShankCoordinateLimitForce(tripod, "front_left_knee_extension");
    addShankCoordinateLimitForce(tripod, "front_right_knee_extension");

    // Actuators.
    // ----------

    // Contact.
    // --------
    // So the tripod does not go through the ground.

    addCoordinateActuator(tripod, "hind_thigh_flexion");
    addCoordinateActuator(tripod, "front_left_thigh_flexion");
    addCoordinateActuator(tripod, "front_right_thigh_flexion");
    addCoordinateActuator(tripod, "hind_knee_extension");
    addCoordinateActuator(tripod, "front_left_knee_extension");
    addCoordinateActuator(tripod, "front_right_knee_extension");

    // Print the model.
    tripod.print("tripod.osim");

    return EXIT_SUCCESS;
}

<commit_msg>Add coordinate actuators.<commit_after>
#include <OpenSim/OpenSim.h>

using SimTK::Inertia;
using SimTK::Pi;
using SimTK::Vec3;

using OpenSim::Body;
using OpenSim::CoordinateSet;
using OpenSim::DisplayGeometry;
using OpenSim::Model;
using OpenSim::PinJoint;

/**
 * Creates an OpenSim model of a three-legged animal. The animal has only one
 * hind leg, centered mediolaterally.
 *
 * Axis orientations, in rough terms:
 * +x: direction of forward travel.
 * +y: up.
 * +z: out of the screen.
 * */

/** Helper functions. **/
void addCylinderDisplayGeometry(Body * body,
        const double & diam, const double & length)
{
    DisplayGeometry * geom = new DisplayGeometry("cylinder.vtp");
    SimTK::Rotation rot;
    // Rotate the cylinder's symmetry (Y) axis to align with the body's X axis:
    rot.setRotationFromAngleAboutZ(-0.5 * Pi);
    geom->setTransform(
            SimTK::Transform(rot, Vec3(0.5 * length, 0, 0)));

    geom->setScaleFactors(Vec3(0.5 * diam, length, 0.5 * diam));
    body->updDisplayer()->setShowAxes(true);
    body->updDisplayer()->updGeometrySet().adoptAndAppend(geom);
};

void addThighCoordinateLimitForce(Model & model, const std::string & coord)
{
    OpenSim::CoordinateLimitForce * force = new OpenSim::CoordinateLimitForce(
                coord, 90, 1.0E2, -90, 1.0E2, 1.0E1, 2.0, false);
	model.addForce(force);
};

void addShankCoordinateLimitForce(Model & model, const std::string & coord)
{
    OpenSim::CoordinateLimitForce * force = new OpenSim::CoordinateLimitForce(
                coord, 10, 1.0E2, -160, 1.0E2, 1.0E1, 2.0, false);
	model.addForce(force);
};

void addCoordinateActuator(Model & model, const std::string & coord)
{
    OpenSim::CoordinateActuator * act = new OpenSim::CoordinateActuator(coord);
    act->setName(coord + "_actuator");
    act->setMinControl(-1000.0);
    act->setMaxControl(1000.0);
    model.addForce(act);
};

int main(int argc, char * argv[])
{
    // Preliminaries.
    // --------------
    Model tripod;
    tripod.setName("tripod");

    // Properties.
    // -----------
    // Lengths, in meters.
    double torsoX = 0.5;
    double torsoY = 0.1;
    double torsoZ = 0.3;
    double thighLength = 0.1;
    double thighDiameter = 0.07;
    double shankLength = 0.1;
    double shankDiameter = 0.05;

    // Masses, in kilograms.
    double torsoMass = 1.0;
    double thighMass = 1.0;
    double shankMass = 1.0;

    // Center of mass, in meters.
    // This really just chooses the origin of our bodies.
    Vec3 torsoCOM(0, 0, 0);
    // We choose the x direction to be the axis of the leg segments, with +x
    // pointing toward the ground.
    Vec3 thighCOM(0.5 * thighLength, 0, 0);
    Vec3 shankCOM(0.5 * shankLength, 0, 0);

    // Moments of inertia, in kilograms-meters^2.
    // These are about the center of mass of the body, expressed in the frame
    // of the body.
    Inertia torsoInertia = Inertia::brick(
            0.5 * torsoX, 0.5 * torsoY, 0.5 * torsoZ);
    Inertia thighInertia = Inertia::cylinderAlongX(0.5 * thighDiameter,
            thighLength);
    Inertia shankInertia = Inertia::cylinderAlongX(0.5 * shankDiameter,
            shankLength);

    // Bodies.
    // -------
    Body * torso = new Body("torso",
            torsoMass, torsoCOM, torsoInertia);
    Body * hindThigh = new Body("hind_thigh",
            thighMass, thighCOM, thighInertia);
    Body * hindShank = new Body("hind_shank",
            shankMass, shankCOM, shankInertia);
    Body * frontLeftThigh = new Body("front_left_thigh",
            thighMass, thighCOM, thighInertia);
    Body * frontLeftShank = new Body("front_left_shank",
            shankMass, shankCOM, shankInertia);
    Body * frontRightThigh = new Body("front_right_thigh",
            thighMass, thighCOM, thighInertia);
    Body * frontRightShank = new Body("front_right_shank",
            shankMass, shankCOM, shankInertia);

    // Joints.
    // -------
    Body & ground = tripod.getGroundBody();

    // Ground -> Torso.
    // ````````````````
    // The torso has no constraints with respect to the ground.
    // By default, the tripod's feet are on the ground.
    Vec3 locGTinG(0, thighLength + shankLength, 0);
    Vec3 orientGTinG(0, 0, 0);
    Vec3 locGTinT(0, 0, 0);
    Vec3 orientGTinT(0, 0, 0);
    OpenSim::FreeJoint * groundTorso = new OpenSim::FreeJoint("torso",
            ground, locGTinG, orientGTinG, *torso, locGTinT, orientGTinT);

    CoordinateSet & groundTorsoCS = groundTorso->upd_CoordinateSet();

    // Rotation about x.
    groundTorsoCS[0].setName("torso_rx");
    double groundTorsoCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    groundTorsoCS[0].setRange(groundTorsoCS0range);

    groundTorsoCS[1].setName("torso_ry");
    double groundTorsoCS1range[2] = {-0.5 * Pi, 0.5 * Pi};
    groundTorsoCS[1].setRange(groundTorsoCS1range);

    groundTorsoCS[2].setName("torso_rz");
    double groundTorsoCS2range[2] = {-0.5 * Pi, 0.5 * Pi};
    groundTorsoCS[2].setRange(groundTorsoCS2range);

    // Translation in x.
    groundTorsoCS[3].setName("torso_tx");
    double groundTorsoCS3range[2] = {-1.0, 10.0};
    groundTorsoCS[3].setRange(groundTorsoCS3range);

    groundTorsoCS[4].setName("torso_ty");
    double groundTorsoCS4range[2] = {0.0, 2.0};
    groundTorsoCS[4].setRange(groundTorsoCS4range);

    groundTorsoCS[5].setName("torso_tz");
    double groundTorsoCS5range[2] = {-1.0, 1.0};
    groundTorsoCS[5].setRange(groundTorsoCS5range);

    // Torso -> hind thigh.
    // ````````````````````
    Vec3 locTHinT(-0.5 * torsoX, 0, 0);
    // By default, the leg is extended.
    Vec3 orientTHinT(0, 0, -0.5 * Pi);
    Vec3 locTHinH(0, 0, 0);
    Vec3 orientTHinH(0, 0, 0);
    PinJoint * torsoHindThigh = new PinJoint("hind_thigh",
            *torso, locTHinT, orientTHinT, *hindThigh, locTHinH, orientTHinH);

    CoordinateSet & torsoHindThighCS = torsoHindThigh->upd_CoordinateSet();
    torsoHindThighCS[0].setName("hind_thigh_flexion");
    double torsoHindThighCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    torsoHindThighCS[0].setRange(torsoHindThighCS0range);

    // Hind thigh -> hind shank.
    // `````````````````````````
    Vec3 locHTSinT(thighLength, 0, 0);
    Vec3 orientHTSinT(0, 0, 0);
    Vec3 locHTSinS(0, 0, 0);
    Vec3 orientHTSinS(0, 0, 0);
    PinJoint * hindThighShank = new PinJoint("hind_shank",
            *hindThigh, locHTSinT, orientHTSinT,
            *hindShank, locHTSinS, orientHTSinS);

    CoordinateSet & hindThighShankCS = hindThighShank->upd_CoordinateSet();
    hindThighShankCS[0].setName("hind_knee_extension");
    double hindThighShankCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    hindThighShankCS[0].setRange(hindThighShankCS0range);

    // Torso -> front left thigh.
    // ``````````````````````````
    Vec3 locTFLinT(0.5 * torsoX, 0, -0.5 * torsoZ);
    // By default, the leg is extended.
    Vec3 orientTFLinT(0, 0, -0.5 * Pi);
    Vec3 locTFLinFL(0, 0, 0);
    Vec3 orientTFLinFL(0, 0, 0);
    PinJoint * torsoFrontLeftThigh = new PinJoint("front_left_thigh",
            *torso, locTFLinT, orientTFLinT,
            *frontLeftThigh, locTFLinFL, orientTFLinFL);

    CoordinateSet & torsoFrontLeftThighCS =
        torsoFrontLeftThigh->upd_CoordinateSet();
    torsoFrontLeftThighCS[0].setName("front_left_thigh_flexion");
    double torsoFrontLeftThighCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    torsoFrontLeftThighCS[0].setRange(torsoFrontLeftThighCS0range);

    // Front left thigh -> front left shank.
    // `````````````````````````````````````
    Vec3 locFLTSinT(thighLength, 0, 0);
    Vec3 orientFLTSinT(0, 0, 0);
    Vec3 locFLTSinS(0, 0, 0);
    Vec3 orientFLTSinS(0, 0, 0);
    PinJoint * frontLeftThighShank = new PinJoint("front_left_shank",
            *frontLeftThigh, locFLTSinT, orientFLTSinT,
            *frontLeftShank, locFLTSinS, orientFLTSinS);

    CoordinateSet & frontLeftThighShankCS =
        frontLeftThighShank->upd_CoordinateSet();
    frontLeftThighShankCS[0].setName("front_left_knee_extension");
    double frontLeftThighShankCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    frontLeftThighShankCS[0].setRange(frontLeftThighShankCS0range);

    // Torso -> front right thigh.
    // ```````````````````````````
    Vec3 locTFRinT(0.5 * torsoX, 0, 0.5 * torsoZ);
    // By default, the leg is extended.
    Vec3 orientTFRinT(0, 0, -0.5 * Pi);
    Vec3 locTFRinFR(0, 0, 0);
    Vec3 orientTFRinFR(0, 0, 0);
    PinJoint * torsoFrontRightThigh = new PinJoint("front_right_thigh",
            *torso, locTFRinT, orientTFRinT,
            *frontRightThigh, locTFRinFR, orientTFRinFR);

    CoordinateSet & torsoFrontRightThighCS =
        torsoFrontRightThigh->upd_CoordinateSet();
    torsoFrontRightThighCS[0].setName("front_right_thigh_flexion");
    double torsoFrontRightThighCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    torsoFrontRightThighCS[0].setRange(torsoFrontRightThighCS0range);

    // Front right thigh -> front right shank.
    // ```````````````````````````````````````
    Vec3 locFRTSinT(thighLength, 0, 0);
    Vec3 orientFRTSinT(0, 0, 0);
    Vec3 locFRTSinS(0, 0, 0);
    Vec3 orientFRTSinS(0, 0, 0);
    PinJoint * frontRightThighShank = new PinJoint("front_right_shank",
            *frontRightThigh, locFRTSinT, orientFRTSinT,
            *frontRightShank, locFRTSinS, orientFRTSinS);

    CoordinateSet & frontRightThighShankCS =
        frontRightThighShank->upd_CoordinateSet();
    frontRightThighShankCS[0].setName("front_right_knee_extension");
    double frontRightThighShankCS0range[2] = {-0.5 * Pi, 0.5 * Pi};
    frontRightThighShankCS[0].setRange(frontRightThighShankCS0range);

    // Add bodies to the model.
    // ------------------------
    // Now that we've define the joints.
    tripod.addBody(torso);
    tripod.addBody(hindThigh);
    tripod.addBody(hindShank);
    tripod.addBody(frontLeftThigh);
    tripod.addBody(frontLeftShank);
    tripod.addBody(frontRightThigh);
    tripod.addBody(frontRightShank);

    // Display geometry.
    // -----------------

    // Torso.
    // ``````
    DisplayGeometry * torsoDisplay = new DisplayGeometry("box.vtp");
    torsoDisplay->setScaleFactors(
            Vec3(torsoX, torsoY,  torsoZ));
    torso->updDisplayer()->updGeometrySet().adoptAndAppend(torsoDisplay);
    torso->updDisplayer()->setShowAxes(true);

    addCylinderDisplayGeometry(hindThigh, thighDiameter, thighLength);
    addCylinderDisplayGeometry(hindShank, shankDiameter, shankLength);
    addCylinderDisplayGeometry(frontLeftThigh, thighDiameter, thighLength);
    addCylinderDisplayGeometry(frontLeftShank, shankDiameter, shankLength);
    addCylinderDisplayGeometry(frontRightThigh, thighDiameter, thighLength);
    addCylinderDisplayGeometry(frontRightShank, shankDiameter, shankLength);

    // Enforce joint limits on the legs.
    // ---------------------------------
    addThighCoordinateLimitForce(tripod, "hind_thigh_flexion");
    addThighCoordinateLimitForce(tripod, "front_left_thigh_flexion");
    addThighCoordinateLimitForce(tripod, "front_right_thigh_flexion");
    addShankCoordinateLimitForce(tripod, "hind_knee_extension");
    addShankCoordinateLimitForce(tripod, "front_left_knee_extension");
    addShankCoordinateLimitForce(tripod, "front_right_knee_extension");

    // Actuators.
    // ----------
    addCoordinateActuator(tripod, "hind_thigh_flexion");
    addCoordinateActuator(tripod, "front_left_thigh_flexion");
    addCoordinateActuator(tripod, "front_right_thigh_flexion");
    addCoordinateActuator(tripod, "hind_knee_extension");
    addCoordinateActuator(tripod, "front_left_knee_extension");
    addCoordinateActuator(tripod, "front_right_knee_extension");

    // Contact.
    // --------
    // So the tripod does not go through the ground.

    // Print the model.
    tripod.print("tripod.osim");

    return EXIT_SUCCESS;
}

<|endoftext|>


<commit_before><commit_msg>-Werror=shadow<commit_after><|endoftext|>


<commit_before><commit_msg>Update the comment & use the column position of the last formula record.<commit_after><|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fumark.cxx,v $
 *
 *  $Revision: 1.6 $
 *
 *  last change: $Author: kz $ $Date: 2006-07-21 13:50:34 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

//------------------------------------------------------------------

#include <svx/svdview.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>

#include "fumark.hxx"
#include "sc.hrc"
#include "tabvwsh.hxx"
#include "scmod.hxx"
#include "reffact.hxx"
#include "document.hxx"
#include "scresid.hxx"

//------------------------------------------------------------------

/*************************************************************************
|*
|* Funktion zum Aufziehen eines Rechtecks
|*
\************************************************************************/

FuMarkRect::FuMarkRect(ScTabViewShell* pViewSh, Window* pWin, SdrView* pView,
               SdrModel* pDoc, SfxRequest& rReq) :
    FuPoor(pViewSh, pWin, pView, pDoc, rReq),
    bVisible(FALSE),
    bStartDrag(FALSE)
{
}

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

FuMarkRect::~FuMarkRect()
{
}

/*************************************************************************
|*
|* MouseButtonDown-event
|*
\************************************************************************/

BOOL FuMarkRect::MouseButtonDown(const MouseEvent& rMEvt)
{
    // #95491# remember button state for creation of own MouseEvents
    SetMouseButtonCode(rMEvt.GetButtons());

    pWindow->CaptureMouse();
    pView->UnmarkAll();         // der Einheitlichkeit halber und wegen #50558#
    bStartDrag = TRUE;

    aBeginPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
    aZoomRect = Rectangle( aBeginPos, Size() );
    return TRUE;
}

/*************************************************************************
|*
|* MouseMove-event
|*
\************************************************************************/

BOOL FuMarkRect::MouseMove(const MouseEvent& rMEvt)
{
    if ( bStartDrag )
    {
        if ( bVisible )
            pViewShell->DrawMarkRect(aZoomRect);
        Point aPixPos= rMEvt.GetPosPixel();
        ForceScroll(aPixPos);

        Point aEndPos = pWindow->PixelToLogic(aPixPos);
        Rectangle aRect(aBeginPos, aEndPos);
        aZoomRect = aRect;
        aZoomRect.Justify();
        pViewShell->DrawMarkRect(aZoomRect);
        bVisible = TRUE;
    }

    ForcePointer(&rMEvt);

    return bStartDrag;
}

/*************************************************************************
|*
|* MouseButtonUp-event
|*
\************************************************************************/

BOOL FuMarkRect::MouseButtonUp(const MouseEvent& rMEvt)
{
    // #95491# remember button state for creation of own MouseEvents
    SetMouseButtonCode(rMEvt.GetButtons());

    if ( bVisible )
    {
        // Hide ZoomRect
        pViewShell->DrawMarkRect(aZoomRect);
        bVisible = FALSE;
    }

    Size aZoomSizePixel = pWindow->LogicToPixel(aZoomRect).GetSize();

    USHORT nMinMove = pView->GetMinMoveDistancePixel();
    if ( aZoomSizePixel.Width() < nMinMove || aZoomSizePixel.Height() < nMinMove )
    {
        // Klick auf der Stelle

        aZoomRect.SetSize(Size());      // dann ganz leer
    }

    bStartDrag = FALSE;
    pWindow->ReleaseMouse();

    pViewShell->GetViewData()->GetDispatcher().
        Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);

        //  Daten an der View merken

    pViewShell->SetChartArea( aSourceRange, aZoomRect );

        //  Chart-Dialog starten:

    USHORT nId  = ScChartDlgWrapper::GetChildWindowId();
    SfxChildWindow* pWnd = pViewShell->GetViewFrame()->GetChildWindow( nId );
    SC_MOD()->SetRefDialog( nId, pWnd ? FALSE : TRUE );

    return TRUE;
}

/*************************************************************************
|*
|* Command-event
|*
\************************************************************************/

BYTE FuMarkRect::Command(const CommandEvent& rCEvt)
{
    if ( COMMAND_STARTDRAG == rCEvt.GetCommand() )
    {
        //  #29877# nicht anfangen, auf der Tabelle rumzudraggen,
        //  aber Maus-Status nicht zuruecksetzen
        return SC_CMD_IGNORE;
    }
    else
        return FuPoor::Command(rCEvt);
}

/*************************************************************************
|*
|* Tastaturereignisse bearbeiten
|*
|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
|* FALSE.
|*
\************************************************************************/

BOOL FuMarkRect::KeyInput(const KeyEvent& rKEvt)
{
    BOOL bReturn = FALSE;

    switch ( rKEvt.GetKeyCode().GetCode() )
    {
        case KEY_ESCAPE:
            //  beenden
            pViewShell->GetViewData()->GetDispatcher().
                Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
            bReturn = TRUE;
            break;
    }

    if (!bReturn)
    {
        bReturn = FuPoor::KeyInput(rKEvt);
    }

    return (bReturn);
}

/*************************************************************************
|*
|* Vor dem Scrollen Selektionsdarstellung ausblenden
|*
\************************************************************************/

void FuMarkRect::ScrollStart()
{
}

/*************************************************************************
|*
|* Nach dem Scrollen Selektionsdarstellung wieder anzeigen
|*
\************************************************************************/

void FuMarkRect::ScrollEnd()
{
}

/*************************************************************************
|*
|* Function aktivieren
|*
\************************************************************************/

void FuMarkRect::Activate()
{
    FuPoor::Activate();

        //  Markierung merken, bevor evtl. Tabelle umgeschaltet wird

    ScViewData* pViewData = pViewShell->GetViewData();
    ScMarkData& rMark = pViewData->GetMarkData();

    if ( !rMark.IsMultiMarked() && !rMark.IsMarked() )
        pViewShell->MarkDataArea( TRUE );

    pViewData->GetMultiArea( aSourceRange );        // Mehrfachselektion erlaubt

//  pViewShell->Unmark();

    ForcePointer(NULL);
}

/*************************************************************************
|*
|* Function deaktivieren
|*
\************************************************************************/

void FuMarkRect::Deactivate()
{
    FuPoor::Deactivate();

    if (bVisible)
    {
        // Hide ZoomRect
        pViewShell->DrawMarkRect(aZoomRect);
        bVisible = FALSE;
        bStartDrag = FALSE;
    }
}

/*************************************************************************
|*
|* Maus-Pointer umschalten
|*
\************************************************************************/

void FuMarkRect::ForcePointer(const MouseEvent* pMEvt)
{
    pViewShell->SetActivePointer( Pointer( POINTER_CHART ) );
}

<commit_msg>INTEGRATION: CWS calcwarnings (1.6.110); FILE MERGED 2006/12/12 17:03:13 nn 1.6.110.2: #i69284# warning-free: ui, unxlngi6 2006/12/01 08:53:30 nn 1.6.110.1: #i69284# warning-free: ui, wntmsci10<commit_after>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: fumark.cxx,v $
 *
 *  $Revision: 1.7 $
 *
 *  last change: $Author: vg $ $Date: 2007-02-27 13:12:52 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sc.hxx"

//------------------------------------------------------------------

#include <svx/svdview.hxx>
#include <sfx2/dispatch.hxx>
#include <sfx2/viewfrm.hxx>

#include "fumark.hxx"
#include "sc.hrc"
#include "tabvwsh.hxx"
#include "scmod.hxx"
#include "reffact.hxx"
#include "document.hxx"
#include "scresid.hxx"

//------------------------------------------------------------------

/*************************************************************************
|*
|* Funktion zum Aufziehen eines Rechtecks
|*
\************************************************************************/

FuMarkRect::FuMarkRect(ScTabViewShell* pViewSh, Window* pWin, SdrView* pViewP,
               SdrModel* pDoc, SfxRequest& rReq) :
    FuPoor(pViewSh, pWin, pViewP, pDoc, rReq),
    bVisible(FALSE),
    bStartDrag(FALSE)
{
}

/*************************************************************************
|*
|* Destruktor
|*
\************************************************************************/

FuMarkRect::~FuMarkRect()
{
}

/*************************************************************************
|*
|* MouseButtonDown-event
|*
\************************************************************************/

BOOL FuMarkRect::MouseButtonDown(const MouseEvent& rMEvt)
{
    // #95491# remember button state for creation of own MouseEvents
    SetMouseButtonCode(rMEvt.GetButtons());

    pWindow->CaptureMouse();
    pView->UnmarkAll();         // der Einheitlichkeit halber und wegen #50558#
    bStartDrag = TRUE;

    aBeginPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
    aZoomRect = Rectangle( aBeginPos, Size() );
    return TRUE;
}

/*************************************************************************
|*
|* MouseMove-event
|*
\************************************************************************/

BOOL FuMarkRect::MouseMove(const MouseEvent& rMEvt)
{
    if ( bStartDrag )
    {
        if ( bVisible )
            pViewShell->DrawMarkRect(aZoomRect);
        Point aPixPos= rMEvt.GetPosPixel();
        ForceScroll(aPixPos);

        Point aEndPos = pWindow->PixelToLogic(aPixPos);
        Rectangle aRect(aBeginPos, aEndPos);
        aZoomRect = aRect;
        aZoomRect.Justify();
        pViewShell->DrawMarkRect(aZoomRect);
        bVisible = TRUE;
    }

    ForcePointer(&rMEvt);

    return bStartDrag;
}

/*************************************************************************
|*
|* MouseButtonUp-event
|*
\************************************************************************/

BOOL FuMarkRect::MouseButtonUp(const MouseEvent& rMEvt)
{
    // #95491# remember button state for creation of own MouseEvents
    SetMouseButtonCode(rMEvt.GetButtons());

    if ( bVisible )
    {
        // Hide ZoomRect
        pViewShell->DrawMarkRect(aZoomRect);
        bVisible = FALSE;
    }

    Size aZoomSizePixel = pWindow->LogicToPixel(aZoomRect).GetSize();

    USHORT nMinMove = pView->GetMinMoveDistancePixel();
    if ( aZoomSizePixel.Width() < nMinMove || aZoomSizePixel.Height() < nMinMove )
    {
        // Klick auf der Stelle

        aZoomRect.SetSize(Size());      // dann ganz leer
    }

    bStartDrag = FALSE;
    pWindow->ReleaseMouse();

    pViewShell->GetViewData()->GetDispatcher().
        Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SYNCHRON | SFX_CALLMODE_RECORD);

        //  Daten an der View merken

    pViewShell->SetChartArea( aSourceRange, aZoomRect );

        //  Chart-Dialog starten:

    USHORT nId  = ScChartDlgWrapper::GetChildWindowId();
    SfxChildWindow* pWnd = pViewShell->GetViewFrame()->GetChildWindow( nId );
    SC_MOD()->SetRefDialog( nId, pWnd ? FALSE : TRUE );

    return TRUE;
}

/*************************************************************************
|*
|* Command-event
|*
\************************************************************************/

BYTE FuMarkRect::Command(const CommandEvent& rCEvt)
{
    if ( COMMAND_STARTDRAG == rCEvt.GetCommand() )
    {
        //  #29877# nicht anfangen, auf der Tabelle rumzudraggen,
        //  aber Maus-Status nicht zuruecksetzen
        return SC_CMD_IGNORE;
    }
    else
        return FuPoor::Command(rCEvt);
}

/*************************************************************************
|*
|* Tastaturereignisse bearbeiten
|*
|* Wird ein KeyEvent bearbeitet, so ist der Return-Wert TRUE, andernfalls
|* FALSE.
|*
\************************************************************************/

BOOL FuMarkRect::KeyInput(const KeyEvent& rKEvt)
{
    BOOL bReturn = FALSE;

    switch ( rKEvt.GetKeyCode().GetCode() )
    {
        case KEY_ESCAPE:
            //  beenden
            pViewShell->GetViewData()->GetDispatcher().
                Execute(aSfxRequest.GetSlot(), SFX_CALLMODE_SLOT | SFX_CALLMODE_RECORD);
            bReturn = TRUE;
            break;
    }

    if (!bReturn)
    {
        bReturn = FuPoor::KeyInput(rKEvt);
    }

    return (bReturn);
}

/*************************************************************************
|*
|* Vor dem Scrollen Selektionsdarstellung ausblenden
|*
\************************************************************************/

void FuMarkRect::ScrollStart()
{
}

/*************************************************************************
|*
|* Nach dem Scrollen Selektionsdarstellung wieder anzeigen
|*
\************************************************************************/

void FuMarkRect::ScrollEnd()
{
}

/*************************************************************************
|*
|* Function aktivieren
|*
\************************************************************************/

void FuMarkRect::Activate()
{
    FuPoor::Activate();

        //  Markierung merken, bevor evtl. Tabelle umgeschaltet wird

    ScViewData* pViewData = pViewShell->GetViewData();
    ScMarkData& rMark = pViewData->GetMarkData();

    if ( !rMark.IsMultiMarked() && !rMark.IsMarked() )
        pViewShell->MarkDataArea( TRUE );

    pViewData->GetMultiArea( aSourceRange );        // Mehrfachselektion erlaubt

//  pViewShell->Unmark();

    ForcePointer(NULL);
}

/*************************************************************************
|*
|* Function deaktivieren
|*
\************************************************************************/

void FuMarkRect::Deactivate()
{
    FuPoor::Deactivate();

    if (bVisible)
    {
        // Hide ZoomRect
        pViewShell->DrawMarkRect(aZoomRect);
        bVisible = FALSE;
        bStartDrag = FALSE;
    }
}

/*************************************************************************
|*
|* Maus-Pointer umschalten
|*
\************************************************************************/

void FuMarkRect::ForcePointer(const MouseEvent* /* pMEvt */)
{
    pViewShell->SetActivePointer( Pointer( POINTER_CHART ) );
}

<|endoftext|>


<commit_before>#if !defined(_MUTEX_HPP_INCLUDED_)
#define _MUTEX_HPP_INCLUDED_

#include <stdint.h>
#include <netinet/in.h>

#include <pthread.h>

class Mutex
{
private:
  pthread_mutex_t m_mutex;

public:
  void Lock(void) { pthread_mutex_lock(&m_mutex); }
  void Unlock(void) { pthread_mutex_unlock(&m_mutex); }
  Mutex();
  ~Mutex();
  pthread_mutex_t *GetMutex() { return &m_mutex; }
};

#endif // _MUTEX_HPP_INCLUDED_
<commit_msg>Get rid of the stuff needed for the socket class.  It was in here because I cut and pasted from the socket class and simply forgot to remove it.<commit_after>#if !defined(_MUTEX_HPP_INCLUDED_)
#define _MUTEX_HPP_INCLUDED_

#include <pthread.h>

class Mutex
{
private:
  pthread_mutex_t m_mutex;

public:
  void Lock(void) { pthread_mutex_lock(&m_mutex); }
  void Unlock(void) { pthread_mutex_unlock(&m_mutex); }
  Mutex();
  ~Mutex();
  pthread_mutex_t *GetMutex() { return &m_mutex; }
};

#endif // _MUTEX_HPP_INCLUDED_
<|endoftext|>


<commit_before>/// \file
/// \ingroup tutorial_tmva
/// \notebook -nodraw
/// This macro provides an example of how to use TMVA for k-folds cross
/// evaluation.
///
/// As input data is used a toy-MC sample consisting of two guassian
/// distributions.
///
/// The output file "TMVA.root" can be analysed with the use of dedicated
/// macros (simply say: root -l <macro.C>), which can be conveniently
/// invoked through a GUI that will appear at the end of the run of this macro.
/// Launch the GUI via the command:
///
/// ```
/// root -l -e 'TMVA::TMVAGui("TMVA.root")'
/// ```
///
/// ## Cross Evaluation
/// Cross evaluation is a special case of k-folds cross validation where the
/// splitting into k folds is computed deterministically. This ensures that the
/// a given event will always end up in the same fold.
///
/// In addition all resulting classifiers are saved and can be applied to new
/// data using `MethodCrossValidation`. One requirement for this to work is a
/// splitting function that is evaluated for each event to determine into what
/// fold it goes (for training/evaluation) or to what classifier (for
/// application).
///
/// ## Split Expression
/// Cross evaluation uses a deterministic split to partition the data into
/// folds called the split expression. The expression can be any valid
/// `TFormula` as long as all parts used are defined.
///
/// For each event the split expression is evaluated to a number and the event
/// is put in the fold corresponding to that number.
///
/// It is recommended to always use `%int([NumFolds])` at the end of the
/// expression.
///
/// The split expression has access to all spectators and variables defined in
/// the dataloader. Additionally, the number of folds in the split can be
/// accessed with `NumFolds` (or `numFolds`).
///
/// ### Example
///  ```
///  "int(fabs([eventID]))%int([NumFolds])"
///  ```
///
/// - Project   : TMVA - a ROOT-integrated toolkit for multivariate data analysis
/// - Package   : TMVA
/// - Root Macro: TMVACrossValidation
///
/// \macro_output
/// \macro_code
/// \author Kim Albertsson (adapted from code originally by Andreas Hoecker)

#include <cstdlib>
#include <iostream>
#include <map>
#include <string>

#include "TChain.h"
#include "TFile.h"
#include "TTree.h"
#include "TString.h"
#include "TObjString.h"
#include "TSystem.h"
#include "TROOT.h"

#include "TMVA/CrossValidation.h"
#include "TMVA/DataLoader.h"
#include "TMVA/Factory.h"
#include "TMVA/Tools.h"
#include "TMVA/TMVAGui.h"

// Helper function to load data into TTrees.
TTree *genTree(Int_t nPoints, Double_t offset, Double_t scale, UInt_t seed = 100)
{
   TRandom3 rng(seed);
   Float_t x = 0;
   Float_t y = 0;
   UInt_t eventID = 0;

   TTree *data = new TTree();
   data->Branch("x", &x, "x/F");
   data->Branch("y", &y, "y/F");
   data->Branch("eventID", &eventID, "eventID/I");

   for (Int_t n = 0; n < nPoints; ++n) {
      x = rng.Gaus(offset, scale);
      y = rng.Gaus(offset, scale);

      // For our simple example it is enough that the id's are uniformly
      // distributed and independent of the data.
      ++eventID;

      data->Fill();
   }

   // Important: Disconnects the tree from the memory locations of x and y.
   data->ResetBranchAddresses();
   return data;
}

int TMVACrossValidation()
{
   // This loads the library
   TMVA::Tools::Instance();

   // --------------------------------------------------------------------------

   // Load the data into TTrees. If you load data from file you can use a
   // variant of
   // ```
   // TString filename = "/path/to/file";
   // TFile * input = TFile::Open( filename );
   // TTree * signalTree = (TTree*)input->Get("TreeName");
   // ```
   TTree *sigTree = genTree(1000, 1.0, 1.0, 100);
   TTree *bkgTree = genTree(1000, -1.0, 1.0, 101);

   // Create a ROOT output file where TMVA will store ntuples, histograms, etc.
   TString outfileName("TMVA.root");
   TFile *outputFile = TFile::Open(outfileName, "RECREATE");

   // DataLoader definitions; We declare variables in the tree so that TMVA can
   // find them. For more information see TMVAClassification tutorial.
   TMVA::DataLoader *dataloader = new TMVA::DataLoader("dataset");

   // Data variables
   dataloader->AddVariable("x", 'F');
   dataloader->AddVariable("y", 'F');

   // Spectator used for split
   dataloader->AddSpectator("eventID", 'I');

   // Attaches the trees so they can be read from
   dataloader->AddSignalTree(sigTree, 1.0);
   dataloader->AddBackgroundTree(bkgTree, 1.0);

   // The CV mechanism of TMVA splits up the training set into several folds.
   // The test set is currently left unused. The `nTest_ClassName=1` assigns
   // one event to the the test set for each class and puts the rest in the
   // training set. A value of 0 is a special value and would split the
   // datasets 50 / 50.
   dataloader->PrepareTrainingAndTestTree("", "",
                                          "nTest_Signal=1"
                                          ":nTest_Background=1"
                                          ":SplitMode=Random"
                                          ":NormMode=NumEvents"
                                          ":!V");

   // --------------------------------------------------------------------------

   //
   // This sets up a CrossValidation class (which wraps a TMVA::Factory
   // internally) for 2-fold cross validation.
   //
   UInt_t numFolds = 2;
   TString analysisType = "Classification";
   TString splitType = "Random";
   TString splitExpr = "";

   //
   // One can also use a custom splitting function for producing the folds.
   // The example uses a dataset spectator `eventID`.
   //
   // The idea here is that eventID should be an event number that is integral,
   // random and independent of the data, generated only once. This last
   // property ensures that if a calibration is changed the same event will
   // still be assigned the same fold.
   //
   // This can be used to use the cross validated classifiers in application,
   // a technique that can simplify statistical analysis.
   //
   // If you want to run TMVACrossValidationApplication, make sure you have
   // run this tutorial with the below line uncommented first.
   //

   // TString splitExpr = "int(fabs([eventID]))%int([NumFolds])";

   TString cvOptions = Form("!V"
                            ":!Silent"
                            ":ModelPersistence"
                            ":AnalysisType=%s"
                            ":SplitType=%s"
                            ":NumFolds=%i"
                            ":SplitExpr=%s",
                            analysisType.Data(), splitType.Data(), numFolds,
                            splitExpr.Data());

   TMVA::CrossValidation cv{"TMVACrossValidation", dataloader, outputFile, cvOptions};

   // --------------------------------------------------------------------------

   //
   // Books a method to use for evaluation
   //
   cv.BookMethod(TMVA::Types::kBDT, "BDTG",
                 "!H:!V:NTrees=100:MinNodeSize=2.5%:BoostType=Grad"
                 ":NegWeightTreatment=Pray:Shrinkage=0.10:nCuts=20"
                 ":MaxDepth=2");

   cv.BookMethod(TMVA::Types::kFisher, "Fisher",
                 "!H:!V:Fisher:VarTransform=None");

   // --------------------------------------------------------------------------

   //
   // Train, test and evaluate the booked methods.
   // Evaluates the booked methods once for each fold and aggregates the result
   // in the specified output file.
   //
   cv.Evaluate();

   // --------------------------------------------------------------------------

   //
   // Process some output programatically, printing the ROC score for each
   // booked method.
   //
   size_t iMethod = 0;
   for (auto && result : cv.GetResults()) {
      std::cout << "Summary for method " << cv.GetMethods()[iMethod++].GetValue<TString>("MethodName")
                << std::endl;
      for (UInt_t iFold = 0; iFold<cv.GetNumFolds(); ++iFold) {
         std::cout << "\tFold " << iFold << ": "
                   << "ROC int: " << result.GetROCValues()[iFold]
                   << ", "
                   << "BkgEff@SigEff=0.3: " << result.GetEff30Values()[iFold]
                   << std::endl;
      }
   }

   // --------------------------------------------------------------------------

   //
   // Save the output
   //
   outputFile->Close();

   std::cout << "==> Wrote root file: " << outputFile->GetName() << std::endl;
   std::cout << "==> TMVACrossValidation is done!" << std::endl;

   // --------------------------------------------------------------------------

   //
   // Launch the GUI for the root macros
   //
   if (!gROOT->IsBatch()) {
      // Draw cv-specific graphs
      cv.GetResults()[0].DrawAvgROCCurve(kTRUE, "Avg ROC for BDTG");
      cv.GetResults()[0].DrawAvgROCCurve(kTRUE, "Avg ROC for Fisher");

      // You can also use the classical gui
      TMVA::TMVAGui(outfileName);
   }

   return 0;
}

//
// This is used if the macro is compiled. If run through ROOT with
// `root -l -b -q MACRO.C` or similar it is unused.
//
int main(int argc, char **argv)
{
   TMVACrossValidation();
}
<commit_msg>[TMVA] CV Stratified -- Add info about split type to tutorial<commit_after>/// \file
/// \ingroup tutorial_tmva
/// \notebook -nodraw
/// This macro provides an example of how to use TMVA for k-folds cross
/// evaluation.
///
/// As input data is used a toy-MC sample consisting of two guassian
/// distributions.
///
/// The output file "TMVA.root" can be analysed with the use of dedicated
/// macros (simply say: root -l <macro.C>), which can be conveniently
/// invoked through a GUI that will appear at the end of the run of this macro.
/// Launch the GUI via the command:
///
/// ```
/// root -l -e 'TMVA::TMVAGui("TMVA.root")'
/// ```
///
/// ## Cross Evaluation
/// Cross evaluation is a special case of k-folds cross validation where the
/// splitting into k folds is computed deterministically. This ensures that the
/// a given event will always end up in the same fold.
///
/// In addition all resulting classifiers are saved and can be applied to new
/// data using `MethodCrossValidation`. One requirement for this to work is a
/// splitting function that is evaluated for each event to determine into what
/// fold it goes (for training/evaluation) or to what classifier (for
/// application).
///
/// ## Split Expression
/// Cross evaluation uses a deterministic split to partition the data into
/// folds called the split expression. The expression can be any valid
/// `TFormula` as long as all parts used are defined.
///
/// For each event the split expression is evaluated to a number and the event
/// is put in the fold corresponding to that number.
///
/// It is recommended to always use `%int([NumFolds])` at the end of the
/// expression.
///
/// The split expression has access to all spectators and variables defined in
/// the dataloader. Additionally, the number of folds in the split can be
/// accessed with `NumFolds` (or `numFolds`).
///
/// ### Example
///  ```
///  "int(fabs([eventID]))%int([NumFolds])"
///  ```
///
/// - Project   : TMVA - a ROOT-integrated toolkit for multivariate data analysis
/// - Package   : TMVA
/// - Root Macro: TMVACrossValidation
///
/// \macro_output
/// \macro_code
/// \author Kim Albertsson (adapted from code originally by Andreas Hoecker)

#include <cstdlib>
#include <iostream>
#include <map>
#include <string>

#include "TChain.h"
#include "TFile.h"
#include "TTree.h"
#include "TString.h"
#include "TObjString.h"
#include "TSystem.h"
#include "TROOT.h"

#include "TMVA/CrossValidation.h"
#include "TMVA/DataLoader.h"
#include "TMVA/Factory.h"
#include "TMVA/Tools.h"
#include "TMVA/TMVAGui.h"

// Helper function to load data into TTrees.
TTree *genTree(Int_t nPoints, Double_t offset, Double_t scale, UInt_t seed = 100)
{
   TRandom3 rng(seed);
   Float_t x = 0;
   Float_t y = 0;
   UInt_t eventID = 0;

   TTree *data = new TTree();
   data->Branch("x", &x, "x/F");
   data->Branch("y", &y, "y/F");
   data->Branch("eventID", &eventID, "eventID/I");

   for (Int_t n = 0; n < nPoints; ++n) {
      x = rng.Gaus(offset, scale);
      y = rng.Gaus(offset, scale);

      // For our simple example it is enough that the id's are uniformly
      // distributed and independent of the data.
      ++eventID;

      data->Fill();
   }

   // Important: Disconnects the tree from the memory locations of x and y.
   data->ResetBranchAddresses();
   return data;
}

int TMVACrossValidation()
{
   // This loads the library
   TMVA::Tools::Instance();

   // --------------------------------------------------------------------------

   // Load the data into TTrees. If you load data from file you can use a
   // variant of
   // ```
   // TString filename = "/path/to/file";
   // TFile * input = TFile::Open( filename );
   // TTree * signalTree = (TTree*)input->Get("TreeName");
   // ```
   TTree *sigTree = genTree(1000, 1.0, 1.0, 100);
   TTree *bkgTree = genTree(1000, -1.0, 1.0, 101);

   // Create a ROOT output file where TMVA will store ntuples, histograms, etc.
   TString outfileName("TMVA.root");
   TFile *outputFile = TFile::Open(outfileName, "RECREATE");

   // DataLoader definitions; We declare variables in the tree so that TMVA can
   // find them. For more information see TMVAClassification tutorial.
   TMVA::DataLoader *dataloader = new TMVA::DataLoader("dataset");

   // Data variables
   dataloader->AddVariable("x", 'F');
   dataloader->AddVariable("y", 'F');

   // Spectator used for split
   dataloader->AddSpectator("eventID", 'I');

   // Attaches the trees so they can be read from
   dataloader->AddSignalTree(sigTree, 1.0);
   dataloader->AddBackgroundTree(bkgTree, 1.0);

   // The CV mechanism of TMVA splits up the training set into several folds.
   // The test set is currently left unused. The `nTest_ClassName=1` assigns
   // one event to the the test set for each class and puts the rest in the
   // training set. A value of 0 is a special value and would split the
   // datasets 50 / 50.
   dataloader->PrepareTrainingAndTestTree("", "",
                                          "nTest_Signal=1"
                                          ":nTest_Background=1"
                                          ":SplitMode=Random"
                                          ":NormMode=NumEvents"
                                          ":!V");

   // --------------------------------------------------------------------------

   //
   // This sets up a CrossValidation class (which wraps a TMVA::Factory
   // internally) for 2-fold cross validation.
   //
   // The split type can be "Random", "RandomStratified" or "Deterministic".
   // For the last option, check the comment below. Random splitting randomises
   // the order of events and distributes events as evenly as possible.
   // RandomStratified applies the same logic but distributes events within a
   // class as evenly as possible over the folds.
   //
   UInt_t numFolds = 2;
   TString analysisType = "Classification";
   TString splitType = "Random";
   TString splitExpr = "";

   //
   // One can also use a custom splitting function for producing the folds.
   // The example uses a dataset spectator `eventID`.
   //
   // The idea here is that eventID should be an event number that is integral,
   // random and independent of the data, generated only once. This last
   // property ensures that if a calibration is changed the same event will
   // still be assigned the same fold.
   //
   // This can be used to use the cross validated classifiers in application,
   // a technique that can simplify statistical analysis.
   //
   // If you want to run TMVACrossValidationApplication, make sure you have
   // run this tutorial with the below line uncommented first.
   //

   // TString splitExpr = "int(fabs([eventID]))%int([NumFolds])";

   TString cvOptions = Form("!V"
                            ":!Silent"
                            ":ModelPersistence"
                            ":AnalysisType=%s"
                            ":SplitType=%s"
                            ":NumFolds=%i"
                            ":SplitExpr=%s",
                            analysisType.Data(), splitType.Data(), numFolds,
                            splitExpr.Data());

   TMVA::CrossValidation cv{"TMVACrossValidation", dataloader, outputFile, cvOptions};

   // --------------------------------------------------------------------------

   //
   // Books a method to use for evaluation
   //
   cv.BookMethod(TMVA::Types::kBDT, "BDTG",
                 "!H:!V:NTrees=100:MinNodeSize=2.5%:BoostType=Grad"
                 ":NegWeightTreatment=Pray:Shrinkage=0.10:nCuts=20"
                 ":MaxDepth=2");

   cv.BookMethod(TMVA::Types::kFisher, "Fisher",
                 "!H:!V:Fisher:VarTransform=None");

   // --------------------------------------------------------------------------

   //
   // Train, test and evaluate the booked methods.
   // Evaluates the booked methods once for each fold and aggregates the result
   // in the specified output file.
   //
   cv.Evaluate();

   // --------------------------------------------------------------------------

   //
   // Process some output programatically, printing the ROC score for each
   // booked method.
   //
   size_t iMethod = 0;
   for (auto && result : cv.GetResults()) {
      std::cout << "Summary for method " << cv.GetMethods()[iMethod++].GetValue<TString>("MethodName")
                << std::endl;
      for (UInt_t iFold = 0; iFold<cv.GetNumFolds(); ++iFold) {
         std::cout << "\tFold " << iFold << ": "
                   << "ROC int: " << result.GetROCValues()[iFold]
                   << ", "
                   << "BkgEff@SigEff=0.3: " << result.GetEff30Values()[iFold]
                   << std::endl;
      }
   }

   // --------------------------------------------------------------------------

   //
   // Save the output
   //
   outputFile->Close();

   std::cout << "==> Wrote root file: " << outputFile->GetName() << std::endl;
   std::cout << "==> TMVACrossValidation is done!" << std::endl;

   // --------------------------------------------------------------------------

   //
   // Launch the GUI for the root macros
   //
   if (!gROOT->IsBatch()) {
      // Draw cv-specific graphs
      cv.GetResults()[0].DrawAvgROCCurve(kTRUE, "Avg ROC for BDTG");
      cv.GetResults()[0].DrawAvgROCCurve(kTRUE, "Avg ROC for Fisher");

      // You can also use the classical gui
      TMVA::TMVAGui(outfileName);
   }

   return 0;
}

//
// This is used if the macro is compiled. If run through ROOT with
// `root -l -b -q MACRO.C` or similar it is unused.
//
int main(int argc, char **argv)
{
   TMVACrossValidation();
}
<|endoftext|>