use of gov.nih.nci.ctd2.dashboard.model.Subject in project nci-ctd2-dashboard by CBIIT.
the class DashboardDaoImpl method createObservedSubjectInfo.
private List<SubjectItem> createObservedSubjectInfo(Integer observationId) {
Session session1 = getSession();
@SuppressWarnings("unchecked") org.hibernate.query.Query<Object[]> query1 = session1.createNativeQuery("SELECT d2.displayName AS role, observed_subject_role.displayText AS description, d1.displayName AS name, subject.id, columnName, stableURL" + " FROM observed_subject join subject on observed_subject.subject_id=subject.id" + " JOIN dashboard_entity d1 ON subject.id=d1.id" + " JOIN observed_subject_role ON observed_subject.observedSubjectRole_id = observed_subject_role.id" + " JOIN subject_role ON observed_subject_role.subjectRole_id=subject_role.id" + " JOIN dashboard_entity AS d2 ON subject_role.id=d2.id" + " where observation_id=" + observationId);
List<Object[]> subjects = query1.list();
List<SubjectItem> list = new ArrayList<SubjectItem>();
for (Object[] obj : subjects) {
String role = (String) obj[0];
String description = (String) obj[1];
String name = (String) obj[2];
Integer subjectId = (Integer) obj[3];
String columnName = (String) obj[4];
String stableURL = (String) obj[5];
@SuppressWarnings("unchecked") org.hibernate.query.Query<String> query2 = session1.createNativeQuery("SELECT displayName FROM subject_synonym_map " + " JOIN synonym ON subject_synonym_map.synonyms_id=synonym.id " + " JOIN dashboard_entity ON synonym.id = dashboard_entity.id" + " WHERE SubjectImpl_id=" + subjectId);
List<String> synonyms = query2.list();
@SuppressWarnings("unchecked") org.hibernate.query.Query<Object[]> query3 = session1.createNativeQuery("SELECT databaseId, databaseName FROM subject_xref_map" + " JOIN xref ON subject_xref_map.xrefs_id=xref.id " + " WHERE SubjectImpl_id=" + subjectId);
List<Object[]> xrefs = query3.list();
List<XRefItem> xrefItems = new ArrayList<XRefItem>();
for (Object[] x : xrefs) {
xrefItems.add(new XRefItem((String) x[1], (String) x[0]));
}
SubjectItem subjectItem = new SubjectItem(stableURL, role, description, name, synonyms.toArray(new String[0]), xrefItems.toArray(new XRefItem[0]), columnName);
list.add(subjectItem);
}
session1.close();
return list;
}
use of gov.nih.nci.ctd2.dashboard.model.Subject in project nci-ctd2-dashboard by CBIIT.
the class DashboardDaoImpl method ontologySearch.
/*
* To get observation 'search' results, i.e. the intersection concept, the
* implmentation of ontology search will be much more complex. Ideally it would
* be better to compeltely separate the observation part, but to avoid repeating
* the actual hierarchical searching, embedding observations here is the best
* choice. Although the previous implementation is better for searching
* subjects, but to cover the observation parts, we have no choice but to
* compromise the clarity here.
*
* Other points of consideration for the purpose of observation 'search': (1)
* the ontologySearch cover the original non-ontology subject results (in
* principle) (2) the subjects other than TissueSample and ECO term are neither
* affected or covered by ontology search so it is not consistent.
*/
@Override
public SearchResults ontologySearch(String queryString) {
final String[] searchTerms = parseWords(queryString);
Set<Integer> observationsIntersection = null;
Set<SubjectResult> subject_result = null;
final int termCount = searchTerms.length;
if (termCount <= 1) {
// prevent wasting time finding observations
subject_result = new HashSet<SubjectResult>(ontologySearchOneTerm(searchTerms[0].replace("\"", ""), null));
} else {
boolean first = true;
Map<SubjectResult, Integer> subjectResultMap = new HashMap<SubjectResult, Integer>();
for (String oneTerm : searchTerms) {
oneTerm = oneTerm.replace("\"", "");
log.debug("ontology search term:" + oneTerm);
Set<Integer> observations = new HashSet<Integer>();
List<SubjectResult> oneTermList = ontologySearchOneTerm(oneTerm, observations);
for (SubjectResult s : oneTermList) {
Integer matchNumber = subjectResultMap.get(s);
if (matchNumber != null) {
s.matchNumber = matchNumber + 1;
}
subjectResultMap.put(s, s.getMatchNumber());
}
if (first) {
observationsIntersection = observations;
first = false;
} else {
observationsIntersection.retainAll(observations);
}
}
subject_result = subjectResultMap.keySet();
}
SearchResults searchResults = new SearchResults();
if (subject_result.size() > maxNumberOfSearchResults) {
searchResults.oversized = subject_result.size();
searchResults.subject_result = subject_result.stream().sorted(new SearchResultComparator()).limit(maxNumberOfSearchResults).collect(Collectors.toList());
log.debug("size after limiting: " + subject_result.size());
} else {
searchResults.subject_result = new ArrayList<SubjectResult>(subject_result);
}
if (observationsIntersection != null) {
searchResults.observation_result = observationsIntersection.stream().map(id -> this.getEntityById(Observation.class, id)).collect(Collectors.toList());
log.debug("size of observation intersection: " + observationsIntersection.size());
}
return searchResults;
}
use of gov.nih.nci.ctd2.dashboard.model.Subject in project nci-ctd2-dashboard by CBIIT.
the class DashboardDaoImpl method summarize.
@Override
public void summarize() {
findEntities(Summary.class).forEach(s -> delete(s));
Map<Class<?>, String> summaryClasses = new HashMap<Class<?>, String>();
summaryClasses.put(AnimalModel.class, "Animal Models");
summaryClasses.put(CellSample.class, "Cell Lines");
summaryClasses.put(Compound.class, "Compounds");
summaryClasses.put(Gene.class, "Genes");
summaryClasses.put(ShRna.class, "shRNA");
summaryClasses.put(TissueSample.class, "Disease Contexts (Tissues)");
summaryClasses.forEach((clazz, label) -> {
@SuppressWarnings("unchecked") Summary s = summarizePerSubject((Class<? extends Subject>) clazz, label);
save(s);
});
Summary s = summarizeStories();
save(s);
Summary eco = summarizeECO();
save(eco);
Summary total = summarizeTotal();
save(total);
}
use of gov.nih.nci.ctd2.dashboard.model.Subject in project nci-ctd2-dashboard by CBIIT.
the class DashboardDaoImpl method search.
@Override
@Cacheable(value = "searchCache")
public SearchResults search(String queryString) {
queryString = queryString.trim();
final String[] searchTerms = parseWords(queryString);
log.debug("search terms: " + String.join(",", searchTerms));
Map<Subject, Integer> subjects = new HashMap<Subject, Integer>();
Map<Submission, Integer> submissions = new HashMap<Submission, Integer>();
for (String singleTerm : searchTerms) {
searchSingleTerm(singleTerm, subjects, submissions);
}
SearchResults searchResults = new SearchResults();
searchResults.submission_result = submissions.keySet().stream().map(submission -> {
ObservationTemplate template = submission.getObservationTemplate();
return new SearchResults.SubmissionResult(submission.getStableURL(), submission.getSubmissionDate(), template.getDescription(), template.getTier(), template.getSubmissionCenter().getDisplayName(), submission.getId(), findObservationsBySubmission(submission).size(), template.getIsSubmissionStory());
}).collect(Collectors.toList());
Map<String, Set<Observation>> observationMap = new HashMap<String, Set<Observation>>();
List<SubjectResult> subject_result = new ArrayList<SubjectResult>();
for (Subject subject : subjects.keySet()) {
Set<Observation> observations = new HashSet<Observation>();
Set<SubmissionCenter> submissionCenters = new HashSet<SubmissionCenter>();
Set<String> roles = new HashSet<String>();
for (ObservedSubject observedSubject : findObservedSubjectBySubject(subject)) {
Observation observation = observedSubject.getObservation();
observations.add(observation);
ObservationTemplate observationTemplate = observation.getSubmission().getObservationTemplate();
submissionCenters.add(observationTemplate.getSubmissionCenter());
roles.add(observedSubject.getObservedSubjectRole().getSubjectRole().getDisplayName());
}
SubjectResult x = new SubjectResult(subject, observations.size(), submissionCenters.size(), subjects.get(subject), roles);
Arrays.stream(searchTerms).filter(term -> matchSubject(term, subject)).forEach(term -> {
Set<Observation> obset = observationMap.get(term);
if (obset == null) {
obset = new HashSet<Observation>();
}
obset.addAll(observations);
observationMap.put(term, obset);
});
subject_result.add(x);
}
/* search ECO terms */
List<ECOTerm> ecoterms = findECOTerms(queryString);
for (ECOTerm ecoterm : ecoterms) {
List<Integer> observationIds = observationIdsForEcoCode(ecoterm.getCode());
int observationNumber = observationIds.size();
if (observationNumber == 0)
continue;
SubjectResult entity = new SubjectResult(ecoterm, observationNumber, centerCount(ecoterm.getCode()), null, // no matchNumber, no roles
null);
subject_result.add(entity);
Set<Observation> observations = new HashSet<Observation>();
observationIds.forEach(obid -> observations.add(getEntityById(Observation.class, obid)));
Arrays.stream(searchTerms).filter(term -> ecoterm.containsTerm(term)).forEach(term -> {
Set<Observation> obset = observationMap.get(term);
if (obset == null) {
obset = new HashSet<Observation>();
}
obset.addAll(observations);
observationMap.put(term, obset);
});
}
/*
* Limit the size. This should be done more efficiently during the process of
* builing up of the list.
* Because the limit needs to be based on 'match number' ranking, which depends
* on all terms, an efficient algorithm is not obvious.
* Unfortunately, we also have to do this after processing all results because
* we need (in fact more often) observation numbers as well in ranking. TODO
*/
if (subject_result.size() > maxNumberOfSearchResults) {
searchResults.oversized = subject_result.size();
subject_result = subject_result.stream().sorted(new SearchResultComparator()).limit(maxNumberOfSearchResults).collect(Collectors.toList());
log.debug("size after limiting: " + subject_result.size());
}
searchResults.subject_result = subject_result;
if (searchTerms.length <= 1) {
return searchResults;
}
// add intersection of observations
Set<Observation> set0 = observationMap.get(searchTerms[0]);
if (set0 == null) {
log.debug("no observation for " + searchTerms[0]);
return searchResults;
}
log.debug("set0 size=" + set0.size());
for (int i = 1; i < searchTerms.length; i++) {
Set<Observation> obset = observationMap.get(searchTerms[i]);
if (obset == null) {
log.debug("... no observation for " + searchTerms[i]);
return searchResults;
}
log.debug("set " + i + " size=" + obset.size());
set0.retainAll(obset);
}
// set0 is now the intersection
if (set0.size() == 0) {
log.debug("no intersection of observations");
}
if (set0.size() > maxNumberOfSearchResults) {
searchResults.oversized_observations = set0.size();
// no particular ranking is enforced when limiting
set0 = set0.stream().limit(maxNumberOfSearchResults).collect(Collectors.toSet());
log.debug("observation results count after limiting: " + set0.size());
}
searchResults.observation_result = new ArrayList<Observation>(set0);
return searchResults;
}
use of gov.nih.nci.ctd2.dashboard.model.Subject in project nci-ctd2-dashboard by CBIIT.
the class DashboardDaoImpl method searchSingleTerm.
private void searchSingleTerm(final String singleTerm, final Map<Subject, Integer> subjects, final Map<Submission, Integer> submissions) {
FullTextSession fullTextSession = Search.getFullTextSession(getSession());
MultiFieldQueryParser multiFieldQueryParser = new MultiFieldQueryParser(defaultSearchFields, new KeywordAnalyzer());
Query luceneQuery = null;
try {
luceneQuery = multiFieldQueryParser.parse(singleTerm);
log.debug(luceneQuery);
} catch (ParseException e) {
e.printStackTrace();
return;
}
FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, searchableClasses);
fullTextQuery.setReadOnly(true);
List<?> list = fullTextQuery.list();
fullTextSession.close();
Integer numberOfSearchResults = getMaxNumberOfSearchResults();
if (numberOfSearchResults > 0 && list.size() > numberOfSearchResults) {
// if lte 0, the maximum number is ignored
log.warn("search result number " + list.size() + " is larger than the maximum expected, " + numberOfSearchResults);
}
for (Object o : list) {
if (o instanceof ObservationTemplate) {
List<Submission> submissionList = queryWithClass("select o from SubmissionImpl as o where o.observationTemplate = :ot", "ot", (ObservationTemplate) o);
for (Submission submission : submissionList) {
if (submissions.containsKey(submission)) {
submissions.put(submission, submissions.get(submission) + 1);
} else {
submissions.put(submission, 1);
}
}
} else if (o instanceof Subject) {
Subject s = (Subject) o;
if (subjects.containsKey(s)) {
subjects.put(s, subjects.get(s) + 1);
} else {
subjects.put(s, 1);
}
} else {
log.warn("unexpected type returned by searching: " + o.getClass().getName());
}
}
}
Aggregations