Hello Richard!

Besides view selection, your suggestion works. The outer analysis engine works 
on the view given by AggregateBuilder.add(analysisEngineDescription, 
CAS.NAME_DEFAULT_SOFA, viewName) as it should. The inner analysis engine is 
called with analysisEngine.process(cas) from the outer ae's process(CAS cas) 
method, where cas is the specified view. But the CAS of the inner ae's process 
method is _initialView. The inner ae's view must be explicitly set.

I've encountered these kinds of difficulties before. All these stuff with views 
just beeing CASes of theire own as suggested by the documentation is just not 
true. I think that this is a principle UIMA CAS design issue. It is not 
possible to extract a view and save it as a separate CAS, e. g. for getting rid 
of all the annotations of intermediate pipeline processes which I do not want 
to be in the final result, or persisting just one view as a lean CAS of its 
own. 

Regards,

Armin

 

-----Ursprüngliche Nachricht-----
Von: [email protected] [mailto:[email protected]] 
Gesendet: Freitag, 8. Juni 2012 10:50
An: [email protected]
Betreff: AW: Calling an annotator from another annotator

Hi Richard,

That is exactly what I wanted to achieve. I got your point. I will try your 
suggestion and report back.

Thank you very much,

Armin

 

-----Ursprüngliche Nachricht-----
Von: Richard Eckart de Castilho [mailto:[email protected]]
Gesendet: Freitag, 8. Juni 2012 09:43
An: <[email protected]>
Betreff: Re: Calling an annotator from another annotator

Am 08.06.2012 um 08:56 schrieb <[email protected]>:

> Hi,
> 
> I like to call an annotator from another annotator as it uses annotatations 
> for which annotators already exist. Calling is not a problem, but setting the 
> parameter is. Can this be done at all? How? Using uimaFIT the parameter 
> values are injected using the AnalysisEngineFactory.createPrimitive(). Doing 
> so the parameters are set in the UIMA context of the outer annotator. The 
> inner annotator has its own UIMA context, does it? How can the outer 
> annotator's context be accessed while creating the inner annotator? At first 
> I thought that this could be done the same way as Philip Ogren has done with 
> XWriterFileNamer and XWriter. You just set the parameters for your 
> XWriterFileNamer implmentation in the XWriter context. But this seems to be a 
> little different as I don't instantiate a CasAnnototar_ImplBase object but 
> create an annotator description which is than use to instantiate an 
> AnalysisEngine object by AnalysisEngineFactory in uimaFit or UIMAFramework in 
> UIMA itself. Do you have any suggestions? Or is it just me, not getting to 
> understand the UIMA way again?

If I understand you correctly, you want to create an OuterAE to which you pass 
parameters. The OuterAE should use some of these parameters itself and forward 
the rest to an InnerAE that it creates. To accomplish that, you would like the 
InnerAE to access the same UIMAContext object as the OuterAE.

I think it's not possible or wise to have two AEs access the same UIMAContext 
object. But it is possible to forward parameters - NOT recommened for various 
reasons (read on). I tried to hack something together here that should work 
(untested):

        public static class OuterAnnotator extends CasAnnotator_ImplBase
        {
                @Override
                public void initialize(UimaContext context) throws 
ResourceInitializationException {
                        super.initialize(context);
                        
                        // Copy all parameters into an array which can be 
passed as the variadic parameter list
                        // to createPrimitiveDesription
                        List<Object> parameters = new ArrayList<Object>();
                        for (String name : context.getConfigParameterNames()) {
                                parameters.add(name);
                                
parameters.add(context.getConfigParameterValue(name));
                        }
                        
                        // Create a new AE which has access to all the 
parameters set on the outer AE
                        AnalysisEngineDescription aed = 
createPrimitiveDescription(InnerAnnotator.class, 
                                        parameters.toArray(new 
Object[parameters.size()]));
                }
                
                @Override
                public void process(CAS aCAS) throws 
AnalysisEngineProcessException {
                        //...
                }
        }

I would like to point out though, that you are going to run into problems with 
this approach, because in general there is no way to properly separate 
parameters that go to the inner and to the outer AE. Well, you could introduce 
a prefix and only parameters having that prefix are passed to the inner AE, but 
what if your InnerAE has another InnerInnerAE...? 

The ConceptMapperAnnotator in the UIMA sandbox accepts the path of an 
AnalysisEngineDescriptor for a tokenizer as a parameter and then instantiates 
this, but it doesn't set any additional parameters. So when one sets up the 
pipeline, one can create a AnalysisEngineDescription for the tokenizer, 
serialize it as XML to a temporary file using the toXml() method and then pass 
that file to the ConceptMapperAnnotator. In that way, the 
ConceptMapperAnnotator does not have to know anything about how to pass on 
parameters to the tokenizer and avoids any potential parameter name clashes.

At the moment, uimaFIT doesn't have explicit support for injecting 
AnalysisEngineDescriptors directly as parameters. One could imagine something 
like this:

        createPrimitiveDescriptor(OuterAE.class,
                OuterAE.PARAM_NAME, "outer",
                OuterAE.PARAM_INNER_AE, 
createPrimitiveDescriptor(InnerAE.class, 
                        PARAM_NAME, "inner");

We do something like that already for external resources. I think it would make 
sense to add it for analysis engines as well. In that example above, you can 
also see the that there could easily be a parameter name clash between the 
parameters of the inner and outer AE. Philip liked to work around that by 
prepending the full class name to each parameter name, but that approach fails 
if OuterAE and InnerAE are actually two components of the same class with 
different configurations, e.g. some generic filtering AE.

As long as uimaFIT doesn't support engine injection, I'd suggest you work with 
a temporary descriptor file that you generate with uimaFIT and pass to your 
OuterAE. 

- use AnalysisEngineFactory.createPrimitiveDescription(...) to create the 
descriptor for your inner AE
- call 
AnalysisEngineDescription.resolveImports(UIMAFramework.newDefaultResourceManager())
 once on the descriptor to resolve it
- persist the generated descriptor to a temporary file using 
AnalysisEngineDescription.toXML()
- pass the path to that file as InnerAEDescriptorPath to OuterAE

File.createTempFile() and File.deleteOnExit() are very helpful here.

-- Richard

--
-------------------------------------------------------------------
Richard Eckart de Castilho
Technical Lead
Ubiquitous Knowledge Processing Lab (UKP-TUD) 
FB 20 Computer Science Department      
Technische Universität Darmstadt
Hochschulstr. 10, D-64289 Darmstadt, Germany phone [+49] (0)6151 16-7477, fax 
-5455, room S2/02/B117 [email protected]
www.ukp.tu-darmstadt.de
Web Research at TU Darmstadt (WeRC) www.werc.tu-darmstadt.de
------------------------------------------------------------------- 








Reply via email to