// For each IdentifiedAnnotations, if it is of one of the right types, copy to the appropriate new subtype
List<Annotation> annotationsToRemoveFromCas = new ArrayList<Annotation>();
try {
while (identifiedAnnotationsIter.hasNext()) {
IdentifiedAnnotation original = (IdentifiedAnnotation)identifiedAnnotationsIter.next();
IdentifiedAnnotation mention = null;
// for 3.0 and earlier, needed to map mentions to the more specific types. in post-3.0, already creating proper type
// for things other than medications. Drug NER was creating MedicationEventMentions still for a while (in trunk)
int t = original.getTypeID();
if (t==CONST.NE_TYPE_ID_ANATOMICAL_SITE || t==CONST.NE_TYPE_ID_DISORDER || t==CONST.NE_TYPE_ID_DISORDER
|| t==CONST.NE_TYPE_ID_FINDING || t==CONST.NE_TYPE_ID_PROCEDURE) {
mapToMentions.put(original, original); // with 3.1 don't need to map to proper mention type, already creating as proper type
} else if (t==CONST.NE_TYPE_ID_DRUG) {
// Drug NER (ctakes-drug-ner) was creating MedicationEventMention,
// if found, create MedicationMention with its attributes based on the MedicationEventMention attributes
if (original instanceof MedicationEventMention) {
mention = new MedicationMention(jcas);
mapToMentions.put(original, mention);
setAttributesFromOriginal(mention, original);
annotationsToRemoveFromCas.add(original);
}
} else {
// Some other type of IdentifiedAnnotation such as TimeMention, Modifier, DateMention, RomanNumeralAnnotation, etc
// For each those we do nothing in this annotator.
}
}
} catch (CASException e) {
throw new AnalysisEngineProcessException(e);
}
// Fill in template slots from relations.
//FSIndex<FeatureStructure> relationArgs = jcas.getFSIndexRepository().getIndex("_org.apache.ctakes.typesystem.type.relation.RelationArgument_GeneratedIndex");
//FSIndex<FeatureStructure> binaryTextRelations = jcas.getFSIndexRepository().getIndex("_org.apache.ctakes.typesystem.type.relation.BinaryTextRelation_GeneratedIndex");
FSIndex<FeatureStructure> locationOfTextRelations = jcas.getFSIndexRepository().getIndex("_org.apache.ctakes.typesystem.type.relation.LocationOfTextRelation_GeneratedIndex");
FSIndex<FeatureStructure> degreeOfTextRelations = jcas.getFSIndexRepository().getIndex("_org.apache.ctakes.typesystem.type.relation.DegreeOfTextRelation_GeneratedIndex");
int i = 0;
if (locationOfTextRelations != null) {
for (FeatureStructure binaryTextRelationFS: locationOfTextRelations) {
i++;
//logger.info("binaryTextRelationFS = " + binaryTextRelationFS);
BinaryTextRelation binaryTextRelation = (BinaryTextRelation) binaryTextRelationFS;
LocationOfTextRelation locationOfTextRelation = null;
if (binaryTextRelation instanceof LocationOfTextRelation) {
locationOfTextRelation = (LocationOfTextRelation) binaryTextRelationFS;
}
RelationArgument arg1 = binaryTextRelation.getArg1(); // an EntityMention OR location
RelationArgument arg2 = binaryTextRelation.getArg2(); // a Modifier OR what is located at location
String relation = binaryTextRelation.getCategory(); // "degree_of", "location_of"
if (relation.equals("degree_of")) {
// do nothing here, this loop is for dealing with location_of
// degree_of has its own loop.
} else if (relation.equals("location_of")) {
IdentifiedAnnotation arg1Arg = (IdentifiedAnnotation) arg1.getArgument();
IdentifiedAnnotation ia = mapToMentions.get(arg1Arg);
if (ia instanceof EntityMention) {
// Note you apparently can have an AnatomicalSiteMention be the location_of an AnatomicalSiteMention
// from running rec041, end up with things like "Left lower extremity" location_of "common femoral vein"
// and "left renal vein" in relation location_of to anatomical site mention "renal vein"
// and "vein" in relation location_of to anatomical site mention "renal vein"
EntityMention entityMention = (EntityMention) ia;
IdentifiedAnnotation location = (IdentifiedAnnotation) arg2.getArgument();
IdentifiedAnnotation loc = (IdentifiedAnnotation)mapToMentions.get(location);
if (loc instanceof AnatomicalSiteMention) {
AnatomicalSiteMention asm = (AnatomicalSiteMention) loc;
//asm.setBodyLocation(binaryTextRelation); // uncomment iff AnatomicalSiteMention ends up with a bodyLocation attribute
} else {
logger.error("Need to implement cases for handling EntityMention " + entityMention + " within relation: " + relation);
logger.error(" loc " + loc + " in relation " + relation + " with/to " + entityMention);
logger.error(" Using covered text: loc " + loc.getCoveredText() + " in relation " + relation + " with/to " + entityMention.getCoveredText());
}
} else {
EventMention eventMention = (EventMention) ia;
if (eventMention instanceof DiseaseDisorderMention) { //(eventMention.getTypeID()==CONST.NE_TYPE_ID_DISORDER) {
DiseaseDisorderMention ddm = (DiseaseDisorderMention) eventMention;
ddm.setBodyLocation(locationOfTextRelation);
} else if (eventMention instanceof ProcedureMention) { //(eventMention.getTypeID()==CONST.NE_TYPE_ID_PROCEDURE) {
ProcedureMention pm = (ProcedureMention) eventMention;
pm.setBodyLocation(locationOfTextRelation);
} else if (eventMention instanceof SignSymptomMention) { //(eventMention.getTypeID()==CONST.NE_TYPE_ID_FINDING) {
SignSymptomMention ssm = (SignSymptomMention) eventMention;
ssm.setBodyLocation(locationOfTextRelation);
} else {
logger.error("Need to implement more cases for handling EventMention " + eventMention + " within relation: " + relation);
}
}
} else {
logger.error("Need to implement more cases for relation: " + relation);
}
}
}
if (degreeOfTextRelations != null) {
for (FeatureStructure binaryTextRelationFS: degreeOfTextRelations) {
i++;
//logger.info("binaryTextRelationFS = " + binaryTextRelationFS);
BinaryTextRelation binaryTextRelation = (BinaryTextRelation) binaryTextRelationFS;
DegreeOfTextRelation degreeOfTextRelation = null;
if (binaryTextRelation instanceof DegreeOfTextRelation) {
degreeOfTextRelation = (DegreeOfTextRelation) binaryTextRelationFS;
}
RelationArgument arg1 = binaryTextRelation.getArg1(); // an EntityMention OR location
RelationArgument arg2 = binaryTextRelation.getArg2(); // a Modifier OR what is located at location
String relation = binaryTextRelation.getCategory(); // "degree_of", "location_of"
if (relation.equals("degree_of")) {
Modifier severity = (Modifier) arg2.getArgument();
// degree_of is aka severity, which applies to SignSymptomMention/SignSymptom and DiseaseDisorder
// find Mention associated with arg1
IdentifiedAnnotation arg1Arg = (IdentifiedAnnotation) arg1.getArgument();
// set severity within the Mention to be arg2 (the Modifier)
// Note at this point mapToMentions.get(entityMention) might be an entityMention instead of an EventMention
// for example rec041 in the seed set resulted in
// ClassCastException: org.apache.ctakes.typesystem.type.textsem.AnatomicalSiteMention
// cannot be cast to org.apache.ctakes.typesystem.type.textsem.EventMention
IdentifiedAnnotation ia = mapToMentions.get(arg1Arg);
if (ia instanceof EntityMention) {
EntityMention entityMention = (EntityMention) ia;
logger.error("Need to implement cases for handling EntityMention " + entityMention + " within relation: " + relation);
logger.error(" severity " + severity + " in relation " + relation + " with/to " + entityMention);
logger.error(" Using covered text: severity " + severity.getCoveredText() + " in relation " + relation + " with/to " + entityMention.getCoveredText());