void GImagePixelAdder::ProcessImageAOIed(const GImageDouble & aoiImage)
{
	IncrementCountProcessed();
	int Npix = aoiImage.size().width() * aoiImage.size().height();
    //int hei = aoiImage.size().height();
    //int wid = aoiImage.size().width();
	GDoubleArray & zArray = aoiImage.DoubleArray();
	double sum = 0;
	double sumSquare = 0;
	int pxTot = 0;
	for(int i = 0; i < Npix; i++) {
		double valPix = zArray[i];
		if(qIsNaN(valPix) || qIsInf(valPix))
			continue;
		pxTot++;
		sum += valPix;
		sumSquare += valPix * valPix;
	}
	if(!pxTot)
		return;
	double dNpixTot = double(pxTot);
	m_SumPix = sum;
	sum /= dNpixTot;
	sumSquare /= dNpixTot;
	m_AvePix = sum;
	m_StdDevPix = qSqrt(sumSquare - sum * sum);
}
void GImageStacker::ProcessImageAOIed(const GImageDouble & aoiImage)
{
	m_ImageMutex.lock();

	QDateTime timeThisPicture = aoiImage.DateTimeCreated();
// 	m_ImageIn.clear();
// 	m_ImageIn.insert(1.25874, aoiImage);
	m_LastReceivedPictureCreationDate = timeThisPicture;

	// prepends the new data to the beginning of the list
	m_History.prepend(aoiImage);
	m_PicturesPutInHistorySinceLastStart++;

	// quick way to implement the history by removing the unused parameters
	int maxSize = qMax(1, m_SampleSize.IntValue());
	while(m_History.count() > maxSize) {
		m_History.removeLast();
	}
	m_ImageMutex.unlock();

	start();
}
void Fit( GImageDouble imageIn, GImage2DGaussFitter* ptr )
{
    QThread::currentThread()->setPriority(QThread::LowPriority);

    int Npix = imageIn.size().width() * imageIn.size().height();
    int hei = imageIn.size().height();
    int wid = imageIn.size().width();
    // the array of values
    GDoubleArray & zArray = imageIn.DoubleArray();
    // the array containing the coordinates of the points as described in the AlgLib documentation
    GDoubleArray x2Array(2 * Npix);
    int iTot = 0;
    for(int jLine = 0; jLine < hei; jLine++) {
        const uchar* scanL = imageIn.constScanLine(jLine);
        for(int iCol = 0; iCol < wid; iCol++) {
            x2Array[2 * iTot] = double(iCol);
            x2Array[2 * iTot + 1] = double(jLine);
            iTot++;
        }
    }
    // the array to set the weight of the point. For NaN and inf values, the weight is 0.0
    GDoubleArray wArray(Npix);
    for(int ind = 0; ind < Npix; ind++) {
        double & valPix = zArray[ind];
        if(qIsNaN(valPix) || qIsInf(valPix)) {
            zArray[ind] = 0.0; // put an acceptable value
            wArray[ind] = 0.0; // set the weigh to 0.0
        }
        else
            wArray[ind] = 1.0;
    }

    real_2d_array x;
    real_1d_array y;
    real_1d_array w;
    x.setcontent(Npix, 2, x2Array.constData());
    y.setcontent(Npix, zArray.constData());
    w.setcontent(Npix, wArray.constData());
    real_1d_array c;
    c.setlength(6);
    c[0] = ptr->m_FitMask[0] ? ptr->m_IniOffset	: ptr->m_Offset;
    c[1] = ptr->m_FitMask[1] ? ptr->m_IniAmpl	: ptr->m_Ampl;
    c[2] = ptr->m_FitMask[2] ? ptr->m_IniX0		: ptr->m_X0;
    c[3] = ptr->m_FitMask[3] ? ptr->m_IniY0		: ptr->m_Y0;
    c[4] = ptr->m_FitMask[4] ? ptr->m_IniSigmaX	: ptr->m_SigmaX;
    c[5] = ptr->m_FitMask[5] ? ptr->m_IniSigmaY	: ptr->m_SigmaY;

    double epsf = 0.0001;
    double epsx = 0.0001;
    ae_int_t maxits = 100;
    ae_int_t info;
    lsfitstate state;
    lsfitreport rep;
    double diffstep = 0.0001;

// STRANGE! fires "Warning: QObject::startTimer: timers cannot be started from another thread"
// 	ptr->UpdateGraphicsItem();

    int whichOne = 2;
    switch (whichOne)
    {
    case 1:
        lsfitcreatewf(x, y, w, c, Npix, 2, 6, diffstep, state);
        lsfitsetcond(state, epsf, epsx, maxits);
        lsfitsetxrep(state, true);
        lsfitfit(state, Gaus2D_func, function_to_call_after_each_iteration, ptr);
        lsfitresults(state, info, c, rep);
        break;
    case 2:
        lsfitcreatewfg(x, y, w, c, Npix, 2, 6, false, state);
        lsfitsetcond(state, epsf, epsx, maxits);
        lsfitsetxrep(state, true);
        lsfitfit(state, Gaus2D_func, Gaus2D_grad, function_to_call_after_each_iteration, ptr);
        lsfitresults(state, info, c, rep);
        break;
    case 3:
        lsfitcreatewfg(x, y, w, c, Npix, 2, 6, true, state);
        lsfitsetcond(state, epsf, epsx, maxits);
        lsfitsetxrep(state, true);
        lsfitfit(state, Gaus2D_func, Gaus2D_grad, function_to_call_after_each_iteration, ptr);
        lsfitresults(state, info, c, rep);
        break;
    case 4:
        lsfitcreatewfgh(x, y, w, c, Npix, 2, 6, state);
        lsfitsetcond(state, epsf, epsx, maxits);
        lsfitsetxrep(state, true);
        lsfitfit(state, Gaus2D_func, Gaus2D_grad, Gaus2D_hess, function_to_call_after_each_iteration, ptr);
        lsfitresults(state, info, c, rep);
        break;
    }

    GVectorDouble finalValues(6);
    c[4] = qAbs(c[4]);
    c[5] = qAbs(c[5]);
    for(int i = 0; i < 6 ; i++) {
        finalValues[i] = c[i];
    }
    QMetaObject::invokeMethod(ptr, "UpdateFinalResultValues", Qt::QueuedConnection, Q_ARG(GVectorDouble, finalValues));
}
void GImageSaver::ProcessImageAOIed(const GImageDouble & aoiImage)
{
	IncrementCountProcessed();
	QString fileName = m_Folder;
 	fileName += "\\";
	fileName += QDateTime::currentDateTime().toString("yyyy-MM-dd-hh-mm-ss.zzz");
	//fileName += ".png";
	QPixmap::fromImage(aoiImage).save(fileName + "_8bit.png");//Gael's original implementation which saves 8-bit QImage.
	
	
	//Shared things for next two if() statements: 
	double* doubleArrayToSave = aoiImage.DoubleArray().data();//Get access to desired DoubleArray.
	uint ulength = aoiImage.width()*aoiImage.height();
	int length = aoiImage.width()*aoiImage.height();
	QString height;
	QString width;
	height.setNum(aoiImage.height());
	width.setNum(aoiImage.width());
	if(m_SaveDouble){
		//2015-06-24 Bart: Trying again to save DoubleArray directly to avoid converting to 8-bit QImage first. 
		//Data is exported as raw binary data file, without separating rows or columns. 
		//The row and column sizes are saved in the file name, so you can reassemble the image later. 
		//Each pixel data point is a double, which is saved as 8 characters. 
		//This works, but double's are huge with unused bytes, so 500x500 AOI ends up taking about 2 megabytes on disk. 
		QFile fileHQ;
		fileHQ.setFileName(fileName + "_Double[width=" + width + ";height=" + height + "].dat");
		fileHQ.open(QFile::WriteOnly);
		//debugging tests: passed! 
		//qDebug()<<"File length should be "<<length<<" times sizeof(doule) = "<<sizeof(double);
		//qDebug()<<"Attempting to save high quality file, num bytes written:"<< //next line goes here
		fileHQ.write((const char*) doubleArrayToSave, ulength*sizeof(double));//following internet's example here...
		fileHQ.flush();
		fileHQ.close();
	}
	if(m_Save12bit){
		//2015-06-24 Bart: Now trying to save high quality image without huge file size! 
		//Goal here is ONLY to save raw imported camera images with 2-bytes/pixel; this will NOT work with processed optical depth, etc. 
		//Essentially, this is the reverse process of what I did with GUEyeImageDistributor:BufferToTreat() for 12-bit images. 
		QFile file12bit;
		file12bit.setFileName(fileName + "_2BytesPerPixel[width=" + width + ";height=" + height + "].dat");
		file12bit.open(QFile::WriteOnly);
		//file12bit.write(ByteArrayToSave);
		QDataStream out(&file12bit);
		//ushort tempvalue;
		for(int iTot=0; iTot<length; iTot++){
			//out << doubleArrayToSave[iTot];//testing,exports double values, appears to work because filesize is as large as expected.
			//qDebug()<<doubleArrayToSave[iTot];//testing
			//memcpy(&tempvalue,&doubleArrayToSave[iTot],sizeof(ushort));//get 2 byte unit from double
			//out << tempvalue;
			//qDebug() << tempvalue;

			//Try just forcing conversion to ushort: SEEMS TO WORK? 
			out << (ushort)doubleArrayToSave[iTot];
			//qDebug()<<(ushort)doubleArrayToSave[iTot];//testing
		}
		file12bit.flush();
		file12bit.close();

		//Trying some random things: 
		//Try PNG with quality set to 100 (highest value, lowest compression.): 
		//QPixmap::fromImage(aoiImage).save(fileName + "_PixMap100.png",0,100);//This saves 735 kB vs 19 kB PNGs with same information b/c least compressed? 
		//Try PGM format:  Saves as 8-bit because loaded from aoiImage. Can do 2-byte if could import values in different way! 
		//QPixmap::fromImage(aoiImage).save(fileName + "_PixMap100fromImage.pgm",0,100);//This saves QImage as 8-bit PGM format (245 kB vs 19 kB default PNG). 
		//Doesn't work... 
		//QPixmap MapToSave; 
		//qDebug()<<"Try to load map from data: " << MapToSave.loadFromData((const uchar*) doubleArrayToSave, length*sizeof(double));
		//MapToSave.save(fileName + "_PixMap100fromData.pgm",0,100);
	}
}