void tst_QFutureWatcher::resultAt()
{
    QFutureWatcher<int> futureWatcher;
    futureWatcher.setFuture((new IntTask())->start());
    futureWatcher.waitForFinished();
    QCOMPARE(futureWatcher.result(), 10);
    QCOMPARE(futureWatcher.resultAt(0), 10);
}
Exemple #2
0
void MainWindow::LoadFile()
{

    if (FileFormatPluginList.size()) {


        QString FileName = QFileDialog::getOpenFileName(this, tr("Open File"),
                                                     "",
                                                     FileFormatPluginList[0]->getFormatDescription());

        //test();
        // Create a progress dialog.
            QProgressDialog dialog;

            dialog.setLabelText(QString("Загрузка данных из файла"));

            // Create a QFutureWatcher and connect signals and slots.
            QFutureWatcher<void> futureWatcher;
            QTimer timer;
            connect(&timer, SIGNAL(timeout()), this, SLOT(updateProgress()));
            timer.start(1000);
            QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
            QObject::connect(&dialog, SIGNAL(canceled()), SLOT(cancelOperation()));
            QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
            QObject::connect(this, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));

            //extern void FileFormatPluginList[0]->getDataFromChannel(channel,(qint8*)data);


            QFuture<void> future = QtConcurrent::run(FileFormatPluginList[0], &FileReadInterface::LoadFile, FileName);

            // Start the computation.
            futureWatcher.setFuture(future);

            // Display the dialog and start the event loop.
            dialog.exec();

            futureWatcher.waitForFinished();
            dialog.setValue(100);
            dialog.hide();


            timer.stop();



        cube= FileFormatPluginList[0]->getCube();


        QList<double> list = cube->GetListOfChannels();




        foreach(double l , list) {
            ui->ChannelListWidget->addItem(QString("%1").arg(l));
        }
Exemple #3
0
void MainWindow::writeFile()
{
    QString filename = QFileDialog::getSaveFileName(this,
                                                    QString("Write fiff data file"),
                                                    QString("./MNE-sample-data/MEG/sample/"),
                                                    tr("fif data files (*.fif)"));

    if(filename.isEmpty()) {
        qDebug("User aborted saving to fiff data file");
        return;
    }

    if(filename == m_qFileRaw.fileName()) {
        QMessageBox msgBox;
        msgBox.setText("You are trying to write to the file you are currently loading the data from. Please choose another file to write to.");
        msgBox.exec();
        return;
    }

    //Create output file, progress dialog and future watcher
    QFile qFileOutput (filename);
    if(qFileOutput.isOpen())
        qFileOutput.close();

    QFutureWatcher<bool> writeFileFutureWatcher;
    QProgressDialog progressDialog("Writing to fif file...", QString(), 0, 0, this, Qt::Dialog);

    //Connect future watcher and dialog
    connect(&writeFileFutureWatcher, &QFutureWatcher<bool>::finished,
            &progressDialog, &QProgressDialog::reset);

    connect(&progressDialog, &QProgressDialog::canceled,
            &writeFileFutureWatcher, &QFutureWatcher<bool>::cancel);

    connect(m_pDataWindow->getDataModel(), &RawModel::writeProgressRangeChanged,
            &progressDialog, &QProgressDialog::setRange);

    connect(m_pDataWindow->getDataModel(), &RawModel::writeProgressChanged,
            &progressDialog, &QProgressDialog::setValue);

    //Run the file writing in seperate thread
    writeFileFutureWatcher.setFuture(QtConcurrent::run(m_pDataWindow->getDataModel(),
                                                         &RawModel::writeFiffData,
                                                         &qFileOutput));

    progressDialog.exec();

    writeFileFutureWatcher.waitForFinished();

    if(!writeFileFutureWatcher.future().result())
        qDebug() << "MainWindow: ERROR writing fiff data file" << qFileOutput.fileName() << "!";
    else
        qDebug() << "MainWindow: Successfully written to" << qFileOutput.fileName() << "!";
}
Exemple #4
0
void TaskDispatcher::cancelRunningTasks(bool wait)
{
  QMutexLocker locker(&mutex_);

  for (size_t i = 0, i_end = active_watchers_.size(); i < i_end; ++ i)
  {
    QFutureWatcher<void>* watcher = dynamic_cast<QFutureWatcher<void>*>(active_watchers_[i]);
    watcher->cancel();
    if (wait)
      watcher->waitForFinished();
  }

  return;
}
Exemple #5
0
int main(int argc, char **argv)
{
    QCoreApplication application(argc, argv);

    if(application.arguments().count() < 4+1) {
        qDebug() << "Usage:" << argv[0] << "order" << "width" << "height" << "output";
        return 0;
    }

// /////////////////////////////////////////////////////////////////
// Single concurrent run preprocessing
// /////////////////////////////////////////////////////////////////

    qtrRenderer::newtonOrder = application.arguments().value(1).toInt();

    qtrTile tile;
    tile.setWholeRect(QRect(0, 0,
        application.arguments().value(2).toInt(),
        application.arguments().value(3).toInt()));
    tile.setTileRect(QRect(0, 0,
        application.arguments().value(2).toInt(),
        application.arguments().value(3).toInt()));

// /////////////////////////////////////////////////////////////////
// Single concurrent run
// /////////////////////////////////////////////////////////////////

    QFuture<QImage> future = QtConcurrent::run(qtrRenderer::newtonImage, tile);

    QFutureWatcher<QImage> watcher;
    watcher.setFuture(future);
    watcher.waitForFinished();

// /////////////////////////////////////////////////////////////////
// Single concurrent run postprocessing
// /////////////////////////////////////////////////////////////////

    watcher.result().save(application.arguments().value(4));

    return 0;
}
Exemple #6
0
int main(int argc, char **argv)
{
	QApplication app(argc, argv);
	
	QVector<int> vector;
	
	for (int i=0; i<iterations; ++i)
		vector.append(i);

	QProgressDialog dialog;
	dialog.setLabelText(QString("Progressing using %1 thraed(s)...").arg(QThread::idealThreadCount()));

	QFutureWatcher<void> futureWatcher;
	QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
	QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
	QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int, int)), &dialog, SLOT(setRange(int, int)));
	QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));

	futureWatcher.setFuture(QtConcurrent::map(vector, spin));

	dialog.exec();
	futureWatcher.waitForFinished();
	qDebug() << "Canceled ?" << futureWatcher.future().isCanceled();
}
Exemple #7
0
/*
 * Fun flux analysis
 */
void FluxAnalysis::RunFluxAnalysis( QString nodeURL, QString surfaceSide, unsigned long nOfRays, bool increasePhotonMap, int heightDivisions, int widthDivisions )
{
	m_surfaceURL = nodeURL;
	m_surfaceSide = surfaceSide;

	//Delete a photonCounts
	if( m_photonCounts && m_photonCounts != 0 )
	{
		for( int h = 0; h < m_heightDivisions; h++ )
		{
			delete[] m_photonCounts[h];
		}

		delete[] m_photonCounts;
	}
	m_photonCounts = 0;
	m_heightDivisions = heightDivisions;
	m_widthDivisions = widthDivisions;

	//Check if there is a scene
	if ( !m_pCurrentScene )  return;

	//Check if there is a transmissivity defined
	TTransmissivity* transmissivity = 0;
	if ( !m_pCurrentScene->getPart( "transmissivity", false ) )	transmissivity = 0;
	else
		transmissivity = static_cast< TTransmissivity* > ( m_pCurrentScene->getPart( "transmissivity", false ) );

	//Check if there is a rootSeparator InstanceNode
	if( !m_pRootSeparatorInstance ) return;

	InstanceNode* sceneInstance = m_pRootSeparatorInstance->GetParent();
	if ( !sceneInstance )  return;

	//Check if there is a light and is properly configured
	if ( !m_pCurrentScene->getPart( "lightList[0]", false ) )return;
	TLightKit* lightKit = static_cast< TLightKit* >( m_pCurrentScene->getPart( "lightList[0]", false ) );

	InstanceNode* lightInstance = sceneInstance->children[0];
	if ( !lightInstance ) return;

	if( !lightKit->getPart( "tsunshape", false ) ) return;
	TSunShape* sunShape = static_cast< TSunShape * >( lightKit->getPart( "tsunshape", false ) );

	if( !lightKit->getPart( "icon", false ) ) return;
	TLightShape* raycastingSurface = static_cast< TLightShape * >( lightKit->getPart( "icon", false ) );

	if( !lightKit->getPart( "transform" ,false ) ) return;
	SoTransform* lightTransform = static_cast< SoTransform * >( lightKit->getPart( "transform" ,false ) );

	//Check if there is a random generator is defined.
	if( !m_pRandomDeviate || m_pRandomDeviate== 0 )	return;

	//Check if the surface and the surface side defined is suitable
	if( CheckSurface() == false || CheckSurfaceSide() == false ) return;

	//Create the photon map where photons are going to be stored
	if( !m_pPhotonMap  || !increasePhotonMap )
	{
		if( m_pPhotonMap ) 	m_pPhotonMap->EndStore( -1 );
		delete m_pPhotonMap;
		m_pPhotonMap = new TPhotonMap();
		m_pPhotonMap->SetBufferSize( HUGE_VAL );
		m_tracedRays = 0;
		m_wPhoton = 0;
		m_totalPower = 0;
	}

	QVector< InstanceNode* > exportSuraceList;
	QModelIndex nodeIndex = m_pCurrentSceneModel->IndexFromNodeUrl( m_surfaceURL );
	if( !nodeIndex.isValid()  )	return;

	InstanceNode* surfaceNode = m_pCurrentSceneModel->NodeFromIndex( nodeIndex );
	if( !surfaceNode || surfaceNode == 0 )	return;
	exportSuraceList.push_back( surfaceNode );

	//UpdateLightSize();
	TSeparatorKit* concentratorRoot = static_cast< TSeparatorKit* >( m_pCurrentScene->getPart( "childList[0]", false ) );
	if ( !concentratorRoot )	return;

	SoGetBoundingBoxAction* bbAction = new SoGetBoundingBoxAction( SbViewportRegion() ) ;
	concentratorRoot->getBoundingBox( bbAction );

	SbBox3f box = bbAction->getXfBoundingBox().project();
	delete bbAction;
	bbAction = 0;

	BBox sceneBox;
	if( !box.isEmpty() )
	{
		sceneBox.pMin = Point3D( box.getMin()[0], box.getMin()[1], box.getMin()[2] );
		sceneBox.pMax = Point3D( box.getMax()[0], box.getMax()[1], box.getMax()[2] );
		if( lightKit ) lightKit->Update( sceneBox );
	}

	m_pCurrentSceneModel->UpdateSceneModel();

	//Compute bounding boxes and world to object transforms
	trf::ComputeSceneTreeMap( m_pRootSeparatorInstance, Transform( new Matrix4x4 ), true );

	m_pPhotonMap->SetConcentratorToWorld( m_pRootSeparatorInstance->GetIntersectionTransform() );

	QStringList disabledNodes = QString( lightKit->disabledNodes.getValue().getString() ).split( ";", QString::SkipEmptyParts );
	QVector< QPair< TShapeKit*, Transform > > surfacesList;
	trf::ComputeFistStageSurfaceList( m_pRootSeparatorInstance, disabledNodes, &surfacesList );
	lightKit->ComputeLightSourceArea( m_sunWidthDivisions, m_sunHeightDivisions, surfacesList );
	if( surfacesList.count() < 1 )	return;

	QVector< long > raysPerThread;
	int maximumValueProgressScale = 100;

	unsigned long  t1 = nOfRays/ maximumValueProgressScale;
	for( int progressCount = 0; progressCount < maximumValueProgressScale; ++ progressCount )
		raysPerThread<< t1;

	if( ( t1 * maximumValueProgressScale ) < nOfRays )	raysPerThread<< ( nOfRays - ( t1* maximumValueProgressScale) );

	Transform lightToWorld = tgf::TransformFromSoTransform( lightTransform );
	lightInstance->SetIntersectionTransform( lightToWorld.GetInverse() );

	// Create a progress dialog.
	QProgressDialog dialog;
	dialog.setLabelText( QString("Progressing using %1 thread(s)..." ).arg( QThread::idealThreadCount() ) );

	// Create a QFutureWatcher and conncect signals and slots.
	QFutureWatcher< void > futureWatcher;
	QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
	QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
	QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int, int)), &dialog, SLOT(setRange(int, int)));
	QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));

	QMutex mutex;
	QMutex mutexPhotonMap;
	QFuture< void > photonMap;
	if( transmissivity )
		photonMap = QtConcurrent::map( raysPerThread, RayTracer( m_pRootSeparatorInstance,
							 lightInstance, raycastingSurface, sunShape, lightToWorld,
							 transmissivity,
							 *m_pRandomDeviate,
							 &mutex, m_pPhotonMap, &mutexPhotonMap,
							 exportSuraceList ) );
	else
		photonMap = QtConcurrent::map( raysPerThread, RayTracerNoTr( m_pRootSeparatorInstance,
						lightInstance, raycastingSurface, sunShape, lightToWorld,
						*m_pRandomDeviate,
						&mutex, m_pPhotonMap, &mutexPhotonMap,
						exportSuraceList ) );

	futureWatcher.setFuture( photonMap );

	// Display the dialog and start the event loop.
	dialog.exec();
	futureWatcher.waitForFinished();

	m_tracedRays += nOfRays;

	double irradiance = sunShape->GetIrradiance();
	double inputAperture = raycastingSurface->GetValidArea();
	m_wPhoton = double ( inputAperture * irradiance ) / m_tracedRays;

	UpdatePhotonCounts();
}
  void QTAIMCriticalPointLocator::locateElectronDensitySinks()
  {

    QString temporaryFileName=QTAIMCriticalPointLocator::temporaryFileName();

    QList<QList<QVariant> > inputList;

    qreal xmin,ymin,zmin;
    qreal xmax,ymax,zmax;
    qreal xstep,ystep,zstep;

    // TODO: if only we were using Eigen data structures...
    QList<qreal> xNuclearCoordinates;
    QList<qreal> yNuclearCoordinates;
    QList<qreal> zNuclearCoordinates;

    for( qint64 i=0; i < m_wfn->numberOfNuclei() ; ++i )
    {
      xNuclearCoordinates.append( m_wfn->xNuclearCoordinate(i) );
      yNuclearCoordinates.append( m_wfn->yNuclearCoordinate(i) );
      zNuclearCoordinates.append( m_wfn->zNuclearCoordinate(i) );
    }

    xmin=xNuclearCoordinates.first();
    xmax=xNuclearCoordinates.first();
    for( qint64 i=1 ; i < m_wfn->numberOfNuclei() ; ++i)
    {
      if( xNuclearCoordinates.at(i) < xmin )
      {
        xmin=xNuclearCoordinates.at(i);
      }
      if( xNuclearCoordinates.at(i) > xmax )
      {
        xmax=xNuclearCoordinates.at(i);
      }
    }

    ymin=yNuclearCoordinates.first();
    ymax=yNuclearCoordinates.first();
    for( qint64 i=1 ; i < yNuclearCoordinates.count() ; ++i)
    {
      if( yNuclearCoordinates.at(i) < ymin )
      {
        ymin=yNuclearCoordinates.at(i);
      }
      if( yNuclearCoordinates.at(i) > ymax )
      {
        ymax=yNuclearCoordinates.at(i);
      }
    }

    zmin=zNuclearCoordinates.first();
    zmax=zNuclearCoordinates.first();
    for( qint64 i=1 ; i < zNuclearCoordinates.count() ; ++i)
    {
      if( zNuclearCoordinates.at(i) < zmin )
      {
        zmin=zNuclearCoordinates.at(i);
      }
      if( zNuclearCoordinates.at(i) > zmax )
      {
        zmax=zNuclearCoordinates.at(i);
      }
    }

    xmin= -2.0 + xmin;
    ymin= -2.0 + ymin;
    zmin= -2.0 + zmin;

    xmax = 2.0 + xmax;
    ymax = 2.0 + ymax;
    zmax = 2.0 + zmax;

    xstep=ystep=zstep= 0.5;

    for( qreal x=xmin ; x < xmax+xstep ; x=x+xstep)
    {
      for( qreal y=ymin ; y < ymax+ystep ; y=y+ystep)
      {
        for( qreal z=zmin ; z < zmax+zstep ; z=z+zstep)
        {
          QList<QVariant> input;
          input.append( temporaryFileName );
//          input.append( n );
          input.append( x );
          input.append( y );
          input.append( z );

          inputList.append(input);
        }
      }
    }

    m_wfn->saveToBinaryFile(temporaryFileName);

    QProgressDialog dialog;
    dialog.setWindowTitle("QTAIM");
    dialog.setLabelText(QString("Electron Density Sinks Search"));

    QFutureWatcher<void> futureWatcher;
    QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
    QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
    QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int)));
    QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));

    QFuture<QList<QVariant> > future=QtConcurrent::mapped(inputList, QTAIMLocateElectronDensitySink );
    futureWatcher.setFuture(future);
    dialog.exec();
    futureWatcher.waitForFinished();

    QList<QList<QVariant> > results;
    if( futureWatcher.future().isCanceled() )
    {
      results.clear();
    }
    else
    {
      results=future.results();
    }

    QFile file;
    file.remove(temporaryFileName);

    for( qint64 n=0 ; n < results.length() ; ++n )
    {

      qint64 counter=0;
      bool correctSignature = results.at(n).at(counter).toBool(); counter++;

      if( correctSignature )
      {
        qreal x=results.at(n).at(counter).toReal(); counter++;
        qreal y=results.at(n).at(counter).toReal(); counter++;
        qreal z=results.at(n).at(counter).toReal(); counter++;

        if( (xmin < x && x < xmax) &&
            (ymin < y && y < ymax) &&
            (zmin < z && z < zmax) )
        {
          QVector3D result(x,y,z);

          qreal smallestDistance=HUGE_REAL_NUMBER;

          for(qint64 i=0 ; i < m_electronDensitySinks.length() ; ++i )
          {

            Matrix<qreal,3,1> a(x,y,z);
            Matrix<qreal,3,1> b(m_electronDensitySinks.at(i).x(),
                                m_electronDensitySinks.at(i).y(),
                                m_electronDensitySinks.at(i).z());

            qreal distance=QTAIMMathUtilities::distance(a,b);

            if( distance < smallestDistance )
            {
              smallestDistance=distance;
            }

          }

          if( smallestDistance > 1.e-2 )
          {
            m_electronDensitySinks.append( result );
          }
        }
      }
    }
//    qDebug() << "SINKS" << m_electronDensitySinks;
  }
  void QTAIMCriticalPointLocator::locateBondCriticalPoints()
  {

    if( m_nuclearCriticalPoints.length() < 1 )
    {
      return;
    }

    const qint64 numberOfNuclei = m_wfn->numberOfNuclei();

    if( numberOfNuclei < 2)
    {
      return;
    }

    QString temporaryFileName=QTAIMCriticalPointLocator::temporaryFileName();

    QString nuclearCriticalPointsFileName=QTAIMCriticalPointLocator::temporaryFileName();
    QFile nuclearCriticalPointsFile(nuclearCriticalPointsFileName);
    nuclearCriticalPointsFile.open(QIODevice::WriteOnly);
    QDataStream nuclearCriticalPointsOut(&nuclearCriticalPointsFile);
    nuclearCriticalPointsOut << m_nuclearCriticalPoints;
    nuclearCriticalPointsFile.close();

    QList<QList<QVariant> > inputList;

    for( qint64 M=0 ; M < numberOfNuclei - 1 ; ++M )
    {
      for( qint64 N=M+1 ; N < numberOfNuclei ; ++N )
      {

        const qreal distanceCutoff = 8.0 ;

        Matrix<qreal,3,1> a;
        Matrix<qreal,3,1> b;

        a << m_wfn->xNuclearCoordinate(M), m_wfn->yNuclearCoordinate(M), m_wfn->zNuclearCoordinate(M) ;
        b << m_wfn->xNuclearCoordinate(N), m_wfn->yNuclearCoordinate(N), m_wfn->zNuclearCoordinate(N) ;

        if( QTAIMMathUtilities::distance(a,b) < distanceCutoff )
        {
          QVector3D x0y0z0( ( m_wfn->xNuclearCoordinate(M) + m_wfn->xNuclearCoordinate(N) ) / 2.0 ,
                            ( m_wfn->yNuclearCoordinate(M) + m_wfn->yNuclearCoordinate(N) ) / 2.0,
                            ( m_wfn->zNuclearCoordinate(M) + m_wfn->zNuclearCoordinate(N) ) / 2.0 );

          QList<QVariant> input;
          input.append( temporaryFileName );
          input.append( nuclearCriticalPointsFileName );
          input.append( M );
          input.append( N );
          input.append( x0y0z0.x() );
          input.append( x0y0z0.y() );
          input.append( x0y0z0.z() );

          inputList.append(input);
        }
      } // end N
    } // end M

    m_wfn->saveToBinaryFile(temporaryFileName);

    QProgressDialog dialog;
    dialog.setWindowTitle("QTAIM");
    dialog.setLabelText(QString("Bond Critical Points Search"));

    QFutureWatcher<void> futureWatcher;
    QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
    QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
    QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int)));
    QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));

    QFuture<QList<QVariant> > future=QtConcurrent::mapped(inputList, QTAIMLocateBondCriticalPoint);;
    futureWatcher.setFuture(future);
    dialog.exec();
    futureWatcher.waitForFinished();

    QList<QList<QVariant> > results;
    if( futureWatcher.future().isCanceled() )
    {
      results.clear();
    }
    else
    {
      results=future.results();
    }

    QFile file;
    file.remove(temporaryFileName);
    file.remove(nuclearCriticalPointsFileName);

    for( qint64 i=0 ; i < results.length() ; ++i )
    {
      QList<QVariant> thisCriticalPoint=results.at(i);

      bool success=thisCriticalPoint.at(0).toBool();

      if(success)
      {
        QPair<qint64,qint64> bondedAtoms;
        bondedAtoms.first=thisCriticalPoint.at(1).toInt();
        bondedAtoms.second=thisCriticalPoint.at(2).toInt();
        m_bondedAtoms.append( bondedAtoms );

        QVector3D coordinates(thisCriticalPoint.at(3).toReal(),
                              thisCriticalPoint.at(4).toReal(),
                              thisCriticalPoint.at(5).toReal());

        m_bondCriticalPoints.append( coordinates );

        m_laplacianAtBondCriticalPoints.append(thisCriticalPoint.at(6).toReal());
        m_ellipticityAtBondCriticalPoints.append(thisCriticalPoint.at(7).toReal());
        qint64 pathLength=thisCriticalPoint.at(8).toInt();

        QList<QVector3D> bondPath;
        for( qint64 i=0 ; i < pathLength ; ++i )
        {
          QVector3D pathPoint(thisCriticalPoint.at(9 + i                ).toReal(),
                              thisCriticalPoint.at(9 + i +   pathLength ).toReal(),
                              thisCriticalPoint.at(9 + i + 2*pathLength ).toReal());

          bondPath.append(pathPoint);
        }

        m_bondPaths.append(bondPath);
      }

    }

  }
  void QTAIMCriticalPointLocator::locateNuclearCriticalPoints()
  {

    QString temporaryFileName=QTAIMCriticalPointLocator::temporaryFileName();

    QList<QList<QVariant> > inputList;

    const qint64 numberOfNuclei = m_wfn->numberOfNuclei();

    for( qint64 n=0 ; n < numberOfNuclei ; ++n)
    {
      QList<QVariant> input;
      input.append( temporaryFileName );
      input.append( n );
      input.append( m_wfn->xNuclearCoordinate(n) );
      input.append( m_wfn->yNuclearCoordinate(n) );
      input.append( m_wfn->zNuclearCoordinate(n) );

      inputList.append(input);
    }

    m_wfn->saveToBinaryFile(temporaryFileName);

    QProgressDialog dialog;
    dialog.setWindowTitle("QTAIM");
    dialog.setLabelText(QString("Nuclear Critical Points Search"));

    QFutureWatcher<void> futureWatcher;
    QObject::connect(&futureWatcher, SIGNAL(finished()), &dialog, SLOT(reset()));
    QObject::connect(&dialog, SIGNAL(canceled()), &futureWatcher, SLOT(cancel()));
    QObject::connect(&futureWatcher, SIGNAL(progressRangeChanged(int,int)), &dialog, SLOT(setRange(int,int)));
    QObject::connect(&futureWatcher, SIGNAL(progressValueChanged(int)), &dialog, SLOT(setValue(int)));

    QFuture<QList<QVariant> > future=QtConcurrent::mapped(inputList, QTAIMLocateNuclearCriticalPoint);
    futureWatcher.setFuture(future);
    dialog.exec();
    futureWatcher.waitForFinished();

    QList<QList<QVariant> > results;
    if( futureWatcher.future().isCanceled() )
    {
      results.clear();
    }
    else
    {
      results=future.results();
    }

    QFile file;
    file.remove(temporaryFileName);

    for( qint64 n=0 ; n < results.length() ; ++n )
    {

      bool correctSignature = results.at(n).at(0).toBool();

      if (correctSignature)
      {

        QVector3D result(
          results.at(n).at(1).toReal(),
          results.at(n).at(2).toReal(),
          results.at(n).at(3).toReal()
        );

        m_nuclearCriticalPoints.append( result );
      }

    }

  }