All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.micromanager.acqj.util.AcquisitionEventIterator Maven / Gradle / Ivy

There is a newer version: 0.38.1
Show newest version
package org.micromanager.acqj.util;

import org.micromanager.acqj.main.AcquisitionEvent;
import java.util.Iterator;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Stream;

/**
 * Takes a list of iterators representing levels of a tree, where each level
 * is an axis (e.g. channels, z, time, position) and provides a lazy
 * iterator over the leaves of the tree. See AcquisitionEventModules
 *
 * @author henrypinkard
 */
public class AcquisitionEventIterator implements Iterator {

   private List>> functionList_;
   private IteratorTreeNode currentLeaf_;
   private boolean eventsExhausted_ = false;
   private Function eventMonitorFunction_;

   public AcquisitionEventIterator(AcquisitionEvent root, List>> functionList,
           Function eventMonitorFunction) {
      eventMonitorFunction_ = eventMonitorFunction;
      functionList_ = functionList;
      currentLeaf_ = new IteratorTreeNode(null, Stream.of(root).iterator(), functionList.get(0));
      descendNewBranch();
   }
   
   public AcquisitionEventIterator(AcquisitionEvent root, List>> functionList) {
      functionList_ = functionList;
      currentLeaf_ = new IteratorTreeNode(null, Stream.of(root).iterator(), functionList.get(0));
      descendNewBranch();
   }

   @Override
   public boolean hasNext() {
      return !eventsExhausted_;
   }

   @Override
   public AcquisitionEvent next() {
      AcquisitionEvent next = currentLeaf_.iterator.next();
      //Move to new branch or determine that all branches are exhausted
      //May need to try ascent and descent multiple times in case a terminal iterator produces no events?
      while (!currentLeaf_.iterator.hasNext()) {
         //ascend to node where next valid branch can be found
         while (!currentLeaf_.iterator.hasNext()) {
            currentLeaf_ = currentLeaf_.parent;
            if (currentLeaf_ == null) {
               eventsExhausted_ = true;
//               System.out.println(next);
               if (eventMonitorFunction_ == null) {
                  return next;
               }
               return eventMonitorFunction_.apply(next);
            }
         }
         descendNewBranch();
      }
//      System.out.println(next);
      if (eventMonitorFunction_ == null) {
         return next;
      }
      return eventMonitorFunction_.apply(next);
   }

   private void descendNewBranch() {
      while (currentLeaf_.branchIteratorFunction_ != null) { //the terminal node will not have a function for producing new branches
         AcquisitionEvent newBranch = currentLeaf_.iterator.next();
         Iterator childIterator = currentLeaf_.branchIteratorFunction_.apply(newBranch);
         int depth = functionList_.indexOf(currentLeaf_.branchIteratorFunction_);
         currentLeaf_ = new IteratorTreeNode(currentLeaf_, childIterator,
                 depth == functionList_.size() - 1 ? null : functionList_.get(depth + 1));
      }
   }

   class IteratorTreeNode {
      //ree where each node is an iterator
      //Only stores links going up the tree, if you lose references to lower down they tree they get GCed

      IteratorTreeNode parent;
      Iterator iterator;
      Function> branchIteratorFunction_;

      public IteratorTreeNode(IteratorTreeNode p, Iterator s, Function> f) {
         parent = p;
         iterator = s;
         branchIteratorFunction_ = f;
      }

   }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy