<commit_before>// $Id: MMPA_UnitTest.cpp $
//
//  Copyright (c) 2015, Novartis Institutes for BioMedical Research Inc.
//  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Novartis Institutes for BioMedical Research Inc.
//       nor the names of its contributors may be used to endorse or promote
//       products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/resource.h>
#endif

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <string>
#include <iostream>
#include <RDGeneral/RDLog.h>
#include <RDGeneral/utils.h>
#include "../RDKitBase.h"
#include "../FileParsers/FileParsers.h" //MOL single molecule !
#include "../FileParsers/MolSupplier.h" //SDF
#include "../SmilesParse/SmilesParse.h"
#include "../SmilesParse/SmilesWrite.h"
#include "../SmilesParse/SmartsWrite.h"
#include "../Substruct/SubstructMatch.h"

#include "MMPA.h"

using namespace RDKit;

unsigned long long T0;
unsigned long long t0;

#ifdef WIN32
#define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL

struct timezone {
    int  tz_minuteswest; // minutes W of Greenwich
    int  tz_dsttime;     // type of dst correction
};

static inline int gettimeofday(struct timeval *tv, struct timezone *tz) {
    FILETIME ft;
    unsigned __int64 tmpres = 0;
    static int tzflag;

    if (NULL != tv) {
        GetSystemTimeAsFileTime(&ft);

        tmpres |= ft.dwHighDateTime;
        tmpres <<= 32;
        tmpres |= ft.dwLowDateTime;

        //converting file time to unix epoch
        tmpres -= DELTA_EPOCH_IN_MICROSECS;
        tmpres /= 10;  //convert into microseconds
        tv->tv_sec = (long)(tmpres / 1000000UL);
        tv->tv_usec = (long)(tmpres % 1000000UL);
    }

    if (NULL != tz) {
        if (!tzflag) {
            _tzset();
            tzflag++;
        }
        tz->tz_minuteswest = _timezone / 60;
        tz->tz_dsttime = _daylight;
    }
    return 0;
}
#endif

static inline unsigned long long nanoClock (void) { // actually returns microseconds
    struct timeval t;
    gettimeofday(&t, (struct timezone*)0);
    return t.tv_usec + t.tv_sec * 1000000ULL;
}

void printTime() {
    unsigned long long t1 = nanoClock();
    double sec = double(t1-t0) / 1000000.;
    printf("Time elapsed %.4lf seconds\n", sec);
    t0 = nanoClock();
}

std::string getSmilesOnly(const char* smiles, std::string* id=0) { // remove label, because RDKit parse FAILED
    const char* sp = strchr(smiles,' ');
    unsigned n = (sp ? sp-smiles+1 : strlen(smiles));
    if(id)
        *id = std::string(smiles+(n--));
    return std::string(smiles, n);
}

// UNIT Test Set:
//=========================================================================

void test1() {
    BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
    BOOST_LOG(rdInfoLog) << "MMPA test1()\n" << std::endl;
/*
// DEBUG PRINT
    RWMol *m = SmartsToMol("[*:1]C.[*:1]c1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-]");
    Atom  *a = m->getAtomWithIdx(0);
    std::cout<<"DEBUG: "<< MolToSmiles(*m, true) <<"\n";
    delete m;
//-----
*/
    const char* smi[] = {
        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-] ZINC21984717",
    };

    const char* fs[] = { // 16 reordered reference results
        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,,[*:1]C.[*:1]c1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-]",
        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:1]c1c([*:2])[n+](=O)c2ccccc2n1[O-],[*:1]C.[*:2]C(=O)NCCO",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:1]CNC([*:2])=O,[*:1]CO.[*:2]c1c(C)n([O-])c2ccccc2[n+]1=O",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:1]C[*:2],[*:1]CO.[*:2]NC(=O)c1c(C)n([O-])c2ccccc2[n+]1=O",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:1]NC([*:2])=O,[*:1]CCO.[*:2]c1c(C)n([O-])c2ccccc2[n+]1=O",
        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:2]NC(=O)c1c([*:1])n([O-])c2ccccc2[n+]1=O,[*:1]C.[*:2]CCO",
        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:2]CNC(=O)c1c([*:1])n([O-])c2ccccc2[n+]1=O,[*:1]C.[*:2]CO",
        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:2]CCNC(=O)c1c([*:1])n([O-])c2ccccc2[n+]1=O,[*:1]C.[*:2]O",
        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,,[*:1]C(=O)NCCO.[*:1]c1c(C)n([O-])c2ccccc2[n+]1=O",
        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,,[*:1]CCO.[*:1]NC(=O)c1c(C)n([O-])c2ccccc2[n+]1=O",

        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,,[*:1]CO.[*:1]CNC(=O)c1c(C)n([O-])c2ccccc2[n+]1=O",
        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,,[*:1]O.[*:1]CCNC(=O)c1c(C)n([O-])c2ccccc2[n+]1=O",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:1]NC([*:2])=O,[*:1]CCO.[*:2]c1c(C)n([O-])c2ccccc2[n+]1=O",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:1]CC[*:2],[*:1]O.[*:2]NC(=O)c1c(C)n([O-])c2ccccc2[n+]1=O",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:1]CCNC([*:2])=O,[*:1]O.[*:2]c1c(C)n([O-])c2ccccc2[n+]1=O",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,[*:1]C[*:2],[*:1]O.[*:2]CNC(=O)c1c(C)n([O-])c2ccccc2[n+]1=O",
    };

    for(int i=0; i<sizeof(smi)/sizeof(smi[0]); i++) {
        static const std::string es("NULL");
        std::string id;
        std::string smiles = getSmilesOnly(smi[i], &id);
        ROMol* mol = SmilesToMol( smiles );
        std::vector< std::pair<ROMOL_SPTR,ROMOL_SPTR> > res;
        t0 = nanoClock();
        RDKit::MMPA::fragmentMol(*mol, res);
        printTime();
        delete mol;
        std::map<size_t, size_t> fs2res;
        std::cout << "\nTEST "<< i+1 << " mol: " << smi[i] <<"\n";
        for(size_t j=0; j<res.size(); j++) {
//            std::cout <<"   "<< j+1 << ": ";
//            std::cout << (res[j].first.get()  ? MolToSmiles(*res[j].first ) : es) <<", ";
//            std::cout << (res[j].second.get() ? MolToSmiles(*res[j].second) : es) <<"\n";
            std::stringstream ss;
            ss << smiles << "," << id << ",";
            ss << (res[j].first.get()  ? MolToSmiles(*res[j].first, true) : "") <<",";
            ss << (res[j].second.get() ? MolToSmiles(*res[j].second,true) : "");
            bool failed = true;
            size_t matchedRefRes = -1;
            for(size_t r=0; r < sizeof(fs)/sizeof(fs[0]); r++) {
                if(0==strcmp(std::string(ss.str()).c_str(), fs[r])) { // PASSED
                    failed = false;
                    matchedRefRes = r;
                    fs2res[r] = j;
                    break;
                }
            }
            if(j<9)
                std::cout << " ";
            if(failed) { //0!=strcmp(std::string(ss.str()).c_str(), fs[j])) { // FAILED
                std::cout << j+1 << ":*FAILED* " << ss.str() <<"\n";//<< "FS: " << fs[j] <<"\n";
//tmp            TEST_ASSERT(0==strcmp(std::string(ss.str()).c_str(), fs[j]));
            }
            else
                std::cout << j+1 << ": PASSED. matchedRefRes = "<< matchedRefRes+1 <<"\n";//ok: << "ss: " << ss.str() <<"\n";
            std::cout.flush();
        }
        std::cout << "\n --- UNMATCHED Reference RESULTS: --- \n";
        for(size_t r=0; r < sizeof(fs)/sizeof(fs[0]); r++) {
            if(fs2res.end() == fs2res.find(r))
                std::cout <<(r<9?" ":"")<< r+1 << ": " << fs[r] <<"\n";
        }
    }
    std::cout << " -----------------------------------\n";
    BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
}

//====================================================================================================
//====================================================================================================

int main(int argc, const char* argv[]) {
    BOOST_LOG(rdInfoLog) << "*******************************************************\n";
    BOOST_LOG(rdInfoLog) << "MMPA Unit Test \n";

// use maximum CPU resoures to increase time measuring accuracy and stability in multi process environment
#ifdef WIN32
//    SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS );
    SetThreadPriority(GetCurrentThread (), THREAD_PRIORITY_HIGHEST );
#else
    setpriority(PRIO_PROCESS, getpid(), -20);
#endif

    T0 = nanoClock();
    t0 = nanoClock();

    test1();
/*
    unsigned long long t1 = nanoClock();
    double sec = double(t1-T0) / 1000000.;
    printf("TOTAL Time elapsed %.4lf seconds\n", sec);
*/
    BOOST_LOG(rdInfoLog) << "*******************************************************\n";
    return 0;
}
<commit_msg>update expected results based on a new run of rfrag.py<commit_after>// $Id: MMPA_UnitTest.cpp $
//
//  Copyright (c) 2015, Novartis Institutes for BioMedical Research Inc.
//  All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
//     * Redistributions of source code must retain the above copyright
//       notice, this list of conditions and the following disclaimer.
//     * Redistributions in binary form must reproduce the above
//       copyright notice, this list of conditions and the following
//       disclaimer in the documentation and/or other materials provided
//       with the distribution.
//     * Neither the name of Novartis Institutes for BioMedical Research Inc.
//       nor the names of its contributors may be used to endorse or promote
//       products derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
#ifdef WIN32
#include <Windows.h>
#else
#include <unistd.h>
#include <fcntl.h>
#include <sys/time.h>
#include <sys/resource.h>
#endif

#include <stdio.h>
#include <string.h>
#include <time.h>
#include <string>
#include <iostream>
#include <RDGeneral/RDLog.h>
#include <RDGeneral/utils.h>
#include "../RDKitBase.h"
#include "../FileParsers/FileParsers.h" //MOL single molecule !
#include "../FileParsers/MolSupplier.h" //SDF
#include "../SmilesParse/SmilesParse.h"
#include "../SmilesParse/SmilesWrite.h"
#include "../SmilesParse/SmartsWrite.h"
#include "../Substruct/SubstructMatch.h"

#include "MMPA.h"

using namespace RDKit;

unsigned long long T0;
unsigned long long t0;

#ifdef WIN32
#define DELTA_EPOCH_IN_MICROSECS  11644473600000000ULL

struct timezone {
    int  tz_minuteswest; // minutes W of Greenwich
    int  tz_dsttime;     // type of dst correction
};

static inline int gettimeofday(struct timeval *tv, struct timezone *tz) {
    FILETIME ft;
    unsigned __int64 tmpres = 0;
    static int tzflag;

    if (NULL != tv) {
        GetSystemTimeAsFileTime(&ft);

        tmpres |= ft.dwHighDateTime;
        tmpres <<= 32;
        tmpres |= ft.dwLowDateTime;

        //converting file time to unix epoch
        tmpres -= DELTA_EPOCH_IN_MICROSECS;
        tmpres /= 10;  //convert into microseconds
        tv->tv_sec = (long)(tmpres / 1000000UL);
        tv->tv_usec = (long)(tmpres % 1000000UL);
    }

    if (NULL != tz) {
        if (!tzflag) {
            _tzset();
            tzflag++;
        }
        tz->tz_minuteswest = _timezone / 60;
        tz->tz_dsttime = _daylight;
    }
    return 0;
}
#endif

static inline unsigned long long nanoClock (void) { // actually returns microseconds
    struct timeval t;
    gettimeofday(&t, (struct timezone*)0);
    return t.tv_usec + t.tv_sec * 1000000ULL;
}

void printTime() {
    unsigned long long t1 = nanoClock();
    double sec = double(t1-t0) / 1000000.;
    printf("Time elapsed %.4lf seconds\n", sec);
    t0 = nanoClock();
}

std::string getSmilesOnly(const char* smiles, std::string* id=0) { // remove label, because RDKit parse FAILED
    const char* sp = strchr(smiles,' ');
    unsigned n = (sp ? sp-smiles+1 : strlen(smiles));
    if(id)
        *id = std::string(smiles+(n--));
    return std::string(smiles, n);
}

// UNIT Test Set:
//=========================================================================

void test1() {
    BOOST_LOG(rdInfoLog) << "-------------------------------------" << std::endl;
    BOOST_LOG(rdInfoLog) << "MMPA test1()\n" << std::endl;
/*
// DEBUG PRINT
    RWMol *m = SmartsToMol("[*:1]C.[*:1]c1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-]");
    Atom  *a = m->getAtomWithIdx(0);
    std::cout<<"DEBUG: "<< MolToSmiles(*m, true) <<"\n";
    delete m;
//-----
*/
    const char* smi[] = {
        "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-] ZINC21984717",
    };

    const char* fs[] = { // 16 reordered reference results
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,O=[n+]1c([*:2])c([*:1])n([O-])c2ccccc21,C[*:1].O=C(NCCO)[*:2]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,,Cc1c(C(=O)NCC[*:1])[n+](=O)c2ccccc2n1[O-].O[*:1]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,,OCC[*:1].Cc1c(C(=O)N[*:1])[n+](=O)c2ccccc2n1[O-]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,,C[*:1].O=C(NCCO)c1c([*:1])n([O-])c2ccccc2[n+]1=O",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,C([*:1])[*:2],Cc1c(C(=O)N[*:1])[n+](=O)c2ccccc2n1[O-].OC[*:2]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,O=C(N[*:2])c1c([*:1])n([O-])c2ccccc2[n+]1=O,C[*:1].OCC[*:2]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,O=C(N[*:2])[*:1],Cc1c([*:1])[n+](=O)c2ccccc2n1[O-].OCC[*:2]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,C(C[*:2])[*:1],Cc1c(C(=O)N[*:1])[n+](=O)c2ccccc2n1[O-].O[*:2]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,,Cc1c(C(=O)NC[*:1])[n+](=O)c2ccccc2n1[O-].OC[*:1]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,,O=C(NCCO)[*:1].Cc1c([*:1])[n+](=O)c2ccccc2n1[O-]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,C([*:1])[*:2],Cc1c(C(=O)NC[*:1])[n+](=O)c2ccccc2n1[O-].O[*:2]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,O=C(NCC[*:2])c1c([*:1])n([O-])c2ccccc2[n+]1=O,C[*:1].O[*:2]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,O=C(NC[*:2])c1c([*:1])n([O-])c2ccccc2[n+]1=O,C[*:1].OC[*:2]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,O=C(NCC[*:2])[*:1],Cc1c([*:1])[n+](=O)c2ccccc2n1[O-].O[*:2]",
      "Cc1c(C(=O)NCCO)[n+](=O)c2ccccc2n1[O-],ZINC21984717,O=C(NC[*:2])[*:1],Cc1c([*:1])[n+](=O)c2ccccc2n1[O-].OC[*:2]"
    };

    for(int i=0; i<sizeof(smi)/sizeof(smi[0]); i++) {
        static const std::string es("NULL");
        std::string id;
        std::string smiles = getSmilesOnly(smi[i], &id);
        ROMol* mol = SmilesToMol( smiles );
        std::vector< std::pair<ROMOL_SPTR,ROMOL_SPTR> > res;
        t0 = nanoClock();
        RDKit::MMPA::fragmentMol(*mol, res);
        printTime();
        delete mol;
        std::map<size_t, size_t> fs2res;
        std::cout << "\nTEST "<< i+1 << " mol: " << smi[i] <<"\n";
        for(size_t j=0; j<res.size(); j++) {
//            std::cout <<"   "<< j+1 << ": ";
//            std::cout << (res[j].first.get()  ? MolToSmiles(*res[j].first ) : es) <<", ";
//            std::cout << (res[j].second.get() ? MolToSmiles(*res[j].second) : es) <<"\n";
            std::stringstream ss;
            ss << smiles << "," << id << ",";
            ss << (res[j].first.get()  ? MolToSmiles(*res[j].first, true) : "") <<",";
            ss << (res[j].second.get() ? MolToSmiles(*res[j].second,true) : "");
            bool failed = true;
            size_t matchedRefRes = -1;
            for(size_t r=0; r < sizeof(fs)/sizeof(fs[0]); r++) {
                if(0==strcmp(std::string(ss.str()).c_str(), fs[r])) { // PASSED
                    failed = false;
                    matchedRefRes = r;
                    fs2res[r] = j;
                    break;
                }
            }
            if(j<9)
                std::cout << " ";
            if(failed) { //0!=strcmp(std::string(ss.str()).c_str(), fs[j])) { // FAILED
                std::cout << j+1 << ":*FAILED* " << ss.str() <<"\n";//<< "FS: " << fs[j] <<"\n";
//tmp            TEST_ASSERT(0==strcmp(std::string(ss.str()).c_str(), fs[j]));
            }
            else
                std::cout << j+1 << ": PASSED. matchedRefRes = "<< matchedRefRes+1 <<"\n";//ok: << "ss: " << ss.str() <<"\n";
            std::cout.flush();
        }
        std::cout << "\n --- UNMATCHED Reference RESULTS: --- \n";
        for(size_t r=0; r < sizeof(fs)/sizeof(fs[0]); r++) {
            if(fs2res.end() == fs2res.find(r))
                std::cout <<(r<9?" ":"")<< r+1 << ": " << fs[r] <<"\n";
        }
    }
    std::cout << " -----------------------------------\n";
    BOOST_LOG(rdInfoLog) << "\tdone" << std::endl;
}

//====================================================================================================
//====================================================================================================

int main(int argc, const char* argv[]) {
    BOOST_LOG(rdInfoLog) << "*******************************************************\n";
    BOOST_LOG(rdInfoLog) << "MMPA Unit Test \n";

// use maximum CPU resoures to increase time measuring accuracy and stability in multi process environment
#ifdef WIN32
//    SetPriorityClass (GetCurrentProcess(), REALTIME_PRIORITY_CLASS );
    SetThreadPriority(GetCurrentThread (), THREAD_PRIORITY_HIGHEST );
#else
    setpriority(PRIO_PROCESS, getpid(), -20);
#endif

    T0 = nanoClock();
    t0 = nanoClock();

    test1();
/*
    unsigned long long t1 = nanoClock();
    double sec = double(t1-T0) / 1000000.;
    printf("TOTAL Time elapsed %.4lf seconds\n", sec);
*/
    BOOST_LOG(rdInfoLog) << "*******************************************************\n";
    return 0;
}
<|endoftext|>


<commit_before>// This file is a part of the OpenSurgSim project.
// Copyright 2013-2016, SimQuest Solutions 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
//
// 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 "SurgSim/Physics/CcdCollisionLoop.h"

#include "SurgSim/Physics/CcdCollision.h"
#include "SurgSim/Physics/UpdateCcdData.h"
#include "SurgSim/Physics/ContactConstraintGeneration.h"
#include "SurgSim/Physics/SolveMlcp.h"
#include "SurgSim/Physics/PushResults.h"
#include "SurgSim/Physics/BuildMlcp.h"
#include "SurgSim/Physics/PhysicsManagerState.h"
#include "SurgSim/Collision/CollisionPair.h"

#include <unordered_set>
#include <limits>

namespace SurgSim
{

namespace Physics
{

CcdCollisionLoop::CcdCollisionLoop(bool copyState) :
	Computation(copyState),
	m_updateCcdData(new UpdateCcdData(copyState)),
	m_ccdCollision(new CcdCollision(copyState)),
	m_constraintGeneration(new ContactConstraintGeneration(copyState)),
	m_buildMlcp(new BuildMlcp(copyState)),
	m_solveMlcp(new SolveMlcp(copyState)),
	m_pushResults(new PushResults(copyState)),
	m_maxIterations(5),
	m_epsilonFactor(1000)
{
}

CcdCollisionLoop::~CcdCollisionLoop()
{

}

std::shared_ptr<SurgSim::Physics::PhysicsManagerState> CcdCollisionLoop::doUpdate(const double& dt,
		const std::shared_ptr<PhysicsManagerState>& state)
{
	static bool doSleep;

	if (doSleep)
	{
		boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
	}

	auto lastState = state;
	size_t iterations = m_maxIterations;

	auto collisionPairs = state->getCollisionPairs();
	std::vector<std::shared_ptr<Collision::CollisionPair>> ccdPairs;
	ccdPairs.reserve(collisionPairs.size());

	std::unordered_set<Collision::Representation*> representations;

	std::copy_if(collisionPairs.cbegin(), collisionPairs.cend(), std::back_inserter(ccdPairs),
				 [&representations](const std::shared_ptr<Collision::CollisionPair>& p)
	{
		if (p->getType() == Collision::COLLISION_DETECTION_TYPE_CONTINUOUS)
		{
			representations.insert(p->getFirst().get());
			representations.insert(p->getSecond().get());
			return true;
		}
		return false;
	});

	// localDt is the time left on dt as we step through the CCD, this gets reduced as contacts are found
	double localDt = dt;
	double toi = 0.0;
	double localToi = 0.0;

	std::cout << "--------Iteration Start " << std::endl;

	std::vector<std::list<std::shared_ptr<Collision::Contact>>> oldContacts;

	while (--iterations > 0)
	{
		toi += (1.0 - toi) * localToi;
		double epsilon = 1.0 / ((1 - toi) * m_epsilonFactor);

		lastState = m_updateCcdData->update(localToi, lastState); // state interpolation is triggered in here
		lastState = m_ccdCollision->update(dt, lastState);

		//printContacts(ccdPairs);

		// Find the first impact and filter all contacts beyond a given epsilon
		if (!filterContacts(ccdPairs, epsilon, &localToi))
		{
			break;
		}

		// set toi to the correct value as a percentage of dt

		lastState = m_constraintGeneration->update(dt, lastState);
		lastState = m_buildMlcp->update(dt, lastState);
		lastState = m_solveMlcp->update(dt, lastState);
		lastState = m_pushResults->update(dt, lastState);

		if (toi > 1.0)
		{
			break;
		}
	}

	if (iterations == 0)
	{
		std::cout << "----- Maxed out iterations ... " << std::endl;
	}
	else if (iterations < m_maxIterations - 1)
	{
		std::cout << "----- Resolved after " << m_maxIterations - iterations << std::endl;
	}
	else
	{
		std::cout << "--------Iteration End " << std::endl;
	}

	return lastState;
}

bool CcdCollisionLoop::filterContacts(
	const std::vector<std::shared_ptr<Collision::CollisionPair>>& ccdPairs,
	double epsilon,
	double* currentToi)
{
	SURGSIM_ASSERT(currentToi != nullptr);

	double toi = std::numeric_limits<double>::max();

	// Find earliest time of impact
	for (const auto& pair : ccdPairs)
	{
		std::for_each(pair->getContacts().begin(),
					  pair->getContacts().end(), [&toi](const std::shared_ptr<Collision::Contact>& contact)
		{
			toi = std::min<double>(toi, contact->time);
		});
	}

	// Did not find any contacts return false
	if (!(toi < std::numeric_limits<double>::max()))
	{
		return false;
	}

	toi += epsilon;

	for (const auto& pair : ccdPairs)
	{
		pair->getContacts().remove_if([toi](const std::shared_ptr<Collision::Contact>& contact)
		{
			return contact->time > toi;
		});
	}

	*currentToi = toi;

	return true;
}

void CcdCollisionLoop::backupContacts(const std::vector<std::shared_ptr<Collision::CollisionPair>>& ccdPairs,
									  std::vector<std::list<std::shared_ptr<Collision::Contact>>>* oldContacts)
{
	for (auto& pair : ccdPairs)
	{
		oldContacts->emplace_back(pair->getContacts());
		pair->getContacts().clear();
	}
}

void CcdCollisionLoop::restoreContacts(const std::vector<std::shared_ptr<Collision::CollisionPair>>& ccdPairs,
									   std::vector<std::list<std::shared_ptr<Collision::Contact>>>* oldContacts)
{
	if (oldContacts->size() == 0)
	{
		return;
	}

	SURGSIM_ASSERT(oldContacts->size() == ccdPairs.size());
	for (int i = 0; i < oldContacts->size(); ++i)
	{
		auto& newContacts = ccdPairs[i]->getContacts();
		newContacts.splice(newContacts.end(), std::move(oldContacts->at(i)));
	}
	oldContacts->clear();
}

void CcdCollisionLoop::printContacts(std::vector<std::shared_ptr<Collision::CollisionPair>> ccdPairs)
{
	for (const auto& pair : ccdPairs)
	{
		std::cout << "Contacts : " << pair->getContacts().size() << std::endl;
		for (const auto& contact : pair->getContacts())
		{
			std::cout << *contact;
		}
	}
}

void CcdCollisionLoop::assert_no_contacts(std::vector<std::shared_ptr<Collision::CollisionPair>> ccdPairs)
{
	for (const auto& pair : ccdPairs)
	{
		SURGSIM_ASSERT(pair->getContacts().size() == 0);
	}
}

void CcdCollisionLoop::clearContacts(std::vector<std::shared_ptr<Collision::CollisionPair>> ccdPairs)
{
	for (const auto& pair : ccdPairs)
	{
		pair->getContacts().clear();
	}
}

}
}<commit_msg>Clear Contacts during iteration<commit_after>// This file is a part of the OpenSurgSim project.
// Copyright 2013-2016, SimQuest Solutions 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
//
// 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 "SurgSim/Physics/CcdCollisionLoop.h"

#include "SurgSim/Physics/CcdCollision.h"
#include "SurgSim/Physics/UpdateCcdData.h"
#include "SurgSim/Physics/ContactConstraintGeneration.h"
#include "SurgSim/Physics/SolveMlcp.h"
#include "SurgSim/Physics/PushResults.h"
#include "SurgSim/Physics/BuildMlcp.h"
#include "SurgSim/Physics/PhysicsManagerState.h"
#include "SurgSim/Collision/CollisionPair.h"

#include <unordered_set>
#include <limits>

namespace SurgSim
{

namespace Physics
{

CcdCollisionLoop::CcdCollisionLoop(bool copyState) :
	Computation(copyState),
	m_updateCcdData(new UpdateCcdData(copyState)),
	m_ccdCollision(new CcdCollision(copyState)),
	m_constraintGeneration(new ContactConstraintGeneration(copyState)),
	m_buildMlcp(new BuildMlcp(copyState)),
	m_solveMlcp(new SolveMlcp(copyState)),
	m_pushResults(new PushResults(copyState)),
	m_maxIterations(20),
	m_epsilonFactor(100)
{
}

CcdCollisionLoop::~CcdCollisionLoop()
{

}

std::shared_ptr<SurgSim::Physics::PhysicsManagerState> CcdCollisionLoop::doUpdate(const double& dt,
		const std::shared_ptr<PhysicsManagerState>& state)
{
	static bool doSleep;

	if (doSleep)
	{
		boost::this_thread::sleep(boost::posix_time::milliseconds(1000));
	}

	auto lastState = state;
	size_t iterations = m_maxIterations;

	auto collisionPairs = state->getCollisionPairs();
	std::vector<std::shared_ptr<Collision::CollisionPair>> ccdPairs;
	ccdPairs.reserve(collisionPairs.size());

	std::unordered_set<Collision::Representation*> representations;

	std::copy_if(collisionPairs.cbegin(), collisionPairs.cend(), std::back_inserter(ccdPairs),
				 [&representations](const std::shared_ptr<Collision::CollisionPair>& p)
	{
		if (p->getType() == Collision::COLLISION_DETECTION_TYPE_CONTINUOUS)
		{
			representations.insert(p->getFirst().get());
			representations.insert(p->getSecond().get());
			return true;
		}
		return false;
	});

	// localDt is the time left on dt as we step through the CCD, this gets reduced as contacts are found
	double localDt = dt;
	double toi = 0.0;
	double localToi = 0.0;

	std::cout << "--------Iteration Start " << std::endl;

	std::vector<std::list<std::shared_ptr<Collision::Contact>>> oldContacts;

	while (--iterations > 0)
	{
		toi += (1.0 - toi) * localToi;
		double epsilon = 1.0 / ((1 - toi) * m_epsilonFactor);

		lastState = m_updateCcdData->update(localToi, lastState); // state interpolation is triggered in here
		lastState = m_ccdCollision->update(dt, lastState);

// 		std::cout << "--- Iteration " << m_maxIterations - iterations << std::endl;
// 		printContacts(ccdPairs);

		// Find the first impact and filter all contacts beyond a given epsilon
		if (!filterContacts(ccdPairs, epsilon, &localToi))
		{
			break;
		}

		lastState = m_constraintGeneration->update(dt, lastState);
		lastState = m_buildMlcp->update(dt, lastState);
		lastState = m_solveMlcp->update(dt, lastState);
		lastState = m_pushResults->update(dt, lastState);

		if (toi > 1.0)
		{
			break;
		}

		clearContacts(ccdPairs);
	}

	if (iterations == 0)
	{
		std::cout << "----- Maxed out iterations ... " << std::endl;
	}
	else if (iterations < m_maxIterations - 1)
	{
		std::cout << "----- Resolved after " << m_maxIterations - iterations << std::endl;
	}
	else
	{
		std::cout << "--------Iteration End " << std::endl;
	}

	return lastState;
}

bool CcdCollisionLoop::filterContacts(
	const std::vector<std::shared_ptr<Collision::CollisionPair>>& ccdPairs,
	double epsilon,
	double* currentToi)
{
	SURGSIM_ASSERT(currentToi != nullptr);

	double toi = std::numeric_limits<double>::max();

	// Find earliest time of impact
	for (const auto& pair : ccdPairs)
	{
		std::for_each(pair->getContacts().begin(),
					  pair->getContacts().end(), [&toi](const std::shared_ptr<Collision::Contact>& contact)
		{
			toi = std::min<double>(toi, contact->time);
		});
	}

	// Did not find any contacts return false
	if (!(toi < std::numeric_limits<double>::max()))
	{
		return false;
	}

	toi += epsilon;

	for (const auto& pair : ccdPairs)
	{
		pair->getContacts().remove_if([toi](const std::shared_ptr<Collision::Contact>& contact)
		{
			return contact->time > toi;
		});
	}

	*currentToi = toi;

	return true;
}

void CcdCollisionLoop::backupContacts(const std::vector<std::shared_ptr<Collision::CollisionPair>>& ccdPairs,
									  std::vector<std::list<std::shared_ptr<Collision::Contact>>>* oldContacts)
{
	for (auto& pair : ccdPairs)
	{
		oldContacts->emplace_back(pair->getContacts());
		pair->getContacts().clear();
	}
}

void CcdCollisionLoop::restoreContacts(const std::vector<std::shared_ptr<Collision::CollisionPair>>& ccdPairs,
									   std::vector<std::list<std::shared_ptr<Collision::Contact>>>* oldContacts)
{
	if (oldContacts->size() == 0)
	{
		return;
	}

	SURGSIM_ASSERT(oldContacts->size() == ccdPairs.size());
	for (int i = 0; i < oldContacts->size(); ++i)
	{
		auto& newContacts = ccdPairs[i]->getContacts();
		newContacts.splice(newContacts.end(), std::move(oldContacts->at(i)));
	}
	oldContacts->clear();
}

void CcdCollisionLoop::printContacts(std::vector<std::shared_ptr<Collision::CollisionPair>> ccdPairs)
{
	for (const auto& pair : ccdPairs)
	{
		std::cout << "Contacts : " << pair->getContacts().size() << std::endl;
		for (const auto& contact : pair->getContacts())
		{
			std::cout << *contact;
		}
	}
}

void CcdCollisionLoop::assert_no_contacts(std::vector<std::shared_ptr<Collision::CollisionPair>> ccdPairs)
{
	for (const auto& pair : ccdPairs)
	{
		SURGSIM_ASSERT(pair->getContacts().size() == 0);
	}
}

void CcdCollisionLoop::clearContacts(std::vector<std::shared_ptr<Collision::CollisionPair>> ccdPairs)
{
	for (const auto& pair : ccdPairs)
	{
		pair->getContacts().clear();
	}
}

}
}<|endoftext|>


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

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

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

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

#include "otbVectorDataKeywordlist.h"
#include <iomanip>

namespace otb
{

VectorDataKeywordlist
::VectorDataKeywordlist()
{
  //Nothing to do here
}

VectorDataKeywordlist
::~VectorDataKeywordlist()
{
  for (unsigned int i = 0; i < m_FieldList.size(); ++i)
    {
    if (m_FieldList[i].first->GetType() == OFTString)
      {
      CPLFree(m_FieldList[i].second.String);
      }
    delete (m_FieldList[i].first);
    }
}

void
VectorDataKeywordlist
::AddField(OGRFieldDefn* fieldDefn, OGRField* field)
{
  FieldType newField;
  newField.first = fieldDefn;
  newField.second = *field;
  //TODO: evaluate performance impact of fieldDefn copy
  // the object itself could be handled at the VectorData level
  // keeping only pointer here. (but it does not seem
  // necessary so far...)
  m_FieldList.push_back(CopyOgrField(newField));
}

void
VectorDataKeywordlist
::AddField(std::string key, std::string value)
{
  FieldType newField;

  OGRFieldDefn* fieldDefn =  new OGRFieldDefn(key.c_str(), OFTString);

  OGRField field;
  char *   cstr = new char[value.length() + 1];
  strcpy(cstr, value.c_str());
  field.String = cstr;

  newField.first = fieldDefn;
  newField.second = field;
  m_FieldList.push_back(newField);
}

std::string
VectorDataKeywordlist
::GetFieldAsString(std::string key) const
{
  for (unsigned int i = 0; i < m_FieldList.size(); ++i)
    {
    if (key.compare(m_FieldList[i].first->GetNameRef()) == 0)
      {
      if (m_FieldList[i].first->GetType() == OFTString)
        {
        return m_FieldList[i].second.String;
        }
      if (m_FieldList[i].first->GetType() == OFTReal)
        {
        std::ostringstream ss;
        ss << std::setprecision(15) << m_FieldList[i].second.Real;
        return ss.str();
        }
      itkExceptionMacro(<< "This type is not handled (yet) by GetFieldAsString(), please request for it");
      }
    }
  return "";
}

bool
VectorDataKeywordlist
::HasField(std::string key) const
{
  for (unsigned int i = 0; i < m_FieldList.size(); ++i)
    {
    if (key.compare(m_FieldList[i].first->GetNameRef()) == 0)
      {
      return true;
      }
    }
  return false;
}

void
VectorDataKeywordlist
::SetFieldAsString(std::string key, std::string value)
{
  if (HasField(key))
    {
    for (unsigned int i = 0; i < m_FieldList.size(); ++i)
      {
      if (key.compare(m_FieldList[i].first->GetNameRef()) == 0)
        {
        if (m_FieldList[i].first->GetType() == OFTString)
          {
          OGRField field;
          char *   cstr = new char[value.length() + 1];
          strcpy(cstr, value.c_str());
          field.String = cstr;
          m_FieldList[i].second = field;
          }
        else
          {
          itkExceptionMacro(<< "This type is not of string type, can't add the element in it");
          }
        }
      }
    }
  else
    {
    AddField(key, value);
    }
}

VectorDataKeywordlist::FieldType
VectorDataKeywordlist
::GetNthField(unsigned int index) const
{
  if (index > m_FieldList.size())
    {
    itkExceptionMacro(<< " Accessing out-of-range metadata ");
    }
  return m_FieldList[index];
}

unsigned int
VectorDataKeywordlist
::GetNumberOfFields() const
{
  return m_FieldList.size();
}

void
VectorDataKeywordlist
::operator =(const Self& p)
{
  for (unsigned int i = 0; i < p.m_FieldList.size(); ++i)
    {
    m_FieldList.push_back(CopyOgrField(p.m_FieldList[i]));
    }
}

void
VectorDataKeywordlist
::Print(std::ostream& os, itk::Indent indent) const
{
  this->PrintSelf(os, indent.GetNextIndent());
}

void
VectorDataKeywordlist
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  os << indent << " VectorData Keyword list: ";
  os << indent << " - Size: " << m_FieldList.size() << std::endl;
  for (unsigned int i = 0; i < m_FieldList.size(); ++i)
    {
    os << indent << "    " << PrintField(m_FieldList[i]);
    }
}

std::string
VectorDataKeywordlist
::PrintField(FieldType field) const
{
  std::stringstream output;
  output << std::setprecision(15);
  output << field.first->GetNameRef() << " (";
  output << field.first->GetFieldTypeName(field.first->GetType()) << "): ";
  switch (field.first->GetType())
    {
  case OFTInteger:
    {
    output << field.second.Integer;
    break;
    }
  case OFTIntegerList:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTReal:
    {
    output << field.second.Real;
    break;
    }
  case OFTRealList:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTString:
    {
    if (field.second.String != NULL)
      {
      output << field.second.String;
      }
    break;
    }
  case OFTStringList:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTWideString:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTWideStringList:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTBinary:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTDate:
    {
    output << field.second.Date.Year << field.second.Date.Month << field.second.Date.Day;
    break;
    }
  case OFTTime:
    {
    output << field.second.Date.Hour << field.second.Date.Minute << field.second.Date.Second;
    break;
    }
  case OFTDateTime:
    {
    output << field.second.Date.Year << field.second.Date.Month << field.second.Date.Day << "-"
           << field.second.Date.Hour << field.second.Date.Minute << field.second.Date.Second;
    break;
    }
    }
  output << std::endl;
  return output.str();
}

VectorDataKeywordlist::FieldType
VectorDataKeywordlist
::CopyOgrField(FieldType field)
{
  FieldType outField;
  outField.first = new OGRFieldDefn(field.first);
  switch (field.first->GetType())
    {
  case OFTInteger:
    {
    outField.second.Integer = field.second.Integer;
    break;
    }
  case OFTIntegerList:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTReal:
    {
    outField.second.Real = field.second.Real;
    break;
    }
  case OFTRealList:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTString:
    {
    if (field.second.String != NULL)
      {
      CPLFree(outField.second.String);
      outField.second.String = CPLStrdup(field.second.String);
      }
    break;
    }
  case OFTStringList:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTWideString:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTWideStringList:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTBinary:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTDate:
    {
    outField.second.Date.Year = field.second.Date.Year;
    outField.second.Date.Month = field.second.Date.Month;
    outField.second.Date.Day = field.second.Date.Day;
    break;
    }
  case OFTTime:
    {
    outField.second.Date.Hour = field.second.Date.Hour;
    outField.second.Date.Minute = field.second.Date.Minute;
    outField.second.Date.Second = field.second.Date.Second;
    break;
    }
  case OFTDateTime:
    {
    outField.second.Date.Year = field.second.Date.Year;
    outField.second.Date.Month = field.second.Date.Month;
    outField.second.Date.Day = field.second.Date.Day;
    outField.second.Date.Hour = field.second.Date.Hour;
    outField.second.Date.Minute = field.second.Date.Minute;
    outField.second.Date.Second = field.second.Date.Second;
    break;
    }
    }
  return outField;
}

std::ostream &
operator <<(std::ostream& os, const VectorDataKeywordlist& kwl)
{
  kwl.Print(os);
  return os;
}

}
<commit_msg>ENH: support integer in shapefile metadata<commit_after>/*=========================================================================

  Program:   ORFEO Toolbox
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
  See OTBCopyright.txt for details.

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

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

#include "otbVectorDataKeywordlist.h"
#include <iomanip>

namespace otb
{

VectorDataKeywordlist
::VectorDataKeywordlist()
{
  //Nothing to do here
}

VectorDataKeywordlist
::~VectorDataKeywordlist()
{
  for (unsigned int i = 0; i < m_FieldList.size(); ++i)
    {
    if (m_FieldList[i].first->GetType() == OFTString)
      {
      CPLFree(m_FieldList[i].second.String);
      }
    delete (m_FieldList[i].first);
    }
}

void
VectorDataKeywordlist
::AddField(OGRFieldDefn* fieldDefn, OGRField* field)
{
  FieldType newField;
  newField.first = fieldDefn;
  newField.second = *field;
  //TODO: evaluate performance impact of fieldDefn copy
  // the object itself could be handled at the VectorData level
  // keeping only pointer here. (but it does not seem
  // necessary so far...)
  m_FieldList.push_back(CopyOgrField(newField));
}

void
VectorDataKeywordlist
::AddField(std::string key, std::string value)
{
  FieldType newField;

  OGRFieldDefn* fieldDefn =  new OGRFieldDefn(key.c_str(), OFTString);

  OGRField field;
  char *   cstr = new char[value.length() + 1];
  strcpy(cstr, value.c_str());
  field.String = cstr;

  newField.first = fieldDefn;
  newField.second = field;
  m_FieldList.push_back(newField);
}

std::string
VectorDataKeywordlist
::GetFieldAsString(std::string key) const
{
  for (unsigned int i = 0; i < m_FieldList.size(); ++i)
    {
    if (key.compare(m_FieldList[i].first->GetNameRef()) == 0)
      {
      if (m_FieldList[i].first->GetType() == OFTString)
        {
        return m_FieldList[i].second.String;
        }
      if (m_FieldList[i].first->GetType() == OFTInteger)
        {
        std::ostringstream ss;
        ss << std::setprecision(15) << m_FieldList[i].second.Integer;
        return ss.str();
        }
      if (m_FieldList[i].first->GetType() == OFTReal)
        {
        std::ostringstream ss;
        ss << std::setprecision(15) << m_FieldList[i].second.Real;
        return ss.str();
        }
      itkExceptionMacro(<< "This type (" << m_FieldList[i].first->GetType() << ") is not handled (yet) by GetFieldAsString(), please request for it");
      }
    }
  return "";
}

bool
VectorDataKeywordlist
::HasField(std::string key) const
{
  for (unsigned int i = 0; i < m_FieldList.size(); ++i)
    {
    if (key.compare(m_FieldList[i].first->GetNameRef()) == 0)
      {
      return true;
      }
    }
  return false;
}

void
VectorDataKeywordlist
::SetFieldAsString(std::string key, std::string value)
{
  if (HasField(key))
    {
    for (unsigned int i = 0; i < m_FieldList.size(); ++i)
      {
      if (key.compare(m_FieldList[i].first->GetNameRef()) == 0)
        {
        if (m_FieldList[i].first->GetType() == OFTString)
          {
          OGRField field;
          char *   cstr = new char[value.length() + 1];
          strcpy(cstr, value.c_str());
          field.String = cstr;
          m_FieldList[i].second = field;
          }
        else
          {
          itkExceptionMacro(<< "This type is not of string type, can't add the element in it");
          }
        }
      }
    }
  else
    {
    AddField(key, value);
    }
}

VectorDataKeywordlist::FieldType
VectorDataKeywordlist
::GetNthField(unsigned int index) const
{
  if (index > m_FieldList.size())
    {
    itkExceptionMacro(<< " Accessing out-of-range metadata ");
    }
  return m_FieldList[index];
}

unsigned int
VectorDataKeywordlist
::GetNumberOfFields() const
{
  return m_FieldList.size();
}

void
VectorDataKeywordlist
::operator =(const Self& p)
{
  for (unsigned int i = 0; i < p.m_FieldList.size(); ++i)
    {
    m_FieldList.push_back(CopyOgrField(p.m_FieldList[i]));
    }
}

void
VectorDataKeywordlist
::Print(std::ostream& os, itk::Indent indent) const
{
  this->PrintSelf(os, indent.GetNextIndent());
}

void
VectorDataKeywordlist
::PrintSelf(std::ostream& os, itk::Indent indent) const
{
  os << indent << " VectorData Keyword list: ";
  os << indent << " - Size: " << m_FieldList.size() << std::endl;
  for (unsigned int i = 0; i < m_FieldList.size(); ++i)
    {
    os << indent << "    " << PrintField(m_FieldList[i]);
    }
}

std::string
VectorDataKeywordlist
::PrintField(FieldType field) const
{
  std::stringstream output;
  output << std::setprecision(15);
  output << field.first->GetNameRef() << " (";
  output << field.first->GetFieldTypeName(field.first->GetType()) << "): ";
  switch (field.first->GetType())
    {
  case OFTInteger:
    {
    output << field.second.Integer;
    break;
    }
  case OFTIntegerList:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTReal:
    {
    output << field.second.Real;
    break;
    }
  case OFTRealList:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTString:
    {
    if (field.second.String != NULL)
      {
      output << field.second.String;
      }
    break;
    }
  case OFTStringList:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTWideString:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTWideStringList:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTBinary:
    {
    output << "Type not handled for printing";
    break;
    }
  case OFTDate:
    {
    output << field.second.Date.Year << field.second.Date.Month << field.second.Date.Day;
    break;
    }
  case OFTTime:
    {
    output << field.second.Date.Hour << field.second.Date.Minute << field.second.Date.Second;
    break;
    }
  case OFTDateTime:
    {
    output << field.second.Date.Year << field.second.Date.Month << field.second.Date.Day << "-"
           << field.second.Date.Hour << field.second.Date.Minute << field.second.Date.Second;
    break;
    }
    }
  output << std::endl;
  return output.str();
}

VectorDataKeywordlist::FieldType
VectorDataKeywordlist
::CopyOgrField(FieldType field)
{
  FieldType outField;
  outField.first = new OGRFieldDefn(field.first);
  switch (field.first->GetType())
    {
  case OFTInteger:
    {
    outField.second.Integer = field.second.Integer;
    break;
    }
  case OFTIntegerList:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTReal:
    {
    outField.second.Real = field.second.Real;
    break;
    }
  case OFTRealList:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTString:
    {
    if (field.second.String != NULL)
      {
      CPLFree(outField.second.String);
      outField.second.String = CPLStrdup(field.second.String);
      }
    break;
    }
  case OFTStringList:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTWideString:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTWideStringList:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTBinary:
    {
    std::cerr << "OGR type not handled" << std::endl;
    break;
    }
  case OFTDate:
    {
    outField.second.Date.Year = field.second.Date.Year;
    outField.second.Date.Month = field.second.Date.Month;
    outField.second.Date.Day = field.second.Date.Day;
    break;
    }
  case OFTTime:
    {
    outField.second.Date.Hour = field.second.Date.Hour;
    outField.second.Date.Minute = field.second.Date.Minute;
    outField.second.Date.Second = field.second.Date.Second;
    break;
    }
  case OFTDateTime:
    {
    outField.second.Date.Year = field.second.Date.Year;
    outField.second.Date.Month = field.second.Date.Month;
    outField.second.Date.Day = field.second.Date.Day;
    outField.second.Date.Hour = field.second.Date.Hour;
    outField.second.Date.Minute = field.second.Date.Minute;
    outField.second.Date.Second = field.second.Date.Second;
    break;
    }
    }
  return outField;
}

std::ostream &
operator <<(std::ostream& os, const VectorDataKeywordlist& kwl)
{
  kwl.Print(os);
  return os;
}

}
<|endoftext|>


<commit_before>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "direct_tensor_attribute.h"
#include "direct_tensor_saver.h"

#include <vespa/eval/eval/fast_value.h>
#include <vespa/eval/eval/value.h>
#include <vespa/searchlib/attribute/readerbase.h>
#include <vespa/searchlib/util/fileutil.h>
#include <vespa/vespalib/util/array.h>

#include "blob_sequence_reader.h"
#include "tensor_deserialize.h"
#include "tensor_attribute.hpp"

using vespalib::eval::FastValueBuilderFactory;

namespace search::tensor {

DirectTensorAttribute::DirectTensorAttribute(stringref name, const Config &cfg)
    : TensorAttribute(name, cfg, _direct_store)
{
}

DirectTensorAttribute::~DirectTensorAttribute()
{
    getGenerationHolder().clearHoldLists();
    _tensorStore.clearHoldLists();
}

bool
DirectTensorAttribute::onLoad(vespalib::Executor *)
{
    BlobSequenceReader tensorReader(*this);
    if (!tensorReader.hasData()) {
        return false;
    }
    setCreateSerialNum(tensorReader.getCreateSerialNum());
    assert(tensorReader.getVersion() == getVersion());
    uint32_t numDocs = tensorReader.getDocIdLimit();
    _refVector.reset();
    _refVector.unsafe_reserve(numDocs);
    vespalib::Array<char> buffer(1024);
    for (uint32_t lid = 0; lid < numDocs; ++lid) {
        uint32_t tensorSize = tensorReader.getNextSize();
        if (tensorSize != 0) {
            if (tensorSize > buffer.size()) {
                buffer.resize(tensorSize + 1024);
            }
            tensorReader.readBlob(&buffer[0], tensorSize);
            auto tensor = deserialize_tensor(&buffer[0], tensorSize);
            EntryRef ref = _direct_store.store_tensor(std::move(tensor));
            _refVector.push_back(AtomicEntryRef(ref));
        } else {
            EntryRef invalid;
            _refVector.push_back(AtomicEntryRef(invalid));
        }
    }
    setNumDocs(numDocs);
    setCommittedDocIdLimit(numDocs);
    return true;
}

void
DirectTensorAttribute::set_tensor(DocId lid, std::unique_ptr<vespalib::eval::Value> tensor)
{
    checkTensorType(*tensor);
    EntryRef ref = _direct_store.store_tensor(std::move(tensor));
    setTensorRef(lid, ref);
}

void
DirectTensorAttribute::setTensor(DocId lid, const vespalib::eval::Value &tensor)
{
    set_tensor(lid, FastValueBuilderFactory::get().copy(tensor));
}

void
DirectTensorAttribute::update_tensor(DocId docId,
                                     const document::TensorUpdate &update,
                                     bool create_if_non_existing)
{
    EntryRef ref;
    if (docId < getCommittedDocIdLimit()) {
        ref = _refVector[docId].load_relaxed();
    }
    if (ref.valid()) {
        auto ptr = _direct_store.get_tensor(ref);
        if (ptr) {
            auto new_value = update.apply_to(*ptr, FastValueBuilderFactory::get());
            if (new_value) {
                set_tensor(docId, std::move(new_value));
            }
            return;
        }
    }
    if (create_if_non_existing) {
        auto new_value = update.apply_to(*_emptyTensor, FastValueBuilderFactory::get());
        if (new_value) {
            set_tensor(docId, std::move(new_value));
        }
    }
}

std::unique_ptr<vespalib::eval::Value>
DirectTensorAttribute::getTensor(DocId docId) const
{
    EntryRef ref;
    if (docId < getCommittedDocIdLimit()) {
        ref = acquire_entry_ref(docId);
    }
    if (ref.valid()) {
        auto ptr = _direct_store.get_tensor(ref);
        if (ptr) {
            return FastValueBuilderFactory::get().copy(*ptr);
        }
    }
    std::unique_ptr<vespalib::eval::Value> empty;
    return empty;
}

const vespalib::eval::Value &
DirectTensorAttribute::get_tensor_ref(DocId docId) const
{
    if (docId >= getCommittedDocIdLimit()) return *_emptyTensor;

    auto ptr = _direct_store.get_tensor(acquire_entry_ref(docId));
    if ( ptr == nullptr) return *_emptyTensor;

    return *ptr;
}

std::unique_ptr<AttributeSaver>
DirectTensorAttribute::onInitSave(vespalib::stringref fileName)
{
    vespalib::GenerationHandler::Guard guard(getGenerationHandler().takeGuard());
    return std::make_unique<DirectTensorAttributeSaver>
        (std::move(guard),
         this->createAttributeHeader(fileName),
         getRefCopy(),
         _direct_store);
}

void
DirectTensorAttribute::compactWorst()
{
    doCompactWorst<DirectTensorStore::RefType>();
}

} // namespace
<commit_msg>Use braces.<commit_after>// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root.

#include "direct_tensor_attribute.h"
#include "direct_tensor_saver.h"

#include <vespa/eval/eval/fast_value.h>
#include <vespa/eval/eval/value.h>
#include <vespa/searchlib/attribute/readerbase.h>
#include <vespa/searchlib/util/fileutil.h>
#include <vespa/vespalib/util/array.h>

#include "blob_sequence_reader.h"
#include "tensor_deserialize.h"
#include "tensor_attribute.hpp"

using vespalib::eval::FastValueBuilderFactory;

namespace search::tensor {

DirectTensorAttribute::DirectTensorAttribute(stringref name, const Config &cfg)
    : TensorAttribute(name, cfg, _direct_store)
{
}

DirectTensorAttribute::~DirectTensorAttribute()
{
    getGenerationHolder().clearHoldLists();
    _tensorStore.clearHoldLists();
}

bool
DirectTensorAttribute::onLoad(vespalib::Executor *)
{
    BlobSequenceReader tensorReader(*this);
    if (!tensorReader.hasData()) {
        return false;
    }
    setCreateSerialNum(tensorReader.getCreateSerialNum());
    assert(tensorReader.getVersion() == getVersion());
    uint32_t numDocs = tensorReader.getDocIdLimit();
    _refVector.reset();
    _refVector.unsafe_reserve(numDocs);
    vespalib::Array<char> buffer(1024);
    for (uint32_t lid = 0; lid < numDocs; ++lid) {
        uint32_t tensorSize = tensorReader.getNextSize();
        if (tensorSize != 0) {
            if (tensorSize > buffer.size()) {
                buffer.resize(tensorSize + 1024);
            }
            tensorReader.readBlob(&buffer[0], tensorSize);
            auto tensor = deserialize_tensor(&buffer[0], tensorSize);
            EntryRef ref = _direct_store.store_tensor(std::move(tensor));
            _refVector.push_back(AtomicEntryRef(ref));
        } else {
            EntryRef invalid;
            _refVector.push_back(AtomicEntryRef(invalid));
        }
    }
    setNumDocs(numDocs);
    setCommittedDocIdLimit(numDocs);
    return true;
}

void
DirectTensorAttribute::set_tensor(DocId lid, std::unique_ptr<vespalib::eval::Value> tensor)
{
    checkTensorType(*tensor);
    EntryRef ref = _direct_store.store_tensor(std::move(tensor));
    setTensorRef(lid, ref);
}

void
DirectTensorAttribute::setTensor(DocId lid, const vespalib::eval::Value &tensor)
{
    set_tensor(lid, FastValueBuilderFactory::get().copy(tensor));
}

void
DirectTensorAttribute::update_tensor(DocId docId,
                                     const document::TensorUpdate &update,
                                     bool create_if_non_existing)
{
    EntryRef ref;
    if (docId < getCommittedDocIdLimit()) {
        ref = _refVector[docId].load_relaxed();
    }
    if (ref.valid()) {
        auto ptr = _direct_store.get_tensor(ref);
        if (ptr) {
            auto new_value = update.apply_to(*ptr, FastValueBuilderFactory::get());
            if (new_value) {
                set_tensor(docId, std::move(new_value));
            }
            return;
        }
    }
    if (create_if_non_existing) {
        auto new_value = update.apply_to(*_emptyTensor, FastValueBuilderFactory::get());
        if (new_value) {
            set_tensor(docId, std::move(new_value));
        }
    }
}

std::unique_ptr<vespalib::eval::Value>
DirectTensorAttribute::getTensor(DocId docId) const
{
    EntryRef ref;
    if (docId < getCommittedDocIdLimit()) {
        ref = acquire_entry_ref(docId);
    }
    if (ref.valid()) {
        auto ptr = _direct_store.get_tensor(ref);
        if (ptr) {
            return FastValueBuilderFactory::get().copy(*ptr);
        }
    }
    std::unique_ptr<vespalib::eval::Value> empty;
    return empty;
}

const vespalib::eval::Value &
DirectTensorAttribute::get_tensor_ref(DocId docId) const
{
    if (docId >= getCommittedDocIdLimit()) { return *_emptyTensor; }

    auto ptr = _direct_store.get_tensor(acquire_entry_ref(docId));
    if ( ptr == nullptr) { return *_emptyTensor; }

    return *ptr;
}

std::unique_ptr<AttributeSaver>
DirectTensorAttribute::onInitSave(vespalib::stringref fileName)
{
    vespalib::GenerationHandler::Guard guard(getGenerationHandler().takeGuard());
    return std::make_unique<DirectTensorAttributeSaver>
        (std::move(guard),
         this->createAttributeHeader(fileName),
         getRefCopy(),
         _direct_store);
}

void
DirectTensorAttribute::compactWorst()
{
    doCompactWorst<DirectTensorStore::RefType>();
}

} // namespace
<|endoftext|>


<commit_before>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
  *
  * Condor Software Copyright Notice
  * Copyright (C) 1990-2006, Condor Team, Computer Sciences Department,
  * University of Wisconsin-Madison, WI.
  *
  * This source code is covered by the Condor Public License, which can
  * be found in the accompanying LICENSE.TXT file, or online at
  * www.condorproject.org.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
  * RIGHT.
  *
  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "condor_common.h"
#include "condor_random_num.h"
#include "io_proxy.h"
#include "io_proxy_handler.h"
#include "starter_privsep_helper.h"

#define IO_PROXY_COOKIE_SIZE 32

static char * cookie_create( int length );

IOProxy::IOProxy()
{
	server = NULL;
	cookie = 0;
	socket_registered = false;
}

IOProxy::~IOProxy()
{
	if ( daemonCore && socket_registered && server ) {
		daemonCore->Cancel_Socket(server);
	}
	if ( server ) {
		server->close();
		delete server;
	}
	if(cookie) free(cookie);
}

/*
This callback is invoked for each new incoming connection.
In response, fork a new IOProxyHandler child to deal with the stream.
Returns KEEP_STREAM if the stream is still valid, ~KEEP_STREAM otherwise.
*/

int IOProxy::connect_callback( Stream * /*stream*/ )
{
	ReliSock *client = new ReliSock;
	bool accept_client = false;
	int success;

	success = server->accept(*client);
	if(success) {
		if( my_ip_addr() != client->endpoint_ip_int() ) {
			dprintf(D_ALWAYS,"IOProxy: rejecting connection from %s: invalid ip addr\n",client->endpoint_ip_str());
		} else {
			dprintf(D_ALWAYS,"IOProxy: accepting connection from %s\n",client->endpoint_ip_str());
			accept_client = true;
		}
	} else {
		dprintf(D_ALWAYS,"IOProxy: Couldn't accept connection: %s\n",strerror(errno));
	}

	if(accept_client) {
		IOProxyHandler *handler = new IOProxyHandler();
		if(!handler->init(client,cookie)) {
			dprintf(D_ALWAYS,"IOProxy: couldn't register request callback!\n");
			client->close();
			delete client;
		}

	} else {
		client->close();
		delete client;
	}

	return KEEP_STREAM;
}

/*
Initialize this proxy and dump the contact information into the given file.
Returns true on success, false otherwise.
*/

bool IOProxy::init( const char *config_file )
{
	FILE *file=0;
	int fd=-1;

	server = new ReliSock;
	if ( !server ) {
		dprintf(D_ALWAYS,"IOProxy: couldn't create socket\n");
		return false;
	}

	/* FALSE means this is an incomming connection */
	if(!server->bind(FALSE)) {
		dprintf(D_ALWAYS,"IOProxy: couldn't bind: %s\n",strerror(errno));
		return false;
	}

	if(!server->listen()) {
		dprintf(D_ALWAYS,"IOProxy: couldn't listen: %s\n",strerror(errno));
		return false;
	}

	cookie = cookie_create(IO_PROXY_COOKIE_SIZE);
	if(!cookie) {
		dprintf(D_ALWAYS,"IOProxy: couldn't create cookie: %s\n",strerror(errno));
		goto failure;
	}

	if (privsep_enabled()) {
		fd = privsep_helper.open_sandbox_file(config_file,
		                                      O_CREAT|O_TRUNC|O_WRONLY,
		                                      0700);
	}
	else {
		fd = safe_open_wrapper(config_file,
		                       O_CREAT|O_TRUNC|O_WRONLY,
		                       0700);
	}
	if(fd<0) {
		dprintf(D_ALWAYS,
		        "IOProxy: couldn't write to %s: %s\n",
		        config_file,
		        strerror(errno));
		goto failure;
	}

	file = fdopen(fd,"w");
	if(!file) {
		dprintf(D_ALWAYS,"IOProxy: couldn't create I/O stream: %s\n",strerror(errno));
		goto failure;
	}

	fprintf(file,"%s %d %s\n",my_ip_string(),server->get_port(),cookie);
	fclose(file);

	daemonCore->Register_Socket( server, "IOProxy listen socket",
		(SocketHandlercpp) &IOProxy::connect_callback,
		"IOProxy connect callback", this );
	socket_registered = true;
	return true;

	failure:
	if(cookie) free(cookie);
	if(file) fclose(file);
	unlink(config_file);
	server->close();
	return false;
}

/*
On success, returns a newly-allocated random cookie string.
On failure, returns null.
*/

static char * cookie_create( int length )
{
	char *c = (char*) malloc(length);
	if(!c) return 0;

	for( int i=0; i<length; i++ ) {
		c[i] = 'a'+get_random_int()%26;
	}

	c[length-1] = 0;

	return c;
}

<commit_msg>no need to register the chrip (IOproxy) listen socket in the starter with a GCB broker, since only machines on this host can ever authenticate to it.<commit_after>/***************************Copyright-DO-NOT-REMOVE-THIS-LINE**
  *
  * Condor Software Copyright Notice
  * Copyright (C) 1990-2006, Condor Team, Computer Sciences Department,
  * University of Wisconsin-Madison, WI.
  *
  * This source code is covered by the Condor Public License, which can
  * be found in the accompanying LICENSE.TXT file, or online at
  * www.condorproject.org.
  *
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  * AND THE UNIVERSITY OF WISCONSIN-MADISON "AS IS" AND ANY EXPRESS OR
  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  * WARRANTIES OF MERCHANTABILITY, OF SATISFACTORY QUALITY, AND FITNESS
  * FOR A PARTICULAR PURPOSE OR USE ARE DISCLAIMED. THE COPYRIGHT
  * HOLDERS AND CONTRIBUTORS AND THE UNIVERSITY OF WISCONSIN-MADISON
  * MAKE NO MAKE NO REPRESENTATION THAT THE SOFTWARE, MODIFICATIONS,
  * ENHANCEMENTS OR DERIVATIVE WORKS THEREOF, WILL NOT INFRINGE ANY
  * PATENT, COPYRIGHT, TRADEMARK, TRADE SECRET OR OTHER PROPRIETARY
  * RIGHT.
  *
  ****************************Copyright-DO-NOT-REMOVE-THIS-LINE**/

#include "condor_common.h"
#include "condor_random_num.h"
#include "io_proxy.h"
#include "io_proxy_handler.h"
#include "starter_privsep_helper.h"

#define IO_PROXY_COOKIE_SIZE 32

static char * cookie_create( int length );

IOProxy::IOProxy()
{
	server = NULL;
	cookie = 0;
	socket_registered = false;
}

IOProxy::~IOProxy()
{
	if ( daemonCore && socket_registered && server ) {
		daemonCore->Cancel_Socket(server);
	}
	if ( server ) {
		server->close();
		delete server;
	}
	if(cookie) free(cookie);
}

/*
This callback is invoked for each new incoming connection.
In response, fork a new IOProxyHandler child to deal with the stream.
Returns KEEP_STREAM if the stream is still valid, ~KEEP_STREAM otherwise.
*/

int IOProxy::connect_callback( Stream * /*stream*/ )
{
	ReliSock *client = new ReliSock;
	bool accept_client = false;
	int success;

	success = server->accept(*client);
	if(success) {
		if( my_ip_addr() != client->endpoint_ip_int() ) {
			dprintf(D_ALWAYS,"IOProxy: rejecting connection from %s: invalid ip addr\n",client->endpoint_ip_str());
		} else {
			dprintf(D_ALWAYS,"IOProxy: accepting connection from %s\n",client->endpoint_ip_str());
			accept_client = true;
		}
	} else {
		dprintf(D_ALWAYS,"IOProxy: Couldn't accept connection: %s\n",strerror(errno));
	}

	if(accept_client) {
		IOProxyHandler *handler = new IOProxyHandler();
		if(!handler->init(client,cookie)) {
			dprintf(D_ALWAYS,"IOProxy: couldn't register request callback!\n");
			client->close();
			delete client;
		}

	} else {
		client->close();
		delete client;
	}

	return KEEP_STREAM;
}

/*
Initialize this proxy and dump the contact information into the given file.
Returns true on success, false otherwise.
*/

bool IOProxy::init( const char *config_file )
{
	FILE *file=0;
	int fd=-1;

	server = new ReliSock;
	if ( !server ) {
		dprintf(D_ALWAYS,"IOProxy: couldn't create socket\n");
		return false;
	}

	/* passing FALSE to bind means this is an incomming connection.
	 * however, here we are going to pass TRUE because only machines
	 * on this host need to connect to the ioproxy (chirp) socket,
	 * so there is no need to register it with a gcb broker.
	 **/
	if(!server->bind(TRUE)) {
		dprintf(D_ALWAYS,"IOProxy: couldn't bind: %s\n",strerror(errno));
		return false;
	}

	if(!server->listen()) {
		dprintf(D_ALWAYS,"IOProxy: couldn't listen: %s\n",strerror(errno));
		return false;
	}

	cookie = cookie_create(IO_PROXY_COOKIE_SIZE);
	if(!cookie) {
		dprintf(D_ALWAYS,"IOProxy: couldn't create cookie: %s\n",strerror(errno));
		goto failure;
	}

	if (privsep_enabled()) {
		fd = privsep_helper.open_sandbox_file(config_file,
		                                      O_CREAT|O_TRUNC|O_WRONLY,
		                                      0700);
	}
	else {
		fd = safe_open_wrapper(config_file,
		                       O_CREAT|O_TRUNC|O_WRONLY,
		                       0700);
	}
	if(fd<0) {
		dprintf(D_ALWAYS,
		        "IOProxy: couldn't write to %s: %s\n",
		        config_file,
		        strerror(errno));
		goto failure;
	}

	file = fdopen(fd,"w");
	if(!file) {
		dprintf(D_ALWAYS,"IOProxy: couldn't create I/O stream: %s\n",strerror(errno));
		goto failure;
	}

	fprintf(file,"%s %d %s\n",my_ip_string(),server->get_port(),cookie);
	fclose(file);

	daemonCore->Register_Socket( server, "IOProxy listen socket",
		(SocketHandlercpp) &IOProxy::connect_callback,
		"IOProxy connect callback", this );
	socket_registered = true;
	return true;

	failure:
	if(cookie) free(cookie);
	if(file) fclose(file);
	unlink(config_file);
	server->close();
	return false;
}

/*
On success, returns a newly-allocated random cookie string.
On failure, returns null.
*/

static char * cookie_create( int length )
{
	char *c = (char*) malloc(length);
	if(!c) return 0;

	for( int i=0; i<length; i++ ) {
		c[i] = 'a'+get_random_int()%26;
	}

	c[length-1] = 0;

	return c;
}

<|endoftext|>


<commit_before><commit_msg>`yli::callback_system::CallbackObject`: `anyvalue_hashmap` is `private`.<commit_after><|endoftext|>


<commit_before>/*
 * Buzzer.cpp
 *
 * Created: 7-2-2013 0:22:37
 *  Author: Elco
 */
#include "pins.h"
#include "Buzzer.h"
#include <util/delay.h>

#if (alarmPin != 3)
	#error "Check PWM settings when you want to use a different pin for the alarm"
#endif

#if defined(USBCON)
// Arduino Leonardo, the buzzer is on OC0B, but Timer0 is already in use for micros() and millis()
// Do not change anything about the timer, just use the output mode
#define BEEP_ON() bitSet(TCCR0A,COM0B1);
#define BEEP_OFF() bitClear(TCCR0A,COM0B1);

void Buzzer::init(void){
	// set up square wave PWM for buzzer
	pinMode(alarmPin,OUTPUT);
}

#else
// Arduino Uno, the buzzer is on OC2B
#define BEEP_ON() bitSet(TCCR2A,COM2B1);
#define BEEP_OFF() bitClear(TCCR2A,COM2B1);

void Buzzer::init(void){
	// set up square wave PWM for buzzer
	pinMode(alarmPin,OUTPUT);
	// Arduino UNO, buzzer is on OC2B
	TCCR2A = (1<<COM2B1) | (1<<WGM22) | (1<<WGM20);
	TCCR2B = (1<<CS21) | (1<<CS20); // prescaler = 32
	OCR2A = 125; // timer top. This value adjusts the frequency.
}
#endif

void Buzzer::beep(uint8_t numBeeps, uint16_t duration){
	for(uint8_t beepCount = 0; beepCount<numBeeps; beepCount++){
		BEEP_ON();
		delay(duration);
		BEEP_OFF();
		if(beepCount < numBeeps - 1){
			delay(duration); // not the last beep
		}
	}
}

Buzzer buzzer;<commit_msg>Fixed buzzer on Arduino UNO<commit_after>/*
 * Buzzer.cpp
 *
 * Created: 7-2-2013 0:22:37
 *  Author: Elco
 */
#include "pins.h"
#include "Buzzer.h"
#include <util/delay.h>

#if (alarmPin != 3)
	#error "Check PWM settings when you want to use a different pin for the alarm"
#endif

#if defined(USBCON)
// Arduino Leonardo, the buzzer is on OC0B, but Timer0 is already in use for micros() and millis()
// Do not change anything about the timer, just use the output mode
#define BEEP_ON() bitSet(TCCR0A,COM0B1);
#define BEEP_OFF() bitClear(TCCR0A,COM0B1);

void Buzzer::init(void){
	// set up square wave PWM for buzzer
	pinMode(alarmPin,OUTPUT);
}

#else
// Arduino Uno, the buzzer is on OC2B
#define BEEP_ON() bitSet(TCCR2A,COM2B1);
#define BEEP_OFF() bitClear(TCCR2A,COM2B1);

void Buzzer::init(void){
	// set up square wave PWM for buzzer
	pinMode(alarmPin,OUTPUT);
	// Arduino UNO, buzzer is on OC2B
	TCCR2A = (1<<COM2B1) | (1<<WGM20);
	TCCR2B = (1<<WGM22) | (1<<CS21) | (1<<CS20); // prescaler = 32
	OCR2A = 125; // timer top. This value adjusts the frequency.
	OCR2B = 62;
}

#endif

void Buzzer::beep(uint8_t numBeeps, uint16_t duration){
	for(uint8_t beepCount = 0; beepCount<numBeeps; beepCount++){
		BEEP_ON();
		delay(duration);
		BEEP_OFF();
		if(beepCount < numBeeps - 1){
			delay(duration); // not the last beep
		}
	}
}

Buzzer buzzer;<|endoftext|>


<commit_before>#include "ParaMapConverter.h"

using namespace std;

namespace dcmqi {

  int ParaMapConverter::itkimage2paramap(const string &inputFileName, const string &dicomImageFileName,
																				 const string &metaDataFileName, const string &outputFileName) {

    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(inputFileName.c_str());
    reader->Update();
    ImageType::Pointer parametricMapImage = reader->GetOutput();

    ImageType::SizeType inputSize = parametricMapImage->GetBufferedRegion().GetSize();
    cout << "Input image size: " << inputSize << endl;

    JSONParametricMapMetaInformationHandler metaInfo(metaDataFileName);
    metaInfo.read();

    MinMaxCalculatorType::Pointer calculator = MinMaxCalculatorType::New();
    calculator->SetImage(parametricMapImage);
    calculator->Compute();

    metaInfo.setFirstValueMapped(calculator->GetMinimum());
    metaInfo.setLastValueMapped(calculator->GetMaximum());

    IODEnhGeneralEquipmentModule::EquipmentInfo eq = getEnhEquipmentInfo();
    ContentIdentificationMacro contentID = createContentIdentificationInformation();
    CHECK_COND(contentID.setInstanceNumber(metaInfo.getInstanceNumber().c_str()));

    DcmDataset pMapDocDataset;
    DPMParametricMapFloat *pMapDoc = NULL;

    // TODO: following should maybe be moved to meta info
    OFString imageFlavor = "VOLUME";
    OFString pixContrast = "MTT";
    DPMTypes::ContentQualification contQual = DPMTypes::CQ_RESEARCH;
    OFString modality = "MR";

    CHECK_COND(DPMParametricMapFloat::create(pMapDoc, modality, metaInfo.getSeriesNumber().c_str(),
																						 metaInfo.getInstanceNumber().c_str(),
																						 inputSize[0], inputSize[1], eq, contentID,
																						 imageFlavor, pixContrast, contQual));

    if (!dicomImageFileName.empty())
      CHECK_COND(pMapDoc->import(dicomImageFileName.c_str(), OFTrue, OFTrue, OFFalse, OFTrue));

    /* Initialize dimension module */
    char dimUID[128];
    dcmGenerateUniqueIdentifier(dimUID, QIICR_UID_ROOT);
    IODMultiframeDimensionModule &mfdim = pMapDoc->getIODMultiframeDimensionModule();
    OFCondition result = mfdim.addDimensionIndex(DCM_ImagePositionPatient, dimUID,
																								 DCM_RealWorldValueMappingSequence, "Frame position");

    // Shared FGs: PixelMeasuresSequence
    {
      FGPixelMeasures *pixmsr = new FGPixelMeasures();

      ImageType::SpacingType labelSpacing = parametricMapImage->GetSpacing();
      ostringstream spacingSStream;
      spacingSStream << scientific << labelSpacing[0] << "\\" << labelSpacing[1];
      CHECK_COND(pixmsr->setPixelSpacing(spacingSStream.str().c_str()));

      spacingSStream.clear(); spacingSStream.str("");
      spacingSStream << scientific << labelSpacing[2];
      CHECK_COND(pixmsr->setSpacingBetweenSlices(spacingSStream.str().c_str()));
      CHECK_COND(pixmsr->setSliceThickness(spacingSStream.str().c_str()));
      CHECK_COND(pMapDoc->addForAllFrames(*pixmsr));
    }

    // Shared FGs: PlaneOrientationPatientSequence
    {
      OFString imageOrientationPatientStr;

      ImageType::DirectionType labelDirMatrix = parametricMapImage->GetDirection();

      cout << "Directions: " << labelDirMatrix << endl;

      FGPlaneOrientationPatient *planor =
          FGPlaneOrientationPatient::createMinimal(
              Helper::floatToStrScientific(labelDirMatrix[0][0]).c_str(),
              Helper::floatToStrScientific(labelDirMatrix[1][0]).c_str(),
              Helper::floatToStrScientific(labelDirMatrix[2][0]).c_str(),
              Helper::floatToStrScientific(labelDirMatrix[0][1]).c_str(),
              Helper::floatToStrScientific(labelDirMatrix[1][1]).c_str(),
              Helper::floatToStrScientific(labelDirMatrix[2][1]).c_str());

      //CHECK_COND(planor->setImageOrientationPatient(imageOrientationPatientStr));
      CHECK_COND(pMapDoc->addForAllFrames(*planor));
    }

    FGFrameAnatomy frameAnaFG;
    frameAnaFG.setLaterality(FGFrameAnatomy::LATERALITY_UNPAIRED);
    frameAnaFG.getAnatomy().getAnatomicRegion().set("T-A0100", "SRT", "Brain");
    CHECK_COND(pMapDoc->addForAllFrames(frameAnaFG));

    FGIdentityPixelValueTransformation idTransFG;
    // Rescale Intercept, Rescale Slope, Rescale Type are missing here
    CHECK_COND(pMapDoc->addForAllFrames(idTransFG));

    FGParametricMapFrameType frameTypeFG;
    frameTypeFG.setFrameType("DERIVED\\PRIMARY\\VOLUME\\MTT");
    CHECK_COND(pMapDoc->addForAllFrames(frameTypeFG));

    for (unsigned long f = 0; result.good() && (f < inputSize[2]); f++) {
      result = addFrame(pMapDoc, parametricMapImage, metaInfo, f);
    }

  {
    string bodyPartAssigned = metaInfo.getBodyPartExamined();
    if(!dicomImageFileName.empty() && bodyPartAssigned.empty()) {
      DcmFileFormat sliceFF;
      CHECK_COND(sliceFF.loadFile(dicomImageFileName.c_str()));
      OFString bodyPartStr;
      if(sliceFF.getDataset()->findAndGetOFString(DCM_BodyPartExamined, bodyPartStr).good()) {
        if (!bodyPartStr.empty())
          bodyPartAssigned = bodyPartStr.c_str();
      }
    }
    if(!bodyPartAssigned.empty())
      pMapDoc->getIODGeneralSeriesModule().setBodyPartExamined(bodyPartAssigned.c_str());
  }

  // SeriesDate/Time should be of when parametric map was taken; initialize to when it was saved
  {
    OFString contentDate, contentTime;
    DcmDate::getCurrentDate(contentDate);
    DcmTime::getCurrentTime(contentTime);

    pMapDocDataset.putAndInsertString(DCM_ContentDate, contentDate.c_str());
    pMapDocDataset.putAndInsertString(DCM_ContentTime, contentTime.c_str());
    pMapDocDataset.putAndInsertString(DCM_SeriesDate, contentDate.c_str());
    pMapDocDataset.putAndInsertString(DCM_SeriesTime, contentTime.c_str());

    pMapDocDataset.putAndInsertString(DCM_SeriesDescription, metaInfo.getSeriesDescription().c_str());
    pMapDocDataset.putAndInsertString(DCM_SeriesNumber, metaInfo.getSeriesNumber().c_str());
  }

  CHECK_COND(pMapDoc->writeDataset(pMapDocDataset));
  CHECK_COND(pMapDoc->saveFile(outputFileName.c_str()));

  COUT << "Saved parametric map as " << outputFileName << endl;
    return EXIT_SUCCESS;
  }

  int ParaMapConverter::paramap2itkimage(const string &inputParamapFileName, const string &outputDirName) {
    return EXIT_SUCCESS;
  }

  OFCondition ParaMapConverter::addFrame(DPMParametricMapFloat *map, const ImageType::Pointer &parametricMapImage,
																				 const JSONParametricMapMetaInformationHandler &metaInfo,
                                         const unsigned long frameNo)
  {
    ImageType::RegionType sliceRegion;
    ImageType::IndexType sliceIndex;
    ImageType::SizeType inputSize = parametricMapImage->GetBufferedRegion().GetSize();

    sliceIndex[0] = 0;
    sliceIndex[1] = 0;
    sliceIndex[2] = frameNo;

    inputSize[2] = 1;

    sliceRegion.SetIndex(sliceIndex);
    sliceRegion.SetSize(inputSize);

    const unsigned frameSize = inputSize[0] * inputSize[1];

    Float32 *data = new Float32[frameSize];

    if (data == NULL) {
      return EC_MemoryExhausted;
    }

    itk::ImageRegionConstIteratorWithIndex<ImageType> sliceIterator(parametricMapImage, sliceRegion);

    unsigned framePixelCnt = 0;
    for(sliceIterator.GoToBegin();!sliceIterator.IsAtEnd(); ++sliceIterator, ++framePixelCnt){
      data[framePixelCnt] = sliceIterator.Get();
      ImageType::IndexType idx = sliceIterator.GetIndex();
//      cout << framePixelCnt << " " << idx[1] << "," << idx[0] << endl;
    }

    OFVector<FGBase*> groups;
    OFunique_ptr<FGPlanePosPatient> fgPlanePos(new FGPlanePosPatient);
    OFunique_ptr<FGFrameContent > fgFracon(new FGFrameContent);
    OFunique_ptr<FGRealWorldValueMapping> realWorldValueMappingFG(new FGRealWorldValueMapping());
    FGRealWorldValueMapping::RWVMItem* realWorldValueMappingItem = new FGRealWorldValueMapping::RWVMItem();
    if (!fgPlanePos  || !fgFracon || !realWorldValueMappingFG || !realWorldValueMappingItem )
    {
      delete[] data;
      return EC_MemoryExhausted;
    }

    realWorldValueMappingItem->setRealWorldValueSlope(atof(metaInfo.getRealWorldValueSlope().c_str()));
    realWorldValueMappingItem->setRealWorldValueIntercept(atof(metaInfo.getRealWorldValueIntercept().c_str()));

    realWorldValueMappingItem->setRealWorldValueFirstValueMappeSigned(metaInfo.getFirstValueMapped());
    realWorldValueMappingItem->setRealWorldValueLastValueMappedSigned(metaInfo.getLastValueMapped());

    CodeSequenceMacro* measurementUnitCode = metaInfo.getMeasurementUnitsCode();
    if (measurementUnitCode != NULL) {
      realWorldValueMappingItem->getMeasurementUnitsCode().set(metaInfo.getCodeSequenceValue(measurementUnitCode).c_str(),
																										metaInfo.getCodeSequenceDesignator(measurementUnitCode).c_str(),
																										metaInfo.getCodeSequenceMeaning(measurementUnitCode).c_str());
    }

    // TODO: LutExplanation and LUTLabel should be added as Metainformation
    realWorldValueMappingItem->setLUTExplanation("We are mapping trash to junk.");
    realWorldValueMappingItem->setLUTLabel("Just testing");
    ContentItemMacro* quantity = new ContentItemMacro;
    CodeSequenceMacro* qCodeName = new CodeSequenceMacro("G-C1C6", "SRT", "Quantity");
    CodeSequenceMacro* qSpec = new CodeSequenceMacro("110805", "SRT", "T2 Weighted MR Signal Intensity");

    if (!quantity || !qSpec || !qCodeName)
    {
      delete[] data;
      return EC_MemoryExhausted;
    }

    quantity->getEntireConceptNameCodeSequence().push_back(qCodeName);
    quantity->getEntireConceptCodeSequence().push_back(qSpec);
    realWorldValueMappingItem->getEntireQuantityDefinitionSequence().push_back(quantity);
    quantity->setValueType(ContentItemMacro::VT_CODE);
    realWorldValueMappingFG->getRealWorldValueMapping().push_back(realWorldValueMappingItem);

    // Plane Position
    OFStringStream ss;
    ss << frameNo;
    OFSTRINGSTREAM_GETOFSTRING(ss, framestr) // convert number to string
    fgPlanePos->setImagePositionPatient("0", "0", framestr);

    // Frame Content
    OFCondition result = fgFracon->setDimensionIndexValues(frameNo+1 /* value within dimension */, 0 /* first dimension */);

    // Add frame with related groups
    if (result.good())
    {
      groups.push_back(fgPlanePos.get());
      groups.push_back(fgFracon.get());
      groups.push_back(realWorldValueMappingFG.get());
      groups.push_back(fgPlanePos.get());
      result = map->addFrame(data, frameSize, groups);
    }
    delete[] data;
    return result;
  }
}

<commit_msg>ENH: using setter for setting DICOM values instead of using tags itself (issue #20)<commit_after>#include "ParaMapConverter.h"

using namespace std;

namespace dcmqi {

  int ParaMapConverter::itkimage2paramap(const string &inputFileName, const string &dicomImageFileName,
																				 const string &metaDataFileName, const string &outputFileName) {

    ReaderType::Pointer reader = ReaderType::New();
    reader->SetFileName(inputFileName.c_str());
    reader->Update();
    ImageType::Pointer parametricMapImage = reader->GetOutput();

    MinMaxCalculatorType::Pointer calculator = MinMaxCalculatorType::New();
    calculator->SetImage(parametricMapImage);
    calculator->Compute();

    JSONParametricMapMetaInformationHandler metaInfo(metaDataFileName);
    metaInfo.read();

    metaInfo.setFirstValueMapped(calculator->GetMinimum());
    metaInfo.setLastValueMapped(calculator->GetMaximum());

    IODEnhGeneralEquipmentModule::EquipmentInfo eq = getEnhEquipmentInfo();
    ContentIdentificationMacro contentID = createContentIdentificationInformation();
    CHECK_COND(contentID.setInstanceNumber(metaInfo.getInstanceNumber().c_str()));

    DcmDataset pMapDocDataset;
    DPMParametricMapFloat *pMapDoc = NULL;

    // TODO: following should maybe be moved to meta info
    OFString imageFlavor = "VOLUME";
    OFString pixContrast = "MTT";
    DPMTypes::ContentQualification contQual = DPMTypes::CQ_RESEARCH;
    OFString modality = "MR";

    ImageType::SizeType inputSize = parametricMapImage->GetBufferedRegion().GetSize();
    cout << "Input image size: " << inputSize << endl;

    CHECK_COND(DPMParametricMapFloat::create(pMapDoc, modality, metaInfo.getSeriesNumber().c_str(),
																						 metaInfo.getInstanceNumber().c_str(),
																						 inputSize[0], inputSize[1], eq, contentID,
																						 imageFlavor, pixContrast, contQual));

    if (!dicomImageFileName.empty())
      CHECK_COND(pMapDoc->import(dicomImageFileName.c_str(), OFTrue, OFTrue, OFFalse, OFTrue));

    /* Initialize dimension module */
    char dimUID[128];
    dcmGenerateUniqueIdentifier(dimUID, QIICR_UID_ROOT);
    IODMultiframeDimensionModule &mfdim = pMapDoc->getIODMultiframeDimensionModule();
    OFCondition result = mfdim.addDimensionIndex(DCM_ImagePositionPatient, dimUID,
																								 DCM_RealWorldValueMappingSequence, "Frame position");

    // Shared FGs: PixelMeasuresSequence
    {
      FGPixelMeasures *pixmsr = new FGPixelMeasures();

      ImageType::SpacingType labelSpacing = parametricMapImage->GetSpacing();
      ostringstream spacingSStream;
      spacingSStream << scientific << labelSpacing[0] << "\\" << labelSpacing[1];
      CHECK_COND(pixmsr->setPixelSpacing(spacingSStream.str().c_str()));

      spacingSStream.clear(); spacingSStream.str("");
      spacingSStream << scientific << labelSpacing[2];
      CHECK_COND(pixmsr->setSpacingBetweenSlices(spacingSStream.str().c_str()));
      CHECK_COND(pixmsr->setSliceThickness(spacingSStream.str().c_str()));
      CHECK_COND(pMapDoc->addForAllFrames(*pixmsr));
    }

    // Shared FGs: PlaneOrientationPatientSequence
    {
      OFString imageOrientationPatientStr;

      ImageType::DirectionType labelDirMatrix = parametricMapImage->GetDirection();

      cout << "Directions: " << labelDirMatrix << endl;

      FGPlaneOrientationPatient *planor =
          FGPlaneOrientationPatient::createMinimal(
              Helper::floatToStrScientific(labelDirMatrix[0][0]).c_str(),
              Helper::floatToStrScientific(labelDirMatrix[1][0]).c_str(),
              Helper::floatToStrScientific(labelDirMatrix[2][0]).c_str(),
              Helper::floatToStrScientific(labelDirMatrix[0][1]).c_str(),
              Helper::floatToStrScientific(labelDirMatrix[1][1]).c_str(),
              Helper::floatToStrScientific(labelDirMatrix[2][1]).c_str());

      //CHECK_COND(planor->setImageOrientationPatient(imageOrientationPatientStr));
      CHECK_COND(pMapDoc->addForAllFrames(*planor));
    }

    FGFrameAnatomy frameAnaFG;
    frameAnaFG.setLaterality(FGFrameAnatomy::LATERALITY_UNPAIRED);
    frameAnaFG.getAnatomy().getAnatomicRegion().set("T-A0100", "SRT", "Brain");
    CHECK_COND(pMapDoc->addForAllFrames(frameAnaFG));

    FGIdentityPixelValueTransformation idTransFG;
    // Rescale Intercept, Rescale Slope, Rescale Type are missing here
    CHECK_COND(pMapDoc->addForAllFrames(idTransFG));

    FGParametricMapFrameType frameTypeFG;
    frameTypeFG.setFrameType("DERIVED\\PRIMARY\\VOLUME\\MTT");
    CHECK_COND(pMapDoc->addForAllFrames(frameTypeFG));

    for (unsigned long f = 0; result.good() && (f < inputSize[2]); f++) {
      result = addFrame(pMapDoc, parametricMapImage, metaInfo, f);
    }

  {
    string bodyPartAssigned = metaInfo.getBodyPartExamined();
    if(!dicomImageFileName.empty() && bodyPartAssigned.empty()) {
      DcmFileFormat sliceFF;
      CHECK_COND(sliceFF.loadFile(dicomImageFileName.c_str()));
      OFString bodyPartStr;
      if(sliceFF.getDataset()->findAndGetOFString(DCM_BodyPartExamined, bodyPartStr).good()) {
        if (!bodyPartStr.empty())
          bodyPartAssigned = bodyPartStr.c_str();
      }
    }
    if(!bodyPartAssigned.empty())
      pMapDoc->getIODGeneralSeriesModule().setBodyPartExamined(bodyPartAssigned.c_str());
  }

  // SeriesDate/Time should be of when parametric map was taken; initialize to when it was saved
  {
    OFString contentDate, contentTime;
    DcmDate::getCurrentDate(contentDate);
    DcmTime::getCurrentTime(contentTime);

    pMapDoc->getSeries().setSeriesDate(contentDate.c_str());
    pMapDoc->getSeries().setSeriesTime(contentTime.c_str());
    pMapDoc->getGeneralImage().setContentDate(contentDate.c_str());
    pMapDoc->getGeneralImage().setContentTime(contentTime.c_str());
  }
  pMapDoc->getSeries().setSeriesDescription(metaInfo.getSeriesDescription().c_str());
  pMapDoc->getSeries().setSeriesNumber(metaInfo.getSeriesNumber().c_str());

  CHECK_COND(pMapDoc->writeDataset(pMapDocDataset));
  CHECK_COND(pMapDoc->saveFile(outputFileName.c_str()));

  COUT << "Saved parametric map as " << outputFileName << endl;
    return EXIT_SUCCESS;
  }

  int ParaMapConverter::paramap2itkimage(const string &inputParamapFileName, const string &outputDirName) {
    return EXIT_SUCCESS;
  }

  OFCondition ParaMapConverter::addFrame(DPMParametricMapFloat *map, const ImageType::Pointer &parametricMapImage,
																				 const JSONParametricMapMetaInformationHandler &metaInfo,
                                         const unsigned long frameNo)
  {
    ImageType::RegionType sliceRegion;
    ImageType::IndexType sliceIndex;
    ImageType::SizeType inputSize = parametricMapImage->GetBufferedRegion().GetSize();

    sliceIndex[0] = 0;
    sliceIndex[1] = 0;
    sliceIndex[2] = frameNo;

    inputSize[2] = 1;

    sliceRegion.SetIndex(sliceIndex);
    sliceRegion.SetSize(inputSize);

    const unsigned frameSize = inputSize[0] * inputSize[1];

    Float32 *data = new Float32[frameSize];

    if (data == NULL) {
      return EC_MemoryExhausted;
    }

    itk::ImageRegionConstIteratorWithIndex<ImageType> sliceIterator(parametricMapImage, sliceRegion);

    unsigned framePixelCnt = 0;
    for(sliceIterator.GoToBegin();!sliceIterator.IsAtEnd(); ++sliceIterator, ++framePixelCnt){
      data[framePixelCnt] = sliceIterator.Get();
      ImageType::IndexType idx = sliceIterator.GetIndex();
//      cout << framePixelCnt << " " << idx[1] << "," << idx[0] << endl;
    }

    OFVector<FGBase*> groups;
    OFunique_ptr<FGPlanePosPatient> fgPlanePos(new FGPlanePosPatient);
    OFunique_ptr<FGFrameContent > fgFracon(new FGFrameContent);
    OFunique_ptr<FGRealWorldValueMapping> realWorldValueMappingFG(new FGRealWorldValueMapping());
    FGRealWorldValueMapping::RWVMItem* realWorldValueMappingItem = new FGRealWorldValueMapping::RWVMItem();
    if (!fgPlanePos  || !fgFracon || !realWorldValueMappingFG || !realWorldValueMappingItem )
    {
      delete[] data;
      return EC_MemoryExhausted;
    }

    realWorldValueMappingItem->setRealWorldValueSlope(atof(metaInfo.getRealWorldValueSlope().c_str()));
    realWorldValueMappingItem->setRealWorldValueIntercept(atof(metaInfo.getRealWorldValueIntercept().c_str()));

    realWorldValueMappingItem->setRealWorldValueFirstValueMappeSigned(metaInfo.getFirstValueMapped());
    realWorldValueMappingItem->setRealWorldValueLastValueMappedSigned(metaInfo.getLastValueMapped());

    CodeSequenceMacro* measurementUnitCode = metaInfo.getMeasurementUnitsCode();
    if (measurementUnitCode != NULL) {
      realWorldValueMappingItem->getMeasurementUnitsCode().set(metaInfo.getCodeSequenceValue(measurementUnitCode).c_str(),
																										metaInfo.getCodeSequenceDesignator(measurementUnitCode).c_str(),
																										metaInfo.getCodeSequenceMeaning(measurementUnitCode).c_str());
    }

    // TODO: LutExplanation and LUTLabel should be added as Metainformation
    realWorldValueMappingItem->setLUTExplanation("We are mapping trash to junk.");
    realWorldValueMappingItem->setLUTLabel("Just testing");
    ContentItemMacro* quantity = new ContentItemMacro;
    CodeSequenceMacro* qCodeName = new CodeSequenceMacro("G-C1C6", "SRT", "Quantity");
    CodeSequenceMacro* qSpec = new CodeSequenceMacro("110805", "SRT", "T2 Weighted MR Signal Intensity");

    if (!quantity || !qSpec || !qCodeName)
    {
      delete[] data;
      return EC_MemoryExhausted;
    }

    quantity->getEntireConceptNameCodeSequence().push_back(qCodeName);
    quantity->getEntireConceptCodeSequence().push_back(qSpec);
    realWorldValueMappingItem->getEntireQuantityDefinitionSequence().push_back(quantity);
    quantity->setValueType(ContentItemMacro::VT_CODE);
    realWorldValueMappingFG->getRealWorldValueMapping().push_back(realWorldValueMappingItem);

    // Plane Position
    OFStringStream ss;
    ss << frameNo;
    OFSTRINGSTREAM_GETOFSTRING(ss, framestr) // convert number to string
    fgPlanePos->setImagePositionPatient("0", "0", framestr);

    // Frame Content
    OFCondition result = fgFracon->setDimensionIndexValues(frameNo+1 /* value within dimension */, 0 /* first dimension */);

    // Add frame with related groups
    if (result.good())
    {
      groups.push_back(fgPlanePos.get());
      groups.push_back(fgFracon.get());
      groups.push_back(realWorldValueMappingFG.get());
      groups.push_back(fgPlanePos.get());
      result = map->addFrame(data, frameSize, groups);
    }
    delete[] data;
    return result;
  }
}

<|endoftext|>