<commit_before>/*******************************************************************************
 The MIT License (MIT)

 Copyright (c) 2015 Alexander Zolotarev <me@alex.bio> from Minsk, Belarus

 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.
 *******************************************************************************/

// Used to avoid cereal compilation issues on iOS/MacOS when check() macro is defined.
#ifdef __APPLE__
#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
#endif

#include "../alohalytics.h"
#include "../http_client.h"
#include "../logger.h"
#include "../event_base.h"

#include "../cereal/include/archives/binary.hpp"
#include "../cereal/include/types/string.hpp"
#include "../cereal/include/types/map.hpp"

#define LOG_IF_DEBUG(...)                   \
  if (debug_mode_) {                        \
    alohalytics::Logger().Log(__VA_ARGS__); \
  }

namespace alohalytics {

// Used for cereal smart-pointers polymorphic serialization.
struct NoOpDeleter {
  template <typename T>
  void operator()(T*) {}
};

// Use alohalytics::Stats::Instance() to access statistics engine.
Stats::Stats() : message_queue_(*this) {}

bool Stats::UploadBuffer(const std::string& url, std::string&& buffer, bool debug_mode) {
  HTTPClientPlatformWrapper request(url);
  request.set_debug_mode(debug_mode);
  request.set_post_body(std::move(buffer), "application/alohalytics-binary-blob");

  try {
    return request.RunHTTPRequest() && 200 == request.error_code() && !request.was_redirected();
  } catch (const std::exception& ex) {
    if (debug_mode) {
      ALOG("Exception while trying to upload file", ex.what());
    }
  }
  return false;
}

// Processes messages passed from UI in message queue's own thread.
// TODO(AlexZ): Refactor message queue to make this method private.
void Stats::OnMessage(const std::string& message, size_t dropped_events) {
  if (dropped_events) {
    LOG_IF_DEBUG("Warning:", dropped_events, "were dropped from the queue.");
  }
  if (file_storage_queue_) {
    file_storage_queue_->PushMessage(message);
  } else {
    auto& container = memory_storage_;
    container.push_back(message);
    static const size_t kMaxEventsInMemory = 2048;
    if (container.size() > kMaxEventsInMemory) {
      container.pop_front();
    }
  }
}

// Called by file storage engine to upload file with collected data.
// Should return true if upload has been successful.
// TODO(AlexZ): Refactor FSQ to make this method private.
bool Stats::OnFileReady(const std::string& full_path_to_file) {
  if (upload_url_.empty()) {
    LOG_IF_DEBUG("Warning: upload server url was not set and file", full_path_to_file, "was not uploaded.");
    return false;
  }
  if (unique_client_id_event_.empty()) {
    LOG_IF_DEBUG("Warning: unique client ID is not set so statistics was not uploaded.");
    return false;
  }
  // TODO(AlexZ): Refactor to use crossplatform and safe/non-throwing version.
  const uint64_t file_size = bricks::FileSystem::GetFileSize(full_path_to_file);
  if (0 == file_size) {
    LOG_IF_DEBUG("ERROR: Trying to upload file of size 0?", full_path_to_file);
    return false;
  }

  LOG_IF_DEBUG("Trying to upload statistics file", full_path_to_file, "to", upload_url_);

  // Append unique installation id in the beginning of each file sent to the server.
  // It can be empty so all stats data will become anonymous.
  // TODO(AlexZ): Refactor fsq to silently add it in the beginning of each file
  // and to avoid not-enough-memory situation for bigger files.
  std::ifstream fi(full_path_to_file, std::ifstream::in | std::ifstream::binary);
  std::string buffer(unique_client_id_event_);
  const size_t id_size = unique_client_id_event_.size();
  buffer.resize(id_size + static_cast<std::string::size_type>(file_size));
  fi.read(&buffer[id_size], static_cast<std::streamsize>(file_size));
  if (fi.good()) {
    fi.close();
    return UploadBuffer(upload_url_, std::move(buffer), debug_mode_);
  } else {
    LOG_IF_DEBUG("Can't load file with size", file_size, "into memory");
  }
  return false;
}

Stats& Stats::Instance() {
  static Stats alohalytics;
  return alohalytics;
}

// Easier integration if enabled.
Stats& Stats::SetDebugMode(bool enable) {
  debug_mode_ = enable;
  LOG_IF_DEBUG("Enabled debug mode.");
  return *this;
}

// If not set, collected data will never be uploaded.
Stats& Stats::SetServerUrl(const std::string& url_to_upload_statistics_to) {
  upload_url_ = url_to_upload_statistics_to;
  LOG_IF_DEBUG("Set upload url:", url_to_upload_statistics_to);
  return *this;
}

// If not set, data will be stored in memory only.
Stats& Stats::SetStoragePath(const std::string& full_path_to_storage_with_a_slash_at_the_end) {
  LOG_IF_DEBUG("Set storage path:", full_path_to_storage_with_a_slash_at_the_end);
  auto& fsq = file_storage_queue_;
  fsq.reset(nullptr);
  if (!full_path_to_storage_with_a_slash_at_the_end.empty()) {
    fsq.reset(new TFileStorageQueue(*this, full_path_to_storage_with_a_slash_at_the_end));
    if (debug_mode_) {
      const TFileStorageQueue::Status status = fsq->GetQueueStatus();
      LOG_IF_DEBUG("Active file size:", status.appended_file_size);
      const size_t count = status.finalized.queue.size();
      if (count) {
        LOG_IF_DEBUG(count, "files with total size of", status.finalized.total_size,
                     "bytes are waiting for upload.");
      }
    }
    const size_t memory_events_count = memory_storage_.size();
    if (memory_events_count) {
      LOG_IF_DEBUG("Save", memory_events_count, "in-memory events into the file storage.");
      for (const auto& msg : memory_storage_) {
        fsq->PushMessage(msg);
      }
      memory_storage_.clear();
    }
  }
  return *this;
}

// If not set, data will be uploaded without any unique id.
Stats& Stats::SetClientId(const std::string& unique_client_id) {
  LOG_IF_DEBUG("Set unique client id:", unique_client_id);
  if (unique_client_id.empty()) {
    unique_client_id_event_.clear();
  } else {
    AlohalyticsIdEvent event;
    event.id = unique_client_id;
    std::ostringstream sstream;
    { cereal::BinaryOutputArchive(sstream) << std::unique_ptr<AlohalyticsBaseEvent, NoOpDeleter>(&event); }
    unique_client_id_event_ = sstream.str();
  }
  return *this;
}

static inline void LogEventImpl(AlohalyticsBaseEvent const& event, MessageQueue<Stats>& msq) {
  std::ostringstream sstream;
  {
    // unique_ptr is used to correctly serialize polymorphic types.
    cereal::BinaryOutputArchive(sstream) << std::unique_ptr<AlohalyticsBaseEvent const, NoOpDeleter>(&event);
  }
  msq.PushMessage(std::move(sstream.str()));
}

void Stats::LogEvent(std::string const& event_name) {
  LOG_IF_DEBUG("LogEvent:", event_name);
  AlohalyticsKeyEvent event;
  event.key = event_name;
  LogEventImpl(event, message_queue_);
}

void Stats::LogEvent(std::string const& event_name, Location const& location) {
  LOG_IF_DEBUG("LogEvent:", event_name, location.ToDebugString());
  AlohalyticsKeyLocationEvent event;
  event.key = event_name;
  event.location = location;
  LogEventImpl(event, message_queue_);
}

void Stats::LogEvent(std::string const& event_name, std::string const& event_value) {
  LOG_IF_DEBUG("LogEvent:", event_name, "=", event_value);
  AlohalyticsKeyValueEvent event;
  event.key = event_name;
  event.value = event_value;
  LogEventImpl(event, message_queue_);
}

void Stats::LogEvent(std::string const& event_name, std::string const& event_value, Location const& location) {
  LOG_IF_DEBUG("LogEvent:", event_name, "=", event_value, location.ToDebugString());
  AlohalyticsKeyValueLocationEvent event;
  event.key = event_name;
  event.value = event_value;
  event.location = location;
  LogEventImpl(event, message_queue_);
}

void Stats::LogEvent(std::string const& event_name, TStringMap const& value_pairs) {
  LOG_IF_DEBUG("LogEvent:", event_name, "=", value_pairs);
  AlohalyticsKeyPairsEvent event;
  event.key = event_name;
  event.pairs = value_pairs;
  LogEventImpl(event, message_queue_);
}

void Stats::LogEvent(std::string const& event_name, TStringMap const& value_pairs, Location const& location) {
  LOG_IF_DEBUG("LogEvent:", event_name, "=", value_pairs, location.ToDebugString());
  AlohalyticsKeyPairsLocationEvent event;
  event.key = event_name;
  event.pairs = value_pairs;
  event.location = location;
  LogEventImpl(event, message_queue_);
}

// Forcedly tries to upload all stored data to the server.
void Stats::Upload() {
  if (upload_url_.empty()) {
    LOG_IF_DEBUG("Warning: upload server url is not set, nothing was uploaded.");
    return;
  }
  if (unique_client_id_event_.empty()) {
    LOG_IF_DEBUG("Warning: unique client ID is not set so statistics was not uploaded.");
    return;
  }
  LOG_IF_DEBUG("Forcing statistics uploading.");
  if (file_storage_queue_) {
    file_storage_queue_->ForceProcessing();
  } else {
    std::string buffer = unique_client_id_event_;
    // TODO(AlexZ): thread-safety?
    TMemoryContainer copy;
    copy.swap(memory_storage_);
    for (const auto& evt : copy) {
      buffer.append(evt);
    }
    LOG_IF_DEBUG("Forcing in-memory statistics uploading.");
    if (!UploadBuffer(upload_url_, std::move(buffer), debug_mode_)) {
      // If failed, merge events we tried to upload with possible new ones.
      memory_storage_.splice(memory_storage_.end(), std::move(copy));
    }
  }
}

}  // namespace alohalytics
<commit_msg>Always force uploading of the current data. It worked previously only in the cases when no any finalized statistics files were stored in the queue.<commit_after>/*******************************************************************************
 The MIT License (MIT)

 Copyright (c) 2015 Alexander Zolotarev <me@alex.bio> from Minsk, Belarus

 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.
 *******************************************************************************/

// Used to avoid cereal compilation issues on iOS/MacOS when check() macro is defined.
#ifdef __APPLE__
#define __ASSERT_MACROS_DEFINE_VERSIONS_WITHOUT_UNDERSCORES 0
#endif

#include "../alohalytics.h"
#include "../http_client.h"
#include "../logger.h"
#include "../event_base.h"

#include "../cereal/include/archives/binary.hpp"
#include "../cereal/include/types/string.hpp"
#include "../cereal/include/types/map.hpp"

#define LOG_IF_DEBUG(...)                   \
  if (debug_mode_) {                        \
    alohalytics::Logger().Log(__VA_ARGS__); \
  }

namespace alohalytics {

// Used for cereal smart-pointers polymorphic serialization.
struct NoOpDeleter {
  template <typename T>
  void operator()(T*) {}
};

// Use alohalytics::Stats::Instance() to access statistics engine.
Stats::Stats() : message_queue_(*this) {}

bool Stats::UploadBuffer(const std::string& url, std::string&& buffer, bool debug_mode) {
  HTTPClientPlatformWrapper request(url);
  request.set_debug_mode(debug_mode);
  request.set_post_body(std::move(buffer), "application/alohalytics-binary-blob");

  try {
    return request.RunHTTPRequest() && 200 == request.error_code() && !request.was_redirected();
  } catch (const std::exception& ex) {
    if (debug_mode) {
      ALOG("Exception while trying to upload file", ex.what());
    }
  }
  return false;
}

// Processes messages passed from UI in message queue's own thread.
// TODO(AlexZ): Refactor message queue to make this method private.
void Stats::OnMessage(const std::string& message, size_t dropped_events) {
  if (dropped_events) {
    LOG_IF_DEBUG("Warning:", dropped_events, "were dropped from the queue.");
  }
  if (file_storage_queue_) {
    file_storage_queue_->PushMessage(message);
  } else {
    auto& container = memory_storage_;
    container.push_back(message);
    static const size_t kMaxEventsInMemory = 2048;
    if (container.size() > kMaxEventsInMemory) {
      container.pop_front();
    }
  }
}

// Called by file storage engine to upload file with collected data.
// Should return true if upload has been successful.
// TODO(AlexZ): Refactor FSQ to make this method private.
bool Stats::OnFileReady(const std::string& full_path_to_file) {
  if (upload_url_.empty()) {
    LOG_IF_DEBUG("Warning: upload server url was not set and file", full_path_to_file, "was not uploaded.");
    return false;
  }
  if (unique_client_id_event_.empty()) {
    LOG_IF_DEBUG("Warning: unique client ID is not set so statistics was not uploaded.");
    return false;
  }
  // TODO(AlexZ): Refactor to use crossplatform and safe/non-throwing version.
  const uint64_t file_size = bricks::FileSystem::GetFileSize(full_path_to_file);
  if (0 == file_size) {
    LOG_IF_DEBUG("ERROR: Trying to upload file of size 0?", full_path_to_file);
    return false;
  }

  LOG_IF_DEBUG("Trying to upload statistics file", full_path_to_file, "to", upload_url_);

  // Append unique installation id in the beginning of each file sent to the server.
  // It can be empty so all stats data will become anonymous.
  // TODO(AlexZ): Refactor fsq to silently add it in the beginning of each file
  // and to avoid not-enough-memory situation for bigger files.
  std::ifstream fi(full_path_to_file, std::ifstream::in | std::ifstream::binary);
  std::string buffer(unique_client_id_event_);
  const size_t id_size = unique_client_id_event_.size();
  buffer.resize(id_size + static_cast<std::string::size_type>(file_size));
  fi.read(&buffer[id_size], static_cast<std::streamsize>(file_size));
  if (fi.good()) {
    fi.close();
    return UploadBuffer(upload_url_, std::move(buffer), debug_mode_);
  } else {
    LOG_IF_DEBUG("Can't load file with size", file_size, "into memory");
  }
  return false;
}

Stats& Stats::Instance() {
  static Stats alohalytics;
  return alohalytics;
}

// Easier integration if enabled.
Stats& Stats::SetDebugMode(bool enable) {
  debug_mode_ = enable;
  LOG_IF_DEBUG("Enabled debug mode.");
  return *this;
}

// If not set, collected data will never be uploaded.
Stats& Stats::SetServerUrl(const std::string& url_to_upload_statistics_to) {
  upload_url_ = url_to_upload_statistics_to;
  LOG_IF_DEBUG("Set upload url:", url_to_upload_statistics_to);
  return *this;
}

// If not set, data will be stored in memory only.
Stats& Stats::SetStoragePath(const std::string& full_path_to_storage_with_a_slash_at_the_end) {
  LOG_IF_DEBUG("Set storage path:", full_path_to_storage_with_a_slash_at_the_end);
  auto& fsq = file_storage_queue_;
  fsq.reset(nullptr);
  if (!full_path_to_storage_with_a_slash_at_the_end.empty()) {
    fsq.reset(new TFileStorageQueue(*this, full_path_to_storage_with_a_slash_at_the_end));
    if (debug_mode_) {
      const TFileStorageQueue::Status status = fsq->GetQueueStatus();
      LOG_IF_DEBUG("Active file size:", status.appended_file_size);
      const size_t count = status.finalized.queue.size();
      if (count) {
        LOG_IF_DEBUG(count, "files with total size of", status.finalized.total_size,
                     "bytes are waiting for upload.");
      }
    }
    const size_t memory_events_count = memory_storage_.size();
    if (memory_events_count) {
      LOG_IF_DEBUG("Save", memory_events_count, "in-memory events into the file storage.");
      for (const auto& msg : memory_storage_) {
        fsq->PushMessage(msg);
      }
      memory_storage_.clear();
    }
  }
  return *this;
}

// If not set, data will be uploaded without any unique id.
Stats& Stats::SetClientId(const std::string& unique_client_id) {
  LOG_IF_DEBUG("Set unique client id:", unique_client_id);
  if (unique_client_id.empty()) {
    unique_client_id_event_.clear();
  } else {
    AlohalyticsIdEvent event;
    event.id = unique_client_id;
    std::ostringstream sstream;
    { cereal::BinaryOutputArchive(sstream) << std::unique_ptr<AlohalyticsBaseEvent, NoOpDeleter>(&event); }
    unique_client_id_event_ = sstream.str();
  }
  return *this;
}

static inline void LogEventImpl(AlohalyticsBaseEvent const& event, MessageQueue<Stats>& msq) {
  std::ostringstream sstream;
  {
    // unique_ptr is used to correctly serialize polymorphic types.
    cereal::BinaryOutputArchive(sstream) << std::unique_ptr<AlohalyticsBaseEvent const, NoOpDeleter>(&event);
  }
  msq.PushMessage(std::move(sstream.str()));
}

void Stats::LogEvent(std::string const& event_name) {
  LOG_IF_DEBUG("LogEvent:", event_name);
  AlohalyticsKeyEvent event;
  event.key = event_name;
  LogEventImpl(event, message_queue_);
}

void Stats::LogEvent(std::string const& event_name, Location const& location) {
  LOG_IF_DEBUG("LogEvent:", event_name, location.ToDebugString());
  AlohalyticsKeyLocationEvent event;
  event.key = event_name;
  event.location = location;
  LogEventImpl(event, message_queue_);
}

void Stats::LogEvent(std::string const& event_name, std::string const& event_value) {
  LOG_IF_DEBUG("LogEvent:", event_name, "=", event_value);
  AlohalyticsKeyValueEvent event;
  event.key = event_name;
  event.value = event_value;
  LogEventImpl(event, message_queue_);
}

void Stats::LogEvent(std::string const& event_name, std::string const& event_value, Location const& location) {
  LOG_IF_DEBUG("LogEvent:", event_name, "=", event_value, location.ToDebugString());
  AlohalyticsKeyValueLocationEvent event;
  event.key = event_name;
  event.value = event_value;
  event.location = location;
  LogEventImpl(event, message_queue_);
}

void Stats::LogEvent(std::string const& event_name, TStringMap const& value_pairs) {
  LOG_IF_DEBUG("LogEvent:", event_name, "=", value_pairs);
  AlohalyticsKeyPairsEvent event;
  event.key = event_name;
  event.pairs = value_pairs;
  LogEventImpl(event, message_queue_);
}

void Stats::LogEvent(std::string const& event_name, TStringMap const& value_pairs, Location const& location) {
  LOG_IF_DEBUG("LogEvent:", event_name, "=", value_pairs, location.ToDebugString());
  AlohalyticsKeyPairsLocationEvent event;
  event.key = event_name;
  event.pairs = value_pairs;
  event.location = location;
  LogEventImpl(event, message_queue_);
}

// Forcedly tries to upload all stored data to the server.
void Stats::Upload() {
  if (upload_url_.empty()) {
    LOG_IF_DEBUG("Warning: upload server url is not set, nothing was uploaded.");
    return;
  }
  if (unique_client_id_event_.empty()) {
    LOG_IF_DEBUG("Warning: unique client ID is not set so statistics was not uploaded.");
    return;
  }
  LOG_IF_DEBUG("Forcing statistics uploading.");
  if (file_storage_queue_) {
    file_storage_queue_->ForceProcessing(true);
  } else {
    std::string buffer = unique_client_id_event_;
    // TODO(AlexZ): thread-safety?
    TMemoryContainer copy;
    copy.swap(memory_storage_);
    for (const auto& evt : copy) {
      buffer.append(evt);
    }
    LOG_IF_DEBUG("Forcing in-memory statistics uploading.");
    if (!UploadBuffer(upload_url_, std::move(buffer), debug_mode_)) {
      // If failed, merge events we tried to upload with possible new ones.
      memory_storage_.splice(memory_storage_.end(), std::move(copy));
    }
  }
}

}  // namespace alohalytics
<|endoftext|>


<commit_before>////////////////////////////////////////////////////////////////////////
//
// AliTPCTracking.C
//
// date: 22.08.2002
// author: Jiri Chudoba based on code of Jourij Belikov
// version: 1.0
// description:
//      reconstructs of tracks in TPC inthe following steps:
//         TPC cluster finding
//         TPC track finding
// input parameters:
//        Int_t nEvents      ... nr of events to process
//        Int_t firstEventNr ... first event number (starts from 0)
//        TString fileNameHits ... name of file with hits
//        TString fileNameDigits .. name of file with TPC digits
//        TString fileNameClusters .. name of file with TPC clusters (output)
//        TString fileNameTracks .. name of file with TPC tracks (output)
//
//        default file names correspond to pp production (2002-04)
//
// History:
//
//     20.11.2002 ... Changes due to a changed interface of AliTPCtracker.
//                    Use Riostream.h instead of iostream.h
//
//     22.08.2002 ... first version
//
////////////////////////////////////////////////////////////////////////

#if !defined(__CINT__) || defined(__MAKECINT__)
#include "Riostream.h"
#include "TTree.h"
#include "TSystem.h"
#include "TArrayF.h"
#include "TPC/alles.h"
#include "TPC/AliTPCtracker.h"
#include "TPC/AliTPCclusterer.h"
#include "STEER/AliRun.h"
#include "STEER/AliHeader.h"
#include "STEER/AliGenEventHeader.h"
#include "STEER/AliMagF.h"

#endif

Int_t gDEBUG = 2;

Int_t TPCFindClusters(Int_t nEvents=1, Int_t firstEvent=0,
		      TString fileNameDigits="rfio:galiceSDR.root",
		      TString fileNameClusters="tpc.clusters.root");
Int_t TPCFindClusters(Int_t nEvents, Int_t firstEvent,
		      TFile* fileDigits, TFile* fileClusters,
		      AliTPCParam* paramTPC=0);
Int_t TPCFindTracks(Int_t nEvents=1, Int_t firstEvent=0,
		    TString fileNameClusters="tpc.clusters.root",
		    TString fileNameTracks="tpc.tracks.root");
Int_t TPCFindTracks(Int_t nEvents, Int_t firstEvent,
		    TFile* fileClusters, TFile* fileTracks,
		    AliTPCParam* paramTPC=0);

AliTPCParam* LoadTPCParam(TFile *file);
void FindVertex(Int_t iEvent, Double_t *vertex);
void PrintVertex(TArrayF &primaryVertex);
Int_t SetFieldFactor(TString fileName, Bool_t closeFile = kTRUE);
Int_t SetFieldFactor(TFile* file, Bool_t deletegAlice = kTRUE);
Int_t SetFieldFactor();

Int_t AliTPCTracking(Int_t nEvents=1, Int_t firstEvent=0,
		     TString fileNameHits="rfio:galice.root",
		     TString fileNameDigits="rfio:galiceSDR.root",
		     TString fileNameClusters="tpc.clusters.root",
		     TString fileNameTracks="tpc.tracks.root");

////////////////////////////////////////////////////////////////////////
Int_t AliTPCTracking( Int_t nEvents, Int_t firstEvent,
		      TString fileNameHits,
		      TString fileNameDigits,
		      TString fileNameClusters,
		      TString fileNameTracks) {

  SetFieldFactor(fileNameHits,kFALSE);

// ********** Find TPC clusters *********** //
  if (TPCFindClusters(nEvents,firstEvent,fileNameDigits,fileNameClusters)) {
    cerr<<"Failed to get TPC clusters: !\n";
    return 1;
  }

// ********** Find TPC tracks *********** //
  if (TPCFindTracks(nEvents,firstEvent,fileNameClusters,fileNameTracks)) {
    cerr<<"Failed to get TPC tracks !\n";
    return 2;
  }

  return 0;
}

////////////////////////////////////////////////////////////////////////
Int_t TPCFindClusters(Int_t nEvents, Int_t firstEvent,
		      TString fileNameDigits, TString fileNameClusters) {

  Int_t rc;
  const Char_t *name="TPCFindClusters";
  if (gDEBUG>1) cout<<name<<" starts...\n";
  if (gDEBUG>1) gBenchmark->Start(name);
  TFile *fileClusters = TFile::Open(fileNameClusters,"recreate");
  TFile *fileDigits = TFile::Open(fileNameDigits);
  if (!fileDigits->IsOpen()) {
    cerr<<"Cannnot open "<<fileNameDigits<<" !\n";
    return 1;
  }
  if (!fileClusters->IsOpen()) {
    cerr<<"Cannnot open "<<fileNameClusters<<" !\n";
    return 1;
  }

  rc = TPCFindClusters(nEvents,firstEvent,fileDigits,fileClusters);

  fileDigits->Close();
  fileClusters->Close();
  delete fileDigits;
  delete fileClusters;
  if (gDEBUG>1) gBenchmark->Stop(name);
  if (gDEBUG>1) gBenchmark->Show(name);

  return rc;
}
////////////////////////////////////////////////////////////////////////
Int_t TPCFindClusters(Int_t nEvents, Int_t firstEvent,
		      TFile* fileDigits, TFile* fileClusters,
		      AliTPCParam* paramTPC) {

  fileDigits->cd();
  if (!paramTPC) paramTPC = LoadTPCParam(fileDigits);
  if (!paramTPC) return 1;

  for (Int_t iEvent = firstEvent; iEvent < firstEvent+nEvents; iEvent++){
    if (gDEBUG > 2) cout<<"TPCFindClusters: event "<<iEvent<<endl;
    AliTPCclusterer::Digits2Clusters(paramTPC, fileClusters, iEvent);
  }
  return 0;
}
////////////////////////////////////////////////////////////////////////
Int_t TPCFindTracks(Int_t nEvents, Int_t firstEvent,
		    TString fileNameClusters, TString fileNameTracks) {

  Int_t rc = 0;
  const Char_t *name="TPCFindTracks";
  if (gDEBUG>1) cout<<name<<" starts"<<endl;
  if (gDEBUG>1) gBenchmark->Start(name);
  TFile *fileTracks = TFile::Open(fileNameTracks,"recreate");
  TFile *fileClusters =TFile::Open(fileNameClusters);

  rc = TPCFindTracks(nEvents, firstEvent, fileClusters, fileTracks);

  fileClusters->Close();
  fileTracks->Close();
  delete fileClusters;
  delete fileTracks;
  if (gDEBUG>1) gBenchmark->Stop(name);
  if (gDEBUG>1) gBenchmark->Show(name);
  return rc;

}
////////////////////////////////////////////////////////////////////////
Int_t TPCFindTracks(Int_t nEvents, Int_t firstEvent,
		    TFile *fileClusters, TFile * fileTracks,
		    AliTPCParam* paramTPC) {

  Int_t rc = 0;
  if (!paramTPC) paramTPC = LoadTPCParam(fileClusters);
  if (!paramTPC) return 1;

  for (Int_t iEvent = firstEvent; iEvent < firstEvent+nEvents; iEvent++){
    if (gDEBUG > 2) cout<<"TPCFindTracks: event "<<iEvent<<endl;
    AliTPCtracker *tracker = new AliTPCtracker(paramTPC);
    tracker->SetEventNumber(iEvent);
    Double_t vertex[3];
    FindVertex(iEvent,vertex);
    tracker->SetVertex(vertex);
    fileClusters->cd();
    rc = tracker->Clusters2Tracks(0,fileTracks);
    delete tracker;
  }
  return rc;
}

////////////////////////////////////////////////////////////////////////
Int_t SetFieldFactor() {

   AliKalmanTrack::SetConvConst(1000/0.299792458/gAlice->Field()->SolenoidField());
   if (gDEBUG > 2) cout<<"Magnetic field in kGauss: "<<gAlice->Field()->SolenoidField()<<endl;
   return 0;
}
////////////////////////////////////////////////////////////////////////
Int_t SetFieldFactor(TFile *file, Bool_t deletegAlice) {

  if (!(gAlice=(AliRun*)file->Get("gAlice"))) {
    cerr<<"gAlice has not been found in file "<<file->GetName();
    return 1;
  }
  Int_t rc = SetFieldFactor();
  if (deletegAlice) {
    delete gAlice;
    gAlice = 0;
  }
  return rc;
}
////////////////////////////////////////////////////////////////////////
Int_t SetFieldFactor(TString fileName, Bool_t closeFile) {

   TFile *file=TFile::Open(fileName);
   if (!file->IsOpen()) {cerr<<"Cannnot open "<<fileName<<" !\n"; return 1;}
   Int_t rc = SetFieldFactor(file, closeFile) ;
   if (closeFile) file->Close();
   return rc;
}
////////////////////////////////////////////////////////////////////////
AliTPCParam* LoadTPCParam(TFile *file) {

  char paramName[50];
  sprintf(paramName,"75x40_100x60_150x60");
  AliTPCParam *paramTPC=(AliTPCParam*)file->Get(paramName);
  if (paramTPC) {
    if (gDEBUG > 1) cout<<"TPC parameters "<<paramName<<" found."<<endl;
  } else {
    cerr<<"TPC parameters not found. Create new (they may be incorrect)."
	<<endl;
    paramTPC = new AliTPCParamSR;
  }
  return paramTPC;

// the older version of parameters can be accessed with this code.
// In some cases, we have old parameters saved in the file but
// digits were created with new parameters, it can be distinguish
// by the name of TPC TreeD. The code here is just for the case
// we would need to compare with old data, uncomment it if needed.
//
//  char paramName[50];
//  sprintf(paramName,"75x40_100x60");
//  AliTPCParam *paramTPC=(AliTPCParam*)in->Get(paramName);
//  if (paramTPC) {
//    cout<<"TPC parameters "<<paramName<<" found."<<endl;
//  } else {
//    sprintf(paramName,"75x40_100x60_150x60");
//    paramTPC=(AliTPCParam*)in->Get(paramName);
//    if (paramTPC) {
//	cout<<"TPC parameters "<<paramName<<" found."<<endl;
//    } else {
//	cerr<<"TPC parameters not found. Create new (they may be incorrect)."
//	    <<endl;
//	paramTPC = new AliTPCParamSR;
//    }
//  }
//  return paramTPC;

}

////////////////////////////////////////////////////////////////////////
void FindVertex(Int_t eventNr, Double_t *vertex) {

  vertex[0] = vertex[1] = vertex[2] = 0.;
  if (!gAlice) {
    cerr<<"gAlice was not found! Using vertex position (0,0,0).\n";
    return;
  }

  gAlice->GetEvent(eventNr);
  AliHeader *header = gAlice->GetHeader();
  if (!header) {
    cerr<<"header was not found!\n";
    return;
  }
  AliGenEventHeader* genEventHeader = header->GenEventHeader();
  if (!genEventHeader) {
    cerr<<"AliGenEventHeader was not found!\n";
    return;
  }

  TArrayF primaryVertex(3);
  genEventHeader->PrimaryVertex(primaryVertex);
  PrintVertex(primaryVertex);
  vertex[0] = static_cast<Double_t>(primaryVertex[0]);
  vertex[1] = static_cast<Double_t>(primaryVertex[1]);
  vertex[2] = static_cast<Double_t>(primaryVertex[2]);
//  delete header;
  delete genEventHeader;
  return;

}
////////////////////////////////////////////////////////////////////////
void PrintVertex(TArrayF &primaryVertex)
{
  cout <<"Vertex: "
       <<primaryVertex[0]<<" "
       <<primaryVertex[1]<<" "
       <<primaryVertex[2]<<" "<<endl;
  exit;
}
////////////////////////////////////////////////////////////////////////
<commit_msg>Updated by J. Chudoba<commit_after>////////////////////////////////////////////////////////////////////////
//
// AliTPCTracking.C
//
// date: 22.08.2002
// author: Jiri Chudoba based on code of Jourij Belikov
// version: 1.0
// description:
//      reconstructs of tracks in TPC inthe following steps:
//         TPC cluster finding
//         TPC track finding
// input parameters:
//        Int_t nEvents      ... nr of events to process
//        Int_t firstEventNr ... first event number (starts from 0)
//        Char_t* fileNameHits ... name of file with hits
//        Char_t* fileNameDigits .. name of file with TPC digits
//        Char_t* fileNameClusters .. name of file with TPC clusters (output)
//        Char_t* fileNameTracks .. name of file with TPC tracks (output)
//
//        default file names correspond to pp production (2002-04)
//
// History:
//
//     03.03.2003 ... SetFieldFactor moved to AliTracker class and
//                    LoadTPCParam moved to AliTPC class
//                    TString replaced by Char_t*
//
//     20.11.2002 ... Changes due to a changed interface of AliTPCtracker.
//                    Use Riostream.h instead of iostream.h
//
//     22.08.2002 ... first version
//
////////////////////////////////////////////////////////////////////////

#if !defined(__CINT__) || defined(__MAKECINT__)
#include "Riostream.h"
#include "TTree.h"
#include "TSystem.h"
#include "TArrayF.h"
#include "TPC/alles.h"
#include "TPC/AliTPCtracker.h"
#include "TPC/AliTPCclusterer.h"
#include "TPC/AliTPC.h"
#include "STEER/AliRun.h"
#include "STEER/AliHeader.h"
#include "STEER/AliGenEventHeader.h"
#include "STEER/AliMagF.h"
#include "STEER/AliTracker.h"

#endif

Int_t gDEBUG = 2;

Int_t TPCFindClusters(Int_t nEvents=1, Int_t firstEvent=0,
		      Char_t* fileNameDigits="rfio:galiceSDR.root",
		      Char_t* fileNameClusters="tpc.clusters.root");
Int_t TPCFindClusters(Int_t nEvents, Int_t firstEvent,
		      TFile* fileDigits, TFile* fileClusters,
		      AliTPCParam* paramTPC=0);
Int_t TPCFindTracks(Int_t nEvents=1, Int_t firstEvent=0,
		    Char_t* fileNameClusters="tpc.clusters.root",
		    Char_t* fileNameTracks="tpc.tracks.root");
Int_t TPCFindTracks(Int_t nEvents, Int_t firstEvent,
		    TFile* fileClusters, TFile* fileTracks,
		    AliTPCParam* paramTPC=0);

void FindVertex(Int_t iEvent, Double_t *vertex);
void PrintVertex(TArrayF &primaryVertex);

Int_t AliTPCTracking(Int_t nEvents=1, Int_t firstEvent=0,
		     Char_t* fileNameHits="rfio:galice.root",
		     Char_t* fileNameDigits="rfio:galiceSDR.root",
		     Char_t* fileNameClusters="tpc.clusters.root",
		     Char_t* fileNameTracks="tpc.tracks.root");

////////////////////////////////////////////////////////////////////////
Int_t AliTPCTracking( Int_t nEvents, Int_t firstEvent,
		      Char_t* fileNameHits,
		      Char_t* fileNameDigits,
		      Char_t* fileNameClusters,
		      Char_t* fileNameTracks) {

  AliTracker::SetFieldFactor(fileNameHits,kFALSE);

// ********** Find TPC clusters *********** //
  if (TPCFindClusters(nEvents,firstEvent,fileNameDigits,fileNameClusters)) {
    cerr<<"Failed to get TPC clusters: !\n";
    return 1;
  }

// ********** Find TPC tracks *********** //
  if (TPCFindTracks(nEvents,firstEvent,fileNameClusters,fileNameTracks)) {
    cerr<<"Failed to get TPC tracks !\n";
    return 2;
  }

  return 0;
}

////////////////////////////////////////////////////////////////////////
Int_t TPCFindClusters(Int_t nEvents, Int_t firstEvent,
		      Char_t* fileNameDigits, Char_t* fileNameClusters) {

  Int_t rc;
  const Char_t *name="TPCFindClusters";
  if (gDEBUG>1) cout<<name<<" starts...\n";
  if (gDEBUG>1) gBenchmark->Start(name);
  TFile *fileClusters = TFile::Open(fileNameClusters,"recreate");
  TFile *fileDigits = TFile::Open(fileNameDigits);
  if (!fileDigits->IsOpen()) {
    cerr<<"Cannnot open "<<fileNameDigits<<" !\n";
    return 1;
  }
  if (!fileClusters->IsOpen()) {
    cerr<<"Cannnot open "<<fileNameClusters<<" !\n";
    return 1;
  }

  rc = TPCFindClusters(nEvents,firstEvent,fileDigits,fileClusters);

  fileDigits->Close();
  fileClusters->Close();
  delete fileDigits;
  delete fileClusters;
  if (gDEBUG>1) gBenchmark->Stop(name);
  if (gDEBUG>1) gBenchmark->Show(name);

  return rc;
}
////////////////////////////////////////////////////////////////////////
Int_t TPCFindClusters(Int_t nEvents, Int_t firstEvent,
		      TFile* fileDigits, TFile* fileClusters,
		      AliTPCParam* paramTPC) {

  fileDigits->cd();
  if (!paramTPC) paramTPC = AliTPC::LoadTPCParam(fileDigits);
  if (!paramTPC) return 1;

  for (Int_t iEvent = firstEvent; iEvent < firstEvent+nEvents; iEvent++){
    if (gDEBUG > 2) cout<<"TPCFindClusters: event "<<iEvent<<endl;
    AliTPCclusterer::Digits2Clusters(paramTPC, fileClusters, iEvent);
  }
  return 0;
}
////////////////////////////////////////////////////////////////////////
Int_t TPCFindTracks(Int_t nEvents, Int_t firstEvent,
		    Char_t* fileNameClusters, Char_t* fileNameTracks) {

  Int_t rc = 0;
  const Char_t *name="TPCFindTracks";
  if (gDEBUG>1) cout<<name<<" starts"<<endl;
  if (gDEBUG>1) gBenchmark->Start(name);
  TFile *fileTracks = TFile::Open(fileNameTracks,"recreate");
  TFile *fileClusters =TFile::Open(fileNameClusters);

  rc = TPCFindTracks(nEvents, firstEvent, fileClusters, fileTracks);

  fileClusters->Close();
  fileTracks->Close();
  delete fileClusters;
  delete fileTracks;
  if (gDEBUG>1) gBenchmark->Stop(name);
  if (gDEBUG>1) gBenchmark->Show(name);
  return rc;

}
////////////////////////////////////////////////////////////////////////
Int_t TPCFindTracks(Int_t nEvents, Int_t firstEvent,
		    TFile *fileClusters, TFile * fileTracks,
		    AliTPCParam* paramTPC) {

  Int_t rc = 0;
  if (!paramTPC) paramTPC = AliTPC::LoadTPCParam(fileClusters);
  if (!paramTPC) return 1;

  for (Int_t iEvent = firstEvent; iEvent < firstEvent+nEvents; iEvent++){
    if (gDEBUG > 2) cout<<"TPCFindTracks: event "<<iEvent<<endl;
    AliTPCtracker *tracker = new AliTPCtracker(paramTPC);
    tracker->SetEventNumber(iEvent);
    Double_t vertex[3];
    FindVertex(iEvent,vertex);
    tracker->SetVertex(vertex);
    fileClusters->cd();
    rc = tracker->Clusters2Tracks(0,fileTracks);
    delete tracker;
  }
  return rc;
}

////////////////////////////////////////////////////////////////////////
void FindVertex(Int_t eventNr, Double_t *vertex) {

  vertex[0] = vertex[1] = vertex[2] = 0.;
  if (!gAlice) {
    cerr<<"gAlice was not found! Using vertex position (0,0,0).\n";
    return;
  }

  gAlice->GetEvent(eventNr);
  AliHeader *header = gAlice->GetHeader();
  if (!header) {
    cerr<<"header was not found!\n";
    return;
  }
  AliGenEventHeader* genEventHeader = header->GenEventHeader();
  if (!genEventHeader) {
    cerr<<"AliGenEventHeader was not found!\n";
    return;
  }

  TArrayF primaryVertex(3);
  genEventHeader->PrimaryVertex(primaryVertex);
  PrintVertex(primaryVertex);
  vertex[0] = static_cast<Double_t>(primaryVertex[0]);
  vertex[1] = static_cast<Double_t>(primaryVertex[1]);
  vertex[2] = static_cast<Double_t>(primaryVertex[2]);
//  delete header;
  delete genEventHeader;
  return;

}
////////////////////////////////////////////////////////////////////////
void PrintVertex(TArrayF &primaryVertex)
{
  cout <<"Vertex: "
       <<primaryVertex[0]<<" "
       <<primaryVertex[1]<<" "
       <<primaryVertex[2]<<" "<<endl;
  exit;
}
////////////////////////////////////////////////////////////////////////
<|endoftext|>


<commit_before>// @(#)root/histpainter:$Name:  $:$Id: TPaletteAxis.cxx,v 1.6 2003/01/13 13:53:55 brun Exp $
// Author: Rene Brun   15/11/2002

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Riostream.h"
#include "TROOT.h"
#include "TPaletteAxis.h"
#include "TVirtualPad.h"
#include "TStyle.h"
#include "TClass.h"
#include "TMath.h"
#include "TView.h"

ClassImp(TPaletteAxis)

//______________________________________________________________________________
//
// a TPaletteAxis object is used to display the color palette when
// drawing 2-d histograms.
// The object is automatically created when drawing a 2-D histogram
// when the option "z" is specified.
// The object is added to the histogram list of functions and can be retrieved
// and its attributes changed with:
//  TPaletteAxis *palette = (TPaletteAxis*)h->GetListOfFunctions()->FindObject("palette");
//
// The palette can be interactively moved and resized. The context menu
// can be used to set the axis attributes.
//
// It is possible to select a range on the axis to set the min/max in z
//
//Begin_Html
/*

*/
//End_Html
//

//______________________________________________________________________________
TPaletteAxis::TPaletteAxis(): TPave()
{
// palette default constructor

   fH  = 0;
   SetName("");
}

//______________________________________________________________________________
TPaletteAxis::TPaletteAxis(Double_t x1, Double_t y1,Double_t x2, Double_t  y2, TH1 *h)
       :TPave(x1,y1,x2,y2)
{
// palette normal constructor

   fH = h;
   SetName("palette");
   TAxis *zaxis = fH->GetZaxis();
   fAxis.ImportAxisAttributes(zaxis);
   if (gPad->GetView()) SetBit(kHasView);
}

//______________________________________________________________________________
TPaletteAxis::~TPaletteAxis()
{
   if (fH) fH->GetListOfFunctions()->Remove(this);
}

//______________________________________________________________________________
TPaletteAxis::TPaletteAxis(const TPaletteAxis &palette) : TPave(palette)
{
   ((TPaletteAxis&)palette).Copy(*this);
}

//______________________________________________________________________________
void TPaletteAxis::Copy(TObject &obj) const
{
//*-*-*-*-*-*-*-*-*-*-*Copy this pave to pave*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ======================

   TPave::Copy(obj);
   ((TPaletteAxis&)obj).fH    = fH;
   ((TPaletteAxis&)obj).fName = fName;
}

//______________________________________________________________________________
Int_t TPaletteAxis::DistancetoPrimitive(Int_t px, Int_t py)
{
   //check if mouse on the axis region
   Int_t plxmax = gPad->XtoAbsPixel(fX2);
   Int_t plymin = gPad->YtoAbsPixel(fY1);
   Int_t plymax = gPad->YtoAbsPixel(fY2);
   if (px > plxmax && px < plxmax+30 && py >= plymax &&py <= plymin) return px-plxmax;

   //otherwise check if inside the box
   return TPave::DistancetoPrimitive(px,py);
}

//______________________________________________________________________________
void TPaletteAxis::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   //check if mouse on the axis region
   static Int_t kmode = 0;
   Int_t plxmin = gPad->XtoAbsPixel(fX1);
   Int_t plxmax = gPad->XtoAbsPixel(fX2);
   if (kmode != 0 || px <= plxmax) {
      if (event == kButton1Down) kmode = 1;
      TBox::ExecuteEvent(event,px,py);
      if (event == kButton1Up) kmode = 0;
//*-* In case pave coordinates have been modified, recompute NDC coordinates
      Double_t dpx  = gPad->GetX2() - gPad->GetX1();
      Double_t dpy  = gPad->GetY2() - gPad->GetY1();
      Double_t xp1  = gPad->GetX1();
      Double_t yp1  = gPad->GetY1();
      fX1NDC = (fX1-xp1)/dpx;
      fY1NDC = (fY1-yp1)/dpy;
      fX2NDC = (fX2-xp1)/dpx;
      fY2NDC = (fY2-yp1)/dpy;
      return;
   }
   gPad->SetCursor(kHand);
   static Double_t ratio1, ratio2;
   static Int_t px1old, py1old, px2old, py2old;
   Double_t temp, xmin,xmax;

   switch (event) {

   case kButton1Down:
      ratio1 = (gPad->AbsPixeltoY(py) - fY1)/(fY2 - fY1);
      py1old = gPad->YtoAbsPixel(fY1+ratio1*(fY2 - fY1));
      px1old = plxmin;
      px2old = plxmax;
      py2old = py1old;
      gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
      gVirtualX->SetLineColor(-1);
      // No break !!!

   case kButton1Motion:
      gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
      ratio2 = (gPad->AbsPixeltoY(py) - fY1)/(fY2 - fY1);
      py2old = gPad->YtoAbsPixel(fY1+ratio2*(fY2 - fY1));
      gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
      break;

   case kButton1Up:
      ratio2 = (gPad->AbsPixeltoY(py) - fY1)/(fY2 - fY1);
      xmin = ratio1;
      xmax = ratio2;
      if (xmin > xmax) {
         temp   = xmin;
         xmin   = xmax;
         xmax   = temp;
         temp   = ratio1;
         ratio1 = ratio2;
         ratio2 = temp;
      }
      if (ratio2 - ratio1 > 0.05) {
         if (fH->GetDimension() == 2) {
            Double_t zmin = fH->GetMinimum();
            Double_t zmax = fH->GetMaximum();
            Double_t newmin = zmin + (zmax-zmin)*ratio1;
            Double_t newmax = zmin + (zmax-zmin)*ratio2;
            if(newmin < zmin)newmin = fH->GetBinContent(fH->GetMinimumBin());
            if(newmax > zmax)newmax = fH->GetBinContent(fH->GetMaximumBin());
            fH->SetMinimum(newmin);
            fH->SetMaximum(newmax);
            fH->SetBit(TH1::kIsZoomed);
         }
         gPad->Modified(kTRUE);
      }
      gVirtualX->SetLineColor(-1);
      kmode = 0;
      break;
   }
}

//______________________________________________________________________________
char *TPaletteAxis::GetObjectInfo(Int_t /* px */, Int_t py) const
{
//   Redefines TObject::GetObjectInfo.
//   Displays the z value corresponding to cursor position py
//
   Double_t z;
   static char info[64];

   Double_t zmin = fH->GetMinimum();
   Double_t zmax = fH->GetMaximum();
   Int_t   y1   = gPad->GetWh()-gPad->VtoPixel(fY1NDC);
   Int_t   y2   = gPad->GetWh()-gPad->VtoPixel(fY2NDC);
   Int_t   y    = gPad->GetWh()-py;

   if (gPad->GetLogz()) {
      if (zmin <= 0 && zmax > 0) zmin = 0.001*zmax;
      Double_t zminl = TMath::Log10(zmin);
      Double_t zmaxl = TMath::Log10(zmax);
      Double_t zl    = (zmaxl-zminl)*((Double_t)(y-y1)/(Double_t)(y2-y1))+zminl;
      z = TMath::Power(10.,zl);
   } else {
      z = (zmax-zmin)*((Double_t)(y-y1)/(Double_t)(y2-y1))+zmin;
   }

   sprintf(info,"(z=%g)",z);
   return info;
}

//______________________________________________________________________________
void TPaletteAxis::Paint(Option_t *)
{

   ConvertNDCtoPad();

   SetFillStyle(1001);
   Double_t ymin = fY1;
   Double_t ymax = fY2;
   Double_t xmin = fX1;
   Double_t xmax = fX2;
   Double_t wmin = fH->GetMinimum();
   Double_t wmax = fH->GetMaximum();
   Double_t wlmin = wmin;
   Double_t wlmax = wmax;
   Double_t y1,y2,w1,w2,zc;
   if (gPad->GetLogz()) {
      if (wmin <= 0 && wmax > 0) wmin = 0.001*wmax;
      wlmin = TMath::Log10(wmin);
      wlmax = TMath::Log10(wmax);
   }
   Double_t ws    = wlmax-wlmin;
   Int_t ncolors = gStyle->GetNumberOfColors();
   Int_t ndivz = TMath::Abs(fH->GetContour());
   Int_t theColor,color;
   Double_t scale = ndivz/(wlmax - wlmin);
   for (Int_t i=0;i<ndivz;i++) {

      zc = fH->GetContourLevel(i);
      if (fH->TestBit(TH1::kUserContour) && gPad->GetLogz())
         zc = TMath::Log10(zc);
      w1 = zc;
      if (w1 < wlmin) w1 = wlmin;

      w2 = wlmax;
      if (i < ndivz-1) {
         zc = fH->GetContourLevel(i+1);
         if (fH->TestBit(TH1::kUserContour) && gPad->GetLogz())
            zc = TMath::Log10(zc);
         w2 = zc;
      }

      if (w2 <= wlmin) continue;
      y1 = ymin + (w1-wlmin)*(ymax-ymin)/ws;
      y2 = ymin + (w2-wlmin)*(ymax-ymin)/ws;

      if (fH->TestBit(TH1::kUserContour)) {
         color = i;
      } else {
         color = Int_t(0.01+(w1-wlmin)*scale);
      }

      theColor = Int_t((color+0.99)*Double_t(ncolors)/Double_t(ndivz));
      SetFillColor(gStyle->GetColorPalette(theColor));
      TAttFill::Modify();
      gPad->PaintBox(xmin,y1,xmax,y2);
   }
   Int_t ndiv  = fH->GetZaxis()->GetNdivisions()%100; //take primary divisions only
   char chopt[5] = "";
   chopt[0] = 0;
   strcat(chopt, "+L");
   if (ndiv < 0) {
      ndiv =TMath::Abs(ndiv);
      strcat(chopt, "N");
   }
   if (gPad->GetLogz()) {
      wmin = TMath::Power(10.,wlmin);
      wmax = TMath::Power(10.,wlmax);
      strcat(chopt, "G");
   }
   fAxis.PaintAxis(xmax,ymin,xmax,ymax,wmin,wmax,ndiv,chopt);
}

//______________________________________________________________________________
void TPaletteAxis::SavePrimitive(ofstream &, Option_t *)
{
   // Save primitive as a C++ statement(s) on output stream out.
}

//______________________________________________________________________________
void TPaletteAxis::UnZoom()
{
   TView *view = gPad->GetView();
   if (view) {
      delete view;
      gPad->SetView(0);
   }
   fH->GetZaxis()->SetRange(0,0);
   if (fH->GetDimension() == 2) {
      fH->SetMinimum();
      fH->SetMaximum();
      fH->ResetBit(TH1::kIsZoomed);
   }
}
<commit_msg>Implement TPaletteAxis::SavePrimitive (we had a dummy implementation)<commit_after>// @(#)root/histpainter:$Name:  $:$Id: TPaletteAxis.cxx,v 1.7 2003/01/13 16:57:36 brun Exp $
// Author: Rene Brun   15/11/2002

/*************************************************************************
 * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
 * All rights reserved.                                                  *
 *                                                                       *
 * For the licensing terms see $ROOTSYS/LICENSE.                         *
 * For the list of contributors see $ROOTSYS/README/CREDITS.             *
 *************************************************************************/

#include "Riostream.h"
#include "TROOT.h"
#include "TPaletteAxis.h"
#include "TVirtualPad.h"
#include "TStyle.h"
#include "TClass.h"
#include "TMath.h"
#include "TView.h"

ClassImp(TPaletteAxis)

//______________________________________________________________________________
//
// a TPaletteAxis object is used to display the color palette when
// drawing 2-d histograms.
// The object is automatically created when drawing a 2-D histogram
// when the option "z" is specified.
// The object is added to the histogram list of functions and can be retrieved
// and its attributes changed with:
//  TPaletteAxis *palette = (TPaletteAxis*)h->GetListOfFunctions()->FindObject("palette");
//
// The palette can be interactively moved and resized. The context menu
// can be used to set the axis attributes.
//
// It is possible to select a range on the axis to set the min/max in z
//
//Begin_Html
/*

*/
//End_Html
//

//______________________________________________________________________________
TPaletteAxis::TPaletteAxis(): TPave()
{
// palette default constructor

   fH  = 0;
   SetName("");
}

//______________________________________________________________________________
TPaletteAxis::TPaletteAxis(Double_t x1, Double_t y1,Double_t x2, Double_t  y2, TH1 *h)
       :TPave(x1,y1,x2,y2)
{
// palette normal constructor

   fH = h;
   SetName("palette");
   TAxis *zaxis = fH->GetZaxis();
   fAxis.ImportAxisAttributes(zaxis);
   if (gPad->GetView()) SetBit(kHasView);
}

//______________________________________________________________________________
TPaletteAxis::~TPaletteAxis()
{
   if (fH) fH->GetListOfFunctions()->Remove(this);
}

//______________________________________________________________________________
TPaletteAxis::TPaletteAxis(const TPaletteAxis &palette) : TPave(palette)
{
   ((TPaletteAxis&)palette).Copy(*this);
}

//______________________________________________________________________________
void TPaletteAxis::Copy(TObject &obj) const
{
//*-*-*-*-*-*-*-*-*-*-*Copy this pave to pave*-*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-*                  ======================

   TPave::Copy(obj);
   ((TPaletteAxis&)obj).fH    = fH;
   ((TPaletteAxis&)obj).fName = fName;
}

//______________________________________________________________________________
Int_t TPaletteAxis::DistancetoPrimitive(Int_t px, Int_t py)
{
   //check if mouse on the axis region
   Int_t plxmax = gPad->XtoAbsPixel(fX2);
   Int_t plymin = gPad->YtoAbsPixel(fY1);
   Int_t plymax = gPad->YtoAbsPixel(fY2);
   if (px > plxmax && px < plxmax+30 && py >= plymax &&py <= plymin) return px-plxmax;

   //otherwise check if inside the box
   return TPave::DistancetoPrimitive(px,py);
}

//______________________________________________________________________________
void TPaletteAxis::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
   //check if mouse on the axis region
   static Int_t kmode = 0;
   Int_t plxmin = gPad->XtoAbsPixel(fX1);
   Int_t plxmax = gPad->XtoAbsPixel(fX2);
   if (kmode != 0 || px <= plxmax) {
      if (event == kButton1Down) kmode = 1;
      TBox::ExecuteEvent(event,px,py);
      if (event == kButton1Up) kmode = 0;
//*-* In case pave coordinates have been modified, recompute NDC coordinates
      Double_t dpx  = gPad->GetX2() - gPad->GetX1();
      Double_t dpy  = gPad->GetY2() - gPad->GetY1();
      Double_t xp1  = gPad->GetX1();
      Double_t yp1  = gPad->GetY1();
      fX1NDC = (fX1-xp1)/dpx;
      fY1NDC = (fY1-yp1)/dpy;
      fX2NDC = (fX2-xp1)/dpx;
      fY2NDC = (fY2-yp1)/dpy;
      return;
   }
   gPad->SetCursor(kHand);
   static Double_t ratio1, ratio2;
   static Int_t px1old, py1old, px2old, py2old;
   Double_t temp, xmin,xmax;

   switch (event) {

   case kButton1Down:
      ratio1 = (gPad->AbsPixeltoY(py) - fY1)/(fY2 - fY1);
      py1old = gPad->YtoAbsPixel(fY1+ratio1*(fY2 - fY1));
      px1old = plxmin;
      px2old = plxmax;
      py2old = py1old;
      gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
      gVirtualX->SetLineColor(-1);
      // No break !!!

   case kButton1Motion:
      gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
      ratio2 = (gPad->AbsPixeltoY(py) - fY1)/(fY2 - fY1);
      py2old = gPad->YtoAbsPixel(fY1+ratio2*(fY2 - fY1));
      gVirtualX->DrawBox(px1old, py1old, px2old, py2old, TVirtualX::kHollow);
      break;

   case kButton1Up:
      ratio2 = (gPad->AbsPixeltoY(py) - fY1)/(fY2 - fY1);
      xmin = ratio1;
      xmax = ratio2;
      if (xmin > xmax) {
         temp   = xmin;
         xmin   = xmax;
         xmax   = temp;
         temp   = ratio1;
         ratio1 = ratio2;
         ratio2 = temp;
      }
      if (ratio2 - ratio1 > 0.05) {
         if (fH->GetDimension() == 2) {
            Double_t zmin = fH->GetMinimum();
            Double_t zmax = fH->GetMaximum();
            Double_t newmin = zmin + (zmax-zmin)*ratio1;
            Double_t newmax = zmin + (zmax-zmin)*ratio2;
            if(newmin < zmin)newmin = fH->GetBinContent(fH->GetMinimumBin());
            if(newmax > zmax)newmax = fH->GetBinContent(fH->GetMaximumBin());
            fH->SetMinimum(newmin);
            fH->SetMaximum(newmax);
            fH->SetBit(TH1::kIsZoomed);
         }
         gPad->Modified(kTRUE);
      }
      gVirtualX->SetLineColor(-1);
      kmode = 0;
      break;
   }
}

//______________________________________________________________________________
char *TPaletteAxis::GetObjectInfo(Int_t /* px */, Int_t py) const
{
//   Redefines TObject::GetObjectInfo.
//   Displays the z value corresponding to cursor position py
//
   Double_t z;
   static char info[64];

   Double_t zmin = fH->GetMinimum();
   Double_t zmax = fH->GetMaximum();
   Int_t   y1   = gPad->GetWh()-gPad->VtoPixel(fY1NDC);
   Int_t   y2   = gPad->GetWh()-gPad->VtoPixel(fY2NDC);
   Int_t   y    = gPad->GetWh()-py;

   if (gPad->GetLogz()) {
      if (zmin <= 0 && zmax > 0) zmin = 0.001*zmax;
      Double_t zminl = TMath::Log10(zmin);
      Double_t zmaxl = TMath::Log10(zmax);
      Double_t zl    = (zmaxl-zminl)*((Double_t)(y-y1)/(Double_t)(y2-y1))+zminl;
      z = TMath::Power(10.,zl);
   } else {
      z = (zmax-zmin)*((Double_t)(y-y1)/(Double_t)(y2-y1))+zmin;
   }

   sprintf(info,"(z=%g)",z);
   return info;
}

//______________________________________________________________________________
void TPaletteAxis::Paint(Option_t *)
{

   ConvertNDCtoPad();

   SetFillStyle(1001);
   Double_t ymin = fY1;
   Double_t ymax = fY2;
   Double_t xmin = fX1;
   Double_t xmax = fX2;
   Double_t wmin = fH->GetMinimum();
   Double_t wmax = fH->GetMaximum();
   Double_t wlmin = wmin;
   Double_t wlmax = wmax;
   Double_t y1,y2,w1,w2,zc;
   if (gPad->GetLogz()) {
      if (wmin <= 0 && wmax > 0) wmin = 0.001*wmax;
      wlmin = TMath::Log10(wmin);
      wlmax = TMath::Log10(wmax);
   }
   Double_t ws    = wlmax-wlmin;
   Int_t ncolors = gStyle->GetNumberOfColors();
   Int_t ndivz = TMath::Abs(fH->GetContour());
   Int_t theColor,color;
   Double_t scale = ndivz/(wlmax - wlmin);
   for (Int_t i=0;i<ndivz;i++) {

      zc = fH->GetContourLevel(i);
      if (fH->TestBit(TH1::kUserContour) && gPad->GetLogz())
         zc = TMath::Log10(zc);
      w1 = zc;
      if (w1 < wlmin) w1 = wlmin;

      w2 = wlmax;
      if (i < ndivz-1) {
         zc = fH->GetContourLevel(i+1);
         if (fH->TestBit(TH1::kUserContour) && gPad->GetLogz())
            zc = TMath::Log10(zc);
         w2 = zc;
      }

      if (w2 <= wlmin) continue;
      y1 = ymin + (w1-wlmin)*(ymax-ymin)/ws;
      y2 = ymin + (w2-wlmin)*(ymax-ymin)/ws;

      if (fH->TestBit(TH1::kUserContour)) {
         color = i;
      } else {
         color = Int_t(0.01+(w1-wlmin)*scale);
      }

      theColor = Int_t((color+0.99)*Double_t(ncolors)/Double_t(ndivz));
      SetFillColor(gStyle->GetColorPalette(theColor));
      TAttFill::Modify();
      gPad->PaintBox(xmin,y1,xmax,y2);
   }
   Int_t ndiv  = fH->GetZaxis()->GetNdivisions()%100; //take primary divisions only
   char chopt[5] = "";
   chopt[0] = 0;
   strcat(chopt, "+L");
   if (ndiv < 0) {
      ndiv =TMath::Abs(ndiv);
      strcat(chopt, "N");
   }
   if (gPad->GetLogz()) {
      wmin = TMath::Power(10.,wlmin);
      wmax = TMath::Power(10.,wlmax);
      strcat(chopt, "G");
   }
   fAxis.PaintAxis(xmax,ymin,xmax,ymax,wmin,wmax,ndiv,chopt);
}

//______________________________________________________________________________
void TPaletteAxis::SavePrimitive(ofstream &out, Option_t *)
{
   // Save primitive as a C++ statement(s) on output stream out.

   //char quote = '"';
   out<<"   "<<endl;
   if (gROOT->ClassSaved(TPaletteAxis::Class())) {
       out<<"   ";
   } else {
       out<<"   "<<ClassName()<<" *";
   }
   if (fOption.Contains("NDC")) {
      out<<"palette = new "<<ClassName()<<"("<<fX1NDC<<","<<fY1NDC<<","<<fX2NDC<<","<<fY2NDC
      <<","<<fH->GetName()<<");"<<endl;
   } else {
      out<<"palette = new "<<ClassName()<<"("<<fX1<<","<<fY1<<","<<fX2<<","<<fY2
      <<","<<fH->GetName()<<");"<<endl;
   }
   out<<"palette->SetLabelColor(" <<fAxis.GetLabelColor()<<");"<<endl;
   out<<"palette->SetLabelFont("  <<fAxis.GetLabelFont()<<");"<<endl;
   out<<"palette->SetLabelOffset("<<fAxis.GetLabelOffset()<<");"<<endl;
   out<<"palette->SetLabelSize("  <<fAxis.GetLabelSize()<<");"<<endl;
   out<<"palette->SetTitleOffset("<<fAxis.GetTitleOffset()<<");"<<endl;
   out<<"palette->SetTitleSize("  <<fAxis.GetTitleSize()<<");"<<endl;
   SaveFillAttributes(out,"palette",-1,-1);
   SaveLineAttributes(out,"palette",1,1,1);
}

//______________________________________________________________________________
void TPaletteAxis::UnZoom()
{
   TView *view = gPad->GetView();
   if (view) {
      delete view;
      gPad->SetView(0);
   }
   fH->GetZaxis()->SetRange(0,0);
   if (fH->GetDimension() == 2) {
      fH->SetMinimum();
      fH->SetMaximum();
      fH->ResetBit(TH1::kIsZoomed);
   }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Alonzo Coeus
#include "crypto/lamport.h"

#include "crypto/ripemd160.h"
#include "crypto/common.h"
#include "uint256.h"

using namespace std;
typedef vector<unsigned char> valtype;

bool LAMPORT::checksig(valtype *pointerdata, valtype *pointerasig, valtype *pointerrootkey, valtype *pointermerklewit)
{

valtype data = *pointerdata;
valtype asig = *pointerasig;
valtype rootkey = *pointerrootkey;
valtype merklewit = *pointermerklewit;

//STARTING to convert asig vector to sig[20][2][20]
unsigned char sig[160/(LAMPORT::chunksize*8)][2][20];
for(int i = 0; i < (LAMPORT::chunksize*8); i++)
{
  for(int o = 0; o < 2; o++)
  {
    for(int p = 0; p < 20; p++)
    {
      sig[i][o][p] = asig[p + (o * 20) + (p * 40)];
    }
  }
}
//END converting asig vector to sig[20][2][20]

  valtype exmerklewit[8]; /*this is the merkle wit minus the main public key max number of publickeys to rootkey is 256 due to 2^n where n is the first array index is 8*/
  char pubkey[160/(LAMPORT::chunksize*8)][2][20];
  valtype hashablepubkey;

  //START converting merkle wit to exmerklewit and public key
  char merklebuffer[800]; //size of publickey is the max size of the buffer
  unsigned int i;
  for(i = 0; i < sizeof(merklewit); i++)
  {
    if(merklewit[i] == 0x00 && merklewit[i+1] == 0x00) /*test for partition beetween merkle segments*/
      break;
    merklebuffer[i] = merklewit[i];
  }

  memcpy(&(pubkey[0][0][0]), &(merklebuffer[0]), sizeof(merklebuffer));
  memcpy(&(hashablepubkey[0]), &(merklebuffer[0]), sizeof(merklebuffer));

  int o = 0;
  int r = 0; //number of times we have reset o count
  for(; i < merklewit.size(); i++)
  {
    if(merklewit[i] == 0x00 && merklewit[i+1] == 0x00)
    {
      if(r == 8)
        break; //lim of exmerklewit
      memcpy(&(exmerklewit[r][0]), &(merklebuffer[0]), sizeof(merklebuffer));
      r++;
      i++; //get i+1 index chunk so we can jump to next part of the merklewit at the end of cycle
      o = 0; //merklebuffer index
    }
    else
    {
      merklebuffer[o] = merklewit[i];
      o++;
    }
  }
  //END decoding merkle wit format

  //START checking if new publickey is a part of the root key
  valtype tempverifyhash;
  CRIPEMD160().Write(&(hashablepubkey[0]), hashablepubkey.size()).Finalize(&(tempverifyhash[0])); //first element is start of arrays address length pre-def
  for(int i = 0; true; i++) //to end if false we will use return to lower processing time
  {
    if(exmerklewit[i][0] == 0 && exmerklewit[i][1] == 0 && exmerklewit[i][2] == 0 && exmerklewit[i][3] == 0)
    {
      if(tempverifyhash == rootkey)
      {
        break;
      }
      else
      {
        return false;
      }
    }

    CRIPEMD160().Write(&(tempverifyhash[0]), tempverifyhash.size()).Write(&(exmerklewit[i][0]), exmerklewit[i].size()).Finalize(&(tempverifyhash[0]));
  }

  //END checking if new publickey is a part of the root key

  //START checking if sig is valid

  //create hash of data
  valtype hashdata;
  valtype sellectedhashseg; //to allow seamless scaling to larger segment sizes
  uint512_t sellectedinthashseg; //memcpy of valtype to uint512_t format
  CRIPEMD160().Write(&(data[0]), data.size()).Finalize(&(hashdata[0]));
  valtype keypair[2]; //the two public values at the ends of the ladder
  valtype sigpair[2]; //the two values from each side of hash ladder when signing

  for(int i = 0; i < 160/(LAMPORT::chunksize*8); i++) {
    //get sig, key pair and sellect hash segments
    memcpy(&(sellectedhashseg), &(hashdata[i*LAMPORT::chunksize]), LAMPORT::chunksize);
    uint512_t sellectedinthashseg = (uint512_t)sellectedhashseg;
    for(int o = 0; o < 2; o++) {
      memcpy(&(keypair[o]), &(pubkey[i][o]), 20);
      memcpy(&(sigpair[i]), &(sig[i][o]), 20);
    }
    //
    uint512_t i_a = 0;
    while (true) { //i-a sigpair[0]
      CRIPEMD160().Write(&(sigpair[0]), data.size()).Finalize(&(sigpair[0]));
      i_a++; //increment after data hased
      if(o == 160) {
        return false;
      }
      if(sigpair[0] == keypair[0]) {
        break;
      }
    }
    uint512_t i_b = 0;
    while (true) { //i-b sigpair[1]
      CRIPEMD160().Write(&(sigpair[1]), data.size()).Finalize(&(sigpair[1]));
      i_b++;
      if(o == 160) {
        return false;
      }
      if(sigpair[1] == keypair[1]) {
        break;
      }
    }
    if((160-i_a != i_b-1) || (160-i_a != sellectedinthashseg)) {
      return false;
    }
  }
  //END checking if sig is valid
  return true; // if compleats all tests return true
}
    char *LAMPORT::createsig(valtype *pdata, uint512_t *pprikey, int sellectedpubkey)
    {
      /* the signing will happen under this */
      valtype data = *pdata;
      uint512_t prikey = *pprikey;
      valtype pkey[20][2][20];

      valtype hash;
      CRIPEMD160().Write(&(data), data.size()).Finalize(&(hash));

      return &sig[0][0][0];
    }
<commit_msg>Update lamport.cpp<commit_after>// Copyright (c) 2016 Alonzo Coeus
#include "crypto/lamport.h"

#include "crypto/ripemd160.h"
#include "crypto/common.h"
#include "uint256.h"

using namespace std;
typedef vector<unsigned char> valtype;

bool LAMPORT::checksig(valtype *pointerdata, valtype *pointerasig, valtype *pointerrootkey, valtype *pointermerklewit)
{

valtype data = *pointerdata;
valtype asig = *pointerasig;
valtype rootkey = *pointerrootkey;
valtype merklewit = *pointermerklewit;

//STARTING to convert asig vector to sig[20][2][20]
unsigned char sig[160/(LAMPORT::chunksize*8)][2][20];
for(int i = 0; i < (LAMPORT::chunksize*8); i++)
{
  for(int o = 0; o < 2; o++)
  {
    for(int p = 0; p < 20; p++)
    {
      sig[i][o][p] = asig[p + (o * 20) + (p * 40)];
    }
  }
}
//END converting asig vector to sig[20][2][20]

  valtype exmerklewit[8]; /*this is the merkle wit minus the main public key max number of publickeys to rootkey is 256 due to 2^n where n is the first array index is 8*/
  char pubkey[160/(LAMPORT::chunksize*8)][2][20];
  valtype hashablepubkey;

  //START converting merkle wit to exmerklewit and public key
  char merklebuffer[800]; //size of publickey is the max size of the buffer
  unsigned int i;
  for(i = 0; i < sizeof(merklewit); i++)
  {
    if(merklewit[i] == 0x00 && merklewit[i+1] == 0x00) /*test for partition beetween merkle segments*/
      break;
    merklebuffer[i] = merklewit[i];
  }

  memcpy(&(pubkey[0][0][0]), &(merklebuffer[0]), sizeof(merklebuffer));
  memcpy(&(hashablepubkey[0]), &(merklebuffer[0]), sizeof(merklebuffer));

  int o = 0;
  int r = 0; //number of times we have reset o count
  for(; i < merklewit.size(); i++)
  {
    if(merklewit[i] == 0x00 && merklewit[i+1] == 0x00)
    {
      if(r == 8)
        break; //lim of exmerklewit
      memcpy(&(exmerklewit[r][0]), &(merklebuffer[0]), sizeof(merklebuffer));
      r++;
      i++; //get i+1 index chunk so we can jump to next part of the merklewit at the end of cycle
      o = 0; //merklebuffer index
    }
    else
    {
      merklebuffer[o] = merklewit[i];
      o++;
    }
  }
  //END decoding merkle wit format

  //START checking if new publickey is a part of the root key
  valtype tempverifyhash;
  CRIPEMD160().Write(&(hashablepubkey[0]), hashablepubkey.size()).Finalize(&(tempverifyhash[0])); //first element is start of arrays address length pre-def
  for(int i = 0; true; i++) //to end if false we will use return to lower processing time
  {
    if(exmerklewit[i][0] == 0 && exmerklewit[i][1] == 0 && exmerklewit[i][2] == 0 && exmerklewit[i][3] == 0)
    {
      if(tempverifyhash == rootkey)
      {
        break;
      }
      else
      {
        return false;
      }
    }

    CRIPEMD160().Write(&(tempverifyhash[0]), tempverifyhash.size()).Write(&(exmerklewit[i][0]), exmerklewit[i].size()).Finalize(&(tempverifyhash[0]));
  }

  //END checking if new publickey is a part of the root key

  //START checking if sig is valid

  //create hash of data
  valtype hashdata;
  valtype sellectedhashseg; //to allow seamless scaling to larger segment sizes
  uint512_t sellectedinthashseg; //memcpy of valtype to uint512_t format
  CRIPEMD160().Write(&(data[0]), data.size()).Finalize(&(hashdata[0]));
  valtype keypair[2]; //the two public values at the ends of the ladder
  valtype sigpair[2]; //the two values from each side of hash ladder when signing

  for(int i = 0; i < 160/(LAMPORT::chunksize*8); i++) {
    //get sig, key pair and sellect hash segments
    uint512_t sellectedinthashseg;
    memcpy(&(sellectedhashseg), &(hashdata[i*LAMPORT::chunksize]), LAMPORT::chunksize);
    memcpy(&(sellectedinthashseg), &(sellectedhashseg), LAMPORT::chunksize);
    for(int o = 0; o < 2; o++) {
      memcpy(&(keypair[o]), &(pubkey[i][o]), 20);
      memcpy(&(sigpair[i]), &(sig[i][o]), 20);
    }
    //
    uint512_t i_a = 0;
    while (true) { //i-a sigpair[0]
      CRIPEMD160().Write(&(sigpair[0]), data.size()).Finalize(&(sigpair[0]));
      i_a++; //increment after data hased
      if(o == 160) {
        return false;
      }
      if(sigpair[0] == keypair[0]) {
        break;
      }
    }
    uint512_t i_b = 0;
    while (true) { //i-b sigpair[1]
      CRIPEMD160().Write(&(sigpair[1]), data.size()).Finalize(&(sigpair[1]));
      i_b++;
      if(o == 160) {
        return false;
      }
      if(sigpair[1] == keypair[1]) {
        break;
      }
    }
    if((160-i_a != i_b-1) || (160-i_a != sellectedinthashseg)) {
      return false;
    }
  }
  //END checking if sig is valid
  return true; // if compleats all tests return true
}
    char *LAMPORT::createsig(valtype *pdata, uint512_t *pprikey, int sellectedpubkey)
    {
      /* the signing will happen under this */
      valtype data = *pdata;
      uint512_t prikey = *pprikey;
      valtype pkey[20][2][20];

      valtype hash;
      CRIPEMD160().Write(&(data), data.size()).Finalize(&(hash));

      return &sig[0][0][0];
    }
<|endoftext|>


<commit_before>// Copyright (c) 2007, 2008 libmv authors.
//
// 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 <cassert>
#include <vector>

#include "libmv/numeric/numeric.h"
#include "libmv/correspondence/klt.h"
#include "libmv/image/image.h"
#include "libmv/image/image_io.h"
#include "libmv/image/convolve.h"
#include "libmv/image/sample.h"

using std::vector;
using std::max;
using std::min;

namespace libmv {

static void FindLocalMaxima(const FloatImage &trackness,
                            float min_trackness,
                            KLTContext::FeatureList *features) {
  for (int i = 1; i < trackness.Height()-1; ++i) {
    for (int j = 1; j < trackness.Width()-1; ++j) {
      if (   trackness(i,j) >= min_trackness
          && trackness(i,j) >= trackness(i-1, j-1)
          && trackness(i,j) >= trackness(i-1, j  )
          && trackness(i,j) >= trackness(i-1, j+1)
          && trackness(i,j) >= trackness(i  , j-1)
          && trackness(i,j) >= trackness(i  , j+1)
          && trackness(i,j) >= trackness(i+1, j-1)
          && trackness(i,j) >= trackness(i+1, j  )
          && trackness(i,j) >= trackness(i+1, j+1)) {
        KLTPointFeature *p = new KLTPointFeature;
        p->position(1) = i;
        p->position(0) = j;
        p->trackness = trackness(i,j);
        features->push_back(p);
      }
    }
  }
}

// Compute the gradient matrix noted by Z in Good Features to Track.
//
//   Z = [gxx gxy; gxy gyy]
//
// This function computes the matrix for every pixel.
static void ComputeGradientMatrix(const Array3Df &image_and_gradients,
                                       int window_size,
                                       Array3Df *gradient_matrix) {
  Array3Df gradients;
  gradients.ResizeLike(image_and_gradients);
  for (int j = 0; j < image_and_gradients.Height(); ++j) {
    for (int i = 0; i < image_and_gradients.Width(); ++i) {
      float gx = image_and_gradients(j, i, 1);
      float gy = image_and_gradients(j, i, 2);
      gradients(j, i, 0) = gx * gx;
      gradients(j, i, 1) = gx * gy;
      gradients(j, i, 2) = gy * gy;
    }
  }
  // Sum the gradient matrix over tracking window for each pixel.
  BoxFilter(gradients, window_size, gradient_matrix);
}

// Given the three distinct elements of the symmetric 2x2 matrix
//
//                     [gxx gxy]
//                     [gxy gyy],
//
// return the minimum eigenvalue of the matrix.
// Borrowed from Stan Birchfield's KLT implementation.
static float MinEigenValue(float gxx, float gxy, float gyy) {
  return (gxx + gyy - sqrt((gxx - gyy) * (gxx - gyy) + 4 * gxy * gxy)) / 2.0f;
}

// Compute trackness of every pixel given the gradient matrix.
// This is done as described in the Good Features to Track paper.
static void ComputeTrackness(const Array3Df gradient_matrix,
                             Array3Df *trackness_pointer,
                             double *trackness_mean) {
  Array3Df &trackness = *trackness_pointer;
  trackness.Resize(gradient_matrix.Height(), gradient_matrix.Width());
  *trackness_mean = 0;
  for (int i = 0; i < trackness.Height(); ++i) {
    for (int j = 0; j < trackness.Width(); ++j) {
      double t = MinEigenValue(gradient_matrix(i, j, 0),
                               gradient_matrix(i, j, 1),
                               gradient_matrix(i, j, 2));
      trackness(i, j) = t;
      *trackness_mean += t;
    }
  }
  *trackness_mean /= trackness.Size();
}

static double dist2(const Vec2f &x, const Vec2f &y) {
  double a = x(0) - y(0);
  double b = x(1) - y(1);
  return a * a + b * b;
}

// TODO(keir): Use Stan's neat trick of using a 'punch-out' array to detect
// too-closes features. This is O(n^2)!
static void RemoveTooCloseFeatures(KLTContext::FeatureList *features,
                                   double mindist2) {

  KLTContext::FeatureList::iterator i = features->begin();
  while (i != features->end()) {
    bool i_deleted = false;
    KLTContext::FeatureList::iterator j = i;
    ++j;
    while (j != features->end() && !i_deleted) {
      if (dist2((*i)->position, (*j)->position) < mindist2) {
        KLTContext::FeatureList::iterator to_delete;
        if ((*i)->trackness < (*j)->trackness) {
          to_delete = i;
          ++i;
          i_deleted = true;
        } else {
          to_delete = j;
          ++j;
        }
        delete *to_delete;
        features->erase(to_delete);
      } else {
        ++j;
      }
    }
    if (!i_deleted) {
      ++i;
    }
  }
}

void KLTContext::DetectGoodFeatures(const Array3Df &image_and_gradients,
                                    FeatureList *features) {
  Array3Df gradient_matrix;
  ComputeGradientMatrix(image_and_gradients, WindowSize(), &gradient_matrix);

  Array3Df trackness;
  double trackness_mean;
  ComputeTrackness(gradient_matrix, &trackness, &trackness_mean);
  min_trackness_ = trackness_mean;

  FindLocalMaxima(trackness, min_trackness_, features);

  RemoveTooCloseFeatures(features, min_feature_dist_ * min_feature_dist_);
}

void KLTContext::TrackFeatures(ImagePyramid *pyramid1,
                               const FeatureList &features1,
                               ImagePyramid *pyramid2,
                               FeatureList *features2_pointer) {
  FeatureList &features2 = *features2_pointer;

  features2.clear();
  for (FeatureList::const_iterator i = features1.begin();
       i != features1.end(); ++i) {
    KLTPointFeature *tracked_feature = new KLTPointFeature;
    TrackFeature(pyramid1, **i, pyramid2, tracked_feature);
    features2.push_back(tracked_feature);
  }
}

bool KLTContext::TrackFeature(ImagePyramid *pyramid1,
                              const KLTPointFeature &feature1,
                              ImagePyramid *pyramid2,
                              KLTPointFeature *feature2_pointer) {
  Vec2 position1, position2;
  position2(0) = feature1.position(0);
  position2(1) = feature1.position(1);
  position2 /= pow(2., pyramid1->NumLevels());

  for (int i = pyramid1->NumLevels() - 1; i >= 0; --i) {
    position1(0) = feature1.position(0) / pow(2., i);
    position1(1) = feature1.position(1) / pow(2., i);
    position2 *= 2;

    bool succeeded = TrackFeatureOneLevel(pyramid1->Level(i),
                                          position1,
                                          pyramid2->Level(i),
                                          &position2);
    if (i == 0 && !succeeded) {
      // Only fail on the highest-resolution level, because a failure on a
      // coarse level does not mean failure at a lower level (consider
      // out-of-bounds conditions).
      return false;
    }
  }
  feature2_pointer->position = position2;
  return true;
}

// Compute the gradient matrix noted by Z and the error vector e.
// See Good Features to Track.
static void ComputeTrackingEquation(const Array3Df &image_and_gradient1,
                                    const Array3Df &image_and_gradient2,
                                    const Vec2 &position1,
                                    const Vec2 &position2,
                                    int half_width,
                                    float *gxx,
                                    float *gxy,
                                    float *gyy,
                                    float *ex,
                                    float *ey) {
  *gxx = *gxy = *gyy = 0;
  *ex = *ey = 0;
  for (int r = -half_width; r <= half_width; ++r) {
    for (int c = -half_width; c <= half_width; ++c) {
      float x1 = position1(0) + c;
      float y1 = position1(1) + r;
      float x2 = position2(0) + c;
      float y2 = position2(1) + r;
      // TODO(pau): should do boundary checking outside this loop, and call here
      // a sampler that does not boundary checking.
      float I =  SampleLinear(image_and_gradient1, y1, x1, 0);
      float J =  SampleLinear(image_and_gradient2, y2, x2, 0);
      float gx = SampleLinear(image_and_gradient2, y2, x2, 1);
      float gy = SampleLinear(image_and_gradient2, y2, x2, 2);
      *gxx += gx * gx;
      *gxy += gx * gy;
      *gyy += gy * gy;
      *ex += (I - J) * gx;
      *ey += (I - J) * gy;
    }
  }
}

// Solve the tracking equation
//
//   [gxx gxy] [dx] = [ex]
//   [gxy gyy] [dy] = [ey]
//
// for dx and dy.  Borrowed from Stan Birchfield's KLT implementation.
static bool SolveTrackingEquation(float gxx, float gxy, float gyy,
                                  float ex, float ey,
                                  float min_determinant,
                                  float *dx, float *dy) {
  float det = gxx * gyy - gxy * gxy;
  if (det < min_determinant) {
    *dx = 0;
    *dy = 0;
    return false;
  }
  *dx = (gyy * ex - gxy * ey) / det;
  *dy = (gxx * ey - gxy * ex) / det;
  return true;
}

bool KLTContext::TrackFeatureOneLevel(const Array3Df &image_and_gradient1,
                                      const Vec2 &position1,
                                      const Array3Df &image_and_gradient2,
                                      Vec2 *position2_pointer) {
  Vec2 &position2 = *position2_pointer;

  int i;
  float dx=0, dy=0;
  max_iterations_ = 10;
  for (i = 0; i < max_iterations_; ++i) {
    // Compute gradient matrix and error vector.
    float gxx, gxy, gyy, ex, ey;
    ComputeTrackingEquation(image_and_gradient1, image_and_gradient2,
                            position1, position2,
                            HalfWindowSize(),
                            &gxx, &gxy, &gyy, &ex, &ey);
    // Solve the linear system for deltad.
    if (!SolveTrackingEquation(gxx, gxy, gyy, ex, ey, min_determinant_,
                               &dx, &dy)) {
      return false;
    }

    // Update feature2 position.
    position2(0) += dx;
    position2(1) += dy;

    // TODO(keir): Handle other tracking failure conditions and pass the
    // reasons out to the caller. For example, for pyramid tracking a failure
    // at a coarse level suggests trying again at a finer level.
    if (Square(dx) + Square(dy) < min_update_distance2_) {
      break;
    }
  }

  if (i == max_iterations_) {
    // TODO(keir): Somehow indicate that we hit max iterations.
  }
  return true;
}

void KLTContext::DrawFeatureList(const FeatureList &features,
                                 const Vec3 &color,
                                 FloatImage *image) const {
  for (FeatureList::const_iterator i = features.begin();
       i != features.end(); ++i) {
    DrawFeature(**i, color, image);
  }
}

// TODO(keir): Replace this with Cairo.
void DrawFeature(const PointFeature &feature,
                 const Vec3 &color,
                 FloatImage *image) {
  assert(image->Depth() == 3);

  const Vec2f &point = feature.Point();

  const int cross_width = 5;
  int x = lround(point(0));
  int y = lround(point(1));
  if (!image->Contains(y,x)) {
    return;
  }

  // Draw vertical line.
  for (int i = max(0, y - cross_width);
       i < min(image->Height(), y + cross_width + 1); ++i) {
    for (int k = 0; k < 3; ++k) {
      (*image)(i, x, k) = color(k);
    }
  }
  // Draw horizontal line.
  for (int j = max(0, x - cross_width);
       j < min(image->Width(), x + cross_width + 1); ++j) {
    for (int k = 0; k < 3; ++k) {
      (*image)(y, j, k) = color(k);
    }
  }
}

}  // namespace libmv
<commit_msg>Todos for KLT to use Eigen primitives.<commit_after>// Copyright (c) 2007, 2008 libmv authors.
//
// 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 <cassert>
#include <vector>

#include "libmv/numeric/numeric.h"
#include "libmv/correspondence/klt.h"
#include "libmv/image/image.h"
#include "libmv/image/image_io.h"
#include "libmv/image/convolve.h"
#include "libmv/image/sample.h"

using std::vector;
using std::max;
using std::min;

namespace libmv {

static void FindLocalMaxima(const FloatImage &trackness,
                            float min_trackness,
                            KLTContext::FeatureList *features) {
  for (int i = 1; i < trackness.Height()-1; ++i) {
    for (int j = 1; j < trackness.Width()-1; ++j) {
      if (   trackness(i,j) >= min_trackness
          && trackness(i,j) >= trackness(i-1, j-1)
          && trackness(i,j) >= trackness(i-1, j  )
          && trackness(i,j) >= trackness(i-1, j+1)
          && trackness(i,j) >= trackness(i  , j-1)
          && trackness(i,j) >= trackness(i  , j+1)
          && trackness(i,j) >= trackness(i+1, j-1)
          && trackness(i,j) >= trackness(i+1, j  )
          && trackness(i,j) >= trackness(i+1, j+1)) {
        KLTPointFeature *p = new KLTPointFeature;
        p->position(1) = i;
        p->position(0) = j;
        p->trackness = trackness(i,j);
        features->push_back(p);
      }
    }
  }
}

// Compute the gradient matrix noted by Z in Good Features to Track.
//
//   Z = [gxx gxy; gxy gyy]
//
// This function computes the matrix for every pixel.
static void ComputeGradientMatrix(const Array3Df &image_and_gradients,
                                       int window_size,
                                       Array3Df *gradient_matrix) {
  Array3Df gradients;
  gradients.ResizeLike(image_and_gradients);
  for (int j = 0; j < image_and_gradients.Height(); ++j) {
    for (int i = 0; i < image_and_gradients.Width(); ++i) {
      float gx = image_and_gradients(j, i, 1);
      float gy = image_and_gradients(j, i, 2);
      gradients(j, i, 0) = gx * gx;
      gradients(j, i, 1) = gx * gy;
      gradients(j, i, 2) = gy * gy;
    }
  }
  // Sum the gradient matrix over tracking window for each pixel.
  BoxFilter(gradients, window_size, gradient_matrix);
}

// Given the three distinct elements of the symmetric 2x2 matrix
//
//                     [gxx gxy]
//                     [gxy gyy],
//
// return the minimum eigenvalue of the matrix.
// Borrowed from Stan Birchfield's KLT implementation.
static float MinEigenValue(float gxx, float gxy, float gyy) {
  return (gxx + gyy - sqrt((gxx - gyy) * (gxx - gyy) + 4 * gxy * gxy)) / 2.0f;
}

// Compute trackness of every pixel given the gradient matrix.
// This is done as described in the Good Features to Track paper.
static void ComputeTrackness(const Array3Df gradient_matrix,
                             Array3Df *trackness_pointer,
                             double *trackness_mean) {
  Array3Df &trackness = *trackness_pointer;
  trackness.Resize(gradient_matrix.Height(), gradient_matrix.Width());
  *trackness_mean = 0;
  for (int i = 0; i < trackness.Height(); ++i) {
    for (int j = 0; j < trackness.Width(); ++j) {
      double t = MinEigenValue(gradient_matrix(i, j, 0),
                               gradient_matrix(i, j, 1),
                               gradient_matrix(i, j, 2));
      trackness(i, j) = t;
      *trackness_mean += t;
    }
  }
  *trackness_mean /= trackness.Size();
}

static double dist2(const Vec2f &x, const Vec2f &y) {
  double a = x(0) - y(0);
  double b = x(1) - y(1);
  return a * a + b * b;
}

// TODO(keir): Use Stan's neat trick of using a 'punch-out' array to detect
// too-closes features. This is O(n^2)!
static void RemoveTooCloseFeatures(KLTContext::FeatureList *features,
                                   double mindist2) {

  KLTContext::FeatureList::iterator i = features->begin();
  while (i != features->end()) {
    bool i_deleted = false;
    KLTContext::FeatureList::iterator j = i;
    ++j;
    while (j != features->end() && !i_deleted) {
      if (dist2((*i)->position, (*j)->position) < mindist2) {
        KLTContext::FeatureList::iterator to_delete;
        if ((*i)->trackness < (*j)->trackness) {
          to_delete = i;
          ++i;
          i_deleted = true;
        } else {
          to_delete = j;
          ++j;
        }
        delete *to_delete;
        features->erase(to_delete);
      } else {
        ++j;
      }
    }
    if (!i_deleted) {
      ++i;
    }
  }
}

void KLTContext::DetectGoodFeatures(const Array3Df &image_and_gradients,
                                    FeatureList *features) {
  Array3Df gradient_matrix;
  ComputeGradientMatrix(image_and_gradients, WindowSize(), &gradient_matrix);

  Array3Df trackness;
  double trackness_mean;
  ComputeTrackness(gradient_matrix, &trackness, &trackness_mean);
  min_trackness_ = trackness_mean;

  FindLocalMaxima(trackness, min_trackness_, features);

  RemoveTooCloseFeatures(features, min_feature_dist_ * min_feature_dist_);
}

void KLTContext::TrackFeatures(ImagePyramid *pyramid1,
                               const FeatureList &features1,
                               ImagePyramid *pyramid2,
                               FeatureList *features2_pointer) {
  FeatureList &features2 = *features2_pointer;

  features2.clear();
  for (FeatureList::const_iterator i = features1.begin();
       i != features1.end(); ++i) {
    KLTPointFeature *tracked_feature = new KLTPointFeature;
    TrackFeature(pyramid1, **i, pyramid2, tracked_feature);
    features2.push_back(tracked_feature);
  }
}

bool KLTContext::TrackFeature(ImagePyramid *pyramid1,
                              const KLTPointFeature &feature1,
                              ImagePyramid *pyramid2,
                              KLTPointFeature *feature2_pointer) {
  Vec2 position1, position2;
  position2(0) = feature1.position(0);
  position2(1) = feature1.position(1);
  position2 /= pow(2., pyramid1->NumLevels());

  for (int i = pyramid1->NumLevels() - 1; i >= 0; --i) {
    position1(0) = feature1.position(0) / pow(2., i);
    position1(1) = feature1.position(1) / pow(2., i);
    position2 *= 2;

    bool succeeded = TrackFeatureOneLevel(pyramid1->Level(i),
                                          position1,
                                          pyramid2->Level(i),
                                          &position2);
    if (i == 0 && !succeeded) {
      // Only fail on the highest-resolution level, because a failure on a
      // coarse level does not mean failure at a lower level (consider
      // out-of-bounds conditions).
      return false;
    }
  }
  feature2_pointer->position = position2;
  return true;
}

// Compute the gradient matrix noted by Z and the error vector e.
// See Good Features to Track.
static void ComputeTrackingEquation(const Array3Df &image_and_gradient1,
                                    const Array3Df &image_and_gradient2,
                                    const Vec2 &position1,
                                    const Vec2 &position2,
                                    int half_width,
                                    float *gxx,
                                    float *gxy,
                                    float *gyy,
                                    float *ex,
                                    float *ey) {
  *gxx = *gxy = *gyy = 0;
  *ex = *ey = 0;
  for (int r = -half_width; r <= half_width; ++r) {
    for (int c = -half_width; c <= half_width; ++c) {
      float x1 = position1(0) + c;
      float y1 = position1(1) + r;
      float x2 = position2(0) + c;
      float y2 = position2(1) + r;
      // TODO(pau): should do boundary checking outside this loop, and call here
      // a sampler that does not boundary checking.
      float I =  SampleLinear(image_and_gradient1, y1, x1, 0);
      float J =  SampleLinear(image_and_gradient2, y2, x2, 0);
      float gx = SampleLinear(image_and_gradient2, y2, x2, 1);
      float gy = SampleLinear(image_and_gradient2, y2, x2, 2);
      *gxx += gx * gx;
      *gxy += gx * gy;
      *gyy += gy * gy;
      *ex += (I - J) * gx;
      *ey += (I - J) * gy;
    }
  }
}

// Solve the tracking equation
//
//   [gxx gxy] [dx] = [ex]
//   [gxy gyy] [dy] = [ey]
//
// for dx and dy.  Borrowed from Stan Birchfield's KLT implementation.
//
// TODO(keir): Replace this with calls to eigen (faster, more stable).
static bool SolveTrackingEquation(float gxx, float gxy, float gyy,
                                  float ex, float ey,
                                  float min_determinant,
                                  float *dx, float *dy) {
  float det = gxx * gyy - gxy * gxy;
  if (det < min_determinant) {
    *dx = 0;
    *dy = 0;
    return false;
  }
  *dx = (gyy * ex - gxy * ey) / det;
  *dy = (gxx * ey - gxy * ex) / det;
  return true;
}

bool KLTContext::TrackFeatureOneLevel(const Array3Df &image_and_gradient1,
                                      const Vec2 &position1,
                                      const Array3Df &image_and_gradient2,
                                      Vec2 *position2_pointer) {
  Vec2 &position2 = *position2_pointer;

  int i;
  float dx=0, dy=0;
  max_iterations_ = 10;
  for (i = 0; i < max_iterations_; ++i) {
    // Compute gradient matrix and error vector.
    float gxx, gxy, gyy, ex, ey;
    ComputeTrackingEquation(image_and_gradient1, image_and_gradient2,
                            position1, position2,
                            HalfWindowSize(),
                            &gxx, &gxy, &gyy, &ex, &ey);
    // Solve the linear system for deltad.
    if (!SolveTrackingEquation(gxx, gxy, gyy, ex, ey, min_determinant_,
                               &dx, &dy)) {
      return false;
    }

    // Update feature2 position.
    position2(0) += dx;
    position2(1) += dy;

    // TODO(keir): Handle other tracking failure conditions and pass the
    // reasons out to the caller. For example, for pyramid tracking a failure
    // at a coarse level suggests trying again at a finer level.
    if (Square(dx) + Square(dy) < min_update_distance2_) {
      break;
    }
  }

  if (i == max_iterations_) {
    // TODO(keir): Somehow indicate that we hit max iterations.
  }
  return true;
}

void KLTContext::DrawFeatureList(const FeatureList &features,
                                 const Vec3 &color,
                                 FloatImage *image) const {
  for (FeatureList::const_iterator i = features.begin();
       i != features.end(); ++i) {
    DrawFeature(**i, color, image);
  }
}

// TODO(keir): Replace this with Cairo.
void DrawFeature(const PointFeature &feature,
                 const Vec3 &color,
                 FloatImage *image) {
  assert(image->Depth() == 3);

  const Vec2f &point = feature.Point();

  const int cross_width = 5;
  int x = lround(point(0));
  int y = lround(point(1));
  if (!image->Contains(y,x)) {
    return;
  }

  // Draw vertical line.
  for (int i = max(0, y - cross_width);
       i < min(image->Height(), y + cross_width + 1); ++i) {
    for (int k = 0; k < 3; ++k) {
      (*image)(i, x, k) = color(k);
    }
  }
  // Draw horizontal line.
  for (int j = max(0, x - cross_width);
       j < min(image->Width(), x + cross_width + 1); ++j) {
    for (int k = 0; k < 3; ++k) {
      (*image)(y, j, k) = color(k);
    }
  }
}

}  // namespace libmv
<|endoftext|>


<commit_before>#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <map>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

const char MODE_NO_SELECTION = 'n';
const char MODE_SELECTION = 's';
const char MODE_DONE = 'd';
const char ACTION_UNDO = 'u';

map<char, string> *modeDescriptions = new map<char, string>;
char mode = MODE_NO_SELECTION;
vector<Point> *points = new vector<Point>();
int keyPressed = -1;
char charTyped = ' ';

Mat imgOriginal, imgDup, imgDraw;
string guiWindowName = "Select Target Region";

void draw(Mat &imgo, Mat &img, vector<Point> *points) {
	bool drawPoints = false;
	imgo.copyTo(img);

	Mat mask(imgo.rows, imgo.cols, CV_8UC3, Scalar(0, 0, 0));
	Mat White(imgo.rows, imgo.cols, CV_8UC3, Scalar(255, 255, 255));

	const int size = points->size();
	Point *newPoints = new Point[size];

	for (int i = 0; i < points->size(); ++i) {
		Point thePoint = points->at(i);
		newPoints[i] = thePoint;
		if (drawPoints) {
			circle(img, thePoint, 3, Scalar(30, 25, 200), 2);
		}
	}
	fillPoly(mask, (const Point**) &newPoints, &size, 1, Scalar(255, 255, 255));

	Mat notMask, notMaskPart, nonMaskFinal;
	bitwise_not(mask, notMask);
	bitwise_and(imgo, notMask, notMaskPart);
	add(mask, notMaskPart, nonMaskFinal);

	float alpha = 0.2;
	float beta = 1 - alpha;

	addWeighted(imgo, alpha, nonMaskFinal, beta, 0.0, img);

	for (int i = 1; i < points->size(); ++i) {
		Point pt1 = points->at(i-1);
		Point pt2 = points->at(i);
		line(img, pt1, pt2, Scalar(0, 0, 255), 1);
	}

	if (mode == MODE_DONE) {
		if (points->size() > 2) {
			line(img, points->at(points->size() -1 ), points->at(0), Scalar(0, 0, 255), 1);
		}
	}
}

static void onMouse(int event, int x, int y, int, void*) {
	switch (mode) {
		case MODE_NO_SELECTION:
			if (event == EVENT_LBUTTONDOWN) {
				mode = MODE_SELECTION;
				points->push_back(Point(x, y));
			}
			break;
		case MODE_SELECTION:
			if (event == EVENT_LBUTTONDOWN) {
				points->push_back(Point(x, y));
			} else if(event == EVENT_RBUTTONDOWN) {
				mode = MODE_DONE;
			}
			break;
		default:
			break;
	}
	draw(imgDup, imgDraw, points);
	imshow(guiWindowName, imgDraw);

	// FIXME: Debug output, remove later
	cout << mode << '|' << points->size() << endl;
}

int main(int argc, char **argv) {

	string imgadr;

	if (argc > 1) {
		imgadr = argv[1];
	} else {
		imgadr = "/Users/yasser/sci-repo/opencv/samples/cpp/pic4.png";
	}

	imgOriginal = imread(imgadr, 1);

	if (imgOriginal.empty()) {
		cerr << "PROB: Cannot Load File" << endl;
		return 1;
	}

	imgOriginal.copyTo(imgDup);
	imgOriginal.copyTo(imgDraw);

	namedWindow(guiWindowName, WINDOW_AUTOSIZE);
	setMouseCallback(guiWindowName, onMouse);
	moveWindow(guiWindowName, 200, 300);

	while(1) {
		imshow(guiWindowName, imgDraw);
		keyPressed = waitKey(0);

		bool toExit = false;
		if ((keyPressed & 255) == 27) {
			switch (mode) {
				case MODE_SELECTION:
				case MODE_DONE:
					mode = MODE_NO_SELECTION;
					points->clear();
					break;
				case MODE_NO_SELECTION:
					toExit = true;
					break;
				default:
					break;
			}
			if (toExit) {
				break;
			}
		} else {
			charTyped = (char) keyPressed;
			switch (charTyped) {
				case ACTION_UNDO:
					if (mode == MODE_SELECTION) {
						points->pop_back();
						if (points->size() == 0) {
							mode = MODE_NO_SELECTION;
						}
					}
					break;
				default:
					break;
			}
		}
		draw(imgDup, imgDraw, points);
	}

	return 0;
}
<commit_msg>small changes to make it work really<commit_after>#include <stdio.h>
#include <stdlib.h>
#include <vector>
#include <map>
#include <opencv2/opencv.hpp>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>

using namespace std;
using namespace cv;

const char MODE_NO_SELECTION = 'n';
const char MODE_SELECTION = 's';
const char MODE_DONE = 'd';
const char ACTION_UNDO = 'u';

map<char, string> *modeDescriptions = new map<char, string>;
char mode = MODE_NO_SELECTION;
vector<Point> *points = new vector<Point>();
int keyPressed = -1;
char charTyped = ' ';

Mat imgOriginal, imgDup, imgDraw;
string guiWindowName = "Select Target Region";

void draw(Mat &imgo, Mat &img, vector<Point> *points) {
	bool drawPoints = false;
	imgo.copyTo(img);

	Mat mask(imgo.rows, imgo.cols, CV_8UC3, Scalar(0, 0, 0));
	Mat White(imgo.rows, imgo.cols, CV_8UC3, Scalar(255, 255, 255));

	const int size = points->size();
	Point *newPoints = new Point[size];

	for (int i = 0; i < points->size(); ++i) {
		Point thePoint = points->at(i);
		newPoints[i] = thePoint;
		if (drawPoints) {
			circle(img, thePoint, 3, Scalar(30, 25, 200), 2);
		}
	}
	fillPoly(mask, (const Point**) &newPoints, &size, 1, Scalar(255, 255, 255));

	Mat notMask, notMaskPart, nonMaskFinal;
	bitwise_not(mask, notMask);
	bitwise_and(imgo, notMask, notMaskPart);
	add(mask, notMaskPart, nonMaskFinal);

	float alpha = 0.2;
	float beta = 1 - alpha;

	addWeighted(imgo, alpha, nonMaskFinal, beta, 0.0, img);

	for (int i = 1; i < points->size(); ++i) {
		Point pt1 = points->at(i-1);
		Point pt2 = points->at(i);
		line(img, pt1, pt2, Scalar(0, 0, 255), 1);
	}

	if (mode == MODE_DONE) {
		if (points->size() > 2) {
			line(img, points->at(points->size() -1 ), points->at(0), Scalar(0, 0, 255), 1);
		}
	}
}

static void onMouse(int event, int x, int y, int, void*) {
	switch (mode) {
		case MODE_NO_SELECTION:
			if (event == EVENT_LBUTTONDOWN) {
				mode = MODE_SELECTION;
				points->push_back(Point(x, y));
			}
			break;
		case MODE_SELECTION:
			if (event == EVENT_LBUTTONDOWN) {
				points->push_back(Point(x, y));
			} else if(event == EVENT_RBUTTONDOWN) {
				mode = MODE_DONE;
			}
			break;
		default:
			break;
	}
	draw(imgDup, imgDraw, points);
	imshow(guiWindowName, imgDraw);
}

int main(int argc, char **argv) {

	string imgadr;

	if (argc > 1) {
		imgadr = argv[1];
	} else {
		imgadr = "/Users/yasser/sharif-repo/mahv/benchmark-dataset/Bear-0-original.jpg";
	}

	imgOriginal = imread(imgadr, 1);

	if (imgOriginal.empty()) {
		cerr << "PROB: Cannot Load File" << endl;
		return 1;
	}

	imgOriginal.copyTo(imgDup);
	imgOriginal.copyTo(imgDraw);

	namedWindow(guiWindowName, WINDOW_AUTOSIZE);
	setMouseCallback(guiWindowName, onMouse);

	while(1) {
		imshow(guiWindowName, imgDraw);
		keyPressed = waitKey(0);

		bool toExit = false;
		if ((keyPressed & 255) == 27) {
			switch (mode) {
				case MODE_SELECTION:
				case MODE_DONE:
					mode = MODE_NO_SELECTION;
					points->clear();
					break;
				case MODE_NO_SELECTION:
					toExit = true;
					break;
				default:
					break;
			}
			if (toExit) {
				break;
			}
		} else {
			charTyped = (char) keyPressed;
			switch (charTyped) {
				case ACTION_UNDO:
					if (mode == MODE_SELECTION) {
						points->pop_back();
						if (points->size() == 0) {
							mode = MODE_NO_SELECTION;
						}
					}
					break;
				default:
					break;
			}
		}
		draw(imgDup, imgDraw, points);
	}

	return 0;
}
<|endoftext|>