<commit_before>//===--- swift_indent_main.cpp - Swift code formatting tool ---------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  Extracts a Symbol Graph from a .swiftmodule file.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Basic/Version.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/SymbolGraphGen/SymbolGraphGen.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/CommandLine.h"

using namespace swift;
using namespace llvm::opt;

namespace options {
static llvm::cl::OptionCategory Category("swift-symbolgraph-extract Options");

static llvm::cl::opt<std::string>
ModuleName("module-name", llvm::cl::desc("Name of the module to extract"), llvm::cl::cat(Category));

static llvm::cl::list<std::string>
FrameworkSearchPaths("F", llvm::cl::desc("add a directory to the framework search paths"), llvm::cl::ZeroOrMore,
                     llvm::cl::cat(Category));

static llvm::cl::list<std::string>
LibrarySearchPaths("L", llvm::cl::desc("Add a directory to the library search paths"), llvm::cl::ZeroOrMore,
                   llvm::cl::cat(Category));

static llvm::cl::list<std::string>
ImportSearchPaths("I", llvm::cl::desc("Add directory to the import search paths"), llvm::cl::ZeroOrMore,
                  llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
ModuleCachePath("module-cache-path", llvm::cl::desc("Specifies a path to cache modules"), llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
SDK("sdk", llvm::cl::desc("Path to the SDK"),
    llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
Target("target", llvm::cl::desc("Target triple"),
       llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
SwiftVersion("swift-version", llvm::cl::desc("Interpret input according to a specific Swift language version number"), llvm::cl::cat(Category));

static llvm::cl::opt<bool>
PrettyPrint("pretty-print", llvm::cl::desc("Pretty-print the resulting Symbol Graph JSON"), llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
MinimumAccessLevel("minimum-access-level", llvm::cl::desc("Include symbols with this access level or more"), llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
OutputPath("o", llvm::cl::desc("Symbol Graph JSON Output Path"), llvm::cl::cat(Category));
} // end namespace options

int swift_symbolgraph_extract_main(ArrayRef<const char *> Args, const char *Argv0, void *MainAddr) {
  INITIALIZE_LLVM();

  llvm::cl::HideUnrelatedOptions(options::Category);

  // LLVM Command Line expects to trim off argv[0].
  SmallVector<const char *, 8> ArgsWithArgv0 { Argv0 };
  ArgsWithArgv0.append(Args.begin(), Args.end());

  llvm::cl::ParseCommandLineOptions(ArgsWithArgv0.size(),
      llvm::makeArrayRef(ArgsWithArgv0).data(), "Swift Symbol Graph Extractor\n");

  CompilerInvocation Invocation;

  Invocation.setMainExecutablePath(
      llvm::sys::fs::getMainExecutable(Argv0, MainAddr));
  Invocation.setModuleName("swift_symbolgraph_extract");
  Invocation.setSDKPath(options::SDK);
  Invocation.setTargetTriple(options::Target);

  std::vector<SearchPathOptions::FrameworkSearchPath> FrameworkSearchPaths;
  for (const auto &Path : options::FrameworkSearchPaths) {
    FrameworkSearchPaths.push_back({ Path, /*isSystem*/ false});
  }
  Invocation.setFrameworkSearchPaths(FrameworkSearchPaths);
  Invocation.getSearchPathOptions().LibrarySearchPaths = options::LibrarySearchPaths;
  Invocation.setImportSearchPaths(options::ImportSearchPaths);

  Invocation.getLangOptions().EnableObjCInterop = llvm::Triple(options::Target).isOSDarwin();
  Invocation.getLangOptions().DebuggerSupport = true;

  Invocation.getFrontendOptions().EnableLibraryEvolution = true;

  Invocation.setClangModuleCachePath(options::ModuleCachePath);
  Invocation.getClangImporterOptions().ModuleCachePath = options::ModuleCachePath;

  if (!options::SwiftVersion.empty()) {
    using version::Version;
    bool isValid = false;
    if (auto Version = Version::parseVersionString(options::SwiftVersion,
                                                   SourceLoc(), nullptr)) {
      if (auto Effective = Version.getValue().getEffectiveLanguageVersion()) {
        Invocation.getLangOptions().EffectiveLanguageVersion = *Effective;
        isValid = true;
      }
    }
    if (!isValid) {
      llvm::errs() << "Unsupported Swift Version.\n";
      return EXIT_FAILURE;
    }
  }

  symbolgraphgen::SymbolGraphOptions Options {
    options::OutputPath,
    llvm::Triple(options::Target),
    options::PrettyPrint,
    AccessLevel::Public,
  };

  if (!options::MinimumAccessLevel.empty()) {
    Options.MinimumAccessLevel =
        llvm::StringSwitch<AccessLevel>(options::MinimumAccessLevel)
      .Case("open", AccessLevel::Open)
      .Case("public", AccessLevel::Public)
      .Case("internal", AccessLevel::Internal)
      .Case("fileprivate", AccessLevel::FilePrivate)
      .Case("private", AccessLevel::Private)
      .Default(AccessLevel::Public);
  }

  PrintingDiagnosticConsumer DiagPrinter;

  CompilerInstance CI;
  CI.getDiags().addConsumer(DiagPrinter);

  if (CI.setup(Invocation)) {
    llvm::outs() << "Failed to setup compiler instance\n";
    return EXIT_FAILURE;
  }

  auto M = CI.getASTContext().getModuleByName(options::ModuleName);
  if (!M) {
    llvm::errs()
      << "Couldn't load module '" << options::ModuleName << '\''
      << " in the current SDK and search paths.\n";
    SmallVector<Identifier, 32> VisibleModuleNames;
    CI.getASTContext().getVisibleTopLevelModuleNames(VisibleModuleNames);

    if (VisibleModuleNames.empty()) {
      llvm::errs() << "Could not find any modules.\n";
    } else {
      std::sort(VisibleModuleNames.begin(), VisibleModuleNames.end(),
                [](const Identifier &A, const Identifier &B) -> bool {
        return A.str() < B.str();
      });
      llvm::errs() << "Current visible modules:\n";
      for (const auto &ModuleName : VisibleModuleNames) {
        llvm::errs() << ModuleName.str() << "\n";
      }
    }
    return EXIT_FAILURE;
  }

  return symbolgraphgen::emitSymbolGraphForModule(M,
    Options);
}
<commit_msg>swift-symbolgraph-extract: Mark required args<commit_after>//===--- swift_indent_main.cpp - Swift code formatting tool ---------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
//
//  Extracts a Symbol Graph from a .swiftmodule file.
//
//===----------------------------------------------------------------------===//

#include "swift/AST/DiagnosticsFrontend.h"
#include "swift/Basic/LLVM.h"
#include "swift/Basic/LLVMInitialize.h"
#include "swift/Basic/Version.h"
#include "swift/Frontend/Frontend.h"
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
#include "swift/SymbolGraphGen/SymbolGraphGen.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/CommandLine.h"

using namespace swift;
using namespace llvm::opt;

namespace options {
static llvm::cl::OptionCategory Category("swift-symbolgraph-extract Options");

static llvm::cl::opt<std::string>
ModuleName("module-name", llvm::cl::desc("Name of the module to extract (Required)"), llvm::cl::cat(Category));

static llvm::cl::list<std::string>
FrameworkSearchPaths("F", llvm::cl::desc("Add a directory to the framework search paths"), llvm::cl::ZeroOrMore,
                     llvm::cl::cat(Category));

static llvm::cl::list<std::string>
LibrarySearchPaths("L", llvm::cl::desc("Add a directory to the library search paths"), llvm::cl::ZeroOrMore,
                   llvm::cl::cat(Category));

static llvm::cl::list<std::string>
ImportSearchPaths("I", llvm::cl::desc("Add directory to the import search paths"), llvm::cl::ZeroOrMore,
                  llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
ModuleCachePath("module-cache-path", llvm::cl::desc("Specifies a path to cache modules"), llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
SDK("sdk", llvm::cl::desc("Path to the SDK"),
    llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
Target("target", llvm::cl::desc("Target triple (Required)"),
       llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
SwiftVersion("swift-version", llvm::cl::desc("Interpret input according to a specific Swift language version number"), llvm::cl::cat(Category));

static llvm::cl::opt<bool>
PrettyPrint("pretty-print", llvm::cl::desc("Pretty-print the resulting Symbol Graph JSON"), llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
MinimumAccessLevel("minimum-access-level", llvm::cl::desc("Include symbols with this access level or more"), llvm::cl::cat(Category));

static llvm::cl::opt<std::string>
OutputPath("o", llvm::cl::desc("Symbol Graph JSON Output Path (Required)"), llvm::cl::cat(Category));
} // end namespace options

static bool argumentsAreValid() {
  bool Valid = true;
  if (options::Target.empty()) {
    llvm::errs() << "Required -target option is missing\n";
    Valid = false;
  }

  if (options::ModuleName.empty()) {
    llvm::errs() << "Required -module-name argument is missing\n";
    Valid = false;
  }

  if (options::OutputPath.empty()) {
    llvm::errs() << "Required -o argument is missing\n";
    Valid = false;
  }

  return Valid;
}

int swift_symbolgraph_extract_main(ArrayRef<const char *> Args, const char *Argv0, void *MainAddr) {
  INITIALIZE_LLVM();

  llvm::cl::HideUnrelatedOptions(options::Category);

  // LLVM Command Line expects to trim off argv[0].
  SmallVector<const char *, 8> ArgsWithArgv0 { Argv0 };
  ArgsWithArgv0.append(Args.begin(), Args.end());

  if (Args.empty()) {
    ArgsWithArgv0.push_back("-help");
  }

  llvm::cl::ParseCommandLineOptions(ArgsWithArgv0.size(),
      llvm::makeArrayRef(ArgsWithArgv0).data(),
      "Swift Symbol Graph Extractor\n");

  if (!argumentsAreValid()) {
    llvm::cl::PrintHelpMessage();
    return EXIT_FAILURE;
  }

  CompilerInvocation Invocation;

  Invocation.setMainExecutablePath(
      llvm::sys::fs::getMainExecutable(Argv0, MainAddr));
  Invocation.setModuleName("swift_symbolgraph_extract");
  Invocation.setSDKPath(options::SDK);
  Invocation.setTargetTriple(options::Target);

  std::vector<SearchPathOptions::FrameworkSearchPath> FrameworkSearchPaths;
  for (const auto &Path : options::FrameworkSearchPaths) {
    FrameworkSearchPaths.push_back({ Path, /*isSystem*/ false});
  }
  Invocation.setFrameworkSearchPaths(FrameworkSearchPaths);
  Invocation.getSearchPathOptions().LibrarySearchPaths = options::LibrarySearchPaths;
  Invocation.setImportSearchPaths(options::ImportSearchPaths);

  Invocation.getLangOptions().EnableObjCInterop = llvm::Triple(options::Target).isOSDarwin();
  Invocation.getLangOptions().DebuggerSupport = true;

  Invocation.getFrontendOptions().EnableLibraryEvolution = true;

  Invocation.setClangModuleCachePath(options::ModuleCachePath);
  Invocation.getClangImporterOptions().ModuleCachePath = options::ModuleCachePath;

  if (!options::SwiftVersion.empty()) {
    using version::Version;
    bool isValid = false;
    if (auto Version = Version::parseVersionString(options::SwiftVersion,
                                                   SourceLoc(), nullptr)) {
      if (auto Effective = Version.getValue().getEffectiveLanguageVersion()) {
        Invocation.getLangOptions().EffectiveLanguageVersion = *Effective;
        isValid = true;
      }
    }
    if (!isValid) {
      llvm::errs() << "Unsupported Swift Version.\n";
      return EXIT_FAILURE;
    }
  }

  symbolgraphgen::SymbolGraphOptions Options {
    options::OutputPath,
    llvm::Triple(options::Target),
    options::PrettyPrint,
    AccessLevel::Public,
  };

  if (!options::MinimumAccessLevel.empty()) {
    Options.MinimumAccessLevel =
        llvm::StringSwitch<AccessLevel>(options::MinimumAccessLevel)
      .Case("open", AccessLevel::Open)
      .Case("public", AccessLevel::Public)
      .Case("internal", AccessLevel::Internal)
      .Case("fileprivate", AccessLevel::FilePrivate)
      .Case("private", AccessLevel::Private)
      .Default(AccessLevel::Public);
  }

  PrintingDiagnosticConsumer DiagPrinter;

  CompilerInstance CI;
  CI.getDiags().addConsumer(DiagPrinter);

  if (CI.setup(Invocation)) {
    llvm::outs() << "Failed to setup compiler instance\n";
    return EXIT_FAILURE;
  }

  auto M = CI.getASTContext().getModuleByName(options::ModuleName);
  if (!M) {
    llvm::errs()
      << "Couldn't load module '" << options::ModuleName << '\''
      << " in the current SDK and search paths.\n";
    SmallVector<Identifier, 32> VisibleModuleNames;
    CI.getASTContext().getVisibleTopLevelModuleNames(VisibleModuleNames);

    if (VisibleModuleNames.empty()) {
      llvm::errs() << "Could not find any modules.\n";
    } else {
      std::sort(VisibleModuleNames.begin(), VisibleModuleNames.end(),
                [](const Identifier &A, const Identifier &B) -> bool {
        return A.str() < B.str();
      });
      llvm::errs() << "Current visible modules:\n";
      for (const auto &ModuleName : VisibleModuleNames) {
        llvm::errs() << ModuleName.str() << "\n";
      }
    }
    return EXIT_FAILURE;
  }

  return symbolgraphgen::emitSymbolGraphForModule(M,
    Options);
}
<|endoftext|>


<commit_before>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreStableHeaders.h"

#include "OgreETCCodec.h"
#include "OgreImage.h"

#define FOURCC(c0, c1, c2, c3) (c0 | (c1 << 8) | (c2 << 16) | (c3 << 24))
#define KTX_ENDIAN_REF      (0x04030201)
#define KTX_ENDIAN_REF_REV  (0x01020304)

// In a PKM-file, the codecs are stored using the following identifiers
//
// identifier                         value               codec
// --------------------------------------------------------------------
// ETC1_RGB_NO_MIPMAPS                  0                 GL_ETC1_RGB8_OES
// ETC2PACKAGE_RGB_NO_MIPMAPS           1                 GL_COMPRESSED_RGB8_ETC2
// ETC2PACKAGE_RGBA_NO_MIPMAPS_OLD      2, not used       -
// ETC2PACKAGE_RGBA_NO_MIPMAPS          3                 GL_COMPRESSED_RGBA8_ETC2_EAC
// ETC2PACKAGE_RGBA1_NO_MIPMAPS         4                 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
// ETC2PACKAGE_R_NO_MIPMAPS             5                 GL_COMPRESSED_R11_EAC
// ETC2PACKAGE_RG_NO_MIPMAPS            6                 GL_COMPRESSED_RG11_EAC
// ETC2PACKAGE_R_SIGNED_NO_MIPMAPS      7                 GL_COMPRESSED_SIGNED_R11_EAC
// ETC2PACKAGE_RG_SIGNED_NO_MIPMAPS     8                 GL_COMPRESSED_SIGNED_RG11_EAC

namespace Ogre {

    const uint32 PKM_MAGIC = FOURCC('P', 'K', 'M', ' ');
    const uint32 KTX_MAGIC = FOURCC(0xAB, 0x4B, 0x54, 0x58);

    typedef struct {
        uint8  name[4];
        uint8  version[2];
        uint8  iTextureTypeMSB;
        uint8  iTextureTypeLSB;
        uint8  iPaddedWidthMSB;
        uint8  iPaddedWidthLSB;
        uint8  iPaddedHeightMSB;
        uint8  iPaddedHeightLSB;
        uint8  iWidthMSB;
        uint8  iWidthLSB;
        uint8  iHeightMSB;
        uint8  iHeightLSB;
    } PKMHeader;

    typedef struct {
        uint8     identifier[12];
        uint32    endianness;
        uint32    glType;
        uint32    glTypeSize;
        uint32    glFormat;
        uint32    glInternalFormat;
        uint32    glBaseInternalFormat;
        uint32    pixelWidth;
        uint32    pixelHeight;
        uint32    pixelDepth;
        uint32    numberOfArrayElements;
        uint32    numberOfFaces;
        uint32    numberOfMipmapLevels;
        uint32    bytesOfKeyValueData;
    } KTXHeader;

    //---------------------------------------------------------------------
    ETCCodec* ETCCodec::msPKMInstance = 0;
    ETCCodec* ETCCodec::msKTXInstance = 0;
    //---------------------------------------------------------------------
    void ETCCodec::startup(void)
    {
        if (!msPKMInstance)
        {
            msPKMInstance = OGRE_NEW ETCCodec("pkm");
            Codec::registerCodec(msPKMInstance);
        }

        if (!msKTXInstance)
        {
            msKTXInstance = OGRE_NEW ETCCodec("ktx");
            Codec::registerCodec(msKTXInstance);
        }

        LogManager::getSingleton().logMessage(LML_NORMAL,
                                              "ETC codec registering");
    }
    //---------------------------------------------------------------------
    void ETCCodec::shutdown(void)
    {
        if(msPKMInstance)
        {
            Codec::unregisterCodec(msPKMInstance);
            OGRE_DELETE msPKMInstance;
            msPKMInstance = 0;
        }

        if(msKTXInstance)
        {
            Codec::unregisterCodec(msKTXInstance);
            OGRE_DELETE msKTXInstance;
            msKTXInstance = 0;
        }
    }
    //---------------------------------------------------------------------
    ETCCodec::ETCCodec(const String &type):
        mType(type)
    {
    }
    //---------------------------------------------------------------------
    DataStreamPtr ETCCodec::encode(const MemoryDataStreamPtr& input,
                                   const Codec::CodecDataPtr& pData) const
    {
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "ETC encoding not supported",
                    "ETCCodec::encode" ) ;
    }
    //---------------------------------------------------------------------
    void ETCCodec::encodeToFile(const MemoryDataStreamPtr& input, const String& outFileName,
                                const Codec::CodecDataPtr& pData) const
    {
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "ETC encoding not supported",
                    "ETCCodec::encodeToFile" ) ;
    }
    //---------------------------------------------------------------------
    Codec::DecodeResult ETCCodec::decode(const DataStreamPtr& stream) const
    {
        DecodeResult ret;
        if (decodeKTX(stream, ret))
            return ret;

        stream->seek(0);
        if (decodePKM(stream, ret))
            return ret;

        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                    "This is not a valid ETC file!", "ETCCodec::decode");
    }
    //---------------------------------------------------------------------
    String ETCCodec::getType() const
    {
        return mType;
    }
    //---------------------------------------------------------------------
    void ETCCodec::flipEndian(void * pData, size_t size, size_t count)
    {
#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
		Bitwise::bswapChunks(pData, size, count);
#endif
    }
    //---------------------------------------------------------------------
    void ETCCodec::flipEndian(void * pData, size_t size)
    {
#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
        Bitwise::bswapBuffer(pData, size);
#endif
    }
    //---------------------------------------------------------------------
    String ETCCodec::magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const
    {
        if (maxbytes >= sizeof(uint32))
        {
            uint32 fileType;
            memcpy(&fileType, magicNumberPtr, sizeof(uint32));
			flipEndian(&fileType, sizeof(uint32));

            if (PKM_MAGIC == fileType)
                return String("pkm");

            if (KTX_MAGIC == fileType)
                return String("ktx");
        }

        return BLANKSTRING;
    }
    //---------------------------------------------------------------------
    bool ETCCodec::decodePKM(const DataStreamPtr& stream, DecodeResult& result) const
    {
        PKMHeader header;

        // Read the ETC header
        stream->read(&header, sizeof(PKMHeader));

        if (PKM_MAGIC != FOURCC(header.name[0], header.name[1], header.name[2], header.name[3]) ) // "PKM 10"
            return false;

        uint16 width = (header.iWidthMSB << 8) | header.iWidthLSB;
        uint16 height = (header.iHeightMSB << 8) | header.iHeightLSB;
        uint16 paddedWidth = (header.iPaddedWidthMSB << 8) | header.iPaddedWidthLSB;
        uint16 paddedHeight = (header.iPaddedHeightMSB << 8) | header.iPaddedHeightLSB;
        uint16 type = (header.iTextureTypeMSB << 8) | header.iTextureTypeLSB;

        ImageData *imgData = OGRE_NEW ImageData();
        imgData->depth = 1;
        imgData->width = width;
        imgData->height = height;

        // File version 2.0 supports ETC2 in addition to ETC1
        if(header.version[0] == '2' && header.version[1] == '0')
        {
            switch (type) {
                case 0:
                    imgData->format = PF_ETC1_RGB8;
                    break;

                    // GL_COMPRESSED_RGB8_ETC2
                case 1:
                    imgData->format = PF_ETC2_RGB8;
                    break;

                    // GL_COMPRESSED_RGBA8_ETC2_EAC
                case 3:
                    imgData->format = PF_ETC2_RGBA8;
                    break;

                    // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
                case 4:
                    imgData->format = PF_ETC2_RGB8A1;
                    break;

                    // Default case is ETC1
                default:
                    imgData->format = PF_ETC1_RGB8;
                    break;
            }
        }
        else
            imgData->format = PF_ETC1_RGB8;

        // ETC has no support for mipmaps - malideveloper.com has a example
        // where the load mipmap levels from different external files
        imgData->num_mipmaps = 0;

        // ETC is a compressed format
        imgData->flags |= IF_COMPRESSED;

        // Calculate total size from number of mipmaps, faces and size
        imgData->size = (paddedWidth * paddedHeight) >> 1;

        // Bind output buffer
        MemoryDataStreamPtr output(OGRE_NEW MemoryDataStream(imgData->size));

        // Now deal with the data
        void *destPtr = output->getPtr();
        stream->read(destPtr, imgData->size);
        destPtr = static_cast<void*>(static_cast<uchar*>(destPtr));

        DecodeResult ret;
        ret.first = output;
        ret.second = CodecDataPtr(imgData);

        return true;
    }
    //---------------------------------------------------------------------
    bool ETCCodec::decodeKTX(const DataStreamPtr& stream, DecodeResult& result) const
    {
        KTXHeader header;
        // Read the ETC1 header
        stream->read(&header, sizeof(KTXHeader));

        const uint8 KTXFileIdentifier[12] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
        if (memcmp(KTXFileIdentifier, &header.identifier, sizeof(KTXFileIdentifier)) != 0 )
            return false;

        if (header.endianness == KTX_ENDIAN_REF_REV)
			flipEndian(&header.glType, sizeof(uint32));

        ImageData *imgData = OGRE_NEW ImageData();
        imgData->depth = 1;
        imgData->width = header.pixelWidth;
        imgData->height = header.pixelHeight;
        imgData->num_mipmaps = static_cast<uint8>(header.numberOfMipmapLevels - 1);

        switch(header.glInternalFormat)
        {
        case 37492: // GL_COMPRESSED_RGB8_ETC2
            imgData->format = PF_ETC2_RGB8;
            break;
        case 37496:// GL_COMPRESSED_RGBA8_ETC2_EAC
            imgData->format = PF_ETC2_RGBA8;
            break;
        case 37494: // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
            imgData->format = PF_ETC2_RGB8A1;
            break;
        case 35986: // ATC_RGB
            imgData->format = PF_ATC_RGB;
            break;
        case 35987: // ATC_RGB_Explicit
            imgData->format = PF_ATC_RGBA_EXPLICIT_ALPHA;
            break;
        case 34798: // ATC_RGB_Interpolated
            imgData->format = PF_ATC_RGBA_INTERPOLATED_ALPHA;
            break;
        case 33777: // DXT 1
            imgData->format = PF_DXT1;
            break;
        case 33778: // DXT 3
            imgData->format = PF_DXT3;
            break;
        case 33779: // DXT 5
            imgData->format = PF_DXT5;
            break;
         case 0x8c00: // COMPRESSED_RGB_PVRTC_4BPPV1_IMG
            imgData->format = PF_PVRTC_RGB4;
            break;
        case 0x8c01: // COMPRESSED_RGB_PVRTC_2BPPV1_IMG
            imgData->format = PF_PVRTC_RGB2;
            break;
        case 0x8c02: // COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
            imgData->format = PF_PVRTC_RGBA4;
            break;
        case 0x8c03: // COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
            imgData->format = PF_PVRTC_RGBA2;
            break;
        default:
            imgData->format = PF_ETC1_RGB8;
            break;
        }

        imgData->flags = 0;
        if (header.glType == 0 || header.glFormat == 0)
            imgData->flags |= IF_COMPRESSED;

		size_t numFaces = header.numberOfFaces;
		if (numFaces > 1)
			imgData->flags |= IF_CUBEMAP;
        // Calculate total size from number of mipmaps, faces and size
        imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces,
                                             imgData->width, imgData->height, imgData->depth, imgData->format);

        stream->skip(header.bytesOfKeyValueData);

        // Bind output buffer
        MemoryDataStreamPtr output(OGRE_NEW MemoryDataStream(imgData->size));

        // Now deal with the data
        uchar* destPtr = output->getPtr();
        uint32 mipOffset = 0;
        for (uint32 level = 0; level < header.numberOfMipmapLevels; ++level)
        {
            uint32 imageSize = 0;
            stream->read(&imageSize, sizeof(uint32));

            for(uint32 face = 0; face < numFaces; ++face)
            {
                uchar* placePtr = destPtr + ((imgData->size)/numFaces)*face + mipOffset; // shuffle mip and face
                stream->read(placePtr, imageSize);
            }
            mipOffset += imageSize;
        }

        result.first = output;
        result.second = CodecDataPtr(imgData);

        return true;
    }
}
<commit_msg>OgreETCCodec: convert tabs to spaces<commit_after>/*
-----------------------------------------------------------------------------
This source file is part of OGRE
(Object-oriented Graphics Rendering Engine)
For the latest info, see http://www.ogre3d.org/

Copyright (c) 2000-2014 Torus Knot Software Ltd

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-----------------------------------------------------------------------------
*/

#include "OgreStableHeaders.h"

#include "OgreETCCodec.h"
#include "OgreImage.h"

#define FOURCC(c0, c1, c2, c3) (c0 | (c1 << 8) | (c2 << 16) | (c3 << 24))
#define KTX_ENDIAN_REF      (0x04030201)
#define KTX_ENDIAN_REF_REV  (0x01020304)

// In a PKM-file, the codecs are stored using the following identifiers
//
// identifier                         value               codec
// --------------------------------------------------------------------
// ETC1_RGB_NO_MIPMAPS                  0                 GL_ETC1_RGB8_OES
// ETC2PACKAGE_RGB_NO_MIPMAPS           1                 GL_COMPRESSED_RGB8_ETC2
// ETC2PACKAGE_RGBA_NO_MIPMAPS_OLD      2, not used       -
// ETC2PACKAGE_RGBA_NO_MIPMAPS          3                 GL_COMPRESSED_RGBA8_ETC2_EAC
// ETC2PACKAGE_RGBA1_NO_MIPMAPS         4                 GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
// ETC2PACKAGE_R_NO_MIPMAPS             5                 GL_COMPRESSED_R11_EAC
// ETC2PACKAGE_RG_NO_MIPMAPS            6                 GL_COMPRESSED_RG11_EAC
// ETC2PACKAGE_R_SIGNED_NO_MIPMAPS      7                 GL_COMPRESSED_SIGNED_R11_EAC
// ETC2PACKAGE_RG_SIGNED_NO_MIPMAPS     8                 GL_COMPRESSED_SIGNED_RG11_EAC

namespace Ogre {

    const uint32 PKM_MAGIC = FOURCC('P', 'K', 'M', ' ');
    const uint32 KTX_MAGIC = FOURCC(0xAB, 0x4B, 0x54, 0x58);

    typedef struct {
        uint8  name[4];
        uint8  version[2];
        uint8  iTextureTypeMSB;
        uint8  iTextureTypeLSB;
        uint8  iPaddedWidthMSB;
        uint8  iPaddedWidthLSB;
        uint8  iPaddedHeightMSB;
        uint8  iPaddedHeightLSB;
        uint8  iWidthMSB;
        uint8  iWidthLSB;
        uint8  iHeightMSB;
        uint8  iHeightLSB;
    } PKMHeader;

    typedef struct {
        uint8     identifier[12];
        uint32    endianness;
        uint32    glType;
        uint32    glTypeSize;
        uint32    glFormat;
        uint32    glInternalFormat;
        uint32    glBaseInternalFormat;
        uint32    pixelWidth;
        uint32    pixelHeight;
        uint32    pixelDepth;
        uint32    numberOfArrayElements;
        uint32    numberOfFaces;
        uint32    numberOfMipmapLevels;
        uint32    bytesOfKeyValueData;
    } KTXHeader;

    //---------------------------------------------------------------------
    ETCCodec* ETCCodec::msPKMInstance = 0;
    ETCCodec* ETCCodec::msKTXInstance = 0;
    //---------------------------------------------------------------------
    void ETCCodec::startup(void)
    {
        if (!msPKMInstance)
        {
            msPKMInstance = OGRE_NEW ETCCodec("pkm");
            Codec::registerCodec(msPKMInstance);
        }

        if (!msKTXInstance)
        {
            msKTXInstance = OGRE_NEW ETCCodec("ktx");
            Codec::registerCodec(msKTXInstance);
        }

        LogManager::getSingleton().logMessage(LML_NORMAL,
                                              "ETC codec registering");
    }
    //---------------------------------------------------------------------
    void ETCCodec::shutdown(void)
    {
        if(msPKMInstance)
        {
            Codec::unregisterCodec(msPKMInstance);
            OGRE_DELETE msPKMInstance;
            msPKMInstance = 0;
        }

        if(msKTXInstance)
        {
            Codec::unregisterCodec(msKTXInstance);
            OGRE_DELETE msKTXInstance;
            msKTXInstance = 0;
        }
    }
    //---------------------------------------------------------------------
    ETCCodec::ETCCodec(const String &type):
        mType(type)
    {
    }
    //---------------------------------------------------------------------
    DataStreamPtr ETCCodec::encode(const MemoryDataStreamPtr& input,
                                   const Codec::CodecDataPtr& pData) const
    {
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "ETC encoding not supported",
                    "ETCCodec::encode" ) ;
    }
    //---------------------------------------------------------------------
    void ETCCodec::encodeToFile(const MemoryDataStreamPtr& input, const String& outFileName,
                                const Codec::CodecDataPtr& pData) const
    {
        OGRE_EXCEPT(Exception::ERR_NOT_IMPLEMENTED,
                    "ETC encoding not supported",
                    "ETCCodec::encodeToFile" ) ;
    }
    //---------------------------------------------------------------------
    Codec::DecodeResult ETCCodec::decode(const DataStreamPtr& stream) const
    {
        DecodeResult ret;
        if (decodeKTX(stream, ret))
            return ret;

        stream->seek(0);
        if (decodePKM(stream, ret))
            return ret;

        OGRE_EXCEPT(Exception::ERR_INVALIDPARAMS,
                    "This is not a valid ETC file!", "ETCCodec::decode");
    }
    //---------------------------------------------------------------------
    String ETCCodec::getType() const
    {
        return mType;
    }
    //---------------------------------------------------------------------
    void ETCCodec::flipEndian(void * pData, size_t size, size_t count)
    {
#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
        Bitwise::bswapChunks(pData, size, count);
#endif
    }
    //---------------------------------------------------------------------
    void ETCCodec::flipEndian(void * pData, size_t size)
    {
#if OGRE_ENDIAN == OGRE_ENDIAN_BIG
        Bitwise::bswapBuffer(pData, size);
#endif
    }
    //---------------------------------------------------------------------
    String ETCCodec::magicNumberToFileExt(const char *magicNumberPtr, size_t maxbytes) const
    {
        if (maxbytes >= sizeof(uint32))
        {
            uint32 fileType;
            memcpy(&fileType, magicNumberPtr, sizeof(uint32));
            flipEndian(&fileType, sizeof(uint32));

            if (PKM_MAGIC == fileType)
                return String("pkm");

            if (KTX_MAGIC == fileType)
                return String("ktx");
        }

        return BLANKSTRING;
    }
    //---------------------------------------------------------------------
    bool ETCCodec::decodePKM(const DataStreamPtr& stream, DecodeResult& result) const
    {
        PKMHeader header;

        // Read the ETC header
        stream->read(&header, sizeof(PKMHeader));

        if (PKM_MAGIC != FOURCC(header.name[0], header.name[1], header.name[2], header.name[3]) ) // "PKM 10"
            return false;

        uint16 width = (header.iWidthMSB << 8) | header.iWidthLSB;
        uint16 height = (header.iHeightMSB << 8) | header.iHeightLSB;
        uint16 paddedWidth = (header.iPaddedWidthMSB << 8) | header.iPaddedWidthLSB;
        uint16 paddedHeight = (header.iPaddedHeightMSB << 8) | header.iPaddedHeightLSB;
        uint16 type = (header.iTextureTypeMSB << 8) | header.iTextureTypeLSB;

        ImageData *imgData = OGRE_NEW ImageData();
        imgData->depth = 1;
        imgData->width = width;
        imgData->height = height;

        // File version 2.0 supports ETC2 in addition to ETC1
        if(header.version[0] == '2' && header.version[1] == '0')
        {
            switch (type) {
                case 0:
                    imgData->format = PF_ETC1_RGB8;
                    break;

                    // GL_COMPRESSED_RGB8_ETC2
                case 1:
                    imgData->format = PF_ETC2_RGB8;
                    break;

                    // GL_COMPRESSED_RGBA8_ETC2_EAC
                case 3:
                    imgData->format = PF_ETC2_RGBA8;
                    break;

                    // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
                case 4:
                    imgData->format = PF_ETC2_RGB8A1;
                    break;

                    // Default case is ETC1
                default:
                    imgData->format = PF_ETC1_RGB8;
                    break;
            }
        }
        else
            imgData->format = PF_ETC1_RGB8;

        // ETC has no support for mipmaps - malideveloper.com has a example
        // where the load mipmap levels from different external files
        imgData->num_mipmaps = 0;

        // ETC is a compressed format
        imgData->flags |= IF_COMPRESSED;

        // Calculate total size from number of mipmaps, faces and size
        imgData->size = (paddedWidth * paddedHeight) >> 1;

        // Bind output buffer
        MemoryDataStreamPtr output(OGRE_NEW MemoryDataStream(imgData->size));

        // Now deal with the data
        void *destPtr = output->getPtr();
        stream->read(destPtr, imgData->size);
        destPtr = static_cast<void*>(static_cast<uchar*>(destPtr));

        DecodeResult ret;
        ret.first = output;
        ret.second = CodecDataPtr(imgData);

        return true;
    }
    //---------------------------------------------------------------------
    bool ETCCodec::decodeKTX(const DataStreamPtr& stream, DecodeResult& result) const
    {
        KTXHeader header;
        // Read the ETC1 header
        stream->read(&header, sizeof(KTXHeader));

        const uint8 KTXFileIdentifier[12] = { 0xAB, 0x4B, 0x54, 0x58, 0x20, 0x31, 0x31, 0xBB, 0x0D, 0x0A, 0x1A, 0x0A };
        if (memcmp(KTXFileIdentifier, &header.identifier, sizeof(KTXFileIdentifier)) != 0 )
            return false;

        if (header.endianness == KTX_ENDIAN_REF_REV)
            flipEndian(&header.glType, sizeof(uint32));

        ImageData *imgData = OGRE_NEW ImageData();
        imgData->depth = 1;
        imgData->width = header.pixelWidth;
        imgData->height = header.pixelHeight;
        imgData->num_mipmaps = static_cast<uint8>(header.numberOfMipmapLevels - 1);

        switch(header.glInternalFormat)
        {
        case 37492: // GL_COMPRESSED_RGB8_ETC2
            imgData->format = PF_ETC2_RGB8;
            break;
        case 37496:// GL_COMPRESSED_RGBA8_ETC2_EAC
            imgData->format = PF_ETC2_RGBA8;
            break;
        case 37494: // GL_COMPRESSED_RGB8_PUNCHTHROUGH_ALPHA1_ETC2
            imgData->format = PF_ETC2_RGB8A1;
            break;
        case 35986: // ATC_RGB
            imgData->format = PF_ATC_RGB;
            break;
        case 35987: // ATC_RGB_Explicit
            imgData->format = PF_ATC_RGBA_EXPLICIT_ALPHA;
            break;
        case 34798: // ATC_RGB_Interpolated
            imgData->format = PF_ATC_RGBA_INTERPOLATED_ALPHA;
            break;
        case 33777: // DXT 1
            imgData->format = PF_DXT1;
            break;
        case 33778: // DXT 3
            imgData->format = PF_DXT3;
            break;
        case 33779: // DXT 5
            imgData->format = PF_DXT5;
            break;
         case 0x8c00: // COMPRESSED_RGB_PVRTC_4BPPV1_IMG
            imgData->format = PF_PVRTC_RGB4;
            break;
        case 0x8c01: // COMPRESSED_RGB_PVRTC_2BPPV1_IMG
            imgData->format = PF_PVRTC_RGB2;
            break;
        case 0x8c02: // COMPRESSED_RGBA_PVRTC_4BPPV1_IMG
            imgData->format = PF_PVRTC_RGBA4;
            break;
        case 0x8c03: // COMPRESSED_RGBA_PVRTC_2BPPV1_IMG
            imgData->format = PF_PVRTC_RGBA2;
            break;
        default:
            imgData->format = PF_ETC1_RGB8;
            break;
        }

        imgData->flags = 0;
        if (header.glType == 0 || header.glFormat == 0)
            imgData->flags |= IF_COMPRESSED;

        size_t numFaces = header.numberOfFaces;
        if (numFaces > 1)
            imgData->flags |= IF_CUBEMAP;
        // Calculate total size from number of mipmaps, faces and size
        imgData->size = Image::calculateSize(imgData->num_mipmaps, numFaces,
                                             imgData->width, imgData->height, imgData->depth, imgData->format);

        stream->skip(header.bytesOfKeyValueData);

        // Bind output buffer
        MemoryDataStreamPtr output(OGRE_NEW MemoryDataStream(imgData->size));

        // Now deal with the data
        uchar* destPtr = output->getPtr();
        uint32 mipOffset = 0;
        for (uint32 level = 0; level < header.numberOfMipmapLevels; ++level)
        {
            uint32 imageSize = 0;
            stream->read(&imageSize, sizeof(uint32));

            for(uint32 face = 0; face < numFaces; ++face)
            {
                uchar* placePtr = destPtr + ((imgData->size)/numFaces)*face + mipOffset; // shuffle mip and face
                stream->read(placePtr, imageSize);
            }
            mipOffset += imageSize;
        }

        result.first = output;
        result.second = CodecDataPtr(imgData);

        return true;
    }
}
<|endoftext|>


<commit_before>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

//_________________________________________________________________________
//  Implementation version 1 of the clusterization algorithm
//
//*-- Author: Yves Schutz (SUBATECH)
//////////////////////////////////////////////////////////////////////////////

// --- ROOT system ---

#include "TMath.h"

// --- Standard library ---

#include <iostream.h>

// --- AliRoot header files ---

#include "AliPHOSClusterizerv1.h"
#include "AliPHOSDigit.h"
#include "AliPHOSEmcRecPoint.h"
#include "AliPHOSPpsdRecPoint.h"
#include "AliPHOSv0.h"
#include "AliRun.h"

ClassImp(AliPHOSClusterizerv1)

//____________________________________________________________________________
AliPHOSClusterizerv1::AliPHOSClusterizerv1()
{
  // default ctor (to be used)

  fA                       = 0.;
  fB                       = 0.01 ;
  fGeom                    = AliPHOSGeometry::GetInstance();
  fNumberOfEmcClusters     = 0 ;
  fNumberOfPpsdClusters    = 0 ;
  fEmcClusteringThreshold  = 0.1;
  fEmcEnergyThreshold      = 0.01;
  fPpsdClusteringThreshold = 0.00000015;
  fPpsdEnergyThreshold     = 0.0000001;
  fW0                      = 4.5 ;
  fLocMaxCut               = 0.06 ;
}

//____________________________________________________________________________
Int_t AliPHOSClusterizerv1::AreNeighbours(AliPHOSDigit * d1, AliPHOSDigit * d2)
{
  // Gives the neighbourness of two digits = 0 are not neighbour but continue searching
  //                                       = 1 are neighbour
  //                                       = 2 are not neighbour but do not continue searching
  // neighbours are defined as digits having at least common vertex
  // The order of d1 and d2 is important: first (d1) should be a digit already in a cluster
  //                                      which is compared to a digit (d2)  not yet in a cluster

  Int_t rv = 0 ;

  Int_t relid1[4] ;
  fGeom->AbsToRelNumbering(d1->GetId(), relid1) ;

  Int_t relid2[4] ;
  fGeom->AbsToRelNumbering(d2->GetId(), relid2) ;

  if ( (relid1[0] == relid2[0]) && (relid1[1]==relid2[1]) ) { // inside the same PHOS module and the same PPSD Module
    Int_t rowdiff = TMath::Abs( relid1[2] - relid2[2] ) ;
    Int_t coldiff = TMath::Abs( relid1[3] - relid2[3] ) ;

    if (( coldiff <= 1 )  && ( rowdiff <= 1 )){
      rv = 1 ;
    }
    else {
      if((relid2[2] > relid1[2]) && (relid2[3] > relid1[3]+1))
	rv = 2; //  Difference in row numbers is too large to look further
    }

  }
  else {

    if( (relid1[0] < relid2[0]) || (relid1[1] < relid2[1]) )
      rv=2 ;

  }
  if((relid1[1]>0) && (relid1[1]<16) ) rv = 2 ; //Do NOT clusterize upper PPSD
  return rv ;
}

//____________________________________________________________________________
void AliPHOSClusterizerv1::FillandSort(const DigitsList * dl, TObjArray * tl)
{
  // Copies the digits with energy above thershold and sorts the list
  // according to increasing Id number

  Int_t relid[4] ;

  TIter next(dl) ;
  AliPHOSDigit * digit ;

  while ( (digit = (AliPHOSDigit *)next()) ) {

//     cout << " clusterizerv1 " << endl ;
//     int nprim = digit->GetNprimary() ;
//     int * aprim = digit->GetPrimary() ;
//     for ( int ii = 0 ; ii < nprim ; ii++)
//       cout << ii << " prim = " << aprim[ii] << endl ;

    Int_t id    = digit->GetId() ;
    Float_t ene = Calibrate(digit->GetAmp()) ;
    fGeom->AbsToRelNumbering(id, relid) ;
    if(relid[1]==0){ // EMC
      if ( ene > fEmcEnergyThreshold )
	tl->Add(digit) ;
    }

    else { //Ppsd
      if ( ene > fPpsdEnergyThreshold )
	tl->Add(digit) ;
    }

  }
  tl->Sort() ;
}

//____________________________________________________________________________
void AliPHOSClusterizerv1:: GetNumberOfClustersFound(Int_t * numb)
{
  // Fills numb with the number of EMC  (numb[0]) clusters found
  //                               PPSD (numb[1]) clusters found

  numb[0] = fNumberOfEmcClusters ;
  numb[1] = fNumberOfPpsdClusters ;
}

//____________________________________________________________________________
Bool_t AliPHOSClusterizerv1::IsInEmc(AliPHOSDigit * digit)
{
  // Tells if (true) or not (false) the digit is in a PHOS-EMC module

  Bool_t rv = kFALSE ;

  Int_t relid[4] ;
  fGeom->AbsToRelNumbering(digit->GetId(), relid) ;

  if ( relid[1] == 0  )
    rv = kTRUE;

  return rv ;
}

//____________________________________________________________________________
void AliPHOSClusterizerv1::MakeClusters(const DigitsList * dl,
					AliPHOSRecPoint::RecPointsList * emcl,
					AliPHOSRecPoint::RecPointsList * ppsdl)
{
  // Steering method to construct the clusters stored in a list of Reconstructed Points
  // A cluster is defined as a list of neighbour digits

  fNumberOfEmcClusters = 0 ;
  fNumberOfPpsdClusters = 0 ;

  // Fill and sort the working digits list
  TObjArray tempodigitslist( dl->GetEntries() ) ;
  FillandSort(dl, &tempodigitslist) ;

  // Clusterization starts
  TIter nextdigit(&tempodigitslist) ;
  AliPHOSDigit * digit ;
  Bool_t notremoved = kTRUE ;

  while ( (digit = (AliPHOSDigit *)nextdigit()) ) { // scan over the list of digits
    AliPHOSRecPoint * clu ;

    AliPHOSDigit ** clusterdigitslist = new AliPHOSDigit*[dl->GetEntries()] ;
    Int_t index ;
    if (( ( IsInEmc(digit) ) && ( Calibrate(digit->GetAmp() ) > fEmcClusteringThreshold ) ) ||
        ( ( !IsInEmc(digit) ) && ( Calibrate(digit->GetAmp() ) > fPpsdClusteringThreshold ) ) ) {

      Int_t iDigitInCluster = 0 ;

      if  ( IsInEmc(digit) ) {
	// start a new EMC RecPoint
	if(fNumberOfEmcClusters >= emcl->GetSize())
	  emcl->Expand(2*fNumberOfEmcClusters+1) ;
	(*emcl)[fNumberOfEmcClusters] = new  AliPHOSEmcRecPoint(fW0, fLocMaxCut) ;
	clu = (AliPHOSEmcRecPoint *) emcl->At(fNumberOfEmcClusters) ;
	fNumberOfEmcClusters++ ;
	clu->AddDigit(*digit, Calibrate(digit->GetAmp())) ;
	clusterdigitslist[iDigitInCluster] = digit ;
	iDigitInCluster++ ;
	tempodigitslist.Remove(digit) ;

      }

      else {

	// start a new PPSD cluster
	if(fNumberOfPpsdClusters >= ppsdl->GetSize())
	  ppsdl->Expand(2*fNumberOfPpsdClusters) ;

	(*ppsdl)[fNumberOfPpsdClusters] = new AliPHOSPpsdRecPoint() ;
	clu =  (AliPHOSPpsdRecPoint *) ppsdl->At(fNumberOfPpsdClusters)  ;
	fNumberOfPpsdClusters++ ;
	clu->AddDigit(*digit, Calibrate(digit->GetAmp()) ) ;
	clusterdigitslist[iDigitInCluster] = digit  ;
	iDigitInCluster++ ;
	tempodigitslist.Remove(digit) ;
        nextdigit.Reset() ;

	// Here we remove resting EMC digits, which cannot make cluster

        if( notremoved ) {

	  while( ( digit = (AliPHOSDigit *)nextdigit() ) ) {

            if( IsInEmc(digit) )
	      tempodigitslist.Remove(digit) ;
            else
	      break ;

	  } // while digit

	} // if notremoved

      } // else

      nextdigit.Reset() ;

      AliPHOSDigit * digitN ;
      index = 0 ;
      while (index < iDigitInCluster){ // scan over digits already in cluster
	digit =  clusterdigitslist[index]  ;
	index++ ;
        while ( (digitN = (AliPHOSDigit *)nextdigit()) ) { // scan over the reduced list of digits
	  Int_t ineb = AreNeighbours(digit, digitN);   //  call (digit,digitN) in THAT oder !!!!!
          switch (ineb ) {
          case 0 :   // not a neighbour
	    break ;
	  case 1 :   // are neighbours
	    clu->AddDigit(*digitN, Calibrate( digitN->GetAmp() ) ) ;
	    clusterdigitslist[iDigitInCluster] = digitN ;
	    iDigitInCluster++ ;
	    tempodigitslist.Remove(digitN) ;
	    break ;
          case 2 :   // too far from each other
	    goto endofloop;
	  } // switch

	} // while digitN

      endofloop: ;
	nextdigit.Reset() ;

      } // loop over cluster
   }  //below energy theshold

    delete[] clusterdigitslist ;

  } // while digit

  tempodigitslist.Clear() ;

  ppsdl->Sort() ;
  Int_t index ;
  for(index = 0; index < ppsdl->GetEntries(); index++)
    ((AliPHOSPpsdRecPoint *)ppsdl->At(index))->SetIndexInList(index) ;
}

//____________________________________________________________________________
void AliPHOSClusterizerv1::PrintParameters()
{
  // Print the energy thresholds

  cout << "PHOS Clusterizer version 1 :" << endl
       << "                       EMC  Clustering threshold = " << fEmcClusteringThreshold << endl
       << "                       EMC  Energy threshold     = " << fEmcEnergyThreshold << endl
       << "                      PPSD  Clustering threshold = " << fPpsdClusteringThreshold << endl
       << "                      PPSD  Energy threshold     = " << fPpsdEnergyThreshold << endl ;
}
<commit_msg>A bug with expansion of PPSD RPointlist is corrected<commit_after>/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/* $Id$ */

//_________________________________________________________________________
//  Implementation version 1 of the clusterization algorithm
//
//*-- Author: Yves Schutz (SUBATECH)
//////////////////////////////////////////////////////////////////////////////

// --- ROOT system ---

#include "TMath.h"

// --- Standard library ---

#include <iostream.h>

// --- AliRoot header files ---

#include "AliPHOSClusterizerv1.h"
#include "AliPHOSDigit.h"
#include "AliPHOSEmcRecPoint.h"
#include "AliPHOSPpsdRecPoint.h"
#include "AliPHOSv0.h"
#include "AliRun.h"

ClassImp(AliPHOSClusterizerv1)

//____________________________________________________________________________
AliPHOSClusterizerv1::AliPHOSClusterizerv1()
{
  // default ctor (to be used)

  fA                       = 0.;
  fB                       = 0.01 ;
  fGeom                    = AliPHOSGeometry::GetInstance();
  fNumberOfEmcClusters     = 0 ;
  fNumberOfPpsdClusters    = 0 ;
  fEmcClusteringThreshold  = 0.1;
  fEmcEnergyThreshold      = 0.01;
  fPpsdClusteringThreshold = 0.00000015;
  fPpsdEnergyThreshold     = 0.0000001;
  fW0                      = 4.5 ;
  fLocMaxCut               = 0.06 ;
}

//____________________________________________________________________________
Int_t AliPHOSClusterizerv1::AreNeighbours(AliPHOSDigit * d1, AliPHOSDigit * d2)
{
  // Gives the neighbourness of two digits = 0 are not neighbour but continue searching
  //                                       = 1 are neighbour
  //                                       = 2 are not neighbour but do not continue searching
  // neighbours are defined as digits having at least common vertex
  // The order of d1 and d2 is important: first (d1) should be a digit already in a cluster
  //                                      which is compared to a digit (d2)  not yet in a cluster

  Int_t rv = 0 ;

  Int_t relid1[4] ;
  fGeom->AbsToRelNumbering(d1->GetId(), relid1) ;

  Int_t relid2[4] ;
  fGeom->AbsToRelNumbering(d2->GetId(), relid2) ;

  if ( (relid1[0] == relid2[0]) && (relid1[1]==relid2[1]) ) { // inside the same PHOS module and the same PPSD Module
    Int_t rowdiff = TMath::Abs( relid1[2] - relid2[2] ) ;
    Int_t coldiff = TMath::Abs( relid1[3] - relid2[3] ) ;

    if (( coldiff <= 1 )  && ( rowdiff <= 1 )){
      rv = 1 ;
    }
    else {
      if((relid2[2] > relid1[2]) && (relid2[3] > relid1[3]+1))
	rv = 2; //  Difference in row numbers is too large to look further
    }

  }
  else {

    if( (relid1[0] < relid2[0]) || (relid1[1] < relid2[1]) )
      rv=2 ;

  }
  if((relid1[1]>0) && (relid1[1]<16) ) rv = 2 ; //Do NOT clusterize upper PPSD
  return rv ;
}

//____________________________________________________________________________
void AliPHOSClusterizerv1::FillandSort(const DigitsList * dl, TObjArray * tl)
{
  // Copies the digits with energy above thershold and sorts the list
  // according to increasing Id number

  Int_t relid[4] ;

  TIter next(dl) ;
  AliPHOSDigit * digit ;

  while ( (digit = (AliPHOSDigit *)next()) ) {

//     cout << " clusterizerv1 " << endl ;
//     int nprim = digit->GetNprimary() ;
//     int * aprim = digit->GetPrimary() ;
//     for ( int ii = 0 ; ii < nprim ; ii++)
//       cout << ii << " prim = " << aprim[ii] << endl ;

    Int_t id    = digit->GetId() ;
    Float_t ene = Calibrate(digit->GetAmp()) ;
    fGeom->AbsToRelNumbering(id, relid) ;
    if(relid[1]==0){ // EMC
      if ( ene > fEmcEnergyThreshold )
	tl->Add(digit) ;
    }

    else { //Ppsd
      if ( ene > fPpsdEnergyThreshold )
	tl->Add(digit) ;
    }

  }
  tl->Sort() ;
}

//____________________________________________________________________________
void AliPHOSClusterizerv1:: GetNumberOfClustersFound(Int_t * numb)
{
  // Fills numb with the number of EMC  (numb[0]) clusters found
  //                               PPSD (numb[1]) clusters found

  numb[0] = fNumberOfEmcClusters ;
  numb[1] = fNumberOfPpsdClusters ;
}

//____________________________________________________________________________
Bool_t AliPHOSClusterizerv1::IsInEmc(AliPHOSDigit * digit)
{
  // Tells if (true) or not (false) the digit is in a PHOS-EMC module

  Bool_t rv = kFALSE ;

  Int_t relid[4] ;
  fGeom->AbsToRelNumbering(digit->GetId(), relid) ;

  if ( relid[1] == 0  )
    rv = kTRUE;

  return rv ;
}

//____________________________________________________________________________
void AliPHOSClusterizerv1::MakeClusters(const DigitsList * dl,
					AliPHOSRecPoint::RecPointsList * emcl,
					AliPHOSRecPoint::RecPointsList * ppsdl)
{
  // Steering method to construct the clusters stored in a list of Reconstructed Points
  // A cluster is defined as a list of neighbour digits

  fNumberOfEmcClusters = 0 ;
  fNumberOfPpsdClusters = 0 ;

  // Fill and sort the working digits list
  TObjArray tempodigitslist( dl->GetEntries() ) ;
  FillandSort(dl, &tempodigitslist) ;

  // Clusterization starts
  TIter nextdigit(&tempodigitslist) ;
  AliPHOSDigit * digit ;
  Bool_t notremoved = kTRUE ;

  while ( (digit = (AliPHOSDigit *)nextdigit()) ) { // scan over the list of digits
    AliPHOSRecPoint * clu ;

    AliPHOSDigit ** clusterdigitslist = new AliPHOSDigit*[dl->GetEntries()] ;
    Int_t index ;
    if (( ( IsInEmc(digit) ) && ( Calibrate(digit->GetAmp() ) > fEmcClusteringThreshold ) ) ||
        ( ( !IsInEmc(digit) ) && ( Calibrate(digit->GetAmp() ) > fPpsdClusteringThreshold ) ) ) {

      Int_t iDigitInCluster = 0 ;

      if  ( IsInEmc(digit) ) {
	// start a new EMC RecPoint
	if(fNumberOfEmcClusters >= emcl->GetSize())
	  emcl->Expand(2*fNumberOfEmcClusters+1) ;
	(*emcl)[fNumberOfEmcClusters] = new  AliPHOSEmcRecPoint(fW0, fLocMaxCut) ;
	clu = (AliPHOSEmcRecPoint *) emcl->At(fNumberOfEmcClusters) ;
	fNumberOfEmcClusters++ ;
	clu->AddDigit(*digit, Calibrate(digit->GetAmp())) ;
	clusterdigitslist[iDigitInCluster] = digit ;
	iDigitInCluster++ ;
	tempodigitslist.Remove(digit) ;

      }

      else {

	// start a new PPSD cluster
	if(fNumberOfPpsdClusters >= ppsdl->GetSize())
	  ppsdl->Expand(2*fNumberOfPpsdClusters+1) ;

	(*ppsdl)[fNumberOfPpsdClusters] = new AliPHOSPpsdRecPoint() ;
	clu =  (AliPHOSPpsdRecPoint *) ppsdl->At(fNumberOfPpsdClusters)  ;
	fNumberOfPpsdClusters++ ;
	clu->AddDigit(*digit, Calibrate(digit->GetAmp()) ) ;
	clusterdigitslist[iDigitInCluster] = digit  ;
	iDigitInCluster++ ;
	tempodigitslist.Remove(digit) ;
        nextdigit.Reset() ;

	// Here we remove resting EMC digits, which cannot make cluster

        if( notremoved ) {

	  while( ( digit = (AliPHOSDigit *)nextdigit() ) ) {

            if( IsInEmc(digit) )
	      tempodigitslist.Remove(digit) ;
            else
	      break ;

	  } // while digit

	} // if notremoved

      } // else

      nextdigit.Reset() ;

      AliPHOSDigit * digitN ;
      index = 0 ;
      while (index < iDigitInCluster){ // scan over digits already in cluster
	digit =  clusterdigitslist[index]  ;
	index++ ;
        while ( (digitN = (AliPHOSDigit *)nextdigit()) ) { // scan over the reduced list of digits
	  Int_t ineb = AreNeighbours(digit, digitN);   //  call (digit,digitN) in THAT oder !!!!!
          switch (ineb ) {
          case 0 :   // not a neighbour
	    break ;
	  case 1 :   // are neighbours
	    clu->AddDigit(*digitN, Calibrate( digitN->GetAmp() ) ) ;
	    clusterdigitslist[iDigitInCluster] = digitN ;
	    iDigitInCluster++ ;
	    tempodigitslist.Remove(digitN) ;
	    break ;
          case 2 :   // too far from each other
	    goto endofloop;
	  } // switch

	} // while digitN

      endofloop: ;
	nextdigit.Reset() ;

      } // loop over cluster
   }  //below energy theshold

    delete[] clusterdigitslist ;

  } // while digit

  tempodigitslist.Clear() ;

  ppsdl->Sort() ;
  Int_t index ;
  for(index = 0; index < ppsdl->GetEntries(); index++)
    ((AliPHOSPpsdRecPoint *)ppsdl->At(index))->SetIndexInList(index) ;
}

//____________________________________________________________________________
void AliPHOSClusterizerv1::PrintParameters()
{
  // Print the energy thresholds

  cout << "PHOS Clusterizer version 1 :" << endl
       << "                       EMC  Clustering threshold = " << fEmcClusteringThreshold << endl
       << "                       EMC  Energy threshold     = " << fEmcEnergyThreshold << endl
       << "                      PPSD  Clustering threshold = " << fPpsdClusteringThreshold << endl
       << "                      PPSD  Energy threshold     = " << fPpsdEnergyThreshold << endl ;
}
<|endoftext|>


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

  Program:   Visualization Toolkit
  Module:    vtkMPIController.cxx

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

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

=========================================================================*/
#include "vtkMPIController.h"

#include "vtkObjectFactory.h"
#include "vtkOutputWindow.h"

#include "vtkMPI.h"

int vtkMPIController::Initialized = 0;
char vtkMPIController::ProcessorName[MPI_MAX_PROCESSOR_NAME] = "";

// Output window which prints out the process id
// with the error or warning messages
class VTK_PARALLEL_EXPORT vtkMPIOutputWindow : public vtkOutputWindow
{
public:
  vtkTypeRevisionMacro(vtkMPIOutputWindow,vtkOutputWindow);

  void DisplayText(const char* t)
  {
    if (this->Controller)
      {
      cout << "Process id: " << this->Controller->GetLocalProcessId()
           << " >> ";
      }
    cout << t;
  }

  vtkMPIOutputWindow()
  {
    vtkObject* ret = vtkObjectFactory::CreateInstance("vtkMPIOutputWindow");
    if (ret)
      ret->Delete();
    this->Controller = 0;
  }

  friend class vtkMPIController;

protected:

  vtkMPIController* Controller;
  vtkMPIOutputWindow(const vtkMPIOutputWindow&);
  void operator=(const vtkMPIOutputWindow&);

};

void vtkMPIController::CreateOutputWindow()
{
  vtkMPIOutputWindow* window = new vtkMPIOutputWindow;
  window->Controller = this;
  this->OutputWindow = window;
  vtkOutputWindow::SetInstance(this->OutputWindow);
}

vtkCxxRevisionMacro(vtkMPIOutputWindow, "1.18");

vtkCxxRevisionMacro(vtkMPIController, "1.18");
vtkStandardNewMacro(vtkMPIController);

//----------------------------------------------------------------------------
vtkMPIController::vtkMPIController()
{
  // If MPI was already initialized obtain rank and size.
  if (vtkMPIController::Initialized)
    {
    this->InitializeCommunicator(vtkMPICommunicator::GetWorldCommunicator());
    // Copy vtkMPIController::WorldRMICommunicataor which is created when
    // MPI is initialized
    vtkMPICommunicator* comm = vtkMPICommunicator::New();
    comm->CopyFrom(vtkMPIController::WorldRMICommunicator);
    this->RMICommunicator = comm;
    }

  this->OutputWindow = 0;
}

//----------------------------------------------------------------------------
vtkMPIController::~vtkMPIController()
{
  this->SetCommunicator(0);
  if (this->RMICommunicator)
    {
    this->RMICommunicator->Delete();
    }
}

//----------------------------------------------------------------------------
void vtkMPIController::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "Initialized: " << ( vtkMPIController::Initialized ? "(yes)" : "(no)" ) << endl;
}

// Set the number of processes and maximum number of processes
// to the size obtained from MPI.
int vtkMPIController::InitializeNumberOfProcesses()
{
  int err;

  this->Modified();

  vtkMPICommunicator* comm = (vtkMPICommunicator*)this->Communicator;
  if ( (err = MPI_Comm_size(*(comm->Comm->Handle),
                            &(this->MaximumNumberOfProcesses)))
       != MPI_SUCCESS  )
    {
    char *msg = vtkMPIController::ErrorString(err);
    vtkErrorMacro("MPI error occured: " << msg);
    delete[] msg;
    return 0;
    }

  if (this->MaximumNumberOfProcesses > MAX_PROCESSES)
    {
    vtkWarningMacro("Maximum of " << MAX_PROCESSES);
    this->MaximumNumberOfProcesses = MAX_PROCESSES;
    }

  this->NumberOfProcesses = this->MaximumNumberOfProcesses;

  if ( (err = MPI_Comm_rank(*(comm->Comm->Handle),&(this->LocalProcessId)))
       != MPI_SUCCESS)
    {
    char *msg = vtkMPIController::ErrorString(err);
    vtkErrorMacro("MPI error occured: " << msg);
    delete[] msg;
    return 0;
    }
  return 1;
}

vtkMPICommunicator* vtkMPIController::WorldRMICommunicator=0;

//----------------------------------------------------------------------------
void vtkMPIController::Initialize(int* argc, char*** argv,
                                  int initializedExternally)
{
  if (vtkMPIController::Initialized)
    {
    vtkWarningMacro("Already initialized.");
    return;
    }

  // Can be done once in the program.
  vtkMPIController::Initialized = 1;
  if (initializedExternally == 0)
    {
      MPI_Init(argc, argv);
    }
  this->InitializeCommunicator(vtkMPICommunicator::GetWorldCommunicator());
  this->InitializeNumberOfProcesses();

  int tmp;
  MPI_Get_processor_name(ProcessorName, &tmp);
  // Make a copy of MPI_COMM_WORLD creating a new context.
  // This is used in the creating of the communicators after
  // Initialize() has been called. It has to be done here
  // because for this to work, all processes have to call
  // MPI_Comm_dup and this is the only method which is
  // guaranteed to be called by all processes.
  vtkMPIController::WorldRMICommunicator = vtkMPICommunicator::New();
  vtkMPIController::WorldRMICommunicator->Duplicate((vtkMPICommunicator*)this->Communicator);
  this->RMICommunicator = vtkMPIController::WorldRMICommunicator;
  // Since we use Delete to get rid of the reference, we should use NULL to register.
  this->RMICommunicator->Register(NULL);

  this->Modified();
}

const char* vtkMPIController::GetProcessorName()
{
  return ProcessorName;
}

// Good-bye world
// There should be no MPI calls after this.
// (Except maybe MPI_XXX_free()) unless finalized externally.
void vtkMPIController::Finalize(int finalizedExternally)
{
  if (vtkMPIController::Initialized)
    {
    vtkMPIController::WorldRMICommunicator->Delete();
    vtkMPIController::WorldRMICommunicator = 0;
    vtkMPICommunicator::WorldCommunicator->Delete();
    this->SetCommunicator(0);
    if (this->RMICommunicator)
      {
      this->RMICommunicator->Delete();
      this->RMICommunicator = 0;
      }
    if (finalizedExternally == 0)
      {
        MPI_Finalize();
      }
    vtkMPIController::Initialized = 0;
    this->Modified();
    }

}

// Called by SetCommunicator and constructor. It frees but does
// not set RMIHandle (which should not be set by using MPI_Comm_dup
// during construction).
void vtkMPIController::InitializeCommunicator(vtkMPICommunicator* comm)
{
  if (this->Communicator != comm)
    {
    if (this->Communicator != 0)
      {
      this->Communicator->UnRegister(this);
      }
    this->Communicator = comm;
    if (this->Communicator != 0)
      {
      this->Communicator->Register(this);
      }

    if (comm && comm->Comm->Handle)
      {
      this->InitializeNumberOfProcesses();
      }
    this->Modified();
    }

}

// Delete the previous RMI communicator and creates a new one
// by duplicating the user communicator.
void vtkMPIController::InitializeRMICommunicator()
{
  if ( this->RMICommunicator )
    {
    this->RMICommunicator->Delete();
    this->RMICommunicator = 0;
    }
  if (this->Communicator)
    {
    this->RMICommunicator = vtkMPICommunicator::New();
    ((vtkMPICommunicator*)this->RMICommunicator)->Duplicate((vtkMPICommunicator*)this->Communicator);
    }
}

void vtkMPIController::SetCommunicator(vtkMPICommunicator* comm)
{
  this->InitializeCommunicator(comm);
  this->InitializeRMICommunicator();
}

void vtkMPIController::Barrier()
{
  vtkMPICommunicator* comm = (vtkMPICommunicator*)this->Communicator;
  int err;
  if ( (err = MPI_Barrier(*(comm->Comm->Handle)) )
       != MPI_SUCCESS )
    {
    char *msg = vtkMPIController::ErrorString(err);
    vtkErrorMacro("MPI error occured: " << msg);
    delete[] msg;
    }
}

//----------------------------------------------------------------------------
// Execute the method set as the SingleMethod.
void vtkMPIController::SingleMethodExecute()
{
  if(!vtkMPIController::Initialized)
    {
    vtkWarningMacro("MPI has to be initialized first.");
    return;
    }

  if (this->LocalProcessId < this->NumberOfProcesses)
    {
    if (this->SingleMethod)
      {
      vtkMultiProcessController::SetGlobalController(this);
      (this->SingleMethod)(this, this->SingleData);
      }
    else
      {
      vtkWarningMacro("SingleMethod not set.");
      }
    }
}

//----------------------------------------------------------------------------
// Execute the methods set as the MultipleMethods.
void vtkMPIController::MultipleMethodExecute()
{
  if(!vtkMPIController::Initialized)
    {
    vtkWarningMacro("MPI has to be initialized first.");
    return;
    }

  int i = this->LocalProcessId;

  if (this->LocalProcessId < this->NumberOfProcesses)
    {
    if (this->MultipleMethod[i])
      {
      vtkMultiProcessController::SetGlobalController(this);
      (this->MultipleMethod[i])(this, this->MultipleData[i]);
      }
    else
      {
      vtkWarningMacro("MultipleMethod " << i << " not set.");
      }
    }
}

char* vtkMPIController::ErrorString(int err)
{
  char* buffer = new char[MPI_MAX_ERROR_STRING];
  int resLen;
  MPI_Error_string(err, buffer, &resLen);
  return buffer;
}

<commit_msg>Fixed indentation<commit_after>/*=========================================================================

Program:   Visualization Toolkit
Module:    vtkMPIController.cxx

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

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

=========================================================================*/
#include "vtkMPIController.h"

#include "vtkObjectFactory.h"
#include "vtkOutputWindow.h"

#include "vtkMPI.h"

int vtkMPIController::Initialized = 0;
char vtkMPIController::ProcessorName[MPI_MAX_PROCESSOR_NAME] = "";

// Output window which prints out the process id
// with the error or warning messages
class VTK_PARALLEL_EXPORT vtkMPIOutputWindow : public vtkOutputWindow
{
public:
  vtkTypeRevisionMacro(vtkMPIOutputWindow,vtkOutputWindow);

  void DisplayText(const char* t)
    {
      if (this->Controller)
        {
        cout << "Process id: " << this->Controller->GetLocalProcessId()
             << " >> ";
        }
      cout << t;
    }

  vtkMPIOutputWindow()
    {
      vtkObject* ret = vtkObjectFactory::CreateInstance("vtkMPIOutputWindow");
      if (ret)
        ret->Delete();
      this->Controller = 0;
    }

  friend class vtkMPIController;

protected:

  vtkMPIController* Controller;
  vtkMPIOutputWindow(const vtkMPIOutputWindow&);
  void operator=(const vtkMPIOutputWindow&);

};

void vtkMPIController::CreateOutputWindow()
{
  vtkMPIOutputWindow* window = new vtkMPIOutputWindow;
  window->Controller = this;
  this->OutputWindow = window;
  vtkOutputWindow::SetInstance(this->OutputWindow);
}

vtkCxxRevisionMacro(vtkMPIOutputWindow, "1.19");

vtkCxxRevisionMacro(vtkMPIController, "1.19");
vtkStandardNewMacro(vtkMPIController);

//----------------------------------------------------------------------------
vtkMPIController::vtkMPIController()
{
  // If MPI was already initialized obtain rank and size.
  if (vtkMPIController::Initialized)
    {
    this->InitializeCommunicator(vtkMPICommunicator::GetWorldCommunicator());
    // Copy vtkMPIController::WorldRMICommunicataor which is created when
    // MPI is initialized
    vtkMPICommunicator* comm = vtkMPICommunicator::New();
    comm->CopyFrom(vtkMPIController::WorldRMICommunicator);
    this->RMICommunicator = comm;
    }

  this->OutputWindow = 0;
}

//----------------------------------------------------------------------------
vtkMPIController::~vtkMPIController()
{
  this->SetCommunicator(0);
  if (this->RMICommunicator)
    {
    this->RMICommunicator->Delete();
    }
}

//----------------------------------------------------------------------------
void vtkMPIController::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);
  os << indent << "Initialized: " << ( vtkMPIController::Initialized ? "(yes)" : "(no)" ) << endl;
}

// Set the number of processes and maximum number of processes
// to the size obtained from MPI.
int vtkMPIController::InitializeNumberOfProcesses()
{
  int err;

  this->Modified();

  vtkMPICommunicator* comm = (vtkMPICommunicator*)this->Communicator;
  if ( (err = MPI_Comm_size(*(comm->Comm->Handle),
                            &(this->MaximumNumberOfProcesses)))
       != MPI_SUCCESS  )
    {
    char *msg = vtkMPIController::ErrorString(err);
    vtkErrorMacro("MPI error occured: " << msg);
    delete[] msg;
    return 0;
    }

  if (this->MaximumNumberOfProcesses > MAX_PROCESSES)
    {
    vtkWarningMacro("Maximum of " << MAX_PROCESSES);
    this->MaximumNumberOfProcesses = MAX_PROCESSES;
    }

  this->NumberOfProcesses = this->MaximumNumberOfProcesses;

  if ( (err = MPI_Comm_rank(*(comm->Comm->Handle),&(this->LocalProcessId)))
       != MPI_SUCCESS)
    {
    char *msg = vtkMPIController::ErrorString(err);
    vtkErrorMacro("MPI error occured: " << msg);
    delete[] msg;
    return 0;
    }
  return 1;
}

vtkMPICommunicator* vtkMPIController::WorldRMICommunicator=0;

//----------------------------------------------------------------------------
void vtkMPIController::Initialize(int* argc, char*** argv,
                                  int initializedExternally)
{
  if (vtkMPIController::Initialized)
    {
    vtkWarningMacro("Already initialized.");
    return;
    }

  // Can be done once in the program.
  vtkMPIController::Initialized = 1;
  if (initializedExternally == 0)
    {
    MPI_Init(argc, argv);
    }
  this->InitializeCommunicator(vtkMPICommunicator::GetWorldCommunicator());
  this->InitializeNumberOfProcesses();

  int tmp;
  MPI_Get_processor_name(ProcessorName, &tmp);
  // Make a copy of MPI_COMM_WORLD creating a new context.
  // This is used in the creating of the communicators after
  // Initialize() has been called. It has to be done here
  // because for this to work, all processes have to call
  // MPI_Comm_dup and this is the only method which is
  // guaranteed to be called by all processes.
  vtkMPIController::WorldRMICommunicator = vtkMPICommunicator::New();
  vtkMPIController::WorldRMICommunicator->Duplicate((vtkMPICommunicator*)this->Communicator);
  this->RMICommunicator = vtkMPIController::WorldRMICommunicator;
  // Since we use Delete to get rid of the reference, we should use NULL to register.
  this->RMICommunicator->Register(NULL);

  this->Modified();
}

const char* vtkMPIController::GetProcessorName()
{
  return ProcessorName;
}

// Good-bye world
// There should be no MPI calls after this.
// (Except maybe MPI_XXX_free()) unless finalized externally.
void vtkMPIController::Finalize(int finalizedExternally)
{
  if (vtkMPIController::Initialized)
    {
    vtkMPIController::WorldRMICommunicator->Delete();
    vtkMPIController::WorldRMICommunicator = 0;
    vtkMPICommunicator::WorldCommunicator->Delete();
    this->SetCommunicator(0);
    if (this->RMICommunicator)
      {
      this->RMICommunicator->Delete();
      this->RMICommunicator = 0;
      }
    if (finalizedExternally == 0)
      {
      MPI_Finalize();
      }
    vtkMPIController::Initialized = 0;
    this->Modified();
    }

}

// Called by SetCommunicator and constructor. It frees but does
// not set RMIHandle (which should not be set by using MPI_Comm_dup
// during construction).
void vtkMPIController::InitializeCommunicator(vtkMPICommunicator* comm)
{
  if (this->Communicator != comm)
    {
    if (this->Communicator != 0)
      {
      this->Communicator->UnRegister(this);
      }
    this->Communicator = comm;
    if (this->Communicator != 0)
      {
      this->Communicator->Register(this);
      }

    if (comm && comm->Comm->Handle)
      {
      this->InitializeNumberOfProcesses();
      }
    this->Modified();
    }

}

// Delete the previous RMI communicator and creates a new one
// by duplicating the user communicator.
void vtkMPIController::InitializeRMICommunicator()
{
  if ( this->RMICommunicator )
    {
    this->RMICommunicator->Delete();
    this->RMICommunicator = 0;
    }
  if (this->Communicator)
    {
    this->RMICommunicator = vtkMPICommunicator::New();
    ((vtkMPICommunicator*)this->RMICommunicator)->Duplicate((vtkMPICommunicator*)this->Communicator);
    }
}

void vtkMPIController::SetCommunicator(vtkMPICommunicator* comm)
{
  this->InitializeCommunicator(comm);
  this->InitializeRMICommunicator();
}

void vtkMPIController::Barrier()
{
  vtkMPICommunicator* comm = (vtkMPICommunicator*)this->Communicator;
  int err;
  if ( (err = MPI_Barrier(*(comm->Comm->Handle)) )
       != MPI_SUCCESS )
    {
    char *msg = vtkMPIController::ErrorString(err);
    vtkErrorMacro("MPI error occured: " << msg);
    delete[] msg;
    }
}

//----------------------------------------------------------------------------
// Execute the method set as the SingleMethod.
void vtkMPIController::SingleMethodExecute()
{
  if(!vtkMPIController::Initialized)
    {
    vtkWarningMacro("MPI has to be initialized first.");
    return;
    }

  if (this->LocalProcessId < this->NumberOfProcesses)
    {
    if (this->SingleMethod)
      {
      vtkMultiProcessController::SetGlobalController(this);
      (this->SingleMethod)(this, this->SingleData);
      }
    else
      {
      vtkWarningMacro("SingleMethod not set.");
      }
    }
}

//----------------------------------------------------------------------------
// Execute the methods set as the MultipleMethods.
void vtkMPIController::MultipleMethodExecute()
{
  if(!vtkMPIController::Initialized)
    {
    vtkWarningMacro("MPI has to be initialized first.");
    return;
    }

  int i = this->LocalProcessId;

  if (this->LocalProcessId < this->NumberOfProcesses)
    {
    if (this->MultipleMethod[i])
      {
      vtkMultiProcessController::SetGlobalController(this);
      (this->MultipleMethod[i])(this, this->MultipleData[i]);
      }
    else
      {
      vtkWarningMacro("MultipleMethod " << i << " not set.");
      }
    }
}

char* vtkMPIController::ErrorString(int err)
{
  char* buffer = new char[MPI_MAX_ERROR_STRING];
  int resLen;
  MPI_Error_string(err, buffer, &resLen);
  return buffer;
}

<|endoftext|>


<commit_before><commit_msg>Disallow calls to render device unless mocked<commit_after><|endoftext|>


<commit_before><commit_msg>added pe70<commit_after><|endoftext|>


<commit_before><commit_msg>INTEGRATION: CWS rt13 (1.3.8); FILE MERGED 2005/12/07 17:24:00 np 1.3.8.1: #i58717#<commit_after><|endoftext|>


<commit_before><commit_msg>Remove the black line from the bottom of the status bubble.<commit_after><|endoftext|>


<commit_before>#ifndef STAN_MCMC_HMC_NUTS_DIAG_E_XHMC_HPP
#define STAN_MCMC_HMC_NUTS_DIAG_E_NUTS_HPP_E_XHMC_HPP

#include <stan/mcmc/hmc/xhmc/base_xhmc.hpp>
#include <stan/mcmc/hmc/hamiltonians/diag_e_point.hpp>
#include <stan/mcmc/hmc/hamiltonians/diag_e_metric.hpp>
#include <stan/mcmc/hmc/integrators/expl_leapfrog.hpp>

namespace stan {
  namespace mcmc {
    /**
     * Exhausive Hamiltonian Monte Carlo (XHMC) with multinomial sampling
     * with a Gaussian-Euclidean disintegration and diagonal metric
     */
    template <class Model, class BaseRNG>
    class diag_e_xhmc
      : public base_xhmc<Model, diag_e_metric,
                         expl_leapfrog, BaseRNG> {
    public:
      diag_e_xhmc(const Model& model, BaseRNG& rng)
        : base_xhmc<Model, diag_e_metric, expl_leapfrog,
                    BaseRNG>(model, rng) { }
    };

  }  // mcmc
}  // stan
#endif
<commit_msg>Fix header guard<commit_after>#ifndef STAN_MCMC_HMC_NUTS_DIAG_E_XHMC_HPP
#define STAN_MCMC_HMC_NUTS_DIAG_E_XHMC_HPP

#include <stan/mcmc/hmc/xhmc/base_xhmc.hpp>
#include <stan/mcmc/hmc/hamiltonians/diag_e_point.hpp>
#include <stan/mcmc/hmc/hamiltonians/diag_e_metric.hpp>
#include <stan/mcmc/hmc/integrators/expl_leapfrog.hpp>

namespace stan {
  namespace mcmc {
    /**
     * Exhausive Hamiltonian Monte Carlo (XHMC) with multinomial sampling
     * with a Gaussian-Euclidean disintegration and diagonal metric
     */
    template <class Model, class BaseRNG>
    class diag_e_xhmc
      : public base_xhmc<Model, diag_e_metric,
                         expl_leapfrog, BaseRNG> {
    public:
      diag_e_xhmc(const Model& model, BaseRNG& rng)
        : base_xhmc<Model, diag_e_metric, expl_leapfrog,
                    BaseRNG>(model, rng) { }
    };

  }  // mcmc
}  // stan
#endif
<|endoftext|>


<commit_before>// infoware - C++ System information Library
//
// Written in 2016 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>

#ifndef _WIN32

#include "infoware/system.hpp"
#include <cstdlib>
#include <cstring>
#include <sys/utsname.h>

iware::system::kernel_info_t iware::system::kernel_info() noexcept {
	utsname uts;
	uname(&uts);

	char* marker                    = uts.release;
	const unsigned int major        = std::strtoul(marker, &marker, 10);
	const unsigned int minor        = std::strtoul(marker + 1, &marker, 10);
	const unsigned int patch        = std::strtoul(marker + 1, &marker, 10);
	const unsigned int build_number = std::strtoul(marker + 1, nullptr, 10);

	auto kernel = iware::system::kernel_t::unknown;
	if(!std::strcmp(uts.sysname, "Linux"))
		kernel = iware::system::kernel_t::linux;
	else if(!std::strcmp(uts.sysname, "Darwin"))
		kernel = iware::system::kernel_t::darwin;

	return {iware::system::kernel_t::linux, major, minor, patch, build_number};
}

#endif
<commit_msg>Fix unused verbol<commit_after>// infoware - C++ System information Library
//
// Written in 2016 by nabijaczleweli <nabijaczleweli@gmail.com> and ThePhD <phdofthehouse@gmail.com>
//
// To the extent possible under law, the author(s) have dedicated all copyright and related
// and neighboring rights to this software to the public domain worldwide. This software is
// distributed without any warranty.
//
// You should have received a copy of the CC0 Public Domain Dedication along with this software.
// If not, see <http://creativecommons.org/publicdomain/zero/1.0/>

#ifndef _WIN32

#include "infoware/system.hpp"
#include <cstdlib>
#include <cstring>
#include <sys/utsname.h>

iware::system::kernel_info_t iware::system::kernel_info() noexcept {
	utsname uts;
	uname(&uts);

	char* marker                    = uts.release;
	const unsigned int major        = std::strtoul(marker, &marker, 10);
	const unsigned int minor        = std::strtoul(marker + 1, &marker, 10);
	const unsigned int patch        = std::strtoul(marker + 1, &marker, 10);
	const unsigned int build_number = std::strtoul(marker + 1, nullptr, 10);

	auto kernel = iware::system::kernel_t::unknown;
	if(!std::strcmp(uts.sysname, "Linux"))
		kernel = iware::system::kernel_t::linux;
	else if(!std::strcmp(uts.sysname, "Darwin"))
		kernel = iware::system::kernel_t::darwin;

	return {kernel, major, minor, patch, build_number};
}

#endif
<|endoftext|>