// $HeadURL$ // $Id$ // // Copyright © 2006, 2010, 2011, 2012 by the President and Fellows of Harvard College. // // Screensaver is an open-source project developed by the ICCB-L and NSRB labs // at Harvard Medical School. This software is distributed under the terms of // the GNU General Public License. package edu.harvard.med.screensaver.service.screens; import java.util.Collection; import java.util.Map; import java.util.Set; import java.util.SortedSet; import com.google.common.base.Function; import com.google.common.base.Functions; import com.google.common.collect.Iterables; import com.google.common.collect.Multimap; import com.google.common.collect.Multimaps; import com.google.common.collect.Ordering; import com.google.common.collect.Sets; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import edu.harvard.med.screensaver.db.GenericEntityDAO; import edu.harvard.med.screensaver.db.ScreenDAO; import edu.harvard.med.screensaver.model.libraries.Copy; import edu.harvard.med.screensaver.model.libraries.Library; import edu.harvard.med.screensaver.model.libraries.Plate; import edu.harvard.med.screensaver.model.screenresults.AssayPlate; import edu.harvard.med.screensaver.model.screens.Screen; public class ScreenDerivedPropertiesUpdater { private GenericEntityDAO _dao; private ScreenDAO _screenDao; /** for CGLIB2 */ protected ScreenDerivedPropertiesUpdater() { } @Autowired public ScreenDerivedPropertiesUpdater(GenericEntityDAO dao, ScreenDAO screenDao) { _dao = dao; _screenDao = screenDao; } @Transactional public Screen updateScreeningStatistics(Screen screenIn) { _dao.flush(); // ensure all of the data that were are about to query is flushed to the database Screen screen = (Screen) _dao.reloadEntity(screenIn); SortedSet<AssayPlate> assayPlatesScreened = screen.getAssayPlatesScreened(); SortedSet<AssayPlate> assayPlatesDataLoaded = screen.getAssayPlatesDataLoaded(); Set<Integer> plateNumbersScreened = Sets.newHashSet(Iterables.transform(assayPlatesScreened, AssayPlate.ToPlateNumber)); Set<Integer> plateNumbersLoaded = Sets.newHashSet(Iterables.transform(assayPlatesDataLoaded, AssayPlate.ToPlateNumber)); Function<AssayPlate,Library> AssayPlateToLibrary = Functions.compose(Copy.ToLibrary, Functions.compose(Plate.ToCopy, AssayPlate.ToPlate)); Set<Library> librariesScreened = Sets.newHashSet(Iterables.transform(assayPlatesScreened, AssayPlateToLibrary)); screen.setAssayPlatesScreenedCount(assayPlatesScreened.size()); screen.setLibraryPlatesScreenedCount(plateNumbersScreened.size()); screen.setLibraryPlatesDataLoadedCount(plateNumbersLoaded.size()); // TODO: currently, all loaded data is also already analyzed; this will change in the future; see [#1315] screen.setLibraryPlatesDataAnalyzedCount(plateNumbersLoaded.size()); screen.setLibrariesScreenedCount(librariesScreened.size()); SortedSet<Integer> maxReplicatesPerPlateNumber = findMaxReplicatesPerPlateNumber(assayPlatesScreened); screen.setMinScreenedReplicateCount(maxReplicatesPerPlateNumber.isEmpty() ? null : maxReplicatesPerPlateNumber.first()); screen.setMaxScreenedReplicateCount(maxReplicatesPerPlateNumber.isEmpty() ? null : maxReplicatesPerPlateNumber.last()); maxReplicatesPerPlateNumber = findMaxReplicatesPerPlateNumber(assayPlatesDataLoaded); screen.setMinDataLoadedReplicateCount(maxReplicatesPerPlateNumber.isEmpty() ? null : maxReplicatesPerPlateNumber.first()); screen.setMaxDataLoadedReplicateCount(maxReplicatesPerPlateNumber.isEmpty() ? null : maxReplicatesPerPlateNumber.last()); screen.setScreenedExperimentalWellCount(_screenDao.countScreenedExperimentalWells(screen, false)); screen.setUniqueScreenedExperimentalWellCount(_screenDao.countScreenedExperimentalWells(screen, true)); if (screen.getScreenResult() != null) { screen.getScreenResult().setExperimentalWellCount(_screenDao.countLoadedExperimentalWells(screen)); } return screen; } private SortedSet<Integer> findMaxReplicatesPerPlateNumber(SortedSet<AssayPlate> assayPlatesScreened) { Multimap<Integer,AssayPlate> plateNumbersToAssayPlates = Multimaps.index(assayPlatesScreened, AssayPlate.ToPlateNumber); SortedSet<Integer> maxReplicatesPerPlateNumber = Sets.newTreeSet(Iterables.transform(plateNumbersToAssayPlates.asMap().entrySet(), new Function<Map.Entry<Integer,Collection<AssayPlate>>,Integer>() { @Override public Integer apply(Map.Entry<Integer,Collection<AssayPlate>> e) { Iterable<Integer> replicateOrdinals = Iterables.transform(e.getValue(), AssayPlate.ToReplicateOrdinal); return Ordering.natural().max(replicateOrdinals) + 1; } })); return maxReplicatesPerPlateNumber; } @Transactional public void updateTotalPlatedLabCherryPickCount(Screen screen) { _dao.flush(); // ensure all of the data that were are about to query is flushed to the database screen = _dao.reloadEntity(screen); screen.setTotalPlatedLabCherryPicks(_screenDao.countTotalPlatedLabCherryPicks(screen)); } }