I have a bunch of cryo and liquid cell dm4 images that are 32bit float, but the precision and the large values of 32bit are completely unnecessary, so we've decided to convert them to 16bit signed int.
I need to preserve the metadata structure that dm4 images have because the images still need to be openable in digital micrograph. So using hyperspy or ncempy is not an option since they can't write dm4 files.
I currently have a script to do this in dm-script, but it only takes in one directory at a time and doesn't know how to handle liquid cell data. And I am not good enough to do that.
I was wondering if I could do the same thing in the python interface in DM? Since I can manipulate the file structure and traverse the directories with easily with python.
The dm script I'm referring to is the on FELMI ZFE DigitalMicrograph Script Database slightly adjusted to allow for signed integers and not creating tiffs since they are not useful for us currently.
Edit: the dm-script works nicely for now, i am curious if there is a way to pass the source and output directory to my dm-script from the python script. That way i can do all the directory handling in python, and just call the dm-script one folder at a time.
Not sure if this is what you're after, but the script below shows how one recursively builds a file-list from all subfolders, filters it by extension, and then act on each of them.
The current script will open all .dm4 files of a given folder and its subfolders, convert the image into sint16 and resave it with a prefixed name.
However, you can very easily adjust the script by modifying the method ActOnFile
.
// Script class compiling a (filtered) TagList of filepaths from
// a folder. Optionally with recursion for subfolders
Class CRecursiveFileList{
TagGroup BuildList( object self, string path, string leadIn, string leadOut, number bSubfolders){
tagGroup FileList = NewTagList()
TagGroup allFiles = GetFilesInDirectory( path, 1 )
number nFiles = allFiles.TagGroupCountTags()
leadIn = StringToLower(leadIn)
leadOut = StringToLower(leadOut)
for ( number i=0; i<nFiles; i++ )
{
string file
TagGroup entry
allFiles.TagGroupgetIndexedTagAsTagGroup( i, entry )
entry.TagGroupGetTagAsString( "Name", file )
file = StringToLower(file)
if ( len(leadIn) > len(file) ) continue
if ( len(leadOut) > len(file) ) continue
if ( left(file,len(leadIn)) != leadIn ) continue
if ( right(file,len(leadOut)) != leadOut ) continue
FileList.TagGroupInsertTagAsString( Infinity(), PathConcatenate(path,file) )
}
if (bSubFolders)
{
TagGroup allFolders = GetFilesInDirectory( path, 2 )
number nFolders = allFolders.TagGroupCountTags()
for ( number i=0; i<nFolders; i++ )
{
string folder
TagGroup entry
allFolders.TagGroupgetIndexedTagAsTagGroup( i, entry )
entry.TagGroupGetTagAsString( "Name", folder )
folder = StringToLower(folder)
TagGroup SubList = self.BuildList( PathConcatenate(path,folder), leadIn, leadOut, bSubfolders )
for ( number j=0; j<SubList.TagGroupCountTags(); j++)
{
string file
if ( SubList.tagGroupGetIndexedTagAsString(j,file))
FileList.TagGroupInsertTagAsString( Infinity(), file )
}
}
}
return FileList
}
TagGroup Create( object self, string root, string LLin, string LLout, number incSubFolder ){
TagGroup fullFileList
if ( !DoesDirectoryExist( root ) || "" == root )
{
root = GetApplicationDirectory( "open_save", 0 )
if ( !GetDirectoryDialog(NULL,"Select root path", root, root ) )
return fullFileList;
}
fullFileList = self.BuildList( root, LLin, LLout, incSubFolder );
return fullFileList;
}
}
Class CActOnFileList{
void ActOnFile( object self, string path ){
// Do whatever you want with a file(path) here!
if ( !DoesFileExist(path) ) {
Result( "\n Not found: " + path ) // Skip with message
// Throw( "File not found:\n" + path ) // or stop the script with error
return
}
//Assuming it is an image, we open it
Image img := OpenImage(path)
if ( !img.ImageIsValid() ) {
Result( "\n Filt not an image: " + path ) // Skip with message
// Throw( "File is not a valid image:\n" + path ) // or stop the script with error
return
}
// We could show it...
//img.ShowImage()
// Instead, we convert it to 2-byte-integer and resave it with modifed name
ConvertToShort(img)
string newName = PathExtractDirectory(path,0) + "Conv_" + PathExtractBaseName(path,0)
img.SaveAsGatan(newName)
Result("\n Converted & Saved: " + newName )
}
number PerformActionOnAllFilesInList( object self, TagGroup fileList, number bShowProgress ){
number nFiles = fileList.TagGroupCountTags()
for( number i = 0; i<nFiles; i++ ){
if ( bShowProgress )
OpenAndSetProgressWindow( "Acting on file", (i+1) + " of " + nFiles, "" )
string path
if ( fileList.TagGroupGetIndexedTagAsString(i,path) )
self.ActOnFile(path)
}
CloseProgressWindow()
}
}
string root = "" // Leave "" to get a prompt
string pre = "" // Leave "" for no filter. Otherwise only paths which start with pre are kept
string suf = ".dm4" // Leave "" for no filter. Otherwise only paths which end with suf are kept
number subfolder = 1 // Set "0" to only work on the specified folder and 1 to include all subfolders
number showProgress = 1 // Set "1" to have a progress output (status bar)
Alloc(CActOnFileList).PerformActionOnAllFilesInList( Alloc(CRecursiveFileList).Create(root, pre, suf, subfolder), showProgress )