Question

Can the 'Count()' FME Feature Function be used with 'Count Scope' = 'Local' and 'Count Start' = '1'?

  • 27 February 2022
  • 11 replies
  • 43 views

Badge +3

If I use a Counter Transformer in my workspace, I often find myself using a 'Local' Count Scope, and also I prefer to start counting at 1 (instead of at 0).

 

Also, I would prefer to use the count functionality through Count() FME Feature Function(s) as opposed to using Counter Transformers, as this makes my workspace a bit more compact.

 

Unfortunately, I haven't been able to combine both of these goals. In particular, I haven't been able to use the 'Count()' FME Feature Function in combination with a Local Count Scope and a Count Start of 1. See below screenshot and the attached workspace (FME 2021.2.2.0 b21806, Counter Version 3)).

 

imageI had a look at the FME Feature Function documentation page, and I thought that the NO_LOG option could be similar to the Local Count Scope.

 

If I look at the indicated Syntax of the Count() function, i.e.

@Count([<domain>[,<startVal>[,<modulo>]]][,NO_LOG]),

I'm tempted to believe that it should be possible to use the use both the 'startVal'='1' and also the NO_LOG option (probably also requiring a dummy domain value), without using the modulo option, but as indicated I haven't been able to make it work.

 

Also I noticed that when using any of the configured Count() FME Feature functions, at the end of the Translation log there is a portion on the`Count' Domain Summary, which indicates the amount of @Count invocations per (Global) domain, and in case of the 'NO_LOG' option it simply states 'Unlogged domains'.

I also see something similar when using the Counter transformer with a Global Count Scope (then there is a `CountFactory' Domain Summary), but when using the Counter transformer with a Local Count Scope there is no such Count Domain Summary in the log. So maybe the Counter transformer (with the Local Count Scope) uses a different setup/implementation than the Count() FME Feature function?


11 replies

Userlevel 5
Badge +29

In response to the count starting at 0 v 1, a simple solution is to just add one to the count when you call the function

@Evaluate(@Count()+1)

 

After looking through the rest of your problem the above can be easily done in the @Count() function.

See the screen shot below:

  • output of 'testa' ranges from 10-1009
  • output of 'testb' ranges from 99-1098
  • output of 'test' ranges from 321-2320

image

Badge +3

In response to the count starting at 0 v 1, a simple solution is to just add one to the count when you call the function

@Evaluate(@Count()+1)

 

After looking through the rest of your problem the above can be easily done in the @Count() function.

See the screen shot below:

  • output of 'testa' ranges from 10-1009
  • output of 'testb' ranges from 99-1098
  • output of 'test' ranges from 321-2320

image

Hi @hkingsbury​ ,

 

Thanks for the reply. I indeed noticed that it is possible to set the startVal directly in the @Count() function (as some of my examples also illustrated). But in your and my examples the @Count() function uses a 'Global' Count Scope, as opposed to the the preferred 'Local' Count Scope. That's an essential part of my question. 

 

So the thing with the Local Count Scope is that it doesn't remember the result of the previous Counter, and thus, each invocation starts counting at the startVal. 

 

When using the @Count() FME Feature function, each domain that you use is logged, and the counter continues counting from the previous count value for that domain. Thus, if you want to get the same result as in a local count, then you would need to make sure that each invocation of the @Count() FME Feature function uses a different domain (and thus in particular you need to keep track of the domains that you already used in the rest of the workspace). That's not ideal.

 

Initially I thought that the NO_LOG option of the @Count() function would make sure that the function would behave similar to a Local Count Scope, but I just noticed that also that option doesn't provide me with the desired result.

 

See also the below screenshot

image

Userlevel 2
Badge +17

II think the Counter transformer with Local Scope also uses the implementation of the @Count() function. FME just generates unique domain name implicitly for each local Counter, I guess.

Isn't it? @danminneyatsaf​ 

I remember that FME logged the domain name (prefixed by the transformer name, so it can be considered as unique) of a local Counter too, in an old version of FME.

Userlevel 5
Badge +29

Hi @hkingsbury​ ,

 

Thanks for the reply. I indeed noticed that it is possible to set the startVal directly in the @Count() function (as some of my examples also illustrated). But in your and my examples the @Count() function uses a 'Global' Count Scope, as opposed to the the preferred 'Local' Count Scope. That's an essential part of my question.

 

So the thing with the Local Count Scope is that it doesn't remember the result of the previous Counter, and thus, each invocation starts counting at the startVal.

 

When using the @Count() FME Feature function, each domain that you use is logged, and the counter continues counting from the previous count value for that domain. Thus, if you want to get the same result as in a local count, then you would need to make sure that each invocation of the @Count() FME Feature function uses a different domain (and thus in particular you need to keep track of the domains that you already used in the rest of the workspace). That's not ideal.

Initially I thought that the NO_LOG option of the @Count() function would make sure that the function would behave similar to a Local Count Scope, but I just noticed that also that option doesn't provide me with the desired result.

 

See also the below screenshot

image

The 'local count' is defined by the domain. So for each counter that you want to be local (a and b in my example) you need to set it with a unique value for that counter

Badge +3

II think the Counter transformer with Local Scope also uses the implementation of the @Count() function. FME just generates unique domain name implicitly for each local Counter, I guess.

Isn't it? @danminneyatsaf​ 

I remember that FME logged the domain name (prefixed by the transformer name, so it can be considered as unique) of a local Counter too, in an old version of FME.

Tnx for the feedback @Takashi Iijima​ .

That does explain my confusion that there might be a difference in implementation between a local vs a global count. So it seems there is no other way than carefully managing the count domains (where using the transformer name for uniqueness is a good tip).

 

Badge +3

Not so essential though, but I am still wondering about the parameters/options of the Count() function. At the FME Feature Function documentation page it states:

@Count([<domain>[,<startVal>[,<modulo>]]][,NO_LOG])

 

If I look at this (particularly the nested brackets), it seems that NO_LOG option can be suffixed in the Count() function, with whatever other options that are used. Furthermore it seems to indicate that the <startVal> can only be used when a <domain> is specified.

 

So this led me to believe that I could use the <domain> and <startVal> option, as well as the NO_LOG option, but not the <modulo> option, but when I try to do so, I get a translation error.

So is there any way to exclude the <modulo> option, but still use both the <startVal> and NO_LOG options?

 

So some examples:

@Count(a,1,2,NO_LOG) -> OK

@Count(a,1,NO_LOG) -> ERROR

@Count(a,1,,NO_LOG) -> ERROR

@Count(a,1,"",NO_LOG) -> ERROR

@Count(a,1) -> OK

@Count(a,NO_LOG) -> OK

 

 

 

Userlevel 2
Badge +9

II think the Counter transformer with Local Scope also uses the implementation of the @Count() function. FME just generates unique domain name implicitly for each local Counter, I guess.

Isn't it? @danminneyatsaf​ 

I remember that FME logged the domain name (prefixed by the transformer name, so it can be considered as unique) of a local Counter too, in an old version of FME.

Hi @Takashi Iijima​ 

The Counter transformer (as of Version 3) with Local Scope does not use an implementation of the @Count() function. Only the Global scope uses a domain name to track counts across instances. Hope this clears things up.

Userlevel 5
Badge +29

Not so essential though, but I am still wondering about the parameters/options of the Count() function. At the FME Feature Function documentation page it states:

@Count([<domain>[,<startVal>[,<modulo>]]][,NO_LOG])

 

If I look at this (particularly the nested brackets), it seems that NO_LOG option can be suffixed in the Count() function, with whatever other options that are used. Furthermore it seems to indicate that the <startVal> can only be used when a <domain> is specified. 

 

So this led me to believe that I could use the <domain> and <startVal> option, as well as the NO_LOG option, but not the <modulo> option, but when I try to do so, I get a translation error. 

So is there any way to exclude the <modulo> option, but still use both the <startVal> and NO_LOG options?

 

So some examples:

@Count(a,1,2,NO_LOG) -> OK

@Count(a,1,NO_LOG) -> ERROR

@Count(a,1,,NO_LOG) -> ERROR

@Count(a,1,"",NO_LOG) -> ERROR

@Count(a,1) -> OK

@Count(a,NO_LOG) -> OK

 

 

 

Thats interesting, it looks like there may be a bug with the modulo part of the count

ERROR |Count -- 3rd parameter `1' is not an integer greater than 0

It almost looks like the default when no modulo is specified is a numeral 1 as a string(?) rather than an int, hence that error. (but see below, it seems to transpose strings to ints successfully)

 

From your tests above, i'd expect the second one to pass successfully, and i would expect the next two to fail as the modulo is required (as an int) and in the first example you're passing it a NULL/NONE and the second you're passing an empty string - neither of which are an int.

 

However, if you call @Count(a,1,"1",NO_LOG) it works as expected, so internally it does transpose strings to ints. If you pass it @Count(a,1,"a",NO_LOG) it does fail

Badge +3

Thats interesting, it looks like there may be a bug with the modulo part of the count

ERROR |Count -- 3rd parameter `1' is not an integer greater than 0

It almost looks like the default when no modulo is specified is a numeral 1 as a string(?) rather than an int, hence that error. (but see below, it seems to transpose strings to ints successfully)

 

From your tests above, i'd expect the second one to pass successfully, and i would expect the next two to fail as the modulo is required (as an int) and in the first example you're passing it a NULL/NONE and the second you're passing an empty string - neither of which are an int.

 

However, if you call @Count(a,1,"1",NO_LOG) it works as expected, so internally it does transpose strings to ints. If you pass it @Count(a,1,"a",NO_LOG) it does fail

Hi @hkingsbury​ ,

 

Thanks for your reply. I also expected that the second statement, i.e. @Count(a,1,NO_LOG) would pass succesfully, and I agree that it seems like a bit of a bug with the modulo option of the @Count() function. That's why I mentioned it here (and in the screenshot of the case I created) ;)

 

I don't think that the default for the modulo is '1', but that that refers to the specified startVal value, and that for some reason when executing '@Count(a,1,NO_LOG)' internally FME picks up this startVal for the modulo value (even though I didn't want to use the modulo option).

 

See for example the following results, where '@Count(a,2,NO_LOG)' provides the error:

Count -- 3rd parameter `2' is not an integer greater than 0

image 

 

 

 

 

 

 

 

Userlevel 5
Badge +29

Thats interesting, it looks like there may be a bug with the modulo part of the count

ERROR |Count -- 3rd parameter `1' is not an integer greater than 0

It almost looks like the default when no modulo is specified is a numeral 1 as a string(?) rather than an int, hence that error. (but see below, it seems to transpose strings to ints successfully)

 

From your tests above, i'd expect the second one to pass successfully, and i would expect the next two to fail as the modulo is required (as an int) and in the first example you're passing it a NULL/NONE and the second you're passing an empty string - neither of which are an int.

 

However, if you call @Count(a,1,"1",NO_LOG) it works as expected, so internally it does transpose strings to ints. If you pass it @Count(a,1,"a",NO_LOG) it does fail

@danatsafe​ Is this a potential bug that may need looking into by the developers?

Userlevel 2
Badge +9

Thats interesting, it looks like there may be a bug with the modulo part of the count

ERROR |Count -- 3rd parameter `1' is not an integer greater than 0

It almost looks like the default when no modulo is specified is a numeral 1 as a string(?) rather than an int, hence that error. (but see below, it seems to transpose strings to ints successfully)

 

From your tests above, i'd expect the second one to pass successfully, and i would expect the next two to fail as the modulo is required (as an int) and in the first example you're passing it a NULL/NONE and the second you're passing an empty string - neither of which are an int.

 

However, if you call @Count(a,1,"1",NO_LOG) it works as expected, so internally it does transpose strings to ints. If you pass it @Count(a,1,"a",NO_LOG) it does fail

Hi all, it looks like this may be a potential bug / enhancement so I have gone ahead and filed a bug report (FMEENGINE-72524). We will notify you here if a fix is released.

 

Even if this is not identified as a bug per se, we can consider this an enhancement request. I have echoed your concerns that there should be a way to specify NO_LOG without having to specify a modulo. 

Reply