<commit_before>/*
 * opencog/atomspace/AtomSpace.cc
 *
 * Copyright (c) 2008-2010 OpenCog Foundation
 * Copyright (c) 2009, 2013 Linas Vepstas
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <string>
#include <iostream>
#include <fstream>
#include <list>

#include <stdlib.h>

#include <opencog/util/Logger.h>
#include <opencog/util/oc_assert.h>

#include <opencog/atoms/base/Link.h>
#include <opencog/atoms/base/Node.h>
#include <opencog/atoms/proto/types.h>

#include "AtomSpace.h"

//#define DPRINTF printf
#define DPRINTF(...)

using std::string;
using std::cerr;
using std::cout;
using std::endl;
using std::min;
using std::max;
using namespace opencog;

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

/**
 * Transient atomspaces skip some of the initialization steps,
 * so that they can be constructed more quickly.  Transient atomspaces
 * are typically used as scratch spaces, to hold temporary results
 * during evaluation, pattern matching and inference. Such temporary
 * spaces don't need some of the heavier-weight crud that atomspaces
 * are festooned with.
 */
AtomSpace::AtomSpace(AtomSpace* parent, bool transient) :
    _atom_table(parent? &parent->_atom_table : nullptr, this, transient),
    _backing_store(nullptr),
    _read_only(false)
{
}

AtomSpace::~AtomSpace()
{
}

void AtomSpace::ready_transient(AtomSpace* parent)
{
    _atom_table.ready_transient(parent? &parent->_atom_table : nullptr, this);
}

void AtomSpace::clear_transient()
{
    _atom_table.clear_transient();
}

// An extremely primitive permissions system.
void AtomSpace::set_read_only(void)
{
    _read_only = true;
}

void AtomSpace::set_read_write(void)
{
    _read_only = false;
}

bool AtomSpace::compare_atomspaces(const AtomSpace& space_first,
                                   const AtomSpace& space_second,
                                   bool check_truth_values,
                                   bool emit_diagnostics)
{
    // Compare sizes
    if (space_first.get_size() != space_second.get_size())
    {
        if (emit_diagnostics)
            std::cout << "compare_atomspaces - size " <<
                    space_first.get_size() << " != size " <<
                    space_second.get_size() << std::endl;
        return false;
    }

    // Compare node count
    if (space_first.get_num_nodes() != space_second.get_num_nodes())
    {
        if (emit_diagnostics)
            std::cout << "compare_atomspaces - node count " <<
                    space_first.get_num_nodes() << " != node count " <<
                    space_second.get_num_nodes() << std::endl;
        return false;
    }

    // Compare link count
    if (space_first.get_num_links() != space_second.get_num_links())
    {
        if (emit_diagnostics)
            std::cout << "compare_atomspaces - link count " <<
                    space_first.get_num_links() << " != link count " <<
                    space_second.get_num_links() << std::endl;
        return false;
    }

    // If we get this far, we need to compare each individual atom.

    // Get the atoms in each atomspace.
    HandleSeq atomsInFirstSpace, atomsInSecondSpace;
    space_first.get_all_atoms(atomsInFirstSpace);
    space_second.get_all_atoms(atomsInSecondSpace);

    // Uncheck each atom in the second atomspace.
    for (auto atom : atomsInSecondSpace)
        atom->setUnchecked();

    // Loop to see if each atom in the first has a match in the second.
    const AtomTable& table_second = space_second._atom_table;
    for (auto atom_first : atomsInFirstSpace)
    {
        Handle atom_second = table_second.getHandle(atom_first);

        if( false)
        {
        Handle atom_second;
        if (atom_first->is_node())
        {
            atom_second = table_second.getHandle(atom_first->get_type(),
                        atom_first->get_name());
        }
        else if (atom_first->is_link())
        {
            atom_second =  table_second.getHandle(atom_first->get_type(),
                        atom_first->getOutgoingSet());
        }
        else
        {
             throw opencog::RuntimeException(TRACE_INFO,
                 "AtomSpace::compare_atomspaces - atom not Node or Link");
        }
        }

        // If the atoms don't match because one of them is null.
        if ((atom_first and not atom_second) or
            (atom_second and not atom_first))
        {
            if (emit_diagnostics)
            {
                if (atom_first)
                    std::cout << "compare_atomspaces - first atom " <<
                            atom_first->to_string() << " != NULL " <<
                            std::endl;
                if (atom_second)
                    std::cout << "compare_atomspaces - first atom " <<
                            "NULL != second atom " <<
                            atom_second->to_string() << std::endl;
            }
            return false;
        }

        // If the atoms don't match... Compare the atoms not the pointers
        // which is the default if we just use Handle operator ==.
        if (*((AtomPtr) atom_first) != *((AtomPtr) atom_second))
        {
            if (emit_diagnostics)
                std::cout << "compare_atomspaces - first atom " <<
                        atom_first->to_string() << " != second atom " <<
                        atom_second->to_string() << std::endl;
            return false;
        }

        // Check the truth values...
        if (check_truth_values)
        {
            TruthValuePtr truth_first = atom_first->getTruthValue();
            TruthValuePtr truth_second = atom_second->getTruthValue();
            if (*truth_first != *truth_second)
            {
                if (emit_diagnostics)
                    std::cout << "compare_atomspaces - first truth " <<
                            atom_first->to_string() << " != second truth " <<
                            atom_second->to_string() << std::endl;
                return false;
            }
        }

        // Set the check for the second atom.
        atom_second->setChecked();
    }

    // Make sure each atom in the second atomspace has been checked.
    bool all_checked = true;
    for (auto atom : atomsInSecondSpace)
    {
        if (!atom->isChecked())
        {
            if (emit_diagnostics)
                std::cout << "compare_atomspaces - unchecked space atom " <<
                        atom->to_string() << std::endl;
            all_checked = false;
        }
    }
    if (!all_checked)
        return false;

    // If we get this far, then the spaces are equal.
    return true;
}

bool AtomSpace::operator==(const AtomSpace& other) const
{
    return compare_atomspaces(*this, other, CHECK_TRUTH_VALUES,
            DONT_EMIT_DIAGNOSTICS);
}

bool AtomSpace::operator!=(const AtomSpace& other) const
{
    return not operator==(other);
}

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

bool AtomSpace::isAttachedToBackingStore()
{
    if (nullptr != _backing_store) return true;
    return false;
}

void AtomSpace::registerBackingStore(BackingStore *bs)
{
    if (isAttachedToBackingStore())
        throw RuntimeException(TRACE_INFO,
            "AtomSpace is already connected to a BackingStore.");

    _backing_store = bs;
}

void AtomSpace::unregisterBackingStore(BackingStore *bs)
{
    if (not isAttachedToBackingStore())
        throw RuntimeException(TRACE_INFO,
            "AtomSpace is not connected to a BackingStore.");

    if (bs == _backing_store) _backing_store = nullptr;
}

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

Handle AtomSpace::add_atom(const Handle& h, bool async)
{
    // If it is a DeleteLink, then the addition will fail. Deal with it.
    Handle rh;
    try {
        rh = _atom_table.add(h, async);
    }
    catch (const DeleteException& ex) {
        // Atom deletion has not been implemented in the backing store
        // This is a major to-do item.
        if (_backing_store)
           _backing_store->removeAtom(h, false);
    }
    return rh;
}

Handle AtomSpace::add_node(Type t, const string& name,
                           bool async)
{
    return _atom_table.add(createNode(t, name), async);
}

Handle AtomSpace::get_node(Type t, const string& name)
{
    return _atom_table.getHandle(t, name);
}

Handle AtomSpace::add_link(Type t, const HandleSeq& outgoing, bool async)
{
    // If it is a DeleteLink, then the addition will fail. Deal with it.
    Handle rh;
    try {
        rh = _atom_table.add(createLink(outgoing, t), async);
    }
    catch (const DeleteException& ex) {
        if (_backing_store) {
           Handle h(createLink(outgoing, t));
           _backing_store->removeAtom(h, false);
        }
    }
    return rh;
}

Handle AtomSpace::get_link(Type t, const HandleSeq& outgoing)
{
    return _atom_table.getHandle(t, outgoing);
}

void AtomSpace::store_atom(const Handle& h)
{
    if (nullptr == _backing_store)
        throw RuntimeException(TRACE_INFO, "No backing store");

    _backing_store->storeAtom(h);
}

Handle AtomSpace::fetch_atom(const Handle& h)
{
    if (nullptr == _backing_store)
        throw RuntimeException(TRACE_INFO, "No backing store");
    if (nullptr == h) return Handle::UNDEFINED;

    // First, make sure the atom is actually in the atomspace.
    Handle hc(_atom_table.add(h, false));

    // Now, get the latest values from the backing store.
    // The operation here is to CLOBBER the values, NOT to merge them!
    // The goal of an explicit fetch is to explicitly fetch the values,
    // and not to play monkey-shines with them.  If you want something
    // else, then save the old TV, fetch the new TV, and combine them
    // with your favorite algo.
    Handle hv;
    if (h->is_node()) {
        hv = _backing_store->getNode(h->get_type(),
                                     h->get_name().c_str());
    }
    else if (h->is_link()) {
        hv = _backing_store->getLink(h->get_type(),
                                     h->getOutgoingSet());
    }

    // Hmm I don't quite get it ...  shouldn't hv and hc be the same
    // atom, by now? So the below should not be needed...!?
    if (hv and hv != hc)
    {
        hc->copyValues(hv);
        TruthValuePtr tv = hv->getTruthValue();
        hc->setTruthValue(tv);
    }

    return hc;
}

Handle AtomSpace::fetch_incoming_set(Handle h, bool recursive)
{
    if (nullptr == _backing_store)
        throw RuntimeException(TRACE_INFO, "No backing store");

    h = get_atom(h);
    if (nullptr == h) return h;

    // Get everything from the backing store.
    _backing_store->getIncomingSet(_atom_table, h);

    if (not recursive) return h;

    IncomingSet vh(h->getIncomingSet());
    for (const LinkPtr& lp : vh)
        fetch_incoming_set(Handle(lp), true);

    return h;
}

Handle AtomSpace::fetch_incoming_by_type(Handle h, Type t)
{
    if (nullptr == _backing_store)
        throw RuntimeException(TRACE_INFO, "No backing store");

    h = get_atom(h);
    if (nullptr == h) return h;

    // Get everything from the backing store.
    _backing_store->getIncomingByType(_atom_table, h, t);

    return h;
}

void AtomSpace::fetch_valuations(Handle key, bool get_all_values)
{
    if (nullptr == _backing_store)
        throw RuntimeException(TRACE_INFO, "No backing store");

    key = get_atom(key);
    if (nullptr == key) return;

    // Get everything from the backing store.
    _backing_store->getValuations(_atom_table, key, get_all_values);
}

bool AtomSpace::remove_atom(Handle h, bool recursive)
{
    if (_backing_store)
        _backing_store->removeAtom(h, recursive);
    return 0 < _atom_table.extract(h, recursive).size();
}

std::string AtomSpace::to_string() const
{
	std::stringstream ss;
	ss << *this;
	return ss.str();
}

namespace std {

ostream& operator<<(ostream& out, const opencog::AtomSpace& as) {
    list<opencog::Handle> results;
    as.get_handles_by_type(back_inserter(results), opencog::ATOM, true);
    for (const opencog::Handle& h : results)
	    if (h->getIncomingSetSize() == 0)
		    out << h->to_string() << endl;
    return out;
}

} // namespace std
<commit_msg>Start implementing the read-only constraint.<commit_after>/*
 * opencog/atomspace/AtomSpace.cc
 *
 * Copyright (c) 2008-2010 OpenCog Foundation
 * Copyright (c) 2009, 2013 Linas Vepstas
 * All Rights Reserved
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License v3 as
 * published by the Free Software Foundation and including the exceptions
 * at http://opencog.org/wiki/Licenses
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public License
 * along with this program; if not, write to:
 * Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */

#include <string>
#include <iostream>
#include <fstream>
#include <list>

#include <stdlib.h>

#include <opencog/util/Logger.h>
#include <opencog/util/oc_assert.h>

#include <opencog/atoms/base/Link.h>
#include <opencog/atoms/base/Node.h>
#include <opencog/atoms/proto/types.h>

#include "AtomSpace.h"

//#define DPRINTF printf
#define DPRINTF(...)

using std::string;
using std::cerr;
using std::cout;
using std::endl;
using std::min;
using std::max;
using namespace opencog;

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

/**
 * Transient atomspaces skip some of the initialization steps,
 * so that they can be constructed more quickly.  Transient atomspaces
 * are typically used as scratch spaces, to hold temporary results
 * during evaluation, pattern matching and inference. Such temporary
 * spaces don't need some of the heavier-weight crud that atomspaces
 * are festooned with.
 */
AtomSpace::AtomSpace(AtomSpace* parent, bool transient) :
    _atom_table(parent? &parent->_atom_table : nullptr, this, transient),
    _backing_store(nullptr),
    _read_only(false)
{
}

AtomSpace::~AtomSpace()
{
}

void AtomSpace::ready_transient(AtomSpace* parent)
{
    _atom_table.ready_transient(parent? &parent->_atom_table : nullptr, this);
}

void AtomSpace::clear_transient()
{
    _atom_table.clear_transient();
}

// An extremely primitive permissions system.
void AtomSpace::set_read_only(void)
{
    _read_only = true;
}

void AtomSpace::set_read_write(void)
{
    _read_only = false;
}

bool AtomSpace::compare_atomspaces(const AtomSpace& space_first,
                                   const AtomSpace& space_second,
                                   bool check_truth_values,
                                   bool emit_diagnostics)
{
    // Compare sizes
    if (space_first.get_size() != space_second.get_size())
    {
        if (emit_diagnostics)
            std::cout << "compare_atomspaces - size " <<
                    space_first.get_size() << " != size " <<
                    space_second.get_size() << std::endl;
        return false;
    }

    // Compare node count
    if (space_first.get_num_nodes() != space_second.get_num_nodes())
    {
        if (emit_diagnostics)
            std::cout << "compare_atomspaces - node count " <<
                    space_first.get_num_nodes() << " != node count " <<
                    space_second.get_num_nodes() << std::endl;
        return false;
    }

    // Compare link count
    if (space_first.get_num_links() != space_second.get_num_links())
    {
        if (emit_diagnostics)
            std::cout << "compare_atomspaces - link count " <<
                    space_first.get_num_links() << " != link count " <<
                    space_second.get_num_links() << std::endl;
        return false;
    }

    // If we get this far, we need to compare each individual atom.

    // Get the atoms in each atomspace.
    HandleSeq atomsInFirstSpace, atomsInSecondSpace;
    space_first.get_all_atoms(atomsInFirstSpace);
    space_second.get_all_atoms(atomsInSecondSpace);

    // Uncheck each atom in the second atomspace.
    for (auto atom : atomsInSecondSpace)
        atom->setUnchecked();

    // Loop to see if each atom in the first has a match in the second.
    const AtomTable& table_second = space_second._atom_table;
    for (auto atom_first : atomsInFirstSpace)
    {
        Handle atom_second = table_second.getHandle(atom_first);

        if( false)
        {
        Handle atom_second;
        if (atom_first->is_node())
        {
            atom_second = table_second.getHandle(atom_first->get_type(),
                        atom_first->get_name());
        }
        else if (atom_first->is_link())
        {
            atom_second =  table_second.getHandle(atom_first->get_type(),
                        atom_first->getOutgoingSet());
        }
        else
        {
             throw opencog::RuntimeException(TRACE_INFO,
                 "AtomSpace::compare_atomspaces - atom not Node or Link");
        }
        }

        // If the atoms don't match because one of them is null.
        if ((atom_first and not atom_second) or
            (atom_second and not atom_first))
        {
            if (emit_diagnostics)
            {
                if (atom_first)
                    std::cout << "compare_atomspaces - first atom " <<
                            atom_first->to_string() << " != NULL " <<
                            std::endl;
                if (atom_second)
                    std::cout << "compare_atomspaces - first atom " <<
                            "NULL != second atom " <<
                            atom_second->to_string() << std::endl;
            }
            return false;
        }

        // If the atoms don't match... Compare the atoms not the pointers
        // which is the default if we just use Handle operator ==.
        if (*((AtomPtr) atom_first) != *((AtomPtr) atom_second))
        {
            if (emit_diagnostics)
                std::cout << "compare_atomspaces - first atom " <<
                        atom_first->to_string() << " != second atom " <<
                        atom_second->to_string() << std::endl;
            return false;
        }

        // Check the truth values...
        if (check_truth_values)
        {
            TruthValuePtr truth_first = atom_first->getTruthValue();
            TruthValuePtr truth_second = atom_second->getTruthValue();
            if (*truth_first != *truth_second)
            {
                if (emit_diagnostics)
                    std::cout << "compare_atomspaces - first truth " <<
                            atom_first->to_string() << " != second truth " <<
                            atom_second->to_string() << std::endl;
                return false;
            }
        }

        // Set the check for the second atom.
        atom_second->setChecked();
    }

    // Make sure each atom in the second atomspace has been checked.
    bool all_checked = true;
    for (auto atom : atomsInSecondSpace)
    {
        if (!atom->isChecked())
        {
            if (emit_diagnostics)
                std::cout << "compare_atomspaces - unchecked space atom " <<
                        atom->to_string() << std::endl;
            all_checked = false;
        }
    }
    if (!all_checked)
        return false;

    // If we get this far, then the spaces are equal.
    return true;
}

bool AtomSpace::operator==(const AtomSpace& other) const
{
    return compare_atomspaces(*this, other, CHECK_TRUTH_VALUES,
            DONT_EMIT_DIAGNOSTICS);
}

bool AtomSpace::operator!=(const AtomSpace& other) const
{
    return not operator==(other);
}

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

bool AtomSpace::isAttachedToBackingStore()
{
    if (nullptr != _backing_store) return true;
    return false;
}

void AtomSpace::registerBackingStore(BackingStore *bs)
{
    if (isAttachedToBackingStore())
        throw RuntimeException(TRACE_INFO,
            "AtomSpace is already connected to a BackingStore.");

    _backing_store = bs;
}

void AtomSpace::unregisterBackingStore(BackingStore *bs)
{
    if (not isAttachedToBackingStore())
        throw RuntimeException(TRACE_INFO,
            "AtomSpace is not connected to a BackingStore.");

    if (bs == _backing_store) _backing_store = nullptr;
}

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

Handle AtomSpace::add_atom(const Handle& h, bool async)
{
    // Cannot add atoms to a read-only atomspce. But if it's already
    // in the atomspace, return it.
    if (_read_only) return _atom_table.getHandle(h);

    // If it is a DeleteLink, then the addition will fail. Deal with it.
    Handle rh;
    try {
        rh = _atom_table.add(h, async);
    }
    catch (const DeleteException& ex) {
        // Atom deletion has not been implemented in the backing store
        // This is a major to-do item.
        if (_backing_store)
           _backing_store->removeAtom(h, false);
    }
    return rh;
}

Handle AtomSpace::add_node(Type t, const string& name,
                           bool async)
{
    return _atom_table.add(createNode(t, name), async);
}

Handle AtomSpace::get_node(Type t, const string& name)
{
    return _atom_table.getHandle(t, name);
}

Handle AtomSpace::add_link(Type t, const HandleSeq& outgoing, bool async)
{
    // Cannot add atoms to a read-only atomspce. But if it's already
    // in the atomspace, return it.
    if (_read_only) return _atom_table.getHandle(t, outgoing);

    // If it is a DeleteLink, then the addition will fail. Deal with it.
    Handle rh;
    try {
        rh = _atom_table.add(createLink(outgoing, t), async);
    }
    catch (const DeleteException& ex) {
        if (_backing_store) {
           Handle h(createLink(outgoing, t));
           _backing_store->removeAtom(h, false);
        }
    }
    return rh;
}

Handle AtomSpace::get_link(Type t, const HandleSeq& outgoing)
{
    return _atom_table.getHandle(t, outgoing);
}

void AtomSpace::store_atom(const Handle& h)
{
    if (nullptr == _backing_store)
        throw RuntimeException(TRACE_INFO, "No backing store");

    if (_read_only)
        throw RuntimeException(TRACE_INFO, "Read-only AtomSpace!");

    _backing_store->storeAtom(h);
}

Handle AtomSpace::fetch_atom(const Handle& h)
{
    if (nullptr == _backing_store)
        throw RuntimeException(TRACE_INFO, "No backing store");
    if (nullptr == h) return Handle::UNDEFINED;

    // Now, get the latest values from the backing store.
    // The operation here is to CLOBBER the values, NOT to merge them!
    // The goal of an explicit fetch is to explicitly fetch the values,
    // and not to play monkey-shines with them.  If you want something
    // else, then save the old TV, fetch the new TV, and combine them
    // with your favorite algo.
    Handle hv;
    if (h->is_node()) {
        hv = _backing_store->getNode(h->get_type(),
                                     h->get_name().c_str());
    }
    else if (h->is_link()) {
        hv = _backing_store->getLink(h->get_type(),
                                     h->getOutgoingSet());
    }

    // If we found it, add it to the atomspace -- even when the
    // atomspace is marked read-only; the atomspace is acting as
    // a cache for the backingstore.
    if (hv) return _atom_table.add(hv, false);

    // If it is not found, then it cannot be added.
    if (_read_only) return Handle::UNDEFINED;

    return _atom_table.add(h, false);
}

Handle AtomSpace::fetch_incoming_set(Handle h, bool recursive)
{
    if (nullptr == _backing_store)
        throw RuntimeException(TRACE_INFO, "No backing store");

    h = get_atom(h);
    if (nullptr == h) return h;

    // Get everything from the backing store.
    _backing_store->getIncomingSet(_atom_table, h);

    if (not recursive) return h;

    IncomingSet vh(h->getIncomingSet());
    for (const LinkPtr& lp : vh)
        fetch_incoming_set(Handle(lp), true);

    return h;
}

Handle AtomSpace::fetch_incoming_by_type(Handle h, Type t)
{
    if (nullptr == _backing_store)
        throw RuntimeException(TRACE_INFO, "No backing store");

    h = get_atom(h);
    if (nullptr == h) return h;

    // Get everything from the backing store.
    _backing_store->getIncomingByType(_atom_table, h, t);

    return h;
}

void AtomSpace::fetch_valuations(Handle key, bool get_all_values)
{
    if (nullptr == _backing_store)
        throw RuntimeException(TRACE_INFO, "No backing store");

    key = get_atom(key);
    if (nullptr == key) return;

    // Get everything from the backing store.
    _backing_store->getValuations(_atom_table, key, get_all_values);
}

bool AtomSpace::remove_atom(Handle h, bool recursive)
{
    if (_backing_store)
        _backing_store->removeAtom(h, recursive);
    return 0 < _atom_table.extract(h, recursive).size();
}

std::string AtomSpace::to_string() const
{
	std::stringstream ss;
	ss << *this;
	return ss.str();
}

namespace std {

ostream& operator<<(ostream& out, const opencog::AtomSpace& as) {
    list<opencog::Handle> results;
    as.get_handles_by_type(back_inserter(results), opencog::ATOM, true);
    for (const opencog::Handle& h : results)
	    if (h->getIncomingSetSize() == 0)
		    out << h->to_string() << endl;
    return out;
}

} // namespace std
<|endoftext|>


<commit_before>// @(#)root/base:$Name:  $:$Id: TBuffer3D.cxx,v 1.00
// Author: Olivier Couet   05/05/04

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

#include "TBuffer3D.h"
#include "TVirtualPad.h"
#include "TVirtualViewer3D.h"
#include "TView.h"

ClassImp(TBuffer3D)

//______________________________________________________________________________
TBuffer3D::TBuffer3D()
{
   fTransparency = 0;
   fType         = -1;
   fOption       = kPAD;
   fId           = 0;
   fNbPnts       = 0;
   fNbSegs       = 0;
   fNbPols       = 0;
   fPnts         = 0;
   fSegs         = 0;
   fPols         = 0;
   fPntsSize     = 0;
   fSegsSize     = 0;
   fPolsSize     = 0;
   fColor        = 0;
}

//______________________________________________________________________________
TBuffer3D::TBuffer3D(Int_t n1, Int_t n2, Int_t n3)
{
   fTransparency = 0;
   fPntsSize     = n1;
   fSegsSize     = n2;
   fPolsSize     = n3;

   fType         = -1;
   fOption       = kPAD;
   fId           = 0;

   fNbPnts       = 0;
   fNbSegs       = 0;
   fNbPols       = 0;

   fPnts         = 0;
   fSegs         = 0;
   fPols         = 0;
   fColor        = 0;
   if ( fPntsSize>0 ) fPnts = new Double_t[fPntsSize];
   if ( fSegsSize>0 ) fSegs = new Int_t[fSegsSize];
   if ( fPolsSize>0 ) fPols = new Int_t[fPolsSize];
}

//______________________________________________________________________________
TBuffer3D::~TBuffer3D()
{
   if (fPnts) delete [] fPnts;
   if (fSegs) delete [] fSegs;
   if (fPols) delete [] fPols;
}

//______________________________________________________________________________
void TBuffer3D::Paint(Option_t *option)
{
   Int_t i, i0, i1, i2;
   Double_t x0, y0, z0, x1, y1, z1;
   TVirtualViewer3D *viewer3D;
   TView *view;

   // Compute the shape range and update gPad->fView
   switch (fOption) {
      case kRANGE:
         x0 = x1 = fPnts[0];
         y0 = y1 = fPnts[1];
         z0 = z1 = fPnts[2];
         for (i=1; i<fNbPnts; i++) {
         i0 = 3*i; i1 = i0+1; i2 = i0+2;
            x0 = fPnts[i0] < x0 ? fPnts[i0] : x0;
            y0 = fPnts[i1] < y0 ? fPnts[i1] : y0;
            z0 = fPnts[i2] < z0 ? fPnts[i2] : z0;
            x1 = fPnts[i0] > x1 ? fPnts[i0] : x1;
            y1 = fPnts[i1] > y1 ? fPnts[i1] : y1;
            z1 = fPnts[i2] > z1 ? fPnts[i2] : z1;
         }
         view = gPad->GetView();
         if (view->GetAutoRange()) view->SetRange(x0,y0,z0,x1,y1,z1,2);
         break;

      // Update viewer
      case kSIZE:
      case kX3D:
      case kOGL:
         viewer3D = gPad->GetViewer3D();
         if (viewer3D) viewer3D->UpdateScene(option);
         break;

      // Paint this in gPad
      case kPAD:
      default:
         if (option && strlen(option) > 0) {
            if (strcmp(option,"SAME") && strcmp(option,"same")) return;
         }
         if (fTransparency > 50) return;  //do not show semi transparent objects
         if ( fType==kMARKER ) {
            view = gPad->GetView();
            Double_t pndc[3], temp[3];
            for (i=0; i<fNbPnts; i++) {
               for ( i0=0; i0<3; i0++ ) temp[i0] = fPnts[3*i+i0];
               view->WCtoNDC(temp, pndc);
               gPad->PaintPolyMarker(1, &pndc[0], &pndc[1]);
            }
         } else {
            for (i=0; i<fNbSegs; i++) {
               i0 = 3*fSegs[3*i+1];
               Double_t *ptpoints_0 = &(fPnts[i0]);
               i0 = 3*fSegs[3*i+2];
               Double_t *ptpoints_3 = &(fPnts[i0]);
               gPad->PaintLine3D(ptpoints_0, ptpoints_3);
            }
         }
         break;
   }
}

//______________________________________________________________________________
void TBuffer3D::ReAllocate(Int_t n1, Int_t n2, Int_t n3)
{
   if (n1 > fPntsSize) {
      delete [] fPnts;
      fPntsSize = n1;
      fPnts     = new Double_t[fPntsSize];
   }
   if (n2 > fSegsSize) {
      delete [] fSegs;
      fSegsSize = n2;
      fSegs     = new Int_t[fSegsSize];
   }
   if (n3 > fPolsSize) {
      delete [] fPols;
      fPolsSize = n3;
      fPols     = new Int_t[fPolsSize];
   }
}
<commit_msg>From Olivier: - revision 1.5 had a bad side effect: it was not anymore possible to   visualize the 3D histograms as box plots. This fix preserve what was   aimed in rev1.5 (not drawing in the pad when the OpenGL viewer is   active), and allow to see 3D histograms with the "box" option.<commit_after>// @(#)root/base:$Name:  $:$Id: TBuffer3D.cxx,v 1.00
// Author: Olivier Couet   05/05/04

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

#include "TBuffer3D.h"
#include "TVirtualPad.h"
#include "TVirtualViewer3D.h"
#include "TView.h"

ClassImp(TBuffer3D)

//______________________________________________________________________________
TBuffer3D::TBuffer3D()
{
   fTransparency = 0;
   fType         = -1;
   fOption       = kPAD;
   fId           = 0;
   fNbPnts       = 0;
   fNbSegs       = 0;
   fNbPols       = 0;
   fPnts         = 0;
   fSegs         = 0;
   fPols         = 0;
   fPntsSize     = 0;
   fSegsSize     = 0;
   fPolsSize     = 0;
   fColor        = 0;
}

//______________________________________________________________________________
TBuffer3D::TBuffer3D(Int_t n1, Int_t n2, Int_t n3)
{
   fTransparency = 0;
   fPntsSize     = n1;
   fSegsSize     = n2;
   fPolsSize     = n3;

   fType         = -1;
   fOption       = kPAD;
   fId           = 0;

   fNbPnts       = 0;
   fNbSegs       = 0;
   fNbPols       = 0;

   fPnts         = 0;
   fSegs         = 0;
   fPols         = 0;
   fColor        = 0;
   if ( fPntsSize>0 ) fPnts = new Double_t[fPntsSize];
   if ( fSegsSize>0 ) fSegs = new Int_t[fSegsSize];
   if ( fPolsSize>0 ) fPols = new Int_t[fPolsSize];
}

//______________________________________________________________________________
TBuffer3D::~TBuffer3D()
{
   if (fPnts) delete [] fPnts;
   if (fSegs) delete [] fSegs;
   if (fPols) delete [] fPols;
}

//______________________________________________________________________________
void TBuffer3D::Paint(Option_t *option)
{
   Int_t i, i0, i1, i2;
   Double_t x0, y0, z0, x1, y1, z1;
   TVirtualViewer3D *viewer3D;
   TView *view;

   // Compute the shape range and update gPad->fView
   switch (fOption) {
      case kRANGE:
         x0 = x1 = fPnts[0];
         y0 = y1 = fPnts[1];
         z0 = z1 = fPnts[2];
         for (i=1; i<fNbPnts; i++) {
         i0 = 3*i; i1 = i0+1; i2 = i0+2;
            x0 = fPnts[i0] < x0 ? fPnts[i0] : x0;
            y0 = fPnts[i1] < y0 ? fPnts[i1] : y0;
            z0 = fPnts[i2] < z0 ? fPnts[i2] : z0;
            x1 = fPnts[i0] > x1 ? fPnts[i0] : x1;
            y1 = fPnts[i1] > y1 ? fPnts[i1] : y1;
            z1 = fPnts[i2] > z1 ? fPnts[i2] : z1;
         }
         view = gPad->GetView();
         if (view->GetAutoRange()) view->SetRange(x0,y0,z0,x1,y1,z1,2);
         break;

      // Update viewer
      case kSIZE:
      case kX3D:
      case kOGL:
         viewer3D = gPad->GetViewer3D();
         if (viewer3D) viewer3D->UpdateScene(option);
         break;

      // Paint this in gPad
      case kPAD:
      default:
         if (option && !strcmp(option, "ogl")) return; // In case of OpenGL, the pad is not redrawn
         if (fTransparency > 50) return;  //do not show semi transparent objects
         if ( fType==kMARKER ) {
            view = gPad->GetView();
            Double_t pndc[3], temp[3];
            for (i=0; i<fNbPnts; i++) {
               for ( i0=0; i0<3; i0++ ) temp[i0] = fPnts[3*i+i0];
               view->WCtoNDC(temp, pndc);
               gPad->PaintPolyMarker(1, &pndc[0], &pndc[1]);
            }
         } else {
            for (i=0; i<fNbSegs; i++) {
               i0 = 3*fSegs[3*i+1];
               Double_t *ptpoints_0 = &(fPnts[i0]);
               i0 = 3*fSegs[3*i+2];
               Double_t *ptpoints_3 = &(fPnts[i0]);
               gPad->PaintLine3D(ptpoints_0, ptpoints_3);
            }
         }
         break;
   }
}

//______________________________________________________________________________
void TBuffer3D::ReAllocate(Int_t n1, Int_t n2, Int_t n3)
{
   if (n1 > fPntsSize) {
      delete [] fPnts;
      fPntsSize = n1;
      fPnts     = new Double_t[fPntsSize];
   }
   if (n2 > fSegsSize) {
      delete [] fSegs;
      fSegsSize = n2;
      fSegs     = new Int_t[fSegsSize];
   }
   if (n3 > fPolsSize) {
      delete [] fPols;
      fPolsSize = n3;
      fPols     = new Int_t[fPolsSize];
   }
}
<|endoftext|>


<commit_before>#include "AliITSPreprocessorSSD.h"

#include "AliCDBMetaData.h"
#include "AliLog.h"
#include "TFile.h"

#include <TTimeStamp.h>
#include <TObjString.h>

#include "AliITSRawStreamSSD.h"
#include "AliITSNoiseSSD.h"
#include "AliITSPedestalSSD.h"
#include "AliITSBadChannelsSSD.h"
#include <Riostream.h>

//
// Author: Enrico Fragiacomo
// Date: 13/10/2006
//
// SHUTTLE preprocessing class for SSD calibration files

/* $Id$ */

const Int_t AliITSPreprocessorSSD::fgkNumberOfSSD = 1698;

ClassImp(AliITSPreprocessorSSD)

//-----------------------------------------------------------------------
AliITSPreprocessorSSD::AliITSPreprocessorSSD(AliShuttleInterface* shuttle) :
  AliPreprocessor("SSD", shuttle)
{
  // constructor

  AddRunType("ELECTRONICS_CALIBRATION_RUN");
  AddRunType("PEDESTAL");
  AddRunType("PHYSICS");

}

///______________________________________________________________________________________________
void AliITSPreprocessorSSD::Initialize(Int_t run, UInt_t startTime,
	UInt_t endTime)
{

  AliPreprocessor::Initialize(run, startTime, endTime);

  Log(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", run,
	       TTimeStamp(startTime).AsString(),
	       TTimeStamp(endTime).AsString()));

}

//______________________________________________________________________________________________
UInt_t AliITSPreprocessorSSD::Process(TMap* /*dcsAliasMap*/)
{

  // Note. To be modified: dcsAliasMap is not needed but I can not get rid
  // of it unless the base class AliPreprocessor is modified accordingly.

  TObjArray calib_array(fgkNumberOfSSD);
  TObjArray badch_array(fgkNumberOfSSD);
  TObjArray ped_array(fgkNumberOfSSD);
  //Float_t noise=0, gain=0;

  TString runType = GetRunType();
  if(runType == "ELECTRONICS_CALIBRATION_RUN") {

  }
  else if(runType == "PEDESTAL") {

    TList* list = GetFileSources(kDAQ, "CALIBRATION");
    if (list && list->GetEntries() > 0)
      {
	Log("The following sources produced files with the id CALIBRATION");
	list->Print();

	// create iterator over list of LDCs (provides list of TObjString)
	TIter next(list);
	TObjString *ok;

	//---------------------------------------
	// in case some module was not calibrated!
	for(Int_t i=0; i<fgkNumberOfSSD; i++) {
	  AliITSNoiseSSD *calib = new AliITSNoiseSSD();
	  calib->SetMod((UShort_t) i+500);
	  calib->SetNNoiseP(768);
	  calib->SetNNoiseN(768);
	  // take a reasonable averaged value for the noise on P- and N-side strips
	  for(Int_t j=0; j<768; j++) {
	    calib->AddNoiseP(j,1000.);
	    calib->AddNoiseN(j,1000.);
	  }
	  calib_array.AddAt(calib,i);
	}
	//-----------------------------------------
	//---------------------------------------
	// in case some module was not calibrated!
	for(Int_t i=0; i<fgkNumberOfSSD; i++) {
	  AliITSBadChannelsSSD *badch = new AliITSBadChannelsSSD();
	  badch->SetMod((UShort_t) i+500);
	  badch_array.AddAt(badch,i);
	}
	//-----------------------------------------

	//---------------------------------------
	// in case some module was not calibrated!
	for(Int_t i=0; i<fgkNumberOfSSD; i++) {
	  AliITSPedestalSSD *pedel = new AliITSPedestalSSD();
	  pedel->SetMod((UShort_t) i+500);
	  pedel->SetNPedestalP(768);
	  pedel->SetNPedestalN(768);
	  for(Int_t j=0; j<768; j++) {
	    pedel->AddPedestalP(j,0.);
	    pedel->AddPedestalN(j,0.);
	  }
	  ped_array.AddAt(pedel,i);
	}
	//-----------------------------------------

	// expect to iterate 3 times (LDC0, LDC1, LDC2)
	while ( (ok = (TObjString*) next()) ) {

	  TString key = ok->String();

	  TString fileName = GetFile(kDAQ, "CALIBRATION", key.Data());
	  if (fileName.Length() > 0) {

	    Log(Form("Got the file %s, now we can extract some values.", fileName.Data()));

	    TFile *f = new TFile(fileName.Data());
	    if(!f || !f->IsOpen()){
	    	Log("Error opening file!");
		delete list;
		return 2;
	    }

	    TObjArray *cal;
	    f->GetObject("Noise;1", cal);
	    if(!cal) {
	    	Log("File does not contain expected data for the noise!");
		delete list;
		return 3;
	    }

	    Int_t nmod = cal->GetEntries();
	    Log(Form("\n#Mod %d", nmod ));
	    for(Int_t mod=0; mod<nmod; mod++) {
	      AliITSNoiseSSD *calib = (AliITSNoiseSSD*) cal->At(mod);
	      Log(Form("\nModId %d", calib->GetMod() ));
	      if((calib->GetMod()<500)||(calib->GetMod()>2198)) continue;
	      calib_array.AddAt(calib,calib->GetMod()-500);
	    }

	    TObjArray *bad;
	    f->GetObject("BadChannels;1", bad);
	    if(!bad) {
	    	Log("File does not contain expected data for bad channels  !");
		delete list;
		return 4;
	    }
	    nmod = bad->GetEntries();
	    for(Int_t mod=0; mod<nmod; mod++) {
	      AliITSBadChannelsSSD *badch = (AliITSBadChannelsSSD*) bad->At(mod);
	      if((badch->GetMod()<500)||(badch->GetMod()>2198)) continue;
	      badch_array.AddAt(badch,badch->GetMod()-500);
	    }

	    TObjArray *ped;
	    f->GetObject("Pedestal;1", ped);
	    if(!ped) {
	    	Log("File does not contain expected data for the pedestals!");
		delete list;
		return 5;
	    }
	    nmod = ped->GetEntries();
	    for(Int_t mod=0; mod<nmod; mod++) {
	      AliITSPedestalSSD *pedel = (AliITSPedestalSSD*) ped->At(mod);
	      if((pedel->GetMod()<500)||(pedel->GetMod()>2198)) continue;
	      ped_array.AddAt(pedel,pedel->GetMod()-500);
	    }

	    f->Close(); delete f;

	  } else {
	  	Log("GetFile error!");
		delete list;
		return 6;
	  } // if filename
	} // end iteration over LDCs

	delete list;
      } else {
      	  Log("GetFileSources error!");
	  if(list) delete list;
	  return 7;
      } // if list

      //Now we have to store the final CDB file
      AliCDBMetaData metaData;
      metaData.SetBeamPeriod(0);
      metaData.SetResponsible("Enrico Fragiacomo");
      metaData.SetComment("Fills noise, pedestal and bad channels TObjArray");

      if(!Store("Calib", "NoiseSSD", &calib_array, &metaData, 0, 1)) {
	Log("no store");
        return 1;
      }

      if(!Store("Calib", "BadChannelsSSD", &badch_array, &metaData, 0, 1)) {
	Log("no store");
        return 1;
      }

      if(!StoreReferenceData("Calib","PedestalSSD", &ped_array, &metaData)) {
	Log("no store");
	return 1;
      }

  } // end if pedestal run
  else {
    Log("Nothing to do");
    return 0;
  }

  Log("Database updated");
  return 0; // 0 means success

}

<commit_msg>new implementation of bad channel map (E. Fragiacomo)<commit_after>#include "AliITSPreprocessorSSD.h"

#include "AliCDBMetaData.h"
#include "AliLog.h"
#include "TFile.h"

#include <TTimeStamp.h>
#include <TObjString.h>

#include "AliITSRawStreamSSD.h"
#include "AliITSNoiseSSD.h"
#include "AliITSPedestalSSD.h"
#include "AliITSBadChannelsSSD.h"
#include <Riostream.h>

//
// Author: Enrico Fragiacomo
// Date: 13/10/2006
//
// SHUTTLE preprocessing class for SSD calibration files

/* $Id$ */

const Int_t AliITSPreprocessorSSD::fgkNumberOfSSD = 1698;

ClassImp(AliITSPreprocessorSSD)

//-----------------------------------------------------------------------
AliITSPreprocessorSSD::AliITSPreprocessorSSD(AliShuttleInterface* shuttle) :
  AliPreprocessor("SSD", shuttle)
{
  // constructor

  AddRunType("ELECTRONICS_CALIBRATION_RUN");
  AddRunType("PEDESTAL");
  AddRunType("PHYSICS");

}

///______________________________________________________________________________________________
void AliITSPreprocessorSSD::Initialize(Int_t run, UInt_t startTime,
	UInt_t endTime)
{

  AliPreprocessor::Initialize(run, startTime, endTime);

  Log(Form("\n\tRun %d \n\tStartTime %s \n\tEndTime %s", run,
	       TTimeStamp(startTime).AsString(),
	       TTimeStamp(endTime).AsString()));

}

//______________________________________________________________________________________________
UInt_t AliITSPreprocessorSSD::Process(TMap* /*dcsAliasMap*/)
{

  // Note. To be modified: dcsAliasMap is not needed but I can not get rid
  // of it unless the base class AliPreprocessor is modified accordingly.

  TObjArray calib_array(fgkNumberOfSSD);
  TObjArray badch_array(fgkNumberOfSSD);
  TObjArray ped_array(fgkNumberOfSSD);
  //Float_t noise=0, gain=0;

  TString runType = GetRunType();
  if(runType == "ELECTRONICS_CALIBRATION_RUN") {

  }
  else if(runType == "PEDESTAL") {

    TList* list = GetFileSources(kDAQ, "CALIBRATION");
    if (list && list->GetEntries() > 0)
      {
	Log("The following sources produced files with the id CALIBRATION");
	list->Print();

	// create iterator over list of LDCs (provides list of TObjString)
	TIter next(list);
	TObjString *ok;

	//---------------------------------------
	// in case some module was not calibrated!
	for(Int_t i=0; i<fgkNumberOfSSD; i++) {
	  AliITSNoiseSSD *calib = new AliITSNoiseSSD();
	  calib->SetMod((UShort_t) i+500);
	  calib->SetNNoiseP(768);
	  calib->SetNNoiseN(768);
	  // take a reasonable averaged value for the noise on P- and N-side strips
	  for(Int_t j=0; j<768; j++) {
	    calib->AddNoiseP(j,1000.);
	    calib->AddNoiseN(j,1000.);
	  }
	  calib_array.AddAt(calib,i);
	}
	//-----------------------------------------
	//---------------------------------------
	// in case some module was not calibrated!
	for(Int_t i=0; i<fgkNumberOfSSD; i++) {
	  AliITSBadChannelsSSD *badch = new AliITSBadChannelsSSD();
	  badch->SetMod((UShort_t) i+500);
	  badch->SetNBadPChannelsList(768);
	  badch->SetNBadNChannelsList(768);
	  badch_array.AddAt(badch,i);
	}
	//-----------------------------------------

	//---------------------------------------
	// in case some module was not calibrated!
	for(Int_t i=0; i<fgkNumberOfSSD; i++) {
	  AliITSPedestalSSD *pedel = new AliITSPedestalSSD();
	  pedel->SetMod((UShort_t) i+500);
	  pedel->SetNPedestalP(768);
	  pedel->SetNPedestalN(768);
	  for(Int_t j=0; j<768; j++) {
	    pedel->AddPedestalP(j,0.);
	    pedel->AddPedestalN(j,0.);
	  }
	  ped_array.AddAt(pedel,i);
	}
	//-----------------------------------------

	// expect to iterate 3 times (LDC0, LDC1, LDC2)
	while ( (ok = (TObjString*) next()) ) {

	  TString key = ok->String();

	  TString fileName = GetFile(kDAQ, "CALIBRATION", key.Data());
	  if (fileName.Length() > 0) {

	    Log(Form("Got the file %s, now we can extract some values.", fileName.Data()));

	    TFile *f = new TFile(fileName.Data());
	    if(!f || !f->IsOpen()){
	    	Log("Error opening file!");
		delete list;
		return 2;
	    }

	    TObjArray *cal;
	    f->GetObject("Noise;1", cal);
	    if(!cal) {
	    	Log("File does not contain expected data for the noise!");
		delete list;
		return 3;
	    }

	    Int_t nmod = cal->GetEntries();
	    Log(Form("\n#Mod %d", nmod ));
	    for(Int_t mod=0; mod<nmod; mod++) {
	      AliITSNoiseSSD *calib = (AliITSNoiseSSD*) cal->At(mod);
	      Log(Form("\nModId %d", calib->GetMod() ));
	      if((calib->GetMod()<500)||(calib->GetMod()>2198)) continue;
	      calib_array.AddAt(calib,calib->GetMod()-500);
	    }

	    TObjArray *bad;
	    f->GetObject("BadChannels;1", bad);
	    if(!bad) {
	    	Log("File does not contain expected data for bad channels  !");
		delete list;
		return 4;
	    }
	    nmod = bad->GetEntries();
	    for(Int_t mod=0; mod<nmod; mod++) {
	      AliITSBadChannelsSSD *badch = (AliITSBadChannelsSSD*) bad->At(mod);
	      if((badch->GetMod()<500)||(badch->GetMod()>2198)) continue;
	      badch_array.AddAt(badch,badch->GetMod()-500);
	    }

	    TObjArray *ped;
	    f->GetObject("Pedestal;1", ped);
	    if(!ped) {
	    	Log("File does not contain expected data for the pedestals!");
		delete list;
		return 5;
	    }
	    nmod = ped->GetEntries();
	    for(Int_t mod=0; mod<nmod; mod++) {
	      AliITSPedestalSSD *pedel = (AliITSPedestalSSD*) ped->At(mod);
	      if((pedel->GetMod()<500)||(pedel->GetMod()>2198)) continue;
	      ped_array.AddAt(pedel,pedel->GetMod()-500);
	    }

	    f->Close(); delete f;

	  } else {
	  	Log("GetFile error!");
		delete list;
		return 6;
	  } // if filename
	} // end iteration over LDCs

	delete list;
      } else {
      	  Log("GetFileSources error!");
	  if(list) delete list;
	  return 7;
      } // if list

      //Now we have to store the final CDB file
      AliCDBMetaData metaData;
      metaData.SetBeamPeriod(0);
      metaData.SetResponsible("Enrico Fragiacomo");
      metaData.SetComment("Fills noise, pedestal and bad channels TObjArray");

      if(!Store("Calib", "NoiseSSD", &calib_array, &metaData, 0, 1)) {
	Log("no store");
        return 1;
      }

      if(!Store("Calib", "BadChannelsSSD", &badch_array, &metaData, 0, 1)) {
	Log("no store");
        return 1;
      }

      if(!StoreReferenceData("Calib","PedestalSSD", &ped_array, &metaData)) {
	Log("no store");
	return 1;
      }

  } // end if pedestal run
  else {
    Log("Nothing to do");
    return 0;
  }

  Log("Database updated");
  return 0; // 0 means success

}

<|endoftext|>


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

/* $Id$ */

#include <TROOT.h>
#include <TSystem.h>
#include <TInterpreter.h>
#include <TChain.h>
#include <TFile.h>
#include <TList.h>

#include "AliAnalysisTaskJets.h"
#include "AliAnalysisManager.h"
#include "AliJetFinder.h"
#include "AliJetHistos.h"
#include "AliESDEvent.h"
#include "AliESD.h"
#include "AliAODEvent.h"
#include "AliAODHandler.h"
#include "AliMCEventHandler.h"
#include "AliESDInputHandler.h"
#include "AliMCEvent.h"
#include "AliStack.h"

ClassImp(AliAnalysisTaskJets)

////////////////////////////////////////////////////////////////////////

AliAnalysisTaskJets::AliAnalysisTaskJets():
    AliAnalysisTaskSE(),
  fConfigFile("ConfigJetAnalysis.C"),
  fNonStdBranch(""),
  fJetFinder(0x0),
  fHistos(0x0),
  fListOfHistos(0x0)
{
  // Default constructor
}

AliAnalysisTaskJets::AliAnalysisTaskJets(const char* name):
    AliAnalysisTaskSE(name),
    fConfigFile("ConfigJetAnalysis.C"),
    fNonStdBranch(""),
    fJetFinder(0x0),
    fHistos(0x0),
    fListOfHistos(0x0)
{
  // Default constructor
    DefineOutput(1, TList::Class());
}

void AliAnalysisTaskJets::UserCreateOutputObjects()
{
// Create the output container
//
    if (fDebug > 1) printf("AnalysisTaskJets::CreateOutPutData() \n");

    if(fNonStdBranch.Length()==0){
      //  Connec default AOD to jet finder
      fJetFinder->ConnectAOD(AODEvent());
    }
    else{
      // Create a new branch for jets...
      // how is this is reset cleared in the UserExec....
      // Can this be handled by the framework?
      TClonesArray *tca = new TClonesArray("AliAODJet", 0);
      tca->SetName(fNonStdBranch);
      AddAODBranch("TClonesArray",&tca);
      fJetFinder->ConnectAODNonStd(AODEvent(),fNonStdBranch.Data());
    }
    //  Histograms
    OpenFile(1);
    fListOfHistos = new TList();
    fHistos       = new AliJetHistos();
    fHistos->AddHistosToList(fListOfHistos);

}

void AliAnalysisTaskJets::Init()
{
    // Initialization
    if (fDebug > 1) printf("AnalysisTaskJets::Init() \n");

    // Call configuration file
    gROOT->LoadMacro(fConfigFile);
    fJetFinder = (AliJetFinder*) gInterpreter->ProcessLine("ConfigJetAnalysis()");
    // Initialise Jet Analysis
    fJetFinder->Init();
    // Write header information to local file
    fJetFinder->WriteHeaders();
}

void AliAnalysisTaskJets::UserExec(Option_t */*option*/)
{
  // Execute analysis for current event
  //

  // Fill control histos
  TClonesArray* jarray = 0;
  if(fNonStdBranch.Length()==0){
    jarray = AODEvent()->GetJets();
  }
  else{
    jarray =  dynamic_cast<TClonesArray*>(AODEvent()->FindListObject(fNonStdBranch.Data()));
    jarray->Delete();    // this is our responsibility, clear before filling again
  }

  fJetFinder->GetReader()->SetInputEvent(InputEvent(), AODEvent(), MCEvent());
  fJetFinder->ProcessEvent();

  fHistos->FillHistos(jarray);
  // Post the data
  PostData(1, fListOfHistos);
}

void AliAnalysisTaskJets::Terminate(Option_t */*option*/)
{
// Terminate analysis
//
    if (fDebug > 1) printf("AnalysisJets: Terminate() \n");
//    if (fJetFinder) fJetFinder->FinishRun();
}

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

/* $Id$ */

#include <TROOT.h>
#include <TSystem.h>
#include <TInterpreter.h>
#include <TChain.h>
#include <TFile.h>
#include <TList.h>

#include "AliAnalysisTaskJets.h"
#include "AliAnalysisManager.h"
#include "AliJetFinder.h"
#include "AliJetHeader.h"
#include "AliJetHistos.h"
#include "AliESDEvent.h"
#include "AliESD.h"
#include "AliAODEvent.h"
#include "AliAODHandler.h"
#include "AliMCEventHandler.h"
#include "AliESDInputHandler.h"
#include "AliMCEvent.h"
#include "AliStack.h"

ClassImp(AliAnalysisTaskJets)

////////////////////////////////////////////////////////////////////////

AliAnalysisTaskJets::AliAnalysisTaskJets():
    AliAnalysisTaskSE(),
  fConfigFile("ConfigJetAnalysis.C"),
  fNonStdBranch(""),
  fJetFinder(0x0),
  fHistos(0x0),
  fListOfHistos(0x0)
{
  // Default constructor
}

AliAnalysisTaskJets::AliAnalysisTaskJets(const char* name):
    AliAnalysisTaskSE(name),
    fConfigFile("ConfigJetAnalysis.C"),
    fNonStdBranch(""),
    fJetFinder(0x0),
    fHistos(0x0),
    fListOfHistos(0x0)
{
  // Default constructor
    DefineOutput(1, TList::Class());
}

void AliAnalysisTaskJets::UserCreateOutputObjects()
{
// Create the output container
//
    if (fDebug > 1) printf("AnalysisTaskJets::CreateOutPutData() \n");

    if(fNonStdBranch.Length()==0){
      //  Connec default AOD to jet finder
      fJetFinder->ConnectAOD(AODEvent());
    }
    else{
      // Create a new branch for jets...
      // how is this is reset cleared in the UserExec....
      // Can this be handled by the framework?
      TClonesArray *tca = new TClonesArray("AliAODJet", 0);
      tca->SetName(fNonStdBranch);
      AddAODBranch("TClonesArray",&tca);
      fJetFinder->ConnectAODNonStd(AODEvent(),fNonStdBranch.Data());
    }
    //  Histograms
    OpenFile(1);
    fListOfHistos = new TList();
    fHistos       = new AliJetHistos();
    fHistos->AddHistosToList(fListOfHistos);

    // Add the JetFinderInforamtion to the Outputlist
    AliJetHeader *fH = fJetFinder->GetHeader();
    // Compose a characteristic output name
    // with the name of the output branch
    if(fH){
      if(fNonStdBranch.Length()==0){
	fH->SetName("AliJetHeader_jets");
      }
      else{
	fH->SetName(Form("AliJetHeader_%s",fNonStdBranch.Data()));
      }
    }
    OutputTree()->GetUserInfo()->Add(fH);
}

void AliAnalysisTaskJets::Init()
{
    // Initialization
    if (fDebug > 1) printf("AnalysisTaskJets::Init() \n");

    // Call configuration file
    gROOT->LoadMacro(fConfigFile);
    fJetFinder = (AliJetFinder*) gInterpreter->ProcessLine("ConfigJetAnalysis()");
    // Initialise Jet Analysis
    fJetFinder->Init();
    // Write header information to local file
    fJetFinder->WriteHeaders();
}

void AliAnalysisTaskJets::UserExec(Option_t */*option*/)
{
  // Execute analysis for current event
  //

  // Fill control histos
  TClonesArray* jarray = 0;
  if(fNonStdBranch.Length()==0){
    jarray = AODEvent()->GetJets();
  }
  else{
    jarray =  dynamic_cast<TClonesArray*>(AODEvent()->FindListObject(fNonStdBranch.Data()));
    jarray->Delete();    // this is our responsibility, clear before filling again
  }

  fJetFinder->GetReader()->SetInputEvent(InputEvent(), AODEvent(), MCEvent());
  fJetFinder->ProcessEvent();

  fHistos->FillHistos(jarray);
  // Post the data
  PostData(1, fListOfHistos);
}

void AliAnalysisTaskJets::Terminate(Option_t */*option*/)
{
// Terminate analysis
//
    if (fDebug > 1) printf("AnalysisJets: Terminate() \n");
//    if (fJetFinder) fJetFinder->FinishRun();
}

<|endoftext|>


<commit_before>/******************************************************************************
 *
 * Mantis_Camera_Focus.cpp
 * Author: Bryan D. Maione
 *
 * This script enables the focusing of all the Mcams in a Mantis system with either
 * autofocus, or assisted manual focus.
 *
 *****************************************************************************/
 /*  gcc -std=c++11 -o  Mantis_Camera_Focus  Mantis_Camera_Focus.cpp -lMantisAPI -lpthread -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lm -lstdc++
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <sstream>
#include <mutex>
#include <utility>

#include "opencv2/core/mat.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

#include "mantis/MantisAPI.h"
const int portbase = 13000;
using namespace cv;
using namespace std;

void newMCamCallback(MICRO_CAMERA mcam, void* data)
{
    static int mcamCounter = 0;
    MICRO_CAMERA* mcamList = (MICRO_CAMERA*) data;
    mcamList[mcamCounter++] = mcam;
}

/**
 * \brief Function to handle recieving microcamera frames that just
 *        prints the mcam ID and timestamp of the received frame
 **/

pair<double,Mat> calculateFocusMetric(Mat img){
    Mat edge;
    int edgeThresh = 100;
    int imgsize = img.rows*img.cols;
    Canny(img, edge, edgeThresh, edgeThresh*2, 3);
    double metric = cv::sum( edge )[0]/imgsize;
    return make_pair(metric, edge);
}

bool processing = false;
double metric = 0;

void mcamFrameCallback(FRAME frame, void* data)
{

    if (!processing && frame.m_metadata.m_height == 1080  /*frame.m_metadata.m_camId == mcamlist[mcamnum]*/){
        processing = true;
        // cout << "Rendering Frame" << "\n";
        int imgsize = frame.m_metadata.m_size;
        Mat rawdata = Mat(1, imgsize ,  CV_8UC1, (void *)frame.m_image); //compressed jpg data
        Mat loaded = imdecode(rawdata,1);
        if (loaded.data==NULL){
            cerr << "Failed to decode data" <<"\n";
        }
        pair<double,Mat> output;
        output = calculateFocusMetric(loaded);
        Mat edges = output.second;
        metric = output.first;
        cvtColor(edges, edges, CV_GRAY2BGR);
        addWeighted(loaded , 0.5, edges, 0.5, 0.0, loaded);
        loaded += edges;
        imshow("Image",loaded);
        waitKey(50);
        processing = false;
    }
}

/**
 * \ Function that computes the focus metric from an image
 **/

void printHelp()
{
   printf("McamStream Demo Application\n");
   printf("Usage:\n");
   printf("\t-c FILE   Host file for microcameras (default sync.cfg) \n");
   printf("\t-port <port> port connect to (default 9999)\n\n");
}

int getIpsFromSyncFile(char fileName[])
{

 //   sleep(5);
      printf("i think the filename is %s \n",fileName);
 //   fileName = "sync.cfg"; /* should check that argc > 1 */
      FILE* file = fopen(fileName, "r"); /* should check the result */
    char line[256];
    int d;
    int currentCam=0;
    int currentChar=0;
    int readingIP=0;
    char ip[10][24];
    memset( ip, '\0', sizeof(ip) -1 );
    int numIps;
    int port = 9999;
    printf("in readsync now \n");
    while (fgets(line, sizeof(line), file)) {
        /* note that fgets don't strip the terminating \n, checking its
           presence would allow to handle lines longer that sizeof(line) */
        printf("%s", line);

    	for(d=0;d<strlen(line);d++) {

		if(line[d] == ':'){
			//printf("I found the colon \n");
			readingIP=0;
		}
		if(readingIP == 1){
			ip[currentCam][currentChar]=line[d];
			currentChar++;
		}
		if(line[d] == '@'){
    	    		//printf("I found the ampersand \n");
			readingIP=1;
		}

    	}
	currentCam++;
	currentChar=0;

        }
       /* may check feof here to make a difference between eof and io failure -- network
       timeout for instance */
    numIps=currentCam;
    for( int ii=0; ii<numIps; ii++){
    /* Connect directly to the Tegra hosting the microcamera.
     * If the IP/port of the desired microcamera is unknown, it
     * can be found using the getCameraMcamList method shown in
     * the MantisGetFrames example, which returns MICRO_CAMERA
     * structs for each microcamera in a Mantis system. These
     * structs contain the IP/port of the Tegras which host them */
	printf("About to connect to ip %s on port %d \n", ip[ii],port);
        mCamConnect(ip[ii], port);
	printf("Connected \n");

	}

    fclose(file);
return numIps;  }

void autofocusMcam(MICRO_CAMERA automcam){
    int step = 100; //Doing a focus sweep with 100 step increments
    int numiter = 2200/step;
    double metricprev = 0;
    double localbestmetric = 0;
    double globalbestmetric= 0;
    int globalbestpos = 0;
    int finalbestpos = 0;
    bool stopflag = false;
    //Bring to near focus
    setMCamFocusNear(automcam, 0);
    sleep(2);
    /* Start the focus sweep for each micro camera connected to this tegra*/
    for ( int i = 0; i <= numiter-1; i++ ){
        cout << "Current Position: "+to_string(i*step) << "\n";
        FRAME frame = grabMCamFrame(portbase, 1.0 );
        int imgsize = frame.m_metadata.m_size;
        //size_t stepcv=CV_AUTO_STEP;
        Mat rawdata = Mat(1, imgsize ,  CV_8UC1, (void *)frame.m_image); //compressed jpg data
        Mat loaded = imdecode(rawdata,1);
        if (loaded.data==NULL){
            cerr << "Failed to decode data" <<"\n";
        }
        /* Calculate the focus metric from the image*/
        metric = calculateFocusMetric(loaded).first;
        cout << "Current metric value: "+to_string(metric) << "\n";
        setMCamFocusFar(automcam, step);
        sleep(2);
        /* If the metric increased update the best value and position */
        if ( metric > metricprev){
        cout << "metric value increased" << "\n";
        localbestmetric = metric;
        /* If the current metric is the best we've seen yet, update as current best*/
            if ( localbestmetric > globalbestmetric){
            cout << "Global best updated" << "\n";
            globalbestmetric = localbestmetric;
            globalbestpos = i+1;
            }
        }
        metricprev = metric;
    }//end coarse sweep

    /* Bring each Mcam to 100 steps before best focus position*/
    int initpos = 2200;
    int nstep = initpos - globalbestpos*step;
    setMCamFocusNear(automcam, nstep);
    /*Recalculate the metric */
    FRAME frame = grabMCamFrame(portbase, 1.0 );
    int imgsize = frame.m_metadata.m_size;
    //size_t step=CV_AUTO_STEP;
    Mat rawdata = Mat(1, imgsize ,  CV_8UC1, (void *)frame.m_image); //compressed jpg data
    Mat loaded = imdecode(rawdata,1);
    if (loaded.data==NULL){
        cerr << "Failed to decode data" <<"\n";
    }
    /* Calculate the focus metric from the image*/
    metricprev = calculateFocusMetric(loaded).first;
    /*DO A FINE FOCUS SWEEP*/
    for (int i=0; i<20; i++){
        if (!stopflag){
                int stepfine = 10;
                setMCamFocusNear(automcam, stepfine);
            }
            FRAME frame = grabMCamFrame(portbase, 1.0 );
            int imgsize = frame.m_metadata.m_size;
            //size_t step=CV_AUTO_STEP;
            Mat rawdata = Mat(1, imgsize ,  CV_8UC1, (void *)frame.m_image); //compressed jpg data
            Mat loaded = imdecode(rawdata,1);
            if (loaded.data==NULL){
                cerr << "Failed to decode data" <<"\n";
            }
            /* Calculate the focus metric from the image*/
            metric = calculateFocusMetric(loaded).first;

            if (metric>=globalbestmetric && metricprev>=metric){
                /* Step back 10 steps stop focusing this camera */
                cout << "Best focus acheived" << "\n";
                setMCamFocusFar(automcam, 10);
                stopflag=true;
            }
            metricprev = metric;
    }

}

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

    //Parse arguments
    int argCount = 0;
    char* hostfile = "sync.cfg";
    //std::string clipfile = DEFAULT_CLIPFILE;
    for( int i = 1; i < argc; i++ ){
        if( !strcmp( argv[i], "-c" ) ){
            argCount++;
            i++;
            if( i > argc ){
                std::cout << "-c option must specify a directory"
                          << std::endl;
                printHelp();
                exit(1);
            }
            hostfile=argv[i];
            std::cout << "using hostfile: " << hostfile << std::endl;
        } else if( !strcmp( argv[i], "-p" ) ){
            argCount++;
            i++;
            if( i > argc ){
                std::cout << "-p option must specify an image port"
                          << std::endl;
                printHelp();
                exit(1);
            }
            //imagePort = std::stoi(argv[1]);
        } else if( !strcmp( argv[i], "-h" ) ){
            printHelp();
            exit(0);
        }else {
            printHelp();
            exit(0);
        }
    }

    /**************** Camera Initialization *****************/
    /********************************************************/
    /* start stream */
    getIpsFromSyncFile(hostfile);
    /* get cameras from API */
    int numMCams = getNumberOfMCams();
    printf("API reported that there are %d microcameras available\n", numMCams);
    MICRO_CAMERA mcamList[numMCams];
     /* create new microcamera callback struct */
    NEW_MICRO_CAMERA_CALLBACK mcamCB;
    mcamCB.f = newMCamCallback;
    mcamCB.data = mcamList;

    /* call setNewMCamCallback; this function sets a callback that is
     * triggered each time a new microcamera is discovered by the API,
     * and also calls the callback function for each microcamera that
     * has already been discovered at the time of setting the callback */
    setNewMCamCallback(mcamCB);

    /* Next we set a callback function to receive the stream of frames
     * from the desired microcamera */
    MICRO_CAMERA_FRAME_CALLBACK frameCB;
    frameCB.f = mcamFrameCallback;
    frameCB.data = NULL;
    setMCamFrameCallback(frameCB);
    //MICRO_CAMERA myMCam = mcamList[0];

    /* now if we check our list, we should see a populated list
     * of MICRO_CAMERA objects */
    initMCamFrameReceiver( portbase, 1 );
    /*for( int i = 0; i < numMCams; i++ ){

        printf("Found mcam with ID %u\n", mcamList[i].mcamID);
        // Star the stream for each Mcam in the list
        if( !startMCamStream(mcamList[i], portbase) ){
        printf("Failed to start streaming mcam %u\n", mcamList[i].mcamID);
        exit(0);
        }
    }*/

    /* We only want to stream HD frame */
   /* for( int i = 0; i < numMCams; i++ ){
    	setMCamStreamFilter(mcamList[i], portbase, 2);
    }*/
    /*************************************************************/
    /*************************************************************/

     /* Start a loop of polling the keyboard to determine action*/
    int stepsize = 100;
    int mcamnum = 0;
    if( !startMCamStream(mcamList[mcamnum], portbase) ){
    printf("Failed to start streaming mcam %u\n", mcamList[mcamnum].mcamID);
    exit(0);
    }
    while (true){
        /*FRAME image = grabMCamFrame(portbase+mcamnum, 1.0 );
        int imgsize = image.m_metadata.m_size;

        size_t step=CV_AUTO_STEP;
        Mat rawdata = Mat(1, imgsize ,  CV_8UC1, (void *)image.m_image); //compressed jpg data
        Mat loaded = imdecode(rawdata,1);
        if (loaded.data==NULL){
            cerr << "Failed to decode data" <<"\n";
        }
        pair<double,Mat> output;
        output = calculateFocusMetric(loaded);
        //Mat edges = output.second;
        //cvtColor(edges, edges, CV_GRAY2BGR);
        //addWeighted(loaded , 0.5, edges, 0.5, 0.0, loaded);
        //loaded += edges;*/

        cout << "Current Metric Value:"+to_string(metric) << "\n";

        //imshow("Image", loaded);
        //waitKey(1000);
        char input;
        cout << "a = auto i=In o=Out s=Step n=next camera q=Quit: ";
        cin >> input;
        if (input== 'i'){
            setMCamFocusFar(mcamList[mcamnum], stepsize);
            sleep(1);
        }
        else if (input== 'o'){
            setMCamFocusNear(mcamList[mcamnum], stepsize);
            sleep(1);
        }
        else if (input== 's'){
            int newstepsize;
            cout << "Enter new step size: ";
            cin >> newstepsize;
            stepsize = newstepsize;
        }
        else if (input== 'q'){
		if (!stopMCamStream(mcamList[mcamnum], portbase)){
		printf("unable to stop stream\n");
		}
            break;
        }
        else if (input== 'a'){
            destroyAllWindows();
            cout << "Autofocusing Current Mcam" << "\n";
            autofocusMcam(mcamList[mcamnum]);
        }
        else if (input== 'n'){
            if (mcamnum < numMCams-1){
		        if (!stopMCamStream(mcamList[mcamnum], portbase)){
  		            printf("unable to stop stream\n");
		        }
		        mcamnum++;
		        if( !startMCamStream(mcamList[mcamnum], portbase) ){
		            printf("Failed to start streaming mcam %u\n", mcamList[mcamnum].mcamID);
		            exit(0);
		        }
            cout << "Switched Mcam" << "\n";
            }
            else{
                if (!stopMCamStream(mcamList[mcamnum], portbase)){
  		            printf("unable to stop stream\n");
		        }
                mcamnum=0;
                if( !startMCamStream(mcamList[mcamnum], portbase) ){
		            printf("Failed to start streaming mcam %u\n", mcamList[mcamnum].mcamID);
		            exit(0);
		        }
            cout << "Switched Mcam" << "\n";
            }
        }
        else{
            ; // Do nothing
        }

    }
}

<commit_msg>Added ability to go to previous cameras, closed mcamFrameReceiver on exit, and added sleeps between stopping and starting streams<commit_after>/******************************************************************************
 *
 * Mantis_Camera_Focus.cpp
 * Author: Bryan D. Maione
 *
 * This script enables the focusing of all the Mcams in a Mantis system with either
 * autofocus, or assisted manual focus.
 *
 *****************************************************************************/
 /*  gcc -std=c++11 -o  Mantis_Camera_Focus  Mantis_Camera_Focus.cpp -lMantisAPI -lpthread -lopencv_core -lopencv_highgui -lopencv_imgcodecs -lopencv_imgproc -lm -lstdc++
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <math.h>
#include <sstream>
#include <mutex>
#include <utility>

#include "opencv2/core/mat.hpp"
#include "opencv2/core/utility.hpp"
#include "opencv2/imgproc.hpp"
#include "opencv2/imgcodecs.hpp"
#include "opencv2/highgui.hpp"
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <iostream>

#include "mantis/MantisAPI.h"
const int portbase = 13000;
using namespace cv;
using namespace std;

void newMCamCallback(MICRO_CAMERA mcam, void* data)
{
    static int mcamCounter = 0;
    MICRO_CAMERA* mcamList = (MICRO_CAMERA*) data;
    mcamList[mcamCounter++] = mcam;
}

/**
 * \brief Function to handle recieving microcamera frames that just
 *        prints the mcam ID and timestamp of the received frame
 **/

pair<double,Mat> calculateFocusMetric(Mat img){
    Mat edge;
    int edgeThresh = 100;
    int imgsize = img.rows*img.cols;
    Canny(img, edge, edgeThresh, edgeThresh*2, 3);
    double metric = cv::sum( edge )[0]/imgsize;
    return make_pair(metric, edge);
}

bool processing = false;
double metric = 0;

void mcamFrameCallback(FRAME frame, void* data)
{

    if (!processing && frame.m_metadata.m_height == 1080  /*frame.m_metadata.m_camId == mcamlist[mcamnum]*/){
        processing = true;
        // cout << "Rendering Frame" << "\n";
        int imgsize = frame.m_metadata.m_size;
        Mat rawdata = Mat(1, imgsize ,  CV_8UC1, (void *)frame.m_image); //compressed jpg data
        Mat loaded = imdecode(rawdata,1);
        if (loaded.data==NULL){
            cerr << "Failed to decode data" <<"\n";
        }
        pair<double,Mat> output;
        output = calculateFocusMetric(loaded);
        Mat edges = output.second;
        metric = output.first;
        cvtColor(edges, edges, CV_GRAY2BGR);
        addWeighted(loaded , 0.5, edges, 0.5, 0.0, loaded);
        loaded += edges;
        imshow("Image",loaded);
        waitKey(50);
        processing = false;
    }
}

/**
 * \ Function that computes the focus metric from an image
 **/

void printHelp()
{
   printf("McamStream Demo Application\n");
   printf("Usage:\n");
   printf("\t-c FILE   Host file for microcameras (default sync.cfg) \n");
   printf("\t-port <port> port connect to (default 9999)\n\n");
}

int getIpsFromSyncFile(char fileName[])
{

 //   sleep(5);
      printf("i think the filename is %s \n",fileName);
 //   fileName = "sync.cfg"; /* should check that argc > 1 */
      FILE* file = fopen(fileName, "r"); /* should check the result */
    char line[256];
    int d;
    int currentCam=0;
    int currentChar=0;
    int readingIP=0;
    char ip[10][24];
    memset( ip, '\0', sizeof(ip) -1 );
    int numIps;
    int port = 9999;
    printf("in readsync now \n");
    while (fgets(line, sizeof(line), file)) {
        /* note that fgets don't strip the terminating \n, checking its
           presence would allow to handle lines longer that sizeof(line) */
        printf("%s", line);

    	for(d=0;d<strlen(line);d++) {

		if(line[d] == ':'){
			//printf("I found the colon \n");
			readingIP=0;
		}
		if(readingIP == 1){
			ip[currentCam][currentChar]=line[d];
			currentChar++;
		}
		if(line[d] == '@'){
    	    		//printf("I found the ampersand \n");
			readingIP=1;
		}

    	}
	currentCam++;
	currentChar=0;

        }
       /* may check feof here to make a difference between eof and io failure -- network
       timeout for instance */
    numIps=currentCam;
    for( int ii=0; ii<numIps; ii++){
    /* Connect directly to the Tegra hosting the microcamera.
     * If the IP/port of the desired microcamera is unknown, it
     * can be found using the getCameraMcamList method shown in
     * the MantisGetFrames example, which returns MICRO_CAMERA
     * structs for each microcamera in a Mantis system. These
     * structs contain the IP/port of the Tegras which host them */
	printf("About to connect to ip %s on port %d \n", ip[ii],port);
        mCamConnect(ip[ii], port);
	printf("Connected \n");

	}

    fclose(file);
return numIps;  }

void autofocusMcam(MICRO_CAMERA automcam){
    int step = 100; //Doing a focus sweep with 100 step increments
    int numiter = 2200/step;
    double metricprev = 0;
    double localbestmetric = 0;
    double globalbestmetric= 0;
    int globalbestpos = 0;
    int finalbestpos = 0;
    bool stopflag = false;
    //Bring to near focus
    setMCamFocusNear(automcam, 0);
    sleep(2);
    /* Start the focus sweep for each micro camera connected to this tegra*/
    for ( int i = 0; i <= numiter-1; i++ ){
        cout << "Current Position: "+to_string(i*step) << "\n";
        FRAME frame = grabMCamFrame(portbase, 1.0 );
        int imgsize = frame.m_metadata.m_size;
        //size_t stepcv=CV_AUTO_STEP;
        Mat rawdata = Mat(1, imgsize ,  CV_8UC1, (void *)frame.m_image); //compressed jpg data
        Mat loaded = imdecode(rawdata,1);
        if (loaded.data==NULL){
            cerr << "Failed to decode data" <<"\n";
        }
        /* Calculate the focus metric from the image*/
        metric = calculateFocusMetric(loaded).first;
        cout << "Current metric value: "+to_string(metric) << "\n";
        setMCamFocusFar(automcam, step);
        sleep(2);
        /* If the metric increased update the best value and position */
        if ( metric > metricprev){
        cout << "metric value increased" << "\n";
        localbestmetric = metric;
        /* If the current metric is the best we've seen yet, update as current best*/
            if ( localbestmetric > globalbestmetric){
            cout << "Global best updated" << "\n";
            globalbestmetric = localbestmetric;
            globalbestpos = i+1;
            }
        }
        metricprev = metric;
    }//end coarse sweep

    /* Bring each Mcam to 100 steps before best focus position*/
    int initpos = 2200;
    int nstep = initpos - globalbestpos*step;
    setMCamFocusNear(automcam, nstep);
    /*Recalculate the metric */
    FRAME frame = grabMCamFrame(portbase, 1.0 );
    int imgsize = frame.m_metadata.m_size;
    //size_t step=CV_AUTO_STEP;
    Mat rawdata = Mat(1, imgsize ,  CV_8UC1, (void *)frame.m_image); //compressed jpg data
    Mat loaded = imdecode(rawdata,1);
    if (loaded.data==NULL){
        cerr << "Failed to decode data" <<"\n";
    }
    /* Calculate the focus metric from the image*/
    metricprev = calculateFocusMetric(loaded).first;
    /*DO A FINE FOCUS SWEEP*/
    for (int i=0; i<20; i++){
        if (!stopflag){
                int stepfine = 10;
                setMCamFocusNear(automcam, stepfine);
            }
            FRAME frame = grabMCamFrame(portbase, 1.0 );
            int imgsize = frame.m_metadata.m_size;
            //size_t step=CV_AUTO_STEP;
            Mat rawdata = Mat(1, imgsize ,  CV_8UC1, (void *)frame.m_image); //compressed jpg data
            Mat loaded = imdecode(rawdata,1);
            if (loaded.data==NULL){
                cerr << "Failed to decode data" <<"\n";
            }
            /* Calculate the focus metric from the image*/
            metric = calculateFocusMetric(loaded).first;

            if (metric>=globalbestmetric && metricprev>=metric){
                /* Step back 10 steps stop focusing this camera */
                cout << "Best focus acheived" << "\n";
                setMCamFocusFar(automcam, 10);
                stopflag=true;
            }
            metricprev = metric;
    }

}

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

    //Parse arguments
    int argCount = 0;
    char* hostfile = "sync.cfg";
    //std::string clipfile = DEFAULT_CLIPFILE;
    for( int i = 1; i < argc; i++ ){
        if( !strcmp( argv[i], "-c" ) ){
            argCount++;
            i++;
            if( i > argc ){
                std::cout << "-c option must specify a directory"
                          << std::endl;
                printHelp();
                exit(1);
            }
            hostfile=argv[i];
            std::cout << "using hostfile: " << hostfile << std::endl;
        } else if( !strcmp( argv[i], "-p" ) ){
            argCount++;
            i++;
            if( i > argc ){
                std::cout << "-p option must specify an image port"
                          << std::endl;
                printHelp();
                exit(1);
            }
            //imagePort = std::stoi(argv[1]);
        } else if( !strcmp( argv[i], "-h" ) ){
            printHelp();
            exit(0);
        }else {
            printHelp();
            exit(0);
        }
    }

    /**************** Camera Initialization *****************/
    /********************************************************/
    /* start stream */
    getIpsFromSyncFile(hostfile);
    /* get cameras from API */
    int numMCams = getNumberOfMCams();
    printf("API reported that there are %d microcameras available\n", numMCams);
    MICRO_CAMERA mcamList[numMCams];
     /* create new microcamera callback struct */
    NEW_MICRO_CAMERA_CALLBACK mcamCB;
    mcamCB.f = newMCamCallback;
    mcamCB.data = mcamList;

    /* call setNewMCamCallback; this function sets a callback that is
     * triggered each time a new microcamera is discovered by the API,
     * and also calls the callback function for each microcamera that
     * has already been discovered at the time of setting the callback */
    setNewMCamCallback(mcamCB);

    /* Next we set a callback function to receive the stream of frames
     * from the desired microcamera */
    MICRO_CAMERA_FRAME_CALLBACK frameCB;
    frameCB.f = mcamFrameCallback;
    frameCB.data = NULL;
    setMCamFrameCallback(frameCB);
    //MICRO_CAMERA myMCam = mcamList[0];

    /* now if we check our list, we should see a populated list
     * of MICRO_CAMERA objects */
    initMCamFrameReceiver( portbase, 1 );
    /*for( int i = 0; i < numMCams; i++ ){

        printf("Found mcam with ID %u\n", mcamList[i].mcamID);
        // Star the stream for each Mcam in the list
        if( !startMCamStream(mcamList[i], portbase) ){
        printf("Failed to start streaming mcam %u\n", mcamList[i].mcamID);
        exit(0);
        }
    }*/

    /* We only want to stream HD frame */
   /* for( int i = 0; i < numMCams; i++ ){
    	setMCamStreamFilter(mcamList[i], portbase, 2);
    }*/
    /*************************************************************/
    /*************************************************************/

     /* Start a loop of polling the keyboard to determine action*/
    int stepsize = 100;
    int mcamnum = 0;
    if( !startMCamStream(mcamList[mcamnum], portbase) ){
    printf("Failed to start streaming mcam %u\n", mcamList[mcamnum].mcamID);
    exit(0);
    }
    while (true){
        /*FRAME image = grabMCamFrame(portbase+mcamnum, 1.0 );
        int imgsize = image.m_metadata.m_size;

        size_t step=CV_AUTO_STEP;
        Mat rawdata = Mat(1, imgsize ,  CV_8UC1, (void *)image.m_image); //compressed jpg data
        Mat loaded = imdecode(rawdata,1);
        if (loaded.data==NULL){
            cerr << "Failed to decode data" <<"\n";
        }
        pair<double,Mat> output;
        output = calculateFocusMetric(loaded);
        //Mat edges = output.second;
        //cvtColor(edges, edges, CV_GRAY2BGR);
        //addWeighted(loaded , 0.5, edges, 0.5, 0.0, loaded);
        //loaded += edges;*/

        cout << "Current Metric Value:"+to_string(metric) << "\n";

        //imshow("Image", loaded);
        //waitKey(1000);
        char input;
        cout << "a = auto i=In o=Out s=Step n=next camera p= previous camera q=Quit: ";
        cin >> input;
        if (input== 'i'){
            setMCamFocusFar(mcamList[mcamnum], stepsize);
            sleep(1);
        }
        else if (input== 'o'){
            setMCamFocusNear(mcamList[mcamnum], stepsize);
            sleep(1);
        }
        else if (input== 's'){
            int newstepsize;
            cout << "Enter new step size: ";
            cin >> newstepsize;
            stepsize = newstepsize;
        }
        else if (input== 'q'){
		if (!stopMCamStream(mcamList[mcamnum], portbase)){
		printf("unable to stop stream\n");
		}
		closeMCamFrameReceiver(portbase);
            break;
        }
        else if (input== 'a'){
            destroyAllWindows();
            cout << "Autofocusing Current Mcam" << "\n";
            autofocusMcam(mcamList[mcamnum]);
        }
        else if (input== 'n' || input== 'p'){
            if (mcamnum < numMCams-1){
		        if (!stopMCamStream(mcamList[mcamnum], portbase)){
  		            printf("unable to stop stream\n");
		        }
			sleep(0.5);
			if (input == 'n') {
			        mcamnum++; }
			else {
				mcamnum--;
			}
			if (mcamnum<0) {
				mcamnum=numMCams-1;
			}
		        if( !startMCamStream(mcamList[mcamnum], portbase) ){
		            printf("Failed to start streaming mcam %u\n", mcamList[mcamnum].mcamID);
		            exit(0);
		        }
            cout << "Switched Mcam" << "\n";
            }
            else{
                if (!stopMCamStream(mcamList[mcamnum], portbase)){
  		            printf("unable to stop stream\n");
		        }
                mcamnum=0;
		sleep(0.5);
                if( !startMCamStream(mcamList[mcamnum], portbase) ){
		            printf("Failed to start streaming mcam %u\n", mcamList[mcamnum].mcamID);
		            exit(0);
		        }
            cout << "Switched Mcam" << "\n";
            }
        }
        else{
            ; // Do nothing
        }

    }
}

<|endoftext|>