<commit_before>// Copyright (c) 2017 Emilian Cioca
#include "Jewel3D/Precompiled.h"
#include "Logging.h"
#include "Jewel3D/Utilities/String.h"

#include <iostream>
#include <fstream>
#include <Windows.h>

namespace
{
	std::ofstream logOutput;
	HANDLE stdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
}

namespace Jwl
{
	void OpenOutputLog()
	{
		if (!logOutput.is_open())
		{
			logOutput.open("Log_Output.txt", std::ofstream::app);
		}
	}

	void CloseOutputLog()
	{
		if (logOutput.is_open())
		{
			logOutput.close();
		}
	}

	void CreateConsoleWindow()
	{
		if (GetConsoleWindow() != NULL)
		{
			return;
		}

		AllocConsole();
		SetConsoleTitle("Output Log");
		freopen("CONOUT$", "w", stdout);
		freopen("CONIN$", "r", stdin);
		stdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	}

	void DestroyConsoleWindow()
	{
		if (GetConsoleWindow() == NULL)
		{
			return;
		}

		fclose(stdout);
		fclose(stdin);
		FreeConsole();

		// There might still be an output stream so we try to obtain a new handle just in case.
		stdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	}

	void MoveConsoleWindowToForeground()
	{
		SetForegroundWindow(GetConsoleWindow());
	}

	void SetConsoleColor(ConsoleColor color)
	{
		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleTextAttribute(stdOutputHandle, static_cast<WORD>(color));
		}
	}

	void ResetConsoleColor()
	{
		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleTextAttribute(stdOutputHandle, static_cast<WORD>(ConsoleColor::Gray));
		}
	}

	void Log(const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		if (logOutput.is_open())
		{
			logOutput << "Log:\t\t" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			std::cout << "Log:     " << message << std::endl;
		}
	}

	void Log(std::string_view message)
	{
		if (logOutput.is_open())
		{
			logOutput << "Log:\t\t" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			std::cout << "Log:     " << message << std::endl;
		}
	}

	void Error(const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		if (logOutput.is_open())
		{
			logOutput << "ERROR:\t\t" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleColor(ConsoleColor::Red);
			std::cout << "ERROR:   " << message << std::endl;
			ResetConsoleColor();
		}
	}

	void Error(std::string_view message)
	{
		if (logOutput.is_open())
		{
			logOutput << "ERROR:\t\t" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleColor(ConsoleColor::Red);
			std::cout << "ERROR:   " << message << std::endl;
			ResetConsoleColor();
		}
	}

	void Warning(const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		if (logOutput.is_open())
		{
			logOutput << "WARNING:\t" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleColor(ConsoleColor::Yellow);
			std::cout << "WARNING: " << message << std::endl;
			ResetConsoleColor();
		}
	}

	void Warning(std::string_view message)
	{
		if (logOutput.is_open())
		{
			logOutput << "WARNING:\t" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleColor(ConsoleColor::Yellow);
			std::cout << "WARNING: " << message << std::endl;
			ResetConsoleColor();
		}
	}

	void ErrorBox(const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		if (logOutput.is_open())
		{
			logOutput << "ERROR:\t\t" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleColor(ConsoleColor::Red);
			std::cout << "ERROR:   " << message << std::endl;
			ResetConsoleColor();
		}

		MessageBox(HWND_DESKTOP, message.c_str(), "Error", MB_ICONERROR);
	}

	void ErrorBox(std::string_view message)
	{
		if (logOutput.is_open())
		{
			logOutput << "ERROR:\t\t" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleColor(ConsoleColor::Red);
			std::cout << "ERROR:   " << message << std::endl;
			ResetConsoleColor();
		}

		MessageBox(HWND_DESKTOP, message.data(), "Error", MB_ICONERROR);
	}

	void WarningBox(const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		if (logOutput.is_open())
		{
			logOutput << "WARNING:\t" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleColor(ConsoleColor::Yellow);
			std::cout << "WARNING: " << message << std::endl;
			ResetConsoleColor();
		}

		MessageBox(HWND_DESKTOP, message.c_str(), "Warning", MB_ICONWARNING);
	}

	void WarningBox(std::string_view message)
	{
		if (logOutput.is_open())
		{
			logOutput << "WARNING:\t" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleColor(ConsoleColor::Yellow);
			std::cout << "WARNING: " << message << std::endl;
			ResetConsoleColor();
		}

		MessageBox(HWND_DESKTOP, message.data(), "Warning", MB_ICONWARNING);
	}

	void Assert(const char* exp, const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		if (logOutput.is_open())
		{
			logOutput << "ASSERT:\t\t( " << exp << " )\n" << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleColor(ConsoleColor::Pink);
			std::cout << "ASSERT:  ( " << exp << " )\n" << message << std::endl;
			ResetConsoleColor();
		}
	}
}
<commit_msg>Logging will now output to Visual Studio's output window in debug<commit_after>// Copyright (c) 2017 Emilian Cioca
#include "Jewel3D/Precompiled.h"
#include "Logging.h"
#include "Jewel3D/Utilities/String.h"

#include <iostream>
#include <fstream>
#include <Windows.h>

namespace
{
	std::ofstream logOutput;
	HANDLE stdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);

	void PushMessage(std::string_view header, std::string_view message)
	{
		if (logOutput.is_open())
		{
			logOutput << header << message << std::endl;
		}

		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			std::cout << header << message << std::endl;
		}

		#if defined(_MSC_VER) && defined(_DEBUG)
			OutputDebugString(header.data());
			OutputDebugString(message.data());
			OutputDebugString("\n");
		#endif
	}

	void PushMessage(std::string_view header, std::string_view message, Jwl::ConsoleColor color)
	{
		Jwl::SetConsoleColor(color);
		PushMessage(header, message);
		Jwl::ResetConsoleColor();
	}
}

namespace Jwl
{
	void OpenOutputLog()
	{
		if (!logOutput.is_open())
		{
			logOutput.open("Log_Output.txt", std::ofstream::app);
		}
	}

	void CloseOutputLog()
	{
		if (logOutput.is_open())
		{
			logOutput.close();
		}
	}

	void CreateConsoleWindow()
	{
		if (GetConsoleWindow() != NULL)
		{
			return;
		}

		AllocConsole();
		SetConsoleTitle("Output Log");
		freopen("CONOUT$", "w", stdout);
		freopen("CONIN$", "r", stdin);
		stdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	}

	void DestroyConsoleWindow()
	{
		if (GetConsoleWindow() == NULL)
		{
			return;
		}

		fclose(stdout);
		fclose(stdin);
		FreeConsole();

		// There might still be an output stream so we try to obtain a new handle just in case.
		stdOutputHandle = GetStdHandle(STD_OUTPUT_HANDLE);
	}

	void MoveConsoleWindowToForeground()
	{
		SetForegroundWindow(GetConsoleWindow());
	}

	void SetConsoleColor(ConsoleColor color)
	{
		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleTextAttribute(stdOutputHandle, static_cast<WORD>(color));
		}
	}

	void ResetConsoleColor()
	{
		if (stdOutputHandle != INVALID_HANDLE_VALUE)
		{
			SetConsoleTextAttribute(stdOutputHandle, static_cast<WORD>(ConsoleColor::Gray));
		}
	}

	void Log(const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		PushMessage("Log:     ", message);
	}

	void Log(std::string_view message)
	{
		PushMessage("Log:     ", message);
	}

	void Error(const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		PushMessage("ERROR:   ", message, ConsoleColor::Red);
	}

	void Error(std::string_view message)
	{
		PushMessage("ERROR:   ", message, ConsoleColor::Red);
	}

	void Warning(const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		PushMessage("WARNING: ", message, ConsoleColor::Yellow);
	}

	void Warning(std::string_view message)
	{
		PushMessage("WARNING: ", message, ConsoleColor::Yellow);
	}

	void ErrorBox(const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		PushMessage("ERROR:   ", message, ConsoleColor::Red);
		MessageBox(HWND_DESKTOP, message.c_str(), "Error", MB_ICONERROR);
	}

	void ErrorBox(std::string_view message)
	{
		PushMessage("ERROR:   ", message, ConsoleColor::Red);
		MessageBox(HWND_DESKTOP, message.data(), "Error", MB_ICONERROR);
	}

	void WarningBox(const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		PushMessage("WARNING: ", message, ConsoleColor::Yellow);
		MessageBox(HWND_DESKTOP, message.c_str(), "Warning", MB_ICONWARNING);
	}

	void WarningBox(std::string_view message)
	{
		PushMessage("WARNING: ", message, ConsoleColor::Yellow);
		MessageBox(HWND_DESKTOP, message.data(), "Warning", MB_ICONWARNING);
	}

	void Assert(const char* exp, const char* format, ...)
	{
		va_list argptr;
		va_start(argptr, format);
		auto message = FormatString(format, argptr);
		va_end(argptr);

		auto header = FormatString("ASSERT:  ( %s )\n", exp);
		PushMessage(header, message, ConsoleColor::Pink);
	}
}
<|endoftext|>


<commit_before>//-*- Mode: C++ -*-
// $Id: AliHLTVZERORecoComponent.cxx $
/**************************************************************************
 * This file is property of and copyright by the ALICE HLT Project        *
 * ALICE Experiment at CERN, All rights reserved.                         *
 *                                                                        *
 * Primary Authors: Jochen Thaeder <jochen@thaeder.de>                    *
 *                  for The ALICE HLT Project.                            *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/** @file    AliHLTVZERORecoComponent.cxx
    @author  Jochen Thaeder <jochen@thaeder.de>
    @brief   VZERO reconstruction component
*/

#if __GNUC__>= 3
using namespace std;
#endif

#include "TTree.h"
#include "TMap.h"
#include "TObjString.h"

#include "AliLog.h"
#include "AliRunInfo.h"
#include "AliGRPObject.h"
#include "AliRawReaderMemory.h"
#include "AliGeomManager.h"

#include "AliVZERORecoParam.h"
#include "AliVZEROReconstructor.h"

#include "AliHLTErrorGuard.h"
#include "AliHLTDataTypes.h"
#include "AliHLTVZERORecoComponent.h"

/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTVZERORecoComponent)

/*
 * ---------------------------------------------------------------------------------
 *                            Constructor / Destructor
 * ---------------------------------------------------------------------------------
 */

// #################################################################################
AliHLTVZERORecoComponent::AliHLTVZERORecoComponent() :
  AliHLTProcessor(),
  fRunInfo(NULL),
  fVZERORecoParam(NULL),
  fVZEROReconstructor(NULL),
  fRawReader(NULL) {
  // an example component which implements the ALICE HLT processor
  // interface and does some analysis on the input raw data
  //
  // see header file for class documentation
  // or
  // refer to README to build package
  // or
  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
  //
  // NOTE: all helper classes should be instantiated in DoInit()
}

// #################################################################################
AliHLTVZERORecoComponent::~AliHLTVZERORecoComponent() {
  // see header file for class documentation
}

/*
 * ---------------------------------------------------------------------------------
 * Public functions to implement AliHLTComponent's interface.
 * These functions are required for the registration process
 * ---------------------------------------------------------------------------------
 */

// #################################################################################
const Char_t* AliHLTVZERORecoComponent::GetComponentID() {
  // see header file for class documentation
  return "VZEROReconstruction";
}

// #################################################################################
void AliHLTVZERORecoComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list) {
  // see header file for class documentation
  list.push_back(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginVZERO);
}

// #################################################################################
AliHLTComponentDataType AliHLTVZERORecoComponent::GetOutputDataType() {
  // see header file for class documentation
  return kAliHLTDataTypeESDContent|kAliHLTDataOriginVZERO;
}

// #################################################################################
void AliHLTVZERORecoComponent::GetOutputDataSize( ULong_t& constBase, Double_t& inputMultiplier ) {
  // see header file for class documentation
  constBase = 1000;
  inputMultiplier = 0.5;
}

// #################################################################################
void AliHLTVZERORecoComponent::GetOCDBObjectDescription( TMap* const targetMap) {
  // see header file for class documentation

  if (!targetMap) return;
  targetMap->Add(new TObjString("HLT/ConfigVZERO/VZEROReconstruction"),
		 new TObjString("configuration object"));

  targetMap->Add(new TObjString("GRP/GRP/Data"),
		 new TObjString("GRP object - run information"));
  targetMap->Add(new TObjString("GRP/CTP/CTPtiming"),
		 new TObjString("GRP object - CTP information"));
  targetMap->Add(new TObjString("GRP/CTP/TimeAlign"),
		 new TObjString("GRP object - CTP information"));
  targetMap->Add(new TObjString("GRP/Calib/LHCClockPhase"),
		 new TObjString("GRP object - time calibration"));

  targetMap->Add(new TObjString("VZERO/Calib/Data"),
		 new TObjString("VZERO calibration object"));
  targetMap->Add(new TObjString("VZERO/Calib/TimeDelays"),
		 new TObjString("VZERO calibration object"));
  targetMap->Add(new TObjString("VZERO/Calib/TimeSlewing"),
		 new TObjString("VZERO calibration object"));

  return;
}

// #################################################################################
AliHLTComponent* AliHLTVZERORecoComponent::Spawn() {
  // see header file for class documentation
  return new AliHLTVZERORecoComponent;
}

/*
 * ---------------------------------------------------------------------------------
 * Protected functions to implement AliHLTComponent's interface.
 * These functions provide initialization as well as the actual processing
 * capabilities of the component.
 * ---------------------------------------------------------------------------------
 */

// #################################################################################
Int_t AliHLTVZERORecoComponent::DoInit( Int_t argc, const Char_t** argv ) {
  // see header file for class documentation

  Int_t iResult=0;

  // -- Load GeomManager
  if(AliGeomManager::GetGeometry()==NULL){
    AliGeomManager::LoadGeometry();
  }

  // -- Read configuration object : HLT/ConfigVZERO/VZEROReconstruction
  TString cdbPath="HLT/ConfigVZERO/";
  cdbPath+=GetComponentID();
  iResult=ConfigureFromCDBTObjString(cdbPath);

  // -- Read the component arguments
  if (iResult>=0) {
    iResult=ConfigureFromArgumentString(argc, argv);
  }

  // -- Get AliRunInfo variables
  // -----------------------------
  TObject* pOCDBEntry=LoadAndExtractOCDBObject("GRP/GRP/Data");
  AliGRPObject* pGRP=pOCDBEntry?dynamic_cast<AliGRPObject*>(pOCDBEntry):NULL;

  TString beamType = "";
  TString lhcState = "";
  TString runType = "";
  Float_t beamEnergy = 0.;
  UInt_t activeDetectors = 0;

  if (pGRP) {
    lhcState        = pGRP->GetLHCState();
    beamType        = pGRP->GetBeamType();
    runType         = pGRP->GetRunType();
    beamEnergy      = pGRP->GetBeamEnergy();
    activeDetectors = pGRP->GetDetectorMask();
  }

  // -- Initialize members
  // -----------------------
  do {
    if (iResult<0) break;

    fRawReader = new AliRawReaderMemory;
    if (!fRawReader) {
      iResult=-ENOMEM;
      break;
    }

    // AliGRPManager grpMan;
    // Bool_t status       = grpMan.ReadGRPEntry(); // Read the corresponding OCDB entry
    // status              = grpMan.SetMagField();  // Set global field instanton
    // AliRunInfo *runInfo = grpMan.GetRunInfo();   // Get instance of run info

    fRunInfo = new AliRunInfo(lhcState.Data(), beamType.Data(),
			      beamEnergy, runType.Data(), activeDetectors);
    if (!fRunInfo) {
      iResult=-ENOMEM;
      break;
    }

    fVZERORecoParam = new AliVZERORecoParam;
    if (!fVZERORecoParam) {
      iResult=-ENOMEM;
      break;
    }

    fVZEROReconstructor = new AliVZEROReconstructor;
    if (!fVZEROReconstructor) {
      iResult=-ENOMEM;
      break;
    }

    // implement further initialization
  } while (0);

  if (iResult<0) {
    // implement cleanup

    if (fRawReader)
      delete fRawReader;
    fRawReader = NULL;

    if (fVZERORecoParam)
      delete fVZERORecoParam;
    fVZERORecoParam = NULL;

    if (fVZEROReconstructor)
      delete fVZEROReconstructor;
    fVZEROReconstructor = NULL;

    if (fRunInfo)
      delete fRunInfo;
    fRunInfo = NULL;
  }

  if (iResult>=0) {
    fVZEROReconstructor->SetRunInfo(fRunInfo);
    fVZEROReconstructor->Init();

    fVZEROReconstructor->SetRecoParam(fVZERORecoParam);
  }

  return iResult;
}

// #################################################################################
Int_t AliHLTVZERORecoComponent::ScanConfigurationArgument(Int_t /*argc*/, const Char_t** argv) {
  // Scan configuration arguments
  // Return the number of processed arguments
  //        -EPROTO if argument format error (e.g. number expected but not found)
  //
  // The AliHLTComponent base class implements a parsing loop for argument strings and
  // arrays of strings which is invoked by ConfigureFromArgumentString/ConfigureFromCDBTObjString
  // The component needs to implement ScanConfigurationArgument in order to decode the arguments.

  Int_t ii =0;
  TString argument=argv[ii];

  if (argument.IsNull()) return 0;

  return 0;
}

// #################################################################################
Int_t AliHLTVZERORecoComponent::DoDeinit() {
  // see header file for class documentation

  if (fRawReader)
    delete fRawReader;
  fRawReader = NULL;

  if (fVZERORecoParam)
    delete fVZERORecoParam;
  fVZERORecoParam = NULL;

  if (fVZEROReconstructor)
    delete fVZEROReconstructor;
  fVZEROReconstructor = NULL;

  if (fRunInfo)
    delete fRunInfo;
  fRunInfo = NULL;

  return 0;
}

// #################################################################################
Int_t AliHLTVZERORecoComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/,
					AliHLTComponentTriggerData& /*trigData*/) {
  // see header file for class documentation

  Int_t iResult=0;

  // -- Only use data event
  if (!IsDataEvent())
    return 0;

  // -- Get VZERO raw dat a input block and set up the rawreader
  const AliHLTComponentBlockData* pBlock = GetFirstInputBlock(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginVZERO);
  if (!pBlock) {
    HLTInfo("No VZERO input block !!!");
    return 0;
  }

  // -- Add input block to raw reader
  if (!fRawReader->SetMemory((UChar_t*) pBlock->fPtr, pBlock->fSize )){
    HLTError("Could not add buffer of data block  %s, 0x%08x to rawreader",
	     DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification);
    iResult = -1;
  }

  TTree *digitsTree = new TTree("D", "Digits Tree");
  if (!digitsTree) {
    iResult=-ENOMEM;
  }

  if (iResult >= 0) {

    // -- Set VZERO EquipmentID
    fRawReader->SetEquipmentID(3584);

    // -- 1. step VZERO reconstruction
    fVZEROReconstructor->ConvertDigits(fRawReader, digitsTree);

    // -- 2. step VZERO reconstruction -- fill AliESDVZERO object
    fVZEROReconstructor->FillESD(digitsTree, NULL, NULL);

    AliESDVZERO *esdVZERO = fVZEROReconstructor->GetESDVZERO();

    HLTInfo("VZERO Multiplicity A %f - C %f", esdVZERO->GetMTotV0A(), esdVZERO->GetMTotV0A() );

    // -- Send AliESDVZERO
    PushBack(static_cast<TObject*>(esdVZERO),
	     kAliHLTDataTypeESDContent|kAliHLTDataOriginVZERO,0);
  }

  // -- Clean up
  delete digitsTree;
  fRawReader->ClearBuffers();

  return iResult;
}

// #################################################################################
Int_t AliHLTVZERORecoComponent::Reconfigure(const Char_t* cdbEntry, const Char_t* chainId) {
  // see header file for class documentation

  Int_t iResult=0;
  TString cdbPath;
  if (cdbEntry) {
    cdbPath=cdbEntry;
  } else {
    cdbPath="HLT/ConfigVZERO/";
    cdbPath+=GetComponentID();
  }

  AliInfoClass(Form("reconfigure '%s' from entry %s%s", chainId, cdbPath.Data(), cdbEntry?"":" (default)"));
  iResult=ConfigureFromCDBTObjString(cdbPath);

  return iResult;
}

// #################################################################################
Int_t AliHLTVZERORecoComponent::ReadPreprocessorValues(const Char_t* /*modules*/) {
  // see header file for class documentation
  ALIHLTERRORGUARD(5, "ReadPreProcessorValues not implemented for this component");
  return 0;
}
<commit_msg>Add time delay to Info<commit_after>//-*- Mode: C++ -*-
// $Id: AliHLTVZERORecoComponent.cxx $
/**************************************************************************
 * This file is property of and copyright by the ALICE HLT Project        *
 * ALICE Experiment at CERN, All rights reserved.                         *
 *                                                                        *
 * Primary Authors: Jochen Thaeder <jochen@thaeder.de>                    *
 *                  for The ALICE HLT Project.                            *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/** @file    AliHLTVZERORecoComponent.cxx
    @author  Jochen Thaeder <jochen@thaeder.de>
    @brief   VZERO reconstruction component
*/

#if __GNUC__>= 3
using namespace std;
#endif

#include "TTree.h"
#include "TMap.h"
#include "TObjString.h"
#include "TDatime.h"

#include "AliLog.h"
#include "AliRunInfo.h"
#include "AliGRPObject.h"
#include "AliRawReaderMemory.h"
#include "AliGeomManager.h"

#include "AliVZERORecoParam.h"
#include "AliVZEROReconstructor.h"

#include "AliHLTErrorGuard.h"
#include "AliHLTDataTypes.h"
#include "AliHLTVZERORecoComponent.h"

/** ROOT macro for the implementation of ROOT specific class methods */
ClassImp(AliHLTVZERORecoComponent)

/*
 * ---------------------------------------------------------------------------------
 *                            Constructor / Destructor
 * ---------------------------------------------------------------------------------
 */

// #################################################################################
AliHLTVZERORecoComponent::AliHLTVZERORecoComponent() :
  AliHLTProcessor(),
  fRunInfo(NULL),
  fVZERORecoParam(NULL),
  fVZEROReconstructor(NULL),
  fRawReader(NULL) {
  // an example component which implements the ALICE HLT processor
  // interface and does some analysis on the input raw data
  //
  // see header file for class documentation
  // or
  // refer to README to build package
  // or
  // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
  //
  // NOTE: all helper classes should be instantiated in DoInit()
}

// #################################################################################
AliHLTVZERORecoComponent::~AliHLTVZERORecoComponent() {
  // see header file for class documentation
}

/*
 * ---------------------------------------------------------------------------------
 * Public functions to implement AliHLTComponent's interface.
 * These functions are required for the registration process
 * ---------------------------------------------------------------------------------
 */

// #################################################################################
const Char_t* AliHLTVZERORecoComponent::GetComponentID() {
  // see header file for class documentation
  return "VZEROReconstruction";
}

// #################################################################################
void AliHLTVZERORecoComponent::GetInputDataTypes( vector<AliHLTComponentDataType>& list) {
  // see header file for class documentation
  list.push_back(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginVZERO);
}

// #################################################################################
AliHLTComponentDataType AliHLTVZERORecoComponent::GetOutputDataType() {
  // see header file for class documentation
  return kAliHLTDataTypeESDContent|kAliHLTDataOriginVZERO;
}

// #################################################################################
void AliHLTVZERORecoComponent::GetOutputDataSize( ULong_t& constBase, Double_t& inputMultiplier ) {
  // see header file for class documentation
  constBase = 1000;
  inputMultiplier = 0.5;
}

// #################################################################################
void AliHLTVZERORecoComponent::GetOCDBObjectDescription( TMap* const targetMap) {
  // see header file for class documentation

  if (!targetMap) return;
  targetMap->Add(new TObjString("HLT/ConfigVZERO/VZEROReconstruction"),
		 new TObjString("configuration object"));

  targetMap->Add(new TObjString("GRP/GRP/Data"),
		 new TObjString("GRP object - run information"));
  targetMap->Add(new TObjString("GRP/CTP/CTPtiming"),
		 new TObjString("GRP object - CTP information"));
  targetMap->Add(new TObjString("GRP/CTP/TimeAlign"),
		 new TObjString("GRP object - CTP information"));
  targetMap->Add(new TObjString("GRP/Calib/LHCClockPhase"),
		 new TObjString("GRP object - time calibration"));

  targetMap->Add(new TObjString("VZERO/Calib/Data"),
		 new TObjString("VZERO calibration object"));
  targetMap->Add(new TObjString("VZERO/Calib/TimeDelays"),
		 new TObjString("VZERO calibration object"));
  targetMap->Add(new TObjString("VZERO/Calib/TimeSlewing"),
		 new TObjString("VZERO calibration object"));

  return;
}

// #################################################################################
AliHLTComponent* AliHLTVZERORecoComponent::Spawn() {
  // see header file for class documentation
  return new AliHLTVZERORecoComponent;
}

/*
 * ---------------------------------------------------------------------------------
 * Protected functions to implement AliHLTComponent's interface.
 * These functions provide initialization as well as the actual processing
 * capabilities of the component.
 * ---------------------------------------------------------------------------------
 */

// #################################################################################
Int_t AliHLTVZERORecoComponent::DoInit( Int_t argc, const Char_t** argv ) {
  // see header file for class documentation

  Int_t iResult=0;

  // -- Load GeomManager
  if(AliGeomManager::GetGeometry()==NULL){
    AliGeomManager::LoadGeometry();
  }

  // -- Read configuration object : HLT/ConfigVZERO/VZEROReconstruction
  TString cdbPath="HLT/ConfigVZERO/";
  cdbPath+=GetComponentID();
  iResult=ConfigureFromCDBTObjString(cdbPath);

  // -- Read the component arguments
  if (iResult>=0) {
    iResult=ConfigureFromArgumentString(argc, argv);
  }

  // -- Get AliRunInfo variables
  // -----------------------------
  TObject* pOCDBEntry=LoadAndExtractOCDBObject("GRP/GRP/Data");
  AliGRPObject* pGRP=pOCDBEntry?dynamic_cast<AliGRPObject*>(pOCDBEntry):NULL;

  TString beamType = "";
  TString lhcState = "";
  TString runType = "";
  Float_t beamEnergy = 0.;
  UInt_t activeDetectors = 0;

  if (pGRP) {
    lhcState        = pGRP->GetLHCState();
    beamType        = pGRP->GetBeamType();
    runType         = pGRP->GetRunType();
    beamEnergy      = pGRP->GetBeamEnergy();
    activeDetectors = pGRP->GetDetectorMask();
  }

  // -- Initialize members
  // -----------------------
  do {
    if (iResult<0) break;

    fRawReader = new AliRawReaderMemory;
    if (!fRawReader) {
      iResult=-ENOMEM;
      break;
    }

    // AliGRPManager grpMan;
    // Bool_t status       = grpMan.ReadGRPEntry(); // Read the corresponding OCDB entry
    // status              = grpMan.SetMagField();  // Set global field instanton
    // AliRunInfo *runInfo = grpMan.GetRunInfo();   // Get instance of run info

    fRunInfo = new AliRunInfo(lhcState.Data(), beamType.Data(),
			      beamEnergy, runType.Data(), activeDetectors);
    if (!fRunInfo) {
      iResult=-ENOMEM;
      break;
    }

    fVZERORecoParam = new AliVZERORecoParam;
    if (!fVZERORecoParam) {
      iResult=-ENOMEM;
      break;
    }

    fVZEROReconstructor = new AliVZEROReconstructor;
    if (!fVZEROReconstructor) {
      iResult=-ENOMEM;
      break;
    }

    // implement further initialization
  } while (0);

  if (iResult<0) {
    // implement cleanup

    if (fRawReader)
      delete fRawReader;
    fRawReader = NULL;

    if (fVZERORecoParam)
      delete fVZERORecoParam;
    fVZERORecoParam = NULL;

    if (fVZEROReconstructor)
      delete fVZEROReconstructor;
    fVZEROReconstructor = NULL;

    if (fRunInfo)
      delete fRunInfo;
    fRunInfo = NULL;
  }

  if (iResult>=0) {
    fVZEROReconstructor->SetRunInfo(fRunInfo);
    fVZEROReconstructor->Init();

    fVZEROReconstructor->SetRecoParam(fVZERORecoParam);
  }

  return iResult;
}

// #################################################################################
Int_t AliHLTVZERORecoComponent::ScanConfigurationArgument(Int_t /*argc*/, const Char_t** argv) {
  // Scan configuration arguments
  // Return the number of processed arguments
  //        -EPROTO if argument format error (e.g. number expected but not found)
  //
  // The AliHLTComponent base class implements a parsing loop for argument strings and
  // arrays of strings which is invoked by ConfigureFromArgumentString/ConfigureFromCDBTObjString
  // The component needs to implement ScanConfigurationArgument in order to decode the arguments.

  Int_t ii =0;
  TString argument=argv[ii];

  if (argument.IsNull()) return 0;

  return 0;
}

// #################################################################################
Int_t AliHLTVZERORecoComponent::DoDeinit() {
  // see header file for class documentation

  if (fRawReader)
    delete fRawReader;
  fRawReader = NULL;

  if (fVZERORecoParam)
    delete fVZERORecoParam;
  fVZERORecoParam = NULL;

  if (fVZEROReconstructor)
    delete fVZEROReconstructor;
  fVZEROReconstructor = NULL;

  if (fRunInfo)
    delete fRunInfo;
  fRunInfo = NULL;

  return 0;
}

// #################################################################################
Int_t AliHLTVZERORecoComponent::DoEvent(const AliHLTComponentEventData& /*evtData*/,
					AliHLTComponentTriggerData& /*trigData*/) {
  // see header file for class documentation

  Int_t iResult=0;

  // -- Only use data event
  if (!IsDataEvent())
    return 0;

  // -- Get VZERO raw dat a input block and set up the rawreader
  const AliHLTComponentBlockData* pBlock = GetFirstInputBlock(kAliHLTDataTypeDDLRaw|kAliHLTDataOriginVZERO);
  if (!pBlock) {
    HLTInfo("No VZERO input block !!!");
    return 0;
  }

  // -- Add input block to raw reader
  if (!fRawReader->SetMemory((UChar_t*) pBlock->fPtr, pBlock->fSize )){
    HLTError("Could not add buffer of data block  %s, 0x%08x to rawreader",
	     DataType2Text(pBlock->fDataType).c_str(), pBlock->fSpecification);
    iResult = -1;
  }

  TTree *digitsTree = new TTree("D", "Digits Tree");
  if (!digitsTree) {
    iResult=-ENOMEM;
  }

  if (iResult >= 0) {

    // -- Set VZERO EquipmentID
    fRawReader->SetEquipmentID(3584);

    // -- 1. step VZERO reconstruction
    fVZEROReconstructor->ConvertDigits(fRawReader, digitsTree);

    // -- 2. step VZERO reconstruction -- fill AliESDVZERO object
    fVZEROReconstructor->FillESD(digitsTree, NULL, NULL);

    AliESDVZERO *esdVZERO = fVZEROReconstructor->GetESDVZERO();

    // Send info every 10 s
    const TDatime time;
    static UInt_t lastTime=0;
    if (time.Get()-lastTime>10) {
      lastTime=time.Get();
      HLTInfo("VZERO Multiplicity A %f - C %f", esdVZERO->GetMTotV0A(), esdVZERO->GetMTotV0A() );
    }

    // -- Send AliESDVZERO
    PushBack(esdVZERO, kAliHLTDataTypeESDContent|kAliHLTDataOriginVZERO,0);
  }

  // -- Clean up
  delete digitsTree;
  fRawReader->ClearBuffers();

  return iResult;
}

// #################################################################################
Int_t AliHLTVZERORecoComponent::Reconfigure(const Char_t* cdbEntry, const Char_t* chainId) {
  // see header file for class documentation

  Int_t iResult=0;
  TString cdbPath;
  if (cdbEntry) {
    cdbPath=cdbEntry;
  } else {
    cdbPath="HLT/ConfigVZERO/";
    cdbPath+=GetComponentID();
  }

  AliInfoClass(Form("reconfigure '%s' from entry %s%s", chainId, cdbPath.Data(), cdbEntry?"":" (default)"));
  iResult=ConfigureFromCDBTObjString(cdbPath);

  return iResult;
}

// #################################################################################
Int_t AliHLTVZERORecoComponent::ReadPreprocessorValues(const Char_t* /*modules*/) {
  // see header file for class documentation
  ALIHLTERRORGUARD(5, "ReadPreProcessorValues not implemented for this component");
  return 0;
}
<|endoftext|>


<commit_before>
#include "physics/inertia_tensor.hpp"

#include "geometry/barycentre_calculator.hpp"
#include "geometry/frame.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/point.hpp"
#include "geometry/r3_element.hpp"
#include "geometry/r3x3_matrix.hpp"
#include "gtest/gtest.h"
#include "quantities/numbers.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "serialization/geometry.pb.h"
#include "testing_utilities/almost_equals.hpp"
#include "testing_utilities/approximate_quantity.hpp"
#include "testing_utilities/componentwise.hpp"
#include "testing_utilities/is_near.hpp"
#include "testing_utilities/numerics_matchers.hpp"
#include "testing_utilities/vanishes_before.hpp"

namespace principia {
namespace physics {

using geometry::Barycentre;
using geometry::Displacement;
using geometry::Frame;
using geometry::Position;
using geometry::R3Element;
using geometry::R3x3Matrix;
using quantities::Density;
using quantities::Length;
using quantities::Mass;
using quantities::MomentOfInertia;
using quantities::Pow;
using quantities::SIUnit;
using quantities::si::Kilogram;
using quantities::si::Metre;
using testing_utilities::Componentwise;
using testing_utilities::IsNear;
using testing_utilities::RelativeErrorFrom;
using testing_utilities::VanishesBefore;
using testing_utilities::operator""_⑴;
using ::testing::Matcher;

// See https://en.wikipedia.org/wiki/List_of_moments_of_inertia.
class InertiaTensorTest : public ::testing::Test {
 protected:
  using Frame1 = Frame<serialization::Frame::TestTag,
                       serialization::Frame::TEST1,
                       /*frame_is_inertial=*/true>;
  using Frame2 = Frame<serialization::Frame::TestTag,
                       serialization::Frame::TEST2,
                       /*frame_is_inertial=*/true>;
  using Frame3 = Frame<serialization::Frame::TestTag,
                       serialization::Frame::TEST3,
                       /*frame_is_inertial=*/true>;

  template<typename Frame>
  void CheckMomentsOfInertia(
      InertiaTensor<Frame> const& tensor,
      Matcher<R3Element<MomentOfInertia>> const& matcher) {
    struct PrincipalAxesFrame {};
    auto const principal_axes = tensor.Diagonalize<PrincipalAxesFrame>();
    EXPECT_THAT(principal_axes.moments_of_inertia, matcher);
  }
};

TEST_F(InertiaTensorTest, PointMass) {
  Mass const mass = 3 * Kilogram;

  using CentreOfMass = Frame1;
  using GeneralPoint = Frame2;

  InertiaTensor<CentreOfMass> const inertia_tensor_centre_of_mass(
      mass,
      SIUnit<MomentOfInertia>() * R3x3Matrix<double>{{0, 0, 0},
                                                     {0, 0, 0},
                                                     {0, 0, 0}},
      CentreOfMass::origin);

  auto const displacement =
      Displacement<CentreOfMass>({1 * Metre, 2 * Metre, 4 * Metre});
  InertiaTensor<GeneralPoint> const inertia_tensor_general_point =
      inertia_tensor_centre_of_mass.Translate<GeneralPoint>(
          CentreOfMass::origin + displacement);

  // One of the principal axes goes through the centre of mass and the general
  // point, and it has no inertia.  The other principal axes are orthogonal and
  // they have the same inertia, which is the elementary inertia of a point with
  // respect to an axis.
  MomentOfInertia const moment_of_inertia = mass * displacement.Norm²();
  CheckMomentsOfInertia(
      inertia_tensor_general_point,
      Componentwise(VanishesBefore(moment_of_inertia, 2),
                    RelativeErrorFrom(moment_of_inertia, IsNear(2.9e-9_⑴)),
                    RelativeErrorFrom(moment_of_inertia, IsNear(2.9e-9_⑴))));
}

//TEST(InertiaTensorTest, Abdulghany) {
//  using F1 = Frame<serialization::Frame::TestTag,
//                   serialization::Frame::TEST1,
//                   /*frame_is_inertial=*/true>;
//  using F2 = Frame<serialization::Frame::TestTag,
//                   serialization::Frame::TEST2,
//                   /*frame_is_inertial=*/true>;
//  using F3 = Frame<serialization::Frame::TestTag,
//                   serialization::Frame::TEST2,
//                   /*frame_is_inertial=*/true>;
//
//  Density const ρ = 13593 * Kilogram / Pow<3>(Metre);
//  Length const r = 3 * Metre;
//  Mass const cuboid_mass = 32 * ρ * Pow<3>(r);
//  Mass const cylinder_mass = 8 * π * ρ * Pow<3>(r);
//
//  Position<F1> const cuboid_centre_of_mass = F1::origin;
//  Position<F1> const cylinder_centre_of_mass =
//      F1::origin + Displacement<F1>({0 * r, 3 * r, 5 * r});
//  Position<F1> const overall_centre_of_mass =
//      Barycentre<Position<F1>, Mass>(
//          {cuboid_centre_of_mass, cylinder_centre_of_mass},
//          {cuboid_mass, cylinder_mass});
//
//  InertiaTensor<F1> const inertia_tensor_cuboid(
//      cuboid_mass,
//      32 * ρ * Pow<5>(r) *
//          R3x3Matrix<double>{{68.0 / 12.0, 0.0, 0.0},
//                             {0.0, 8.0 / 12.0, 0.0},
//                             {0.0, 0.0, 68.0 / 12.0}},
//      cuboid_centre_of_mass);
//  InertiaTensor<F2> const inertia_tensor_cylinder(
//      cylinder_mass,
//      8 * π * ρ * Pow<5>(r) *
//          R3x3Matrix<double>{{67.0 / 12.0, 0.0, 0.0},
//                             {0.0, 67.0 / 12.0, 0.0},
//                             {0.0, 0.0, 1.0 / 2.0}},
//      F2::origin);
//
//  InertiaTensor<F3> itcu =
//      inertia_tensor_cuboid.Translate<F3>(overall_centre_of_mass);
//  InertiaTensor<F3> itcy =
//      inertia_tensor_cylinder.Translate<F3>(overall_centre_of_mass);
//  InertiaTensor<F3> ittot = itcu + itcy;
//}

}  // namespace physics
}  // namespace principia
<commit_msg>Start writing Abdulghany's test.<commit_after>
#include "physics/inertia_tensor.hpp"

#include "geometry/barycentre_calculator.hpp"
#include "geometry/frame.hpp"
#include "geometry/grassmann.hpp"
#include "geometry/named_quantities.hpp"
#include "geometry/point.hpp"
#include "geometry/r3_element.hpp"
#include "geometry/r3x3_matrix.hpp"
#include "geometry/rotation.hpp"
#include "gtest/gtest.h"
#include "quantities/numbers.hpp"
#include "quantities/named_quantities.hpp"
#include "quantities/quantities.hpp"
#include "quantities/si.hpp"
#include "serialization/geometry.pb.h"
#include "testing_utilities/almost_equals.hpp"
#include "testing_utilities/approximate_quantity.hpp"
#include "testing_utilities/componentwise.hpp"
#include "testing_utilities/is_near.hpp"
#include "testing_utilities/numerics_matchers.hpp"
#include "testing_utilities/vanishes_before.hpp"

namespace principia {
namespace physics {

using geometry::Barycentre;
using geometry::Bivector;
using geometry::DefinesFrame;
using geometry::Displacement;
using geometry::Frame;
using geometry::Position;
using geometry::R3Element;
using geometry::R3x3Matrix;
using geometry::Rotation;
using quantities::Density;
using quantities::Length;
using quantities::Mass;
using quantities::MomentOfInertia;
using quantities::Pow;
using quantities::SIUnit;
using quantities::si::Degree;
using quantities::si::Kilogram;
using quantities::si::Metre;
using testing_utilities::Componentwise;
using testing_utilities::IsNear;
using testing_utilities::RelativeErrorFrom;
using testing_utilities::VanishesBefore;
using testing_utilities::operator""_⑴;
using ::testing::Matcher;

// See https://en.wikipedia.org/wiki/List_of_moments_of_inertia.
class InertiaTensorTest : public ::testing::Test {
 protected:
  using Frame1 = Frame<serialization::Frame::TestTag,
                       serialization::Frame::TEST1,
                       /*frame_is_inertial=*/true>;
  using Frame2 = Frame<serialization::Frame::TestTag,
                       serialization::Frame::TEST2,
                       /*frame_is_inertial=*/true>;
  using Frame3 = Frame<serialization::Frame::TestTag,
                       serialization::Frame::TEST3,
                       /*frame_is_inertial=*/true>;

  template<typename Frame>
  void CheckMomentsOfInertia(
      InertiaTensor<Frame> const& tensor,
      Matcher<R3Element<MomentOfInertia>> const& matcher) {
    struct PrincipalAxesFrame {};
    auto const principal_axes = tensor.Diagonalize<PrincipalAxesFrame>();
    EXPECT_THAT(principal_axes.moments_of_inertia, matcher);
  }
};

// A point mass at a certain distance of an axis.
TEST_F(InertiaTensorTest, PointMass) {
  Mass const mass = 3 * Kilogram;

  using CentreOfMass = Frame1;
  using GeneralPoint = Frame2;

  InertiaTensor<CentreOfMass> const inertia_tensor_centre_of_mass(
      mass,
      SIUnit<MomentOfInertia>() * R3x3Matrix<double>{{0, 0, 0},
                                                     {0, 0, 0},
                                                     {0, 0, 0}},
      CentreOfMass::origin);

  auto const displacement =
      Displacement<CentreOfMass>({1 * Metre, 2 * Metre, 4 * Metre});
  InertiaTensor<GeneralPoint> const inertia_tensor_general_point =
      inertia_tensor_centre_of_mass.Translate<GeneralPoint>(
          CentreOfMass::origin + displacement);

  // One of the principal axes goes through the centre of mass and the general
  // point, and it has no inertia.  The other principal axes are orthogonal and
  // they have the same inertia, which is the elementary inertia of a point with
  // respect to an axis.
  MomentOfInertia const moment_of_inertia = mass * displacement.Norm²();
  CheckMomentsOfInertia(
      inertia_tensor_general_point,
      Componentwise(VanishesBefore(moment_of_inertia, 2),
                    RelativeErrorFrom(moment_of_inertia, IsNear(2.9e-9_⑴)),
                    RelativeErrorFrom(moment_of_inertia, IsNear(2.9e-9_⑴))));
}

// A rod with respect to an axis going through its extremity
TEST_F(InertiaTensorTest, Rod) {
  Mass const mass = 3 * Kilogram;
  Length const length = 5 * Metre;

  using CentreOfMass = Frame1;
  using Extremity = Frame2;

  InertiaTensor<CentreOfMass> const inertia_tensor_centre_of_mass(
      mass,
      mass * Pow<2>(length) * R3x3Matrix<double>{{0, 0, 0},
                                                 {0, 1.0 / 12.0, 0},
                                                 {0, 0, 1.0 / 12.0}},
      CentreOfMass::origin);

  auto const displacement =
      Displacement<CentreOfMass>({length / 2.0, 0 * Metre, 0 * Metre});
  InertiaTensor<Extremity> const inertia_tensor_extremity =
      inertia_tensor_centre_of_mass.Translate<Extremity>(
          CentreOfMass::origin + displacement);

  // One of the principal axes goes through the axis of the rod, and it has no
  // inertia.  The other principal axes are orthogonal and they have the same
  // inertia.
  MomentOfInertia const moment_of_inertia = mass * Pow<2>(length) / 3.0;
  CheckMomentsOfInertia(
      inertia_tensor_extremity,
      Componentwise(VanishesBefore(moment_of_inertia, 1),
                    RelativeErrorFrom(moment_of_inertia, IsNear(4.1e-9_⑴)),
                    RelativeErrorFrom(moment_of_inertia, IsNear(4.1e-9_⑴))));
}

TEST_F(InertiaTensorTest, Abdulghany) {
  constexpr MomentOfInertia zero;
  Density const ρ = 13593 * Kilogram / Pow<3>(Metre);  // Hg.

  using CylinderCentreOfMassZ = Frame1;
  using CuboidCentreOfMassZ = Frame2;
  using CuboidCentreOfMassY = Frame3;

  Length const cylinder_radius = 3 * Metre;
  Length const cylinder_height = 24 * Metre;
  Mass const cylinder_mass = π * ρ * Pow<2>(cylinder_radius) * cylinder_height;

  // The cylinder with its axis along z.
  MomentOfInertia const cylinder_axis_inertia =
      cylinder_mass * Pow<2>(cylinder_radius) / 2.0;
  MomentOfInertia const cylinder_orthogonal_inertia =
      cylinder_mass *
      (3.0 * Pow<2>(cylinder_radius) + Pow<2>(cylinder_height)) / 12.0;
  InertiaTensor<CylinderCentreOfMassZ> const
      cylinder_inertia_centre_of_mass_z(
          cylinder_mass,
          R3x3Matrix<MomentOfInertia>{{cylinder_orthogonal_inertia, zero, zero},
                                      {zero, cylinder_orthogonal_inertia, zero},
                                      {zero, zero, cylinder_axis_inertia}},
          CylinderCentreOfMassZ::origin);

  Length const cuboid_small_side = 6 * Metre;
  Length const cuboid_long_side = 24 * Metre;
  Mass const cuboid_mass = ρ * Pow<2>(cuboid_small_side) * cuboid_long_side;

  // The cuboid with its long axis along z.
  MomentOfInertia const cuboid_long_axis_inertia =
      cuboid_mass * (Pow<2>(cuboid_small_side) + Pow<2>(cuboid_small_side)) /
      12.0;
  MomentOfInertia const cuboid_short_axis_inertia =
      cuboid_mass * (Pow<2>(cuboid_small_side) + Pow<2>(cuboid_long_side)) /
      12.0;
  InertiaTensor<CuboidCentreOfMassZ> const cuboid_inertia_centre_of_mass_z(
      cuboid_mass,
      R3x3Matrix<MomentOfInertia>{{cylinder_orthogonal_inertia, zero, zero},
                                  {zero, cylinder_orthogonal_inertia, zero},
                                  {zero, zero, cylinder_axis_inertia}},
      CuboidCentreOfMassZ::origin);

  // Rotate the cuboid around the x axis.
  InertiaTensor<CuboidCentreOfMassY> const cuboid_inertia_centre_of_mass_y =
      cuboid_inertia_centre_of_mass_z.Rotate(
          Rotation<CuboidCentreOfMassZ, CuboidCentreOfMassY>(
              90 * Degree,
              Bivector<double, CuboidCentreOfMassZ>({1, 0, 0}),
              DefinesFrame<CuboidCentreOfMassY>{}));

  // Translate the cylinder.
  Position<CylinderCentreOfMassZ> const translated_cylinder_centre_of_mass =
      CylinderCentreOfMassZ::origin +
      Displacement<CylinderCentreOfMassZ>(
          {0 * Metre,
           cuboid_long_side / 2.0 - cylinder_radius,
           cylinder_height / 2.0 + cuboid_small_side / 2.0});
  InertiaTensor<CuboidCentreOfMassY> const
      translated_cylinder_inertia_centre_of_mass_z =
          cylinder_inertia_centre_of_mass_z.Translate<CuboidCentreOfMassY>(
              translated_cylinder_centre_of_mass);

}

}  // namespace physics
}  // namespace principia
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkGraphHierarchicalBundle.cxx

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

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

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
#include "vtkGraphHierarchicalBundle.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkFloatArray.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkIdTypeArray.h"
#include "vtkAbstractGraph.h"
#include "vtkTree.h"
#include "vtkStdString.h"

#include <vtksys/stl/map>
using vtksys_stl::map;

vtkCxxRevisionMacro(vtkGraphHierarchicalBundle, "1.3");
vtkStandardNewMacro(vtkGraphHierarchicalBundle);

vtkGraphHierarchicalBundle::vtkGraphHierarchicalBundle()
{
  this->BundlingStrength = 0.8;
  this->SetNumberOfInputPorts(2);
  this->DirectMapping = false;
}

int vtkGraphHierarchicalBundle::FillInputPortInformation(int port, vtkInformation* info)
{
  if (port == 0)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkAbstractGraph");
    return 1;
    }
  else if (port == 1)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTree");
    return 1;
    }
  return 0;
}

template <typename T>
void mappingMadness(T *graphIds, T *treeIds,
                    map<vtkIdType,vtkIdType> *idMap, int numVertices)
{
  map<T,vtkIdType> graphIdMap;

  // Now create the two maps
  for (int i=0; i<numVertices; ++i)
    {
    graphIdMap[graphIds[i]] = i;
    }

  // Now create the output map
  for (int i=0; i<numVertices; ++i)
    {
    (*idMap)[graphIdMap[treeIds[i]]] = i;
    }
}

int vtkGraphHierarchicalBundle::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *graphInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *treeInfo = inputVector[1]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and ouptut
  vtkAbstractGraph *graph = vtkAbstractGraph::SafeDownCast(
    graphInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkTree *tree = vtkTree::SafeDownCast(
    treeInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // Create a map from graph indices to tree indices
  // If we are using DirectMapping this is trivial
  // we just create an identity map
  map<vtkIdType, vtkIdType> graphIndexToTreeIndex;
  if (this->DirectMapping)
    {
    if (graph->GetNumberOfVertices() > tree->GetNumberOfVertices())
      {
      vtkErrorMacro("Cannot have more graph vertices than tree vertices using direct mapping.");
      return 0;
      }
    // Create identity map.
    for (vtkIdType gv = 0; gv < graph->GetNumberOfVertices(); gv++)
      {
      graphIndexToTreeIndex[gv] = gv;
      }
    }

  // Okay if we do not have direct mapping then we need
  // to do some templated madness to go from an arbitrary
  // type to a nice vtkIdType to vtkIdType mapping
  if (!this->DirectMapping)
    {
    // Check for valid pedigree id arrays.
    vtkAbstractArray* graphIdArray =
      graph->GetVertexData()->GetAbstractArray("PedigreeId");
    if (graphIdArray == NULL)
      {
      // Check for any id array.
      graphIdArray = graph->GetVertexData()->GetAbstractArray("id");
      if (graphIdArray == NULL)
        {
        vtkErrorMacro("Graph pedigree id array not found.");
        return 0;
        }
      }
    vtkAbstractArray* treeIdArray =
      tree->GetVertexData()->GetAbstractArray("PedigreeId");
    if (treeIdArray == NULL)
      {
      // Check for any id array.
      treeIdArray = tree->GetVertexData()->GetAbstractArray("id");
      if (treeIdArray == NULL)
        {
        vtkErrorMacro("Tree pedigree id array not found.");
        return 0;
        }
      }
    if (graphIdArray->GetDataType() != treeIdArray->GetDataType())
      {
      vtkErrorMacro("Pedigree id types not not match.");
      return 0;
      }

    // Create void pointers that will be recast within
    // the template macro
    void *graphVoid = graphIdArray->GetVoidPointer(0);
    void *treeVoid = treeIdArray->GetVoidPointer(0);
    switch(graphIdArray->GetDataType())
      {
      vtkExtendedTemplateMacro(mappingMadness(static_cast<VTK_TT*>(graphVoid),
                                      static_cast<VTK_TT*>(treeVoid),
                                      &graphIndexToTreeIndex,
                                      tree->GetNumberOfVertices()));
      }
    }

  // Make a point array holding the fraction of the distance
  // source to target.
  vtkPoints* newPoints = vtkPoints::New();
  newPoints->DeepCopy(tree->GetPoints());
  vtkFloatArray* fractionArray = vtkFloatArray::New();
  fractionArray->SetName("fraction");
  vtkIdType numVertices = tree->GetNumberOfVertices();
  for (vtkIdType i = 0; i < numVertices; i++)
    {
    fractionArray->InsertNextValue(0);
    }

  // Insert additional points for incoming vertices.
  for (vtkIdType i = 0; i < numVertices; i++)
    {
    double pt[3];
    newPoints->GetPoint(i, pt);
    newPoints->InsertNextPoint(pt);
    fractionArray->InsertNextValue(1);
    }

  // Prepare to copy cell data
  output->GetCellData()->CopyAllocate(graph->GetEdgeData());

  // Traverse graph edge list, adding polylines for each edge
  // using the tree hierarchy to "guide" the edges.
  vtkCellArray* newLines = vtkCellArray::New();
  vtkIdList* sourceList = vtkIdList::New();
  vtkIdList* targetList = vtkIdList::New();
  for (vtkIdType i = 0; i < graph->GetNumberOfEdges(); i++)
    {
    unsigned int graphSourceIndex = graph->GetSourceVertex(i);
    unsigned int graphTargetIndex = graph->GetTargetVertex(i);

    // Do not render loops
    if (graphSourceIndex == graphTargetIndex)
      {
      continue;
      }

    vtkIdType source = 0;
    vtkIdType target = 0;
    if (graphSourceIndex < graphIndexToTreeIndex.size()&&
        graphTargetIndex < graphIndexToTreeIndex.size())
      {
      source = graphIndexToTreeIndex[graphSourceIndex];
      target = graphIndexToTreeIndex[graphTargetIndex];
      }
    else
      {
      // The endpoints of this edge are not found in the tree.
      continue;
      }

    // Find path from source to target
    sourceList->Reset();
    vtkIdType curSource = source;
    while (curSource != tree->GetRoot())
      {
      curSource = tree->GetParent(curSource);
      sourceList->InsertNextId(curSource);
      }
    targetList->Reset();
    vtkIdType curTarget = target;
    while (sourceList->IsId(curTarget) == -1 && curTarget != source)
      {
      curTarget = tree->GetParent(curTarget);
      targetList->InsertNextId(curTarget);
      }

    vtkIdType cellPoints;
    if (curTarget == source)
      {
      cellPoints = 2 + targetList->GetNumberOfIds();
      }
    else
      {
      cellPoints = 2 + sourceList->IsId(curTarget) + targetList->GetNumberOfIds();
      }

    // We may eliminate a common ancestor if:
    // 1. The source is not an ancestor of the target
    // 2. The target is not an ancestor of the source
    // 3. The number of points along the path is at least 4
    bool eliminateCommonAncestor = false;
    if (sourceList->IsId(target) == -1 && targetList->IsId(source) == -1 && cellPoints >= 4)
      {
      cellPoints--;
      eliminateCommonAncestor = true;
      }

    // Create the new cell
    vtkIdType cellId = newLines->InsertNextCell(cellPoints);
    output->GetCellData()->CopyData(graph->GetEdgeData(), i, cellId);

    double cellPointsD = static_cast<double>(cellPoints);
    double sourcePt[3];
    newPoints->GetPoint(source, sourcePt);
    double targetPt[3];
    newPoints->GetPoint(target, targetPt);

    // Insert a point into the polyline for the source vertex.
    double pt[3];
    double interpPt[3];
    vtkIdType curPoint = 0;
    newLines->InsertCellPoint(source);
    curPoint++;

    // Insert points into the polyline going up the tree to
    // the common ancestor.
    for (vtkIdType s = 0; s < sourceList->IsId(curTarget); s++)
      {
      tree->GetPoint(sourceList->GetId(s), pt);
      for (int c = 0; c < 3; c++)
        {
        interpPt[c] = (1.0 - curPoint/cellPointsD)*sourcePt[c]
          + (curPoint/cellPointsD)*targetPt[c];
        interpPt[c] = (1.0 - this->BundlingStrength)*interpPt[c]
          + this->BundlingStrength*pt[c];
        }
      vtkIdType ptId = newPoints->InsertNextPoint(interpPt);
      newLines->InsertCellPoint(ptId);
      fractionArray->InsertNextValue(curPoint/cellPointsD);
      curPoint++;
      }

    // Insert points into the polyline going down the tree from
    // the common ancestor to the target vertex, possibly excluding
    // the common ancestor if it is a long path.
    vtkIdType maxTargetId = targetList->GetNumberOfIds() - 1;
    if (eliminateCommonAncestor)
      {
      maxTargetId = targetList->GetNumberOfIds() - 2;
      }
    for (vtkIdType t = maxTargetId; t >= 0; t--)
      {
      tree->GetPoint(targetList->GetId(t), pt);
      for (int c = 0; c < 3; c++)
        {
        interpPt[c] = (1.0 - curPoint/cellPointsD)*sourcePt[c]
          + (curPoint/cellPointsD)*targetPt[c];
        interpPt[c] = (1.0 - this->BundlingStrength)*interpPt[c]
          + this->BundlingStrength*pt[c];
        }
      vtkIdType ptId = newPoints->InsertNextPoint(interpPt);
      newLines->InsertCellPoint(ptId);
      fractionArray->InsertNextValue(curPoint/cellPointsD);
      curPoint++;
      }

    // The incoming vertex point is stored at vertex + numVertices
    newLines->InsertCellPoint(target + numVertices);
    curPoint++;
    if (curPoint != cellPoints)
      {
      vtkErrorMacro(<< "Number of points mismatch! Expected " << cellPoints << ", have " << curPoint);
      cerr << "Number of points mismatch! Expected " << cellPoints << ", have " << curPoint << endl;
      cerr << source << "," << target << endl;
      }
    }
  output->GetPointData()->AddArray(fractionArray);

  // Send the data to output.
  output->SetLines(newLines);
  output->SetPoints(newPoints);

  // Clean up.
  newLines->Delete();
  newPoints->Delete();
  sourceList->Delete();
  targetList->Delete();
  fractionArray->Delete();

  return 1;
}

void vtkGraphHierarchicalBundle::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "BundlingStrength: " << this->BundlingStrength << endl;
  os << indent << "DirectMapping: " << this->DirectMapping << endl;
}

<commit_msg>BUG: Disregard last checkin. The correct thing to do was use both the number of graph vertices and tree vertices depending on the map your constructing. So should be fixed now (as opposed to before :)<commit_after>/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkGraphHierarchicalBundle.cxx

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

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

=========================================================================*/
/*----------------------------------------------------------------------------
 Copyright (c) Sandia Corporation
 See Copyright.txt or http://www.paraview.org/HTML/Copyright.html for details.
----------------------------------------------------------------------------*/
#include "vtkGraphHierarchicalBundle.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkFloatArray.h"
#include "vtkMath.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkIdTypeArray.h"
#include "vtkAbstractGraph.h"
#include "vtkTree.h"
#include "vtkStdString.h"

#include <vtksys/stl/map>
using vtksys_stl::map;

vtkCxxRevisionMacro(vtkGraphHierarchicalBundle, "1.4");
vtkStandardNewMacro(vtkGraphHierarchicalBundle);

vtkGraphHierarchicalBundle::vtkGraphHierarchicalBundle()
{
  this->BundlingStrength = 0.8;
  this->SetNumberOfInputPorts(2);
  this->DirectMapping = false;
}

int vtkGraphHierarchicalBundle::FillInputPortInformation(int port, vtkInformation* info)
{
  if (port == 0)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkAbstractGraph");
    return 1;
    }
  else if (port == 1)
    {
    info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTree");
    return 1;
    }
  return 0;
}

template <typename T>
void mappingMadness(T *graphIds, T *treeIds, map<vtkIdType,vtkIdType> *idMap,
                    int numGraphVertices, int numTreeVertices)
{
  map<T,vtkIdType> graphIdMap;

  // Now create the two maps
  for (int i=0; i<numGraphVertices; ++i)
    {
    graphIdMap[graphIds[i]] = i;
    }

  // Now create the output map
  for (int i=0; i<numTreeVertices; ++i)
    {
    (*idMap)[graphIdMap[treeIds[i]]] = i;
    }
}

int vtkGraphHierarchicalBundle::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
{
  // get the info objects
  vtkInformation *graphInfo = inputVector[0]->GetInformationObject(0);
  vtkInformation *treeInfo = inputVector[1]->GetInformationObject(0);
  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  // get the input and ouptut
  vtkAbstractGraph *graph = vtkAbstractGraph::SafeDownCast(
    graphInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkTree *tree = vtkTree::SafeDownCast(
    treeInfo->Get(vtkDataObject::DATA_OBJECT()));
  vtkPolyData *output = vtkPolyData::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  // Create a map from graph indices to tree indices
  // If we are using DirectMapping this is trivial
  // we just create an identity map
  map<vtkIdType, vtkIdType> graphIndexToTreeIndex;
  if (this->DirectMapping)
    {
    if (graph->GetNumberOfVertices() > tree->GetNumberOfVertices())
      {
      vtkErrorMacro("Cannot have more graph vertices than tree vertices using direct mapping.");
      return 0;
      }
    // Create identity map.
    for (vtkIdType gv = 0; gv < graph->GetNumberOfVertices(); gv++)
      {
      graphIndexToTreeIndex[gv] = gv;
      }
    }

  // Okay if we do not have direct mapping then we need
  // to do some templated madness to go from an arbitrary
  // type to a nice vtkIdType to vtkIdType mapping
  if (!this->DirectMapping)
    {
    // Check for valid pedigree id arrays.
    vtkAbstractArray* graphIdArray =
      graph->GetVertexData()->GetAbstractArray("PedigreeId");
    if (graphIdArray == NULL)
      {
      // Check for any id array.
      graphIdArray = graph->GetVertexData()->GetAbstractArray("id");
      if (graphIdArray == NULL)
        {
        vtkErrorMacro("Graph pedigree id array not found.");
        return 0;
        }
      }
    vtkAbstractArray* treeIdArray =
      tree->GetVertexData()->GetAbstractArray("PedigreeId");
    if (treeIdArray == NULL)
      {
      // Check for any id array.
      treeIdArray = tree->GetVertexData()->GetAbstractArray("id");
      if (treeIdArray == NULL)
        {
        vtkErrorMacro("Tree pedigree id array not found.");
        return 0;
        }
      }
    if (graphIdArray->GetDataType() != treeIdArray->GetDataType())
      {
      vtkErrorMacro("Pedigree id types not not match.");
      return 0;
      }

    // Create void pointers that will be recast within
    // the template macro
    void *graphVoid = graphIdArray->GetVoidPointer(0);
    void *treeVoid = treeIdArray->GetVoidPointer(0);
    switch(graphIdArray->GetDataType())
      {
      vtkExtendedTemplateMacro(mappingMadness(static_cast<VTK_TT*>(graphVoid),
                                      static_cast<VTK_TT*>(treeVoid),
                                      &graphIndexToTreeIndex,
                                      graph->GetNumberOfVertices(),
                                      tree->GetNumberOfVertices()));
      }
    }

  // Make a point array holding the fraction of the distance
  // source to target.
  vtkPoints* newPoints = vtkPoints::New();
  newPoints->DeepCopy(tree->GetPoints());
  vtkFloatArray* fractionArray = vtkFloatArray::New();
  fractionArray->SetName("fraction");
  vtkIdType numVertices = tree->GetNumberOfVertices();
  for (vtkIdType i = 0; i < numVertices; i++)
    {
    fractionArray->InsertNextValue(0);
    }

  // Insert additional points for incoming vertices.
  for (vtkIdType i = 0; i < numVertices; i++)
    {
    double pt[3];
    newPoints->GetPoint(i, pt);
    newPoints->InsertNextPoint(pt);
    fractionArray->InsertNextValue(1);
    }

  // Prepare to copy cell data
  output->GetCellData()->CopyAllocate(graph->GetEdgeData());

  // Traverse graph edge list, adding polylines for each edge
  // using the tree hierarchy to "guide" the edges.
  vtkCellArray* newLines = vtkCellArray::New();
  vtkIdList* sourceList = vtkIdList::New();
  vtkIdList* targetList = vtkIdList::New();
  for (vtkIdType i = 0; i < graph->GetNumberOfEdges(); i++)
    {
    unsigned int graphSourceIndex = graph->GetSourceVertex(i);
    unsigned int graphTargetIndex = graph->GetTargetVertex(i);

    // Do not render loops
    if (graphSourceIndex == graphTargetIndex)
      {
      continue;
      }

    vtkIdType source = 0;
    vtkIdType target = 0;
    if (graphSourceIndex < graphIndexToTreeIndex.size()&&
        graphTargetIndex < graphIndexToTreeIndex.size())
      {
      source = graphIndexToTreeIndex[graphSourceIndex];
      target = graphIndexToTreeIndex[graphTargetIndex];
      }
    else
      {
      // The endpoints of this edge are not found in the tree.
      continue;
      }

    // Find path from source to target
    sourceList->Reset();
    vtkIdType curSource = source;
    while (curSource != tree->GetRoot())
      {
      curSource = tree->GetParent(curSource);
      sourceList->InsertNextId(curSource);
      }
    targetList->Reset();
    vtkIdType curTarget = target;
    while (sourceList->IsId(curTarget) == -1 && curTarget != source)
      {
      curTarget = tree->GetParent(curTarget);
      targetList->InsertNextId(curTarget);
      }

    vtkIdType cellPoints;
    if (curTarget == source)
      {
      cellPoints = 2 + targetList->GetNumberOfIds();
      }
    else
      {
      cellPoints = 2 + sourceList->IsId(curTarget) + targetList->GetNumberOfIds();
      }

    // We may eliminate a common ancestor if:
    // 1. The source is not an ancestor of the target
    // 2. The target is not an ancestor of the source
    // 3. The number of points along the path is at least 4
    bool eliminateCommonAncestor = false;
    if (sourceList->IsId(target) == -1 && targetList->IsId(source) == -1 && cellPoints >= 4)
      {
      cellPoints--;
      eliminateCommonAncestor = true;
      }

    // Create the new cell
    vtkIdType cellId = newLines->InsertNextCell(cellPoints);
    output->GetCellData()->CopyData(graph->GetEdgeData(), i, cellId);

    double cellPointsD = static_cast<double>(cellPoints);
    double sourcePt[3];
    newPoints->GetPoint(source, sourcePt);
    double targetPt[3];
    newPoints->GetPoint(target, targetPt);

    // Insert a point into the polyline for the source vertex.
    double pt[3];
    double interpPt[3];
    vtkIdType curPoint = 0;
    newLines->InsertCellPoint(source);
    curPoint++;

    // Insert points into the polyline going up the tree to
    // the common ancestor.
    for (vtkIdType s = 0; s < sourceList->IsId(curTarget); s++)
      {
      tree->GetPoint(sourceList->GetId(s), pt);
      for (int c = 0; c < 3; c++)
        {
        interpPt[c] = (1.0 - curPoint/cellPointsD)*sourcePt[c]
          + (curPoint/cellPointsD)*targetPt[c];
        interpPt[c] = (1.0 - this->BundlingStrength)*interpPt[c]
          + this->BundlingStrength*pt[c];
        }
      vtkIdType ptId = newPoints->InsertNextPoint(interpPt);
      newLines->InsertCellPoint(ptId);
      fractionArray->InsertNextValue(curPoint/cellPointsD);
      curPoint++;
      }

    // Insert points into the polyline going down the tree from
    // the common ancestor to the target vertex, possibly excluding
    // the common ancestor if it is a long path.
    vtkIdType maxTargetId = targetList->GetNumberOfIds() - 1;
    if (eliminateCommonAncestor)
      {
      maxTargetId = targetList->GetNumberOfIds() - 2;
      }
    for (vtkIdType t = maxTargetId; t >= 0; t--)
      {
      tree->GetPoint(targetList->GetId(t), pt);
      for (int c = 0; c < 3; c++)
        {
        interpPt[c] = (1.0 - curPoint/cellPointsD)*sourcePt[c]
          + (curPoint/cellPointsD)*targetPt[c];
        interpPt[c] = (1.0 - this->BundlingStrength)*interpPt[c]
          + this->BundlingStrength*pt[c];
        }
      vtkIdType ptId = newPoints->InsertNextPoint(interpPt);
      newLines->InsertCellPoint(ptId);
      fractionArray->InsertNextValue(curPoint/cellPointsD);
      curPoint++;
      }

    // The incoming vertex point is stored at vertex + numVertices
    newLines->InsertCellPoint(target + numVertices);
    curPoint++;
    if (curPoint != cellPoints)
      {
      vtkErrorMacro(<< "Number of points mismatch! Expected " << cellPoints << ", have " << curPoint);
      cerr << "Number of points mismatch! Expected " << cellPoints << ", have " << curPoint << endl;
      cerr << source << "," << target << endl;
      }
    }
  output->GetPointData()->AddArray(fractionArray);

  // Send the data to output.
  output->SetLines(newLines);
  output->SetPoints(newPoints);

  // Clean up.
  newLines->Delete();
  newPoints->Delete();
  sourceList->Delete();
  targetList->Delete();
  fractionArray->Delete();

  return 1;
}

void vtkGraphHierarchicalBundle::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "BundlingStrength: " << this->BundlingStrength << endl;
  os << indent << "DirectMapping: " << this->DirectMapping << endl;
}

<|endoftext|>


<commit_before>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU General Public License as published by the Free  *
* Software Foundation; either version 2 of the License, or (at your option)   *
* any later version.                                                          *
*                                                                             *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
* more details.                                                               *
*                                                                             *
* You should have received a copy of the GNU General Public License along     *
* with this program; if not, write to the Free Software Foundation, Inc., 51  *
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
*******************************************************************************
*                            SOFA :: Applications                             *
*                                                                             *
* Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
* H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
* M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <iostream>
#include <sstream>
#include <fstream>
#include <sofa/helper/ArgumentParser.h>
#include <sofa/simulation/common/xml/initXml.h>
#include <sofa/simulation/common/Node.h>
#ifdef SOFA_DEV
#include <sofa/simulation/bgl/BglSimulation.h>
#endif
#ifdef SOFA_SMP
#include <sofa/simulation/tree/SMPSimulation.h>
#else
#include <sofa/simulation/tree/TreeSimulation.h>
#endif
#include <sofa/component/init.h>
#include <sofa/helper/Factory.h>
#include <sofa/helper/BackTrace.h>
#include <sofa/helper/system/FileRepository.h>
#include <sofa/gui/GUIManager.h>
#include <sofa/helper/system/gl.h>
#include <sofa/helper/system/glut.h>
#include <sofa/helper/system/atomic.h>
#ifdef SOFA_SMP
#include <athapascan-1>
#endif /* SOFA_SMP */

#ifdef SOFA_GPU_CUDA
#include <sofa/gpu/cuda/mycuda.h>
#endif

#ifndef WIN32
#include <dlfcn.h>
bool loadPlugin(const char* filename)
{
    void *handle;
    handle=dlopen(filename, RTLD_LAZY);
    if (!handle)
    {
        std::cerr<<"Error loading plugin "<<filename<<": "<<dlerror()<<std::endl;
        return false;
    }
    std::cerr<<"Plugin "<<filename<<" loaded."<<std::endl;
    return true;
}
#else
bool loadPlugin(const char* filename)
{
    HINSTANCE DLLHandle;
    DLLHandle = LoadLibraryA(filename); //warning: issue between unicode and ansi encoding on Visual c++ -> force to ansi-> dirty!
    if (DLLHandle == NULL)
    {
        std::cerr<<"Error loading plugin "<<filename<<std::endl;
        return false;
    }
    std::cerr<<"Plugin "<<filename<<" loaded."<<std::endl;
    return true;
}
#endif

// ---------------------------------------------------------------------
// ---
// ---------------------------------------------------------------------
int main(int argc, char** argv)
{
    //std::cout << "Using " << sofa::helper::system::atomic<int>::getImplName()<<" atomics." << std::endl;

    sofa::helper::BackTrace::autodump();

    std::string fileName ;
    bool        startAnim = false;
    bool        printFactory = false;
    bool        loadRecent = false;
    bool        temporaryFile = false;
    int nbIterations=0;

    std::string gui = "";
    std::string simulationType = "tree";
    std::vector<std::string> plugins;
    std::vector<std::string> files;
#ifdef SOFA_SMP
    std::string nProcs="";
    bool        disableStealing = false;
#endif

    std::string gui_help = "choose the UI (";
    gui_help += sofa::gui::GUIManager::ListSupportedGUI('|');
    gui_help += ")";

    sofa::helper::parse(&files, "This is a SOFA application. Here are the command line arguments")
    .option(&startAnim,'a',"start","start the animation loop")
    .option(&printFactory,'p',"factory","print factory logs")
    .option(&gui,'g',"gui",gui_help.c_str())
    .option(&nbIterations,'n',"nb_iterations","(only batch) Number of iterations of the simulation")
    .option(&simulationType,'s',"simu","select the type of simulation (bgl, tree)")
    .option(&plugins,'l',"load","load given plugins")
    .option(&loadRecent,'r',"recent","load most recently opened file")
    .option(&temporaryFile,'t',"temporary","the loaded scene won't appear in history of opened files")
#ifdef SOFA_SMP
    .option(&disableStealing,'w',"disableStealing","Disable Work Stealing")
    .option(&nProcs,'c',"nprocs","Number of processor")
#endif
    (argc,argv);
#ifdef SOFA_SMP
    int ac=0;
    char **av=NULL;

    Util::KaapiComponentManager::prop["util.globalid"]="0";
    Util::KaapiComponentManager::prop["sched.strategy"]="I";
    if(!disableStealing)
        Util::KaapiComponentManager::prop["sched.stealing"]="true";
    if(nProcs!="")
        Util::KaapiComponentManager::prop["community.thread.poolsize"]=nProcs;

    a1::Community com = a1::System::join_community( ac, av);
#endif /* SOFA_SMP */

    if(gui!="batch") glutInit(&argc,argv);
#ifdef SOFA_GPU_CUDA
    sofa::gpu::cuda::mycudaInit();
#endif

#ifdef SOFA_DEV
    if (simulationType == "bgl")
    {
        sofa::simulation::setSimulation(new sofa::simulation::bgl::BglSimulation());
    }
    else
#endif
    {
        sofa::simulation::setSimulation(new sofa::simulation::tree::TreeSimulation());
    }
    sofa::component::init();
#ifdef SOFA_SMP
    sofa::simulation::setSimulation(new sofa::simulation::tree::SMPSimulation());
#else
    sofa::simulation::setSimulation(new sofa::simulation::tree::TreeSimulation());
#endif
    sofa::simulation::xml::initXml();

    if (!files.empty()) fileName = files[0];

    for (unsigned int i=0; i<plugins.size(); i++)
        loadPlugin(plugins[i].c_str());

    if(gui.compare("batch") == 0 && nbIterations > 0)
    {
        std::ostringstream oss ;
        oss << "nbIterations=";
        oss << nbIterations;
        sofa::gui::GUIManager::AddGUIOption(oss.str().c_str());
    }

    if (int err=sofa::gui::GUIManager::Init(argv[0],gui.c_str()))
        return err;

    if (fileName.empty())
    {
        if (loadRecent) // try to reload the latest scene
        {
            std::string scenes = "config/Sofa.ini";
            scenes = sofa::helper::system::DataRepository.getFile( scenes );
            std::ifstream mrulist(scenes.c_str());
            std::getline(mrulist,fileName);
            mrulist.close();
        }
        else
            fileName = "Demos/liver.scn";

        fileName = sofa::helper::system::DataRepository.getFile(fileName);
    }

    if (int err=sofa::gui::GUIManager::createGUI(NULL))
        return err;

    //To set a specific resolution for the viewer, use the component ViewerDimensionSetting in you scene graph
    sofa::gui::GUIManager::SetDimension(800,600);

    sofa::simulation::Node* groot = dynamic_cast<sofa::simulation::Node*>( sofa::simulation::getSimulation()->load(fileName.c_str()));
    if (groot==NULL)  groot = sofa::simulation::getSimulation()->newNode("");

    sofa::simulation::getSimulation()->init(groot);
    sofa::gui::GUIManager::SetScene(groot,fileName.c_str(), temporaryFile);

    //=======================================
    //Apply Options

    if (startAnim)  groot->setAnimate(true);

    if (printFactory)
    {
        std::cout << "////////// FACTORY //////////" << std::endl;
        sofa::helper::printFactoryLog();
        std::cout << "//////// END FACTORY ////////" << std::endl;
    }

    //=======================================
    // Run the main loop
    if (int err=sofa::gui::GUIManager::MainLoop(groot,fileName.c_str()))
        return err;
    groot = dynamic_cast<sofa::simulation::Node*>( sofa::gui::GUIManager::CurrentSimulation() );

    if (groot!=NULL) sofa::simulation::getSimulation()->unload(groot);
    return 0;
}
<commit_msg>r7409/sofa-dev : FIX: setting the simulation type was not correctly done with SMP<commit_after>/******************************************************************************
*       SOFA, Simulation Open-Framework Architecture, version 1.0 beta 4      *
*                (c) 2006-2009 MGH, INRIA, USTL, UJF, CNRS                    *
*                                                                             *
* This program is free software; you can redistribute it and/or modify it     *
* under the terms of the GNU General Public License as published by the Free  *
* Software Foundation; either version 2 of the License, or (at your option)   *
* any later version.                                                          *
*                                                                             *
* This program is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or       *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for    *
* more details.                                                               *
*                                                                             *
* You should have received a copy of the GNU General Public License along     *
* with this program; if not, write to the Free Software Foundation, Inc., 51  *
* Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.                   *
*******************************************************************************
*                            SOFA :: Applications                             *
*                                                                             *
* Authors: M. Adam, J. Allard, B. Andre, P-J. Bensoussan, S. Cotin, C. Duriez,*
* H. Delingette, F. Falipou, F. Faure, S. Fonteneau, L. Heigeas, C. Mendoza,  *
* M. Nesme, P. Neumann, J-P. de la Plata Alcade, F. Poyer and F. Roy          *
*                                                                             *
* Contact information: contact@sofa-framework.org                             *
******************************************************************************/
#include <iostream>
#include <sstream>
#include <fstream>
#include <sofa/helper/ArgumentParser.h>
#include <sofa/simulation/common/xml/initXml.h>
#include <sofa/simulation/common/Node.h>
#ifdef SOFA_DEV
#include <sofa/simulation/bgl/BglSimulation.h>
#endif
#ifdef SOFA_SMP
#include <sofa/simulation/tree/SMPSimulation.h>
#else
#include <sofa/simulation/tree/TreeSimulation.h>
#endif
#include <sofa/component/init.h>
#include <sofa/helper/Factory.h>
#include <sofa/helper/BackTrace.h>
#include <sofa/helper/system/FileRepository.h>
#include <sofa/gui/GUIManager.h>
#include <sofa/helper/system/gl.h>
#include <sofa/helper/system/glut.h>
#include <sofa/helper/system/atomic.h>
#ifdef SOFA_SMP
#include <athapascan-1>
#endif /* SOFA_SMP */

#ifdef SOFA_GPU_CUDA
#include <sofa/gpu/cuda/mycuda.h>
#endif

#ifndef WIN32
#include <dlfcn.h>
bool loadPlugin(const char* filename)
{
    void *handle;
    handle=dlopen(filename, RTLD_LAZY);
    if (!handle)
    {
        std::cerr<<"Error loading plugin "<<filename<<": "<<dlerror()<<std::endl;
        return false;
    }
    std::cerr<<"Plugin "<<filename<<" loaded."<<std::endl;
    return true;
}
#else
bool loadPlugin(const char* filename)
{
    HINSTANCE DLLHandle;
    DLLHandle = LoadLibraryA(filename); //warning: issue between unicode and ansi encoding on Visual c++ -> force to ansi-> dirty!
    if (DLLHandle == NULL)
    {
        std::cerr<<"Error loading plugin "<<filename<<std::endl;
        return false;
    }
    std::cerr<<"Plugin "<<filename<<" loaded."<<std::endl;
    return true;
}
#endif

// ---------------------------------------------------------------------
// ---
// ---------------------------------------------------------------------
int main(int argc, char** argv)
{
    //std::cout << "Using " << sofa::helper::system::atomic<int>::getImplName()<<" atomics." << std::endl;

    sofa::helper::BackTrace::autodump();

    std::string fileName ;
    bool        startAnim = false;
    bool        printFactory = false;
    bool        loadRecent = false;
    bool        temporaryFile = false;
    int nbIterations=0;

    std::string gui = "";
#ifdef SOFA_SMP
    std::string simulationType = "smp";
#else
    std::string simulationType = "tree";
#endif
    std::vector<std::string> plugins;
    std::vector<std::string> files;
#ifdef SOFA_SMP
    std::string nProcs="";
    bool        disableStealing = false;
#endif

    std::string gui_help = "choose the UI (";
    gui_help += sofa::gui::GUIManager::ListSupportedGUI('|');
    gui_help += ")";

    sofa::helper::parse(&files, "This is a SOFA application. Here are the command line arguments")
    .option(&startAnim,'a',"start","start the animation loop")
    .option(&printFactory,'p',"factory","print factory logs")
    .option(&gui,'g',"gui",gui_help.c_str())
    .option(&nbIterations,'n',"nb_iterations","(only batch) Number of iterations of the simulation")
    .option(&simulationType,'s',"simu","select the type of simulation (bgl, tree)")
    .option(&plugins,'l',"load","load given plugins")
    .option(&loadRecent,'r',"recent","load most recently opened file")
    .option(&temporaryFile,'t',"temporary","the loaded scene won't appear in history of opened files")
#ifdef SOFA_SMP
    .option(&disableStealing,'w',"disableStealing","Disable Work Stealing")
    .option(&nProcs,'c',"nprocs","Number of processor")
#endif
    (argc,argv);
#ifdef SOFA_SMP
    int ac=0;
    char **av=NULL;

    Util::KaapiComponentManager::prop["util.globalid"]="0";
    Util::KaapiComponentManager::prop["sched.strategy"]="I";
    if(!disableStealing)
        Util::KaapiComponentManager::prop["sched.stealing"]="true";
    if(nProcs!="")
        Util::KaapiComponentManager::prop["community.thread.poolsize"]=nProcs;

    a1::Community com = a1::System::join_community( ac, av);
#endif /* SOFA_SMP */

    if(gui!="batch") glutInit(&argc,argv);
#ifdef SOFA_GPU_CUDA
    sofa::gpu::cuda::mycudaInit();
#endif

#ifdef SOFA_DEV
    if (simulationType == "bgl")  sofa::simulation::setSimulation(new sofa::simulation::bgl::BglSimulation());
    else
#endif
#ifdef SOFA_SMP
        if (simulationType == "smp")  sofa::simulation::setSimulation(new sofa::simulation::tree::SMPSimulation());
        else
#endif
            sofa::simulation::setSimulation(new sofa::simulation::tree::TreeSimulation());

    sofa::component::init();
    sofa::simulation::xml::initXml();

    if (!files.empty()) fileName = files[0];

    for (unsigned int i=0; i<plugins.size(); i++)
        loadPlugin(plugins[i].c_str());

    if(gui.compare("batch") == 0 && nbIterations > 0)
    {
        std::ostringstream oss ;
        oss << "nbIterations=";
        oss << nbIterations;
        sofa::gui::GUIManager::AddGUIOption(oss.str().c_str());
    }

    if (int err=sofa::gui::GUIManager::Init(argv[0],gui.c_str()))
        return err;

    if (fileName.empty())
    {
        if (loadRecent) // try to reload the latest scene
        {
            std::string scenes = "config/Sofa.ini";
            scenes = sofa::helper::system::DataRepository.getFile( scenes );
            std::ifstream mrulist(scenes.c_str());
            std::getline(mrulist,fileName);
            mrulist.close();
        }
        else
            fileName = "Demos/liver.scn";

        fileName = sofa::helper::system::DataRepository.getFile(fileName);
    }

    if (int err=sofa::gui::GUIManager::createGUI(NULL))
        return err;

    //To set a specific resolution for the viewer, use the component ViewerDimensionSetting in you scene graph
    sofa::gui::GUIManager::SetDimension(800,600);

    sofa::simulation::Node* groot = dynamic_cast<sofa::simulation::Node*>( sofa::simulation::getSimulation()->load(fileName.c_str()));
    if (groot==NULL)  groot = sofa::simulation::getSimulation()->newNode("");

    sofa::simulation::getSimulation()->init(groot);
    sofa::gui::GUIManager::SetScene(groot,fileName.c_str(), temporaryFile);

    //=======================================
    //Apply Options

    if (startAnim)  groot->setAnimate(true);

    if (printFactory)
    {
        std::cout << "////////// FACTORY //////////" << std::endl;
        sofa::helper::printFactoryLog();
        std::cout << "//////// END FACTORY ////////" << std::endl;
    }

    //=======================================
    // Run the main loop
    if (int err=sofa::gui::GUIManager::MainLoop(groot,fileName.c_str()))
        return err;
    groot = dynamic_cast<sofa::simulation::Node*>( sofa::gui::GUIManager::CurrentSimulation() );

    if (groot!=NULL) sofa::simulation::getSimulation()->unload(groot);
    return 0;
}
<|endoftext|>