Auto save upon computer shutdown
KP
Hello! I am wondering if there is a way to enable auto save option to igor files for recovery upon PC shutdown/restart? I have lost my files many a times and it would be great if someone could share the steps to enable auto save option.
Thank you!
I don't know of any built-in options. It seems to me like the best approach would be to have Igor save periodically on its own. (Because a computer shutdown might not provide enough time for Igor to save anyway.)
I sometimes use the code below to make sure my experiments save every so often, but I haven't tested it that much. It could be modified to save a copy instead of overwriting the pre-existing pxp file.
As to handling an unexpected computer shutdown, I wonder if IgorBeforeQuitHook (displayhelptopic "Used-defined hook functions") with the SaveExperiment function could help.
All of these home-made options require the code to be compiled, which is a downside.
Editing to add: another downside to this approach is that it does not save items in the Igor instance that are saved in separate files (e.g., in some cases, Notebooks and procedure files). (I also changed the code below to make it an independent module, which seems a good idea.)
//EXPERIMENT AUTO SAVE FUNCTIONS
//default is that auto save begins on experiment start (assuming code compiles at experiment start)
//otherwise toggle start/stop in the file menu
//if the functions attempt an auto save before a pxp has been saved (and thus has no name)
//then the name begins with ks_autoSaveBaseName followed by the year,month,day,hour,minute,second of the first save (underscore-delimited)
//constants that determine key aspects of auto save behavior -- user should adjust as preferred
static constant k_experimentAutoSaveRate_inMinutes = 30
static constant k_autoSaveCancelWindows_inSeconds = 20
static strconstant ks_autoSaveBaseName = "experimentAutoSave_"
//menu toggle
Menu "File", hideable,dynamic
selectstring(getExperimentAutoSaveStatus(),"Toggle experiment auto save from off to ON","! Toggle experiment auto save from on to OFF"),/Q,experimentAutoSave("")
end
//start auto save on experiment start
function IgorStartOrNewHook(igorApplicationNameStr)
String igorApplicationNameStr //not used
experimentAutoSave("on") //this line should be added to IgorStartOrNewHook() if another exists already
end
//functions for auto save
function experimentAutoSave(onOrOffStr)
String onOrOffStr //"" to toggle, "on" to start, "off" to stop (any other string also defaults to "off")
if (strlen(onOrOffStr) < 1) //toggle for ""
onOrOffStr = selectstring(getExperimentAutoSaveStatus(),"on","off")
endif
strswitch (onOrOffStr)
case "on":
//one issue: when Ctrlnamedbackground runs, except apparently at start up, it attempts to auto save immediately when I think due to start=periodTicks it should wait until a full period has passed...
Variable periodTicks = k_experimentAutoSaveRate_inMinutes*60*60 //convert to ticks (60 per second)
Ctrlnamedbackground pxpSaveMainBgTask,dialogsOK=0,period=periodTicks,start=periodTicks,proc=pxpSaveMainBg //set it to start after one period and not to run during dialogs
print "experiment auto saves started at a rate of every",k_experimentAutoSaveRate_inMinutes,"minutes (adjust with k_experimentAutoSaveRate_inMinutes)"
break
default:
killwindow/z pxpSavePanel
ctrlnamedbackground pxpSaveHelperBgTask,kill=1 //kill the helper background task (which might or might not exist at a given run time)
Ctrlnamedbackground pxpSaveMainBgTask,kill=1 //kill the main background task
endswitch
end
//returns 1 if auto save is on, 0 if off
function getExperimentAutoSaveStatus()
Ctrlnamedbackground pxpSaveMainBgTask,status //if the main background task is running, auto save is ON
return str2num(stringbykey("RUN",S_info)) //run is 1 if running, in which case auto save is also running
end
function pxpSaveMainBg(s)
STRUCT WMBackgroundStruct &s
//check if the experiment has been modified since last save and therefore needs saving
experimentmodified
if (!V_flag)
return 0 //dont try to save at present but continue the background task
endif
//if there's already an auto save panel up, somehow an auto save is already scheduled to occur (might happen if k_experimentAutoSaveRate_inMinutes is really short relative to k_autoSaveCancelWindows_inSeconds
if (wintype("pxpSavePanel") != 0)
return 0 //dont try to save at present but continue the background task
endif
newpanel/n=pxpSavePanel/w=(0,0,200,50)/k=1 as "Auto save experiment"
setwindow pxpSavePanel userdata(cancelCountdown)=num2str(k_autoSaveCancelWindows_inSeconds)
Button cancelAutoSavePxp win=pxpSavePanel,fsize=15,fstyle=1,pos={20,2.5},size={170,40},title="CANCEL pxp auto save",proc=cancelAutoSavePxpBtn
Ctrlnamedbackground pxpSaveHelperBgTask,period=60,start=60,dialogsOK=0,proc=pxpSaveHelperBg //start helper function running every 60 ticks (~1 second) and starting after 60 ticks
return 0 //continue the background task
end
function pxpSaveHelperBg(s)
STRUCT WMBackgroundStruct &s
//cancel if the window has been killed and cancel if so
if (wintype("pxpSavePanel") == 0)
return 1 //end this helper background function
endif
//check if the count down is over
variable cancelCountdown = str2num(getuserdata("pxpSavePanel","","cancelCountdown"))
if (cancelCountdown > 0)
Button cancelAutoSavePxp win=pxpSavePanel,title=("CANCEL pxp auto save\rstarting in ~"+num2str(cancelCountdown)+" secs")
setwindow pxpSavePanel userdata(cancelCountdown)=num2str(cancelCountdown-1) //iterate down the timer
return 0 //continue count down
endif
//figure out if the experiment has been saved before
String pxpName = igorinfo(1)
int hasPxpName = cmpstr(pxpName,"Untitled",1) != 0 //Note: experiments actually saved as "Untitled.pxp" appear to be an issue
if (hasPxpName) //been saved before, so easy to just resave
saveexperiment
else //name is "Untitled", indicating that pxp has not been saved (or at his been saved as "Untitled", which would be problematic at present!)
int secs = datetime
String timeStr = replacestring("-",secs2date(secs,-2),"_") +"_"+replacestring(":",secs2time(secs,3),"_")
String savename = ks_autoSaveBaseName + timeStr + ".pxp"
pathinfo IgorUserFiles
print "experimentAutoSave() this pxp appears to be previously unsaved. Pxp will be saved with the automatically generated name:",savename,"in folder="+S_path
saveexperiment/p=IgorUserFiles as savename
endif
killwindow pxpSavePanel //kill the panel
experimentmodified 0 //since we just killed the window, the experiment has been modified, but it's not a reason to save again next round, so mark experiment unmodified
return 1 //end this helper background function
end
function cancelAutoSavePxpBtn(s) : ButtonControl
STRUCT WMButtonAction &s
if (s.eventcode != 2) //only react to mouse up in button area
return 0
endif
Ctrlnamedbackground pxpSaveHelperBgTask,kill=1
killwindow pxpSavePanel
end
//end of functions for auto save
May 14, 2020 at 04:07 pm - Permalink
Autosave is useful, not exactly what you want. Here is code snippet I am using: https://www.wavemetrics.com/code-snippet/autosave
May 14, 2020 at 08:03 pm - Permalink
One issue with these auto save approaches is that a save can take a long time for a large file, which will disrupt whatever the instance of Igor is doing. Adobe Illustrator auto-saves in a parallel task, so you can keep working. I think it would be really nice if Igor did that.
I'm not sure it's something that could be programmed by users -- I think it would have to be possible to initiate saving a copy of a pxp file from a parallel thread (and I'm not sure what happens if you try that). Once the copy is saved, the original pxp could optionally be overwritten by the copy.
It also doesn't seem straightforward for a user/programmer to auto save stand-alone files (Notebooks, procedures). For example, I don't see a documented way to tell whether a notebook is adopted or saved into a stand-alone file (and thus in potential need of autosaving).
May 15, 2020 at 08:25 am - Permalink
Hi,
One strategy I have used in the past for metrology tool I built is to use an unpacked experiment where the waves are saved to a folder. That way if the system crashed the data files would still be there. Additionally the operating system did a back up to save the data.
Andy
May 15, 2020 at 09:23 am - Permalink
In reply to Hi, One strategy I have… by hegedus
I haven't used unpacked experiment files much, but wouldn't you still have to save the unpacked experiment (or the individual waves, as ibws) in order to avoid losing changes that you've made to the data in Igor? If you've been working on an unpacked experiment and the computer crashes, you're going to lose the changes just as for a packed experiment (please correct me if I am wrong).
May 15, 2020 at 10:44 am - Permalink
You are correct about the save and if i recall (this was ~10 years back and I don't have access to the code any longer) that I saved the new data waves when they there generated so it was not the whole experiment. Also The procedure and history are saved in easily readable text files.
Andy
May 15, 2020 at 10:58 am - Permalink
In reply to You are correct about the… by hegedus
ah, I see. That is a nice approach for such a situation.
May 15, 2020 at 11:03 am - Permalink
Igor 9 (soon in beta) has autosave built in. There are options for saving an entire experiment vs. standalone files only, and options to save to the original files vs. saving to a ".autosave" file instead. Even then, if the user-configurable autosave interval has not expired since the last save, any changes made since the last save will be lost.
If you are primarily acquiring data, I recommend that you save the data as soon as you acquire it (or as soon as practical) so that Igor crashing or a power failure won't cause you to lose data. I like to write data to an HDF5 file, since this is a binary format that can be easily appended to, so you don't need to rewrite the entire file each time you save like you would with a packed experiment.
May 17, 2020 at 07:23 am - Permalink
Sounds great. Is there any chance that saving (and autosaving) could occur in the background, so that Igor can keep running during the save?
May 17, 2020 at 07:31 am - Permalink
In reply to Sounds great. Is there any… by gsb
No, I believe the autosave will only do the save if nothing else is happening (eg. no procedures running, etc.). The save code all runs from the main thread, so it needs to be run only when Igor is idle. This means that if you enable autosaving experiments, and saving your experiment takes more than a trivial amount of time, you'll probably notice a bit of lag when autosave kicks in. But if you are only autosaving procedure files, I don't expect you'll notice much lag unless the files are located on a network share and the save is relatively slow.
May 17, 2020 at 08:02 am - Permalink