Scheduler is awesome, we all know this. But one downside is that flat collection is a bit in-efficient. You end up collecting flats for all filters every night, whether or not that filter was used. I have 7 filters and my image size is 100MB. This quickly becomes a problem by clogging up my disk with gigs of unwanted flats.

So, I changed things up. I only collect flats for the filters that were used during the night. A few caveats:
- My method will only work if you are doing dawn flats or panel flats in the morning. The flats need to happen after the light frames so we can keep tabs on what filters were used during the night
- It should work with rotator angles as well making it even more efficient (you only collect for the rotator angles you used during the night), although I don't use a rotator and so have not explored this deeply or tested it.

So here's what I do:
- Register UserActions.wsc, so ACP will run your code at certain events
- ImageStart is called everytime ACP is about to acquire an image, and this happens through the night
- In ImageStart, we know the filter and binning that is being used.
- Note this down into SchedulerDawnFlats.txt
- In ShutDownObs blow away the SchedulerDawnFlats.txt so that we start fresh again the next night

That's it! So through the night, we tabulate all the filters we used (and only those) and in the morning after all frames are done, scheduler uses SchedulerDawnFlats to only capture flats for those filters. Here's the code I use for this in ImageStart:

function ImageStart(Interval, Binning, Subframe, FilterNum, ForPointing)
	// Pointing Image
	if(ForPointing) {
		return true;

	// Bias or Dark Frame
	if (Interval <= 0) {
		return true;

        // customize this for the location of your SchedulerDawnFlats.txt
        // there is probably a better way of getting this from prefs somewhere rather
        // than hardcoding. But I am lazy and this works for now

	var schedFlatsFile = "Documents\\ACP Astronomy\\Plans\\SchedulerDawnFlats.txt";
	var currFlats = [[],[]];

	//creates the file if it does not exist. Open for reading and in ASCII
	var config = FSO.OpenTextFile(schedFlatsFile,1,true);
		var configLine = config.ReadLine();
		var configLineWords = configLine.split(",");
		var configFilt = configLineWords[1];
		var configBin = configLineWords[2];
		if(!currFlats.hasOwnProperty(configFilt)) {
			currFlats[configFilt] = new Array();


    //re-open file for appending. don't create if it does not exist. open as ASCII
    config = FSO.OpenTextFile(schedFlatsFile,8,false);
	var filt = "";
	switch(FilterNum) {
		case 0:
			filt = "Ha5nm";
		case 1:
			filt = "SII3nm";
		case 2:
			filt = "OIII3nm";
		case 3:
			filt = "LPSP2";
		case 4:
			filt = "Ha20nmRED";
		case 5:
			filt = "s_YGREEN";
		case 6:
			filt = "s_VBLUE";
			filt = "unknown";
	Util.Console.PrintLine("  Checking if filter " + filt + " bin " + Binning + " is in flats config...");
	if (!currFlats.hasOwnProperty(filt)) {
		Util.Console.PrintLine("  Filter and bin does not exist. Adding...");
		config.WriteLine("20," + filt + "," + Binning);
	} else {
		var bins = currFlats[filt];
		for (var b=0; b < bins.length; b++) {
			if (bins[b] == Binning) {
				Util.Console.PrintLine("  Filter and bin already exists...");
				return true;
		Util.Console.PrintLine("  Filter exists. Bin does not. Adding...");
		config.WriteLine("20," + filt + "," + Binning);
    return true;
Hope that helps!