<commit_before>//////////////////////////////////////////////////////////////////////////
#include "Plugin/pyRegistry.hpp"
#include "Plugin/iRegistry.hpp"
#include "GOM/pyResult.hpp"

using namespace Cpf;
using namespace Plugin;

/*
GOM::Result CPF_STDCALL Install(GOM::ClassID cid, iClassInstance* clsInst) = 0;
GOM::Result CPF_STDCALL Remove(GOM::ClassID cid) = 0;
GOM::Result CPF_STDCALL Exists(GOM::ClassID cid) = 0;
GOM::Result CPF_STDCALL Create(iBase* outer, GOM::ClassID cid, GOM::InterfaceID iid, void** result) = 0;
GOM::Result CPF_STDCALL ClassInstall(int32_t count, const IID_CID* pairs) = 0;
GOM::Result CPF_STDCALL ClassRemove(int32_t count, const IID_CID* pairs) = 0;
GOM::Result CPF_STDCALL GetClasses(GOM::InterfaceID id, int32_t* count, GOM::ClassID* cid) = 0;
GOM::Result CPF_STDCALL InstanceInstall(GOM::InterfaceID id, void* instance) = 0;
GOM::Result CPF_STDCALL InstanceRemove(GOM::InterfaceID id) = 0;
GOM::Result CPF_STDCALL GetInstances(GOM::InterfaceID id, void** outIface) = 0;
*/

extern "C" PyObject* CPF_STDCALL RegistryLoad(py::Registry* self, PyObject* args)
{
	char* name = nullptr;
	if (!PyArg_ParseTuple(args, "s:load", &name))
	{
		PyErr_SetString(PyExc_RuntimeError, "Invalid argument.");
		return nullptr;
	}
	{
		if (Succeeded(reinterpret_cast<iRegistry*>(self->mBase.mpBase)->Load(name)))
			return PyBool_FromLong(1);
		PyErr_SetString(PyExc_RuntimeError, "Plugin load failure.");
	}
	return nullptr;
}

extern "C" PyObject* CPF_STDCALL RegistryCanUnload(py::Registry* self, PyObject* args)
{
	char* name = nullptr;
	if (!PyArg_ParseTuple(args, "s:can_unload", &name))
	{
		PyErr_SetString(PyExc_RuntimeError, "Invalid argument.");
		return nullptr;
	}

	if (Succeeded(reinterpret_cast<iRegistry*>(self->mBase.mpBase)->CanUnload(name)))
		return PyBool_FromLong(1);
	return PyBool_FromLong(0);
}

extern "C" PyObject* CPF_STDCALL RegistryUnload(py::Registry* self, PyObject* args)
{
	char* name = nullptr;
	if (!PyArg_ParseTuple(args, "s:unload", &name))
	{
		PyErr_SetString(PyExc_RuntimeError, "Invalid argument.");
		return nullptr;
	}
	if (Succeeded(reinterpret_cast<iRegistry*>(self->mBase.mpBase)->Unload(name)))
		return PyBool_FromLong(1);
	return PyBool_FromLong(0);
}

extern "C" PyObject* CPF_STDCALL RegistryExists(py::Registry* self, PyObject* args)
{

}

PyMethodDef PluginRegistry_methods[] =
{
	{ "load", (PyCFunction)RegistryLoad, METH_VARARGS, PyDoc_STR("Attempt to load a plugin.") },
	{ "can_unload", (PyCFunction)RegistryCanUnload, METH_VARARGS, PyDoc_STR("Test if a plugin can be unloaded.") },
	{ "unload", (PyCFunction)RegistryUnload, METH_VARARGS, PyDoc_STR("Attempt to unload a plugin.") },
	{ nullptr, nullptr }
};

PyTypeObject py::PluginRegistry_type =
{
	PyVarObject_HEAD_INIT(nullptr, 0)
	"plugin.Registry",			/* tp_name */
	sizeof(py::Registry),		/* tp_basicsize */
	0,							/* tp_itemsize */
	0,							/* tp_dealloc */
	0,							/* tp_print */
	0,							/* tp_getattr */
	0,							/* tp_setattr */
	0,							/* tp_reserved */
	0,							/* tp_repr */
	0,							/* tp_as_number */
	0,							/* tp_as_sequence */
	0,							/* tp_as_mapping */
	0,							/* tp_hash  */
	0,							/* tp_call */
	0,							/* tp_str */
	0,							/* tp_getattro */
	0,							/* tp_setattro */
	0,							/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
	"Cpf objects",				/* tp_doc */
	nullptr,					/* tp_traverse */
	nullptr,					/* tp_clear */
	nullptr,					/* tp_richcompare */
	0,							/* tp_weaklistoffset */
	nullptr,					/* tp_iter */
	nullptr,					/* tp_iternext */
	PluginRegistry_methods,		/* tp_methods */
	nullptr,					/* tp_members */
	nullptr,					/* tp_getset */
	nullptr,					/* tp_base */
};

//////////////////////////////////////////////////////////////////////////
extern PyTypeObject GOMBase_type;

bool py::AddRegistryType(PyObject* parent)
{
	PluginRegistry_type.tp_base = &GOMBase_type;
	PluginRegistry_type.tp_new = PyType_GenericNew;
	if (PyType_Ready(&PluginRegistry_type) < 0)
		return false;
	Py_INCREF(&PluginRegistry_type);
	PyModule_AddObject(parent, "Registry", reinterpret_cast<PyObject*>(&PluginRegistry_type));

	return true;
}
<commit_msg>Missed a minor issue.<commit_after>//////////////////////////////////////////////////////////////////////////
#include "Plugin/pyRegistry.hpp"
#include "Plugin/iRegistry.hpp"
#include "GOM/pyResult.hpp"

using namespace Cpf;
using namespace Plugin;

/*
GOM::Result CPF_STDCALL Install(GOM::ClassID cid, iClassInstance* clsInst) = 0;
GOM::Result CPF_STDCALL Remove(GOM::ClassID cid) = 0;
GOM::Result CPF_STDCALL Exists(GOM::ClassID cid) = 0;
GOM::Result CPF_STDCALL Create(iBase* outer, GOM::ClassID cid, GOM::InterfaceID iid, void** result) = 0;
GOM::Result CPF_STDCALL ClassInstall(int32_t count, const IID_CID* pairs) = 0;
GOM::Result CPF_STDCALL ClassRemove(int32_t count, const IID_CID* pairs) = 0;
GOM::Result CPF_STDCALL GetClasses(GOM::InterfaceID id, int32_t* count, GOM::ClassID* cid) = 0;
GOM::Result CPF_STDCALL InstanceInstall(GOM::InterfaceID id, void* instance) = 0;
GOM::Result CPF_STDCALL InstanceRemove(GOM::InterfaceID id) = 0;
GOM::Result CPF_STDCALL GetInstances(GOM::InterfaceID id, void** outIface) = 0;
*/

extern "C" PyObject* CPF_STDCALL RegistryLoad(py::Registry* self, PyObject* args)
{
	char* name = nullptr;
	if (!PyArg_ParseTuple(args, "s:load", &name))
	{
		PyErr_SetString(PyExc_RuntimeError, "Invalid argument.");
		return nullptr;
	}
	{
		if (Succeeded(reinterpret_cast<iRegistry*>(self->mBase.mpBase)->Load(name)))
			return PyBool_FromLong(1);
		PyErr_SetString(PyExc_RuntimeError, "Plugin load failure.");
	}
	return nullptr;
}

extern "C" PyObject* CPF_STDCALL RegistryCanUnload(py::Registry* self, PyObject* args)
{
	char* name = nullptr;
	if (!PyArg_ParseTuple(args, "s:can_unload", &name))
	{
		PyErr_SetString(PyExc_RuntimeError, "Invalid argument.");
		return nullptr;
	}

	if (Succeeded(reinterpret_cast<iRegistry*>(self->mBase.mpBase)->CanUnload(name)))
		return PyBool_FromLong(1);
	return PyBool_FromLong(0);
}

extern "C" PyObject* CPF_STDCALL RegistryUnload(py::Registry* self, PyObject* args)
{
	char* name = nullptr;
	if (!PyArg_ParseTuple(args, "s:unload", &name))
	{
		PyErr_SetString(PyExc_RuntimeError, "Invalid argument.");
		return nullptr;
	}
	if (Succeeded(reinterpret_cast<iRegistry*>(self->mBase.mpBase)->Unload(name)))
		return PyBool_FromLong(1);
	return PyBool_FromLong(0);
}

extern "C" PyObject* CPF_STDCALL RegistryExists(py::Registry* self, PyObject* args)
{
	return nullptr;
}

PyMethodDef PluginRegistry_methods[] =
{
	{ "load", (PyCFunction)RegistryLoad, METH_VARARGS, PyDoc_STR("Attempt to load a plugin.") },
	{ "can_unload", (PyCFunction)RegistryCanUnload, METH_VARARGS, PyDoc_STR("Test if a plugin can be unloaded.") },
	{ "unload", (PyCFunction)RegistryUnload, METH_VARARGS, PyDoc_STR("Attempt to unload a plugin.") },
	{ nullptr, nullptr }
};

PyTypeObject py::PluginRegistry_type =
{
	PyVarObject_HEAD_INIT(nullptr, 0)
	"plugin.Registry",			/* tp_name */
	sizeof(py::Registry),		/* tp_basicsize */
	0,							/* tp_itemsize */
	0,							/* tp_dealloc */
	0,							/* tp_print */
	0,							/* tp_getattr */
	0,							/* tp_setattr */
	0,							/* tp_reserved */
	0,							/* tp_repr */
	0,							/* tp_as_number */
	0,							/* tp_as_sequence */
	0,							/* tp_as_mapping */
	0,							/* tp_hash  */
	0,							/* tp_call */
	0,							/* tp_str */
	0,							/* tp_getattro */
	0,							/* tp_setattro */
	0,							/* tp_as_buffer */
	Py_TPFLAGS_DEFAULT,			/* tp_flags */
	"Cpf objects",				/* tp_doc */
	nullptr,					/* tp_traverse */
	nullptr,					/* tp_clear */
	nullptr,					/* tp_richcompare */
	0,							/* tp_weaklistoffset */
	nullptr,					/* tp_iter */
	nullptr,					/* tp_iternext */
	PluginRegistry_methods,		/* tp_methods */
	nullptr,					/* tp_members */
	nullptr,					/* tp_getset */
	nullptr,					/* tp_base */
};

//////////////////////////////////////////////////////////////////////////
extern PyTypeObject GOMBase_type;

bool py::AddRegistryType(PyObject* parent)
{
	PluginRegistry_type.tp_base = &GOMBase_type;
	PluginRegistry_type.tp_new = PyType_GenericNew;
	if (PyType_Ready(&PluginRegistry_type) < 0)
		return false;
	Py_INCREF(&PluginRegistry_type);
	PyModule_AddObject(parent, "Registry", reinterpret_cast<PyObject*>(&PluginRegistry_type));

	return true;
}
<|endoftext|>


<commit_before>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* interface header */
#include "CustomZone.h"
#include "common.h"

/* system headers */
#include <sstream>
#include <math.h>

/* local implementation headers */
#include "EntryZones.h"
#include "Flag.h"
#include "Team.h"

CustomZone::CustomZone()
{
  pos[0] = pos[1] = pos[2] = 0.0f;
  rotation = 0.0f;
  size[0] = size[1] = size[2] = 1.0f;
}

bool CustomZone::read(const char *cmd, std::istream& input) {
  if (strcmp(cmd, "flag") == 0) {
    std::string args, flag;

    std::getline(input, args);
    std::istringstream  parms(args);

    while (parms >> flag) {
      FlagType *type;

      if (flag == "good") {
        FlagSet &fs = Flag::getGoodFlags();
	for (FlagSet::iterator it = fs.begin(); it != fs.end(); ++it) {
	  FlagType *f = *it;
	  if (f->endurance != FlagNormal) { // Null and Team flags
	    qualifiers.push_back(f->flagAbbv);
	  }
	}
      }
      else if (flag == "bad") {
	FlagSet &fs = Flag::getBadFlags();
	for (FlagSet::iterator it = fs.begin(); it != fs.end(); ++it) {
	  FlagType *f = *it;
	  if (f->endurance != FlagNormal) { // Null and Team flags
	    qualifiers.push_back(f->flagAbbv);
	  }
	}
      }
      else {
        type = Flag::getDescFromAbbreviation(flag.c_str());
        if (type == Flags::Null)
          return false;
        qualifiers.push_back(flag);
      }
    }
    input.putback('\n');
    if (qualifiers.size() == 0)
      return false;
  }
  else if ((strcmp(cmd, "team") == 0) || (strcmp(cmd, "safety") == 0)) {
    std::string args;
    int color;

    std::getline(input, args);
    std::istringstream  parms(args);

    while (parms >> color) {
      if ((color < 0) || (color >= CtfTeams))
        return false;
      std::string qual = std::string(Team::getName((TeamColor)color));
      if (strcmp(cmd, "safety") == 0) {
        qual = EntryZones::getSafetyPrefix() + qual;
      }
      qualifiers.push_back(qual);
    }
    input.putback('\n');
    if (qualifiers.size() == 0)
      return false;
  }
  else if (!WorldFileLocation::read(cmd, input))
      return false;

  return true;
}

void CustomZone::write(WorldInfo* worldInfo) const
{
  worldInfo->addZone( this );
}

void CustomZone::getRandomPoint(float *pt) const
{
  float x = (float)((bzfrand() * (2.0f * size[0])) - size[0]);
  float y = (float)((bzfrand() * (2.0f * size[1])) - size[1]);
  pt[2] = (float)(bzfrand() * size[2]);

  pt[0] = x * cosf(rotation) - y * sinf(rotation);
  pt[1] = x * sinf(rotation) + y * cosf(rotation);

  pt[0] += pos[0];
  pt[1] += pos[1];
  pt[2] += pos[2];
}

float CustomZone::getDistToPoint (const float *_pos) const
{
  // FIXME - should use proper minimum distance from
  // the zone edge, and maybe -1.0f if its inside the zone
  float v[3], dist;
  v[0] = _pos[0] - pos[0];
  v[1] = _pos[1] - pos[1];
  v[2] = _pos[2] - pos[2];
  dist = sqrtf (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);

  return dist;
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<commit_msg>common.h is always first<commit_after>/* bzflag
 * Copyright (c) 1993 - 2004 Tim Riker
 *
 * This package is free software;  you can redistribute it and/or
 * modify it under the terms of the license found in the file
 * named COPYING that should have accompanied this file.
 *
 * THIS PACKAGE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
 */

/* the common header */
#include "common.h"

/* interface header */
#include "CustomZone.h"

/* system headers */
#include <sstream>
#include <math.h>

/* local implementation headers */
#include "EntryZones.h"
#include "Flag.h"
#include "Team.h"

CustomZone::CustomZone()
{
  pos[0] = pos[1] = pos[2] = 0.0f;
  rotation = 0.0f;
  size[0] = size[1] = size[2] = 1.0f;
}

bool CustomZone::read(const char *cmd, std::istream& input) {
  if (strcmp(cmd, "flag") == 0) {
    std::string args, flag;

    std::getline(input, args);
    std::istringstream  parms(args);

    while (parms >> flag) {
      FlagType *type;

      if (flag == "good") {
        FlagSet &fs = Flag::getGoodFlags();
	for (FlagSet::iterator it = fs.begin(); it != fs.end(); ++it) {
	  FlagType *f = *it;
	  if (f->endurance != FlagNormal) { // Null and Team flags
	    qualifiers.push_back(f->flagAbbv);
	  }
	}
      }
      else if (flag == "bad") {
	FlagSet &fs = Flag::getBadFlags();
	for (FlagSet::iterator it = fs.begin(); it != fs.end(); ++it) {
	  FlagType *f = *it;
	  if (f->endurance != FlagNormal) { // Null and Team flags
	    qualifiers.push_back(f->flagAbbv);
	  }
	}
      }
      else {
        type = Flag::getDescFromAbbreviation(flag.c_str());
        if (type == Flags::Null)
          return false;
        qualifiers.push_back(flag);
      }
    }
    input.putback('\n');
    if (qualifiers.size() == 0)
      return false;
  }
  else if ((strcmp(cmd, "team") == 0) || (strcmp(cmd, "safety") == 0)) {
    std::string args;
    int color;

    std::getline(input, args);
    std::istringstream  parms(args);

    while (parms >> color) {
      if ((color < 0) || (color >= CtfTeams))
        return false;
      std::string qual = std::string(Team::getName((TeamColor)color));
      if (strcmp(cmd, "safety") == 0) {
        qual = EntryZones::getSafetyPrefix() + qual;
      }
      qualifiers.push_back(qual);
    }
    input.putback('\n');
    if (qualifiers.size() == 0)
      return false;
  }
  else if (!WorldFileLocation::read(cmd, input))
      return false;

  return true;
}

void CustomZone::write(WorldInfo* worldInfo) const
{
  worldInfo->addZone( this );
}

void CustomZone::getRandomPoint(float *pt) const
{
  float x = (float)((bzfrand() * (2.0f * size[0])) - size[0]);
  float y = (float)((bzfrand() * (2.0f * size[1])) - size[1]);
  pt[2] = (float)(bzfrand() * size[2]);

  pt[0] = x * cosf(rotation) - y * sinf(rotation);
  pt[1] = x * sinf(rotation) + y * cosf(rotation);

  pt[0] += pos[0];
  pt[1] += pos[1];
  pt[2] += pos[2];
}

float CustomZone::getDistToPoint (const float *_pos) const
{
  // FIXME - should use proper minimum distance from
  // the zone edge, and maybe -1.0f if its inside the zone
  float v[3], dist;
  v[0] = _pos[0] - pos[0];
  v[1] = _pos[1] - pos[1];
  v[2] = _pos[2] - pos[2];
  dist = sqrtf (v[0]*v[0] + v[1]*v[1] + v[2]*v[2]);

  return dist;
}

// Local variables: ***
// mode:C++ ***
// tab-width: 8 ***
// c-basic-offset: 2 ***
// indent-tabs-mode: t ***
// End: ***
// ex: shiftwidth=2 tabstop=8
<|endoftext|>


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

#include "google/fhir/stu3/extensions.h"

#include <unordered_map>

#include "google/protobuf/descriptor.h"
#include "absl/strings/str_cat.h"
#include "google/fhir/status/status.h"
#include "google/fhir/stu3/util.h"
#include "proto/stu3/annotations.pb.h"
#include "proto/stu3/datatypes.pb.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/platform/logging.h"

namespace google {
namespace fhir {
namespace stu3 {

using std::string;
using ::google::fhir::stu3::proto::Extension;
using ::google::protobuf::Descriptor;
using ::google::protobuf::FieldDescriptor;
using ::google::protobuf::Message;
using ::google::protobuf::Reflection;
using ::tensorflow::Status;
using ::tensorflow::errors::InvalidArgument;

namespace {

const std::unordered_map<string, const FieldDescriptor*>*
GetExtensionValueFieldsMap() {
  static const std::unordered_map<string, const FieldDescriptor*>*
      extension_value_fields_by_type = []() {
        const google::protobuf::OneofDescriptor* value_oneof =
            Extension::Value::descriptor()->FindOneofByName("value");
        CHECK(value_oneof != nullptr);

        std::unordered_map<string, const FieldDescriptor*>* map =
            new std::unordered_map<string, const FieldDescriptor*>;
        for (int i = 0; i < value_oneof->field_count(); i++) {
          const FieldDescriptor* field = value_oneof->field(i);
          (*map)[field->message_type()->full_name()] = field;
        }
        return map;
      }();
  return extension_value_fields_by_type;
}

Status AddFieldsToExtension(const Message& message, Extension* extension);

Status CheckIsMessage(const FieldDescriptor* field) {
  if (field->type() != FieldDescriptor::Type::TYPE_MESSAGE) {
    return InvalidArgument("Encountered unexpected proto primitive: ",
                           field->full_name(), ".  Should be FHIR type");
  }
  return Status::OK();
}

Status AddValueToExtension(const Message& message, Extension* extension,
                           bool is_choice_type) {
  const Descriptor* descriptor = message.GetDescriptor();
  const Reflection* extension_value_reflection =
      extension->value().GetReflection();

  if (is_choice_type) {
    const google::protobuf::OneofDescriptor* oneof = descriptor->oneof_decl(0);
    if (oneof == nullptr) {
      return InvalidArgument("Choice type is missing a oneof: ",
                             descriptor->full_name());
    }
    const Reflection* message_reflection = message.GetReflection();
    const FieldDescriptor* value_field =
        message_reflection->GetOneofFieldDescriptor(message, oneof);
    if (value_field == nullptr) {
      return InvalidArgument("Choice type has no value set: ",
                             descriptor->full_name());
    }
    FHIR_RETURN_IF_ERROR(CheckIsMessage(value_field));
    return AddValueToExtension(
        message_reflection->GetMessage(message, value_field), extension, false);
  }
  auto value_field_iter =
      GetExtensionValueFieldsMap()->find(descriptor->full_name());
  if (value_field_iter != GetExtensionValueFieldsMap()->end()) {
    extension_value_reflection
        ->MutableMessage(extension->mutable_value(), value_field_iter->second)
        ->CopyFrom(message);
    return Status::OK();
  }
  // Fall back to adding individual fields as sub-extensions.
  return AddFieldsToExtension(message, extension);
}

Status AddFieldsToExtension(const Message& message, Extension* extension) {
  const Descriptor* descriptor = message.GetDescriptor();
  const Reflection* reflection = message.GetReflection();
  std::vector<const FieldDescriptor*> fields;
  reflection->ListFields(message, &fields);
  for (const auto* field : fields) {
    if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
      return InvalidArgument(descriptor->full_name(),
                             " is not a FHIR extension type");
    }
    // Add submessages to nested extensions.
    if (field->is_repeated()) {
      for (int j = 0; j < reflection->FieldSize(message, field); j++) {
        Extension* child = extension->add_extension();
        child->mutable_url()->set_value(field->name());
        FHIR_RETURN_IF_ERROR(CheckIsMessage(field));
        FHIR_RETURN_IF_ERROR(AddValueToExtension(
            reflection->GetRepeatedMessage(message, field, j), child,
            IsChoiceType(field)));
      }
    } else {
      Extension* child = extension->add_extension();
      child->mutable_url()->set_value(GetInlinedExtensionUrl(field));
      FHIR_RETURN_IF_ERROR(CheckIsMessage(field));
      FHIR_RETURN_IF_ERROR(AddValueToExtension(
          reflection->GetMessage(message, field), child, IsChoiceType(field)));
    }
  }
  return Status::OK();
}

StatusOr<const FieldDescriptor*> GetExtensionValueField(
    const Extension& extension) {
  static const google::protobuf::OneofDescriptor* value_oneof =
      Extension::Value::descriptor()->FindOneofByName("value");
  const Extension::Value value = extension.value();
  const Reflection* value_reflection = value.GetReflection();
  const FieldDescriptor* field =
      value_reflection->GetOneofFieldDescriptor(value, value_oneof);
  if (field == nullptr) {
    return InvalidArgument("No value set on extension.");
  }
  FHIR_RETURN_IF_ERROR(CheckIsMessage(field));
  return field;
}

Status ValueToMessage(const Extension& extension, Message* message,
                      const FieldDescriptor* field) {
  const Descriptor* descriptor = message->GetDescriptor();
  if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
    return InvalidArgument(descriptor->full_name(),
                           " is not a FHIR extension type");
  }
  // If there's a value, there can not be any extensions set.
  if (extension.extension_size() > 0) {
    return InvalidArgument("Invalid extension: ", extension.DebugString());
  }
  FHIR_ASSIGN_OR_RETURN(const FieldDescriptor* value_field,
                        GetExtensionValueField(extension));

  const Reflection* message_reflection = message->GetReflection();
  if (IsChoiceType(field)) {
    // We need to assign the value from the extension to the correct field
    // on the choice type.
    Message* choice_message =
        message_reflection->MutableMessage(message, field);
    const Descriptor* choice_descriptor = choice_message->GetDescriptor();
    for (int i = 0; i < choice_descriptor->field_count(); i++) {
      const FieldDescriptor* choice_field = choice_descriptor->field(i);
      if (value_field->message_type()->full_name() ==
          choice_field->message_type()->full_name()) {
        return ValueToMessage(extension, choice_message, choice_field);
      }
    }
    return InvalidArgument("No field on Choice Type ",
                           choice_descriptor->full_name(), " for extension ",
                           extension.DebugString());
  }

  // Value types must match.
  if (value_field->message_type()->full_name() !=
      field->message_type()->full_name()) {
    return InvalidArgument("Missing expected value of type ",
                           field->message_type()->full_name(), " in extension ",
                           extension.DebugString());
  }
  const Extension::Value value = extension.value();
  const Reflection* value_reflection = value.GetReflection();
  if (field->is_repeated()) {
    message_reflection->AddMessage(message, field)
        ->CopyFrom(value_reflection->GetMessage(extension, value_field));
  } else {
    message_reflection->MutableMessage(message, field)
        ->CopyFrom(value_reflection->GetMessage(value, value_field));
  }
  return Status::OK();
}

const std::vector<const FieldDescriptor*> FindValueFields(
    const Descriptor* descriptor) {
  std::vector<const FieldDescriptor*> value_fields;
  for (int i = 0; i < descriptor->field_count(); i++) {
    const string& name = descriptor->field(i)->name();
    if (name != "id" && name != "extension") {
      value_fields.push_back(descriptor->field(i));
    }
  }
  return value_fields;
}

}  // namespace

Status ValidateExtension(const Descriptor* descriptor) {
  if (descriptor->options().GetExtension(stu3::proto::fhir_profile_base) !=
      Extension::descriptor()->options().GetExtension(
          stu3::proto::fhir_structure_definition_url)) {
    return InvalidArgument(descriptor->full_name(),
                           " is not a FHIR extension type");
  }
  if (!descriptor->options().HasExtension(
          stu3::proto::fhir_structure_definition_url)) {
    return InvalidArgument(descriptor->full_name(),
                           " is not a valid FHIR extension type: No "
                           "fhir_structure_definition_url.");
  }
  return Status::OK();
}

Status ConvertToExtension(const Message& message, Extension* extension) {
  const Descriptor* descriptor = message.GetDescriptor();
  FHIR_RETURN_IF_ERROR(ValidateExtension(descriptor));

  extension->mutable_url()->set_value(descriptor->options().GetExtension(
      stu3::proto::fhir_structure_definition_url));

  // Carry over the id field if present.
  const FieldDescriptor* id_field =
      descriptor->field_count() > 1 && descriptor->field(0)->name() == "id"
          ? descriptor->field(0)
          : nullptr;
  const Reflection* reflection = message.GetReflection();
  if (id_field != nullptr && reflection->HasField(message, id_field)) {
    extension->mutable_id()->CopyFrom(
        reflection->GetMessage(message, id_field));
  }

  const std::vector<const FieldDescriptor*> value_fields =
      FindValueFields(descriptor);
  if (value_fields.empty()) {
    return InvalidArgument("Extension has no value fields: ",
                           descriptor->name());
  }
  if (value_fields.size() == 1 && !value_fields[0]->is_repeated()) {
    const FieldDescriptor* value_field = value_fields[0];
    FHIR_RETURN_IF_ERROR(CheckIsMessage(value_field));
    if (reflection->HasField(message, value_field)) {
      return AddValueToExtension(reflection->GetMessage(message, value_field),
                                 extension, IsChoiceType(value_field));
    } else {
      // TODO(nickgeorge, sundberg): This is an invalid extension.  Maybe we
      // should be erroring out here?
      return Status::OK();
    }
  } else {
    return AddFieldsToExtension(message, extension);
  }
}

Status ExtensionToMessage(const Extension& extension, Message* message) {
  const Descriptor* descriptor = message->GetDescriptor();
  const Reflection* reflection = message->GetReflection();

  std::unordered_map<string, const FieldDescriptor*> fields_by_url;
  const FieldDescriptor* id_field = nullptr;
  for (int i = 0; i < descriptor->field_count(); i++) {
    // We need to handle the "id" field separately, since it corresponds to
    // Extension.id, not the slice "id".
    const FieldDescriptor* field = descriptor->field(i);
    if (field->name() == "id") {
      id_field = field;
    } else {
      fields_by_url[GetInlinedExtensionUrl(field)] = field;
    }
  }

  // Copy the id of the extension if present (this is uncommon).
  if (extension.has_id() && id_field != nullptr) {
    const Reflection* message_reflection = message->GetReflection();
    message_reflection->MutableMessage(message, id_field)
        ->CopyFrom(extension.id());
  }

  if (extension.value().value_case() != Extension::Value::VALUE_NOT_SET) {
    // This is a simple extension, with only one value.
    if (fields_by_url.size() != 1 ||
        fields_by_url.begin()->second->is_repeated()) {
      return InvalidArgument(descriptor->full_name(),
                             " is not a FHIR extension type");
    }
    return ValueToMessage(extension, message, fields_by_url.begin()->second);
  }

  for (const Extension& inner : extension.extension()) {
    const FieldDescriptor* field = fields_by_url[inner.url().value()];

    if (field == nullptr) {
      return InvalidArgument("Message of type ", descriptor->full_name(),
                             " has no field with name ", inner.url().value());
    }

    if (inner.value().value_case() != Extension::Value::VALUE_NOT_SET) {
      FHIR_RETURN_IF_ERROR(ValueToMessage(inner, message, field));
    } else {
      Message* child;
      if (field->is_repeated()) {
        child = reflection->AddMessage(message, field);
      } else if (reflection->HasField(*message, field) ||
                 inner.extension_size() > 0) {
        return ::tensorflow::errors::AlreadyExists(
            "Unexpected repeated value for tag ", field->name(),
            " in extension ", inner.DebugString());
      } else {
        child = reflection->MutableMessage(message, field);
      }
      FHIR_RETURN_IF_ERROR(ExtensionToMessage(inner, child));
    }
  }
  return Status::OK();
}

Status ClearTypedExtensions(const Descriptor* descriptor, Message* message) {
  FHIR_RETURN_IF_ERROR(ValidateExtension(descriptor));
  const string url = descriptor->options().GetExtension(
      stu3::proto::fhir_structure_definition_url);

  const Reflection* reflection = message->GetReflection();
  const FieldDescriptor* field =
      message->GetDescriptor()->FindFieldByName("extension");
  std::vector<Extension> other_extensions;
  for (int i = 0; i < reflection->FieldSize(*message, field); i++) {
    Extension extension = dynamic_cast<const Extension&>(
        reflection->GetRepeatedMessage(*message, field, i));
    if (extension.url().value() != url) {
      other_extensions.push_back(extension);
    }
  }
  reflection->ClearField(message, field);
  for (const Extension& extension : other_extensions) {
    message->GetReflection()->AddMessage(message, field)->CopyFrom(extension);
  }
  return Status::OK();
}

string GetInlinedExtensionUrl(const FieldDescriptor* field) {
  return field->options().HasExtension(proto::fhir_inlined_extension_url)
             ? field->options().GetExtension(proto::fhir_inlined_extension_url)
             : field->json_name();
}

}  // namespace stu3
}  // namespace fhir
}  // namespace google
<commit_msg>fixes bug where repeated extension element could use incorrect serialized url.<commit_after>// Copyright 2018 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "google/fhir/stu3/extensions.h"

#include <unordered_map>

#include "google/protobuf/descriptor.h"
#include "absl/strings/str_cat.h"
#include "google/fhir/status/status.h"
#include "google/fhir/stu3/util.h"
#include "proto/stu3/annotations.pb.h"
#include "proto/stu3/datatypes.pb.h"
#include "tensorflow/core/lib/core/errors.h"
#include "tensorflow/core/lib/core/status.h"
#include "tensorflow/core/platform/logging.h"

namespace google {
namespace fhir {
namespace stu3 {

using std::string;
using ::google::fhir::stu3::proto::Extension;
using ::google::protobuf::Descriptor;
using ::google::protobuf::FieldDescriptor;
using ::google::protobuf::Message;
using ::google::protobuf::Reflection;
using ::tensorflow::Status;
using ::tensorflow::errors::InvalidArgument;

namespace {

const std::unordered_map<string, const FieldDescriptor*>*
GetExtensionValueFieldsMap() {
  static const std::unordered_map<string, const FieldDescriptor*>*
      extension_value_fields_by_type = []() {
        const google::protobuf::OneofDescriptor* value_oneof =
            Extension::Value::descriptor()->FindOneofByName("value");
        CHECK(value_oneof != nullptr);

        std::unordered_map<string, const FieldDescriptor*>* map =
            new std::unordered_map<string, const FieldDescriptor*>;
        for (int i = 0; i < value_oneof->field_count(); i++) {
          const FieldDescriptor* field = value_oneof->field(i);
          (*map)[field->message_type()->full_name()] = field;
        }
        return map;
      }();
  return extension_value_fields_by_type;
}

Status AddFieldsToExtension(const Message& message, Extension* extension);

Status CheckIsMessage(const FieldDescriptor* field) {
  if (field->type() != FieldDescriptor::Type::TYPE_MESSAGE) {
    return InvalidArgument("Encountered unexpected proto primitive: ",
                           field->full_name(), ".  Should be FHIR type");
  }
  return Status::OK();
}

Status AddValueToExtension(const Message& message, Extension* extension,
                           bool is_choice_type) {
  const Descriptor* descriptor = message.GetDescriptor();
  const Reflection* extension_value_reflection =
      extension->value().GetReflection();

  if (is_choice_type) {
    const google::protobuf::OneofDescriptor* oneof = descriptor->oneof_decl(0);
    if (oneof == nullptr) {
      return InvalidArgument("Choice type is missing a oneof: ",
                             descriptor->full_name());
    }
    const Reflection* message_reflection = message.GetReflection();
    const FieldDescriptor* value_field =
        message_reflection->GetOneofFieldDescriptor(message, oneof);
    if (value_field == nullptr) {
      return InvalidArgument("Choice type has no value set: ",
                             descriptor->full_name());
    }
    FHIR_RETURN_IF_ERROR(CheckIsMessage(value_field));
    return AddValueToExtension(
        message_reflection->GetMessage(message, value_field), extension, false);
  }
  auto value_field_iter =
      GetExtensionValueFieldsMap()->find(descriptor->full_name());
  if (value_field_iter != GetExtensionValueFieldsMap()->end()) {
    extension_value_reflection
        ->MutableMessage(extension->mutable_value(), value_field_iter->second)
        ->CopyFrom(message);
    return Status::OK();
  }
  // Fall back to adding individual fields as sub-extensions.
  return AddFieldsToExtension(message, extension);
}

Status AddFieldsToExtension(const Message& message, Extension* extension) {
  const Descriptor* descriptor = message.GetDescriptor();
  const Reflection* reflection = message.GetReflection();
  std::vector<const FieldDescriptor*> fields;
  reflection->ListFields(message, &fields);
  for (const auto* field : fields) {
    if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
      return InvalidArgument(descriptor->full_name(),
                             " is not a FHIR extension type");
    }
    // Add submessages to nested extensions.
    if (field->is_repeated()) {
      for (int j = 0; j < reflection->FieldSize(message, field); j++) {
        Extension* child = extension->add_extension();
        child->mutable_url()->set_value(GetInlinedExtensionUrl(field));
        FHIR_RETURN_IF_ERROR(CheckIsMessage(field));
        FHIR_RETURN_IF_ERROR(AddValueToExtension(
            reflection->GetRepeatedMessage(message, field, j), child,
            IsChoiceType(field)));
      }
    } else {
      Extension* child = extension->add_extension();
      child->mutable_url()->set_value(GetInlinedExtensionUrl(field));
      FHIR_RETURN_IF_ERROR(CheckIsMessage(field));
      FHIR_RETURN_IF_ERROR(AddValueToExtension(
          reflection->GetMessage(message, field), child, IsChoiceType(field)));
    }
  }
  return Status::OK();
}

StatusOr<const FieldDescriptor*> GetExtensionValueField(
    const Extension& extension) {
  static const google::protobuf::OneofDescriptor* value_oneof =
      Extension::Value::descriptor()->FindOneofByName("value");
  const Extension::Value value = extension.value();
  const Reflection* value_reflection = value.GetReflection();
  const FieldDescriptor* field =
      value_reflection->GetOneofFieldDescriptor(value, value_oneof);
  if (field == nullptr) {
    return InvalidArgument("No value set on extension.");
  }
  FHIR_RETURN_IF_ERROR(CheckIsMessage(field));
  return field;
}

Status ValueToMessage(const Extension& extension, Message* message,
                      const FieldDescriptor* field) {
  const Descriptor* descriptor = message->GetDescriptor();
  if (field->cpp_type() != FieldDescriptor::CPPTYPE_MESSAGE) {
    return InvalidArgument(descriptor->full_name(),
                           " is not a FHIR extension type");
  }
  // If there's a value, there can not be any extensions set.
  if (extension.extension_size() > 0) {
    return InvalidArgument("Invalid extension: ", extension.DebugString());
  }
  FHIR_ASSIGN_OR_RETURN(const FieldDescriptor* value_field,
                        GetExtensionValueField(extension));

  const Reflection* message_reflection = message->GetReflection();
  if (IsChoiceType(field)) {
    // We need to assign the value from the extension to the correct field
    // on the choice type.
    Message* choice_message =
        message_reflection->MutableMessage(message, field);
    const Descriptor* choice_descriptor = choice_message->GetDescriptor();
    for (int i = 0; i < choice_descriptor->field_count(); i++) {
      const FieldDescriptor* choice_field = choice_descriptor->field(i);
      if (value_field->message_type()->full_name() ==
          choice_field->message_type()->full_name()) {
        return ValueToMessage(extension, choice_message, choice_field);
      }
    }
    return InvalidArgument("No field on Choice Type ",
                           choice_descriptor->full_name(), " for extension ",
                           extension.DebugString());
  }

  // Value types must match.
  if (value_field->message_type()->full_name() !=
      field->message_type()->full_name()) {
    return InvalidArgument("Missing expected value of type ",
                           field->message_type()->full_name(), " in extension ",
                           extension.DebugString());
  }
  const Extension::Value value = extension.value();
  const Reflection* value_reflection = value.GetReflection();
  if (field->is_repeated()) {
    message_reflection->AddMessage(message, field)
        ->CopyFrom(value_reflection->GetMessage(extension, value_field));
  } else {
    message_reflection->MutableMessage(message, field)
        ->CopyFrom(value_reflection->GetMessage(value, value_field));
  }
  return Status::OK();
}

const std::vector<const FieldDescriptor*> FindValueFields(
    const Descriptor* descriptor) {
  std::vector<const FieldDescriptor*> value_fields;
  for (int i = 0; i < descriptor->field_count(); i++) {
    const string& name = descriptor->field(i)->name();
    if (name != "id" && name != "extension") {
      value_fields.push_back(descriptor->field(i));
    }
  }
  return value_fields;
}

}  // namespace

Status ValidateExtension(const Descriptor* descriptor) {
  if (descriptor->options().GetExtension(stu3::proto::fhir_profile_base) !=
      Extension::descriptor()->options().GetExtension(
          stu3::proto::fhir_structure_definition_url)) {
    return InvalidArgument(descriptor->full_name(),
                           " is not a FHIR extension type");
  }
  if (!descriptor->options().HasExtension(
          stu3::proto::fhir_structure_definition_url)) {
    return InvalidArgument(descriptor->full_name(),
                           " is not a valid FHIR extension type: No "
                           "fhir_structure_definition_url.");
  }
  return Status::OK();
}

Status ConvertToExtension(const Message& message, Extension* extension) {
  const Descriptor* descriptor = message.GetDescriptor();
  FHIR_RETURN_IF_ERROR(ValidateExtension(descriptor));

  extension->mutable_url()->set_value(descriptor->options().GetExtension(
      stu3::proto::fhir_structure_definition_url));

  // Carry over the id field if present.
  const FieldDescriptor* id_field =
      descriptor->field_count() > 1 && descriptor->field(0)->name() == "id"
          ? descriptor->field(0)
          : nullptr;
  const Reflection* reflection = message.GetReflection();
  if (id_field != nullptr && reflection->HasField(message, id_field)) {
    extension->mutable_id()->CopyFrom(
        reflection->GetMessage(message, id_field));
  }

  const std::vector<const FieldDescriptor*> value_fields =
      FindValueFields(descriptor);
  if (value_fields.empty()) {
    return InvalidArgument("Extension has no value fields: ",
                           descriptor->name());
  }
  if (value_fields.size() == 1 && !value_fields[0]->is_repeated()) {
    const FieldDescriptor* value_field = value_fields[0];
    FHIR_RETURN_IF_ERROR(CheckIsMessage(value_field));
    if (reflection->HasField(message, value_field)) {
      return AddValueToExtension(reflection->GetMessage(message, value_field),
                                 extension, IsChoiceType(value_field));
    } else {
      // TODO(nickgeorge, sundberg): This is an invalid extension.  Maybe we
      // should be erroring out here?
      return Status::OK();
    }
  } else {
    return AddFieldsToExtension(message, extension);
  }
}

Status ExtensionToMessage(const Extension& extension, Message* message) {
  const Descriptor* descriptor = message->GetDescriptor();
  const Reflection* reflection = message->GetReflection();

  std::unordered_map<string, const FieldDescriptor*> fields_by_url;
  const FieldDescriptor* id_field = nullptr;
  for (int i = 0; i < descriptor->field_count(); i++) {
    // We need to handle the "id" field separately, since it corresponds to
    // Extension.id, not the slice "id".
    const FieldDescriptor* field = descriptor->field(i);
    if (field->name() == "id") {
      id_field = field;
    } else {
      fields_by_url[GetInlinedExtensionUrl(field)] = field;
    }
  }

  // Copy the id of the extension if present (this is uncommon).
  if (extension.has_id() && id_field != nullptr) {
    const Reflection* message_reflection = message->GetReflection();
    message_reflection->MutableMessage(message, id_field)
        ->CopyFrom(extension.id());
  }

  if (extension.value().value_case() != Extension::Value::VALUE_NOT_SET) {
    // This is a simple extension, with only one value.
    if (fields_by_url.size() != 1 ||
        fields_by_url.begin()->second->is_repeated()) {
      return InvalidArgument(descriptor->full_name(),
                             " is not a FHIR extension type");
    }
    return ValueToMessage(extension, message, fields_by_url.begin()->second);
  }

  for (const Extension& inner : extension.extension()) {
    const FieldDescriptor* field = fields_by_url[inner.url().value()];

    if (field == nullptr) {
      return InvalidArgument("Message of type ", descriptor->full_name(),
                             " has no field with name ", inner.url().value());
    }

    if (inner.value().value_case() != Extension::Value::VALUE_NOT_SET) {
      FHIR_RETURN_IF_ERROR(ValueToMessage(inner, message, field));
    } else {
      Message* child;
      if (field->is_repeated()) {
        child = reflection->AddMessage(message, field);
      } else if (reflection->HasField(*message, field) ||
                 inner.extension_size() > 0) {
        return ::tensorflow::errors::AlreadyExists(
            "Unexpected repeated value for tag ", field->name(),
            " in extension ", inner.DebugString());
      } else {
        child = reflection->MutableMessage(message, field);
      }
      FHIR_RETURN_IF_ERROR(ExtensionToMessage(inner, child));
    }
  }
  return Status::OK();
}

Status ClearTypedExtensions(const Descriptor* descriptor, Message* message) {
  FHIR_RETURN_IF_ERROR(ValidateExtension(descriptor));
  const string url = descriptor->options().GetExtension(
      stu3::proto::fhir_structure_definition_url);

  const Reflection* reflection = message->GetReflection();
  const FieldDescriptor* field =
      message->GetDescriptor()->FindFieldByName("extension");
  std::vector<Extension> other_extensions;
  for (int i = 0; i < reflection->FieldSize(*message, field); i++) {
    Extension extension = dynamic_cast<const Extension&>(
        reflection->GetRepeatedMessage(*message, field, i));
    if (extension.url().value() != url) {
      other_extensions.push_back(extension);
    }
  }
  reflection->ClearField(message, field);
  for (const Extension& extension : other_extensions) {
    message->GetReflection()->AddMessage(message, field)->CopyFrom(extension);
  }
  return Status::OK();
}

string GetInlinedExtensionUrl(const FieldDescriptor* field) {
  return field->options().HasExtension(proto::fhir_inlined_extension_url)
             ? field->options().GetExtension(proto::fhir_inlined_extension_url)
             : field->json_name();
}

}  // namespace stu3
}  // namespace fhir
}  // namespace google
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPATissueGenerator.h"
#include "mitkPAVector.h"
#include "mitkPAVolumeManipulator.h"

mitk::pa::InSilicoTissueVolume::Pointer mitk::pa::InSilicoTissueGenerator::GenerateInSilicoData(
  TissueGeneratorParameters::Pointer parameters)
{
  MITK_DEBUG << "Initializing Empty Volume";

  const double RESAMPLING_FACTOR = 2;

  if (parameters->GetDoPartialVolume())
  {
    parameters->SetXDim(parameters->GetXDim() * RESAMPLING_FACTOR);
    parameters->SetYDim(parameters->GetYDim() * RESAMPLING_FACTOR);
    parameters->SetZDim(parameters->GetZDim() * RESAMPLING_FACTOR);
    parameters->SetVesselBifurcationFrequency(parameters->GetVesselBifurcationFrequency() * RESAMPLING_FACTOR);
    parameters->SetVoxelSpacingInCentimeters(parameters->GetVoxelSpacingInCentimeters() / RESAMPLING_FACTOR);
  }

  auto generatedVolume = mitk::pa::InSilicoTissueVolume::New(parameters);

  const double DIRECTION_VECTOR_INITIAL_VARIANCE = 0.2;

  std::mt19937 randomNumberGenerator;
  std::random_device randomDevice;
  if (parameters->GetUseRngSeed())
  {
    randomNumberGenerator.seed(parameters->GetRngSeed());
  }
  else
  {
    if (randomDevice.entropy() > 0.1)
    {
      randomNumberGenerator.seed(randomDevice());
    }
    else
    {
      randomNumberGenerator.seed(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count());
    }
  }

  std::uniform_int_distribution<int> randomNumVesselDistribution(parameters->GetMinNumberOfVessels(), parameters->GetMaxNumberOfVessels());
  std::uniform_real_distribution<double> randomBendingDistribution(parameters->GetMinVesselBending(), parameters->GetMaxVesselBending());
  std::uniform_real_distribution<double> randomAbsorptionDistribution(parameters->GetMinVesselAbsorption(), parameters->GetMaxVesselAbsorption());
  std::uniform_real_distribution<double> randomRadiusDistribution(parameters->GetMinVesselRadiusInMillimeters(), parameters->GetMaxVesselRadiusInMillimeters());
  std::uniform_real_distribution<double> randomScatteringDistribution(parameters->GetMinVesselScattering(), parameters->GetMaxVesselScattering());
  std::uniform_real_distribution<double> randomAnisotropyDistribution(parameters->GetMinVesselAnisotropy(), parameters->GetMaxVesselAnisotropy());
  std::uniform_int_distribution<int> borderTypeDistribution(0, 3);

  int numberOfBloodVessels = randomNumVesselDistribution(randomNumberGenerator);

  generatedVolume->AddIntProperty("numberOfVessels", numberOfBloodVessels);
  generatedVolume->AddIntProperty("bifurcationFrequency", parameters->GetVesselBifurcationFrequency());

  MITK_INFO << "Simulating " << numberOfBloodVessels << " vessel structures";
  for (int vesselNumber = 0; vesselNumber < numberOfBloodVessels; vesselNumber++)
  {
    Vector::Pointer initialPosition = Vector::New();
    Vector::Pointer initialDirection = Vector::New();

    double initialRadius = randomRadiusDistribution(randomNumberGenerator) / parameters->GetVoxelSpacingInCentimeters() / 10;
    std::stringstream radiusString;
    radiusString << "vessel_" << vesselNumber + 1 << "_radius";
    generatedVolume->AddDoubleProperty(radiusString.str(), initialRadius);

    double absorptionCoefficient = randomAbsorptionDistribution(randomNumberGenerator);
    std::stringstream absorptionString;
    absorptionString << "vessel_" << vesselNumber + 1 << "_absorption";
    generatedVolume->AddDoubleProperty(absorptionString.str(), absorptionCoefficient);

    double bendingFactor = randomBendingDistribution(randomNumberGenerator);
    std::stringstream bendingString;
    bendingString << "vessel_" << vesselNumber + 1 << "_bendingFactor";
    generatedVolume->AddDoubleProperty(bendingString.str(), bendingFactor);

    double vesselScattering = randomScatteringDistribution(randomNumberGenerator);
    std::stringstream scatteringString;
    scatteringString << "vessel_" << vesselNumber + 1 << "_scattering";
    generatedVolume->AddDoubleProperty(scatteringString.str(), vesselScattering);

    double vesselAnisotropy = randomAnisotropyDistribution(randomNumberGenerator);
    std::stringstream anisotropyString;
    anisotropyString << "vessel_" << vesselNumber + 1 << "_anisotropy";
    generatedVolume->AddDoubleProperty(anisotropyString.str(), vesselAnisotropy);

    /*The vessel tree shall start at one of the 4 sides of the volume.
    * The vessels will always be completely contained in the volume
    * when starting to meander.
    * They will meander in a direction perpendicular to the
    * plane they started from (within the limits of the
    * DIRECTION_VECTOR_INITIAL_VARIANCE)
    */
    int borderType = borderTypeDistribution(randomNumberGenerator);
    switch (borderType)
    {
    case 0:
      initialPosition->Randomize(0, 0, initialRadius, parameters->GetYDim() - initialRadius, parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(),
        parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator);
      initialDirection->Randomize(1, 2, -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE,
        -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator);
      break;
    case 1:
      initialPosition->Randomize(parameters->GetXDim(), parameters->GetXDim(), initialRadius, parameters->GetYDim() - initialRadius, parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(),
        parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator);
      initialDirection->Randomize(-2, -1, -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE,
        -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator);
      break;
    case 2:
      initialPosition->Randomize(initialRadius, parameters->GetXDim() - initialRadius, 0, 0, parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(),
        parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator);
      initialDirection->Randomize(-DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, 1, 2,
        -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator);
      break;
    case 3:
      initialPosition->Randomize(initialRadius, parameters->GetXDim() - initialRadius, parameters->GetYDim(), parameters->GetYDim(), parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(),
        parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator);
      initialDirection->Randomize(-DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, -2, -1,
        -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator);
      break;
    }

    VesselProperties::Pointer vesselParams = VesselProperties::New();
    vesselParams->SetDirectionVector(initialDirection);
    vesselParams->SetPositionVector(initialPosition);
    vesselParams->SetRadiusInVoxel(initialRadius);
    vesselParams->SetAbsorptionCoefficient(absorptionCoefficient);
    vesselParams->SetScatteringCoefficient(vesselScattering);
    vesselParams->SetAnisotopyCoefficient(vesselAnisotropy);
    vesselParams->SetBifurcationFrequency(parameters->GetVesselBifurcationFrequency());
    vesselParams->SetDoPartialVolume(parameters->GetDoPartialVolume());

    VesselTree::Pointer vesselTree = VesselTree::New(vesselParams);

    while (!vesselTree->IsFinished())
    {
      vesselTree->Step(generatedVolume, parameters->GetCalculateNewVesselPositionCallback(), bendingFactor, &randomNumberGenerator);
    }
  }

  if (parameters->GetDoPartialVolume())
  {
    VolumeManipulator::RescaleImage(generatedVolume, (1.0 / RESAMPLING_FACTOR));
    parameters->SetXDim(parameters->GetXDim() / RESAMPLING_FACTOR);
    parameters->SetYDim(parameters->GetYDim() / RESAMPLING_FACTOR);
    parameters->SetZDim(parameters->GetZDim() / RESAMPLING_FACTOR);
    parameters->SetVesselBifurcationFrequency(parameters->GetVesselBifurcationFrequency() / RESAMPLING_FACTOR);
    parameters->SetVoxelSpacingInCentimeters(parameters->GetVoxelSpacingInCentimeters() * RESAMPLING_FACTOR);
  }

  generatedVolume->FinalizeVolume();

  return generatedVolume;
}

mitk::pa::InSilicoTissueGenerator::InSilicoTissueGenerator()
{
}

mitk::pa::InSilicoTissueGenerator::~InSilicoTissueGenerator()
{
}
<commit_msg>fix a bug, where some vessels would not be simulated due to new out of bounds check<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

Copyright (c) German Cancer Research Center,
Division of Medical and Biological Informatics.
All rights reserved.

This software is distributed WITHOUT ANY WARRANTY; without
even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE.

See LICENSE.txt or http://www.mitk.org for details.

===================================================================*/

#include "mitkPATissueGenerator.h"
#include "mitkPAVector.h"
#include "mitkPAVolumeManipulator.h"

mitk::pa::InSilicoTissueVolume::Pointer mitk::pa::InSilicoTissueGenerator::GenerateInSilicoData(
  TissueGeneratorParameters::Pointer parameters)
{
  MITK_DEBUG << "Initializing Empty Volume";

  const double RESAMPLING_FACTOR = 2;

  if (parameters->GetDoPartialVolume())
  {
    parameters->SetXDim(parameters->GetXDim() * RESAMPLING_FACTOR);
    parameters->SetYDim(parameters->GetYDim() * RESAMPLING_FACTOR);
    parameters->SetZDim(parameters->GetZDim() * RESAMPLING_FACTOR);
    parameters->SetVesselBifurcationFrequency(parameters->GetVesselBifurcationFrequency() * RESAMPLING_FACTOR);
    parameters->SetVoxelSpacingInCentimeters(parameters->GetVoxelSpacingInCentimeters() / RESAMPLING_FACTOR);
  }

  auto generatedVolume = mitk::pa::InSilicoTissueVolume::New(parameters);

  const double DIRECTION_VECTOR_INITIAL_VARIANCE = 0.2;

  std::mt19937 randomNumberGenerator;
  std::random_device randomDevice;
  if (parameters->GetUseRngSeed())
  {
    randomNumberGenerator.seed(parameters->GetRngSeed());
  }
  else
  {
    if (randomDevice.entropy() > 0.1)
    {
      randomNumberGenerator.seed(randomDevice());
    }
    else
    {
      randomNumberGenerator.seed(std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::high_resolution_clock::now().time_since_epoch()).count());
    }
  }

  std::uniform_int_distribution<int> randomNumVesselDistribution(parameters->GetMinNumberOfVessels(), parameters->GetMaxNumberOfVessels());
  std::uniform_real_distribution<double> randomBendingDistribution(parameters->GetMinVesselBending(), parameters->GetMaxVesselBending());
  std::uniform_real_distribution<double> randomAbsorptionDistribution(parameters->GetMinVesselAbsorption(), parameters->GetMaxVesselAbsorption());
  std::uniform_real_distribution<double> randomRadiusDistribution(parameters->GetMinVesselRadiusInMillimeters(), parameters->GetMaxVesselRadiusInMillimeters());
  std::uniform_real_distribution<double> randomScatteringDistribution(parameters->GetMinVesselScattering(), parameters->GetMaxVesselScattering());
  std::uniform_real_distribution<double> randomAnisotropyDistribution(parameters->GetMinVesselAnisotropy(), parameters->GetMaxVesselAnisotropy());
  std::uniform_int_distribution<int> borderTypeDistribution(0, 3);

  int numberOfBloodVessels = randomNumVesselDistribution(randomNumberGenerator);

  generatedVolume->AddIntProperty("numberOfVessels", numberOfBloodVessels);
  generatedVolume->AddIntProperty("bifurcationFrequency", parameters->GetVesselBifurcationFrequency());

  MITK_INFO << "Simulating " << numberOfBloodVessels << " vessel structures";
  for (int vesselNumber = 0; vesselNumber < numberOfBloodVessels; vesselNumber++)
  {
    Vector::Pointer initialPosition = Vector::New();
    Vector::Pointer initialDirection = Vector::New();

    double initialRadius = randomRadiusDistribution(randomNumberGenerator) / parameters->GetVoxelSpacingInCentimeters() / 10;
    std::stringstream radiusString;
    radiusString << "vessel_" << vesselNumber + 1 << "_radius";
    generatedVolume->AddDoubleProperty(radiusString.str(), initialRadius);

    double absorptionCoefficient = randomAbsorptionDistribution(randomNumberGenerator);
    std::stringstream absorptionString;
    absorptionString << "vessel_" << vesselNumber + 1 << "_absorption";
    generatedVolume->AddDoubleProperty(absorptionString.str(), absorptionCoefficient);

    double bendingFactor = randomBendingDistribution(randomNumberGenerator);
    std::stringstream bendingString;
    bendingString << "vessel_" << vesselNumber + 1 << "_bendingFactor";
    generatedVolume->AddDoubleProperty(bendingString.str(), bendingFactor);

    double vesselScattering = randomScatteringDistribution(randomNumberGenerator);
    std::stringstream scatteringString;
    scatteringString << "vessel_" << vesselNumber + 1 << "_scattering";
    generatedVolume->AddDoubleProperty(scatteringString.str(), vesselScattering);

    double vesselAnisotropy = randomAnisotropyDistribution(randomNumberGenerator);
    std::stringstream anisotropyString;
    anisotropyString << "vessel_" << vesselNumber + 1 << "_anisotropy";
    generatedVolume->AddDoubleProperty(anisotropyString.str(), vesselAnisotropy);

    /*The vessel tree shall start at one of the 4 sides of the volume.
    * The vessels will always be completely contained in the volume
    * when starting to meander.
    * They will meander in a direction perpendicular to the
    * plane they started from (within the limits of the
    * DIRECTION_VECTOR_INITIAL_VARIANCE)
    */
    int borderType = borderTypeDistribution(randomNumberGenerator);
    switch (borderType)
    {
    case 0:
      initialPosition->Randomize(0, 0, initialRadius, parameters->GetYDim() - initialRadius, parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(),
        parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator);
      initialDirection->Randomize(1, 2, -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE,
        -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator);
      break;
    case 1:
      initialPosition->Randomize(parameters->GetXDim() - 1, parameters->GetXDim() - 1, initialRadius, parameters->GetYDim() - initialRadius, parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(),
        parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator);
      initialDirection->Randomize(-2, -1, -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE,
        -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator);
      break;
    case 2:
      initialPosition->Randomize(initialRadius, parameters->GetXDim() - initialRadius, 0, 0, parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(),
        parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator);
      initialDirection->Randomize(-DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, 1, 2,
        -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator);
      break;
    case 3:
      initialPosition->Randomize(initialRadius, parameters->GetXDim() - initialRadius, parameters->GetYDim() - 1, parameters->GetYDim() - 1, parameters->GetMinVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(),
        parameters->GetMaxVesselZOrigin() / parameters->GetVoxelSpacingInCentimeters(), &randomNumberGenerator);
      initialDirection->Randomize(-DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, -2, -1,
        -DIRECTION_VECTOR_INITIAL_VARIANCE, DIRECTION_VECTOR_INITIAL_VARIANCE, &randomNumberGenerator);
      break;
    }

    initialDirection->Normalize();
    MITK_INFO << initialPosition->GetElement(0) << " | " << initialPosition->GetElement(1) << " | " << initialPosition->GetElement(2);
    MITK_INFO << initialDirection->GetElement(0) << " | " << initialDirection->GetElement(1) << " | " << initialDirection->GetElement(2);

    VesselProperties::Pointer vesselParams = VesselProperties::New();
    vesselParams->SetDirectionVector(initialDirection);
    vesselParams->SetPositionVector(initialPosition);
    vesselParams->SetRadiusInVoxel(initialRadius);
    vesselParams->SetAbsorptionCoefficient(absorptionCoefficient);
    vesselParams->SetScatteringCoefficient(vesselScattering);
    vesselParams->SetAnisotopyCoefficient(vesselAnisotropy);
    vesselParams->SetBifurcationFrequency(parameters->GetVesselBifurcationFrequency());
    vesselParams->SetDoPartialVolume(parameters->GetDoPartialVolume());

    VesselTree::Pointer vesselTree = VesselTree::New(vesselParams);

    while (!vesselTree->IsFinished())
    {
      vesselTree->Step(generatedVolume, parameters->GetCalculateNewVesselPositionCallback(), bendingFactor, &randomNumberGenerator);
    }
  }

  if (parameters->GetDoPartialVolume())
  {
    VolumeManipulator::RescaleImage(generatedVolume, (1.0 / RESAMPLING_FACTOR));
    parameters->SetXDim(parameters->GetXDim() / RESAMPLING_FACTOR);
    parameters->SetYDim(parameters->GetYDim() / RESAMPLING_FACTOR);
    parameters->SetZDim(parameters->GetZDim() / RESAMPLING_FACTOR);
    parameters->SetVesselBifurcationFrequency(parameters->GetVesselBifurcationFrequency() / RESAMPLING_FACTOR);
    parameters->SetVoxelSpacingInCentimeters(parameters->GetVoxelSpacingInCentimeters() * RESAMPLING_FACTOR);
  }

  generatedVolume->FinalizeVolume();

  return generatedVolume;
}

mitk::pa::InSilicoTissueGenerator::InSilicoTissueGenerator()
{
}

mitk::pa::InSilicoTissueGenerator::~InSilicoTissueGenerator()
{
}
<|endoftext|>


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

#include "absl/flags/flag.h"
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "xls/codegen/combinational_generator.h"
#include "xls/codegen/module_signature.pb.h"
#include "xls/codegen/pipeline_generator.h"
#include "xls/common/file/filesystem.h"
#include "xls/common/init_xls.h"
#include "xls/common/logging/logging.h"
#include "xls/common/status/ret_check.h"
#include "xls/common/status/status_macros.h"
#include "xls/delay_model/delay_estimator.h"
#include "xls/delay_model/delay_estimators.h"
#include "xls/ir/ir_parser.h"
#include "xls/passes/standard_pipeline.h"
#include "xls/scheduling/pipeline_schedule.h"
#include "xls/scheduling/scheduling_pass.h"

const char kUsage[] = R"(
Generates Verilog RTL from a given IR file. Writes a Verilog file and a module
signature describing the module interface to a specified location. Example
invocations:

Emit combinational module:
   codegen_main --generator=combinational --output_verilog_path=DIR IR_FILE

Emit a feed-forward pipelined module:
   codegen_main --generator=pipeline \
       --clock_period_ps=500 \
       --pipeline_stages=7 \
       IR_FILE
)";

ABSL_FLAG(int64_t, clock_period_ps, 0, "Target clock period, in picoseconds.");
ABSL_FLAG(int64_t, pipeline_stages, 0,
          "The number of stages in the generated pipeline.");
ABSL_FLAG(std::string, delay_model, "",
          "Delay model name to use from registry.");
ABSL_FLAG(
    std::string, output_verilog_path, "",
    "Specific output path for the Verilog generated. If not specified then "
    "Verilog is written to stdout.");
ABSL_FLAG(std::string, output_schedule_path, "",
          "Specific output path for the generated pipeline schedule. "
          "If not specified, then no schedule is output.");
ABSL_FLAG(
    std::string, output_signature_path, "",
    "Specific output path for the module signature. If not specified then "
    "no module signature is generated.");
ABSL_FLAG(std::string, entry, "", "Entry function for the package.");
ABSL_FLAG(std::string, generator, "pipeline",
          "The generator to use when emitting the device function. Valid "
          "values: pipeline, combinational.");
ABSL_FLAG(
    std::string, input_valid_signal, "",
    "If specified, the emitted module will use an external \"valid\" signal "
    "as the load enable for pipeline registers. The flag value is the "
    "name of the input port for this signal.");
ABSL_FLAG(std::string, output_valid_signal, "",
          "The name of the output port which holds the pipelined valid signal. "
          "Must be specified with --input_valid_signal.");
ABSL_FLAG(
    std::string, manual_load_enable_signal, "",
    "If specified the load-enable of the pipeline registers of each stage is "
    "controlled via an input port of the indicated name. The width of the "
    "input port is equal to the number of pipeline stages. Bit N of the port "
    "is the load-enable signal for the pipeline registers after stage N.");
ABSL_FLAG(bool, flop_inputs, true,
          "If true, inputs of the the module are flopped into registers before "
          "use in generated pipelines. Only used with pipline generator.");
ABSL_FLAG(bool, flop_outputs, true,
          "If true, the module outputs are flopped into registers before "
          "leaving module. Only used with pipline generator.");
ABSL_FLAG(std::string, module_name, "",
          "Explicit name to use for the generated module; if not provided the "
          "mangled IR function name is used");
ABSL_FLAG(int64_t, clock_margin_percent, 0,
          "The percentage of clock period to set aside as a margin to ensure "
          "timing is met. Effectively, this lowers the clock period by this "
          "percentage amount for the purposes of scheduling.");
// TODO(meheff): Rather than specify all reset (or codegen options in general)
// as a multitude of flags, these can be specified via a separate file (like a
// options proto).
ABSL_FLAG(std::string, reset, "",
          "Name of the reset signal. If empty, no reset signal is used.");
ABSL_FLAG(bool, reset_active_low, false,
          "Whether the reset signal is active low.");
ABSL_FLAG(bool, reset_asynchronous, false,
          "Whether the reset signal is asynchronous.");
ABSL_FLAG(bool, use_system_verilog, true,
          "If true, emit SystemVerilog otherwise emit Verilog.");

namespace xls {
namespace {

absl::Status RealMain(absl::string_view ir_path, absl::string_view verilog_path,
                      absl::string_view signature_path,
                      absl::string_view schedule_path) {
  XLS_ASSIGN_OR_RETURN(std::string ir_contents, GetFileContents(ir_path));
  XLS_ASSIGN_OR_RETURN(std::unique_ptr<Package> p,
                       Parser::ParsePackage(ir_contents, ir_path));

  Function* main;
  if (absl::GetFlag(FLAGS_entry).empty()) {
    XLS_ASSIGN_OR_RETURN(main, p->EntryFunction());
  } else {
    XLS_ASSIGN_OR_RETURN(main, p->GetFunction(absl::GetFlag(FLAGS_entry)));
  }

  verilog::ModuleGeneratorResult result;
  if (absl::GetFlag(FLAGS_generator) == "pipeline") {
    XLS_QCHECK(absl::GetFlag(FLAGS_pipeline_stages) != 0 ||
               absl::GetFlag(FLAGS_clock_period_ps) != 0)
        << "Musts specify --pipeline_stages or --clock_period_ps (or both).";

    SchedulingPassOptions sched_options;
    if (!absl::GetFlag(FLAGS_entry).empty()) {
      sched_options.scheduling_options.entry(absl::GetFlag(FLAGS_entry));
    }
    if (absl::GetFlag(FLAGS_pipeline_stages) != 0) {
      sched_options.scheduling_options.pipeline_stages(
          absl::GetFlag(FLAGS_pipeline_stages));
    }
    if (absl::GetFlag(FLAGS_clock_period_ps) != 0) {
      sched_options.scheduling_options.clock_period_ps(
          absl::GetFlag(FLAGS_clock_period_ps));
    }
    if (absl::GetFlag(FLAGS_clock_margin_percent) != 0) {
      sched_options.scheduling_options.clock_margin_percent(
          absl::GetFlag(FLAGS_clock_margin_percent));
    }
    XLS_ASSIGN_OR_RETURN(sched_options.delay_estimator,
                         GetDelayEstimator(absl::GetFlag(FLAGS_delay_model)));
    std::unique_ptr<SchedulingCompoundPass> scheduling_pipeline =
        CreateStandardSchedulingPassPipeline();
    SchedulingPassResults results;
    SchedulingUnit scheduling_unit = {p.get(),
                                      /*schedule=*/absl::nullopt};
    absl::Status scheduling_status =
        scheduling_pipeline->Run(&scheduling_unit, sched_options, &results)
            .status();
    if (!scheduling_status.ok()) {
      if (absl::IsResourceExhausted(scheduling_status)) {
        // Resource exhausted error indicates that the schedule was
        // infeasible. Emit a meaningful error in this case.
        if (sched_options.scheduling_options.pipeline_stages().has_value() &&
            sched_options.scheduling_options.clock_period_ps().has_value()) {
          // TODO(meheff): Add link to documentation with more information and
          // guidance.
          XLS_LOG(QFATAL) << absl::StreamFormat(
              "Design cannot be scheduled in %d stages with a %dps clock.",
              sched_options.scheduling_options.pipeline_stages().value(),
              sched_options.scheduling_options.clock_period_ps().value());
        }
      }
      return scheduling_status;
    }
    XLS_RET_CHECK(scheduling_unit.schedule.has_value());

    verilog::PipelineOptions pipeline_options;
    if (!absl::GetFlag(FLAGS_module_name).empty()) {
      pipeline_options.module_name(absl::GetFlag(FLAGS_module_name));
    }
    pipeline_options.use_system_verilog(
        absl::GetFlag(FLAGS_use_system_verilog));
    if (!absl::GetFlag(FLAGS_input_valid_signal).empty()) {
      pipeline_options.valid_control(absl::GetFlag(FLAGS_input_valid_signal),
                                     absl::GetFlag(FLAGS_output_valid_signal));
    } else if (!absl::GetFlag(FLAGS_manual_load_enable_signal).empty()) {
      pipeline_options.manual_control(
          absl::GetFlag(FLAGS_manual_load_enable_signal));
    }
    pipeline_options.flop_inputs(absl::GetFlag(FLAGS_flop_inputs));
    pipeline_options.flop_outputs(absl::GetFlag(FLAGS_flop_outputs));

    if (!absl::GetFlag(FLAGS_reset).empty()) {
      verilog::ResetProto reset_proto;
      reset_proto.set_name(absl::GetFlag(FLAGS_reset));
      reset_proto.set_asynchronous(absl::GetFlag(FLAGS_reset_asynchronous));
      reset_proto.set_active_low(absl::GetFlag(FLAGS_reset_active_low));
      pipeline_options.reset(reset_proto);
    }

    XLS_ASSIGN_OR_RETURN(
        result, verilog::ToPipelineModuleText(*scheduling_unit.schedule, main,
                                              pipeline_options));
    if (!schedule_path.empty()) {
      XLS_RETURN_IF_ERROR(
          SetTextProtoFile(schedule_path, scheduling_unit.schedule->ToProto()));
    }
  } else if (absl::GetFlag(FLAGS_generator) == "combinational") {
    XLS_ASSIGN_OR_RETURN(result,
                         verilog::GenerateCombinationalModule(
                             main, absl::GetFlag(FLAGS_use_system_verilog)));
  } else {
    XLS_LOG(QFATAL) << absl::StreamFormat(
        "Invalid value for --generator: %s. Expected 'pipeline' or "
        "'combinational'",
        absl::GetFlag(FLAGS_generator));
  }
  if (!signature_path.empty()) {
    XLS_RETURN_IF_ERROR(
        SetTextProtoFile(signature_path, result.signature.proto()));
  }
  if (verilog_path.empty()) {
    std::cout << result.verilog_text;
  } else {
    XLS_RETURN_IF_ERROR(SetFileContents(verilog_path, result.verilog_text));
  }
  return absl::OkStatus();
}

}  // namespace
}  // namespace xls

int main(int argc, char** argv) {
  std::vector<absl::string_view> positional_arguments =
      xls::InitXls(kUsage, argc, argv);

  if (positional_arguments.size() != 1) {
    XLS_LOG(QFATAL) << absl::StreamFormat("Expected invocation: %s IR_FILE",
                                          argv[0]);
  }
  absl::string_view ir_path = positional_arguments[0];
  XLS_QCHECK_OK(xls::RealMain(ir_path, absl::GetFlag(FLAGS_output_verilog_path),
                              absl::GetFlag(FLAGS_output_signature_path),
                              absl::GetFlag(FLAGS_output_schedule_path)));

  return EXIT_SUCCESS;
}
<commit_msg>[tools/codegen_main] accept stdin as positional argument<commit_after>// Copyright 2020 The XLS Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

#include "absl/flags/flag.h"
#include "absl/status/status.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "xls/codegen/combinational_generator.h"
#include "xls/codegen/module_signature.pb.h"
#include "xls/codegen/pipeline_generator.h"
#include "xls/common/file/filesystem.h"
#include "xls/common/init_xls.h"
#include "xls/common/logging/logging.h"
#include "xls/common/status/ret_check.h"
#include "xls/common/status/status_macros.h"
#include "xls/delay_model/delay_estimator.h"
#include "xls/delay_model/delay_estimators.h"
#include "xls/ir/ir_parser.h"
#include "xls/passes/standard_pipeline.h"
#include "xls/scheduling/pipeline_schedule.h"
#include "xls/scheduling/scheduling_pass.h"

const char kUsage[] = R"(
Generates Verilog RTL from a given IR file. Writes a Verilog file and a module
signature describing the module interface to a specified location. Example
invocations:

Emit combinational module:
   codegen_main --generator=combinational --output_verilog_path=DIR IR_FILE

Emit a feed-forward pipelined module:
   codegen_main --generator=pipeline \
       --clock_period_ps=500 \
       --pipeline_stages=7 \
       IR_FILE
)";

ABSL_FLAG(int64_t, clock_period_ps, 0, "Target clock period, in picoseconds.");
ABSL_FLAG(int64_t, pipeline_stages, 0,
          "The number of stages in the generated pipeline.");
ABSL_FLAG(std::string, delay_model, "",
          "Delay model name to use from registry.");
ABSL_FLAG(
    std::string, output_verilog_path, "",
    "Specific output path for the Verilog generated. If not specified then "
    "Verilog is written to stdout.");
ABSL_FLAG(std::string, output_schedule_path, "",
          "Specific output path for the generated pipeline schedule. "
          "If not specified, then no schedule is output.");
ABSL_FLAG(
    std::string, output_signature_path, "",
    "Specific output path for the module signature. If not specified then "
    "no module signature is generated.");
ABSL_FLAG(std::string, entry, "", "Entry function for the package.");
ABSL_FLAG(std::string, generator, "pipeline",
          "The generator to use when emitting the device function. Valid "
          "values: pipeline, combinational.");
ABSL_FLAG(
    std::string, input_valid_signal, "",
    "If specified, the emitted module will use an external \"valid\" signal "
    "as the load enable for pipeline registers. The flag value is the "
    "name of the input port for this signal.");
ABSL_FLAG(std::string, output_valid_signal, "",
          "The name of the output port which holds the pipelined valid signal. "
          "Must be specified with --input_valid_signal.");
ABSL_FLAG(
    std::string, manual_load_enable_signal, "",
    "If specified the load-enable of the pipeline registers of each stage is "
    "controlled via an input port of the indicated name. The width of the "
    "input port is equal to the number of pipeline stages. Bit N of the port "
    "is the load-enable signal for the pipeline registers after stage N.");
ABSL_FLAG(bool, flop_inputs, true,
          "If true, inputs of the the module are flopped into registers before "
          "use in generated pipelines. Only used with pipline generator.");
ABSL_FLAG(bool, flop_outputs, true,
          "If true, the module outputs are flopped into registers before "
          "leaving module. Only used with pipline generator.");
ABSL_FLAG(std::string, module_name, "",
          "Explicit name to use for the generated module; if not provided the "
          "mangled IR function name is used");
ABSL_FLAG(int64_t, clock_margin_percent, 0,
          "The percentage of clock period to set aside as a margin to ensure "
          "timing is met. Effectively, this lowers the clock period by this "
          "percentage amount for the purposes of scheduling.");
// TODO(meheff): Rather than specify all reset (or codegen options in general)
// as a multitude of flags, these can be specified via a separate file (like a
// options proto).
ABSL_FLAG(std::string, reset, "",
          "Name of the reset signal. If empty, no reset signal is used.");
ABSL_FLAG(bool, reset_active_low, false,
          "Whether the reset signal is active low.");
ABSL_FLAG(bool, reset_asynchronous, false,
          "Whether the reset signal is asynchronous.");
ABSL_FLAG(bool, use_system_verilog, true,
          "If true, emit SystemVerilog otherwise emit Verilog.");

namespace xls {
namespace {

absl::Status RealMain(absl::string_view ir_path, absl::string_view verilog_path,
                      absl::string_view signature_path,
                      absl::string_view schedule_path) {
  if (ir_path == "-") {
    ir_path = "/dev/stdin";
  }
  XLS_ASSIGN_OR_RETURN(std::string ir_contents, GetFileContents(ir_path));
  XLS_ASSIGN_OR_RETURN(std::unique_ptr<Package> p,
                       Parser::ParsePackage(ir_contents, ir_path));

  Function* main;
  if (absl::GetFlag(FLAGS_entry).empty()) {
    XLS_ASSIGN_OR_RETURN(main, p->EntryFunction());
  } else {
    XLS_ASSIGN_OR_RETURN(main, p->GetFunction(absl::GetFlag(FLAGS_entry)));
  }

  verilog::ModuleGeneratorResult result;
  if (absl::GetFlag(FLAGS_generator) == "pipeline") {
    XLS_QCHECK(absl::GetFlag(FLAGS_pipeline_stages) != 0 ||
               absl::GetFlag(FLAGS_clock_period_ps) != 0)
        << "Musts specify --pipeline_stages or --clock_period_ps (or both).";

    SchedulingPassOptions sched_options;
    if (!absl::GetFlag(FLAGS_entry).empty()) {
      sched_options.scheduling_options.entry(absl::GetFlag(FLAGS_entry));
    }
    if (absl::GetFlag(FLAGS_pipeline_stages) != 0) {
      sched_options.scheduling_options.pipeline_stages(
          absl::GetFlag(FLAGS_pipeline_stages));
    }
    if (absl::GetFlag(FLAGS_clock_period_ps) != 0) {
      sched_options.scheduling_options.clock_period_ps(
          absl::GetFlag(FLAGS_clock_period_ps));
    }
    if (absl::GetFlag(FLAGS_clock_margin_percent) != 0) {
      sched_options.scheduling_options.clock_margin_percent(
          absl::GetFlag(FLAGS_clock_margin_percent));
    }
    XLS_ASSIGN_OR_RETURN(sched_options.delay_estimator,
                         GetDelayEstimator(absl::GetFlag(FLAGS_delay_model)));
    std::unique_ptr<SchedulingCompoundPass> scheduling_pipeline =
        CreateStandardSchedulingPassPipeline();
    SchedulingPassResults results;
    SchedulingUnit scheduling_unit = {p.get(),
                                      /*schedule=*/absl::nullopt};
    absl::Status scheduling_status =
        scheduling_pipeline->Run(&scheduling_unit, sched_options, &results)
            .status();
    if (!scheduling_status.ok()) {
      if (absl::IsResourceExhausted(scheduling_status)) {
        // Resource exhausted error indicates that the schedule was
        // infeasible. Emit a meaningful error in this case.
        if (sched_options.scheduling_options.pipeline_stages().has_value() &&
            sched_options.scheduling_options.clock_period_ps().has_value()) {
          // TODO(meheff): Add link to documentation with more information and
          // guidance.
          XLS_LOG(QFATAL) << absl::StreamFormat(
              "Design cannot be scheduled in %d stages with a %dps clock.",
              sched_options.scheduling_options.pipeline_stages().value(),
              sched_options.scheduling_options.clock_period_ps().value());
        }
      }
      return scheduling_status;
    }
    XLS_RET_CHECK(scheduling_unit.schedule.has_value());

    verilog::PipelineOptions pipeline_options;
    if (!absl::GetFlag(FLAGS_module_name).empty()) {
      pipeline_options.module_name(absl::GetFlag(FLAGS_module_name));
    }
    pipeline_options.use_system_verilog(
        absl::GetFlag(FLAGS_use_system_verilog));
    if (!absl::GetFlag(FLAGS_input_valid_signal).empty()) {
      pipeline_options.valid_control(absl::GetFlag(FLAGS_input_valid_signal),
                                     absl::GetFlag(FLAGS_output_valid_signal));
    } else if (!absl::GetFlag(FLAGS_manual_load_enable_signal).empty()) {
      pipeline_options.manual_control(
          absl::GetFlag(FLAGS_manual_load_enable_signal));
    }
    pipeline_options.flop_inputs(absl::GetFlag(FLAGS_flop_inputs));
    pipeline_options.flop_outputs(absl::GetFlag(FLAGS_flop_outputs));

    if (!absl::GetFlag(FLAGS_reset).empty()) {
      verilog::ResetProto reset_proto;
      reset_proto.set_name(absl::GetFlag(FLAGS_reset));
      reset_proto.set_asynchronous(absl::GetFlag(FLAGS_reset_asynchronous));
      reset_proto.set_active_low(absl::GetFlag(FLAGS_reset_active_low));
      pipeline_options.reset(reset_proto);
    }

    XLS_ASSIGN_OR_RETURN(
        result, verilog::ToPipelineModuleText(*scheduling_unit.schedule, main,
                                              pipeline_options));
    if (!schedule_path.empty()) {
      XLS_RETURN_IF_ERROR(
          SetTextProtoFile(schedule_path, scheduling_unit.schedule->ToProto()));
    }
  } else if (absl::GetFlag(FLAGS_generator) == "combinational") {
    XLS_ASSIGN_OR_RETURN(result,
                         verilog::GenerateCombinationalModule(
                             main, absl::GetFlag(FLAGS_use_system_verilog)));
  } else {
    XLS_LOG(QFATAL) << absl::StreamFormat(
        "Invalid value for --generator: %s. Expected 'pipeline' or "
        "'combinational'",
        absl::GetFlag(FLAGS_generator));
  }
  if (!signature_path.empty()) {
    XLS_RETURN_IF_ERROR(
        SetTextProtoFile(signature_path, result.signature.proto()));
  }
  if (verilog_path.empty()) {
    std::cout << result.verilog_text;
  } else {
    XLS_RETURN_IF_ERROR(SetFileContents(verilog_path, result.verilog_text));
  }
  return absl::OkStatus();
}

}  // namespace
}  // namespace xls

int main(int argc, char** argv) {
  std::vector<absl::string_view> positional_arguments =
      xls::InitXls(kUsage, argc, argv);

  if (positional_arguments.size() != 1) {
    XLS_LOG(QFATAL) << absl::StreamFormat("Expected invocation: %s IR_FILE",
                                          argv[0]);
  }
  absl::string_view ir_path = positional_arguments[0];
  XLS_QCHECK_OK(xls::RealMain(ir_path, absl::GetFlag(FLAGS_output_verilog_path),
                              absl::GetFlag(FLAGS_output_signature_path),
                              absl::GetFlag(FLAGS_output_schedule_path)));

  return EXIT_SUCCESS;
}
<|endoftext|>


<commit_before>// @(#)root/gui:$Name:  $:$Id: TGApplication.cxx,v 1.6 2003/05/12 16:44:08 rdm Exp $
// Author: Guy Barrand   30/05/2001

/*************************************************************************
 * Copyright (C) 2001, Guy Barrand.                                      *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGApplication                                                        //
//                                                                      //
// This class initialize the ROOT GUI toolkit.                          //
// This class must be instantiated exactly once in any given            //
// application.                                                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifdef HAVE_CONFIG
#include "config.h"
#endif

#include "TGApplication.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TGClient.h"
#include "TPluginManager.h"
#include "TError.h"
#include "TEnv.h"
#include "TVirtualX.h"
#include "TStyle.h"
#include "TInterpreter.h"

ClassImp(TGApplication)

//_____________________________________________________________________________
TGApplication::TGApplication(const char *appClassName,
                             int *argc, char **argv, void*, int)
   : TApplication(), fDisplay(0), fClient(0)
{
   // Create a GUI application environment. Use this class if you only
   // want to use the ROOT GUI and no other services. In all other cases
   // use either TApplication or TRint.

   if (gApplication) {
      Error("TGApplication", "only one instance of TGApplication allowed");
      return;
   }

   if (!gROOT)
      ::Fatal("TGApplication::TGApplication", "ROOT system not initialized");

   if (!gSystem)
      ::Fatal("TGApplication::TGApplication", "gSystem not initialized");

   gApplication = this;
   gROOT->SetApplication(this);
   gROOT->SetName(appClassName);

   GetOptions(argc, argv);
   if (argv && argv[0])
      gSystem->SetProgname(argv[0]);

   LoadGraphicsLibs();

   if (!fDisplay) gSystem->SetDisplay();
   fClient = new TGClient(fDisplay);

   if (fClient->IsZombie()) {
      Error("TGApplication", "cannot switch to batch mode, exiting...");
      gSystem->Exit(1);
   }

#if !defined(R__WIN32) || defined(GDK_WIN32)
   if (strcmp(appClassName, "proofserv")) {
      const char *ttpath = gEnv->GetValue("Root.TTFontPath",
# ifdef TTFFONTDIR
                                          TTFFONTDIR);
# else
                                          "$(ROOTSYS)/fonts");
# endif
      char *ttfont = gSystem->Which(ttpath, "arialbd.ttf", kReadPermission);

      if (!gROOT->IsBatch() && ttfont && gEnv->GetValue("Root.UseTTFonts", 1)) {
         TPluginHandler *h;
         if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", "x11ttf")))
            h->LoadPlugin();
      }

      delete [] ttfont;
   }
#endif

   // Create the canvas colors early so they are allocated before
   // any color table expensive bitmaps get allocated in GUI routines (like
   // creation of XPM bitmaps).
   InitializeColors();

   // Set default screen factor (if not disabled in rc file)
   if (gEnv->GetValue("Canvas.UseScreenFactor", 1)) {
      Int_t  x, y;
      UInt_t w, h;
      if (gVirtualX) {
         gVirtualX->GetGeometry(-1, x, y, w, h);
         if (h > 0 && h < 1000) gStyle->SetScreenFactor(0.0011*h);
      }
   }

   // Make sure all registered dictionaries have been initialized
   // and that all types have been loaded
   gInterpreter->InitializeDictionaries();
   gInterpreter->UpdateListOfTypes();

   // Save current interpreter context
   gInterpreter->SaveContext();
   gInterpreter->SaveGlobalsContext();

   gROOT->SetLineHasBeenProcessed(); // to allow user to interact with TCanvas's under WIN32

}

//_____________________________________________________________________________
TGApplication::~TGApplication()
{
   // TGApplication dtor.

   delete fDisplay;
   delete fClient;
}

//_____________________________________________________________________________
void TGApplication::LoadGraphicsLibs()
{
   // Load shared libs necessary for GUI.

   TString name;
   TString title1 = "ROOT interface to ";
   TString nativex, title;
#ifndef R__WIN32
   nativex = "x11";
   name    = "X11";
   title   = title1 + "X11";
#else
#ifndef GDK_WIN32
   nativex = "win32";
   name    = "Win32";
   title   = title1 + "Win32";
#else
   nativex = "win32gdk";
   name    = "Win32gdk";
   title   = title1 + "Win32gdk";
#endif
#endif

   TString guiBackend(gEnv->GetValue("Gui.Backend", "native"));
   guiBackend.ToLower();
   if (guiBackend == "native") {
      guiBackend = nativex;
   } else {
      name   = guiBackend;
      title  = title1 + guiBackend;
   }

   TPluginHandler *h;
   if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", guiBackend))) {
      if (h->LoadPlugin() == -1)
         return;
      gVirtualX = (TVirtualX *) h->ExecPlugin(2, name.Data(), title.Data());
   }
}

//______________________________________________________________________________
void TGApplication::GetOptions(Int_t *argc, char **argv)
{
   // Handle command line arguments. Arguments handled are removed from the
   // argument array. Currently only option "-display xserver" is considered.

   if (!argc) return;

   int i, j;
   for (i = 0; i < *argc; i++) {
      if (!strcmp(argv[i], "-display")) {
         if (argv[i+1] && strlen(argv[i+1]) && argv[i+1][0] != '-') {
            fDisplay = StrDup(argv[i+1]);
            argv[i]   = 0;
            argv[i+1] = 0;
            i++;
         }
      }
   }

   j = 0;
   for (i = 0; i < *argc; i++) {
      if (argv[i]) {
         argv[j] = argv[i];
         j++;
      }
   }

   *argc = j;
}

<commit_msg>if connection to X server was successful make sure that TROOT is not in batch mode, a GUI in batch mode makes no sense.<commit_after>// @(#)root/gui:$Name:  $:$Id: TGApplication.cxx,v 1.7 2003/10/22 17:20:50 rdm Exp $
// Author: Guy Barrand   30/05/2001

/*************************************************************************
 * Copyright (C) 2001, Guy Barrand.                                      *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

//////////////////////////////////////////////////////////////////////////
//                                                                      //
// TGApplication                                                        //
//                                                                      //
// This class initialize the ROOT GUI toolkit.                          //
// This class must be instantiated exactly once in any given            //
// application.                                                         //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#ifdef HAVE_CONFIG
#include "config.h"
#endif

#include "TGApplication.h"
#include "TROOT.h"
#include "TSystem.h"
#include "TGClient.h"
#include "TPluginManager.h"
#include "TError.h"
#include "TEnv.h"
#include "TVirtualX.h"
#include "TStyle.h"
#include "TInterpreter.h"

ClassImp(TGApplication)

//_____________________________________________________________________________
TGApplication::TGApplication(const char *appClassName,
                             int *argc, char **argv, void*, int)
   : TApplication(), fDisplay(0), fClient(0)
{
   // Create a GUI application environment. Use this class if you only
   // want to use the ROOT GUI and no other services. In all other cases
   // use either TApplication or TRint.

   if (gApplication) {
      Error("TGApplication", "only one instance of TGApplication allowed");
      return;
   }

   if (!gROOT)
      ::Fatal("TGApplication::TGApplication", "ROOT system not initialized");

   if (!gSystem)
      ::Fatal("TGApplication::TGApplication", "gSystem not initialized");

   gApplication = this;
   gROOT->SetApplication(this);
   gROOT->SetName(appClassName);

   GetOptions(argc, argv);
   if (argv && argv[0])
      gSystem->SetProgname(argv[0]);

   LoadGraphicsLibs();

   if (!fDisplay) gSystem->SetDisplay();
   fClient = new TGClient(fDisplay);

   if (fClient->IsZombie()) {
      Error("TGApplication", "cannot switch to batch mode, exiting...");
      gSystem->Exit(1);
   }

   // a GUI application is never run in batch mode
   gROOT->SetBatch(kFALSE);

#if !defined(R__WIN32) || defined(GDK_WIN32)
   if (strcmp(appClassName, "proofserv")) {
      const char *ttpath = gEnv->GetValue("Root.TTFontPath",
# ifdef TTFFONTDIR
                                          TTFFONTDIR);
# else
                                          "$(ROOTSYS)/fonts");
# endif
      char *ttfont = gSystem->Which(ttpath, "arialbd.ttf", kReadPermission);

      if (ttfont && gEnv->GetValue("Root.UseTTFonts", 1)) {
         TPluginHandler *h;
         if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", "x11ttf")))
            h->LoadPlugin();
      }

      delete [] ttfont;
   }
#endif

   // Create the canvas colors early so they are allocated before
   // any color table expensive bitmaps get allocated in GUI routines (like
   // creation of XPM bitmaps).
   InitializeColors();

   // Set default screen factor (if not disabled in rc file)
   if (gEnv->GetValue("Canvas.UseScreenFactor", 1)) {
      Int_t  x, y;
      UInt_t w, h;
      if (gVirtualX) {
         gVirtualX->GetGeometry(-1, x, y, w, h);
         if (h > 0 && h < 1000) gStyle->SetScreenFactor(0.0011*h);
      }
   }

   // Make sure all registered dictionaries have been initialized
   // and that all types have been loaded
   gInterpreter->InitializeDictionaries();
   gInterpreter->UpdateListOfTypes();

   // Save current interpreter context
   gInterpreter->SaveContext();
   gInterpreter->SaveGlobalsContext();

   // to allow user to interact with TCanvas's under WIN32
   gROOT->SetLineHasBeenProcessed();
}

//_____________________________________________________________________________
TGApplication::~TGApplication()
{
   // TGApplication dtor.

   delete fDisplay;
   delete fClient;
}

//_____________________________________________________________________________
void TGApplication::LoadGraphicsLibs()
{
   // Load shared libs necessary for GUI.

   TString name;
   TString title1 = "ROOT interface to ";
   TString nativex, title;
#ifndef R__WIN32
   nativex = "x11";
   name    = "X11";
   title   = title1 + "X11";
#else
#ifndef GDK_WIN32
   nativex = "win32";
   name    = "Win32";
   title   = title1 + "Win32";
#else
   nativex = "win32gdk";
   name    = "Win32gdk";
   title   = title1 + "Win32gdk";
#endif
#endif

   TString guiBackend(gEnv->GetValue("Gui.Backend", "native"));
   guiBackend.ToLower();
   if (guiBackend == "native") {
      guiBackend = nativex;
   } else {
      name   = guiBackend;
      title  = title1 + guiBackend;
   }

   TPluginHandler *h;
   if ((h = gROOT->GetPluginManager()->FindHandler("TVirtualX", guiBackend))) {
      if (h->LoadPlugin() == -1)
         return;
      gVirtualX = (TVirtualX *) h->ExecPlugin(2, name.Data(), title.Data());
   }
}

//______________________________________________________________________________
void TGApplication::GetOptions(Int_t *argc, char **argv)
{
   // Handle command line arguments. Arguments handled are removed from the
   // argument array. Currently only option "-display xserver" is considered.

   if (!argc) return;

   int i, j;
   for (i = 0; i < *argc; i++) {
      if (!strcmp(argv[i], "-display")) {
         if (argv[i+1] && strlen(argv[i+1]) && argv[i+1][0] != '-') {
            fDisplay = StrDup(argv[i+1]);
            argv[i]   = 0;
            argv[i+1] = 0;
            i++;
         }
      }
   }

   j = 0;
   for (i = 0; i < *argc; i++) {
      if (argv[i]) {
         argv[j] = argv[i];
         j++;
      }
   }

   *argc = j;
}

<|endoftext|>