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 -------------------------------------------------------------------
