/**
 * \brief Task execution function
 *
 * In this function, all waits should use the wait function to ensure that
 * cancel is recognized.
 */
void	ExposureWork::run() {
	debug(LOG_DEBUG, DEBUG_LOG, 0, "start ExposureWork");
	// set the cooler
	if (cooler) {
		debug(LOG_DEBUG, DEBUG_LOG, 0, "turning on cooler");
		cooler->setTemperature(_task.ccdtemperature());
		cooler->setOn(true);
	}

	// set the filterwheel position
	std::string	filtername("NONE");
	if (filterwheel) {
		debug(LOG_DEBUG, DEBUG_LOG, 0, "selecting filter");
		// make sure filter wheel is ready
		FilterwheelCondition	condition(filterwheel,
			camera::FilterWheel::idle);
		if (!wait(10., condition)) {
			throw std::runtime_error("filterwheel did not settle");
		}

		// select the new filter
		if (_task.filter().size() > 0) {
			filterwheel->select(_task.filter());
			filtername = _task.filter();
		}
	}

	// wait for the cooler, if present, but at most 30 seconds
	if (cooler) {
		debug(LOG_DEBUG, DEBUG_LOG, 0, "wait for cooler");
		CoolerCondition	coolercondition(cooler);
		if (!wait(30., coolercondition)) {
			debug(LOG_DEBUG, DEBUG_LOG, 0,
				"cannot stabilize temperature");
			// XXX what do we do when the cooler cannot stabilize?
		}
		debug(LOG_DEBUG, DEBUG_LOG, 0, "cooler now stable");
	} else {
		debug(LOG_DEBUG, DEBUG_LOG, 0, "no cooler");
	}

	// wait for the filterwheel if present
	if (filterwheel) {
		debug(LOG_DEBUG, DEBUG_LOG, 0, "wait for filterwheel");

		// wait once more for the filterwheel to become ready
		FilterwheelCondition	condition(filterwheel,
			camera::FilterWheel::idle);
		if (!wait(30., condition)) {
			throw std::runtime_error("filter wheel does not idle");
		}
		debug(LOG_DEBUG, DEBUG_LOG, 0, "filterwheel now idle");
	} else {
		debug(LOG_DEBUG, DEBUG_LOG, 0, "no filter");
	}

	// start exposure
	debug(LOG_DEBUG, DEBUG_LOG, 0, "start exposure: time=%f",
		_task.exposure().exposuretime());
	ccd->startExposure(_task.exposure());

	// wait for completion of exposure
	debug(LOG_DEBUG, DEBUG_LOG, 0, "waiting for %.3f seconds",
		_task.exposure().exposuretime());
	CcdCondition	ccdcondition(ccd, camera::CcdState::exposed);

	// if waiting is cancelled, then we have to cancel the exposure
	// also
	try {
		if (!wait(_task.exposure().exposuretime() + 30, ccdcondition)) {
			debug(LOG_DEBUG, DEBUG_LOG, 0,
				"waiting for image failed");
			throw std::runtime_error("failed waiting for image");
		}
	} catch (CancelException& x) {
		debug(LOG_DEBUG, DEBUG_LOG, 0, "cancel exception caught");
		// cancel the image...
		ccd->cancelExposure();
		debug(LOG_DEBUG, DEBUG_LOG, 0, "exposure cancelled, waiting");

		// ... and wait until either the camera is in a safe state
		do {
			sleep(1);
			
		} while ((ccd->exposureStatus() == camera::CcdState::cancelling)
			|| (ccd->exposureStatus() == camera::CcdState::exposing));
		debug(LOG_DEBUG, DEBUG_LOG, 0, "wait comlete");

		// now throw again to signal the work process that the process
		// was in fact cancelled
		throw;
	}


	// get the image from the ccd
	astro::image::ImagePtr	image = ccd->getImage();
	debug(LOG_DEBUG, DEBUG_LOG, 0, "image frame: %s",
		image->getFrame().toString().c_str());

	// add instrument info
	if (_task.instrument().size() > 0) {
		image->setMetadata(FITSKeywords::meta("INSTRUME",
			_task.instrument()));
	}

	// add filter information to the image, if present
	if ((filterwheel) && (filtername.size() > 0)) {
		image->setMetadata(FITSKeywords::meta("FILTER", filtername));
	}

	// add temperature metadata
	if (cooler) {
		cooler->addTemperatureMetadata(*image);
	}

	// position information from the mount
	if (mount) {
		mount->addPositionMetadata(*image);
	}

	// project inforamtion
	if (_task.project().size() > 0) {
		image->setMetadata(astro::io::FITSKeywords::meta(
			std::string("PROJECT"), _task.project()));
	}

	if (_task.repository().size() > 0) {
		// add the image to the repository
		std::string	repository = _task.repository();
		debug(LOG_DEBUG, DEBUG_LOG, 0, "saving image to imagerepo %s",
			repository.c_str());
		project::ImageRepoPtr	 imagerepo
			= config::ImageRepoConfiguration::get()->repo(repository);
		if (imagerepo) {
			long	id = imagerepo->save(image);
			_task.filename(stringprintf("%ld", id));
		} else {
			debug(LOG_DEBUG, DEBUG_LOG, 0, "no image repo found");
		}
	} else {
		// add to the ImageDirectory
		astro::image::ImageDatabaseDirectory	imagedir;
		debug(LOG_DEBUG, DEBUG_LOG, 0, "saving image");
		std::string	filename = imagedir.save(image);

		// remember the filename
		_task.filename(filename);
		debug(LOG_DEBUG, DEBUG_LOG, 0, "saving image to file %s",
			filename.c_str());
	}

	// update the frame information
	astro::camera::Exposure	exposure = _task.exposure();
	_task.exposure(exposure);

	// copy the returned image information
	_task.size(image->size());
	_task.origin(image->origin());

	// log info
	debug(LOG_DEBUG, DEBUG_LOG, 0, "image %s written",
		_task.filename().c_str());
	_task.state(TaskQueueEntry::complete);
}
Пример #2
0
void nemo_main()
{
  int colnr[2];
  real *coldat[2], *xdat, *ydat, xmin, xmax, ymin, ymax;
  real *udat, *vdat, umin, umax, vmin, vmax;
  real x, y1, y2, dx, xscale, yscale, xQmin, xQmax;
  real tbb,sum,sum0;
  stream instr, tabstr;
  int i, n, ns, nmax;
  real *sdat, *spdat;
  string spectrum, filter = filtername(getparam("filter"));
  bool Qnorm = getbparam("normalize");
  bool Qmin = hasvalue("xmin");
  bool Qmax = hasvalue("xmax");
  bool Qtab = hasvalue("out");
  
  nmax = nemo_file_lines(filter,MAXLINES);
  xdat = coldat[0] = (real *) allocate(nmax*sizeof(real));
  ydat = coldat[1] = (real *) allocate(nmax*sizeof(real));
  colnr[0] = 1;  /* wavelenght in angstrom */
  colnr[1] = 2;  /* normalized filter response [0,1] */
  instr = stropen(filter,"r");
  n = get_atable(instr,2,colnr,coldat,nmax);
  strclose(instr);

  if (Qtab) tabstr = stropen(getparam("out"),"w");
  
  for(i=0; i<n; i++) {
    dprintf(2,"%g %g\n",xdat[i],ydat[i]);
    if (i==0) {
      xmin = xmax = xdat[0];
      ymin = ymax = ydat[0];
    } else {
      if (xdat[i] <= xdat[i-1]) 
	error("Filter %s must be sorted in wavelength",filter);
      xmax = MAX(xmax,xdat[i]);
      ymax = MAX(ymax,ydat[i]);
      xmin = MIN(xmin,xdat[i]);
      ymin = MIN(ymin,ydat[i]);
    }
  }
  dprintf(1,"Filter wavelength range: %g : %g\n",xmin,xmax);
  dprintf(1,"Filter response range: %g : %g\n",ymin,ymax);
  if (ydat[0]   != 0) warning("lower edge filter response not 0: %g",ydat[0]);
  if (ydat[n-1] != 0) warning("upper edge filter response not 0: %g",ydat[n-1]);
  dx = getdparam("step");
  if ((xmax-xmin)/100 < dx) {
    warning("Integration step %g in Angstrom too large, resetting to %g",
	    dx, (xmax-xmin)/100);
    dx = (xmax-xmin)/100;
  }
  
  /* setup a spline interpolation table into the filter */
  sdat = (real *) allocate(sizeof(real)*n*3);
  spline(sdat,xdat,ydat,n);

  if (Qmin) {                  /* override any min/max rules ? */
    xQmin = getdparam("xmin");
    if (xQmin > xmin) warning("xmin=%g greater than minimum in filter (%g)",xQmin,xmin);
  }
  if (Qmax) {
    xQmax = getdparam("xmax");
    if (xQmax < xmax) warning("xmax=%g less than maximum in filter (%g)",xQmax,xmax);
  }

  if (hasvalue("tbb")) {                /* using a Planck curve */
    tbb = getdparam("tbb");
    if (Qmin) xmin = xQmin;
    if (Qmax) xmax = xQmax;

    sum = sum0 = 0;
    for (x = xmin; x <= xmax; x += dx) {
      y1 = seval(x,xdat,ydat,sdat,n);    /* filter */
      y2 = planck(x,tbb);
      dprintf(3,"%g %g %g\n",x,y1,y2);
      if (Qtab) fprintf(tabstr,"%g %g\n",x,MAX(DATAMIN,y1*y2));
      sum += y1*y2;
      sum0 += y1;
    }
    if (Qnorm)
      sum /= sum0;
    else
      sum *= dx;
    if (Qtab)
      dprintf(0,"%g %g %g\n",tbb,sum,-2.5*log10(sum));
    else
      printf("%g %g %g\n",tbb,sum,-2.5*log10(sum));

  } else if (hasvalue("spectrum")) {

    warning("spectrum= is a new feature");
    spectrum = getparam("spectrum");
    nmax = nemo_file_lines(spectrum,MAXLINES);
    udat = coldat[0] = (real *) allocate(nmax*sizeof(real));
    vdat = coldat[1] = (real *) allocate(nmax*sizeof(real));
    colnr[0] = getiparam("xcol");
    colnr[1] = getiparam("ycol");
    instr = stropen(spectrum,"r");
    ns = get_atable(instr,2,colnr,coldat,nmax);
    strclose(instr);

    xscale = getdparam("xscale");
    yscale = getdparam("yscale");

    for(i=0; i<ns; i++) {
      dprintf(2,"%g %g\n",udat[i],vdat[i]);
      udat[i] *= xscale;
      vdat[i] *= yscale;
      if (i==0) {
	umin = umax = udat[0];
	vmin = vmax = vdat[0];
      } else {
	if (udat[i] <= udat[i-1])
	  error("Spectrum %s must be sorted in wavelength",spectrum);
	umax = MAX(umax,udat[i]);
	vmax = MAX(vmax,vdat[i]);
	umin = MIN(umin,udat[i]);
	vmin = MIN(vmin,vdat[i]);
      }
    }
    dprintf(1,"Spectrum wavelength range: %g : %g\n",umin,umax);
    dprintf(1,"Spectrum response range: %g : %g\n",vmin,vmax);

    if (umax < xmin || umin >xmax)
      error("Spectrum and filter do not overlap");

    /* setup a spline interpolation table into the spectrum */
    spdat = (real *) allocate(sizeof(real)*n*3);
    spline(spdat,udat,vdat,ns);

    sum = sum0 = 0;
    if (Qmin) xmin = xQmin;
    if (Qmax) xmax = xQmax;
    for (x = xmin; x <= xmax; x += dx) {
      y1 = seval(x,xdat,ydat,sdat,n);    /* filter */
      if (umin < x && x <umax)
	y2 = seval(x,udat,vdat,spdat,ns);  /* spectrum */
      else
	y2 = 0.0;
      dprintf(3,"%g %g %g\n",x,y1,y2);
      if (Qtab) fprintf(tabstr,"%g %g\n",x,MAX(DATAMIN,y1*y2));
      sum += y1*y2;
      sum0 += y1;
    }
    if (Qnorm)
      sum /= sum0;
    else
      sum *= dx;
    if (Qtab)
      dprintf(0,"0   %g %g\n",sum,-2.5*log10(sum));
    else
      printf("0   %g %g\n",sum,-2.5*log10(sum));

  } else
    warning("Either spectrum= or tbb= must be used");
}
Пример #3
0
void Editor::importMovie( QString filePath, int fps )
{
    int i = 0;
    QSettings settings( PENCIL2D, PENCIL2D );

    qDebug() << "-------IMPORT VIDEO------" << filePath;

    // --------- Import all the temporary frames ----------
    QDir::temp().mkdir( "pencil" );
    QString tempPath = QDir::temp().absolutePath() + "/pencil/";

    if ( QFile::exists( QDir::current().currentPath() + "/plugins/ffmpeg.exe" ) == true )
    {
        QProgressDialog progress( "Importing movie...", "Abort", 0, 100, NULL );
        progress.setWindowModality( Qt::WindowModal );
        progress.show();
        progress.setValue( 10 );
        QProcess ffmpeg;
        qDebug() << "./plugins/ffmpeg.exe -i \"" << filePath << "\" -r " << QString::number( fps ) << " -f image2 \"" << tempPath << "tmp_import%4d.png\"";
        ffmpeg.start( "./plugins/ffmpeg.exe -i \"" + filePath + "\" -r " + QString::number( fps ) + " -f image2 \"" + tempPath + "tmp_import%4d.png\"" );
        progress.setValue( 20 );
        if ( ffmpeg.waitForStarted() == true )
        {
            if ( ffmpeg.waitForFinished() == true )
            {
                qDebug() << "stdout: " + ffmpeg.readAllStandardOutput();
                qDebug() << "stderr: " + ffmpeg.readAllStandardError();
            }
            else
            {
                qDebug() << "ERROR: FFmpeg did not finish executing.";
            }
        }
        else
        {
            qDebug() << "ERROR: Could not execute FFmpeg.";
        }
        progress.setValue( 50 );
        QDir dir1( tempPath );
        int nFiles = dir1.entryList().count();
        i = 1;
        QString frameNumberString = QString::number( i );
        while ( frameNumberString.length() < 4 ) frameNumberString.prepend( "0" );
        while ( QFile::exists( tempPath + "tmp_import" + frameNumberString + ".png" ) )
        {
            progress.setValue( 50 + i * 50 / nFiles );
            if ( i>1 ) scrubForward();
            importImage( tempPath + "tmp_import" + frameNumberString + ".png" );
            i++;
            frameNumberString = QString::number( i );
            while ( frameNumberString.length() < 4 ) frameNumberString.prepend( "0" );
        }
        progress.setValue( 100 );
        // --------- Clean up temp directory ---------
        QDir dir( tempPath );
        QStringList filtername( "*.*" );
        QStringList entries = dir.entryList( filtername, QDir::Files, QDir::Type );
        for ( int e = 0; e < entries.size(); e++ )
            dir.remove( entries[ e ] );
    }
    else
    {
        qDebug() << "Please place ffmpeg.exe in plugins directory";
    }
}
Пример #4
0
// added parameter exportFps -> frame rate of exported video
// added parameter exportFormat -> to set ffmpeg parameters
bool Object::exportMovie( ExportMovieParameters parameters )
{
    int startFrame = parameters.startFrame;
    int endFrame = parameters.endFrame;
    QTransform view = parameters.view;
    Layer* currentLayer = parameters.currentLayer;
    QSize exportSize = parameters.exportSize;
    QString filePath = parameters.filePath;
    int fps = parameters.fps;
    int exportFps = parameters.exportFps;
    QString exportFormat = parameters.exportFormat;

    if(!filePath.endsWith(".avi", Qt::CaseInsensitive))
    {
        filePath = filePath + ".avi";
    }

    //  additional parameters for ffmpeg
    QString ffmpegParameter = "";
    if(filePath.endsWith(".avi", Qt::CaseInsensitive))
    {ffmpegParameter = " -vcodec msmpeg4 ";}
    if(filePath.endsWith(".mov", Qt::CaseInsensitive))
    {ffmpegParameter = "";}
    if(filePath.endsWith(".mp4", Qt::CaseInsensitive))
    {ffmpegParameter = "";}

    qDebug() << "-------VIDEO------";
    // --------- Export all the temporary frames ----------
    QDir::temp().mkdir("pencil");
    QString tempPath = QDir::temp().absolutePath()+"/pencil/";
    QProgressDialog progress("Exporting movie...", "Abort", 0, 100, NULL);
    progress.setWindowModality(Qt::WindowModal);
    progress.show();

    QDir dir2(filePath);
    if (QFile::exists(filePath) == true) { dir2.remove(filePath); }

    const char* format = "png";

    ExportFrames1Parameters par;

    par.frameStart = startFrame;
    par.frameEnd = endFrame;
    par.view = view;
    par.currentLayer = currentLayer;
    par.exportSize = exportSize;
    par.filePath = tempPath + "tmp";
    par.format = format;
    par.quality = 100;
    par.background = true;
    par.antialiasing = true;
    par.progress = &progress;
    par.progressMax = 50;
    par.fps = fps;
    par.exportFps = exportFps;

    exportFrames1( par );

    // --------- Quicktime assemble call ----------
    QDir sampledir;
    qDebug() << "testmic:" << sampledir.filePath(filePath);

    QProcess ffmpeg;

    qDebug() << "Trying to export VIDEO";
    quint32 audioDataSize = 44100*2*2*(endFrame-1)/fps;
    qint16* audioData =(qint16*) malloc(audioDataSize);
    for (uint i = 0; i < audioDataSize/2; i++ ) audioData[i] = 0;
    quint16 header1[22];
    bool audioDataValid = false;
    for(int i = 0; i < this->getLayerCount() ; i++)
    {
        Layer* layer = this->getLayer(i);
        if(layer->type() == Layer::SOUND)
        {
            auto pSoundLayer = static_cast< LayerSound* >( layer );
            pSoundLayer->foreachKeyFrame( [&] ( KeyFrame* key )
            {
                int l = 0; // FIXME: export sound
                // convert audio file: 44100Hz sampling rate, stereo, signed 16 bit little endian
                // supported audio file types: wav, mp3, ogg... ( all file types supported by ffmpeg )
                qDebug() << "ffmpeg -i \"" + ((LayerSound*)layer)->getSoundFilepathAt(l) + "\" -ar 44100 -acodec pcm_s16le -ac 2 -y \"" + tempPath + "tmpaudio0.wav\"";
                ffmpeg.start("ffmpeg -i \"" + ((LayerSound*)layer)->getSoundFilepathAt(l) + "\" -ar 44100 -acodec pcm_s16le -ac 2 -y \"" + tempPath + "tmpaudio0.wav\"");
                if (ffmpeg.waitForStarted() == true)
                {
                    if (ffmpeg.waitForFinished() == true)
                    {
                        QByteArray sErr = ffmpeg.readAllStandardError();
                        if (sErr == "")
                        {
                            qDebug() << "ERROR: Could not execute FFmpeg.";
                        }
                        else
                        {
                            qDebug() << "stdout: " << ffmpeg.readAllStandardOutput();
                            qDebug() << "stderr: " << sErr;
                            qDebug() << "AUDIO conversion done. ( file: " << ((LayerSound*)layer)->getSoundFilepathAt(l) << ")";
                        }
                    }
                    else
                    {
                        qDebug() << "ERROR: FFmpeg did not finish executing.";
                    }
                }
                else
                {
                    qDebug() << "ERROR: Could not execute FFmpeg.";
                }
                int frame = key->pos() - 1;
                float fframe = (float)frame/(float)fps;
                QFile file(tempPath+"tmpaudio0.wav");
                qDebug() << "audio file " + tempPath+"tmpaudio0.wav";
                file.open(QIODevice::ReadOnly);
                file.read((char*)header1,sizeof(header1));
                quint32 audioSize = header1[21];
                audioSize = audioSize * 65536 + header1[20];
                qDebug() << "audio len " << audioSize;
                // before calling malloc should check: audioSize < max credible value
                qint16* data = (qint16*) malloc(audioSize);
                file.read((char*)data,audioSize);
                audioDataValid = true;
                int delta = fframe*44100*2;
                qDebug() << "audio delta " << delta;
                int indexMax = MIN(audioSize/2,audioDataSize/2-delta);
                // audio files 'mixing': 'higher' sound layers overwrite 'lower' sound layers
                for (int index = 0; index < indexMax; index++)
                {
                    audioData[index+delta] = safeSum(audioData[index+delta],data[index]);
                }
                free(data);
                file.close();
            } );
        }
    }
    if ( audioDataValid )
    {
        // save mixed audio file ( will be used as audio stream )
        QFile file(tempPath+"tmpaudio.wav");
        file.open(QIODevice::WriteOnly);
        header1[20] = audioDataSize % 65536;
        header1[21] = audioDataSize / 65536;
        file.write((char*)header1,sizeof(header1));
        file.write((char*)audioData,audioDataSize);
        file.close();
    }


    // video input:  frame sequence ( -i tmp%03d.png )
    //               frame rate     ( -r fps )
    // audio input:                 ( -i tmpaudio.wav )
    // movie output:                ( filePath )
    //               frame rate     ( -r 25 )
    if ( audioDataValid )
    {
        qDebug() << "ffmpeg -r " + QString::number(exportFps) + " -i " + tempPath + "tmp%4d.png -i " + tempPath + "tmpaudio.wav -r " + QString::number(exportFps) + " -y " + ffmpegParameter + "\"" + filePath + "\"";
        ffmpeg.start("ffmpeg -r " + QString::number(exportFps) + " -i " + tempPath + "tmp%4d.png -i " + tempPath + "tmpaudio.wav -r " + QString::number(exportFps) + " -y " + ffmpegParameter + "\"" + filePath + "\"");
    }
    else
    {
        qDebug() << "ffmpeg -r " + QString::number(exportFps) + " -i " + tempPath + "tmp%4d.png -r " + QString::number(exportFps) + " -y " + ffmpegParameter + "\"" + filePath + "\"";
        ffmpeg.start("ffmpeg -r " + QString::number(exportFps) + " -i " + tempPath + "tmp%4d.png -r " + QString::number(exportFps) + " -y " + ffmpegParameter + "\"" + filePath + "\"");
    }
    if (ffmpeg.waitForStarted() == true)
    {
        if (ffmpeg.waitForFinished() == true)
        {
            QByteArray sErr = ffmpeg.readAllStandardError();
            if (sErr == "")
            {
                qDebug() << "ERROR: Could not execute FFmpeg.";
            }
            else
            {
                qDebug() << "stdout: " << ffmpeg.readAllStandardOutput();
                qDebug() << "stderr: " << sErr;

                qDebug() << "dbg:" << QDir::current().currentPath() +"/plugins/";
                qDebug() << ":" << tempPath + "tmp%03d.png";
                qDebug() << ":\"" + filePath + "\"";
                qDebug() << "VIDEO export done.";
            }
        }
        else
        {
            qDebug() << "ERROR: FFmpeg did not finish executing.";
        }
    }
    else
    {
        qDebug() << "Please install FFMPEG: sudo apt-get install ffmpeg";
    }

    progress.setValue(100);
    free(audioData);


    // --------- Clean up temp directory ---------
    QDir dir(tempPath);
    QStringList filtername("*.*");
    QStringList entries = dir.entryList(filtername,QDir::Files,QDir::Type);
    for(int i=0; i<entries.size(); i++)
        dir.remove(entries[i]);
    qDebug() << "-----";

    return true;
}