<commit_before>#include "ImageClassificationNetwork.hpp"
#include "FAST/Data/Image.hpp"
#include <FAST/Data/Text.hpp>

namespace fast {

ImageClassificationNetwork::ImageClassificationNetwork() {
	createOutputPort<ImageClassification>(0);
	createStringAttribute("labels", "Labels", "Name of each class", "");
}

void ImageClassificationNetwork::setLabels(std::vector<std::string> labels) {
	mLabels = labels;
}

void ImageClassificationNetwork::execute() {

    run();

    auto tensor = std::dynamic_pointer_cast<Tensor>(m_processedOutputData[0]);
    auto access = tensor->getAccess(ACCESS_READ);

    auto data = access->getData<2>();
    auto output = getOutputData<ImageClassification>(0);
    for(int i = 0; i < data.dimension(0); ++i) { // for each input image
        std::map<std::string, float> mapResult;
        for(int j = 0; j < data.dimension(1); ++j) { // for each class
            mapResult[mLabels[j]] = data(i, j);
            reportInfo() << mLabels[j] << ": " << data(i, j) << reportEnd();
        }

        output->create(mapResult);
    }
}

void ImageClassificationNetwork::loadAttributes() {
	NeuralNetwork::loadAttributes();
	setLabels(getStringListAttribute("labels"));
}

ClassificationToText::ClassificationToText() {
    createInputPort<ImageClassification>(0);
    createOutputPort<Text>(0);
    createIntegerAttribute("average_size", "Average size", "nr of frames to average", 100);
}

void ClassificationToText::loadAttributes() {
    mBufferSize = getIntegerAttribute("average_size");
}

void ClassificationToText::execute() {
    ImageClassification::pointer classification = getInputData<ImageClassification>();
    Text::pointer text = getOutputData<Text>();

    ImageClassification::access access = classification->getAccess(ACCESS_READ);
    std::map<std::string, float> values = access->getData();

    // Add to buffer
    mBuffer.push_back(values);

    // Remove item from buffer
    if(mBuffer.size() > mBufferSize)
        mBuffer.pop_front();

    // Calculate average
    for(auto&& val : values)
       val.second = 0;

    // Sum
    for(auto sample : mBuffer) {
        for(auto val : sample) {
            values[val.first] += val.second;
        }
    }
    // Divide
    for(auto&& val : values) {
        val.second /= mBuffer.size();
    }

    // Find classification with max
    float max = 0;
    std::string label;
    for (auto &&item : values) {
        if(item.second > max) {
            max = item.second;
            label = item.first;
        }
    }

    char buffer[8];
    std::sprintf(buffer, "%.2f", max);
    std::string result = label + ": " + buffer;
    text->setText(result);
}

}
<commit_msg>Fixed ImageClassificationNetwork for new tensor setup<commit_after>#include "ImageClassificationNetwork.hpp"
#include "FAST/Data/Image.hpp"
#include <FAST/Data/Text.hpp>

namespace fast {

ImageClassificationNetwork::ImageClassificationNetwork() {
	createOutputPort<ImageClassification>(0);
	createStringAttribute("labels", "Labels", "Name of each class", "");
}

void ImageClassificationNetwork::setLabels(std::vector<std::string> labels) {
	mLabels = labels;
}

void ImageClassificationNetwork::execute() {

    run();

    // TODO batch support
    auto tensor = std::dynamic_pointer_cast<Tensor>(m_processedOutputData[0]);
    if(!tensor)
        throw Exception("ImageClassificationNetwork batch support not implemented");
    auto access = tensor->getAccess(ACCESS_READ);
    std::cout << tensor->getShape().toString() << std::endl;

    auto data = access->getData<1>();
    auto output = getOutputData<ImageClassification>(0);
	std::map<std::string, float> mapResult;
	for(int j = 0; j < data.dimension(0); ++j) { // for each class
		mapResult[mLabels[j]] = data(j);
		reportInfo() << mLabels[j] << ": " << data(j) << reportEnd();
	}

	output->create(mapResult);
}

void ImageClassificationNetwork::loadAttributes() {
	NeuralNetwork::loadAttributes();
	setLabels(getStringListAttribute("labels"));
}

ClassificationToText::ClassificationToText() {
    createInputPort<ImageClassification>(0);
    createOutputPort<Text>(0);
    createIntegerAttribute("average_size", "Average size", "nr of frames to average", 100);
}

void ClassificationToText::loadAttributes() {
    mBufferSize = getIntegerAttribute("average_size");
}

void ClassificationToText::execute() {
    ImageClassification::pointer classification = getInputData<ImageClassification>();
    Text::pointer text = getOutputData<Text>();

    ImageClassification::access access = classification->getAccess(ACCESS_READ);
    std::map<std::string, float> values = access->getData();

    // Add to buffer
    mBuffer.push_back(values);

    // Remove item from buffer
    if(mBuffer.size() > mBufferSize)
        mBuffer.pop_front();

    // Calculate average
    for(auto&& val : values)
       val.second = 0;

    // Sum
    for(auto sample : mBuffer) {
        for(auto val : sample) {
            values[val.first] += val.second;
        }
    }
    // Divide
    for(auto&& val : values) {
        val.second /= mBuffer.size();
    }

    // Find classification with max
    float max = 0;
    std::string label;
    for (auto &&item : values) {
        if(item.second > max) {
            max = item.second;
            label = item.first;
        }
    }

    char buffer[8];
    std::sprintf(buffer, "%.2f", max);
    std::string result = label + ": " + buffer;
    text->setText(result);
}

}
<|endoftext|>


<commit_before>/*
    This file is part of KOrganizer.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    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 General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "history.h"

#include <libkcal/calendar.h>
#include <libkcal/incidence.h>

#include <klocale.h>
#include <kdebug.h>

using namespace KCal;
using namespace KOrg;

History::History( KCal::Calendar *calendar )
  : mCalendar( calendar ), mCurrentMultiEntry( 0 ),
    mUndoEntry( mEntries ), mRedoEntry( mEntries )
{
  mEntries.setAutoDelete( true );
}

void History::undo()
{
  if ( mCurrentMultiEntry ) mCurrentMultiEntry = 0;
  Entry *entry = mUndoEntry.current();
  if ( !entry ) return;

  entry->undo();
  emit undone();

  emit redoAvailable( entry->text() );

  mRedoEntry = mUndoEntry;
  --mUndoEntry;

  entry = mUndoEntry.current();
  if ( entry ) emit undoAvailable( entry->text() );
  else emit undoAvailable( QString::null );
}

void History::redo()
{
  if ( mCurrentMultiEntry ) mCurrentMultiEntry = 0;
  Entry *entry = mRedoEntry.current();
  if ( !entry ) return;

  emit undoAvailable( entry->text() );

  entry->redo();
  emit redone();

  mUndoEntry = mRedoEntry;
  ++mRedoEntry;

  entry = mRedoEntry.current();
  if ( entry ) emit redoAvailable( entry->text() );
  else emit redoAvailable( QString::null );
}

void History::truncate()
{
  while ( mUndoEntry.current() != mEntries.last() ) {
    mEntries.removeLast();
  }
  mRedoEntry = QPtrList<Entry>( mEntries );
  emit redoAvailable( QString::null );
}

void History::recordDelete( Incidence *incidence )
{
  Entry *entry = new EntryDelete( mCalendar, incidence );
  if (mCurrentMultiEntry) {
    mCurrentMultiEntry->appendEntry( entry );
  } else {
    truncate();
    mEntries.append( entry );
    mUndoEntry.toLast();
    mRedoEntry = QPtrList<Entry>( mEntries );
    emit undoAvailable( entry->text() );
  }
}

void History::recordAdd( Incidence *incidence )
{
  Entry *entry = new EntryAdd( mCalendar, incidence );
  if (mCurrentMultiEntry) {
    mCurrentMultiEntry->appendEntry( entry );
  } else {
    truncate();
    mEntries.append( entry );
    mUndoEntry.toLast();
    mRedoEntry = QPtrList<Entry>( mEntries );
    emit undoAvailable( entry->text() );
  }
}

void History::recordEdit( Incidence *oldIncidence, Incidence *newIncidence )
{
  Entry *entry = new EntryEdit( mCalendar, oldIncidence, newIncidence );
  if (mCurrentMultiEntry) {
    mCurrentMultiEntry->appendEntry( entry );
  } else {
    truncate();
    mEntries.append( entry );
    mUndoEntry.toLast();
    mRedoEntry = QPtrList<Entry>( mEntries );
    emit undoAvailable( entry->text() );
  }
}

void History::startMultiModify( const QString &description )
{
  if ( mCurrentMultiEntry ) {
    endMultiModify();
  }
  mCurrentMultiEntry = new MultiEntry( mCalendar, description );
  truncate();
  mEntries.append( mCurrentMultiEntry );
  mUndoEntry.toLast();
  mRedoEntry = QPtrList<Entry>( mEntries );
  emit undoAvailable( mCurrentMultiEntry->text() );
}

void History::endMultiModify()
{
  mCurrentMultiEntry = 0;
}

History::Entry::Entry( KCal::Calendar *calendar )
  : mCalendar( calendar )
{
}

History::Entry::~Entry()
{
}

History::EntryDelete::EntryDelete( Calendar *calendar, Incidence *incidence )
  : Entry( calendar ), mIncidence( incidence->clone() )
{
}

History::EntryDelete::~EntryDelete()
{
  delete mIncidence;
}

void History::EntryDelete::undo()
{
  mCalendar->addIncidence( mIncidence->clone() );
}

void History::EntryDelete::redo()
{
  Incidence *incidence = mCalendar->incidence( mIncidence->uid() );
  mCalendar->deleteIncidence( incidence );
}

QString History::EntryDelete::text()
{
  return i18n("Delete %1").arg(mIncidence->type());
}

History::EntryAdd::EntryAdd( Calendar *calendar, Incidence *incidence )
  : Entry( calendar ), mIncidence( incidence->clone() )
{
}

History::EntryAdd::~EntryAdd()
{
  delete mIncidence;
}

void History::EntryAdd::undo()
{
  Incidence *incidence = mCalendar->incidence( mIncidence->uid() );
  mCalendar->deleteIncidence( incidence );
}

void History::EntryAdd::redo()
{
  mCalendar->addIncidence( mIncidence->clone() );
}

QString History::EntryAdd::text()
{
  return i18n("Add %1").arg(mIncidence->type());
}

History::EntryEdit::EntryEdit( Calendar *calendar, Incidence *oldIncidence,
                               Incidence *newIncidence )
  : Entry( calendar ), mOldIncidence( oldIncidence->clone() ),
    mNewIncidence( newIncidence->clone() )
{
}

History::EntryEdit::~EntryEdit()
{
  delete mOldIncidence;
  delete mNewIncidence;
}

void History::EntryEdit::undo()
{
  Incidence *incidence = mCalendar->incidence( mNewIncidence->uid() );
  if ( incidence )
      mCalendar->deleteIncidence( incidence );
  mCalendar->addIncidence( mOldIncidence->clone() );
}

void History::EntryEdit::redo()
{
  Incidence *incidence = mCalendar->incidence( mOldIncidence->uid() );
  if ( incidence )
      mCalendar->deleteIncidence( incidence );
  mCalendar->addIncidence( mNewIncidence->clone() );
}

QString History::EntryEdit::text()
{
  return i18n("Edit %1").arg(mNewIncidence->type());
}

History::MultiEntry::MultiEntry( Calendar *calendar, QString text )
  : Entry( calendar ), mText( text )
{
  mEntries.setAutoDelete( true );
}

History::MultiEntry::~MultiEntry()
{
}

void History::MultiEntry::appendEntry( Entry* entry )
{
  mEntries.append( entry );
}

void History::MultiEntry::undo()
{
  QPtrListIterator<Entry> it( mEntries );
  it.toLast();
  Entry *entry;
  while ( (entry = it.current()) != 0 ) {
    --it;
    entry->undo();
  }
}

void History::MultiEntry::redo()
{
  QPtrListIterator<Entry> it( mEntries );
  Entry *entry;
  while ( (entry = it.current()) != 0 ) {
    ++it;
    entry->redo();
  }
}

QString History::MultiEntry::text()
{
  return mText;
}

#include "history.moc"
<commit_msg>backport CVS commit by tokoe:<commit_after>/*
    This file is part of KOrganizer.

    Copyright (c) 2003 Cornelius Schumacher <schumacher@kde.org>

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    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 General Public License
    along with this program; if not, write to the Free Software
    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.

    As a special exception, permission is given to link this program
    with any edition of Qt, and distribute the resulting executable,
    without including the source code for Qt in the source distribution.
*/

#include "history.h"

#include <libkcal/calendar.h>
#include <libkcal/incidence.h>

#include <klocale.h>
#include <kdebug.h>

using namespace KCal;
using namespace KOrg;

History::History( KCal::Calendar *calendar )
  : mCalendar( calendar ), mCurrentMultiEntry( 0 ),
    mUndoEntry( mEntries ), mRedoEntry( mEntries )
{
  mEntries.setAutoDelete( true );
}

void History::undo()
{
  if ( mCurrentMultiEntry ) mCurrentMultiEntry = 0;
  Entry *entry = mUndoEntry.current();
  if ( !entry ) return;

  entry->undo();
  emit undone();

  emit redoAvailable( entry->text() );

  mRedoEntry = mUndoEntry;
  --mUndoEntry;

  entry = mUndoEntry.current();
  if ( entry ) emit undoAvailable( entry->text() );
  else emit undoAvailable( QString::null );
}

void History::redo()
{
  if ( mCurrentMultiEntry ) mCurrentMultiEntry = 0;
  Entry *entry = mRedoEntry.current();
  if ( !entry ) return;

  emit undoAvailable( entry->text() );

  entry->redo();
  emit redone();

  mUndoEntry = mRedoEntry;
  ++mRedoEntry;

  entry = mRedoEntry.current();
  if ( entry ) emit redoAvailable( entry->text() );
  else emit redoAvailable( QString::null );
}

void History::truncate()
{
  while ( mUndoEntry.current() != mEntries.last() ) {
    mEntries.removeLast();
  }
  mRedoEntry = QPtrList<Entry>( mEntries );
  emit redoAvailable( QString::null );
}

void History::recordDelete( Incidence *incidence )
{
  Entry *entry = new EntryDelete( mCalendar, incidence );
  if (mCurrentMultiEntry) {
    mCurrentMultiEntry->appendEntry( entry );
  } else {
    truncate();
    mEntries.append( entry );
    mUndoEntry.toLast();
    mRedoEntry = QPtrList<Entry>( mEntries );
    emit undoAvailable( entry->text() );
  }
}

void History::recordAdd( Incidence *incidence )
{
  Entry *entry = new EntryAdd( mCalendar, incidence );
  if (mCurrentMultiEntry) {
    mCurrentMultiEntry->appendEntry( entry );
  } else {
    truncate();
    mEntries.append( entry );
    mUndoEntry.toLast();
    mRedoEntry = QPtrList<Entry>( mEntries );
    emit undoAvailable( entry->text() );
  }
}

void History::recordEdit( Incidence *oldIncidence, Incidence *newIncidence )
{
  Entry *entry = new EntryEdit( mCalendar, oldIncidence, newIncidence );
  if (mCurrentMultiEntry) {
    mCurrentMultiEntry->appendEntry( entry );
  } else {
    truncate();
    mEntries.append( entry );
    mUndoEntry.toLast();
    mRedoEntry = QPtrList<Entry>( mEntries );
    emit undoAvailable( entry->text() );
  }
}

void History::startMultiModify( const QString &description )
{
  if ( mCurrentMultiEntry ) {
    endMultiModify();
  }
  mCurrentMultiEntry = new MultiEntry( mCalendar, description );
  truncate();
  mEntries.append( mCurrentMultiEntry );
  mUndoEntry.toLast();
  mRedoEntry = QPtrList<Entry>( mEntries );
  emit undoAvailable( mCurrentMultiEntry->text() );
}

void History::endMultiModify()
{
  mCurrentMultiEntry = 0;
}

History::Entry::Entry( KCal::Calendar *calendar )
  : mCalendar( calendar )
{
}

History::Entry::~Entry()
{
}

History::EntryDelete::EntryDelete( Calendar *calendar, Incidence *incidence )
  : Entry( calendar ), mIncidence( incidence->clone() )
{
}

History::EntryDelete::~EntryDelete()
{
  delete mIncidence;
}

void History::EntryDelete::undo()
{
  mCalendar->addIncidence( mIncidence->clone() );
}

void History::EntryDelete::redo()
{
  Incidence *incidence = mCalendar->incidence( mIncidence->uid() );
  mCalendar->deleteIncidence( incidence );
}

QString History::EntryDelete::text()
{
  return i18n("Delete %1").arg(mIncidence->type());
}

History::EntryAdd::EntryAdd( Calendar *calendar, Incidence *incidence )
  : Entry( calendar ), mIncidence( incidence->clone() )
{
}

History::EntryAdd::~EntryAdd()
{
  delete mIncidence;
}

void History::EntryAdd::undo()
{
  Incidence *incidence = mCalendar->incidence( mIncidence->uid() );
  if ( incidence )
    mCalendar->deleteIncidence( incidence );
}

void History::EntryAdd::redo()
{
  mCalendar->addIncidence( mIncidence->clone() );
}

QString History::EntryAdd::text()
{
  return i18n("Add %1").arg(mIncidence->type());
}

History::EntryEdit::EntryEdit( Calendar *calendar, Incidence *oldIncidence,
                               Incidence *newIncidence )
  : Entry( calendar ), mOldIncidence( oldIncidence->clone() ),
    mNewIncidence( newIncidence->clone() )
{
}

History::EntryEdit::~EntryEdit()
{
  delete mOldIncidence;
  delete mNewIncidence;
}

void History::EntryEdit::undo()
{
  Incidence *incidence = mCalendar->incidence( mNewIncidence->uid() );
  if ( incidence )
      mCalendar->deleteIncidence( incidence );
  mCalendar->addIncidence( mOldIncidence->clone() );
}

void History::EntryEdit::redo()
{
  Incidence *incidence = mCalendar->incidence( mOldIncidence->uid() );
  if ( incidence )
      mCalendar->deleteIncidence( incidence );
  mCalendar->addIncidence( mNewIncidence->clone() );
}

QString History::EntryEdit::text()
{
  return i18n("Edit %1").arg(mNewIncidence->type());
}

History::MultiEntry::MultiEntry( Calendar *calendar, QString text )
  : Entry( calendar ), mText( text )
{
  mEntries.setAutoDelete( true );
}

History::MultiEntry::~MultiEntry()
{
}

void History::MultiEntry::appendEntry( Entry* entry )
{
  mEntries.append( entry );
}

void History::MultiEntry::undo()
{
  QPtrListIterator<Entry> it( mEntries );
  it.toLast();
  Entry *entry;
  while ( (entry = it.current()) != 0 ) {
    --it;
    entry->undo();
  }
}

void History::MultiEntry::redo()
{
  QPtrListIterator<Entry> it( mEntries );
  Entry *entry;
  while ( (entry = it.current()) != 0 ) {
    ++it;
    entry->redo();
  }
}

QString History::MultiEntry::text()
{
  return mText;
}

#include "history.moc"
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: FrameworkHelper.hxx,v $
 *
 *  $Revision: 1.5 $
 *
 *  last change: $Author: kz $ $Date: 2008-04-03 14:03:05 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library 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
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef SD_FRAMEWORK_FRAMEWORK_HELPER_HXX
#define SD_FRAMEWORK_FRAMEWORK_HELPER_HXX

#include "ViewShell.hxx"

#include "tools/SdGlobalResourceContainer.hxx"

#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
#include <com/sun/star/drawing/framework/XView.hpp>
#include <com/sun/star/lang/XEventListener.hpp>

#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/function.hpp>
#include <map>

namespace sd {
class ViewShell;
class ViewShellBase;
}

namespace rtl {
class OUString;
}

namespace css = ::com::sun::star;

namespace sd { namespace framework {

/** The FrameworkHelper is a convenience class that simplifies the
    access to the drawing framework.
    It has three main tasks:
    1. Provide frequently used strings of resource URLs and event names.
    2. Provide shortcuts for accessing the sd framework.
    3. Easy the migration to the drawing framwork.

    Note that a FrameworkHelper disposes itself when one of the resource
    controllers called by it throw a DisposedException.
*/
class FrameworkHelper
    : public ::boost::enable_shared_from_this<FrameworkHelper>,
      public SdGlobalResource
{
public:
    // URLs of frequently used panes.
    static const ::rtl::OUString msPaneURLPrefix;
    static const ::rtl::OUString msCenterPaneURL;
    static const ::rtl::OUString msFullScreenPaneURL;
    static const ::rtl::OUString msLeftImpressPaneURL;
    static const ::rtl::OUString msLeftDrawPaneURL;
    static const ::rtl::OUString msRightPaneURL;

    // URLs of frequently used views.
    static const ::rtl::OUString msViewURLPrefix;
    static const ::rtl::OUString msImpressViewURL;
    static const ::rtl::OUString msDrawViewURL;
    static const ::rtl::OUString msOutlineViewURL;
    static const ::rtl::OUString msNotesViewURL;
    static const ::rtl::OUString msHandoutViewURL;
    static const ::rtl::OUString msSlideSorterURL;
    static const ::rtl::OUString msPresentationViewURL;
    static const ::rtl::OUString msTaskPaneURL;

    // URLs of frequently used tool bars.
    static const ::rtl::OUString msToolBarURLPrefix;
    static const ::rtl::OUString msViewTabBarURL;

    // URLs of task panels.
    static const ::rtl::OUString msTaskPanelURLPrefix;
    static const ::rtl::OUString msMasterPagesTaskPanelURL;
    static const ::rtl::OUString msLayoutTaskPanelURL;
    static const ::rtl::OUString msTableDesignPanelURL;
    static const ::rtl::OUString msCustomAnimationTaskPanelURL;
    static const ::rtl::OUString msSlideTransitionTaskPanelURL;

    // Names of frequently used events.
    static const ::rtl::OUString msResourceActivationRequestEvent;
    static const ::rtl::OUString msResourceDeactivationRequestEvent;
    static const ::rtl::OUString msResourceActivationEvent;
    static const ::rtl::OUString msResourceDeactivationEvent;
    static const ::rtl::OUString msConfigurationUpdateStartEvent;
    static const ::rtl::OUString msConfigurationUpdateEndEvent;

    // Service names of the common controllers.
    static const ::rtl::OUString msModuleControllerService;
    static const ::rtl::OUString msConfigurationControllerService;

    /** Return the FrameworkHelper object that is associated with the given
        ViewShellBase.  If such an object does not yet exist, a new one is
        created.
    */
    static ::boost::shared_ptr<FrameworkHelper> Instance (ViewShellBase& rBase);

    static ::boost::shared_ptr<FrameworkHelper> Instance (
        const css::uno::Reference<css::frame::XController>& rxController);

    /** Mark the FrameworkHelper object for the given ViewShellBase as
        disposed.  A following ReleaseInstance() call will destroy the
        FrameworkHelper object.

        Do not call this method.  It is an internally used method that can
        not be made private.
    */
    static void DisposeInstance (ViewShellBase& rBase);

    /** Destroy the FrameworkHelper object for the given ViewShellBase.

        Do not call this method.  It is an internally used method that can
        not be made private.
    */
    static void ReleaseInstance (ViewShellBase& rBase);

    /** Return an identifier for the given view URL.  This identifier can be
        used in a switch statement.  See GetViewURL() for a mapping in the
        opposite direction.
    */
    static ViewShell::ShellType GetViewId (const rtl::OUString& rsViewURL);

    /** Return a view URL for the given identifier.  See GetViewId() for a
        mapping in the opposite direction.
    */
    static ::rtl::OUString GetViewURL (ViewShell::ShellType eType);

    /** Return a ViewShell pointer for the given XView reference.  This
        assumes that the given reference is implemented by the
        ViewShellWrapper class that supports the XTunnel interface.
        @return
            When the ViewShell pointer can not be inferred from the given
            reference then an empty pointer is returned.
    */
    static ::boost::shared_ptr<ViewShell> GetViewShell (
        const css::uno::Reference<css::drawing::framework::XView>& rxView);

    ~FrameworkHelper (void);

    typedef ::boost::function<bool(const css::drawing::framework::ConfigurationChangeEvent&)>
        ConfigurationChangeEventFilter;
    typedef ::boost::function<void(bool bEventSeen)> Callback;
    typedef ::boost::function<
        void(
            const css::uno::Reference<
                css::drawing::framework::XResourceId>&)
        > ResourceFunctor;

    /** Test whether the called FrameworkHelper object is valid.
        @return
            When the object has already been disposed then <FALSE/> is returned.
    */
    bool IsValid (void);

    /** Return a pointer to the view shell that is displayed in the
        specified pane.  See GetView() for a variant that returns a
        reference to XView instead of a ViewShell pointer.
        @return
            An empty pointer is returned when for example the specified pane
            does not exist or is not visible or does not show a view or one
            of the involved objects does not support XUnoTunnel (where
            necessary).
    */
    ::boost::shared_ptr<ViewShell> GetViewShell (const ::rtl::OUString& rsPaneURL);

    /** Return a reference to the view that is displayed in the specified
        pane.  See GetViewShell () for a variant that returns a ViewShell
        pointer instead of a reference to XView.
        @param rxPaneOrViewId
            When this ResourceId specifies a view then that view is
            returned.  When it belongs to a pane then one view in that pane
            is returned.
        @return
            An empty reference is returned when for example the specified pane
            does not exist or is not visible or does not show a view or one
            of the involved objects does not support XTunnel (where
            necessary).
    */
    css::uno::Reference<css::drawing::framework::XView>
        GetView (
            const css::uno::Reference<
                css::drawing::framework::XResourceId>& rxPaneOrViewId);

    /** Request the specified view to be displayed in the specified pane.
        When the pane is not visible its creation is also requested.  The
        update that creates the actual view object is done asynchronously.
        @param rsResourceURL
            The resource URL of the view to show.
        @param rsAnchorURL
            The URL of the pane in which to show the view.
    */
    void RequestView (
        const ::rtl::OUString& rsResourceURL,
        const ::rtl::OUString& rsAnchorURL);

    /** Request the activation of the specified task panel in the standard
        task pane.
    */
    void RequestTaskPanel (
        const ::rtl::OUString& rsTaskPanelURL);

    /** Process a slot call that requests a view shell change.
    */
    void HandleModeChangeSlot (
        ULONG nSlotId,
        SfxRequest& rRequest);

    /** Run the given callback when the specified event is notified by the
        ConfigurationManager.  When there are no pending requests and
        therefore no events would be notified (in the foreseeable future)
        then the callback is called immediately.
        The callback is called with a flag that tells the callback whether
        the event it waits for has been sent.
    */
    void RunOnConfigurationEvent(
        const ::rtl::OUString& rsEventType,
        const Callback& rCallback);

    /** Run the given callback when the specified resource has been
        activated.  When the resource is active already when this method is
        called then rCallback is called before this method returns.
        @param rxResourceId
            Wait for the activation of this resource before calling
            rCallback.
        @param rCallback
            The callback to be called when the resource is activated.

    */
    void RunOnResourceActivation(
        const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId,
        const Callback& rCallback);

    /** Block until the specified event is notified by the configuration
        controller.  When the configuration controller is not processing any
        requests the method returns immediately.
    */
    void WaitForEvent (const ::rtl::OUString& rsEventName) const;

    /** This is a short cut for WaitForEvent(msConfigurationUpdateEndEvent).
        Call this method to execute the pending requests.
    */
    void WaitForUpdate (void) const;

    /** Explicit request for an update of the current configuration.  Call
        this method when one of the resources managed by the sd framework
        has been activated or deactivated from the outside, i.e. not by the
        framework itself.  An example for this is a click on the closer
        button of one of the side panes.
    */
    void UpdateConfiguration (void);

    /** Return a string representation of the given XResourceId object.
    */
    static ::rtl::OUString ResourceIdToString (
        const css::uno::Reference<
            css::drawing::framework::XResourceId>& rxResourceId);

    /** Create a new XResourceId object for the given resource URL.
    */
    static css::uno::Reference<
        css::drawing::framework::XResourceId>
            CreateResourceId (
                const ::rtl::OUString& rsResourceURL);

    /** Create a new XResourceId object for the given resource URL and a
        single anchor URL.
    */
    static css::uno::Reference<
        css::drawing::framework::XResourceId>
            CreateResourceId (
                const ::rtl::OUString& rsResourceURL,
                const ::rtl::OUString& rsAnchorURL);

    /** Create a new XResourceId object for the given resource URL and the
        two given anchor URLs.
    */
    static css::uno::Reference<
        css::drawing::framework::XResourceId>
            CreateResourceId (
                const ::rtl::OUString& rsResourceURL,
                const ::rtl::OUString& rsFirstAnchorURL,
                const ::rtl::OUString& rsSecondAnchorURL);

    /** Create a new XResourceId object for the given resource URL.
    */
    static css::uno::Reference<
        css::drawing::framework::XResourceId>
            CreateResourceId (
                const ::rtl::OUString& rsResourceURL,
                const css::uno::Reference<
                    css::drawing::framework::XResourceId>& rxAnchor);

    css::uno::Reference<css::drawing::framework::XConfigurationController>
        GetConfigurationController (void) const;

private:
    typedef ::std::map<
        ViewShellBase*,
        ::boost::shared_ptr<FrameworkHelper> > InstanceMap;
    /** The instance map holds (at least) one FrameworkHelper instance for
        every ViewShellBase object.
    */
    static InstanceMap maInstanceMap;
    class ViewURLMap;
    static ::boost::scoped_ptr<ViewURLMap> mpViewURLMap;

    ViewShellBase& mrBase;
    css::uno::Reference<css::drawing::framework::XConfigurationController>
        mxConfigurationController;

    class DisposeListener;
    friend class DisposeListener;
    css::uno::Reference<css::lang::XComponent>
        mxDisposeListener;

    FrameworkHelper (ViewShellBase& rBase);
    FrameworkHelper (const FrameworkHelper& rHelper); // Not implemented.
    FrameworkHelper& operator= (const FrameworkHelper& rHelper); // Not implemented.

    void Initialize (void);

    void Dispose (void);

    /** Run the given callback when an event of the specified type is
        received from the ConfigurationController or when the
        ConfigurationController has no pending change requests.
        @param rsEventType
            Run rCallback only on this event.
        @param rFilter
            This filter has to return <TRUE/> in order for rCallback to be
            called.
        @param rCallback
            The callback functor to be called.
    */
    void RunOnEvent(
        const ::rtl::OUString& rsEventType,
        const ConfigurationChangeEventFilter& rFilter,
        const Callback& rCallback) const;

    /** This disposing method is forwarded from the inner DisposeListener class.
    */
    void disposing (const css::lang::EventObject& rEventObject);
};

/** This functor wraps a slot call.  It is used to call a slot after an
    asynchronous configuration update, eg after switching views.
*/
class DispatchCaller
{
    SfxDispatcher& mrDispatcher;
    USHORT mnSId;
public:
    /** Create a new DispatchCaller object that, when executed, will call
        the given slot at the given dispatcher.
    */
    DispatchCaller(SfxDispatcher& rDispatcher, USHORT nSId);
    void operator() (bool bEventSeen);
};

} } // end of namespace sd::framework

namespace sd { namespace framework {

namespace {

    class FrameworkHelperAllPassFilter
    {
    public:
        bool operator() (const css::drawing::framework::ConfigurationChangeEvent&) { return true; }
    };

    class FrameworkHelperResourceIdFilter
    {
    public:
        FrameworkHelperResourceIdFilter (
            const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId);
        bool operator() (const css::drawing::framework::ConfigurationChangeEvent& rEvent)
        { return mxResourceId.is() && rEvent.ResourceId.is()
                && mxResourceId->compareTo(rEvent.ResourceId) == 0; }
    private:
        css::uno::Reference<css::drawing::framework::XResourceId> mxResourceId;
    };

} // end of anonymous namespace

} } // end of namespace sd::framework

#endif
<commit_msg>INTEGRATION: CWS changefileheader (1.4.12); FILE MERGED 2008/04/01 12:39:10 thb 1.4.12.2: #i85898# Stripping all external header guards 2008/03/31 13:58:38 rt 1.4.12.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: FrameworkHelper.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org 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 Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef SD_FRAMEWORK_FRAMEWORK_HELPER_HXX
#define SD_FRAMEWORK_FRAMEWORK_HELPER_HXX

#include "ViewShell.hxx"

#include "tools/SdGlobalResourceContainer.hxx"

#include <com/sun/star/drawing/framework/XConfigurationController.hpp>
#include <com/sun/star/drawing/framework/XView.hpp>
#include <com/sun/star/lang/XEventListener.hpp>

#include <boost/scoped_ptr.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/function.hpp>
#include <map>

namespace sd {
class ViewShell;
class ViewShellBase;
}

namespace rtl {
class OUString;
}

namespace css = ::com::sun::star;

namespace sd { namespace framework {

/** The FrameworkHelper is a convenience class that simplifies the
    access to the drawing framework.
    It has three main tasks:
    1. Provide frequently used strings of resource URLs and event names.
    2. Provide shortcuts for accessing the sd framework.
    3. Easy the migration to the drawing framwork.

    Note that a FrameworkHelper disposes itself when one of the resource
    controllers called by it throw a DisposedException.
*/
class FrameworkHelper
    : public ::boost::enable_shared_from_this<FrameworkHelper>,
      public SdGlobalResource
{
public:
    // URLs of frequently used panes.
    static const ::rtl::OUString msPaneURLPrefix;
    static const ::rtl::OUString msCenterPaneURL;
    static const ::rtl::OUString msFullScreenPaneURL;
    static const ::rtl::OUString msLeftImpressPaneURL;
    static const ::rtl::OUString msLeftDrawPaneURL;
    static const ::rtl::OUString msRightPaneURL;

    // URLs of frequently used views.
    static const ::rtl::OUString msViewURLPrefix;
    static const ::rtl::OUString msImpressViewURL;
    static const ::rtl::OUString msDrawViewURL;
    static const ::rtl::OUString msOutlineViewURL;
    static const ::rtl::OUString msNotesViewURL;
    static const ::rtl::OUString msHandoutViewURL;
    static const ::rtl::OUString msSlideSorterURL;
    static const ::rtl::OUString msPresentationViewURL;
    static const ::rtl::OUString msTaskPaneURL;

    // URLs of frequently used tool bars.
    static const ::rtl::OUString msToolBarURLPrefix;
    static const ::rtl::OUString msViewTabBarURL;

    // URLs of task panels.
    static const ::rtl::OUString msTaskPanelURLPrefix;
    static const ::rtl::OUString msMasterPagesTaskPanelURL;
    static const ::rtl::OUString msLayoutTaskPanelURL;
    static const ::rtl::OUString msTableDesignPanelURL;
    static const ::rtl::OUString msCustomAnimationTaskPanelURL;
    static const ::rtl::OUString msSlideTransitionTaskPanelURL;

    // Names of frequently used events.
    static const ::rtl::OUString msResourceActivationRequestEvent;
    static const ::rtl::OUString msResourceDeactivationRequestEvent;
    static const ::rtl::OUString msResourceActivationEvent;
    static const ::rtl::OUString msResourceDeactivationEvent;
    static const ::rtl::OUString msConfigurationUpdateStartEvent;
    static const ::rtl::OUString msConfigurationUpdateEndEvent;

    // Service names of the common controllers.
    static const ::rtl::OUString msModuleControllerService;
    static const ::rtl::OUString msConfigurationControllerService;

    /** Return the FrameworkHelper object that is associated with the given
        ViewShellBase.  If such an object does not yet exist, a new one is
        created.
    */
    static ::boost::shared_ptr<FrameworkHelper> Instance (ViewShellBase& rBase);

    static ::boost::shared_ptr<FrameworkHelper> Instance (
        const css::uno::Reference<css::frame::XController>& rxController);

    /** Mark the FrameworkHelper object for the given ViewShellBase as
        disposed.  A following ReleaseInstance() call will destroy the
        FrameworkHelper object.

        Do not call this method.  It is an internally used method that can
        not be made private.
    */
    static void DisposeInstance (ViewShellBase& rBase);

    /** Destroy the FrameworkHelper object for the given ViewShellBase.

        Do not call this method.  It is an internally used method that can
        not be made private.
    */
    static void ReleaseInstance (ViewShellBase& rBase);

    /** Return an identifier for the given view URL.  This identifier can be
        used in a switch statement.  See GetViewURL() for a mapping in the
        opposite direction.
    */
    static ViewShell::ShellType GetViewId (const rtl::OUString& rsViewURL);

    /** Return a view URL for the given identifier.  See GetViewId() for a
        mapping in the opposite direction.
    */
    static ::rtl::OUString GetViewURL (ViewShell::ShellType eType);

    /** Return a ViewShell pointer for the given XView reference.  This
        assumes that the given reference is implemented by the
        ViewShellWrapper class that supports the XTunnel interface.
        @return
            When the ViewShell pointer can not be inferred from the given
            reference then an empty pointer is returned.
    */
    static ::boost::shared_ptr<ViewShell> GetViewShell (
        const css::uno::Reference<css::drawing::framework::XView>& rxView);

    ~FrameworkHelper (void);

    typedef ::boost::function<bool(const css::drawing::framework::ConfigurationChangeEvent&)>
        ConfigurationChangeEventFilter;
    typedef ::boost::function<void(bool bEventSeen)> Callback;
    typedef ::boost::function<
        void(
            const css::uno::Reference<
                css::drawing::framework::XResourceId>&)
        > ResourceFunctor;

    /** Test whether the called FrameworkHelper object is valid.
        @return
            When the object has already been disposed then <FALSE/> is returned.
    */
    bool IsValid (void);

    /** Return a pointer to the view shell that is displayed in the
        specified pane.  See GetView() for a variant that returns a
        reference to XView instead of a ViewShell pointer.
        @return
            An empty pointer is returned when for example the specified pane
            does not exist or is not visible or does not show a view or one
            of the involved objects does not support XUnoTunnel (where
            necessary).
    */
    ::boost::shared_ptr<ViewShell> GetViewShell (const ::rtl::OUString& rsPaneURL);

    /** Return a reference to the view that is displayed in the specified
        pane.  See GetViewShell () for a variant that returns a ViewShell
        pointer instead of a reference to XView.
        @param rxPaneOrViewId
            When this ResourceId specifies a view then that view is
            returned.  When it belongs to a pane then one view in that pane
            is returned.
        @return
            An empty reference is returned when for example the specified pane
            does not exist or is not visible or does not show a view or one
            of the involved objects does not support XTunnel (where
            necessary).
    */
    css::uno::Reference<css::drawing::framework::XView>
        GetView (
            const css::uno::Reference<
                css::drawing::framework::XResourceId>& rxPaneOrViewId);

    /** Request the specified view to be displayed in the specified pane.
        When the pane is not visible its creation is also requested.  The
        update that creates the actual view object is done asynchronously.
        @param rsResourceURL
            The resource URL of the view to show.
        @param rsAnchorURL
            The URL of the pane in which to show the view.
    */
    void RequestView (
        const ::rtl::OUString& rsResourceURL,
        const ::rtl::OUString& rsAnchorURL);

    /** Request the activation of the specified task panel in the standard
        task pane.
    */
    void RequestTaskPanel (
        const ::rtl::OUString& rsTaskPanelURL);

    /** Process a slot call that requests a view shell change.
    */
    void HandleModeChangeSlot (
        ULONG nSlotId,
        SfxRequest& rRequest);

    /** Run the given callback when the specified event is notified by the
        ConfigurationManager.  When there are no pending requests and
        therefore no events would be notified (in the foreseeable future)
        then the callback is called immediately.
        The callback is called with a flag that tells the callback whether
        the event it waits for has been sent.
    */
    void RunOnConfigurationEvent(
        const ::rtl::OUString& rsEventType,
        const Callback& rCallback);

    /** Run the given callback when the specified resource has been
        activated.  When the resource is active already when this method is
        called then rCallback is called before this method returns.
        @param rxResourceId
            Wait for the activation of this resource before calling
            rCallback.
        @param rCallback
            The callback to be called when the resource is activated.

    */
    void RunOnResourceActivation(
        const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId,
        const Callback& rCallback);

    /** Block until the specified event is notified by the configuration
        controller.  When the configuration controller is not processing any
        requests the method returns immediately.
    */
    void WaitForEvent (const ::rtl::OUString& rsEventName) const;

    /** This is a short cut for WaitForEvent(msConfigurationUpdateEndEvent).
        Call this method to execute the pending requests.
    */
    void WaitForUpdate (void) const;

    /** Explicit request for an update of the current configuration.  Call
        this method when one of the resources managed by the sd framework
        has been activated or deactivated from the outside, i.e. not by the
        framework itself.  An example for this is a click on the closer
        button of one of the side panes.
    */
    void UpdateConfiguration (void);

    /** Return a string representation of the given XResourceId object.
    */
    static ::rtl::OUString ResourceIdToString (
        const css::uno::Reference<
            css::drawing::framework::XResourceId>& rxResourceId);

    /** Create a new XResourceId object for the given resource URL.
    */
    static css::uno::Reference<
        css::drawing::framework::XResourceId>
            CreateResourceId (
                const ::rtl::OUString& rsResourceURL);

    /** Create a new XResourceId object for the given resource URL and a
        single anchor URL.
    */
    static css::uno::Reference<
        css::drawing::framework::XResourceId>
            CreateResourceId (
                const ::rtl::OUString& rsResourceURL,
                const ::rtl::OUString& rsAnchorURL);

    /** Create a new XResourceId object for the given resource URL and the
        two given anchor URLs.
    */
    static css::uno::Reference<
        css::drawing::framework::XResourceId>
            CreateResourceId (
                const ::rtl::OUString& rsResourceURL,
                const ::rtl::OUString& rsFirstAnchorURL,
                const ::rtl::OUString& rsSecondAnchorURL);

    /** Create a new XResourceId object for the given resource URL.
    */
    static css::uno::Reference<
        css::drawing::framework::XResourceId>
            CreateResourceId (
                const ::rtl::OUString& rsResourceURL,
                const css::uno::Reference<
                    css::drawing::framework::XResourceId>& rxAnchor);

    css::uno::Reference<css::drawing::framework::XConfigurationController>
        GetConfigurationController (void) const;

private:
    typedef ::std::map<
        ViewShellBase*,
        ::boost::shared_ptr<FrameworkHelper> > InstanceMap;
    /** The instance map holds (at least) one FrameworkHelper instance for
        every ViewShellBase object.
    */
    static InstanceMap maInstanceMap;
    class ViewURLMap;
    static ::boost::scoped_ptr<ViewURLMap> mpViewURLMap;

    ViewShellBase& mrBase;
    css::uno::Reference<css::drawing::framework::XConfigurationController>
        mxConfigurationController;

    class DisposeListener;
    friend class DisposeListener;
    css::uno::Reference<css::lang::XComponent>
        mxDisposeListener;

    FrameworkHelper (ViewShellBase& rBase);
    FrameworkHelper (const FrameworkHelper& rHelper); // Not implemented.
    FrameworkHelper& operator= (const FrameworkHelper& rHelper); // Not implemented.

    void Initialize (void);

    void Dispose (void);

    /** Run the given callback when an event of the specified type is
        received from the ConfigurationController or when the
        ConfigurationController has no pending change requests.
        @param rsEventType
            Run rCallback only on this event.
        @param rFilter
            This filter has to return <TRUE/> in order for rCallback to be
            called.
        @param rCallback
            The callback functor to be called.
    */
    void RunOnEvent(
        const ::rtl::OUString& rsEventType,
        const ConfigurationChangeEventFilter& rFilter,
        const Callback& rCallback) const;

    /** This disposing method is forwarded from the inner DisposeListener class.
    */
    void disposing (const css::lang::EventObject& rEventObject);
};

/** This functor wraps a slot call.  It is used to call a slot after an
    asynchronous configuration update, eg after switching views.
*/
class DispatchCaller
{
    SfxDispatcher& mrDispatcher;
    USHORT mnSId;
public:
    /** Create a new DispatchCaller object that, when executed, will call
        the given slot at the given dispatcher.
    */
    DispatchCaller(SfxDispatcher& rDispatcher, USHORT nSId);
    void operator() (bool bEventSeen);
};

} } // end of namespace sd::framework

namespace sd { namespace framework {

namespace {

    class FrameworkHelperAllPassFilter
    {
    public:
        bool operator() (const css::drawing::framework::ConfigurationChangeEvent&) { return true; }
    };

    class FrameworkHelperResourceIdFilter
    {
    public:
        FrameworkHelperResourceIdFilter (
            const css::uno::Reference<css::drawing::framework::XResourceId>& rxResourceId);
        bool operator() (const css::drawing::framework::ConfigurationChangeEvent& rEvent)
        { return mxResourceId.is() && rEvent.ResourceId.is()
                && mxResourceId->compareTo(rEvent.ResourceId) == 0; }
    private:
        css::uno::Reference<css::drawing::framework::XResourceId> mxResourceId;
    };

} // end of anonymous namespace

} } // end of namespace sd::framework

#endif
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2009, Image Engine Design 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 Image Engine Design nor the names of any
//       other contributors to this software 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.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/python.hpp"

#include "IECore/Parameterised.h"
#include "IECore/CompoundParameter.h"
#include "IECore/bindings/RunTimeTypedBinding.h"
#include "IECore/bindings/Wrapper.h"

using namespace boost;
using namespace boost::python;

namespace IECore {

class ParameterisedWrap : public Parameterised, public Wrapper<Parameterised>
{
	public :
		ParameterisedWrap( PyObject *self, const std::string &name, const std::string &description ) : Parameterised( name, description ), Wrapper<Parameterised>( self, this ) {};
		ParameterisedWrap( PyObject *self, const std::string &name, const std::string &description, CompoundParameterPtr compoundParameter ) : Parameterised( name, description, compoundParameter ), Wrapper<Parameterised>( self, this ) {};
};
IE_CORE_DECLAREPTR( ParameterisedWrap );

static ParameterPtr parameterisedGetItem( Parameterised &o, const std::string &n )
{
	ParameterPtr p = o.parameters()->parameter<Parameter>( n );
	if( !p )
	{
		throw Exception( std::string("Parameter ") + n + " doesn't exist" );
	}
	return p;
}

static object parameterisedGetAttr( Parameterised &o, const std::string &n )
{
	ParameterPtr p = o.parameters()->parameter<Parameter>( n );

	if ( p )
	{
		if( PyErr_WarnEx( PyExc_DeprecationWarning, "Access to Parameters as attributes is deprecated - please use item style access instead.", 1 ) )
		{
			// warning converted to exception;
			throw error_already_set();
		}
		return object( p );
	}

	PyErr_SetString( PyExc_KeyError, ( "'"  + n + "'" ).c_str() );
	throw error_already_set();
}

void bindParameterised()
{
	using boost::python::arg;

	RunTimeTypedClass<Parameterised, ParameterisedWrapPtr>()
		.def( init< const std::string, const std::string>( ( arg( "name" ), arg( "description") ) ) )
		.def( init< const std::string, const std::string, CompoundParameterPtr >( ( arg( "name" ), arg( "description") , arg( "compoundParameter") ) ) )
		.add_property( "name", make_function( &Parameterised::name, return_value_policy<copy_const_reference>() ) )
		.add_property( "description", make_function( &Parameterised::description, return_value_policy<copy_const_reference>() ) )
		.def( "parameters", (CompoundParameterPtr (Parameterised::*)())&Parameterised::parameters )
		.def( "__getitem__", &parameterisedGetItem )
		/// \todo Remove this in major version 5.
		.def( "__getattr__", &parameterisedGetAttr )
		.def( "userData", (CompoundObjectPtr (Parameterised::*)())&Parameterised::userData )
	;

}

} // namespace IECore
<commit_msg>Fixed unintentional change to return type of function<commit_after>//////////////////////////////////////////////////////////////////////////
//
//  Copyright (c) 2007-2009, Image Engine Design 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 Image Engine Design nor the names of any
//       other contributors to this software 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.
//
//////////////////////////////////////////////////////////////////////////

#include "boost/python.hpp"

#include "IECore/Parameterised.h"
#include "IECore/CompoundParameter.h"
#include "IECore/bindings/RunTimeTypedBinding.h"
#include "IECore/bindings/Wrapper.h"

using namespace boost;
using namespace boost::python;

namespace IECore {

class ParameterisedWrap : public Parameterised, public Wrapper<Parameterised>
{
	public :
		ParameterisedWrap( PyObject *self, const std::string &name, const std::string &description ) : Parameterised( name, description ), Wrapper<Parameterised>( self, this ) {};
		ParameterisedWrap( PyObject *self, const std::string &name, const std::string &description, CompoundParameterPtr compoundParameter ) : Parameterised( name, description, compoundParameter ), Wrapper<Parameterised>( self, this ) {};
};
IE_CORE_DECLAREPTR( ParameterisedWrap );

static ParameterPtr parameterisedGetItem( Parameterised &o, const std::string &n )
{
	ParameterPtr p = o.parameters()->parameter<Parameter>( n );
	if( !p )
	{
		throw Exception( std::string("Parameter ") + n + " doesn't exist" );
	}
	return p;
}

static ParameterPtr parameterisedGetAttr( Parameterised &o, const std::string &n )
{
	ParameterPtr p = o.parameters()->parameter<Parameter>( n );

	if ( p )
	{
		if( PyErr_WarnEx( PyExc_DeprecationWarning, "Access to Parameters as attributes is deprecated - please use item style access instead.", 1 ) )
		{
			// warning converted to exception;
			throw error_already_set();
		}
		return p;
	}

	PyErr_SetString( PyExc_KeyError, ( "'"  + n + "'" ).c_str() );
	throw error_already_set();
}

void bindParameterised()
{
	using boost::python::arg;

	RunTimeTypedClass<Parameterised, ParameterisedWrapPtr>()
		.def( init< const std::string, const std::string>( ( arg( "name" ), arg( "description") ) ) )
		.def( init< const std::string, const std::string, CompoundParameterPtr >( ( arg( "name" ), arg( "description") , arg( "compoundParameter") ) ) )
		.add_property( "name", make_function( &Parameterised::name, return_value_policy<copy_const_reference>() ) )
		.add_property( "description", make_function( &Parameterised::description, return_value_policy<copy_const_reference>() ) )
		.def( "parameters", (CompoundParameterPtr (Parameterised::*)())&Parameterised::parameters )
		.def( "__getitem__", &parameterisedGetItem )
		/// \todo Remove this in major version 5.
		.def( "__getattr__", &parameterisedGetAttr )
		.def( "userData", (CompoundObjectPtr (Parameterised::*)())&Parameterised::userData )
	;

}

} // namespace IECore
<|endoftext|>


<commit_before>// ==========================================================================
//                              sam2matrix
// ==========================================================================
// Copyright (c) 2006-2014, Knut Reinert, FU Berlin
// 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 Knut Reinert or the FU Berlin 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 KNUT REINERT OR THE FU BERLIN 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.
//
// This program determines for each read in the reference file if it has an
// entry in the provided sam files stating that it mapped.
//
// ==========================================================================
// Author: Jochen Singer <jochen.singer@fu-berlin.de>
// ==========================================================================
#include <map>
#include <iostream>
#include <fstream>

#include <seqan/basic.h>
#include <seqan/sequence.h>
#include <seqan/bam_io.h>

#include <seqan/arg_parse.h>
#include <seqan/seq_io.h>

// ==========================================================================
// Classes
// ==========================================================================

// --------------------------------------------------------------------------
// Class SamToGasicOptions
// --------------------------------------------------------------------------

// This struct stores the options from the command line.
using namespace seqan;

struct SamToGasicOptions
{
    String<String<char> > samFileNames;
    String<String<char> > genomeFileNames;
    String<char> readNameFileName;
    String<char> outPutFileName;
};

// ==========================================================================
// Functions
// ==========================================================================

// --------------------------------------------------------------------------
// Function parseCommandLine()
// --------------------------------------------------------------------------

seqan::ArgumentParser::ParseResult
parseCommandLine(SamToGasicOptions& options, int argc, char const ** argv)
{
    // Setup ArgumentParser.
    seqan::ArgumentParser parser("sam2matrix");
    // Set short description, version, and date.
    setShortDescription(parser, "This program outputs for each read the ids of references it maps to.");
    setVersion(parser, "0.1");
    setDate(parser, "April 2014");
    setCategory(parser, "Metagenomics");

    // Define usage line and long description.
    addUsageLine(parser, "\\fB-m\\fP \\fIa.sam\\fP \\fB-m\\fP \\fIb.sam\\fP \\fB-r\\fP \\fIreads\\fP \\fB-rf\\fP "
                         "\\fIref_a.fasta\\fP \\fB-rf\\fP \\fIref_b.fasta\\fP \\fB-o\\fP \\fIout.tsv\\fP");
    addDescription(parser, "This program determines for each read in the reference file if it has an entry in the "
                           "provided sam files stating that it mapped. Afterwards a file is generated containing a row"
                           " for each read which contains the read ID and the index of the mapped references.");

    addOption(parser, ArgParseOption("m", "mapping", "File containing the mappings.", ArgParseOption::INPUTFILE,
                                     "FILE", true));
    setValidValues(parser, "m", ".sam");
    setRequired(parser, "m");
    addOption(parser, ArgParseOption("r", "reads", "File containing the reads contained in the mapping file(s).",
                                     ArgParseOption::INPUTFILE, "FILE"));
    setValidValues(parser, "r", ".fa .fasta .fq .fastq");
    setRequired(parser, "r");

    addOption(parser, ArgParseOption("rf", "reference", "Name of the file used as reference of the corresponding sam "
                                     "file.", ArgParseOption::STRING, "STRING", true));
    setRequired(parser, "rf");

    addOption(parser, ArgParseOption("o", "out", "Output file.", ArgParseOption::OUTPUTFILE));
    setRequired(parser, "o");
    setValidValues(parser, "o", ".tsv");

    // Add Examples Section.
    addTextSection(parser, "Examples");
    addListItem(parser, "\\fB./sam2matrix\\fP \\fB-m\\fP \\fIa.sam\\fP \\fB-m\\fP \\fIb.sam\\fP \\fB-r\\fP "
                        "\\fIreads.fasta\\fP \\fB-rf\\fP \\fIref_a.fasta\\fP \\fB-rf\\fP \\fIref_b.fasta\\fP "
                        "\\fB-o\\fP \\fIout.tsv\\fP",
                        "Storing in \\fIout.tsv\\fP for each read contained in \\fIreads.fasta\\fP if it mapped to "
                        "the references in \\fIref_a.fasta\\fP or \\fIref_b.fasta\\fP using the corresponding sam "
                        "files \\fIa.sam\\fP and \\fIb.sam\\fP.");

    // Parse command line.
    seqan::ArgumentParser::ParseResult res = seqan::parse(parser, argc, argv);

    // Only extract  options if the program will continue after parseCommandLine()
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res;

    options.samFileNames = getOptionValues(parser, "m");
    getOptionValue(options.readNameFileName, parser, "r");
    options.genomeFileNames = getOptionValues(parser, "rf");
    getOptionValue(options.outPutFileName, parser, "o");

    return seqan::ArgumentParser::PARSE_OK;
}

// A std::map is used to quickly find a read id when parsing the sam
// files.
bool _initializeMap(std::map<String<char>, unsigned> & nameToPos, SamToGasicOptions const & options)
{
    seqan::CharString id;
    seqan::Dna5String seq;

    SequenceStream seqStream(toCString(options.readNameFileName));
    if (!isGood(seqStream))
    {
        std::cerr << "ERROR: Could not open the file " << options.readNameFileName << "!\n";
        return 1;
    }

    seqan::CharString fixedId;
    for (unsigned i = 0 ;!atEnd(seqStream); ++i)
    {
        if (readRecord(id, seq, seqStream) != 0)
        {
            std::cerr << "ERROR: Could not read from " << options.readNameFileName << "!\n";
            return 1;
        }

        clear(fixedId);
        for(unsigned s = 0; s < length(id); ++s)
        {
            if(id[s] == ' ') break;
            appendValue(fixedId, id[s]);
        }

        nameToPos[fixedId] = i;
    }

    return true;
}

bool _parseSamFiles(StringSet<String<unsigned> > & mappedReads,
                    std::map<String<char>, unsigned> & nameToPos,
                    SamToGasicOptions const & options)
{
    resize(mappedReads, nameToPos.size());

    for (unsigned i = 0; i < length(options.samFileNames); ++i)
    {
        BamStream bamIO(toCString(options.samFileNames[i]));
        BamAlignmentRecord record;

        for (unsigned j = 0 ;!atEnd(bamIO); ++j)
        {
            if (readRecord(record, bamIO) != 0)
                return false;
            if (!hasFlagUnmapped(record))
            {
                if (nameToPos.find(record.qName) != nameToPos.end())
                {
                    if (length(mappedReads[nameToPos[record.qName]]) == 0 || back(mappedReads[nameToPos[record.qName]]) != i)
                        appendValue(mappedReads[nameToPos[record.qName]], i);
                }
            }
        }
    }
    return true;
}

bool _writeFile(StringSet<String<unsigned> > const & result,
                std::map<String<char>, unsigned> & nameToPos,
                SamToGasicOptions const & options)
{
    std::fstream fout(toCString(options.outPutFileName), std::ios::binary | std::ios::out);

    if (streamPut(fout, length(options.samFileNames)))
        return 1;
    if (streamWriteChar(fout, '\t'))
        return 1;
    if (streamPut(fout, length(result)))
        return 1;
    if (streamWriteChar(fout, '\n'))
        return 1;

    for (unsigned i = 0; i < length(options.genomeFileNames); ++i)
    {
        if (streamWriteChar(fout, '>'))
            return 1;
        if (streamWriteBlock(fout, &(options.genomeFileNames[i])[0], length(options.genomeFileNames[i])) != length(options.genomeFileNames[i]))
            return 1;
        if (streamWriteChar(fout, '\n'))
            return 1;
    }

    std::map<String<char>, unsigned>::iterator it = nameToPos.begin();
    for (unsigned i = 0; i < length(result); ++i)
    {
        if (streamWriteBlock(fout, &(it->first)[0], length(it->first)) != length(it->first))
            return 1;
        if (streamWriteChar(fout, '\t'))
            return 1;

        for (unsigned j = 0; j < length(result[i]); ++j)
        {
            if (streamPut(fout, result[i][j]))
                return 1;
            if (streamWriteChar(fout, '\t'))
                return 1;
        }
        if (streamWriteChar(fout, '\n'))
            return 1;

        ++it;
    }

    fout.close();

    return 0;
}

// --------------------------------------------------------------------------
// Function main()
// --------------------------------------------------------------------------

// Program entry point.

int main(int argc, char const ** argv)
{
    // Parse the command line.
    seqan::ArgumentParser parser;
    SamToGasicOptions options;
    seqan::ArgumentParser::ParseResult res = parseCommandLine(options, argc, argv);

    // If there was an error parsing or built-in argument parser functionality
    // was triggered then we exit the program.  The return code is 1 if there
    // were errors and 0 if there were none.
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res == seqan::ArgumentParser::PARSE_ERROR;

    StringSet<String<unsigned> > mappedReads;
    std::map<String<char>, unsigned> nameToPos;

    // A std::map is used to quickly find a read id when parsing the sam
    if (!_initializeMap(nameToPos, options))
        std::cerr << "Problem extracting the read names." << std::endl;
    if (!_parseSamFiles(mappedReads, nameToPos, options))
        std::cerr << "Problem parsing the sam files." << std::endl;
    if (!_writeFile(mappedReads, nameToPos, options))
        std::cerr << "Problem writing the result." << std::endl;

    return 0;
}

<commit_msg>[INTERNAL] Changed the file handling if no reference files are specified.<commit_after>// ==========================================================================
//                              sam2matrix
// ==========================================================================
// Copyright (c) 2006-2014, Knut Reinert, FU Berlin
// 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 Knut Reinert or the FU Berlin 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 KNUT REINERT OR THE FU BERLIN 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.
//
// This program determines for each read in the reference file if it has an
// entry in the provided sam files stating that it mapped.
//
// ==========================================================================
// Author: Jochen Singer <jochen.singer@fu-berlin.de>
// ==========================================================================
#include <map>
#include <iostream>
#include <fstream>

#include <seqan/basic.h>
#include <seqan/sequence.h>
#include <seqan/bam_io.h>

#include <seqan/arg_parse.h>
#include <seqan/seq_io.h>

// ==========================================================================
// Classes
// ==========================================================================

// --------------------------------------------------------------------------
// Class SamToGasicOptions
// --------------------------------------------------------------------------

// This struct stores the options from the command line.
using namespace seqan;

struct SamToGasicOptions
{
    String<String<char> > samFileNames;
    String<String<char> > genomeFileNames;
    String<char> readNameFileName;
    String<char> outPutFileName;
};

// ==========================================================================
// Functions
// ==========================================================================

// --------------------------------------------------------------------------
// Function parseCommandLine()
// --------------------------------------------------------------------------

seqan::ArgumentParser::ParseResult
parseCommandLine(SamToGasicOptions& options, int argc, char const ** argv)
{
    // Setup ArgumentParser.
    seqan::ArgumentParser parser("sam2matrix");
    // Set short description, version, and date.
    setShortDescription(parser, "This program outputs for each read the ids of references it maps to.");
    setVersion(parser, "0.1");
    setDate(parser, "April 2014");
    setCategory(parser, "Metagenomics");

    // Define usage line and long description.
    addUsageLine(parser, "\\fB-m\\fP \\fIa.sam\\fP \\fB-m\\fP \\fIb.sam\\fP \\fB-r\\fP \\fIreads\\fP \\fB-rf\\fP "
                         "\\fIref_a.fasta\\fP \\fB-rf\\fP \\fIref_b.fasta\\fP \\fB-o\\fP \\fIout.tsv\\fP");
    addDescription(parser, "This program determines for each read in the reference file if it has an entry in the "
                           "provided sam files stating that it mapped. Afterwards a file is generated containing a row"
                           " for each read which contains the read ID and the index of the mapped references.");

    addOption(parser, ArgParseOption("m", "mapping", "File containing the mappings.", ArgParseOption::INPUTFILE,
                                     "FILE", true));
    setValidValues(parser, "m", ".sam");
    setRequired(parser, "m");
    addOption(parser, ArgParseOption("r", "reads", "File containing the reads contained in the mapping file(s).",
                                     ArgParseOption::INPUTFILE, "FILE"));
    setValidValues(parser, "r", ".fa .fasta .fq .fastq");
    setRequired(parser, "r");

    addOption(parser, ArgParseOption("rf", "reference", "Name of the file used as reference of the corresponding sam "
                                     "file. If not specified the names of the mapping files are taken",
                                     ArgParseOption::STRING, "STRING", true));

    addOption(parser, ArgParseOption("o", "out", "Output file.", ArgParseOption::OUTPUTFILE));
    setRequired(parser, "o");
    setValidValues(parser, "o", ".tsv");

    // Add Examples Section.
    addTextSection(parser, "Examples");
    addListItem(parser, "\\fB./sam2matrix\\fP \\fB-m\\fP \\fIa.sam\\fP \\fB-m\\fP \\fIb.sam\\fP \\fB-r\\fP "
                        "\\fIreads.fasta\\fP \\fB-rf\\fP \\fIref_a.fasta\\fP \\fB-rf\\fP \\fIref_b.fasta\\fP "
                        "\\fB-o\\fP \\fIout.tsv\\fP",
                        "Storing in \\fIout.tsv\\fP for each read contained in \\fIreads.fasta\\fP if it mapped to "
                        "the references in \\fIref_a.fasta\\fP or \\fIref_b.fasta\\fP using the corresponding sam "
                        "files \\fIa.sam\\fP and \\fIb.sam\\fP.");

    // Parse command line.
    seqan::ArgumentParser::ParseResult res = seqan::parse(parser, argc, argv);

    // Only extract  options if the program will continue after parseCommandLine()
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res;

    options.samFileNames = getOptionValues(parser, "m");
    getOptionValue(options.readNameFileName, parser, "r");
    options.genomeFileNames = getOptionValues(parser, "rf");
    getOptionValue(options.outPutFileName, parser, "o");

    if (length(options.samFileNames) > length(options.genomeFileNames))
        for (unsigned i = length(options.genomeFileNames); i < length(options.samFileNames); ++i)
            appendValue(options.genomeFileNames, options.samFileNames[i]);

    return seqan::ArgumentParser::PARSE_OK;
}

// A std::map is used to quickly find a read id when parsing the sam
// files.
bool _initializeMap(std::map<String<char>, unsigned> & nameToPos, SamToGasicOptions const & options)
{
    seqan::CharString id;
    seqan::Dna5String seq;

    SequenceStream seqStream(toCString(options.readNameFileName));
    if (!isGood(seqStream))
    {
        std::cerr << "ERROR: Could not open the file " << options.readNameFileName << "!\n";
        return 1;
    }

    seqan::CharString fixedId;
    for (unsigned i = 0 ;!atEnd(seqStream); ++i)
    {
        if (readRecord(id, seq, seqStream) != 0)
        {
            std::cerr << "ERROR: Could not read from " << options.readNameFileName << "!\n";
            return 1;
        }

        clear(fixedId);
        for(unsigned s = 0; s < length(id); ++s)
        {
            if(id[s] == ' ') break;
            appendValue(fixedId, id[s]);
        }

        nameToPos[fixedId] = i;
    }

    return true;
}

bool _parseSamFiles(StringSet<String<unsigned> > & mappedReads,
                    std::map<String<char>, unsigned> & nameToPos,
                    SamToGasicOptions const & options)
{
    resize(mappedReads, nameToPos.size());

    for (unsigned i = 0; i < length(options.samFileNames); ++i)
    {
        BamStream bamIO(toCString(options.samFileNames[i]));
        BamAlignmentRecord record;

        for (unsigned j = 0 ;!atEnd(bamIO); ++j)
        {
            if (readRecord(record, bamIO) != 0)
                return false;
            if (!hasFlagUnmapped(record))
            {
                if (nameToPos.find(record.qName) != nameToPos.end())
                {
                    if (length(mappedReads[nameToPos[record.qName]]) == 0 || back(mappedReads[nameToPos[record.qName]]) != i)
                        appendValue(mappedReads[nameToPos[record.qName]], i);
                }
            }
        }
    }
    return true;
}

bool _writeFile(StringSet<String<unsigned> > const & result,
                std::map<String<char>, unsigned> & nameToPos,
                SamToGasicOptions const & options)
{
    std::fstream fout(toCString(options.outPutFileName), std::ios::binary | std::ios::out);

    if (streamPut(fout, length(options.samFileNames)))
        return 1;
    if (streamWriteChar(fout, '\t'))
        return 1;
    if (streamPut(fout, length(result)))
        return 1;
    if (streamWriteChar(fout, '\n'))
        return 1;

    for (unsigned i = 0; i < length(options.genomeFileNames); ++i)
    {
        if (streamWriteChar(fout, '>'))
            return 1;
        if (streamWriteBlock(fout, &(options.genomeFileNames[i])[0], length(options.genomeFileNames[i])) != length(options.genomeFileNames[i]))
            return 1;
        if (streamWriteChar(fout, '\n'))
            return 1;
    }

    std::map<String<char>, unsigned>::iterator it = nameToPos.begin();
    for (unsigned i = 0; i < length(result); ++i)
    {
        if (streamWriteBlock(fout, &(it->first)[0], length(it->first)) != length(it->first))
            return 1;
        if (streamWriteChar(fout, '\t'))
            return 1;

        for (unsigned j = 0; j < length(result[i]); ++j)
        {
            if (streamPut(fout, result[i][j]))
                return 1;
            if (streamWriteChar(fout, '\t'))
                return 1;
        }
        if (streamWriteChar(fout, '\n'))
            return 1;

        ++it;
    }

    fout.close();

    return 0;
}

// --------------------------------------------------------------------------
// Function main()
// --------------------------------------------------------------------------

// Program entry point.

int main(int argc, char const ** argv)
{
    // Parse the command line.
    seqan::ArgumentParser parser;
    SamToGasicOptions options;
    seqan::ArgumentParser::ParseResult res = parseCommandLine(options, argc, argv);

    // If there was an error parsing or built-in argument parser functionality
    // was triggered then we exit the program.  The return code is 1 if there
    // were errors and 0 if there were none.
    if (res != seqan::ArgumentParser::PARSE_OK)
        return res == seqan::ArgumentParser::PARSE_ERROR;

    StringSet<String<unsigned> > mappedReads;
    std::map<String<char>, unsigned> nameToPos;

    // A std::map is used to quickly find a read id when parsing the sam
    if (!_initializeMap(nameToPos, options))
        std::cerr << "Problem extracting the read names." << std::endl;
    if (!_parseSamFiles(mappedReads, nameToPos, options))
        std::cerr << "Problem parsing the sam files." << std::endl;
    if (!_writeFile(mappedReads, nameToPos, options))
        std::cerr << "Problem writing the result." << std::endl;

    return 0;
}

<|endoftext|>