What is the opposite command of CleanImage() - dm-script

CleanImage( BasicImage )
allows to delete an image without getting the dialog: "Do you want to save ..."
Apart from adding zero to the whole image (8k by 8k), is there a counter part? Like:
DirtyImage( BasicImage )
Thanks!

No, such a command does not exist, but it also isn't really useful.Any action on an imageDocument will automaticaly mark it dirty (i.e. needs to be saved), so you can easily do this by f.e. adding/removing a tag; setting a pixelvalue temporarily; moving the window, etc.
The command CleanImage() is just a convenience feature really. The actual property "is different from stored file" is a property of the the ImageDocument, the stuff that gets saved to disc.
As a consequence, the command isn't really doing anything to images which do not have an ImageDocument, i.e. image variables which have never been shown, saved, or had ImageGetOrCreateImageDocument() called on them. You can see this here:
image img := RealImage( "test", 4, 100, 100 )
If ( TwoButtonDialog("Show?","Yes","No") )
img.ShowImage()
If ( TwoButtonDialog("Try closing before cleaning?","Yes","No") )
img.CloseImage()
else
{
img.CleanImage()
img.CloseImage()
}
The command really matches to:
void ImageDocumentClean( ImageDocument imgDoc )
and the command to check if an imageDocument needs saving is
Boolean ImageDocumentIsDirty( ImageDocument img_doc )
So, more typically one would use these commands instead, as I do in the scripts below.
The following script shows how you can easily "dirty" an imageDocument just by re-setting one of the pixels value. Note that this script works independently of having the image displayed, because we explicitly create the ImageDocument.
Result( "\n Create Image... ")
image img := RealImage( "test", 4, 100, 100 )
Result( "\n Get it's ImageDocument... ")
imageDocument doc = img.ImageGetOrCreateImageDocument()
Result( "\n Is it dirty? --> " + (doc.ImageDocumentIsDirty()?"Yes, dirty":"No, clean"))
Result( "\n Clean it!" )
doc.ImageDocumentClean()
Result( "\n Is it dirty? --> " + (doc.ImageDocumentIsDirty()?"Yes, dirty":"No, clean"))
Result( "\n Make it dirty by setting the first pixel value to the value it has..." )
img.SetPixel(0,0,img.GetPixel(0,0))
Result( "\n Is it dirty? --> " + (doc.ImageDocumentIsDirty()?"Yes, dirty":"No, clean"))
However, I am curious in when such a functionality would ever be needed?

Related

dm-script adjust image display content

Drag a corner of an image in DM triggers the image content refreshed to the new window size. What is the DM script command to trigger that refreshing?
Specifically, I want to add a text below the image. So, I get the imageDocument as root component, add a text annotation below the image (the vertical position of the text is beyond the bottom border of the image). Without "imgDoc.ImageDocumentSwitchToPageMode()", the text is not visible. When I change the image size with mouse, the image content is updated and the text is shown. Looking for script doing that.
Thanks,
The command you're seeking is void ImageDocumentOptimizeWindow( ImageDocument imgDoc )
but there is a bit more to the story:
You can add annotations (which really are Components ) to any other Component. An ImageDisplay is also a specialization of a Component. Thus, you may either add text as an annotation on an ImageDisplay - or on an ImageDocument.
If the first, then the text will move & resize when you move/resize the ImageDisplay, but if you add it to the ImageDocument's root component, it is "side-ordered" to and independent of the ImageDisplay on the page.
Here is a code example for either:
image test := RealImage("Test",4,512,512)
test=icol
test.ShowImage()
imageDisplay disp = test.ImageGetImageDisplay(0)
imageDocument doc = test.ImageGetOrCreateImageDocument()
If ( TwoButtonDialog("Add as part of Image or Page?","Image","Page") )
{
component text1 = NewTextAnnotation( 10, 550, "Under image as part of ImageDisplay", 20)
disp.ComponentAddChildAtEnd(text1)
doc.ImageDocumentOptimizeWindow()
}
else
{
component text2 = NewTextAnnotation( 10, 550, "Under image as part of ImageDocument", 20)
doc.ImageDocumentEnsurePlacedOnPage()
doc.ImageDocumentSwitchToPageMode()
doc.ImageDocumentGetRootComponent().ComponentAddChildAtEnd(text2)
}
To better understand the structure of things, you may want to run a script like the following on an ImageDocument:
void RecursiveListChildren( component parent, string preFix )
{
number numChild = parent.ComponentCountChildren()
Result("\n"+preFix+" [Type "+parent.ComponentGetType()+"]")
for( Number i =0; i<numChild; i++ )
RecursiveListChildren( parent.ComponentGetChild(i), prefix + "..." )
}
component root = GetFrontImageDocument().ImageDocumentGetRootComponent()
ClearResults()
RecursiveListChildren(root,".")
For the two documents of the first script, this will give you:
. [Type 24]
.... [Type 20]
....... [Type 13]
and
. [Type 24]
.... [Type 20]
.... [Type 13]
For new GMS 2.x or higher, the answer is void ImageDocumentOptimizeWindow( ImageDocument imgDoc ). Not tested.
For older GMS, a generic solution is like this,
void resetImageDisplay(image img) {
imageDisplay imgDsp=img.ImageGetImageDisplay(0)
imageDocument imgDoc = img.ImageGetOrCreateImageDocument()
imgDoc.ImageDocumentSwitchToPageMode()
imgDoc.ImageDocumentSwitchToImageMode(imgDsp)
}
void main() {
image img:=exprSize(512,512, random())
img.showImage()
imageDisplay imgDsp=img.ImageGetImageDisplay(0)
component comp1=imgDsp.NewTextAnnotation(200, 540, "text 1", 14)
component comp2=imgDsp.NewTextAnnotation(200, 560, "text 2", 18)
comp1.ComponentSetForegroundColor(0,0,0)
comp2.ComponentSetForegroundColor(0,0,0)
imgDsp.ComponentAddChildAtEnd(comp1)
imgDsp.ComponentAddChildAtEnd(comp2)
img.resetImageDisplay()
//img.setWindowSize(1024,1024)
}
main()

How to use dm script to realize the "save display as" function?

It is easy to save the false color image to BMP or JPG by using "save display as" function in menu. But it fails to save a image stack as the seperated images with the displaying color. "save display as" only saves the front image of the stack. I could not click hundreds of times to save the whole stack! But I do not find the corresponding script function in the dm manual. How to realize it?
The command you're looking for is ImageDisplayGetExportImage() and there is actually an
example script in the F1 help documentation of latest GMS for that:
But the command - same as the menu item - will only act on the actual display, so you still need to iterate over the displayed layers by script using ImageDisplaySetDisplayedLayers()
So your script will be something like the following example:
image test:=RealImage("Stack",4,100,100,10)
test=sin(icol/iwidth*Pi()*2) * cos(itheta*iplane)
test.ShowImage()
imagedisplay disp = test.ImageGetImageDisplay(0)
disp.ImageDisplaySetColorTableByName("Rainbow")
number nz = test.ImageGetDimensionSize(2)
for( number z=0; z<nz; z++){
disp.ImageDisplaySetDisplayedLayers(z,z)
imageDisplay newdisp
image asDisplayedRGB := disp.ImageDisplayGetExportImage( 7, newdisp )
asDisplayedRGB.SetName( test.GetName() + "_" + z )
asDisplayedRGB.ShowImage()
}
EGUPerformActionWithAllShownImages("arrange")
I hope this is what you are looking for. The shown script allows you to save all images in the current workspace to a directory. You can specify the format, the directory and the name pattern. (It got a bit longer than I expected):
TagGroup formats = NewTagGroup();
formats.TagGroupSetTagAsString("Gatan Format", "dm4");
formats.TagGroupSetTagAsString("Gatan 3 Format", "dm3");
formats.TagGroupSetTagAsString("GIF Format", "gif");
formats.TagGroupSetTagAsString("BMP Format", "bmp");
formats.TagGroupSetTagAsString("JPEG/JFIF Format", "jpg");
formats.TagGroupSetTagAsString("Enhanced Metafile Format", "emf");
formats.TagGroupSetTagAsString("TIFF Format", "tif");
formats.TagGroupSetTagAsString("PCX Format", "pcx");
class FormatDialog : UIFrame{
TagGroup format_select;
number FormatDialogGetSelectedFormat(object self){
if(format_select.TagGroupIsValid()){
return format_select.DLGGetValue();
}
else{
return -1;
}
}
object init(object self){
TagGroup dlg, dlg_items;
dlg = DLGCreateDialog("Select the format", dlg_items);
dlg_items.DLGAddElement(DLGCreateLabel("Please select the export format"));
format_select = DLGCreateChoice(0);
format_select.DLGIdentifier("format_select");
for(number i = 0; i < formats.TagGroupCountTags(); i++){
string text;
formats.TagGroupGetIndexedTagAsString(i, text);
text = formats.TagGroupGetTagLabel(i) + " (" + text + ")";
format_select.DLGAddChoiceItemEntry(text);
}
dlg_items.DLGAddElement(format_select);
self.super.init(dlg);
return self;
}
}
object format_dialog = alloc(FormatDialog).init();
if(format_dialog.pose()){
number format = format_dialog.FormatDialogGetSelectedFormat();
if(format < 0 || format >= formats.TagGroupCountTags()){
throw("Invalid format is selected");
}
string save_format = formats.TagGroupGetTagLabel(format);
string save_extension;
formats.TagGroupGetIndexedTagAsString(format, save_extension);
string save_dir;
if(GetDirectoryDialog("Please select the path to save to", GetApplicationDirectory("open_save", 1), save_dir)){
string save_name;
if(GetString("Please set the file name (without extension). A number will be added to the end automatically.", "file_", save_name)){
for(number i = 0; i < CountImageDocuments(); i++){
ImageDocument doc = GetImageDocument(i);
doc.ImageDocumentSaveToFile(save_format, PathConcatenate(save_dir, save_name + i + "." + save_extension));
}
OKDialog("Saved " + CountImageDocuments() + " files.");
}
}
}
Note that you can add that to DigitalMicrographs menus. Save the posted code as a file, then use File > Install Script File and add the script to any of your existing menus or a new menu.

How to trace the data that is going through caches and DRAM memory in gem5?

--exec-flags Cache,DRAM show addresses and sizes, but sometimes I just need to see the actual data being sent.
I know that this might produce large logs, but that is fine as I'm restricting my area of interest well via --debug-start and -m/--debug-break (used a hack here to just finish the simulation at a tick).
https://gem5-users.gem5.narkive.com/VUAhxc7J/how-can-i-trace-data-of-cache mentions using CommMonitor. It is a bit annoying to have to modify the run script, but that's also a valid solution. It would be good to give a minimal example here that patches say se.py to add it and how to view its output.
I also have DPRINTF patch which seems to help and I'll try to publish. Here's a sketch:
## -385,14 +386,17 ## void
Packet::print(std::ostream &o, const int verbosity,
const std::string &prefix) const
{
- ccprintf(o, "%s%s [%x:%x]%s%s%s%s%s%s", prefix, cmdString(),
+ ccprintf(o, "%s%s [%x:%x]%s%s%s%s%s%s D=%llx", prefix, cmdString(),
getAddr(), getAddr() + getSize() - 1,
req->isSecure() ? " (s)" : "",
req->isInstFetch() ? " IF" : "",
req->isUncacheable() ? " UC" : "",
isExpressSnoop() ? " ES" : "",
req->isToPOC() ? " PoC" : "",
- req->isToPOU() ? " PoU" : "");
+ req->isToPOU() ? " PoU" : "",
+ flags.isSet(STATIC_DATA|DYNAMIC_DATA) ?
+ mem2hex_string(getConstPtr<const char>(), getSize())
+ : "");
}
and then implement mem2hex_string as shown at: C++ read binary file and convert to hex
Edit: I managed to add a CommMonitor by hacking se.py, but I could not see any memory value output in any files nor in its code, the only thing I could see was new stats being added, so not sure that can help at all.

Can one get a list of fonts available for text annotations in DM scripting?

One can create text annotations on image displays via the function NewTextAnnotation and then change the font via the method ComponentSetFontFaceName. However to do so successfully, one must provide the full name of the desired font as a string and one must already know that it is available on the current system. If one specifies an unavailable font, some default font seems to be chosen and no exception or error message is posted.
Is there any way to get a list of available fonts within a DM script or to determine whether a specific named font is actually available?
Interesting task!
There is no actual script command to do this, and the list of installed font-names is populated by the OS.
However, using Powershell and the script command LaunchExternal() one can construct a workaround.
After some trial and error, I think I got it working by the following script:
void WriteFontListToDisk( string fileName )
{
String PSscript
PSscript += "[System.Reflection.Assembly]::LoadWithPartialName('System.Drawing');"
PSscript += "(New-Object System.Drawing.Text.InstalledFontCollection).Families "
PSscript += " | out-file -encoding ASCII " + fileName // Need to specify ASCII here!
String callString
callString += "powershell"
//callString += " -NoExit" // Keep Powershell open
callString += " -Command &{ "
callString += PSscript
callString += " }"
LaunchExternalProcess( callString, 5 )
}
TagGroup ReadFontListFromFile( string fileName )
{
TagGroup tg = NewTagList()
if ( !DoesFileExist( fileName ) ) Throw( "Font list file not found:\n" + fileName )
number fileID = OpenFileForReading( fileName )
object fileStream = NewStreamFromFileReference( fileID, 1 )
result("\n SIZE:" + fileStream.StreamGetSize() )
// Output format is
// #1:(empty)
// #2: Name
// #3: ----
// #4+: FontNames
string line
for( number i=0;i<3;i++) fileStream.StreamReadTextLine( 0, line )
number inc = 0
while( fileStream.StreamGetPos() != fileStream.StreamGetSize() )
{
if ( !fileStream.StreamReadTextLine( 0, line ) ) break;
tg.TagGroupInsertTagAsString( Infinity(), line )
if ( ShiftDown() ) exit(0)
}
return tg
}
TagGroup GetFontList()
{
TagGroup tg = NewTagGroup()
string fileName = "C:\\FontNamesList.txt"
if ( DoesFileExist( fileName ) ) DeleteFile( fileName )
WriteFontListToDisk( fileName )
tg = ReadFontListFromFile( fileName )
if ( DoesFileExist( fileName ) ) DeleteFile( fileName )
return tg
}
GetFontList().TagGroupOpenBrowserWindow( "Fonts" , 0 )
It is worthwhile to note that PowerShell by default streams text output as UNICODE and that does not work well with text-import in DM. However, this question was helpful, and the script above sets the output to ASCII. One issue though is, that in doing so some characters might be lost and it might be needed to carefully check the output font-list.

How to save images automatically after setting up a path?

I want to save my images automatically, but I don't know how to set it in DM. My script is as follows:
Image img
img.GetFrontImage()
string name
if ( GetString( "Enter Name of Sample", "Hello!", name ))
result( "\nThe Name Of Sample is "+name)
string path
if ( GetDirectoryDialog("select path","",path) )
result("\nSelected path is:"+path)
While( img.ImageIsValid() )
{
For( number i=i; i<1000000;i++ )
{
img.SetName(name+i)
img.SaveImage(name+i)
img := FindNextImage(img)
}
}
It seems the main thing you are missing is a line that creates a full pathname from the combination of the destination directory path and the name for each image. So in addition to the changes suggested in the answer by BmyGuest, you should add a call to PathConcatenate, as follows:
number i = 1
While( img.ImageIsValid() )
{
img.SetName(name+i)
string filepath = path.PathConcatenate(name+i)
img.SaveAsGatan(filepath)
img := FindNextImage(img)
i++
}
The script you've written will not save anything, but most likely produce an error.
In the For-loop you 1000000x get the "next" image to save, but when you reach the end the "next" image is invalid.
Therefore, the next iteration will throw an error at img.SetName, because img is not a valid image at that moment.
What you want to do is something like the following:
number i = 1
While( img.ImageIsValid() )
{
img.SetName(name+i)
img.SaveAsGatan(name+i)
img := FindNextImage(img)
i++
}