2

Is there an efficient and elegant way to managing tag paths used by different scripts? For example, I have one script to write certain metadata in to an image:

// common tag group paths
string tgPath1A = "script1:group1:parameter A";
string tgPath1B = "script2:group2:parameter B";
string tgPath2 = "point";

// write meta data
image img := RealImage( "image 1", 4, 50, 50 );
TagGroup tgImg = img.ImageGetTagGroup();
tgImg.TagGroupSetTagAsString( tgPath1A, "Hello" );
tgImg.TagGroupSetTagAsNumber( tgPath1B, 35 );
tgImg.TagGroupSetTagAsShortPoint( tgPath2, 3, 5 );
img.ShowImage();

Then I have another script to access these metadata:

// common tag group paths
string tgPath1A = "script1:group1:parameter A";
string tgPath1B = "script2:group2:parameter B";
string tgPath2 = "point";

// write meta data
image img := GetFrontImage();
TagGroup tgImg = img.ImageGetTagGroup();
string str;
if( tgImg.TagGroupGetTagAsString( tgPath1A, str ) ) \
    result( tgPath1A + " = " + str + "\n" );
number num;
if( tgImg.TagGroupGetTagAsNumber( tgPath1B, num ) ) \
    result( tgPath1B + " = " + num + "\n" );
number px, py;
if( tgImg.TagGroupGetTagAsShortPoint( tgPath2, px, py) ) \
    result( tgPath2 + " = (" + px + ", " + py + ")\n" );

Instead of "hard coding" the tag paths at the beginning for each script handling these specific metadata, is there a better way? The entries of these tag paths can reach hundreds or more for a large projects where multiple scripts writing and reading to the corresponding tag group (which can be associated with images or as part of global tag group).

2 Answers 2

3

It looks like what you are trying to do is to have some sort of formalized and generalized way to access structured data associated with your projects and to do so without all the overhead involved with TagGroup access and tags paths. In the DMS framework I have developed for my own script app collection, I do this by way of a global class library that I can access from any of my DMS-based apps. With this approach, the nitty gritty of TagGroup access and tag paths is encapsulated within each library class and app-level code simply uses methods of each class to get and set values that are relevant to a given object context.

For example, suppose one of your data sets involves tag data at the Image object level that is relevant to EDS data analysis. You could define a class, perhaps called QuantitativeEDS, that takes such an Image object as input to an Init method. This class would have methods for directly accessing parameters (stored in Image tags) related to EDS data analysis. Examples of such methods might be GetBeamEnergy or GetDetectorSolidAngle. Only the implementations of these methods would do the actual tag data access via tag paths. Any application code that uses the QuantitativeEDS class would only need to know the correct method names and can completely side-step the details of TagGroup access and tag paths.

This is a very abstract sort of answer, but if this approach is of interest, I can try to come up with some simple examples to illustrate the approach a bit more concretely.

Sign up to request clarification or add additional context in comments.

Comments

2

My answer is somewhat similar to Mike's, but maybe simpler to implement.

If the identical tag-paths need to be accessed from different scripts multiple times, it definitely makes sense to abstract that into some central location. Depending on your coding and package-management style, there are different ideas I could think of:

1) Single-Place hardcoded paths

Have a single accessor method in which you hardcode all your paths. Then install that method as a library function.

string REPO_GetPropertyPath(string key)
{
    if ("BeamEnergy" == key) return "Microscope Info:Beam Energy (kV)"
    if ("ImageFormat" == key) return "Meta Data:Image Format"
    ...
    Throw("TagPath for property '"+key+"' not found.")
}

2) "TagPath repository" in Globaltags

Store paths in the GlobalTags as strings, and access them via two methods. These could either be "copy pasted" into all of your scripts, or installed as library methods.

void REPO_SetPropertyPath(string key, string path)
{
    TagGroup repo = GetPersistentTagGroup()
    if (""==path)
        repo.TagGroupDeleteTagWithLabel("Path-Repo:"+key)
    else
        repo.TagGroupSetTagAsString( "Path-Repo:"+key,path))        
}

string REPO_GetPropertyPath(string key)
{
    string path
    TagGroup repo = GetPersistentTagGroup()
    if (!repo.TagGroupGetTagAsString( "Path-Repo:"+key,path))
        Throw("TagPath for property '"+key+"' not found.")
    return path
}

3) "TagPath repository" in file

Like the above, but use a dedicated .gtg file for your path instead of the persistent tags.

TagGroup GetRepoTags()
{
    string repoPath = "C:\\repotags.gtg"
    TagGroup repo = NewTagGroup()
    if ( !repo.TagGroupLoadFromFile( repoPath ) )
        Throw( "Could not open repo file\n\n" + repoPath )
        
    return repo
}

void REPO_SetPropertyPath(string key, string path)
{
    TagGroup repo = GetRepoTags()
    if (""==path)
        repo.TagGroupDeleteTagWithLabel(key)
    else
        repo.TagGroupSetTagAsString(key,path))      
}

string REPO_GetPropertyPath(string key)
{
    TagGroup repo = GetRepoTags()
    if (!repo.TagGroupGetTagAsString( "Path-Repo:"+key,path))
        Throw("TagPath for property '"+key+"' not found.")
    return path
}

4) "TagPath repository" as script package

It is also possible to store taggroups in packages. So one could create a package that contains the lookup-paths as well as an accessor method. (This is not so different from #1 installed as library, just that the paths are coded as taggroup rather than a method.)

string packageName = "TagRepo"
number packageLevel = 0
string packageLocation = "plugin"  // or "user_plugin" for per user-packages)
string packageTagID = "REPO"
string packageLibraryID = "REPOSCRIPT"

TagGroup repotgs = NewTagGroup()
repoTgs.TagGroupSetTagAsString("BeamEnergy","Microscope Info:Beam Energy (kV)")
repoTgs.TagGroupSetTagAsString("ImageFormat","Meta Data:Image Format")

repoTgs.AddTagsToPackage(packageName,packageLevel,packageLocation,packageTagID)

string scriptCode
scriptCode += "\n" + "string REPO_GetPath(string key)" 
scriptCode += "\n" + "{"
scriptCode += "\n" + "  string path"
scriptCode += "\n" + "  TagGroup repo = GetPackageTags( \"" + packageTagID + "\" )"
scriptCode += "\n" + "  if ( !repo.TagGroupGetTagAsString( key, path) )"
scriptCode += "\n" + "  Throw( \"TagPath for property '\"+key+\"' not found.\" )"
scriptCode += "\n" + "  return path"
scriptCode += "\n" + "}"
//result(""+scriptcode)
AddScriptToPackage(scriptCode,packageName,packageLevel,packageLocation,packageLibraryID ,"","",1)   // as library command

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.