Class ALCEDSAcqThread : thread{
	Image _imgEDS;

	Object _oSignal;
	Number _isAcquiring, _nChannels, _disp, _acqTime;

	Object init(Object self, Object oSignal, \
	Number nChannels, Number disp, Number acqTime){
		_oSignal = oSignal
		_isAcquiring = 1;
		_nChannels = nChannels;
		_disp = disp;
		_acqTime = acqTime;
		return self;
	}

	Void RunThread(Object self){
		_imgEDS := EDSAcquireSpectrum(_nChannels, _disp, _acqTime);
		_isAcquiring = 0;
		_oSignal.SetSignal();
	}

	Number IsAcquiring(Object self){
		return _isAcquiring;
	}

	Image GetEDSImage(Object self){
		return _imgEDS;
	}
}

Image ALCEELSAcq(Number nCycle, Number acqTime, Number sumFrames, \
	Number specBin, Number vertBin, Number processing){
	Image imgTemp, imgR;
	Number nChannels;
	imgTemp := EELSAcquireSpectrum(acqTime, sumFrames, specBin, vertBin, processing);
	nChannels = imgTemp.ImageGetDimensionSize(0);
	imgR := realimage("", 4,  nChannels, nCycle);
	imgR[0, 0, 1, nChannels] = imgTemp;
	for(Number i = 1; i < nCycle; i++){
		imgTemp := EELSAcquireSpectrum(acqTime, sumFrames, specBin, vertBin, processing);
		imgR[i, 0, i + 1, nChannels] = imgTemp;
	}
	return imgR;
}

Void QEDAcquireALCHEMI(Image img){
	Number w, h;
	img.GetSize(w, h); 

	Number nEds = 1; // EDS acquisition is enabled (1) or disabled (otherwise)
	Number nChEds = 4096; // Number of EDS detector channels
	Number dispEds = 0.1; // Dispersion of EDS detector (in keV)
	Number acqEds = 10; // EDS acquisition time (in seconds)
	Number timeOut = 30; // Timeout time when EDS is not responding (in seconds)

	Number nEels = 10; // Number of EELS acquisitions (0 => EELS is disabled)
	Number acqEels = 1; // EELS acquisition time (in seconds)
	Number sumFrames= 1; // Number of summing frames in a single EELS acquisition
	Number specBin = 1; // Spectrum binning in EELS acquisition
	Number vertBin = 100; // Vertical binning in EELS acquisition
	Number processing = 2; // Post processing for acquired spectrum
	// 0: Unprocessed, 1: Dark Subtracted, 2: Gain Normalized

	Object oEDSSignal = NewSignal(0);
	Object oCancelSignal = NewSignal(0);
	Object cEDSAcq;

	if(nEds == 1){
		cEdsAcq = alloc(ALCEDSAcqThread).init(oEDSSignal, nChEds, dispEds, acqEds);
		cEDSAcq.StartThread(); // Start EDS acquisition in background
	}

	if(nEels > 0){
		Image EelsStack := ALCEELSAcq(nEels, acqEels, sumFrames, \
		specBin, vertBin, processing); // Acquire EEL spectra
		Number nChEels = EelsStack.ImageGetDimensionSize(0);
		img[0, 0, nEels, min(nChEels, w)] = EelsStack[0, 0, nEels, min(nChEels, w)];
	}

	if(nEds == 1){
		oEDSSignal.WaitOnsignal(timeOut, oCancelSignal);
		if(!cEDSAcq.IsAcquiring()){
			Image EdsSpec := cEDSAcq.GetEDSImage(); // Receive EDS spectrum data
			nChEds = EdsSpec.ImageGetDimensionSize(0);
			img[nEels, 0 , nEels + 1, min(nChEds, w)] = EdsSpec[0, 0, 1, min(nChEds, w)]
		}else{
			Result("EDS acquisition has been timed out.\n");
		}
	}
}
