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

#include <cstdlib>
#include <iostream>
#include <votca/csg/topology.h>
#include "gmxtrajectoryreader.h"

namespace votca { namespace csg {

using namespace std;

bool GMXTrajectoryReader::Open(const string &file)
{
       _filename = file;
       return true;
}

void GMXTrajectoryReader::Close()
{
    close_trx(_gmx_status);
}

bool GMXTrajectoryReader::FirstFrame(Topology &conf)
{
    set_program_name("VOTCA");

#if GMX == 50

    output_env_t oenv;
    // _snew("oenv", oenv, 1);
    oenv = (output_env_t)malloc(sizeof(*oenv));
    output_env_init_default (oenv);

    if(!read_first_frame(oenv, &_gmx_status,(char*)_filename.c_str(),&_gmx_frame,TRX_READ_X | TRX_READ_V | TRX_READ_F))
        throw std::runtime_error(string("cannot open ") + _filename);
    //sfree(oenv);
    free(oenv);
#elif GMX == 45
    output_env_t oenv;
    // _snew("oenv", oenv, 1);
    oenv = (output_env_t)malloc(sizeof(*oenv));
    output_env_init_default (oenv);

    if(!read_first_frame(oenv, &_gmx_status,(char*)_filename.c_str(),&_gmx_frame,TRX_READ_X | TRX_READ_V | TRX_READ_F))
        throw std::runtime_error(string("cannot open ") + _filename);
    //sfree(oenv);
    free(oenv);
#elif GMX == 40
    if(!read_first_frame(&_gmx_status,(char*)_filename.c_str(),&_gmx_frame,TRX_READ_X  | TRX_READ_V | TRX_READ_F))
        throw std::runtime_error(string("cannot open ") + _filename);
#else
#error Unsupported GMX version
#endif

    matrix m;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            m[i][j] = _gmx_frame.box[j][i];
    conf.setBox(m);
    conf.setTime(_gmx_frame.time);
    conf.setStep(_gmx_frame.step);
    cout << endl;

    if(_gmx_frame.natoms != (int)conf.Beads().size())
        throw std::runtime_error("number of beads in trajectory do not match topology");

    //conf.HasPos(true);
    //conf.HasF(_gmx_frame.bF);

    for(int i=0; i<_gmx_frame.natoms; i++) {
        double r[3] = { _gmx_frame.x[i][XX],  _gmx_frame.x[i][YY], _gmx_frame.x[i][ZZ] };
        conf.getBead(i)->setPos(r);
        if(_gmx_frame.bF) {
            double f[3] = { _gmx_frame.f[i][XX],  _gmx_frame.f[i][YY], _gmx_frame.f[i][ZZ] };
            conf.getBead(i)->setF(f);
        }
        if(_gmx_frame.bV) {
            double v[3] = { _gmx_frame.v[i][XX],  _gmx_frame.v[i][YY], _gmx_frame.v[i][ZZ] };
            conf.getBead(i)->setVel(v);
        }
    }
    return true;
}

bool GMXTrajectoryReader::NextFrame(Topology &conf)
{
#if GMX == 50
    output_env_t oenv;
    //_snew("oenv", oenv, 1);
    oenv = (output_env_t)malloc(sizeof(*oenv));
    output_env_init_default (oenv);
    if(!read_next_frame(oenv, _gmx_status,&_gmx_frame))
        return false;
    //sfree(oenv);
    free(oenv);
#elif GMX == 45
    output_env_t oenv;
    //_snew("oenv", oenv, 1);
    oenv = (output_env_t)malloc(sizeof(*oenv));
    output_env_init_default (oenv);
    if(!read_next_frame(oenv, _gmx_status,&_gmx_frame))
        return false;
    //sfree(oenv);
    free(oenv);
#elif GMX == 40
    if(!read_next_frame(_gmx_status,&_gmx_frame))
        return false;
#else
#error Unsupported GMX version
#endif

    matrix m;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            m[i][j] = _gmx_frame.box[j][i];
    conf.setTime(_gmx_frame.time);
    conf.setStep(_gmx_frame.step);
    conf.setBox(m);

    //conf.HasF(_gmx_frame.bF);

    for(int i=0; i<_gmx_frame.natoms; i++) {
        double r[3] = { _gmx_frame.x[i][XX],  _gmx_frame.x[i][YY], _gmx_frame.x[i][ZZ] };
        conf.getBead(i)->setPos(r);
        if(_gmx_frame.bF) {
            double f[3] = { _gmx_frame.f[i][XX],  _gmx_frame.f[i][YY], _gmx_frame.f[i][ZZ] };
            conf.getBead(i)->setF(f);
        }
        if(_gmx_frame.bV) {
            double v[3] = { _gmx_frame.v[i][XX],  _gmx_frame.v[i][YY], _gmx_frame.v[i][ZZ] };
            conf.getBead(i)->setVel(v);
        }

    }
    return true;
}

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

#include <cstdlib>
#include <iostream>
#include <votca/csg/topology.h>
#include "gmxtrajectoryreader.h"

namespace votca { namespace csg {

using namespace std;

bool GMXTrajectoryReader::Open(const string &file)
{
       _filename = file;
       return true;
}

void GMXTrajectoryReader::Close()
{
    close_trx(_gmx_status);
}

bool GMXTrajectoryReader::FirstFrame(Topology &conf)
{
    set_program_name("VOTCA");

#if GMX == 50

    output_env_t oenv;
    // _snew("oenv", oenv, 1);
    //oenv = (output_env_t)malloc(sizeof(*oenv));
    output_env_init_default (&oenv);

    if(!read_first_frame(oenv, &_gmx_status,(char*)_filename.c_str(),&_gmx_frame,TRX_READ_X | TRX_READ_V | TRX_READ_F))
        throw std::runtime_error(string("cannot open ") + _filename);
    //sfree(oenv);
    free(oenv);
#elif GMX == 45
    output_env_t oenv;
    // _snew("oenv", oenv, 1);
    oenv = (output_env_t)malloc(sizeof(*oenv));
    output_env_init_default (oenv);

    if(!read_first_frame(oenv, &_gmx_status,(char*)_filename.c_str(),&_gmx_frame,TRX_READ_X | TRX_READ_V | TRX_READ_F))
        throw std::runtime_error(string("cannot open ") + _filename);
    //sfree(oenv);
    free(oenv);
#elif GMX == 40
    if(!read_first_frame(&_gmx_status,(char*)_filename.c_str(),&_gmx_frame,TRX_READ_X  | TRX_READ_V | TRX_READ_F))
        throw std::runtime_error(string("cannot open ") + _filename);
#else
#error Unsupported GMX version
#endif

    matrix m;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            m[i][j] = _gmx_frame.box[j][i];
    conf.setBox(m);
    conf.setTime(_gmx_frame.time);
    conf.setStep(_gmx_frame.step);
    cout << endl;

    if(_gmx_frame.natoms != (int)conf.Beads().size())
        throw std::runtime_error("number of beads in trajectory do not match topology");

    //conf.HasPos(true);
    //conf.HasF(_gmx_frame.bF);

    for(int i=0; i<_gmx_frame.natoms; i++) {
        double r[3] = { _gmx_frame.x[i][XX],  _gmx_frame.x[i][YY], _gmx_frame.x[i][ZZ] };
        conf.getBead(i)->setPos(r);
        if(_gmx_frame.bF) {
            double f[3] = { _gmx_frame.f[i][XX],  _gmx_frame.f[i][YY], _gmx_frame.f[i][ZZ] };
            conf.getBead(i)->setF(f);
        }
        if(_gmx_frame.bV) {
            double v[3] = { _gmx_frame.v[i][XX],  _gmx_frame.v[i][YY], _gmx_frame.v[i][ZZ] };
            conf.getBead(i)->setVel(v);
        }
    }
    return true;
}

bool GMXTrajectoryReader::NextFrame(Topology &conf)
{
#if GMX == 50
    output_env_t oenv;
    //_snew("oenv", oenv, 1);
    //oenv = (output_env_t)malloc(sizeof(*oenv));
    output_env_init_default (&oenv);
    if(!read_next_frame(oenv, _gmx_status,&_gmx_frame))
        return false;
    //sfree(oenv);
    free(oenv);
#elif GMX == 45
    output_env_t oenv;
    //_snew("oenv", oenv, 1);
    oenv = (output_env_t)malloc(sizeof(*oenv));
    output_env_init_default (oenv);
    if(!read_next_frame(oenv, _gmx_status,&_gmx_frame))
        return false;
    //sfree(oenv);
    free(oenv);
#elif GMX == 40
    if(!read_next_frame(_gmx_status,&_gmx_frame))
        return false;
#else
#error Unsupported GMX version
#endif

    matrix m;
    for(int i=0; i<3; i++)
        for(int j=0; j<3; j++)
            m[i][j] = _gmx_frame.box[j][i];
    conf.setTime(_gmx_frame.time);
    conf.setStep(_gmx_frame.step);
    conf.setBox(m);

    //conf.HasF(_gmx_frame.bF);

    for(int i=0; i<_gmx_frame.natoms; i++) {
        double r[3] = { _gmx_frame.x[i][XX],  _gmx_frame.x[i][YY], _gmx_frame.x[i][ZZ] };
        conf.getBead(i)->setPos(r);
        if(_gmx_frame.bF) {
            double f[3] = { _gmx_frame.f[i][XX],  _gmx_frame.f[i][YY], _gmx_frame.f[i][ZZ] };
            conf.getBead(i)->setF(f);
        }
        if(_gmx_frame.bV) {
            double v[3] = { _gmx_frame.v[i][XX],  _gmx_frame.v[i][YY], _gmx_frame.v[i][ZZ] };
            conf.getBead(i)->setVel(v);
        }

    }
    return true;
}

}}
<|endoftext|>


<commit_before>#include <iostream>
#include "ctc_beam_entry.h"
#include "ctc_beam_scorer.h"
#include "ctc_beam_search.h"
#include "ctc_labels.h"
#include "ctc_decoder.h"
#include "util/status.h"
#include "TH.h"
#include "cpu_binding.h"

#ifdef INCLUDE_KENLM
#include "ctc_beam_scorer_klm.h"
#include "ctc_trie_node.h"
#include "lm/model.hh"
#endif

namespace pytorch {
  using pytorch::ctc::Labels;
  using pytorch::ctc::Status;

  #ifdef INCLUDE_KENLM
  using pytorch::ctc::KenLMBeamScorer;
  using pytorch::ctc::ctc_beam_search::KenLMBeamState;
  typedef lm::ngram::ProbingModel Model;

  lm::WordIndex GetWordIndex(const Model& model, const std::string& word) {
    lm::WordIndex vocab;
    vocab = model.GetVocabulary().Index(word);
    return vocab;
  }

  float ScoreWord(const Model& model, lm::WordIndex vocab) {
    Model::State in_state = model.NullContextState();
    Model::State out;
    lm::FullScoreReturn full_score_return;
    full_score_return = model.FullScore(in_state, vocab, out);
    return full_score_return.prob;
  }

  int generate_trie(Labels& labels, const char* kenlm_path, const char* vocab_path, const char* trie_path) {
    lm::ngram::Config config;
    config.load_method = util::POPULATE_OR_READ;
    Model model(kenlm_path, config);
    ctc::TrieNode root(labels.GetSize());

    std::ifstream ifs;
    ifs.open(vocab_path, std::ifstream::in);

    if (!ifs.is_open()) {
      std::cout << "unable to open vocabulary" << std::endl;
      return -1;
    }

    std::ofstream ofs;
    ofs.open(trie_path);

    std::string word;
    while (ifs >> word) {
      lm::WordIndex vocab = GetWordIndex(model, word);
      float unigram_score = ScoreWord(model, vocab);
      std::wstring wide_word;
      utf8::utf8to16(word.begin(), word.end(), std::back_inserter(wide_word));
      root.Insert(wide_word.c_str(), [&labels](wchar_t c) {
                    return labels.GetLabel(c);
                  }, vocab, unigram_score);
    }

    root.WriteToStream(ofs);
    ifs.close();
    ofs.close();
    return 0;
  }
  #endif

  extern "C"
  {
    void* get_kenlm_scorer(const wchar_t* label_str, int labels_size, int space_index, int blank_index,
                           const char* lm_path, const char* trie_path) {
      #ifdef INCLUDE_KENLM
      Labels* labels = new Labels(label_str, labels_size, blank_index, space_index);
      ctc::KenLMBeamScorer *beam_scorer = new ctc::KenLMBeamScorer(labels, lm_path, trie_path);
      return static_cast<void*>(beam_scorer);
      #else
      return nullptr;
      #endif
    }

    void set_kenlm_scorer_lm_weight(void *scorer, float weight) {
      #ifdef INCLUDE_KENLM
      ctc::KenLMBeamScorer *beam_scorer = static_cast<ctc::KenLMBeamScorer *>(scorer);
      beam_scorer->SetLMWeight(weight);
      #endif
    }

    void set_kenlm_scorer_wc_weight(void *scorer, float weight) {
      #ifdef INCLUDE_KENLM
      ctc::KenLMBeamScorer *beam_scorer = static_cast<ctc::KenLMBeamScorer *>(scorer);
      beam_scorer->SetWordCountWeight(weight);
      #endif
    }

    void set_kenlm_scorer_vwc_weight(void *scorer, float weight) {
      #ifdef INCLUDE_KENLM
      ctc::KenLMBeamScorer *beam_scorer = static_cast<ctc::KenLMBeamScorer *>(scorer);
      beam_scorer->SetValidWordCountWeight(weight);
      #endif
    }

    void* get_base_scorer() {
      ctc::CTCBeamSearchDecoder<>::DefaultBeamScorer *beam_scorer = new ctc::CTCBeamSearchDecoder<>::DefaultBeamScorer();
      return static_cast<void *>(beam_scorer);
    }

    void* get_ctc_beam_decoder(int num_classes, int top_paths, int beam_width, int blank_index, int merge_repeated, void *scorer, DecodeType type) {
      switch (type) {
        case CTC:
          {
            ctc::CTCBeamSearchDecoder<>::DefaultBeamScorer *beam_scorer = static_cast<ctc::CTCBeamSearchDecoder<>::DefaultBeamScorer *>(scorer);
            ctc::CTCBeamSearchDecoder<> *decoder = new ctc::CTCBeamSearchDecoder<>
                (num_classes, beam_width, beam_scorer, blank_index, merge_repeated == 1);
            return static_cast<void *>(decoder);
          }
        #ifdef INCLUDE_KENLM
        case CTC_KENLM:
        {
          ctc::KenLMBeamScorer *beam_scorer = static_cast<ctc::KenLMBeamScorer*>(scorer);
          ctc::CTCBeamSearchDecoder<KenLMBeamState> *decoder = new ctc::CTCBeamSearchDecoder<KenLMBeamState>
              (num_classes, beam_width, beam_scorer, blank_index, merge_repeated == 1);
          return static_cast<void *>(decoder);
        }
        #endif
      }
      return nullptr;
    }

    int ctc_beam_decode(void *void_decoder, DecodeType type, THFloatTensor *th_probs, THIntTensor *th_seq_len, THIntTensor *th_output,
                        THFloatTensor *th_scores, THIntTensor *th_out_len)
    {
      const int64_t max_time = THFloatTensor_size(th_probs, 0);
      const int64_t batch_size = THFloatTensor_size(th_probs, 1);
      const int64_t num_classes = THFloatTensor_size(th_probs, 2);
      const int64_t top_paths = THIntTensor_size(th_output, 0);

      // convert tensors to something the beam scorer can use
      // sequence length
      int* seq_len_ptr = THIntTensor_data(th_seq_len);
      ptrdiff_t seq_len_offset = THIntTensor_storageOffset(th_seq_len);
      Eigen::Map<const Eigen::ArrayXi> seq_len(seq_len_ptr + seq_len_offset, batch_size);

      // input logits
      float* probs_ptr = THFloatTensor_data(th_probs);
      ptrdiff_t probs_offset = THFloatTensor_storageOffset(th_probs);
      const int64_t probs_stride_0 = THFloatTensor_stride(th_probs, 0);
      const int64_t probs_stride_1 = THFloatTensor_stride(th_probs, 1);
      const int64_t probs_stride_2 = THFloatTensor_stride(th_probs, 2);
      std::vector<Eigen::Map<Eigen::MatrixXf, 0, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>> inputs;
      for (int t=0; t < max_time; ++t) {
        inputs.emplace_back(probs_ptr + probs_offset + (t*probs_stride_0), batch_size, num_classes, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>(probs_stride_2, probs_stride_1));
      }

      // prepare/initialize output variables
      // paths, batches, class
      std::vector<ctc::CTCDecoder::Output> outputs(top_paths);
      for (ctc::CTCDecoder::Output& output : outputs) {
        output.resize(batch_size);
      }

      float score[batch_size][top_paths] = {{0.0}};
      Eigen::Map<Eigen::MatrixXf> *scores;

      // TODO: this is ugly -- can we better leverage generics somehow?
      switch (type) {
        case CTC:
          {
            ctc::CTCBeamSearchDecoder<> *decoder = static_cast<ctc::CTCBeamSearchDecoder<> *>(void_decoder);
            scores = new Eigen::Map<Eigen::MatrixXf>(&score[0][0], batch_size, decoder->GetBeamWidth());
            Status stat = decoder->Decode(seq_len, inputs, &outputs, scores);
            if (!stat.ok()) {
              return 0;
            }
          }
          break;
        #ifdef INCLUDE_KENLM
        case CTC_KENLM:
          {
            ctc::CTCBeamSearchDecoder<KenLMBeamState> *decoder = static_cast<ctc::CTCBeamSearchDecoder<KenLMBeamState> *>(void_decoder);
            scores = new Eigen::Map<Eigen::MatrixXf>(&score[0][0], batch_size, decoder->GetBeamWidth());
            Status stat = decoder->Decode(seq_len, inputs, &outputs, scores);
            if (!stat.ok()) {
              return 0;
            }
          }
          break;
        #endif
      }

      std::vector<float> log_probs;
      for (int p=0; p < top_paths; ++p) {
        int64_t max_decoded = 0;
        int64_t offset = 0;
        for (int b=0; b < batch_size; ++b) {
          auto& p_batch = outputs[p][b];
          int64_t num_decoded = p_batch.size();

          max_decoded = std::max(max_decoded, num_decoded);
          THIntTensor_set2d(th_out_len, p, b, num_decoded);
          for (int64_t t=0; t < num_decoded; ++t) {
            // TODO: this could be more efficient (significant pointer arithmetic every time currently)
            THIntTensor_set3d(th_output, p, b, t, p_batch[t]);
            THFloatTensor_set2d(th_scores, p, b, (*scores)(b, p));
          }
        }
      }
      delete scores;
      return 1;
    }

    int generate_lm_trie(const wchar_t* label_str, int size, int blank_index, int space_index,
                         const char* lm_path, const char* dictionary_path, const char* output_path) {
        #ifdef INCLUDE_KENLM
        Labels labels(label_str, size, blank_index, space_index);
        return generate_trie(labels, lm_path, dictionary_path, output_path);
        #else
        return -1;
        #endif
    }

    int kenlm_enabled() {
      #ifdef INCLUDE_KENLM
      return 1;
      #else
      return 0;
      #endif
    }
  }
}
<commit_msg>Changed dynamic allocation to handle gcc compile errors<commit_after>#include <iostream>
#include "ctc_beam_entry.h"
#include "ctc_beam_scorer.h"
#include "ctc_beam_search.h"
#include "ctc_labels.h"
#include "ctc_decoder.h"
#include "util/status.h"
#include "TH.h"
#include "cpu_binding.h"

#ifdef INCLUDE_KENLM
#include "ctc_beam_scorer_klm.h"
#include "ctc_trie_node.h"
#include "lm/model.hh"
#endif

namespace pytorch {
  using pytorch::ctc::Labels;
  using pytorch::ctc::Status;

  #ifdef INCLUDE_KENLM
  using pytorch::ctc::KenLMBeamScorer;
  using pytorch::ctc::ctc_beam_search::KenLMBeamState;
  typedef lm::ngram::ProbingModel Model;

  lm::WordIndex GetWordIndex(const Model& model, const std::string& word) {
    lm::WordIndex vocab;
    vocab = model.GetVocabulary().Index(word);
    return vocab;
  }

  float ScoreWord(const Model& model, lm::WordIndex vocab) {
    Model::State in_state = model.NullContextState();
    Model::State out;
    lm::FullScoreReturn full_score_return;
    full_score_return = model.FullScore(in_state, vocab, out);
    return full_score_return.prob;
  }

  int generate_trie(Labels& labels, const char* kenlm_path, const char* vocab_path, const char* trie_path) {
    lm::ngram::Config config;
    config.load_method = util::POPULATE_OR_READ;
    Model model(kenlm_path, config);
    ctc::TrieNode root(labels.GetSize());

    std::ifstream ifs;
    ifs.open(vocab_path, std::ifstream::in);

    if (!ifs.is_open()) {
      std::cout << "unable to open vocabulary" << std::endl;
      return -1;
    }

    std::ofstream ofs;
    ofs.open(trie_path);

    std::string word;
    while (ifs >> word) {
      lm::WordIndex vocab = GetWordIndex(model, word);
      float unigram_score = ScoreWord(model, vocab);
      std::wstring wide_word;
      utf8::utf8to16(word.begin(), word.end(), std::back_inserter(wide_word));
      root.Insert(wide_word.c_str(), [&labels](wchar_t c) {
                    return labels.GetLabel(c);
                  }, vocab, unigram_score);
    }

    root.WriteToStream(ofs);
    ifs.close();
    ofs.close();
    return 0;
  }
  #endif

  extern "C"
  {
    void* get_kenlm_scorer(const wchar_t* label_str, int labels_size, int space_index, int blank_index,
                           const char* lm_path, const char* trie_path) {
      #ifdef INCLUDE_KENLM
      Labels* labels = new Labels(label_str, labels_size, blank_index, space_index);
      ctc::KenLMBeamScorer *beam_scorer = new ctc::KenLMBeamScorer(labels, lm_path, trie_path);
      return static_cast<void*>(beam_scorer);
      #else
      return nullptr;
      #endif
    }

    void set_kenlm_scorer_lm_weight(void *scorer, float weight) {
      #ifdef INCLUDE_KENLM
      ctc::KenLMBeamScorer *beam_scorer = static_cast<ctc::KenLMBeamScorer *>(scorer);
      beam_scorer->SetLMWeight(weight);
      #endif
    }

    void set_kenlm_scorer_wc_weight(void *scorer, float weight) {
      #ifdef INCLUDE_KENLM
      ctc::KenLMBeamScorer *beam_scorer = static_cast<ctc::KenLMBeamScorer *>(scorer);
      beam_scorer->SetWordCountWeight(weight);
      #endif
    }

    void set_kenlm_scorer_vwc_weight(void *scorer, float weight) {
      #ifdef INCLUDE_KENLM
      ctc::KenLMBeamScorer *beam_scorer = static_cast<ctc::KenLMBeamScorer *>(scorer);
      beam_scorer->SetValidWordCountWeight(weight);
      #endif
    }

    void* get_base_scorer() {
      ctc::CTCBeamSearchDecoder<>::DefaultBeamScorer *beam_scorer = new ctc::CTCBeamSearchDecoder<>::DefaultBeamScorer();
      return static_cast<void *>(beam_scorer);
    }

    void* get_ctc_beam_decoder(int num_classes, int top_paths, int beam_width, int blank_index, int merge_repeated, void *scorer, DecodeType type) {
      switch (type) {
        case CTC:
          {
            ctc::CTCBeamSearchDecoder<>::DefaultBeamScorer *beam_scorer = static_cast<ctc::CTCBeamSearchDecoder<>::DefaultBeamScorer *>(scorer);
            ctc::CTCBeamSearchDecoder<> *decoder = new ctc::CTCBeamSearchDecoder<>
                (num_classes, beam_width, beam_scorer, blank_index, merge_repeated == 1);
            return static_cast<void *>(decoder);
          }
        #ifdef INCLUDE_KENLM
        case CTC_KENLM:
        {
          ctc::KenLMBeamScorer *beam_scorer = static_cast<ctc::KenLMBeamScorer*>(scorer);
          ctc::CTCBeamSearchDecoder<KenLMBeamState> *decoder = new ctc::CTCBeamSearchDecoder<KenLMBeamState>
              (num_classes, beam_width, beam_scorer, blank_index, merge_repeated == 1);
          return static_cast<void *>(decoder);
        }
        #endif
      }
      return nullptr;
    }

    int ctc_beam_decode(void *void_decoder, DecodeType type, THFloatTensor *th_probs, THIntTensor *th_seq_len, THIntTensor *th_output,
                        THFloatTensor *th_scores, THIntTensor *th_out_len)
    {
      const int64_t max_time = THFloatTensor_size(th_probs, 0);
      const int64_t batch_size = THFloatTensor_size(th_probs, 1);
      const int64_t num_classes = THFloatTensor_size(th_probs, 2);
      const int64_t top_paths = THIntTensor_size(th_output, 0);

      // convert tensors to something the beam scorer can use
      // sequence length
      int* seq_len_ptr = THIntTensor_data(th_seq_len);
      ptrdiff_t seq_len_offset = THIntTensor_storageOffset(th_seq_len);
      Eigen::Map<const Eigen::ArrayXi> seq_len(seq_len_ptr + seq_len_offset, batch_size);

      // input logits
      float* probs_ptr = THFloatTensor_data(th_probs);
      ptrdiff_t probs_offset = THFloatTensor_storageOffset(th_probs);
      const int64_t probs_stride_0 = THFloatTensor_stride(th_probs, 0);
      const int64_t probs_stride_1 = THFloatTensor_stride(th_probs, 1);
      const int64_t probs_stride_2 = THFloatTensor_stride(th_probs, 2);
      std::vector<Eigen::Map<Eigen::MatrixXf, 0, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>>> inputs;
      for (int t=0; t < max_time; ++t) {
        inputs.emplace_back(probs_ptr + probs_offset + (t*probs_stride_0), batch_size, num_classes, Eigen::Stride<Eigen::Dynamic, Eigen::Dynamic>(probs_stride_2, probs_stride_1));
      }

      // prepare/initialize output variables
      // paths, batches, class
      std::vector<ctc::CTCDecoder::Output> outputs(top_paths);
      for (ctc::CTCDecoder::Output& output : outputs) {
        output.resize(batch_size);
      }
      float score[batch_size][top_paths];
      memset(score, 0.0, batch_size*top_paths*sizeof(int));
      Eigen::Map<Eigen::MatrixXf> *scores;

      // TODO: this is ugly -- can we better leverage generics somehow?
      switch (type) {
        case CTC:
          {
            ctc::CTCBeamSearchDecoder<> *decoder = static_cast<ctc::CTCBeamSearchDecoder<> *>(void_decoder);
            scores = new Eigen::Map<Eigen::MatrixXf>(&score[0][0], batch_size, decoder->GetBeamWidth());
            Status stat = decoder->Decode(seq_len, inputs, &outputs, scores);
            if (!stat.ok()) {
              return 0;
            }
          }
          break;
        #ifdef INCLUDE_KENLM
        case CTC_KENLM:
          {
            ctc::CTCBeamSearchDecoder<KenLMBeamState> *decoder = static_cast<ctc::CTCBeamSearchDecoder<KenLMBeamState> *>(void_decoder);
            scores = new Eigen::Map<Eigen::MatrixXf>(&score[0][0], batch_size, decoder->GetBeamWidth());
            Status stat = decoder->Decode(seq_len, inputs, &outputs, scores);
            if (!stat.ok()) {
              return 0;
            }
          }
          break;
        #endif
      }

      std::vector<float> log_probs;
      for (int p=0; p < top_paths; ++p) {
        int64_t max_decoded = 0;
        int64_t offset = 0;
        for (int b=0; b < batch_size; ++b) {
          auto& p_batch = outputs[p][b];
          int64_t num_decoded = p_batch.size();

          max_decoded = std::max(max_decoded, num_decoded);
          THIntTensor_set2d(th_out_len, p, b, num_decoded);
          for (int64_t t=0; t < num_decoded; ++t) {
            // TODO: this could be more efficient (significant pointer arithmetic every time currently)
            THIntTensor_set3d(th_output, p, b, t, p_batch[t]);
            THFloatTensor_set2d(th_scores, p, b, (*scores)(b, p));
          }
        }
      }
      delete scores;
      return 1;
    }

    int generate_lm_trie(const wchar_t* label_str, int size, int blank_index, int space_index,
                         const char* lm_path, const char* dictionary_path, const char* output_path) {
        #ifdef INCLUDE_KENLM
        Labels labels(label_str, size, blank_index, space_index);
        return generate_trie(labels, lm_path, dictionary_path, output_path);
        #else
        return -1;
        #endif
    }

    int kenlm_enabled() {
      #ifdef INCLUDE_KENLM
      return 1;
      #else
      return 0;
      #endif
    }
  }
}
<|endoftext|>


<commit_before>// RUN: cat %s | %cling 2>&1 | FileCheck %s
// Test Interpreter::lookupFunctionProto()
#include "cling/Interpreter/Interpreter.h"
#include "clang/AST/Decl.h"

#include <cstdio>
using namespace std;

//
//  We need to fetch the global scope declaration,
//  otherwise known as the translation unit decl.
//
const clang::Decl* G = gCling->lookupScope("");
printf("G: 0x%lx\n", (unsigned long) G);
//CHECK: G: 0x{{[1-9a-f][0-9a-f]*$}}

//
//  Test finding a global function taking no args.
//

.rawInput 1
void f() { int x = 1; }
.rawInput 0

const clang::FunctionDecl* F = gCling->lookupFunctionProto(G, "f", "");
printf("F: 0x%lx\n", (unsigned long) F);
//CHECK-NEXT: F: 0x{{[1-9a-f][0-9a-f]*$}}
F->print(llvm::outs());
//CHECK-NEXT: void f() {
//CHECK-NEXT:     int x = 1;
//CHECK-NEXT: }

//
//  Test finding a global function taking a single int argument.
//

.rawInput 1
void a(int v) { int x = v; }
.rawInput 0

const clang::FunctionDecl* A = gCling->lookupFunctionProto(G, "a", "int");
printf("A: 0x%lx\n", (unsigned long) A);
//CHECK: A: 0x{{[1-9a-f][0-9a-f]*$}}
A->print(llvm::outs());
//CHECK-NEXT: void a(int v) {
//CHECK-NEXT:     int x = v;
//CHECK-NEXT: }

//
//  Test finding a global function taking an int and a double argument.
//

.rawInput 1
void b(int vi, double vd) { int x = vi; double y = vd; }
.rawInput 0

const clang::FunctionDecl* B = gCling->lookupFunctionProto(G, "b", "int,double");
printf("B: 0x%lx\n", (unsigned long) B);
//CHECK: B: 0x{{[1-9a-f][0-9a-f]*$}}
B->print(llvm::outs());
//CHECK-NEXT: void b(int vi, double vd) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     double y = vd;
//CHECK-NEXT: }

//
//  Test finding a global overloaded function.
//

.rawInput 1
void c(int vi, int vj) { int x = vi; int y = vj; }
void c(int vi, double vd) { int x = vi; double y = vd; }
.rawInput 0

const clang::FunctionDecl* C1 = gCling->lookupFunctionProto(G, "c", "int,int");
printf("C1: 0x%lx\n", (unsigned long) C1);
//CHECK: C1: 0x{{[1-9a-f][0-9a-f]*$}}
C1->print(llvm::outs());
//CHECK-NEXT: void c(int vi, int vj) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     int y = vj;
//CHECK-NEXT: }

const clang::FunctionDecl* C2 = gCling->lookupFunctionProto(G, "c", "int,double");
printf("C2: 0x%lx\n", (unsigned long) C2);
//CHECK: C2: 0x{{[1-9a-f][0-9a-f]*$}}
C2->print(llvm::outs());
//CHECK-NEXT: void c(int vi, double vd) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     double y = vd;
//CHECK-NEXT: }

//
//  Test finding simple global template instantiations.
//

.rawInput 1
template <class T> void d(T v) { T x = v; }
// Note: In CINT, looking up a class template specialization causes
//       instantiation, but looking up a function template specialization
//       does not.
template void d(int);
template void d(double);
.rawInput 0

const clang::FunctionDecl* D1 = gCling->lookupFunctionProto(G, "d<int>", "int");
printf("D1: 0x%lx\n", (unsigned long) D1);
//CHECK: D1: 0x{{[1-9a-f][0-9a-f]*$}}
D1->print(llvm::outs());
//CHECK-NEXT: void d(int v) {
//CHECK-NEXT:     int x = v;
//CHECK-NEXT: }

const clang::FunctionDecl* D2 = gCling->lookupFunctionProto(G, "d<double>", "double");
printf("D2: 0x%lx\n", (unsigned long) D2);
//CHECK: D2: 0x{{[1-9a-f][0-9a-f]*$}}
D2->print(llvm::outs());
//CHECK-NEXT: void d(double v) {
//CHECK-NEXT:     double x = v;
//CHECK-NEXT: }

//
//  Test finding a member function taking no args.
//

.rawInput 1
class A {
   void A_f() { int x = 1; }
};
.rawInput 0

const clang::Decl* class_A = gCling->lookupScope("A");
printf("class_A: 0x%lx\n", (unsigned long) class_A);
//CHECK: class_A: 0x{{[1-9a-f][0-9a-f]*$}}
const clang::FunctionDecl* class_A_F = gCling->lookupFunctionProto(class_A, "A_f", "");
printf("class_A_F: 0x%lx\n", (unsigned long) class_A_F);
//CHECK-NEXT: class_A_F: 0x{{[1-9a-f][0-9a-f]*$}}
class_A_F->print(llvm::outs());
//CHECK-NEXT: void A_f() {
//CHECK-NEXT:     int x = 1;
//CHECK-NEXT: }

//
//  Test finding a member function taking an int arg.
//

.rawInput 1
class B {
   void B_f(int v) { int x = v; }
};
.rawInput 0

const clang::Decl* class_B = gCling->lookupScope("B");
printf("class_B: 0x%lx\n", (unsigned long) class_B);
//CHECK: class_B: 0x{{[1-9a-f][0-9a-f]*$}}
const clang::FunctionDecl* class_B_F = gCling->lookupFunctionProto(class_B, "B_f", "int");
printf("class_B_F: 0x%lx\n", (unsigned long) class_B_F);
//CHECK-NEXT: class_B_F: 0x{{[1-9a-f][0-9a-f]*$}}
class_B_F->print(llvm::outs());
//CHECK-NEXT: void B_f(int v) {
//CHECK-NEXT:     int x = v;
//CHECK-NEXT: }

//
//  Test finding a member function taking no args in a base class.
//

.rawInput 1
class C {
   void C_f() { int x = 1; }
};
class D : public C {
};
.rawInput 0

const clang::Decl* class_D = gCling->lookupScope("D");
printf("class_D: 0x%lx\n", (unsigned long) class_D);
//CHECK: class_D: 0x{{[1-9a-f][0-9a-f]*$}}
const clang::FunctionDecl* class_D_F = gCling->lookupFunctionProto(class_D, "C_f", "");
printf("class_D_F: 0x%lx\n", (unsigned long) class_D_F);
//CHECK-NEXT: class_D_F: 0x{{[1-9a-f][0-9a-f]*$}}
class_D_F->print(llvm::outs());
//CHECK-NEXT: void C_f() {
//CHECK-NEXT:     int x = 1;
//CHECK-NEXT: }

//
//  Test finding a member function taking an int arg in a base class.
//

.rawInput 1
class E {
   void E_f(int v) { int x = v; }
};
class F : public E {
};
.rawInput 0

const clang::Decl* class_F = gCling->lookupScope("F");
printf("class_F: 0x%lx\n", (unsigned long) class_F);
//CHECK: class_F: 0x{{[1-9a-f][0-9a-f]*$}}
const clang::FunctionDecl* class_F_F = gCling->lookupFunctionProto(class_F, "E_f", "int");
printf("class_F_F: 0x%lx\n", (unsigned long) class_F_F);
//CHECK-NEXT: class_F_F: 0x{{[1-9a-f][0-9a-f]*$}}
class_F_F->print(llvm::outs());
//CHECK-NEXT: void E_f(int v) {
//CHECK-NEXT:     int x = v;
//CHECK-NEXT: }

//
//  One final check to make sure we are at the right line in the output.
//

"abc"
//CHECK: (const char [4]) @0x{{[0-9a-f]+}}
<commit_msg>Use same tests and test classes as funcargs.C.<commit_after>// RUN: cat %s | %cling 2>&1 | FileCheck %s
// Test Interpreter::lookupFunctionProto()
#include "cling/Interpreter/Interpreter.h"
#include "clang/AST/Decl.h"

#include <cstdio>
using namespace std;

//
//  We need to fetch the global scope declaration,
//  otherwise known as the translation unit decl.
//
const clang::Decl* G = gCling->lookupScope("");
printf("G: 0x%lx\n", (unsigned long) G);
//CHECK: G: 0x{{[1-9a-f][0-9a-f]*$}}

//
//  Test finding a global function taking no args.
//

.rawInput 1
void f() { int x = 1; }
void a(int v) { int x = v; }
void b(int vi, double vd) { int x = vi; double y = vd; }
void c(int vi, int vj) { int x = vi; int y = vj; }
void c(int vi, double vd) { int x = vi; double y = vd; }
template <class T> void d(T v) { T x = v; }
// Note: In CINT, looking up a class template specialization causes
//       instantiation, but looking up a function template specialization
//       does not, so we explicitly request the instantiations we are
//       going to lookup so they will be there to find.
template void d(int);
template void d(double);
.rawInput 0

const clang::FunctionDecl* F = gCling->lookupFunctionProto(G, "f", "");
printf("F: 0x%lx\n", (unsigned long) F);
//CHECK-NEXT: F: 0x{{[1-9a-f][0-9a-f]*$}}
F->print(llvm::outs());
//CHECK-NEXT: void f() {
//CHECK-NEXT:     int x = 1;
//CHECK-NEXT: }

//
//  Test finding a global function taking a single int argument.
//

const clang::FunctionDecl* A = gCling->lookupFunctionProto(G, "a", "int");
printf("A: 0x%lx\n", (unsigned long) A);
//CHECK: A: 0x{{[1-9a-f][0-9a-f]*$}}
A->print(llvm::outs());
//CHECK-NEXT: void a(int v) {
//CHECK-NEXT:     int x = v;
//CHECK-NEXT: }

//
//  Test finding a global function taking an int and a double argument.
//

const clang::FunctionDecl* B = gCling->lookupFunctionProto(G, "b", "int,double");
printf("B: 0x%lx\n", (unsigned long) B);
//CHECK: B: 0x{{[1-9a-f][0-9a-f]*$}}
B->print(llvm::outs());
//CHECK-NEXT: void b(int vi, double vd) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     double y = vd;
//CHECK-NEXT: }

//
//  Test finding a global overloaded function.
//

const clang::FunctionDecl* C1 = gCling->lookupFunctionProto(G, "c", "int,int");
printf("C1: 0x%lx\n", (unsigned long) C1);
//CHECK: C1: 0x{{[1-9a-f][0-9a-f]*$}}
C1->print(llvm::outs());
//CHECK-NEXT: void c(int vi, int vj) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     int y = vj;
//CHECK-NEXT: }

const clang::FunctionDecl* C2 = gCling->lookupFunctionProto(G, "c", "int,double");
printf("C2: 0x%lx\n", (unsigned long) C2);
//CHECK: C2: 0x{{[1-9a-f][0-9a-f]*$}}
C2->print(llvm::outs());
//CHECK-NEXT: void c(int vi, double vd) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     double y = vd;
//CHECK-NEXT: }

//
//  Test finding simple global template instantiations.
//

const clang::FunctionDecl* D1 = gCling->lookupFunctionProto(G, "d<int>", "int");
printf("D1: 0x%lx\n", (unsigned long) D1);
//CHECK: D1: 0x{{[1-9a-f][0-9a-f]*$}}
D1->print(llvm::outs());
//CHECK-NEXT: void d(int v) {
//CHECK-NEXT:     int x = v;
//CHECK-NEXT: }

const clang::FunctionDecl* D2 = gCling->lookupFunctionProto(G, "d<double>", "double");
printf("D2: 0x%lx\n", (unsigned long) D2);
//CHECK: D2: 0x{{[1-9a-f][0-9a-f]*$}}
D2->print(llvm::outs());
//CHECK-NEXT: void d(double v) {
//CHECK-NEXT:     double x = v;
//CHECK-NEXT: }

.rawInput 1
class B {
   void B_f() { int x = 1; }
   void B_g(int v) { int x = v; }
   void B_h(int vi, double vd) { int x = vi; double y = vd; }
   void B_j(int vi, int vj) { int x = vi; int y = vj; }
   void B_j(int vi, double vd) { int x = vi; double y = vd; }
   template <class T> void B_k(T v) { T x = v; }
};
class A : public B {
   void A_f() { int x = 1; }
   void A_g(int v) { int x = v; }
   void A_h(int vi, double vd) { int x = vi; double y = vd; }
   void A_j(int vi, int vj) { int x = vi; int y = vj; }
   void A_j(int vi, double vd) { int x = vi; double y = vd; }
   template <class T> void A_k(T v) { T x = v; }
};
// Note: In CINT, looking up a class template specialization causes
//       instantiation, but looking up a function template specialization
//       does not, so we explicitly request the instantiations we are
//       going to lookup so they will be there to find.
template void A::A_k(int);
template void A::A_k(double);
template void A::B_k(int);
template void A::B_k(double);
.rawInput 0

const clang::Decl* class_A = gCling->lookupScope("A");
printf("class_A: 0x%lx\n", (unsigned long) class_A);
//CHECK: class_A: 0x{{[1-9a-f][0-9a-f]*$}}

const clang::Decl* class_B = gCling->lookupScope("B");
printf("class_B: 0x%lx\n", (unsigned long) class_B);
//CHECK-NEXT: class_B: 0x{{[1-9a-f][0-9a-f]*$}}

//
//  Test finding a member function taking no args.
//

const clang::FunctionDecl* class_A_F = gCling->lookupFunctionProto(class_A, "A_f", "");
printf("class_A_F: 0x%lx\n", (unsigned long) class_A_F);
//CHECK-NEXT: class_A_F: 0x{{[1-9a-f][0-9a-f]*$}}
class_A_F->print(llvm::outs());
//CHECK-NEXT: void A_f() {
//CHECK-NEXT:     int x = 1;
//CHECK-NEXT: }

//
//  Test finding a member function taking an int arg.
//

const clang::FunctionDecl* func_A_g = gCling->lookupFunctionProto(class_A, "A_g", "int");
printf("func_A_g: 0x%lx\n", (unsigned long) func_A_g);
//CHECK: func_A_g: 0x{{[1-9a-f][0-9a-f]*$}}
func_A_g->print(llvm::outs());
//CHECK-NEXT: void A_g(int v) {
//CHECK-NEXT:     int x = v;
//CHECK-NEXT: }

//
//  Test finding a member function taking an int and a double argument.
//

const clang::FunctionDecl* func_A_h = gCling->lookupFunctionProto(class_A, "A_h", "int,double");
printf("func_A_h: 0x%lx\n", (unsigned long) func_A_h);
//CHECK: func_A_h: 0x{{[1-9a-f][0-9a-f]*$}}
func_A_h->print(llvm::outs());
//CHECK-NEXT: void A_h(int vi, double vd) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     double y = vd;
//CHECK-NEXT: }

//
//  Test finding an overloaded member function.
//

const clang::FunctionDecl* func_A_j1 = gCling->lookupFunctionProto(class_A, "A_j", "int,int");
printf("func_A_j1: 0x%lx\n", (unsigned long) func_A_j1);
//CHECK: func_A_j1: 0x{{[1-9a-f][0-9a-f]*$}}
func_A_j1->print(llvm::outs());
//CHECK-NEXT: void A_j(int vi, int vj) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     int y = vj;
//CHECK-NEXT: }

const clang::FunctionDecl* func_A_j2 = gCling->lookupFunctionProto(class_A, "A_j", "int,double");
printf("func_A_j2: 0x%lx\n", (unsigned long) func_A_j2);
//CHECK: func_A_j2: 0x{{[1-9a-f][0-9a-f]*$}}
func_A_j2->print(llvm::outs());
//CHECK-NEXT: void A_j(int vi, double vd) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     double y = vd;
//CHECK-NEXT: }

//
//  Test finding simple member function template instantiations.
//

const clang::FunctionDecl* func_A_k1 = gCling->lookupFunctionProto(class_A, "A_k<int>", "int");
printf("func_A_k1: 0x%lx\n", (unsigned long) func_A_k1);
//CHECK: func_A_k1: 0x{{[1-9a-f][0-9a-f]*$}}
func_A_k1->print(llvm::outs());
//CHECK-NEXT: void A_k(int v) {
//CHECK-NEXT:     int x = v;
//CHECK-NEXT: }

const clang::FunctionDecl* func_A_k2 = gCling->lookupFunctionProto(class_A, "A_k<double>", "double");
printf("func_A_k2: 0x%lx\n", (unsigned long) func_A_k2);
//CHECK: func_A_k2: 0x{{[1-9a-f][0-9a-f]*$}}
func_A_k2->print(llvm::outs());
//CHECK-NEXT: void A_k(double v) {
//CHECK-NEXT:     double x = v;
//CHECK-NEXT: }

//
//  Test finding a member function taking no args in a base class.
//

const clang::FunctionDecl* func_B_F = gCling->lookupFunctionProto(class_A, "B_f", "");
printf("func_B_F: 0x%lx\n", (unsigned long) func_B_F);
//CHECK: func_B_F: 0x{{[1-9a-f][0-9a-f]*$}}
func_B_F->print(llvm::outs());
//CHECK-NEXT: void B_f() {
//CHECK-NEXT:     int x = 1;
//CHECK-NEXT: }

//
//  Test finding a member function taking an int arg in a base class.
//

const clang::FunctionDecl* func_B_G = gCling->lookupFunctionProto(class_A, "B_g", "int");
printf("func_B_G: 0x%lx\n", (unsigned long) func_B_G);
//CHECK: func_B_G: 0x{{[1-9a-f][0-9a-f]*$}}
func_B_G->print(llvm::outs());
//CHECK-NEXT: void B_g(int v) {
//CHECK-NEXT:     int x = v;
//CHECK-NEXT: }

//
//  Test finding a member function taking an int and a double argument
//  in a base class.
//

const clang::FunctionDecl* func_B_h = gCling->lookupFunctionProto(class_A, "B_h", "int,double");
printf("func_B_h: 0x%lx\n", (unsigned long) func_B_h);
//CHECK: func_B_h: 0x{{[1-9a-f][0-9a-f]*$}}
func_B_h->print(llvm::outs());
//CHECK-NEXT: void B_h(int vi, double vd) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     double y = vd;
//CHECK-NEXT: }

//
//  Test finding an overloaded member function in a base class.
//

const clang::FunctionDecl* func_B_j1 = gCling->lookupFunctionProto(class_A, "B_j", "int,int");
printf("func_B_j1: 0x%lx\n", (unsigned long) func_B_j1);
//CHECK: func_B_j1: 0x{{[1-9a-f][0-9a-f]*$}}
func_B_j1->print(llvm::outs());
//CHECK-NEXT: void B_j(int vi, int vj) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     int y = vj;
//CHECK-NEXT: }

const clang::FunctionDecl* func_B_j2 = gCling->lookupFunctionProto(class_A, "B_j", "int,double");
printf("func_B_j2: 0x%lx\n", (unsigned long) func_B_j2);
//CHECK: func_B_j2: 0x{{[1-9a-f][0-9a-f]*$}}
func_B_j2->print(llvm::outs());
//CHECK-NEXT: void B_j(int vi, double vd) {
//CHECK-NEXT:     int x = vi;
//CHECK-NEXT:     double y = vd;
//CHECK-NEXT: }

//
//  Test finding simple member function template instantiations in a base class.
//

const clang::FunctionDecl* func_B_k1 = gCling->lookupFunctionProto(class_A, "B_k<int>", "int");
printf("func_B_k1: 0x%lx\n", (unsigned long) func_B_k1);
//CHECK: func_B_k1: 0x{{[1-9a-f][0-9a-f]*$}}
func_B_k1->print(llvm::outs());
//CHECK-NEXT: void B_k(int v) {
//CHECK-NEXT:     int x = v;
//CHECK-NEXT: }

const clang::FunctionDecl* func_B_k2 = gCling->lookupFunctionProto(class_A, "B_k<double>", "double");
printf("func_B_k2: 0x%lx\n", (unsigned long) func_B_k2);
//CHECK: func_B_k2: 0x{{[1-9a-f][0-9a-f]*$}}
func_B_k2->print(llvm::outs());
//CHECK-NEXT: void B_k(double v) {
//CHECK-NEXT:     double x = v;
//CHECK-NEXT: }

//
//  One final check to make sure we are at the right line in the output.
//

"abc"
//CHECK: (const char [4]) @0x{{[0-9a-f]+}}
<|endoftext|>


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

  Library:   CTK

  Copyright (c) Kitware Inc.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

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

//Qt includes
#include <QDebug>
#include <QLabel>
#include <QMessageBox>
#include <QProgressDialog>
#include <QSettings>
#include <QTreeView>
#include <QTabBar>

/// CTK includes
#include <ctkCheckableHeaderView.h>
#include <ctkCheckableModelHelper.h>
#include <ctkLogger.h>

// ctkDICOMCore includes
#include "ctkDICOMDatabase.h"
#include "ctkDICOMModel.h"
#include "ctkDICOMQuery.h"
#include "ctkDICOMRetrieve.h"

// ctkDICOMWidgets includes
#include "ctkDICOMQueryRetrieveWidget.h"
#include "ctkDICOMQueryResultsTabWidget.h"
#include "ui_ctkDICOMQueryRetrieveWidget.h"

static ctkLogger logger("org.commontk.DICOM.Widgets.ctkDICOMQueryRetrieveWidget");

//----------------------------------------------------------------------------
class ctkDICOMQueryRetrieveWidgetPrivate: public Ui_ctkDICOMQueryRetrieveWidget
{
  Q_DECLARE_PUBLIC( ctkDICOMQueryRetrieveWidget );

protected:
  ctkDICOMQueryRetrieveWidget* const q_ptr;

public:
  ctkDICOMQueryRetrieveWidgetPrivate(ctkDICOMQueryRetrieveWidget& obj);
  ~ctkDICOMQueryRetrieveWidgetPrivate();
  void init();

  QMap<QString, ctkDICOMQuery*>     QueriesByServer;
  QMap<QString, ctkDICOMQuery*>     QueriesByStudyUID;
  QMap<QString, ctkDICOMRetrieve*>  RetrievalsByStudyUID;
  ctkDICOMDatabase                  QueryResultDatabase;
  QSharedPointer<ctkDICOMDatabase>  RetrieveDatabase;
  ctkDICOMModel                     Model;

  QProgressDialog*                  ProgressDialog;
  QString                           CurrentServer;
};

//----------------------------------------------------------------------------
// ctkDICOMQueryRetrieveWidgetPrivate methods

//----------------------------------------------------------------------------
ctkDICOMQueryRetrieveWidgetPrivate::ctkDICOMQueryRetrieveWidgetPrivate(
  ctkDICOMQueryRetrieveWidget& obj)
  : q_ptr(&obj)
{
  this->ProgressDialog = 0;
}

//----------------------------------------------------------------------------
ctkDICOMQueryRetrieveWidgetPrivate::~ctkDICOMQueryRetrieveWidgetPrivate()
{
  foreach(ctkDICOMQuery* query, this->QueriesByServer.values())
    {
    delete query;
    }
  foreach(ctkDICOMRetrieve* retrieval, this->RetrievalsByStudyUID.values())
    {
    delete retrieval;
    }
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidgetPrivate::init()
{
  Q_Q(ctkDICOMQueryRetrieveWidget);
  this->setupUi(q);

  QObject::connect(this->QueryButton, SIGNAL(clicked()), q, SLOT(query()));
  QObject::connect(this->RetrieveButton, SIGNAL(clicked()), q, SLOT(retrieve()));
  QObject::connect(this->CancelButton, SIGNAL(clicked()), q, SLOT(cancel()));

  this->results->setModel(&this->Model);
  // TODO: use the checkable headerview when it becomes possible
  // to select individual studies.  For now, assume that the
  // user will use the query terms to narrow down the transfer
  /*
  this->Model.setHeaderData(0, Qt::Horizontal, Qt::Unchecked, Qt::CheckStateRole);
  QHeaderView* previousHeaderView = this->results->header();
  ctkCheckableHeaderView* headerView =
    new ctkCheckableHeaderView(Qt::Horizontal, this->results);
  headerView->setClickable(previousHeaderView->isClickable());
  headerView->setMovable(previousHeaderView->isMovable());
  headerView->setHighlightSections(previousHeaderView->highlightSections());
  headerView->checkableModelHelper()->setPropagateDepth(-1);
  this->results->setHeader(headerView);
  // headerView is hidden because it was created with a visisble parent widget
  headerView->setHidden(false);
  */
}

//----------------------------------------------------------------------------
// ctkDICOMQueryRetrieveWidget methods

//----------------------------------------------------------------------------
ctkDICOMQueryRetrieveWidget::ctkDICOMQueryRetrieveWidget(QWidget* parentWidget)
  : Superclass(parentWidget)
  , d_ptr(new ctkDICOMQueryRetrieveWidgetPrivate(*this))
{
  Q_D(ctkDICOMQueryRetrieveWidget);
  d->init();
}

//----------------------------------------------------------------------------
ctkDICOMQueryRetrieveWidget::~ctkDICOMQueryRetrieveWidget()
{
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidget::setRetrieveDatabase(QSharedPointer<ctkDICOMDatabase> dicomDatabase)
{
  Q_D(ctkDICOMQueryRetrieveWidget);

  d->RetrieveDatabase = dicomDatabase;
}

//----------------------------------------------------------------------------
QSharedPointer<ctkDICOMDatabase> ctkDICOMQueryRetrieveWidget::retrieveDatabase()const
{
  Q_D(const ctkDICOMQueryRetrieveWidget);
  return d->RetrieveDatabase;
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidget::query()
{
  Q_D(ctkDICOMQueryRetrieveWidget);

  d->RetrieveButton->setEnabled(false);

  // create a database in memory to hold query results
  try { d->QueryResultDatabase.openDatabase( ":memory:", "QUERY-DB" ); }
  catch (std::exception e)
  {
    logger.error ( "Database error: " + d->QueryResultDatabase.lastError() );
    d->QueryResultDatabase.closeDatabase();
    return;
  }

  // for each of the selected server nodes, send the query
  QProgressDialog progress("Query DICOM servers", "Cancel", 0, 100, this,
                           Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
  // We don't want the progress dialog to resize itself, so we bypass the label
  // by creating our own
  QLabel* progressLabel = new QLabel("Initialization...");
  progress.setLabel(progressLabel);
  d->ProgressDialog = &progress;
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(0);
  progress.setValue(0);
  foreach (d->CurrentServer, d->ServerNodeWidget->selectedServerNodes())
    {
    if (progress.wasCanceled())
      {
      break;
      }
    QMap<QString, QVariant> parameters =
      d->ServerNodeWidget->serverNodeParameters(d->CurrentServer);
    // if we are here it's because the server node was checked
    Q_ASSERT(parameters["CheckState"] == static_cast<int>(Qt::Checked) );
    // create a query for the current server
    ctkDICOMQuery* query = new ctkDICOMQuery;
    query->setCallingAETitle(d->ServerNodeWidget->callingAETitle());
    query->setCalledAETitle(parameters["AETitle"].toString());
    query->setHost(parameters["Address"].toString());
    query->setPort(parameters["Port"].toInt());

    // populate the query with the current search options
    query->setFilters( d->QueryWidget->parameters() );

    try
      {
      connect(query, SIGNAL(progress(QString)),
              //&progress, SLOT(setLabelText(QString)));
              progressLabel, SLOT(setText(QString)));
      // for some reasons, setLabelText() doesn't refresh the dialog.
      connect(query, SIGNAL(progress(int)),
              this, SLOT(onQueryProgressChanged(int)));
      // run the query against the selected server and put results in database
      query->query ( d->QueryResultDatabase );
      disconnect(query, SIGNAL(progress(QString)),
                 //&progress, SLOT(setLabelText(QString)));
                 progressLabel, SLOT(setText(QString)));
      disconnect(query, SIGNAL(progress(int)),
                 this, SLOT(onQueryProgressChanged(int)));
      }
    catch (std::exception e)
      {
      logger.error ( "Query error: " + parameters["Name"].toString() );
      progress.setLabelText("Query error: " + parameters["Name"].toString());
      delete query;
      }
    d->QueriesByServer[d->CurrentServer] = query;

    foreach( QString studyUID, query->studyInstanceUIDQueried() )
      {
      d->QueriesByStudyUID[studyUID] = query;
      }
    }

  // checkable headers - allow user to select the patient/studies to retrieve
  d->Model.setDatabase(d->QueryResultDatabase.database());

  d->RetrieveButton->setEnabled(d->Model.rowCount());
  progress.setValue(progress.maximum());
  d->ProgressDialog = 0;
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidget::retrieve()
{
  Q_D(ctkDICOMQueryRetrieveWidget);

  if (!d->RetrieveButton->isEnabledTo(this))
    {
    return;
    }

  QMap<QString,QVariant> serverParameters = d->ServerNodeWidget->parameters();
  ctkDICOMRetrieve *retrieve = new ctkDICOMRetrieve;
  // only start new association if connection parameters change
  retrieve->setKeepAssociationOpen(true);
  // pull from GUI
  retrieve->setMoveDestinationAETitle( serverParameters["StorageAETitle"].toString() );
  foreach( QString studyUID, d->QueriesByStudyUID.keys() )
    {
    // Get information which server we want to get the study from and prepare request accordingly
    ctkDICOMQuery *query = d->QueriesByStudyUID[studyUID];
    retrieve->setRetrieveDatabase( d->RetrieveDatabase );
    retrieve->setCallingAETitle( query->callingAETitle() );
    retrieve->setCalledAETitle( query->calledAETitle() );
    retrieve->setCalledPort( query->port() );
    retrieve->setHost( query->host() );
    // TODO: check the model item to see if it is checked
    // for now, assume all studies queried and shown to the user will be retrieved
    logger.debug("About to retrieve " + studyUID + " from " + d->QueriesByStudyUID[studyUID]->host());
    logger.info ( "Starting to retrieve" );
    try
      {
      retrieve->retrieveStudy ( studyUID );
      }
    catch (std::exception e)
      {
      logger.error ( "Retrieve failed" );
      // TODO: ask the user if he wants to keep trying to retrieve other studies
      QMessageBox::information ( this, tr("Query Retrieve"), tr("Retrieve failed.") );
      continue;
      }
    // Store retrieve structure for later use.
    // Comment MO: I do not think that makes much sense; you store per study one fat
    // structure including an SCU. Also, I switched the code to re-use the retrieve
    // SCU in order to not start/stop the association for every study. In general,
    // it would make most sense in my opinion to have one SCU for each server you
    // like to retrieve from. There is no good reason to have one for each study.
    // d->RetrievalsByStudyUID[studyUID] = retrieve;
    logger.info ( "Retrieve success" );
    }
  delete retrieve;
  QMessageBox::information ( this, tr("Query Retrieve"), tr("Selected studies have been downloaded.") );
  emit studiesRetrieved(d->RetrievalsByStudyUID.keys());
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidget::cancel()
{
  emit studiesRetrieved(QStringList());
  emit canceled();
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidget::onQueryProgressChanged(int value)
{
  Q_D(ctkDICOMQueryRetrieveWidget);
  if (d->ProgressDialog == 0)
    {
    return;
    }
  QStringList servers = d->ServerNodeWidget->selectedServerNodes();
  int serverIndex = servers.indexOf(d->CurrentServer);
  if (serverIndex < 0)
    {
    return;
    }
  float serverProgress = 100. / servers.size();
  d->ProgressDialog->setValue( (serverIndex + (value / 101.)) * serverProgress);
  if (d->ProgressDialog->width() != 500)
    {
    QPoint pp = this->mapToGlobal(QPoint(0,0));
    pp = QPoint(pp.x() + (this->width() - d->ProgressDialog->width()) / 2,
                pp.y() + (this->height() - d->ProgressDialog->height())/ 2);
    d->ProgressDialog->move(pp - QPoint((500 - d->ProgressDialog->width())/2, 0));
    d->ProgressDialog->resize(500, d->ProgressDialog->height());
    }
  //d->CurrentServerqApp->processEvents();
}
<commit_msg>Give user option of breaking out of failed loop<commit_after>/*=========================================================================

  Library:   CTK

  Copyright (c) Kitware Inc.

  Licensed under the Apache License, Version 2.0 (the "License");
  you may not use this file except in compliance with the License.
  You may obtain a copy of the License at

      http://www.apache.org/licenses/LICENSE-2.0.txt

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  See the License for the specific language governing permissions and
  limitations under the License.

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

//Qt includes
#include <QDebug>
#include <QLabel>
#include <QMessageBox>
#include <QProgressDialog>
#include <QSettings>
#include <QTreeView>
#include <QTabBar>

/// CTK includes
#include <ctkCheckableHeaderView.h>
#include <ctkCheckableModelHelper.h>
#include <ctkLogger.h>

// ctkDICOMCore includes
#include "ctkDICOMDatabase.h"
#include "ctkDICOMModel.h"
#include "ctkDICOMQuery.h"
#include "ctkDICOMRetrieve.h"

// ctkDICOMWidgets includes
#include "ctkDICOMQueryRetrieveWidget.h"
#include "ctkDICOMQueryResultsTabWidget.h"
#include "ui_ctkDICOMQueryRetrieveWidget.h"

static ctkLogger logger("org.commontk.DICOM.Widgets.ctkDICOMQueryRetrieveWidget");

//----------------------------------------------------------------------------
class ctkDICOMQueryRetrieveWidgetPrivate: public Ui_ctkDICOMQueryRetrieveWidget
{
  Q_DECLARE_PUBLIC( ctkDICOMQueryRetrieveWidget );

protected:
  ctkDICOMQueryRetrieveWidget* const q_ptr;

public:
  ctkDICOMQueryRetrieveWidgetPrivate(ctkDICOMQueryRetrieveWidget& obj);
  ~ctkDICOMQueryRetrieveWidgetPrivate();
  void init();

  QMap<QString, ctkDICOMQuery*>     QueriesByServer;
  QMap<QString, ctkDICOMQuery*>     QueriesByStudyUID;
  QMap<QString, ctkDICOMRetrieve*>  RetrievalsByStudyUID;
  ctkDICOMDatabase                  QueryResultDatabase;
  QSharedPointer<ctkDICOMDatabase>  RetrieveDatabase;
  ctkDICOMModel                     Model;

  QProgressDialog*                  ProgressDialog;
  QString                           CurrentServer;
};

//----------------------------------------------------------------------------
// ctkDICOMQueryRetrieveWidgetPrivate methods

//----------------------------------------------------------------------------
ctkDICOMQueryRetrieveWidgetPrivate::ctkDICOMQueryRetrieveWidgetPrivate(
  ctkDICOMQueryRetrieveWidget& obj)
  : q_ptr(&obj)
{
  this->ProgressDialog = 0;
}

//----------------------------------------------------------------------------
ctkDICOMQueryRetrieveWidgetPrivate::~ctkDICOMQueryRetrieveWidgetPrivate()
{
  foreach(ctkDICOMQuery* query, this->QueriesByServer.values())
    {
    delete query;
    }
  foreach(ctkDICOMRetrieve* retrieval, this->RetrievalsByStudyUID.values())
    {
    delete retrieval;
    }
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidgetPrivate::init()
{
  Q_Q(ctkDICOMQueryRetrieveWidget);
  this->setupUi(q);

  QObject::connect(this->QueryButton, SIGNAL(clicked()), q, SLOT(query()));
  QObject::connect(this->RetrieveButton, SIGNAL(clicked()), q, SLOT(retrieve()));
  QObject::connect(this->CancelButton, SIGNAL(clicked()), q, SLOT(cancel()));

  this->results->setModel(&this->Model);
  // TODO: use the checkable headerview when it becomes possible
  // to select individual studies.  For now, assume that the
  // user will use the query terms to narrow down the transfer
  /*
  this->Model.setHeaderData(0, Qt::Horizontal, Qt::Unchecked, Qt::CheckStateRole);
  QHeaderView* previousHeaderView = this->results->header();
  ctkCheckableHeaderView* headerView =
    new ctkCheckableHeaderView(Qt::Horizontal, this->results);
  headerView->setClickable(previousHeaderView->isClickable());
  headerView->setMovable(previousHeaderView->isMovable());
  headerView->setHighlightSections(previousHeaderView->highlightSections());
  headerView->checkableModelHelper()->setPropagateDepth(-1);
  this->results->setHeader(headerView);
  // headerView is hidden because it was created with a visisble parent widget
  headerView->setHidden(false);
  */
}

//----------------------------------------------------------------------------
// ctkDICOMQueryRetrieveWidget methods

//----------------------------------------------------------------------------
ctkDICOMQueryRetrieveWidget::ctkDICOMQueryRetrieveWidget(QWidget* parentWidget)
  : Superclass(parentWidget)
  , d_ptr(new ctkDICOMQueryRetrieveWidgetPrivate(*this))
{
  Q_D(ctkDICOMQueryRetrieveWidget);
  d->init();
}

//----------------------------------------------------------------------------
ctkDICOMQueryRetrieveWidget::~ctkDICOMQueryRetrieveWidget()
{
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidget::setRetrieveDatabase(QSharedPointer<ctkDICOMDatabase> dicomDatabase)
{
  Q_D(ctkDICOMQueryRetrieveWidget);

  d->RetrieveDatabase = dicomDatabase;
}

//----------------------------------------------------------------------------
QSharedPointer<ctkDICOMDatabase> ctkDICOMQueryRetrieveWidget::retrieveDatabase()const
{
  Q_D(const ctkDICOMQueryRetrieveWidget);
  return d->RetrieveDatabase;
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidget::query()
{
  Q_D(ctkDICOMQueryRetrieveWidget);

  d->RetrieveButton->setEnabled(false);

  // create a database in memory to hold query results
  try { d->QueryResultDatabase.openDatabase( ":memory:", "QUERY-DB" ); }
  catch (std::exception e)
  {
    logger.error ( "Database error: " + d->QueryResultDatabase.lastError() );
    d->QueryResultDatabase.closeDatabase();
    return;
  }

  // for each of the selected server nodes, send the query
  QProgressDialog progress("Query DICOM servers", "Cancel", 0, 100, this,
                           Qt::WindowTitleHint | Qt::WindowSystemMenuHint);
  // We don't want the progress dialog to resize itself, so we bypass the label
  // by creating our own
  QLabel* progressLabel = new QLabel("Initialization...");
  progress.setLabel(progressLabel);
  d->ProgressDialog = &progress;
  progress.setWindowModality(Qt::WindowModal);
  progress.setMinimumDuration(0);
  progress.setValue(0);
  foreach (d->CurrentServer, d->ServerNodeWidget->selectedServerNodes())
    {
    if (progress.wasCanceled())
      {
      break;
      }
    QMap<QString, QVariant> parameters =
      d->ServerNodeWidget->serverNodeParameters(d->CurrentServer);
    // if we are here it's because the server node was checked
    Q_ASSERT(parameters["CheckState"] == static_cast<int>(Qt::Checked) );
    // create a query for the current server
    ctkDICOMQuery* query = new ctkDICOMQuery;
    query->setCallingAETitle(d->ServerNodeWidget->callingAETitle());
    query->setCalledAETitle(parameters["AETitle"].toString());
    query->setHost(parameters["Address"].toString());
    query->setPort(parameters["Port"].toInt());

    // populate the query with the current search options
    query->setFilters( d->QueryWidget->parameters() );

    try
      {
      connect(query, SIGNAL(progress(QString)),
              //&progress, SLOT(setLabelText(QString)));
              progressLabel, SLOT(setText(QString)));
      // for some reasons, setLabelText() doesn't refresh the dialog.
      connect(query, SIGNAL(progress(int)),
              this, SLOT(onQueryProgressChanged(int)));
      // run the query against the selected server and put results in database
      query->query ( d->QueryResultDatabase );
      disconnect(query, SIGNAL(progress(QString)),
                 //&progress, SLOT(setLabelText(QString)));
                 progressLabel, SLOT(setText(QString)));
      disconnect(query, SIGNAL(progress(int)),
                 this, SLOT(onQueryProgressChanged(int)));
      }
    catch (std::exception e)
      {
      logger.error ( "Query error: " + parameters["Name"].toString() );
      progress.setLabelText("Query error: " + parameters["Name"].toString());
      delete query;
      }
    d->QueriesByServer[d->CurrentServer] = query;

    foreach( QString studyUID, query->studyInstanceUIDQueried() )
      {
      d->QueriesByStudyUID[studyUID] = query;
      }
    }

  // checkable headers - allow user to select the patient/studies to retrieve
  d->Model.setDatabase(d->QueryResultDatabase.database());

  d->RetrieveButton->setEnabled(d->Model.rowCount());
  progress.setValue(progress.maximum());
  d->ProgressDialog = 0;
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidget::retrieve()
{
  Q_D(ctkDICOMQueryRetrieveWidget);

  if (!d->RetrieveButton->isEnabledTo(this))
    {
    return;
    }

  QMap<QString,QVariant> serverParameters = d->ServerNodeWidget->parameters();
  ctkDICOMRetrieve *retrieve = new ctkDICOMRetrieve;
  // only start new association if connection parameters change
  retrieve->setKeepAssociationOpen(true);
  // pull from GUI
  retrieve->setMoveDestinationAETitle( serverParameters["StorageAETitle"].toString() );
  foreach( QString studyUID, d->QueriesByStudyUID.keys() )
    {
    // Get information which server we want to get the study from and prepare request accordingly
    ctkDICOMQuery *query = d->QueriesByStudyUID[studyUID];
    retrieve->setRetrieveDatabase( d->RetrieveDatabase );
    retrieve->setCallingAETitle( query->callingAETitle() );
    retrieve->setCalledAETitle( query->calledAETitle() );
    retrieve->setCalledPort( query->port() );
    retrieve->setHost( query->host() );
    // TODO: check the model item to see if it is checked
    // for now, assume all studies queried and shown to the user will be retrieved
    logger.debug("About to retrieve " + studyUID + " from " + d->QueriesByStudyUID[studyUID]->host());
    logger.info ( "Starting to retrieve" );
    try
      {
      retrieve->retrieveStudy ( studyUID );
      }
    catch (std::exception e)
      {
      logger.error ( "Retrieve failed" );
      if ( QMessageBox::question ( this,
            tr("Query Retrieve"), tr("Retrieve failed.  Keep trying?"),
            QMessageBox::Yes | QMessageBox::No) == QMessageBox::Yes)
        {
        continue;
        }
      else
        {
        break;
        }
      }
    // Store retrieve structure for later use.
    // Comment MO: I do not think that makes much sense; you store per study one fat
    // structure including an SCU. Also, I switched the code to re-use the retrieve
    // SCU in order to not start/stop the association for every study. In general,
    // it would make most sense in my opinion to have one SCU for each server you
    // like to retrieve from. There is no good reason to have one for each study.
    // d->RetrievalsByStudyUID[studyUID] = retrieve;
    logger.info ( "Retrieve success" );
    }
  delete retrieve;
  QMessageBox::information ( this, tr("Query Retrieve"), tr("Selected studies have been downloaded.") );
  emit studiesRetrieved(d->RetrievalsByStudyUID.keys());
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidget::cancel()
{
  emit studiesRetrieved(QStringList());
  emit canceled();
}

//----------------------------------------------------------------------------
void ctkDICOMQueryRetrieveWidget::onQueryProgressChanged(int value)
{
  Q_D(ctkDICOMQueryRetrieveWidget);
  if (d->ProgressDialog == 0)
    {
    return;
    }
  QStringList servers = d->ServerNodeWidget->selectedServerNodes();
  int serverIndex = servers.indexOf(d->CurrentServer);
  if (serverIndex < 0)
    {
    return;
    }
  float serverProgress = 100. / servers.size();
  d->ProgressDialog->setValue( (serverIndex + (value / 101.)) * serverProgress);
  if (d->ProgressDialog->width() != 500)
    {
    QPoint pp = this->mapToGlobal(QPoint(0,0));
    pp = QPoint(pp.x() + (this->width() - d->ProgressDialog->width()) / 2,
                pp.y() + (this->height() - d->ProgressDialog->height())/ 2);
    d->ProgressDialog->move(pp - QPoint((500 - d->ProgressDialog->width())/2, 0));
    d->ProgressDialog->resize(500, d->ProgressDialog->height());
    }
  //d->CurrentServerqApp->processEvents();
}
<|endoftext|>


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

The Medical Imaging Interaction Toolkit (MITK)

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

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

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

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

#include "mitkSegmentationSink.h"
#include "mitkDataStorage.h"
#include "mitkRenderingManager.h"

namespace mitk
{
  SegmentationSink::SegmentationSink() {}
  SegmentationSink::~SegmentationSink() {}
  void SegmentationSink::Initialize(const NonBlockingAlgorithm *other)
  {
    Superclass::Initialize(other);
    // sinks should be called explicitly from the tool, because otherwise the order of setting "Input" and "Group node"
    // would matter
    UnDefineTriggerParameter("Input");

    // some basedata output
    DataNode::Pointer groupNode;
    bool showResult(true);

    if (other)
    {
      other->GetPointerParameter("Group node", groupNode);
      other->GetParameter("Show result", showResult);
    }

    SetPointerParameter("Group node", groupNode);
    SetParameter("Show result", showResult);
  }

  bool SegmentationSink::ReadyToRun()
  {
    Image::Pointer image;
    GetPointerParameter("Input", image);

    DataNode::Pointer groupNode;
    GetPointerParameter("Group node", groupNode);

    return image.IsNotNull() && groupNode.IsNotNull();
  }

  bool SegmentationSink::ThreadedUpdateFunction() { return true; }
  /// to be called by subclasses when they want to insert some resulting object (binary image, surface, ...) into the
  /// data tree
  void SegmentationSink::InsertBelowGroupNode(mitk::DataNode *node)
  {
    DataNode *groupNode = GetGroupNode();

    if (m_DataStorage.IsNotNull())
    {
      if (node)
        node->GetData()->DisconnectPipeline();
      m_DataStorage->Add(node, groupNode);
    }

    RenderingManager::GetInstance()->RequestUpdateAll();
  }

  DataNode *SegmentationSink::GetGroupNode()
  {
    DataNode::Pointer groupNode;
    GetPointerParameter("Group node", groupNode);

    return groupNode.GetPointer();
  }

  DataNode *SegmentationSink::LookForPointerTargetBelowGroupNode(const char *name)
  {
    DataNode::Pointer groupNode;
    GetPointerParameter("Group node", groupNode);

    if (groupNode.IsNotNull() && m_DataStorage.IsNotNull())
    {
      return m_DataStorage->GetNamedDerivedNode(name, groupNode, true);
    }

    return nullptr;
  }

} // namespace
<commit_msg>Migrate SegmentationSink to new WeakPointer API<commit_after>/*===================================================================

The Medical Imaging Interaction Toolkit (MITK)

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

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

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

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

#include "mitkSegmentationSink.h"
#include "mitkDataStorage.h"
#include "mitkRenderingManager.h"

namespace mitk
{
  SegmentationSink::SegmentationSink() {}
  SegmentationSink::~SegmentationSink() {}
  void SegmentationSink::Initialize(const NonBlockingAlgorithm *other)
  {
    Superclass::Initialize(other);
    // sinks should be called explicitly from the tool, because otherwise the order of setting "Input" and "Group node"
    // would matter
    UnDefineTriggerParameter("Input");

    // some basedata output
    DataNode::Pointer groupNode;
    bool showResult(true);

    if (other)
    {
      other->GetPointerParameter("Group node", groupNode);
      other->GetParameter("Show result", showResult);
    }

    SetPointerParameter("Group node", groupNode);
    SetParameter("Show result", showResult);
  }

  bool SegmentationSink::ReadyToRun()
  {
    Image::Pointer image;
    GetPointerParameter("Input", image);

    DataNode::Pointer groupNode;
    GetPointerParameter("Group node", groupNode);

    return image.IsNotNull() && groupNode.IsNotNull();
  }

  bool SegmentationSink::ThreadedUpdateFunction() { return true; }
  /// to be called by subclasses when they want to insert some resulting object (binary image, surface, ...) into the
  /// data tree
  void SegmentationSink::InsertBelowGroupNode(mitk::DataNode *node)
  {
    DataNode *groupNode = GetGroupNode();

    if (!m_DataStorage.IsExpired())
    {
      if (node)
        node->GetData()->DisconnectPipeline();
      m_DataStorage.Lock()->Add(node, groupNode);
    }

    RenderingManager::GetInstance()->RequestUpdateAll();
  }

  DataNode *SegmentationSink::GetGroupNode()
  {
    DataNode::Pointer groupNode;
    GetPointerParameter("Group node", groupNode);

    return groupNode.GetPointer();
  }

  DataNode *SegmentationSink::LookForPointerTargetBelowGroupNode(const char *name)
  {
    DataNode::Pointer groupNode;
    GetPointerParameter("Group node", groupNode);

    if (groupNode.IsNotNull() && !m_DataStorage.IsExpired())
    {
      return m_DataStorage.Lock()->GetNamedDerivedNode(name, groupNode, true);
    }

    return nullptr;
  }

} // namespace
<|endoftext|>