uima-user mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From <Armin.Weg...@bka.bund.de>
Subject AW: Calling an annotator from another annotator
Date Fri, 08 Jun 2012 13:41:15 GMT
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: Armin.Wegner@bka.bund.de [mailto:Armin.Wegner@bka.bund.de] 
Gesendet: Freitag, 8. Juni 2012 10:50
An: user@uima.apache.org
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:eckart@ukp.informatik.tu-darmstadt.de]
Gesendet: Freitag, 8. Juni 2012 09:43
An: <user@uima.apache.org>
Betreff: Re: Calling an annotator from another annotator

Am 08.06.2012 um 08:56 schrieb <Armin.Wegner@bka.bund.de>:

> 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 eckart@ukp.informatik.tu-darmstadt.de
www.ukp.tu-darmstadt.de
Web Research at TU Darmstadt (WeRC) www.werc.tu-darmstadt.de
------------------------------------------------------------------- 









Mime
View raw message