Change feature name in gate document with JAPE or Groovy - gate

I have a GATE document like that:
I need to change the name of a feature in the annotation. Here i need to change typeby category
Is it possible to do that with a JAPE rule or Groovy script ?

Yes, either. A JAPE rule is probably the simplest:
Phase: RenameFeature
Input: Mention
Options: control = all
Rule: Rename
({Mention}):mention
-->
:mention {
for(Annotation a : mentionAnnots) {
a.getFeatures().put("category", a.getFeatures().remove("type"));
// note Map.remove returns the value we just removed
}
}
Inside a RHS Java block labelled with :label the variable labelAnnots is an AnnotationSet containing the annotations that were matched by the label on the LHS. In this case there's only one of them but the for loop is still the most convenient way to access the individual Annotation from the set.

Related

Google Healthcare API Nodejs - Filter Appointment using start and end date

I cannot filter an Appointment from start and end date using the google healthcare API.
I am trying to recreate the query below:
Appointment?date=ge2023-02-03T04:00:00.000Z&date=le2023-02-05T04:00:00.000Z
This is my javascript code using the library:
const parent = `projects/${projectId}/locations/${cloudRegion}/datasets/${datasetId}/fhirStores/${fhirStoreId}`;
const params = {
parent,
resourceType,
date: `le${end}`,
date: `ge${start}`,
};
const resource = await healthcare.projects.locations.datasets.fhirStores.fhir.search(params);
date: `ge${start}` is ignored because you cannot duplicate the same key.
Is there any other way I can achieve this.
Thanks!
I was able to make it work.
const params = {
parent,
resourceType,
"date:end": `le${end}`,
"date:start": `ge${start}`,
};
Just change "date" to "date:start" and "date:end"
I see that you were able to make this work, but there's a better way. What you essentially want to do here is specify multiple date parameters. The solution that you've come up with does this, but by using non-existent modifiers, :start and :end. By default the FHIR store drop modifiers it does not recognize, so your query as the same as date=le...&date=ge..., which is the end result you want. But if you were using the header Prefer: handling=strict, or set defaultSearchHandlingStrict in your FHIR store config, you'll get an error back from this search.
So what's the correct thing to do? If you want to specify multiple query parameters to be ANDed together (with the Node API), all you need to do is specify an array. In the future, if you wanted to OR them together you would use a single parameter with a comma separated list. So your code becomes
const params = {
parent,
resourceType,
date: [`le${end}`, `ge${start}`],
};
As a side note, the behaviour of search with the resourceType parameter is undefined, the method you want is searchType. These look the same due to the way the code is generated, but they function slightly differently.

Regex for finding the name of a method containing a string

I've got a Node module file containing about 100 exported methods, which looks something like this:
exports.methodOne = async user_id => {
// other method contents
};
exports.methodTwo = async user_id => {
// other method contents
fooMethod();
};
exports.methodThree = async user_id => {
// other method contents
fooMethod();
};
Goal: What I'd like to do is figure out how to grab the name of any method which contains a call to fooMethod, and return the correct method names: methodTwo and methodThree. I wrote a regex which gets kinda close:
exports\.(\w+).*(\n.*?){1,}fooMethod
Problem: using my example code from above, though, it would effectively match methodOne and methodThree because it finds the first instance of export and then the first instance of fooMethod and goes on from there. Here's a regex101 example.
I suspect I could make use of lookaheads or lookbehinds, but I have little experience with those parts of regex, so any guidance would be much appreciated!
Edit: Turns out regex is poorly-suited for this type of task. #ctcherry advised using a parser, and using that as a springboard, I was able to learn about Abstract Syntax Trees (ASTs) and the recast tool which lets you traverse the tree after using various tools (acorn and others) to parse your code into tree form.
With these tools in hand, I successfully built a script to parse and traverse my node app's files, and was able to find all methods containing fooMethod as intended.
Regex isn't the best tool to tackle all the parts of this problem, ideally we could rely on something higher level, a parser.
One way to do this is to let the javascript parse itself during load and execution. If your node module doesn't include anything that would execute on its own (or at least anything that would conflict with the below), you can put this at the bottom of your module, and then run the module with node mod.js.
console.log(Object.keys(exports).filter(fn => exports[fn].toString().includes("fooMethod(")));
(In the comments below it is revealed that the above isn't possible.)
Another option would be to use a library like https://github.com/acornjs/acorn (there are other options) to write some other javascript that parses your original target javascript, then you would have a tree structure you could use to perform your matching and eventually return the function names you are after. I'm not an expert in that library so unfortunately I don't have sample code for you.
This regex matches (only) the method names that contain a call to fooMethod();
(?<=exports\.)\w+(?=[^{]+\{[^}]+fooMethod\(\)[^}]+};)
See live demo.
Assuming that all methods have their body enclosed within { and }, I would make an approach to get to the final regex like this:
First, find a regex to get the individual methods. This can be done using this regex:
exports\.(\w+)(\s|.)*?\{(\s|.)*?\}
Next, we are interested in those methods that have fooMethod in them before they close. So, look for } or fooMethod.*}, in that order. So, let us name the group searching for fooMethod as FOO and the name of the method calling it as METH. When we iterate the matches, if group FOO is present in a match, we will use the corresponding METH group, else we will reject it.
exports\.(?<METH>\w+)(\s|.)*?\{(\s|.)*?(\}|(?<FOO>fooMethod)(\s|.)*?\})
Explanation:
exports\.(?<METH>\w+): Till the method name (you have already covered this)
(\s|.)*?\{(\s|.)*?: Some code before { and after, non-greedy so that the subsequent group is given preference
(\}|(?<FOO>fooMethod)(\s|.)*?\}): This has 2 parts:
\}: Match the method close delimiter, OR
(?<FOO>fooMethod)(\s|.)*?\}): The call to fooMethod followed by optional code and method close delimiter.
Here's a JavaScript code that demostrates this:
let p = /exports\.(?<METH>\w+)(\s|.)*?\{(\s|.)*?(\}|(?<FOO>fooMethod)(\s|.)*?\})/g
let input = `exports.methodOne = async user_id => {
// other method contents
};
exports.methodTwo = async user_id => {
// other method contents
fooMethod();
};
exports.methodThree = async user_id => {
// other method contents
fooMethod();
};';`
let match = p.exec( input );
while( match !== null) {
if( match.groups.FOO !== undefined ) console.log( match.groups.METH );
match = p.exec( input )
}

Regular expression logic

I'm developing a web application using Angular 6. I have a question:
I'm creating a custom input component (for text input) such as:
#Component({
selector: 'input-text',
templateUrl: './input-text.component.html'
]
})
export class InputTextComponent {
#Input() pattern?: string;
}
I would like a user can insert a regular expression for the validation of the input field, in this way:
<input-text pattern="^[a-z0-9_-]{8,15}$"></input-text>
The template of my component is defined like this:
<input type="text" [attr.pattern]="pattern"/>
Unfortunately I know absolutely nothing about regular expressions.
I would like to do two things:
1 - Create a method that checks the validity of the regular expression and changes the visual style.
2 - Make sure that if the input (with a pattern field) is inserted into a form, the attribute form.valid remains false until the expression is valid.
Thanks for your help!
Check regex validity
You can simply catch exceptions thrown by the RegExp constructor when instanciating it.
try {
const regex = new RegExp(pattern);
} catch (error) {
// If it goes here, then the regex model is not correct
console.error(error.message)
}
Change the visual style
You can simply use the ngClass attribute to change your input style.
If you enter the catch statement, set a style variable to change the class like so
private hasBadInput: boolean;
// [...]
catch (error) {
hasBadInput= true;
}
Then apply a specific class in that case:
<input-text [ngClass]="{'yourErrorClass': hasBadInput}"><input-text>
Form validity
You did well using [attr.pattern], the form should automatically consider the entered pattern. You should try your form with a hard written regex before, and then use the input one.
Follow this official guideline to create Angular 2+ forms.

Annotating a document with JAPE

I have been searching for a solution to this for weeks, I have some documents(about 95) that I am trying to classify using GATE. I have put them in one corpus I called training_corpus, however, after ANNIE has annotated the corpus, I have to go back into each file, select all token in the document, and create an annotation called Mention, with feature type and value the class for the document. for example:
type Start End id Features
Mention 0 70000 2588 {type=neg}
Is there anyway to automatically do this with JAPE? Basically, I want to select all tokens and create a new annotation with feature(type=class). Also, the class is appended to the document. Since there are many documents, can JAPE extract the class from the document name and set it to the value of Mentions feature. Example document name is neg_data1.txt, so the annotation will be Mention.type = neg?
Any help will be greatly appreciated. Thanks
I think you answered to your question by yourself.If the class assignment based on just a token present in text - why not simply process text outside of GATE?
For example to create an xml file like:
text and then use it in training process.
Also you can create a simple JAPE rule which will:
a) will take a text within document boundaries (see gate.Utils.length methods AFAIR)
b) based on presence of your token will create a new Annotation instance with features necessary.
an abstract example:
Phase: Instance
Input: Token
Options: control = once
Rule:Instance
(
{Token}
):instance
-->
{
AnnotationSet instances = outputAS.get("INSTANCE_ANNOTATION");
FeatureMap featureMap = Factory.newFeatureMap();
if (instances!=null&&!instances.isEmpty()){
featureMap.put("features when annotation presented in doc");
}else{
featureMap.put("features when annotation not in doc");
}
outputAS.add(new Long(0), new Long(documentLength), "Mention", featureMap);
}

Auto quote reserved words with Doctrine 2

Is there a way to auto quote reserved words with Doctrine 2 when using $entityManager->find('entity', id) ?
When using the query builder this can be done but there should be a global configuration setting that does this? I don't want to have to specify it in the annotations for the reserved words.
This was an issue I raised a while back with the Doctrine team.
https://github.com/doctrine/doctrine2/issues/2409
The ticket was closed with the comment:
You have to manually escape characters with #Column(name="`integer`")
So I guess you'd need to deal with any reserved keywords in your annotations
4.6. Quoting Reserved Words
Sometimes it is necessary to quote a column or table name because of reserved word conflicts. Doctrine does not quote identifiers automatically, because it leads to more problems than it would solve. Quoting tables and column names needs to be done explicitly using ticks in the definition.
<?php
/** #Column(name="`number`", type="integer") */
private $number;
Doctrine will then quote this column name in all SQL statements according to the used database platform.
Identifier Quoting does not work for join column names or discriminator column names unless you are using a custom QuoteStrategy.
For more control over column quoting the Doctrine\ORM\Mapping\QuoteStrategy interface was introduced in 2.3. It is invoked for every column, table, alias and other SQL names. You can implement the QuoteStrategy and set it by calling Doctrine\ORM\Configuration#setQuoteStrategy().
The ANSI Quote Strategy was added, which assumes quoting is not necessary for any SQL name. You can use it with the following code:
<?php
use Doctrine\ORM\Mapping\AnsiQuoteStrategy;
$configuration->setQuoteStrategy(new AnsiQuoteStrategy());
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/basic-mapping.html#quoting-reserved-words
It's not implemented by Doctrine just because it's too platform-depending.
All you need, is implement own QuoteStrategy.
For example, for symfony project:
Copy-paste vendor AnsiQuoteStrategy class, rename it and make some quoting:
AppBundle/ORM/QuoteStrategy.php
namespace AppBundle\ORM;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\ORM\Mapping as M;
class QuoteStrategy implements M\QuoteStrategy
{
private function quote($token, AbstractPlatform $platform)
{
// implement your quote strategy
switch ($platform->getName()) {
case 'mysql':
default:
return '`' . $token . '`';
}
}
// add quoting to appropriate methods
public function getColumnName($fieldName, M\ClassMetadata $class, AbstractPlatform $platform)
{
return $this->quote($class->fieldMappings[$fieldName]['columnName'], $platform);
}
// ... Rest methods
}
Then, register your quote strategy as a service:
src/AppBundle/Resources/config/services.yml
app.orm.quote_strategy:
class: AppBundle\ORM\QuoteStrategy
public: false
Then, use it for your entitymanager configuration:
app/config/config.yml
orm:
entity_managers:
default:
quote_strategy: app.orm.quote_strategy
That is all :)
Per the statement made by #tim-lytle, I have re-raised the issue. This really should be included with Doctrine ORM's scope of safety.
https://github.com/doctrine/doctrine2/issues/5874