【问题标题】:Converting 32bit float DM4s to signed 16bit将 32 位浮点 DM4 转换为带符号的 16 位
【发布时间】:2020-08-27 12:29:32
【问题描述】:

我有一堆 32 位浮点数的冷冻和液态细胞 dm4 图像,但完全不需要 32 位的精度和大值,因此我们决定将它们转换为 16 位有符号整数。

我需要保留 dm4 图像所具有的元数据结构,因为图像仍需要在数字显微照片中可打开。因此,使用 hyperspy 或 ncempy 不是一个选项,因为它们无法写入 dm4 文件。

我目前在 dm-script 中有一个脚本可以执行此操作,但它一次只接收一个目录,并且不知道如何处理液体单元格数据。而且我还不够好。

我想知道我是否可以在 DM 的 python 界面中做同样的事情?因为我可以使用 python 轻松操作文件结构并遍历目录。

我指的 dm 脚本是 on FELMI ZFE DigitalMicrograph Script Database 稍作调整以允许有符号整数并且不创建 tiff,因为它们目前对我们没有用处。

编辑:dm 脚本现在运行良好,我很好奇是否有办法将源和输出目录从 python 脚本传递给我的 dm 脚本。这样我就可以在 python 中完成所有目录处理,一次只调用一个文件夹。

【问题讨论】:

  • 您的具体目标是什么? “冷冻和液体细胞”数据是否具有不同的格式,因此您无法使用当前的脚本?还是您当前脚本的唯一问题是它只能占用一个目录?请澄清这一点。在第一种情况下,请添加一些示例数据,在第二种情况下,请显示您当前的脚本。
  • “目录处理”到底需要什么,如果您只是在进行一些递归浏览之后,这在 DM 脚本中很容易完成。我认为 F1 帮助部分中甚至有一个示例脚本可以满足您的大部分需求......

标签: python dm-script


【解决方案1】:

不确定这是否是您所追求的,但下面的脚本显示了如何从所有子文件夹递归构建文件列表,按扩展名对其进行过滤,然后对每个子文件夹进行操作。

当前脚本将打开给定文件夹及其子文件夹的所有 .dm4 文件,将图像转换为 sint16 并使用前缀名称重新保存。

不过,你可以通过修改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 )

【讨论】:

  • 这看起来很棒,唯一的问题是我对 dm-scripts 非常天真。反正我可以从 python 调用一个 dm-script 函数?
  • @jovanymerham 你可以。使用import DigitalMicrograph; DigitalMicrograph.ExecuteScriptString(dmscript)。我建议将@BmyGuests 代码保存为单独的文件,然后使用open 获取文件内容。
  • @jovanymerham 我不想劝你不要使用 Python,但你真的可以在 DM 脚本中保持简单。我实际上已经修改了我上面的例子来做你需要的(我认为)。但它也非常通用且易于适应。
猜你喜欢
  • 2010-12-12
  • 2011-10-25
  • 1970-01-01
  • 2021-03-26
  • 1970-01-01
  • 1970-01-01
  • 2014-10-10
  • 1970-01-01
相关资源
最近更新 更多