<commit_before>/*
    Copyright (C) 2005 by Jorrit Tyberghein
	      (C) 2005 by Frank Richter
              (C) 2009 by Marten Svanfeldt

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

    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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"

#include "csgeom/math.h"
#include "csutil/sysfunc.h"
#include "csutil/threadjobqueue.h"
#include "csutil/randomgen.h"

namespace
{
  static CS::Threading::Mutex rgenLock;
  static csRandomGen rgen;
}

namespace CS
{
namespace Threading
{

  ThreadedJobQueue::ThreadedJobQueue (size_t numWorkers, ThreadPriority priority,
    const char* name)
    : scfImplementationType (this),
    numWorkerThreads (numWorkers),
    outstandingJobs (0), name (name)
  {
    if (this->name.IsEmpty())
      this->name.Format ("Queue [%p]", this);

    allThreadState = new csRef<ThreadState>[numWorkerThreads];

    // Start up the threads
    for (unsigned int i = 0; i < numWorkerThreads; ++i)
    {
      allThreadState[i].AttachNew (new ThreadState (this, i));
      allThreadState[i]->threadObject->SetPriority(priority);

      allThreads.Add (allThreadState[i]->threadObject);
    }

    allThreads.StartAll ();
  }

  ThreadedJobQueue::~ThreadedJobQueue ()
  {
    // Kill all threads, friendly
    for(size_t i = 0; i < numWorkerThreads; ++i)
    {
      CS::Threading::AtomicOperations::Set (
	&(allThreadState[i]->runnable->shutdownQueue), 0xff);
      allThreadState[i]->tsNewJob.NotifyAll ();
    }

    allThreads.WaitAll ();

    // Deallocate
    for (size_t i = 0; i < numWorkerThreads; ++i)
    {
      allThreadState[i]->runnable.Invalidate();
    }
    delete[] allThreadState;
  }

  void ThreadedJobQueue::Enqueue (iJob* job)
  {
    if (!job)
      return;

    while (true)
    {
      // Find a thread (on random) to add it to
      size_t targetThread = rgen.Get ((uint32)numWorkerThreads);

      // Lock, add and notify
      ThreadState* ts = allThreadState[targetThread];

      // Might be contended, so try next if locked
      if (ts->tsMutex.TryLock ())
      {
        ts->jobQueue.Push (job);
        CS::Threading::AtomicOperations::Increment (&outstandingJobs);
        ts->tsMutex.Unlock ();

        ts->tsNewJob.NotifyAll ();

        return;
      }
    }

  }

  iJobQueue::JobStatus ThreadedJobQueue::Dequeue (iJob* job, bool waitForCompletion)
  {
    // Check all the thread queues
    bool removedJob = PullFromQueues (job);

    if (!removedJob)
    {
      return Dequeued;
    }
    else
    {
      return CheckCompletion (job, waitForCompletion);
    }
    // Nothing
    return NotEnqueued;
  }

  iJobQueue::JobStatus ThreadedJobQueue::PullAndRun (iJob* job, bool waitForCompletion)
  {
    bool removedJob = PullFromQueues (job);

    if (removedJob)
    {
      job->Run ();
      return Dequeued;
    }
    else
    {
      return CheckCompletion (job, waitForCompletion);
    }
    // Nothing
    return NotEnqueued;
  }

  iJobQueue::JobStatus ThreadedJobQueue::CheckCompletion (iJob* job, bool waitForCompletion)
  {
    // Check if it is running, then wait
    ThreadState *ownerTs = 0;

    for (size_t i = 0; i < numWorkerThreads; ++i)
    {
      ThreadState* ts = allThreadState[i];

      ts->tsMutex.Lock ();

      if (ts->currentJob == job)
      {
	ownerTs = ts;
	break;
      }
      ts->tsMutex.Unlock (); // Unlock if not right
    }

    if (ownerTs)
    {
      JobStatus result;
      if (waitForCompletion)
      {
	// Always enter here with ownerTs->tsMutex locked!
	while (ownerTs->currentJob == job)
	{
	  ownerTs->tsJobFinished.Wait (ownerTs->tsMutex);
	}
	result = Dequeued;
      }
      else
	result = Pending;

      ownerTs->tsMutex.Unlock (); // Unlock if right
      return result;
    }
    else
      return NotEnqueued;

    // All mutex that have been locked are unlocked!
  }

  void ThreadedJobQueue::WaitAll ()
  {
    while(!IsFinished ())
    {
      for (size_t i = 0; i < numWorkerThreads; ++i)
      {
        ThreadState* ts = allThreadState[i];

        MutexScopedLock l (ts->tsMutex);
        if(ts->currentJob || ts->jobQueue.GetSize() > 0)
        {
          // Have a job, wait for it
          ts->tsJobFinished.Wait (ts->tsMutex);
        }
      }
    }
  }

  bool ThreadedJobQueue::IsFinished ()
  {
    int32 c = CS::Threading::AtomicOperations::Read (&outstandingJobs);
    return c == 0;
  }

  int32 ThreadedJobQueue::GetQueueCount()
  {
    return CS::Threading::AtomicOperations::Read(&outstandingJobs);
  }

  bool ThreadedJobQueue::PullFromQueues (iJob* job)
  {
    // Check all the thread queues
    for (size_t i = 0; i < numWorkerThreads; ++i)
    {
      ThreadState* ts = allThreadState[i];
      MutexScopedLock l (ts->tsMutex);

      bool removedJob = ts->jobQueue.Delete (job);

      if (removedJob)
      {
        CS::Threading::AtomicOperations::Decrement(&outstandingJobs);
        return true;
      }
    }

    return false;
  }

  ThreadedJobQueue::QueueRunnable::QueueRunnable (ThreadedJobQueue* queue,
    ThreadState* ts, unsigned int id)
    : ownerQueue (queue), shutdownQueue (0), threadState (ts)
  {
    name.Format ("#%u %s", id, queue->GetName());
  }

  void ThreadedJobQueue::QueueRunnable::Run ()
  {
    // Forcibly keep QueueRunnable object alive until we got a shutdown
    this->IncRef();
    while (CS::Threading::AtomicOperations::Read(&(/*ownerQueue->*/shutdownQueue)) == 0x0)
    {
      // Get a job
      csRef<iJob> currentJob;

      // Try our own list first
      // We need to hold this until currentJob is set, otherwise something might slip through in "wait"
      threadState->tsMutex.Lock ();

      if (threadState->jobQueue.GetSize () > 0)
      {
        currentJob = threadState->jobQueue.PopTop ();
      }

      if (!currentJob)
      {
        // If we couldn't get any job, try to steal. At most try to steal once
        // from each of the other threads
        size_t start;
        {
          MutexScopedLock l (rgenLock);
          start = rgen.Get ((uint32)ownerQueue->numWorkerThreads);
        }

        for (size_t i = 0, index = start;
             i < ownerQueue->numWorkerThreads;
             ++i, index = (index + 1) % ownerQueue->numWorkerThreads
             )
        {
          ThreadState* foreignTS = ownerQueue->allThreadState[index];
          if (foreignTS == threadState)
            continue;

          // Try to lock it, but never wait for a lock
          if (foreignTS->tsMutex.TryLock ()) // Lock foreign object A
          {
            // Get the job
            if (foreignTS->jobQueue.GetSize() > 0)
            {
              currentJob = foreignTS->jobQueue.PopBottom ();
              foreignTS->tsMutex.Unlock (); // Unlock foreign object A if success
              break;
            }

            foreignTS->tsMutex.Unlock (); // Unlock foreign object A if unsuccessful
          }
        }
      }

      if (currentJob)
      {
        // Got one, execute
        threadState->currentJob = currentJob;
        threadState->tsMutex.Unlock (); // Unlock our own TS after getting a job

        currentJob->Run ();

	/* Release reference to job only until after the last access of the
	   thread manager.
	   This is a cautionary measure: the _job_ may keep the last ref to the
	   TM; releasing the job will also release the TM, causing segfaults
	   upon accesses to it. Thus keep it until after having accessed the
	   TM for the last time. */
	csRef<iJob> justKeepCurrentJobRefALittleLonger (currentJob);
        {
          MutexScopedLock l (threadState->tsMutex);
          threadState->currentJob = 0;
          currentJob = 0;
        }

        CS::Threading::AtomicOperations::Decrement(&(ownerQueue->outstandingJobs));

        threadState->tsJobFinished.NotifyAll ();
      }
      else
      {
        // Couldn't get one, wait for a newly added job
        threadState->tsNewJob.Wait (threadState->tsMutex);
        threadState->tsMutex.Unlock ();
      }
    }

    // There is a circular ref between ThreadState and QueueRunnable, break it up
    threadState.Invalidate();

    this->DecRef();
  }

  const char* ThreadedJobQueue::QueueRunnable::GetName () const
  {
    return name.GetDataSafe ();
  }

}
}
<commit_msg>threadqueue: When some queues are 'underfilled', wake up all threads, to facilitate job stealing<commit_after>/*
    Copyright (C) 2005 by Jorrit Tyberghein
	      (C) 2005 by Frank Richter
              (C) 2009 by Marten Svanfeldt

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

    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
    Library General Public License for more details.

    You should have received a copy of the GNU Library General Public
    License along with this library; if not, write to the Free
    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/

#include "cssysdef.h"

#include "csgeom/math.h"
#include "csutil/sysfunc.h"
#include "csutil/threadjobqueue.h"
#include "csutil/randomgen.h"

namespace
{
  static CS::Threading::Mutex rgenLock;
  static csRandomGen rgen;
}

namespace CS
{
namespace Threading
{

  ThreadedJobQueue::ThreadedJobQueue (size_t numWorkers, ThreadPriority priority,
    const char* name)
    : scfImplementationType (this),
    numWorkerThreads (numWorkers),
    outstandingJobs (0), name (name)
  {
    if (this->name.IsEmpty())
      this->name.Format ("Queue [%p]", this);

    allThreadState = new csRef<ThreadState>[numWorkerThreads];

    // Start up the threads
    for (unsigned int i = 0; i < numWorkerThreads; ++i)
    {
      allThreadState[i].AttachNew (new ThreadState (this, i));
      allThreadState[i]->threadObject->SetPriority(priority);

      allThreads.Add (allThreadState[i]->threadObject);
    }

    allThreads.StartAll ();
  }

  ThreadedJobQueue::~ThreadedJobQueue ()
  {
    // Kill all threads, friendly
    for(size_t i = 0; i < numWorkerThreads; ++i)
    {
      CS::Threading::AtomicOperations::Set (
	&(allThreadState[i]->runnable->shutdownQueue), 0xff);
      allThreadState[i]->tsNewJob.NotifyAll ();
    }

    allThreads.WaitAll ();

    // Deallocate
    for (size_t i = 0; i < numWorkerThreads; ++i)
    {
      allThreadState[i]->runnable.Invalidate();
    }
    delete[] allThreadState;
  }

  void ThreadedJobQueue::Enqueue (iJob* job)
  {
    if (!job)
      return;

    while (true)
    {
      // Find a thread (on random) to add it to
      size_t targetThread = rgen.Get ((uint32)numWorkerThreads);

      // Lock, add and notify
      ThreadState* ts = allThreadState[targetThread];

      // Might be contended, so try next if locked
      if (ts->tsMutex.TryLock ())
      {
        ts->jobQueue.Push (job);
        size_t jobCount (CS::Threading::AtomicOperations::Increment (&outstandingJobs));
        ts->tsMutex.Unlock ();

        if ((jobCount > 1) && (jobCount < numWorkerThreads))
        {
          /* There must be some empty queues, so notify all queues so one
           * might possible steal the job just added if it happened to go into
           * a non-empty queue */
          for (size_t i = 0; i < numWorkerThreads; ++i)
          {
            ThreadState* ts = allThreadState[(targetThread + i) % numWorkerThreads];
            ts->tsNewJob.NotifyAll ();
          }
        }
        else
        {
          /* Queues are generally filled, just notify the thread we gave to
           * job to */
          ts->tsNewJob.NotifyAll ();
        }

        return;
      }
    }

  }

  iJobQueue::JobStatus ThreadedJobQueue::Dequeue (iJob* job, bool waitForCompletion)
  {
    // Check all the thread queues
    bool removedJob = PullFromQueues (job);

    if (!removedJob)
    {
      return Dequeued;
    }
    else
    {
      return CheckCompletion (job, waitForCompletion);
    }
    // Nothing
    return NotEnqueued;
  }

  iJobQueue::JobStatus ThreadedJobQueue::PullAndRun (iJob* job, bool waitForCompletion)
  {
    bool removedJob = PullFromQueues (job);

    if (removedJob)
    {
      job->Run ();
      return Dequeued;
    }
    else
    {
      return CheckCompletion (job, waitForCompletion);
    }
    // Nothing
    return NotEnqueued;
  }

  iJobQueue::JobStatus ThreadedJobQueue::CheckCompletion (iJob* job, bool waitForCompletion)
  {
    // Check if it is running, then wait
    ThreadState *ownerTs = 0;

    for (size_t i = 0; i < numWorkerThreads; ++i)
    {
      ThreadState* ts = allThreadState[i];

      ts->tsMutex.Lock ();

      if (ts->currentJob == job)
      {
	ownerTs = ts;
	break;
      }
      ts->tsMutex.Unlock (); // Unlock if not right
    }

    if (ownerTs)
    {
      JobStatus result;
      if (waitForCompletion)
      {
	// Always enter here with ownerTs->tsMutex locked!
	while (ownerTs->currentJob == job)
	{
	  ownerTs->tsJobFinished.Wait (ownerTs->tsMutex);
	}
	result = Dequeued;
      }
      else
	result = Pending;

      ownerTs->tsMutex.Unlock (); // Unlock if right
      return result;
    }
    else
      return NotEnqueued;

    // All mutex that have been locked are unlocked!
  }

  void ThreadedJobQueue::WaitAll ()
  {
    while(!IsFinished ())
    {
      for (size_t i = 0; i < numWorkerThreads; ++i)
      {
        ThreadState* ts = allThreadState[i];

        MutexScopedLock l (ts->tsMutex);
        if(ts->currentJob || ts->jobQueue.GetSize() > 0)
        {
          // Have a job, wait for it
          ts->tsJobFinished.Wait (ts->tsMutex);
        }
      }
    }
  }

  bool ThreadedJobQueue::IsFinished ()
  {
    int32 c = CS::Threading::AtomicOperations::Read (&outstandingJobs);
    return c == 0;
  }

  int32 ThreadedJobQueue::GetQueueCount()
  {
    return CS::Threading::AtomicOperations::Read(&outstandingJobs);
  }

  bool ThreadedJobQueue::PullFromQueues (iJob* job)
  {
    // Check all the thread queues
    for (size_t i = 0; i < numWorkerThreads; ++i)
    {
      ThreadState* ts = allThreadState[i];
      MutexScopedLock l (ts->tsMutex);

      bool removedJob = ts->jobQueue.Delete (job);

      if (removedJob)
      {
        CS::Threading::AtomicOperations::Decrement(&outstandingJobs);
        return true;
      }
    }

    return false;
  }

  ThreadedJobQueue::QueueRunnable::QueueRunnable (ThreadedJobQueue* queue,
    ThreadState* ts, unsigned int id)
    : ownerQueue (queue), shutdownQueue (0), threadState (ts)
  {
    name.Format ("#%u %s", id, queue->GetName());
  }

  void ThreadedJobQueue::QueueRunnable::Run ()
  {
    // Forcibly keep QueueRunnable object alive until we got a shutdown
    this->IncRef();
    while (CS::Threading::AtomicOperations::Read(&(/*ownerQueue->*/shutdownQueue)) == 0x0)
    {
      // Get a job
      csRef<iJob> currentJob;

      // Try our own list first
      // We need to hold this until currentJob is set, otherwise something might slip through in "wait"
      threadState->tsMutex.Lock ();

      if (threadState->jobQueue.GetSize () > 0)
      {
        currentJob = threadState->jobQueue.PopTop ();
      }

      if (!currentJob)
      {
        // If we couldn't get any job, try to steal. At most try to steal once
        // from each of the other threads
        size_t start;
        {
          MutexScopedLock l (rgenLock);
          start = rgen.Get ((uint32)ownerQueue->numWorkerThreads);
        }

        for (size_t i = 0, index = start;
             i < ownerQueue->numWorkerThreads;
             ++i, index = (index + 1) % ownerQueue->numWorkerThreads
             )
        {
          ThreadState* foreignTS = ownerQueue->allThreadState[index];
          if (foreignTS == threadState)
            continue;

          // Try to lock it, but never wait for a lock
          if (foreignTS->tsMutex.TryLock ()) // Lock foreign object A
          {
            // Get the job
            if (foreignTS->jobQueue.GetSize() > 0)
            {
              currentJob = foreignTS->jobQueue.PopBottom ();
              foreignTS->tsMutex.Unlock (); // Unlock foreign object A if success
              break;
            }

            foreignTS->tsMutex.Unlock (); // Unlock foreign object A if unsuccessful
          }
        }
      }

      if (currentJob)
      {
        // Got one, execute
        threadState->currentJob = currentJob;
        threadState->tsMutex.Unlock (); // Unlock our own TS after getting a job

        currentJob->Run ();

	/* Release reference to job only until after the last access of the
	   thread manager.
	   This is a cautionary measure: the _job_ may keep the last ref to the
	   TM; releasing the job will also release the TM, causing segfaults
	   upon accesses to it. Thus keep it until after having accessed the
	   TM for the last time. */
	csRef<iJob> justKeepCurrentJobRefALittleLonger (currentJob);
        {
          MutexScopedLock l (threadState->tsMutex);
          threadState->currentJob = 0;
          currentJob = 0;
        }

        CS::Threading::AtomicOperations::Decrement(&(ownerQueue->outstandingJobs));

        threadState->tsJobFinished.NotifyAll ();
      }
      else
      {
        // Couldn't get one, wait for a newly added job
        threadState->tsNewJob.Wait (threadState->tsMutex);
        threadState->tsMutex.Unlock ();
      }
    }

    // There is a circular ref between ThreadState and QueueRunnable, break it up
    threadState.Invalidate();

    this->DecRef();
  }

  const char* ThreadedJobQueue::QueueRunnable::GetName () const
  {
    return name.GetDataSafe ();
  }

}
}
<|endoftext|>


<commit_before>/* +---------------------------------------------------------------------------+
   |                 The Mobile Robot Programming Toolkit (MRPT)               |
   |                                                                           |
   |                          http://www.mrpt.org/                             |
   |                                                                           |
   | Copyright (c) 2005-2013, Individual contributors, see AUTHORS file        |
   | Copyright (c) 2005-2013, MAPIR group, University of Malaga                |
   | Copyright (c) 2012-2013, University of Almeria                            |
   | 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 the copyright holders nor the                    |
   |      names of its contributors may be used to endorse or promote products |
   |      derived from this software without specific prior written permission.|
   |                                                                           |
   | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       |
   | 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
   | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR|
   | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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 <mrpt/hwdrivers.h>  // Precompiled headers
#include <mrpt/hwdrivers/CRaePID.h>

#include <iostream>
#include <sstream>

using namespace mrpt::utils;
using namespace mrpt::hwdrivers;

IMPLEMENTS_GENERIC_SENSOR(CRaePID,mrpt::hwdrivers)

/* -----------------------------------------------------
                Constructor
   ----------------------------------------------------- */
CRaePID::CRaePID()
{
	m_sensorLabel = "RAE_PID";
}

/* -----------------------------------------------------
                loadConfig_sensorSpecific
   ----------------------------------------------------- */
void  CRaePID::loadConfig_sensorSpecific(
	const mrpt::utils::CConfigFileBase &configSource,
	const std::string			&iniSection )
{
#ifdef MRPT_OS_WINDOWS
	com_port = configSource.read_string(iniSection, "COM_port_PID", "COM1", true ) ;
#else
	com_port = configSource.read_string(iniSection, "COM_port_PID", "/dev/tty0", true );
#endif

	com_bauds		= configSource.read_int( iniSection, "baudRate",9600, false );

	pose_x = configSource.read_float(iniSection,"pose_x",0,true);
	pose_y = configSource.read_float(iniSection,"pose_y",0,true);
	pose_z = configSource.read_float(iniSection,"pose_z",0,true);
	pose_roll = configSource.read_float(iniSection,"pose_roll",0,true);
	pose_pitch = configSource.read_float(iniSection,"pose_pitch",0,true);
	pose_yaw = configSource.read_float(iniSection,"pose_yaw",0,true);

}

/* -----------------------------------------------------
				tryToOpenTheCOM
----------------------------------------------------- */
bool  CRaePID::tryToOpenTheCOM()
{
    if (COM.isOpen())
        return true;	// Already open

    if (m_verbose) cout << "[CRaePID] Opening " << com_port << " @ " <<com_bauds << endl;

	try
	{
        COM.open(com_port);
        // Config:
        COM.setConfig( com_bauds, 0, 8, 1 );
        //COM.setTimeouts( 1, 0, 1, 1, 1 );
		COM.setTimeouts(50,1,100, 1,20);
		//mrpt::system::sleep(10);
		COM.purgeBuffers();
		//mrpt::system::sleep(10);

		return true; // All OK!
	}
	catch (std::exception &e)
	{
		std::cerr << "[CRaePID::tryToOpenTheCOM] Error opening or configuring the serial port:" << std::endl << e.what();
        COM.close();
		return false;
	}
	catch (...)
	{
		std::cerr << "[CRaePID::tryToOpenTheCOM] Error opening or configuring the serial port." << std::endl;
		COM.close();
		return false;
	}
}

/* -----------------------------------------------------
				doProcess
----------------------------------------------------- */
void CRaePID::doProcess()
{
	// Is the COM open?
	if (!tryToOpenTheCOM())
	{
		m_state = ssError;
		THROW_EXCEPTION("Cannot open the serial port");
	}

	bool have_reading = false;
	std::string power_reading;
	bool time_out = false;

	while (!have_reading)
	{
		// Send command to PID to request a measurement
		COM.purgeBuffers();
		COM.Write("R",1);

		// Read PID response
		power_reading = COM.ReadString(500,&time_out);
		if (time_out)
		{
			cout << "[CRaePID] " << com_port << " @ " <<com_bauds << " - measurement Timed-Out" << endl;
			sleep(10);
		}
		else
			have_reading = true;
	}

	cout << "[CRaePID] " << com_port << " @ " <<com_bauds << " - measurement -> " << power_reading << endl;

	// Convert the text to a number (ppm)
	const float readnum = atof(power_reading.c_str());
	const float val_ppm = readnum/1000;

	// Fill the observation
	mrpt::slam::CObservationGasSensors::TObservationENose obs;
	obs.readingsVoltage.push_back(val_ppm);
	obs.sensorTypes.push_back(0xFFFF);

	CObservationGasSensors obsG;
	obsG.sensorLabel = this->getSensorLabel();
	obsG.m_readings.push_back(obs);
	obsG.timestamp = now();

	appendObservation(CObservationGasSensorsPtr(new CObservationGasSensors(obsG)));

}

std::string CRaePID::getFirmware()
{
	// Send the command
	cout << "Firmware version: " << endl;
	COM.purgeBuffers();
	size_t B_written = COM.Write("F",1);

	// Read the returned text
	bool time_out = false;
	std::string s_read = COM.ReadString(2000,&time_out);
	if (time_out)
		s_read =  "Time_out";
	return s_read;
}

std::string CRaePID::getModel()
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("M",1);

	// Read the returned text
	return COM.ReadString();
}

std::string CRaePID::getSerialNumber()
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("S",1);

	// Read the returned text
	return COM.ReadString();
}

std::string CRaePID::getName()
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("N",1);

	// Read the returned text
	return COM.ReadString();

}

bool CRaePID::switchPower()
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("P",1);

	// Read the returned text
	std::string reading;
	reading = COM.ReadString();

	if (strcmp(reading.c_str(),"Sleep...")==0)
		return true;
	else
		return false;
}

CObservationGasSensors CRaePID::getFullInfo()
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("C",1);

	// Read the returned text
	std::string reading;
	reading = COM.ReadString();

	// Iterate over each information component (tokenize first)
	// construct a stream from the string (as seen in http://stackoverflow.com/a/53921)
	std::stringstream readings_str(reading);

	// use stream iterators to copy the stream to the vector as whitespace separated strings
	std::istream_iterator<std::string> it(readings_str);
	std::istream_iterator<std::string> endit;
	std::vector<std::string> measurements_text(it, endit);

	// Convert the text to a number (ppm)
	mrpt::slam::CObservationGasSensors::TObservationENose obs;
	CObservationGasSensors obsG;

	for (size_t k=0; k < measurements_text.size(); k++)
	{
		const float readnum = atof(measurements_text[k].c_str());
		const float val_ppm = readnum/1000.f;

		// Fill the observation
		obs.readingsVoltage.push_back(val_ppm);
		obsG.m_readings.push_back(obs);
	}

	obsG.sensorLabel = this->getSensorLabel();
	obsG.timestamp = now();

	return obsG;

}

bool CRaePID::errorStatus(std::string &errorString)
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("E",1);

	// Read the returned text
	std::string reading;
	reading = COM.ReadString();

	// Tokenize to separate the two components:
	// construct a stream from the string (as seen in http://stackoverflow.com/a/53921)
	std::stringstream readings_str(reading);

	// use stream iterators to copy the stream to the vector as whitespace separated strings
	std::istream_iterator<std::string> it(readings_str);
	std::istream_iterator<std::string> endit;
	std::vector<std::string> errors_text(it, endit);

	// Take the first part and check the possible error condition
	if((strcmp(errors_text[0].c_str(),"0")==0) && (strcmp(errors_text[1].c_str(),"0")==0)) // no error
	{
		return false;
	}
	else
	{
		// By the moment, return the raw error; note that if necessary a detailed description of the error can be obtained analyzing the two error strings separately
		errorString = reading;
		return true;
	}
}

void CRaePID::getLimits(float &min, float &max)
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("L",1);

	// Read the returned text
	std::string reading;
	reading = COM.ReadString();

	// Tokenize to separate the two components:
	// construct a stream from the string (as seen in http://stackoverflow.com/a/53921)
	std::stringstream readings_str(reading);

	// use stream iterators to copy the stream to the vector as whitespace separated strings
	std::istream_iterator<std::string> it(readings_str);
	std::istream_iterator<std::string> endit;
	std::vector<std::string> readings_text(it, endit);

	// read min and max
	max = atof(readings_text[0].c_str());
	min = atof(readings_text[1].c_str());

}
<commit_msg>CRaePID: fixed GCC warning<commit_after>/* +---------------------------------------------------------------------------+
   |                 The Mobile Robot Programming Toolkit (MRPT)               |
   |                                                                           |
   |                          http://www.mrpt.org/                             |
   |                                                                           |
   | Copyright (c) 2005-2013, Individual contributors, see AUTHORS file        |
   | Copyright (c) 2005-2013, MAPIR group, University of Malaga                |
   | Copyright (c) 2012-2013, University of Almeria                            |
   | 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 the copyright holders nor the                    |
   |      names of its contributors may be used to endorse or promote products |
   |      derived from this software without specific prior written permission.|
   |                                                                           |
   | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS       |
   | 'AS IS' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED |
   | TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR|
   | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS 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 <mrpt/hwdrivers.h>  // Precompiled headers
#include <mrpt/hwdrivers/CRaePID.h>

#include <iostream>
#include <sstream>

using namespace mrpt::utils;
using namespace mrpt::hwdrivers;

IMPLEMENTS_GENERIC_SENSOR(CRaePID,mrpt::hwdrivers)

/* -----------------------------------------------------
                Constructor
   ----------------------------------------------------- */
CRaePID::CRaePID()
{
	m_sensorLabel = "RAE_PID";
}

/* -----------------------------------------------------
                loadConfig_sensorSpecific
   ----------------------------------------------------- */
void  CRaePID::loadConfig_sensorSpecific(
	const mrpt::utils::CConfigFileBase &configSource,
	const std::string			&iniSection )
{
#ifdef MRPT_OS_WINDOWS
	com_port = configSource.read_string(iniSection, "COM_port_PID", "COM1", true ) ;
#else
	com_port = configSource.read_string(iniSection, "COM_port_PID", "/dev/tty0", true );
#endif

	com_bauds		= configSource.read_int( iniSection, "baudRate",9600, false );

	pose_x = configSource.read_float(iniSection,"pose_x",0,true);
	pose_y = configSource.read_float(iniSection,"pose_y",0,true);
	pose_z = configSource.read_float(iniSection,"pose_z",0,true);
	pose_roll = configSource.read_float(iniSection,"pose_roll",0,true);
	pose_pitch = configSource.read_float(iniSection,"pose_pitch",0,true);
	pose_yaw = configSource.read_float(iniSection,"pose_yaw",0,true);

}

/* -----------------------------------------------------
				tryToOpenTheCOM
----------------------------------------------------- */
bool  CRaePID::tryToOpenTheCOM()
{
    if (COM.isOpen())
        return true;	// Already open

    if (m_verbose) cout << "[CRaePID] Opening " << com_port << " @ " <<com_bauds << endl;

	try
	{
        COM.open(com_port);
        // Config:
        COM.setConfig( com_bauds, 0, 8, 1 );
        //COM.setTimeouts( 1, 0, 1, 1, 1 );
		COM.setTimeouts(50,1,100, 1,20);
		//mrpt::system::sleep(10);
		COM.purgeBuffers();
		//mrpt::system::sleep(10);

		return true; // All OK!
	}
	catch (std::exception &e)
	{
		std::cerr << "[CRaePID::tryToOpenTheCOM] Error opening or configuring the serial port:" << std::endl << e.what();
        COM.close();
		return false;
	}
	catch (...)
	{
		std::cerr << "[CRaePID::tryToOpenTheCOM] Error opening or configuring the serial port." << std::endl;
		COM.close();
		return false;
	}
}

/* -----------------------------------------------------
				doProcess
----------------------------------------------------- */
void CRaePID::doProcess()
{
	// Is the COM open?
	if (!tryToOpenTheCOM())
	{
		m_state = ssError;
		THROW_EXCEPTION("Cannot open the serial port");
	}

	bool have_reading = false;
	std::string power_reading;
	bool time_out = false;

	while (!have_reading)
	{
		// Send command to PID to request a measurement
		COM.purgeBuffers();
		COM.Write("R",1);

		// Read PID response
		power_reading = COM.ReadString(500,&time_out);
		if (time_out)
		{
			cout << "[CRaePID] " << com_port << " @ " <<com_bauds << " - measurement Timed-Out" << endl;
			sleep(10);
		}
		else
			have_reading = true;
	}

	cout << "[CRaePID] " << com_port << " @ " <<com_bauds << " - measurement -> " << power_reading << endl;

	// Convert the text to a number (ppm)
	const float readnum = atof(power_reading.c_str());
	const float val_ppm = readnum/1000;

	// Fill the observation
	mrpt::slam::CObservationGasSensors::TObservationENose obs;
	obs.readingsVoltage.push_back(val_ppm);
	obs.sensorTypes.push_back(0xFFFF);

	CObservationGasSensors obsG;
	obsG.sensorLabel = this->getSensorLabel();
	obsG.m_readings.push_back(obs);
	obsG.timestamp = now();

	appendObservation(CObservationGasSensorsPtr(new CObservationGasSensors(obsG)));

}

std::string CRaePID::getFirmware()
{
	// Send the command
	cout << "Firmware version: " << endl;
	COM.purgeBuffers();
	size_t B_written = COM.Write("F",1);
	if (!B_written) return std::string("COMMS.ERROR");

	// Read the returned text
	bool time_out = false;
	std::string s_read = COM.ReadString(2000,&time_out);
	if (time_out)
		s_read =  "Time_out";
	return s_read;
}

std::string CRaePID::getModel()
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("M",1);

	// Read the returned text
	return COM.ReadString();
}

std::string CRaePID::getSerialNumber()
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("S",1);

	// Read the returned text
	return COM.ReadString();
}

std::string CRaePID::getName()
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("N",1);

	// Read the returned text
	return COM.ReadString();

}

bool CRaePID::switchPower()
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("P",1);

	// Read the returned text
	std::string reading;
	reading = COM.ReadString();

	if (strcmp(reading.c_str(),"Sleep...")==0)
		return true;
	else
		return false;
}

CObservationGasSensors CRaePID::getFullInfo()
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("C",1);

	// Read the returned text
	std::string reading;
	reading = COM.ReadString();

	// Iterate over each information component (tokenize first)
	// construct a stream from the string (as seen in http://stackoverflow.com/a/53921)
	std::stringstream readings_str(reading);

	// use stream iterators to copy the stream to the vector as whitespace separated strings
	std::istream_iterator<std::string> it(readings_str);
	std::istream_iterator<std::string> endit;
	std::vector<std::string> measurements_text(it, endit);

	// Convert the text to a number (ppm)
	mrpt::slam::CObservationGasSensors::TObservationENose obs;
	CObservationGasSensors obsG;

	for (size_t k=0; k < measurements_text.size(); k++)
	{
		const float readnum = atof(measurements_text[k].c_str());
		const float val_ppm = readnum/1000.f;

		// Fill the observation
		obs.readingsVoltage.push_back(val_ppm);
		obsG.m_readings.push_back(obs);
	}

	obsG.sensorLabel = this->getSensorLabel();
	obsG.timestamp = now();

	return obsG;

}

bool CRaePID::errorStatus(std::string &errorString)
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("E",1);

	// Read the returned text
	std::string reading;
	reading = COM.ReadString();

	// Tokenize to separate the two components:
	// construct a stream from the string (as seen in http://stackoverflow.com/a/53921)
	std::stringstream readings_str(reading);

	// use stream iterators to copy the stream to the vector as whitespace separated strings
	std::istream_iterator<std::string> it(readings_str);
	std::istream_iterator<std::string> endit;
	std::vector<std::string> errors_text(it, endit);

	// Take the first part and check the possible error condition
	if((strcmp(errors_text[0].c_str(),"0")==0) && (strcmp(errors_text[1].c_str(),"0")==0)) // no error
	{
		return false;
	}
	else
	{
		// By the moment, return the raw error; note that if necessary a detailed description of the error can be obtained analyzing the two error strings separately
		errorString = reading;
		return true;
	}
}

void CRaePID::getLimits(float &min, float &max)
{
	// Send the command
	COM.purgeBuffers();
	COM.Write("L",1);

	// Read the returned text
	std::string reading;
	reading = COM.ReadString();

	// Tokenize to separate the two components:
	// construct a stream from the string (as seen in http://stackoverflow.com/a/53921)
	std::stringstream readings_str(reading);

	// use stream iterators to copy the stream to the vector as whitespace separated strings
	std::istream_iterator<std::string> it(readings_str);
	std::istream_iterator<std::string> endit;
	std::vector<std::string> readings_text(it, endit);

	// read min and max
	max = atof(readings_text[0].c_str());
	min = atof(readings_text[1].c_str());

}
<|endoftext|>


<commit_before>#include "ui/socket_item.h"

#include <QApplication>
#include <QCursor>
#include <QDebug>
#include <QDrag>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsWidget>
#include <QMimeData>
#include <QWidget>

#include "elements/package.h"
#include "ui/colors.h"
#include "ui/link_item.h"
#include "ui/package_view.h"

SocketItem::SocketItem(Type a_type, QGraphicsItem *const a_parent)
  : QGraphicsItem{ a_parent }
  , m_type{ a_type }
{
  m_font.setFamily("Consolas");
  m_font.setPointSize(12);

  setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable |
           QGraphicsItem::ItemSendsScenePositionChanges);
  setAcceptHoverEvents(true);
  setAcceptedMouseButtons(Qt::LeftButton);

  setZValue(1);

  if (a_type == Type::eOutput)
    setCursor(Qt::OpenHandCursor);
  else
    setAcceptDrops(true);
}

QRectF SocketItem::boundingRect() const
{
  return QRectF{ -(static_cast<qreal>(SIZE) / 2.), 0, static_cast<qreal>(SIZE), static_cast<qreal>(SIZE) };
}

void SocketItem::paint(QPainter *a_painter, const QStyleOptionGraphicsItem *a_option, QWidget *a_widget)
{
  Q_UNUSED(a_option);
  Q_UNUSED(a_widget);

  QRectF const rect{ boundingRect() };

  QPen pen{ get_color(Color::eSocketBorder) };
  pen.setWidth(2);

  QBrush brush{};
  if (m_isHover)
    brush.setColor(get_color(Color::eSocketHover));
  else if (m_isDrop)
    brush.setColor(get_color(Color::eSocketDrop));
  else if (m_isSignalOn)
    brush.setColor(m_colorSignalOn);
  else if (!m_isSignalOn)
    brush.setColor(m_colorSignalOff);
  //  else if (m_type == Type::eInput)
  //    brush.setColor(config.getColor(Config::Color::eSocketInput));
  //  else if (m_type == Type::eOutput)
  //    brush.setColor(config.getColor(Config::Color::eSocketOutput));
  brush.setStyle(Qt::SolidPattern);

  a_painter->setPen(pen);
  a_painter->setBrush(brush);
  a_painter->drawEllipse(rect);

  if (m_used) {
    a_painter->save();
    a_painter->setPen(Qt::NoPen);
    a_painter->setBrush(pen.color());
    a_painter->drawEllipse(rect.adjusted(4, 4, -4, -4));
    a_painter->restore();
  }

  if (!m_nameHidden) {
    pen.setColor(get_color(Color::eFontName));
    a_painter->setPen(pen);
    QFont font{ a_painter->font() };
    font.setPointSize(12);
    a_painter->setFont(font);

    QFontMetrics const metrics{ font };

    if (m_type == Type::eInput)
      a_painter->drawText(static_cast<int>(rect.width()) - 2, 13, m_name);
    else
      a_painter->drawText(-metrics.width(m_name) - 14, 13, m_name);
  }
}

void SocketItem::hoverEnterEvent(QGraphicsSceneHoverEvent *a_event)
{
  Q_UNUSED(a_event);

  m_isHover = true;

  for (auto const link : m_links) link->setHover(m_isHover);
}

void SocketItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *a_event)
{
  Q_UNUSED(a_event);

  m_isHover = false;

  for (auto const link : m_links) link->setHover(m_isHover);
}

void SocketItem::dragEnterEvent(QGraphicsSceneDragDropEvent *a_event)
{
  Q_UNUSED(a_event);

  if (m_used) {
    a_event->ignore();
    return;
  }

  PackageView *const view{ reinterpret_cast<PackageView *const>(scene()->views()[0]) };

  LinkItem *const linkItem{ view->dragLink() };
  if (!linkItem || m_valueType != linkItem->valueType()) {
    a_event->ignore();
    return;
  }

  linkItem->setTo(this);
  m_isDrop = true;
}

void SocketItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *a_event)
{
  Q_UNUSED(a_event);

  m_isDrop = false;

  PackageView *const view{ reinterpret_cast<PackageView *const>(scene()->views()[0]) };

  LinkItem *const linkItem{ view->dragLink() };
  if (!linkItem) return;
  linkItem->setTo(nullptr);
}

void SocketItem::dragMoveEvent(QGraphicsSceneDragDropEvent *a_event)
{
  Q_UNUSED(a_event);
}

void SocketItem::dropEvent(QGraphicsSceneDragDropEvent *a_event)
{
  Q_UNUSED(a_event);

  PackageView *const packageView{ reinterpret_cast<PackageView *const>(scene()->views()[0]) };

  LinkItem *const linkItem{ packageView->dragLink() };
  if (!linkItem) return;

  m_links.push_back(linkItem);
  linkItem->setTo(this);
  m_used = true;
  m_isDrop = false;

  packageView->acceptDragLink();

  auto const package = packageView->package();
  auto const from = linkItem->from();

  package->connect(from->elementId(), from->socketId(), m_elementId, m_socketId);

  setSignal(linkItem->isSignalOn());
}

void SocketItem::mousePressEvent(QGraphicsSceneMouseEvent *a_event)
{
  Q_UNUSED(a_event);

  if (m_type == Type::eInput) return;

  setCursor(Qt::ClosedHandCursor);
}

void SocketItem::mouseMoveEvent(QGraphicsSceneMouseEvent *a_event)
{
  Q_UNUSED(a_event);

  if (m_type == Type::eInput) return;

  if (QLineF(a_event->screenPos(), a_event->buttonDownScreenPos(Qt::LeftButton)).length() <
      QApplication::startDragDistance())
    return;

  //  QRectF const rect{ boundingRect() };

  QDrag *const drag = new QDrag(a_event->widget());

  QMimeData *const mime = new QMimeData;
  //  mime->setData("data/x-element", QByteArray());
  drag->setMimeData(mime);

  LinkItem *linkItem{ new LinkItem };
  linkItem->setColors(m_colorSignalOff, m_colorSignalOn);
  linkItem->setFrom(this);

  scene()->addItem(linkItem);

  PackageView *const view{ reinterpret_cast<PackageView *const>(scene()->views()[0]) };
  view->setDragLink(linkItem);

  Qt::DropAction const action{ drag->exec() };
  if (action == Qt::IgnoreAction)
    view->cancelDragLink();
  else {
    m_links.push_back(linkItem);
    m_used = true;
  }

  setCursor(Qt::OpenHandCursor);
}

void SocketItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *a_event)
{
  Q_UNUSED(a_event);

  if (m_type == Type::eInput) return;

  setCursor(Qt::OpenHandCursor);
}

QVariant SocketItem::itemChange(QGraphicsItem::GraphicsItemChange a_change, const QVariant &a_value)
{
  if (a_change == QGraphicsItem::ItemScenePositionHasChanged) {
    for (LinkItem *const link : m_links) link->trackNodes();
  }
  return QGraphicsItem::itemChange(a_change, a_value);
}

int SocketItem::nameWidth() const
{
  QFontMetrics const metrics{ m_font };
  return metrics.width(m_name);
}

void SocketItem::setColors(QColor const a_signalOff, QColor const a_signalOn)
{
  m_colorSignalOff = a_signalOff;
  m_colorSignalOn = a_signalOn;
}

void SocketItem::setSignal(const bool a_signal)
{
  m_isSignalOn = a_signal;

  if (m_type == Type::eOutput)
    for (LinkItem *const link : m_links) link->setSignal(a_signal);
}

void SocketItem::connect(SocketItem *const a_other)
{
  auto const linkItem = new LinkItem;
  linkItem->setColors(m_colorSignalOff, m_colorSignalOn);
  linkItem->setFrom(this);
  linkItem->setTo(a_other);

  m_links.push_back(linkItem);
  m_used = true;

  a_other->m_links.push_back(linkItem);
  a_other->m_used = true;
  a_other->m_isDrop = false;

  scene()->addItem(linkItem);
}
<commit_msg>Fix SocketItem::mouseMoveEvent<commit_after>#include "ui/socket_item.h"

#include <QApplication>
#include <QCursor>
#include <QDebug>
#include <QDrag>
#include <QGraphicsSceneMouseEvent>
#include <QGraphicsWidget>
#include <QMimeData>
#include <QWidget>

#include "elements/package.h"
#include "ui/colors.h"
#include "ui/link_item.h"
#include "ui/package_view.h"

SocketItem::SocketItem(Type a_type, QGraphicsItem *const a_parent)
  : QGraphicsItem{ a_parent }
  , m_type{ a_type }
{
  m_font.setFamily("Consolas");
  m_font.setPointSize(12);

  setFlags(QGraphicsItem::ItemIsMovable | QGraphicsItem::ItemIsFocusable |
           QGraphicsItem::ItemSendsScenePositionChanges);
  setAcceptHoverEvents(true);
  setAcceptedMouseButtons(Qt::LeftButton);

  setZValue(1);

  if (a_type == Type::eOutput)
    setCursor(Qt::OpenHandCursor);
  else
    setAcceptDrops(true);
}

QRectF SocketItem::boundingRect() const
{
  return QRectF{ -(static_cast<qreal>(SIZE) / 2.), 0, static_cast<qreal>(SIZE), static_cast<qreal>(SIZE) };
}

void SocketItem::paint(QPainter *a_painter, const QStyleOptionGraphicsItem *a_option, QWidget *a_widget)
{
  Q_UNUSED(a_option);
  Q_UNUSED(a_widget);

  QRectF const rect{ boundingRect() };

  QPen pen{ get_color(Color::eSocketBorder) };
  pen.setWidth(2);

  QBrush brush{};
  if (m_isHover)
    brush.setColor(get_color(Color::eSocketHover));
  else if (m_isDrop)
    brush.setColor(get_color(Color::eSocketDrop));
  else if (m_isSignalOn)
    brush.setColor(m_colorSignalOn);
  else if (!m_isSignalOn)
    brush.setColor(m_colorSignalOff);
  //  else if (m_type == Type::eInput)
  //    brush.setColor(config.getColor(Config::Color::eSocketInput));
  //  else if (m_type == Type::eOutput)
  //    brush.setColor(config.getColor(Config::Color::eSocketOutput));
  brush.setStyle(Qt::SolidPattern);

  a_painter->setPen(pen);
  a_painter->setBrush(brush);
  a_painter->drawEllipse(rect);

  if (m_used) {
    a_painter->save();
    a_painter->setPen(Qt::NoPen);
    a_painter->setBrush(pen.color());
    a_painter->drawEllipse(rect.adjusted(4, 4, -4, -4));
    a_painter->restore();
  }

  if (!m_nameHidden) {
    pen.setColor(get_color(Color::eFontName));
    a_painter->setPen(pen);
    QFont font{ a_painter->font() };
    font.setPointSize(12);
    a_painter->setFont(font);

    QFontMetrics const metrics{ font };

    if (m_type == Type::eInput)
      a_painter->drawText(static_cast<int>(rect.width()) - 2, 13, m_name);
    else
      a_painter->drawText(-metrics.width(m_name) - 14, 13, m_name);
  }
}

void SocketItem::hoverEnterEvent(QGraphicsSceneHoverEvent *a_event)
{
  Q_UNUSED(a_event);

  m_isHover = true;

  for (auto const link : m_links) link->setHover(m_isHover);
}

void SocketItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *a_event)
{
  Q_UNUSED(a_event);

  m_isHover = false;

  for (auto const link : m_links) link->setHover(m_isHover);
}

void SocketItem::dragEnterEvent(QGraphicsSceneDragDropEvent *a_event)
{
  Q_UNUSED(a_event);

  if (m_used) {
    a_event->ignore();
    return;
  }

  PackageView *const view{ reinterpret_cast<PackageView *const>(scene()->views()[0]) };

  LinkItem *const linkItem{ view->dragLink() };
  if (!linkItem || m_valueType != linkItem->valueType()) {
    a_event->ignore();
    return;
  }

  linkItem->setTo(this);
  m_isDrop = true;
}

void SocketItem::dragLeaveEvent(QGraphicsSceneDragDropEvent *a_event)
{
  Q_UNUSED(a_event);

  m_isDrop = false;

  PackageView *const view{ reinterpret_cast<PackageView *const>(scene()->views()[0]) };

  LinkItem *const linkItem{ view->dragLink() };
  if (!linkItem) return;
  linkItem->setTo(nullptr);
}

void SocketItem::dragMoveEvent(QGraphicsSceneDragDropEvent *a_event)
{
  Q_UNUSED(a_event);
}

void SocketItem::dropEvent(QGraphicsSceneDragDropEvent *a_event)
{
  Q_UNUSED(a_event);

  PackageView *const packageView{ reinterpret_cast<PackageView *const>(scene()->views()[0]) };

  LinkItem *const linkItem{ packageView->dragLink() };
  if (!linkItem) return;

  m_links.push_back(linkItem);
  linkItem->setTo(this);
  m_used = true;
  m_isDrop = false;

  packageView->acceptDragLink();

  auto const package = packageView->package();
  auto const from = linkItem->from();

  package->connect(from->elementId(), from->socketId(), m_elementId, m_socketId);

  setSignal(linkItem->isSignalOn());
}

void SocketItem::mousePressEvent(QGraphicsSceneMouseEvent *a_event)
{
  Q_UNUSED(a_event);

  if (m_type == Type::eInput) return;

  setCursor(Qt::ClosedHandCursor);
}

void SocketItem::mouseMoveEvent(QGraphicsSceneMouseEvent *a_event)
{
  Q_UNUSED(a_event);

  if (m_type == Type::eInput) return;

  if (QLineF(a_event->screenPos(), a_event->buttonDownScreenPos(Qt::LeftButton)).length() <
      QApplication::startDragDistance())
    return;

  QDrag *const drag = new QDrag(a_event->widget());

  QMimeData *const mime = new QMimeData;
  drag->setMimeData(mime);

  LinkItem *linkItem{ new LinkItem };
  linkItem->setColors(m_colorSignalOff, m_colorSignalOn);
  linkItem->setValueType(m_valueType);
  linkItem->setFrom(this);
  linkItem->setSignal(m_isSignalOn);

  scene()->addItem(linkItem);
  m_links.push_back(linkItem);

  PackageView *const view{ reinterpret_cast<PackageView *const>(scene()->views()[0]) };
  view->setDragLink(linkItem);

  Qt::DropAction const action{ drag->exec() };
  if (action == Qt::IgnoreAction) {
    m_links.removeAll(linkItem);
    scene()->removeItem(linkItem);
    view->cancelDragLink();
  } else
    m_used = true;

  setCursor(Qt::OpenHandCursor);
}

void SocketItem::mouseReleaseEvent(QGraphicsSceneMouseEvent *a_event)
{
  Q_UNUSED(a_event);

  if (m_type == Type::eInput) return;

  setCursor(Qt::OpenHandCursor);
}

QVariant SocketItem::itemChange(QGraphicsItem::GraphicsItemChange a_change, const QVariant &a_value)
{
  if (a_change == QGraphicsItem::ItemScenePositionHasChanged) {
    for (LinkItem *const link : m_links) link->trackNodes();
  }
  return QGraphicsItem::itemChange(a_change, a_value);
}

int SocketItem::nameWidth() const
{
  QFontMetrics const metrics{ m_font };
  return metrics.width(m_name);
}

void SocketItem::setColors(QColor const a_signalOff, QColor const a_signalOn)
{
  m_colorSignalOff = a_signalOff;
  m_colorSignalOn = a_signalOn;
}

void SocketItem::setSignal(const bool a_signal)
{
  m_isSignalOn = a_signal;

  if (m_type == Type::eOutput)
    for (LinkItem *const link : m_links) link->setSignal(a_signal);
}

void SocketItem::connect(SocketItem *const a_other)
{
  auto const linkItem = new LinkItem;
  linkItem->setColors(m_colorSignalOff, m_colorSignalOn);
  linkItem->setValueType(m_valueType);
  linkItem->setFrom(this);
  linkItem->setTo(a_other);

  m_links.push_back(linkItem);
  m_used = true;

  a_other->m_links.push_back(linkItem);
  a_other->m_used = true;
  a_other->m_isDrop = false;

  scene()->addItem(linkItem);
}
<|endoftext|>


<commit_before>#include <stdexcept>
#include <iostream>
#include <iomanip>
#include <sstream>
#include <string>
using namespace std;

int main()
{
	int n;
	cin>>n;
	int countn = 0;double sum = 0.0;
	for(int i = 0;i < n;i++)
    {
        string temps;
        double tempd;
        cin>>temps;
        bool flag = true;
        try{tempd = stof(temps);}
        catch(invalid_argument e) {flag = false;}
        if(flag)
        {
            stringstream ss;
            ss << temps;
            ss >> tempd;
            ss.clear();
            ss.str("");
            if(tempd >= -1000 && tempd <= 1000)
            {
                if(tempd*100 - (int)(tempd*100) == 0)
                {
                    sum += tempd;
                    countn++;
                }
                else flag = false;
            }
            else flag = false;
        }
        if(!flag) cout<<"ERROR: "<<temps<<" is not a legal number"<<endl;
    }
    cout.setf(ios::fixed);
    if(!countn) cout<<"The average of 0 numbers is Undefined"<<endl;
    else if(countn == 1) cout<<"The average of "<<countn<<" number is "<<setprecision(2)<<sum/countn<<endl;
    else cout<<"The average of "<<countn<<" numbers is "<<setprecision(2)<<sum/countn<<endl;
}
<commit_msg>Update 1054.cpp<commit_after>#include <stdexcept>
#include <algorithm>
#include <iostream>
#include <iomanip>
#include <string>
#include <cctype>
using namespace std;

int main()
{
    int n;
    cin>>n;
    int countn = 0;double sum = 0.0;
    for(int i = 0;i < n;i++)
    {
        string temps;
        double tempd;
        cin>>temps;
        bool flag = true;
        if(count(temps.begin(),temps.end(),'.') > 1) flag = false;
        try{tempd = stod(temps);}
        catch(invalid_argument e) {flag = false;}
        if((temps.end() - find(temps.begin(),temps.end(),'.')) > 3) flag = false;
        else if((!isdigit(temps.front()) && temps.front() != '-') || (temps.front() == '-' && !isdigit(*(temps.begin()+1)))) flag = false;
        if(flag)
        {
            tempd = stod(temps);
            if(tempd >= -1000.00 && tempd <= 1000.00)
            {
                sum += tempd;
                countn++;
            }
            else flag = false;
        }
        if(!flag) cout<<"ERROR: "<<temps<<" is not a legal number"<<endl;
    }
    cout.setf(ios::fixed);
    if(!countn) cout<<"The average of 0 numbers is Undefined"<<endl;
    else if(countn == 1) cout<<"The average of "<<countn<<" number is "<<setprecision(2)<<sum/countn<<endl;
    else cout<<"The average of "<<countn<<" numbers is "<<setprecision(2)<<sum/countn<<endl;
}
<|endoftext|>


<commit_before>#include <assert.h>
#include <stdlib.h>

extern "C"
void __cxa_pure_virtual(void) {
    /* Pure C++ virtual call; abort! */
    assert(false);
}

void* __weak operator new(size_t size) {
    return malloc(size);
}

void* __weak operator new[](size_t size) {
    return malloc(size);
}

void __weak operator delete(void *ptr) {
    free(ptr);
}

void __weak operator delete[](void *ptr) {
    free(ptr);
}
<commit_msg>Add new operator overloads from new C++ standards (C++11 on onward)<commit_after>#include <assert.h>
#include <stdlib.h>

extern "C"
void __cxa_pure_virtual(void) {
    /* Pure C++ virtual call; abort! */
    assert(false);
}

void* __weak operator new(size_t size) {
    return malloc(size);
}

void* __weak operator new[](size_t size) {
    return malloc(size);
}

void __weak operator delete(void* ptr) {
    free(ptr);
}

void __weak operator delete[](void* ptr) {
    free(ptr);
}

/*-
 * <https://en.cppreference.com/w/cpp/memory/new/operator_delete>
 *
 * Called if a user-defined replacement is provided, except that it's
 * unspecified whether other overloads or this overload is called when deleting
 * objects of incomplete type and arrays of non-class and trivially-destructible
 * class types.
 *
 * A memory allocator can use the given size to be more efficient */
void __weak operator delete(void* ptr, unsigned int) {
    free(ptr);
}
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  $RCSfile: spelldsp.hxx,v $
 *
 *  $Revision: 1.3 $
 *
 *  last change: $Author: tl $ $Date: 2001-06-05 11:28:25 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _LINGUISTIC_SPELLDSP_HXX_
#define _LINGUISTIC_SPELLDSP_HXX_

#include "lngopt.hxx"
#include "misc.hxx"
#include "iprcache.hxx"

#include <uno/lbnames.h>            // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
#include <cppuhelper/implbase1.hxx> // helper for implementations
#include <cppuhelper/implbase2.hxx> // helper for implementations
#include <cppuhelper/implbase7.hxx> // helper for implementations

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEDISPLAYNAME_HPP_
#include <com/sun/star/lang/XServiceDisplayName.hpp>
#endif
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValues.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/linguistic2/XSpellChecker.hpp>
#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp>

#ifndef _TOOLS_TABLE_HXX
#include <tools/table.hxx>
#endif

class LngSvcMgr;

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

class SeqLangSvcEntry_Spell
{
    friend class SpellCheckerDispatcher;
    friend static BOOL SvcListHasLanguage(
                            const SeqLangSvcEntry_Spell &rEntry,
                            INT16 nLanguage );

    ::com::sun::star::uno::Sequence< ::rtl::OUString >          aSvcImplNames;
    ::com::sun::star::uno::Sequence<
        ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XSpellChecker > >    aSvcRefs;
    ::com::sun::star::uno::Sequence<
        ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XSpellChecker1 > >   aSvc1Refs;

//  INT16           nLang;     //used as key in the table
    SvcFlags        aFlags;

public:
    SeqLangSvcEntry_Spell() {}
    SeqLangSvcEntry_Spell( const ::com::sun::star::uno::Sequence<
            ::rtl::OUString > &rSvcImplNames );
    ~SeqLangSvcEntry_Spell();

    BOOL    IsAlreadyWarned() const     { return aFlags.bAlreadyWarned != 0; }
    void    SetAlreadyWarned(BOOL bVal) { aFlags.bAlreadyWarned = 0 != bVal; }
    BOOL    IsDoWarnAgain() const       { return aFlags.bDoWarnAgain != 0; }
    void    SetDoWarnAgain(BOOL bVal)   { aFlags.bDoWarnAgain = 0 != bVal; }
};

DECLARE_TABLE( SpellSvcList, SeqLangSvcEntry_Spell * );

class SpellCheckerDispatcher :
    public cppu::WeakImplHelper2
    <
        ::com::sun::star::linguistic2::XSpellChecker,
        ::com::sun::star::linguistic2::XSpellChecker1
    >,
    public LinguDispatcher
{
    SpellSvcList        aSvcList;
    LinguOptions        aOpt;

    ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet >                     xPropSet;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSearchableDictionaryList >  xDicList;

    LngSvcMgr                   &rMgr;
    linguistic::IPRSpellCache   *pExtCache; // SpellCache for external SpellCheckers
                                    // (usually those not called via XSpellChecker1)
                                    // One for all of them.

    // disallow copy-constructor and assignment-operator for now
    SpellCheckerDispatcher(const SpellCheckerDispatcher &);
    SpellCheckerDispatcher & operator = (const SpellCheckerDispatcher &);

    inline linguistic::IPRSpellCache &  GetExtCache() const;

    inline ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet >
            GetPropSet();
    inline ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSearchableDictionaryList >
            GetDicList();

    void    ClearSvcList();

    BOOL    isValid_Impl(const ::rtl::OUString& aWord, INT16 nLanguage,
                    const ::com::sun::star::beans::PropertyValues& aProperties,
                    BOOL bCheckDics)
                throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException );

    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSpellAlternatives >
            spell_Impl(const ::rtl::OUString& aWord, INT16 nLanguage,
                    const ::com::sun::star::beans::PropertyValues& aProperties,
                    BOOL bCheckDics)
                throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException );

    BOOL    isValidInAny(const ::rtl::OUString& aWord,
                         const ::com::sun::star::uno::Sequence< INT16 >& aLanguages,
                         const ::com::sun::star::beans::PropertyValues& aProperties)
                throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException );

    com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSpellAlternatives >
            spellInAny(const ::rtl::OUString& aWord,
                       const ::com::sun::star::uno::Sequence< INT16 >& aLanguages,
                       const ::com::sun::star::beans::PropertyValues& aProperties,
                       INT16 nPreferredResultLang)
                throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException );

public:
    SpellCheckerDispatcher( LngSvcMgr &rLngSvcMgr );
    virtual ~SpellCheckerDispatcher();

    // XSupportedLocales (for XSpellChecker)
    virtual ::com::sun::star::uno::Sequence<
            ::com::sun::star::lang::Locale > SAL_CALL
        getLocales()
            throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL
        hasLocale( const ::com::sun::star::lang::Locale& aLocale )
            throw(::com::sun::star::uno::RuntimeException);

    // XSpellChecker
    virtual sal_Bool SAL_CALL
        isValid( const ::rtl::OUString& aWord,
                const ::com::sun::star::lang::Locale& aLocale,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL
        spell( const ::rtl::OUString& aWord,
                const ::com::sun::star::lang::Locale& aLocale,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);

    // XSupportedLanguages (for XSpellChecker1)
    virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL
        getLanguages()
            throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL
        hasLanguage( sal_Int16 nLanguage )
            throw(::com::sun::star::uno::RuntimeException);

    // XSpellChecker1 (same as XSpellChecker but sal_Int16 for language)
    virtual sal_Bool SAL_CALL
        isValid( const ::rtl::OUString& aWord, sal_Int16 nLanguage,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL
        spell( const ::rtl::OUString& aWord, sal_Int16 nLanguage,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);

    // LinguDispatcher
    virtual void
        SetServiceList( const ::com::sun::star::lang::Locale &rLocale,
                const ::com::sun::star::uno::Sequence<
                    rtl::OUString > &rSvcImplNames );
    virtual ::com::sun::star::uno::Sequence< rtl::OUString >
        GetServiceList( const ::com::sun::star::lang::Locale &rLocale ) const;
    virtual DspType
        GetDspType() const;
};

inline linguistic::IPRSpellCache & SpellCheckerDispatcher::GetExtCache() const
{
    return pExtCache ? *pExtCache : * new linguistic::IPRSpellCache( 997 );
}

inline ::com::sun::star::uno::Reference<
    ::com::sun::star::beans::XPropertySet >
        SpellCheckerDispatcher::GetPropSet()
{
    return xPropSet.is() ?
        xPropSet : xPropSet = linguistic::GetLinguProperties();
}

inline ::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XSearchableDictionaryList >
        SpellCheckerDispatcher::GetDicList()
{
    return xDicList.is() ?
        xDicList : xDicList = linguistic::GetSearchableDictionaryList();
}

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

#endif

<commit_msg>#87772# static modifier removed from friend declaration<commit_after>/*************************************************************************
 *
 *  $RCSfile: spelldsp.hxx,v $
 *
 *  $Revision: 1.4 $
 *
 *  last change: $Author: tl $ $Date: 2001-06-05 13:54:51 $
 *
 *  The Contents of this file are made available subject to the terms of
 *  either of the following licenses
 *
 *         - GNU Lesser General Public License Version 2.1
 *         - Sun Industry Standards Source License Version 1.1
 *
 *  Sun Microsystems Inc., October, 2000
 *
 *  GNU Lesser General Public License Version 2.1
 *  =============================================
 *  Copyright 2000 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
 *
 *
 *  Sun Industry Standards Source License Version 1.1
 *  =================================================
 *  The contents of this file are subject to the Sun Industry Standards
 *  Source License Version 1.1 (the "License"); You may not use this file
 *  except in compliance with the License. You may obtain a copy of the
 *  License at http://www.openoffice.org/license.html.
 *
 *  Software provided under this License is provided on an "AS IS" basis,
 *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
 *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
 *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
 *  See the License for the specific provisions governing your rights and
 *  obligations concerning the Software.
 *
 *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
 *
 *  Copyright: 2000 by Sun Microsystems, Inc.
 *
 *  All Rights Reserved.
 *
 *  Contributor(s): _______________________________________
 *
 *
 ************************************************************************/

#ifndef _LINGUISTIC_SPELLDSP_HXX_
#define _LINGUISTIC_SPELLDSP_HXX_

#include "lngopt.hxx"
#include "misc.hxx"
#include "iprcache.hxx"

#include <uno/lbnames.h>            // CPPU_CURRENT_LANGUAGE_BINDING_NAME macro, which specify the environment type
#include <cppuhelper/implbase1.hxx> // helper for implementations
#include <cppuhelper/implbase2.hxx> // helper for implementations
#include <cppuhelper/implbase7.hxx> // helper for implementations

#ifndef _COM_SUN_STAR_LANG_XCOMPONENT_HPP_
#include <com/sun/star/lang/XComponent.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XINITIALIZATION_HPP_
#include <com/sun/star/lang/XInitialization.hpp>
#endif
#ifndef _COM_SUN_STAR_LANG_XSERVICEDISPLAYNAME_HPP_
#include <com/sun/star/lang/XServiceDisplayName.hpp>
#endif
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/PropertyValues.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/linguistic2/XSpellChecker.hpp>
#include <com/sun/star/linguistic2/XSpellChecker1.hpp>
#include <com/sun/star/linguistic2/XSearchableDictionaryList.hpp>
#include <com/sun/star/linguistic2/XLinguServiceEventBroadcaster.hpp>

#ifndef _TOOLS_TABLE_HXX
#include <tools/table.hxx>
#endif

class LngSvcMgr;

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

class SeqLangSvcEntry_Spell
{
    friend class SpellCheckerDispatcher;
    friend BOOL SvcListHasLanguage(
                            const SeqLangSvcEntry_Spell &rEntry,
                            INT16 nLanguage );

    ::com::sun::star::uno::Sequence< ::rtl::OUString >          aSvcImplNames;
    ::com::sun::star::uno::Sequence<
        ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XSpellChecker > >    aSvcRefs;
    ::com::sun::star::uno::Sequence<
        ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XSpellChecker1 > >   aSvc1Refs;

//  INT16           nLang;     //used as key in the table
    SvcFlags        aFlags;

public:
    SeqLangSvcEntry_Spell() {}
    SeqLangSvcEntry_Spell( const ::com::sun::star::uno::Sequence<
            ::rtl::OUString > &rSvcImplNames );
    ~SeqLangSvcEntry_Spell();

    BOOL    IsAlreadyWarned() const     { return aFlags.bAlreadyWarned != 0; }
    void    SetAlreadyWarned(BOOL bVal) { aFlags.bAlreadyWarned = 0 != bVal; }
    BOOL    IsDoWarnAgain() const       { return aFlags.bDoWarnAgain != 0; }
    void    SetDoWarnAgain(BOOL bVal)   { aFlags.bDoWarnAgain = 0 != bVal; }
};

DECLARE_TABLE( SpellSvcList, SeqLangSvcEntry_Spell * );

class SpellCheckerDispatcher :
    public cppu::WeakImplHelper2
    <
        ::com::sun::star::linguistic2::XSpellChecker,
        ::com::sun::star::linguistic2::XSpellChecker1
    >,
    public LinguDispatcher
{
    SpellSvcList        aSvcList;
    LinguOptions        aOpt;

    ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet >                     xPropSet;
    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSearchableDictionaryList >  xDicList;

    LngSvcMgr                   &rMgr;
    linguistic::IPRSpellCache   *pExtCache; // SpellCache for external SpellCheckers
                                    // (usually those not called via XSpellChecker1)
                                    // One for all of them.

    // disallow copy-constructor and assignment-operator for now
    SpellCheckerDispatcher(const SpellCheckerDispatcher &);
    SpellCheckerDispatcher & operator = (const SpellCheckerDispatcher &);

    inline linguistic::IPRSpellCache &  GetExtCache() const;

    inline ::com::sun::star::uno::Reference<
        ::com::sun::star::beans::XPropertySet >
            GetPropSet();
    inline ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSearchableDictionaryList >
            GetDicList();

    void    ClearSvcList();

    BOOL    isValid_Impl(const ::rtl::OUString& aWord, INT16 nLanguage,
                    const ::com::sun::star::beans::PropertyValues& aProperties,
                    BOOL bCheckDics)
                throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException );

    ::com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSpellAlternatives >
            spell_Impl(const ::rtl::OUString& aWord, INT16 nLanguage,
                    const ::com::sun::star::beans::PropertyValues& aProperties,
                    BOOL bCheckDics)
                throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException );

    BOOL    isValidInAny(const ::rtl::OUString& aWord,
                         const ::com::sun::star::uno::Sequence< INT16 >& aLanguages,
                         const ::com::sun::star::beans::PropertyValues& aProperties)
                throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException );

    com::sun::star::uno::Reference<
        ::com::sun::star::linguistic2::XSpellAlternatives >
            spellInAny(const ::rtl::OUString& aWord,
                       const ::com::sun::star::uno::Sequence< INT16 >& aLanguages,
                       const ::com::sun::star::beans::PropertyValues& aProperties,
                       INT16 nPreferredResultLang)
                throw( ::com::sun::star::uno::RuntimeException, ::com::sun::star::lang::IllegalArgumentException );

public:
    SpellCheckerDispatcher( LngSvcMgr &rLngSvcMgr );
    virtual ~SpellCheckerDispatcher();

    // XSupportedLocales (for XSpellChecker)
    virtual ::com::sun::star::uno::Sequence<
            ::com::sun::star::lang::Locale > SAL_CALL
        getLocales()
            throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL
        hasLocale( const ::com::sun::star::lang::Locale& aLocale )
            throw(::com::sun::star::uno::RuntimeException);

    // XSpellChecker
    virtual sal_Bool SAL_CALL
        isValid( const ::rtl::OUString& aWord,
                const ::com::sun::star::lang::Locale& aLocale,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL
        spell( const ::rtl::OUString& aWord,
                const ::com::sun::star::lang::Locale& aLocale,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);

    // XSupportedLanguages (for XSpellChecker1)
    virtual ::com::sun::star::uno::Sequence< sal_Int16 > SAL_CALL
        getLanguages()
            throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL
        hasLanguage( sal_Int16 nLanguage )
            throw(::com::sun::star::uno::RuntimeException);

    // XSpellChecker1 (same as XSpellChecker but sal_Int16 for language)
    virtual sal_Bool SAL_CALL
        isValid( const ::rtl::OUString& aWord, sal_Int16 nLanguage,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Reference<
            ::com::sun::star::linguistic2::XSpellAlternatives > SAL_CALL
        spell( const ::rtl::OUString& aWord, sal_Int16 nLanguage,
                const ::com::sun::star::beans::PropertyValues& aProperties )
            throw(::com::sun::star::lang::IllegalArgumentException,
                  ::com::sun::star::uno::RuntimeException);

    // LinguDispatcher
    virtual void
        SetServiceList( const ::com::sun::star::lang::Locale &rLocale,
                const ::com::sun::star::uno::Sequence<
                    rtl::OUString > &rSvcImplNames );
    virtual ::com::sun::star::uno::Sequence< rtl::OUString >
        GetServiceList( const ::com::sun::star::lang::Locale &rLocale ) const;
    virtual DspType
        GetDspType() const;
};

inline linguistic::IPRSpellCache & SpellCheckerDispatcher::GetExtCache() const
{
    return pExtCache ? *pExtCache : * new linguistic::IPRSpellCache( 997 );
}

inline ::com::sun::star::uno::Reference<
    ::com::sun::star::beans::XPropertySet >
        SpellCheckerDispatcher::GetPropSet()
{
    return xPropSet.is() ?
        xPropSet : xPropSet = linguistic::GetLinguProperties();
}

inline ::com::sun::star::uno::Reference<
    ::com::sun::star::linguistic2::XSearchableDictionaryList >
        SpellCheckerDispatcher::GetDicList()
{
    return xDicList.is() ?
        xDicList : xDicList = linguistic::GetSearchableDictionaryList();
}

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

#endif

<|endoftext|>


<commit_before>void geom_cms_playback()
{
   TRecorder r("http://mtadel.home.cern.ch/mtadel/geom_cms_recording.root");
}
<commit_msg>Use new instead of normal constructor for TRecorder.<commit_after>void geom_cms_playback()
{
   TRecorder* r = new TRecorder("http://mtadel.home.cern.ch/mtadel/geom_cms_recording.root");
}
<|endoftext|>


<commit_before>/*  parse_bam.cc -- Example BAM parser

    Copyright (c) 2015, The Griffith Lab

    Author: Avinash Ramu <aramu@genome.wustl.edu>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.  */

#include <iostream>

#include "hts.h"
#include "sam.h"

using namespace std;

int usage() {
    cerr << "./parse_bam example.bam";
    return 0;
}

int main(int argc, char* argv[]) {
    if(argc < 2) {
        return usage();
    }
    string bam = string(argv[1]);
    string region_ = "";
    if(argc > 2) {
        region_ = string(argv[2]);
    }
    if(!bam.empty()) {
        //open BAM for reading
        samFile *in = sam_open(bam.c_str(), "r");
        if(in == NULL) {
            throw runtime_error("Unable to open BAM/SAM file.");
        }
        //Load the index
        hts_idx_t *idx = sam_index_load(in, bam.c_str());
        if(idx == NULL) {
            throw runtime_error("Unable to open BAM/SAM index."
                                " Make sure alignments are indexed");
        }
        //Get the header
        bam_hdr_t *header = sam_hdr_read(in);
        //Initialize iterator
        hts_itr_t *iter = NULL;
        //Move the iterator to the region we are interested in
        iter  = sam_itr_querys(idx, header, region_.c_str());
        if(header == NULL || iter == NULL) {
            sam_close(in);
            throw runtime_error("Unable to iterate to region within BAM.");
        }
        //Initiate the alignment record
        bam1_t *aln = bam_init1();
        while(sam_itr_next(in, iter, aln) >= 0) {
            cout << endl << aln->core.tid;
            cout << endl << aln->core.pos;
        }
        hts_itr_destroy(iter);
        hts_idx_destroy(idx);
        bam_destroy1(aln);
        bam_hdr_destroy(header);
        sam_close(in);
    }
    return 0;
}
<commit_msg>Copyright stuff<commit_after>/*  parse_bam.cc -- Example BAM parser using the htslib API

    Copyright (c) 2015, Washington University

    Author: Avinash Ramu <avinash3003@yahoo.co.in>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
DEALINGS IN THE SOFTWARE.  */

#include <iostream>

#include "hts.h"
#include "sam.h"

using namespace std;

int usage() {
    cerr << "./parse_bam example.bam";
    return 0;
}

int main(int argc, char* argv[]) {
    if(argc < 2) {
        return usage();
    }
    string bam = string(argv[1]);
    string region_ = "";
    if(argc > 2) {
        region_ = string(argv[2]);
    }
    if(!bam.empty()) {
        //open BAM for reading
        samFile *in = sam_open(bam.c_str(), "r");
        if(in == NULL) {
            throw runtime_error("Unable to open BAM/SAM file.");
        }
        //Load the index
        hts_idx_t *idx = sam_index_load(in, bam.c_str());
        if(idx == NULL) {
            throw runtime_error("Unable to open BAM/SAM index."
                                " Make sure alignments are indexed");
        }
        //Get the header
        bam_hdr_t *header = sam_hdr_read(in);
        //Initialize iterator
        hts_itr_t *iter = NULL;
        //Move the iterator to the region we are interested in
        iter  = sam_itr_querys(idx, header, region_.c_str());
        if(header == NULL || iter == NULL) {
            sam_close(in);
            throw runtime_error("Unable to iterate to region within BAM.");
        }
        //Initiate the alignment record
        bam1_t *aln = bam_init1();
        while(sam_itr_next(in, iter, aln) >= 0) {
            cout << endl << aln->core.tid;
            cout << endl << aln->core.pos;
        }
        hts_itr_destroy(iter);
        hts_idx_destroy(idx);
        bam_destroy1(aln);
        bam_hdr_destroy(header);
        sam_close(in);
    }
    return 0;
}
<|endoftext|>


<commit_before>#include <iostream>
#include <stdint.h>
#include <map>
#include <vector>
#include <string>

#include "api/BamReader.h"
#include "utils/bamtools_pileup_engine.h"
#include "utils/bamtools_fasta.h"

#include "model.h"

using namespace std;
using namespace BamTools;

typedef vector< string > SampleNames;
typedef map < string, int> ChrMap;

string get_sample(string& tag){
    string res;
    for(size_t i = 0; tag[i] != '_'; i++) {
        res.push_back(tag[i]);
    }
    return(res);
}

int find_sample_index(string s, SampleNames sv){
    for (size_t i=0; i < sv.size(); i++){
        if(s.compare(sv[i])==0){
            return i;
        }
    }
    cerr << "didn't find name " << s << endl;
    return(13); //TODO refactor this to  update sample in place
}

//int get_id_by_name(string chr, const Fasta& refseq){
//    int result = find_if(begin(refseq.FastaPrivate.Index),
//                         end(refseq.FastaPrivate.Index),
//                         [&](const FastaIndexData  &fid) {fid.Name == chr});
//   return result;
//}

uint16_t base_index(char b){
    switch(b){//TODO best 'null/npos' result for a short int?
        case 'A':
        case 'a':
            return 0;
         case 'T':
         case 't':
             return 3;
         case 'C':
         case 'c':
             return 1;
         case 'G':
         case 'g':
             return 2;
         case '-':
         case 'N':
             return 4;
         default:
             cerr << "Don't know what to make of base" << b <<endl;
             return 4;
    };
}

class VariantVisitor : public PileupVisitor{
    public:
        VariantVisitor(const RefVector& bam_references,
                       const Fasta fasta_references,
                       SampleNames samples,
                       const ModelParams& p,
                       BamAlignment& ali,
                       int q =13,
                       double prob_cutoff=0.1):

            PileupVisitor(), m_idx_ref(fasta_references), m_bam_ref(bam_references),
                             m_samples(samples), m_q(q), m_params(p), m_ali(ali)
            {
                nsamp = m_samples.size();
            }
        ~VariantVisitor(void) { }
    public:
         void Visit(const PileupPosition& pileupData) {
             string chr = m_bam_ref[pileupData.RefId].RefName;
             uint64_t pos  = pileupData.Position;
//             int chr_idx = get_id_by_name(pileupData.RefId, m_idx_ref);
             m_idx_ref.GetBase(pileupData.RefId, pos, current_base);
             ReadDataVector bcalls (nsamp, ReadData{{ 0,0,0,0 }}); //fill constructor
             string tag_id;
             for(auto it = begin(pileupData.PileupAlignments);
                      it != end(pileupData.PileupAlignments);
                      ++it){
                 int const *pos = &it->PositionInAlignment;
                 if (it->Alignment.Qualities[*pos] - 33 > m_q){
                     it->Alignment.GetTag("RG", tag_id);
                     int sindex = find_sample_index(get_sample(tag_id), m_samples);
                     size_t bindex  = base_index(it->Alignment.AlignedBases[*pos]);
                     if (bindex < 4){
                         bcalls[sindex].reads[bindex] += 1;
                     }
                 }
            }
            ModelInput d = {"", 1, base_index(current_base), bcalls};
            double prob = TetMAProbability(m_params,d);
            if(prob >= 0.0){//NOTE: Probablity cut off is hard-coded atm
             cout << chr << '\t' << pos << '\t' << current_base << '\t' <<
                 prob << '\t' << TetMAProbOneMutation(m_params,d) << endl;
            }
        }
    private:
        Fasta m_idx_ref;
        RefVector m_bam_ref;
        SampleNames m_samples;
        int m_q;
        int nsamp;
        ModelParams m_params;
        BamAlignment& m_ali;
        char current_base;
        uint64_t chr_index;

};

int main(){
    BamReader myBam;
    myBam.Open("test/test.bam");
    RefVector references = myBam.GetReferenceData();
    cerr << "buliding fasta index..." << endl;
    Fasta reference_genome;
    reference_genome.Open("test/test.fasta");
    reference_genome.CreateIndex("test/test.fai");
 //   ifstream idx ("test/test.fai");

    //bamtools api makes the actual index private
    //only public acess to a sequence is via it ID (index)
    //so need to make a map of them
//    string idx_line;
//    ChrMap idx_map;
//
//    while(getline(idx, idx_line)){
//        size_t i = 0;
//        string name;
//        int counter = 0;
//        for(; L[i] != '\t', i++){
//            name.push_back(L[i])
//        }
//        idx_map[name] = counter;
//        counter += 1;
//    }
//

    reference_genome.Close();
    reference_genome.Open("test/test.fasta", "test/test.fai");

    SampleNames all_samples {"M0", "M19", "M20", "M28","M25", "M29",
                             "M40", "M44","M47", "M50","M51", "M531"};
    ModelParams p = {
       0.001,
       {0.25, 0.25, 0.25, 0.25},
       1.0e-8,
       0.01,
       0.001,
       0.001,
    };
    BamAlignment ali;
    PileupEngine pileup;
    VariantVisitor *v = new VariantVisitor(references, reference_genome, all_samples,p, ali);
    pileup.AddVisitor(v);
    cerr << "calling variants" << endl;
    while( myBam.GetNextAlignment(ali)){
        pileup.AddAlignment(ali);

    };
    pileup.Flush();
    return 0;
}

<commit_msg>pass references by ref<commit_after>#include <iostream>
#include <stdint.h>
#include <map>
#include <vector>
#include <string>

#include "api/BamReader.h"
#include "utils/bamtools_pileup_engine.h"
#include "utils/bamtools_fasta.h"

#include "model.h"

using namespace std;
using namespace BamTools;

typedef vector< string > SampleNames;
typedef map < string, int> ChrMap;

string get_sample(string& tag){
    string res;
    for(size_t i = 0; tag[i] != '_'; i++) {
        res.push_back(tag[i]);
    }
    return(res);
}

int find_sample_index(string s, SampleNames sv){
    for (size_t i=0; i < sv.size(); i++){
        if(s.compare(sv[i])==0){
            return i;
        }
    }
    cerr << "didn't find name " << s << endl;
    return(13); //TODO refactor this to  update sample in place
}

//int get_id_by_name(string chr, const Fasta& refseq){
//    int result = find_if(begin(refseq.FastaPrivate.Index),
//                         end(refseq.FastaPrivate.Index),
//                         [&](const FastaIndexData  &fid) {fid.Name == chr});
//   return result;
//}

uint16_t base_index(char b){
    switch(b){//TODO best 'null/npos' result for a short int?
        case 'A':
        case 'a':
            return 0;
         case 'T':
         case 't':
             return 3;
         case 'C':
         case 'c':
             return 1;
         case 'G':
         case 'g':
             return 2;
         case '-':
         case 'N':
             return 4;
         default:
             cerr << "Don't know what to make of base" << b <<endl;
             return 4;
    };
}

class VariantVisitor : public PileupVisitor{
    public:
        VariantVisitor(const RefVector& bam_references,
                       const Fasta& fasta_references,
                       SampleNames samples,
                       const ModelParams& p,
                       BamAlignment& ali,
                       int q =13,
                       double prob_cutoff=0.1):

            PileupVisitor(), m_idx_ref(fasta_references), m_bam_ref(bam_references),
                             m_samples(samples), m_q(q), m_params(p), m_ali(ali)
            {
                nsamp = m_samples.size();
            }
        ~VariantVisitor(void) { }
    public:
         void Visit(const PileupPosition& pileupData) {
             string chr = m_bam_ref[pileupData.RefId].RefName;
             uint64_t pos  = pileupData.Position;
//             int chr_idx = get_id_by_name(pileupData.RefId, m_idx_ref);
             m_idx_ref.GetBase(pileupData.RefId, pos, current_base);
             ReadDataVector bcalls (nsamp, ReadData{{ 0,0,0,0 }}); //fill constructor
             string tag_id;
             for(auto it = begin(pileupData.PileupAlignments);
                      it != end(pileupData.PileupAlignments);
                      ++it){
                 int const *pos = &it->PositionInAlignment;
                 if (it->Alignment.Qualities[*pos] - 33 > m_q){
                     it->Alignment.GetTag("RG", tag_id);
                     int sindex = find_sample_index(get_sample(tag_id), m_samples);
                     size_t bindex  = base_index(it->Alignment.AlignedBases[*pos]);
                     if (bindex < 4){
                         bcalls[sindex].reads[bindex] += 1;
                     }
                 }
            }
            ModelInput d = {"", 1, base_index(current_base), bcalls};
            double prob = TetMAProbability(m_params,d);
            if(prob >= 0.0){//NOTE: Probablity cut off is hard-coded atm
             cout << chr << '\t' << pos << '\t' << current_base << '\t' <<
                 prob << '\t' << TetMAProbOneMutation(m_params,d) << endl;
            }
        }
    private:
        Fasta m_idx_ref;
        RefVector m_bam_ref;
        SampleNames m_samples;
        int m_q;
        int nsamp;
        ModelParams m_params;
        BamAlignment& m_ali;
        char current_base;
        uint64_t chr_index;

};

int main(){
    BamReader myBam;
    myBam.Open("test/test.bam");
    RefVector references = myBam.GetReferenceData();
    cerr << "buliding fasta index..." << endl;
    Fasta reference_genome;
    reference_genome.Open("test/test.fasta");
    reference_genome.CreateIndex("test/test.fai");
 //   ifstream idx ("test/test.fai");

    //bamtools api makes the actual index private
    //only public acess to a sequence is via it ID (index)
    //so need to make a map of them
//    string idx_line;
//    ChrMap idx_map;
//
//    while(getline(idx, idx_line)){
//        size_t i = 0;
//        string name;
//        int counter = 0;
//        for(; L[i] != '\t', i++){
//            name.push_back(L[i])
//        }
//        idx_map[name] = counter;
//        counter += 1;
//    }
//

    reference_genome.Close();
    reference_genome.Open("test/test.fasta", "test/test.fai");

    SampleNames all_samples {"M0", "M19", "M20", "M28","M25", "M29",
                             "M40", "M44","M47", "M50","M51", "M531"};
    ModelParams p = {
       0.001,
       {0.25, 0.25, 0.25, 0.25},
       1.0e-8,
       0.01,
       0.001,
       0.001,
    };
    BamAlignment ali;
    PileupEngine pileup;
    VariantVisitor *v = new VariantVisitor(references, reference_genome, all_samples,p, ali);
    pileup.AddVisitor(v);
    cerr << "calling variants" << endl;
    while( myBam.GetNextAlignment(ali)){
        pileup.AddAlignment(ali);

    };
    pileup.Flush();
    return 0;
}

<|endoftext|>