<commit_before>package ch.unizh.ini.jaer.projects.rbodo.opticalflow;

import java.util.Iterator;
import net.sf.jaer.Description;
import net.sf.jaer.DevelopmentStatus;
import net.sf.jaer.chip.AEChip;
import net.sf.jaer.event.ApsDvsEvent;
import net.sf.jaer.event.ApsDvsEventPacket;
import net.sf.jaer.event.orientation.ApsDvsMotionOrientationEvent;
import net.sf.jaer.event.orientation.ApsDvsOrientationEvent;
import net.sf.jaer.event.EventPacket;
import net.sf.jaer.event.orientation.OrientationEventInterface;
import net.sf.jaer.event.PolarityEvent;
import net.sf.jaer.event.orientation.DvsMotionOrientationEvent;
import static net.sf.jaer.eventprocessing.EventFilter.log;
import net.sf.jaer.eventprocessing.label.AbstractOrientationFilter;
import net.sf.jaer.eventprocessing.label.SimpleOrientationFilter;

/**
 * Outputs local motion events derived from time of flight of orientation events
 * from DVS sensors. Output cells type has values 0-7, 0 being upward motion,
 * increasing by 45 deg CCW to 7 being motion up and to right.
 * <p>
 * This class was originally DirectionSelectiveFilter (ca 2007 and later
 * DvsDirectionSelectiveFilter (ca 2014) in the package
 * net.sf.jaer.eventprocessing.label. These original classes have been deleted
 * and replaced by this class. The original source code is available by version
 * control reversion of the project.
 *
 * @author tobi
 */
@Description("Local motion optical flow by time-of-travel of orientation events for APSDVS (DAVIS) sensor")
@DevelopmentStatus(DevelopmentStatus.Status.Experimental)
public class DirectionSelectiveFlow extends AbstractMotionFlow {

    // min 100us to filter noise or multiple spikes.
    private int minDtThreshold = getInt("minDtThreshold", 100);

    private EventPacket oriPacket; // Holds orientation events.
    private final AbstractOrientationFilter oriFilter;
    private byte ori;
    private int polValue;

    public DirectionSelectiveFlow(AEChip chip) {
        super(chip);
        numInputTypes = 8; // 4 orientations * 2 polarities
        oriFilter = new SimpleOrientationFilter(chip);
        oriFilter.setAnnotationEnabled(false);
        oriFilter.setShowRawInputEnabled(false); // So that the orientation filter 
        // returns the orientation events, 
        // not the input packet.
        setEnclosedFilter(oriFilter);
        resetFilter();
        setPropertyTooltip("Dir. Selective", "minDtThreshold", "min delta time (us) "
                + "for past events allowed for selecting a particular direction. "
                + "E.g. 100 us filter out speeds higher than 10 cm/s (for a pixelWidth of 10 um)");
    }

    @Override
    synchronized public boolean extractEventInfo(Object ein) {
        if (!super.extractEventInfo(ein)) {
            return false;
        }
        if (!(ein instanceof OrientationEventInterface)) {
            return false;
        }
        polValue = e.getPolarity() == PolarityEvent.Polarity.On ? 0 : 4;
        ori = ((OrientationEventInterface) ein).getOrientation();
        // Type information here is mixture of input orientation and polarity, 
        // in order to match both characteristics.
        type = (byte) (ori + polValue);
        return true;
    }

    synchronized void writeOutputEvent(byte motionDir, Object ein) {
        super.processGoodEvent();
        eout.copyFrom((ApsDvsOrientationEvent) ein);
        eout.direction = motionDir;
        eout.dir = ApsDvsMotionOrientationEvent.unitDirs[motionDir];
    }

    @Override
    synchronized public EventPacket filterPacket(EventPacket in) {
        oriPacket = oriFilter.filterPacket(in);  // compute orientation events.
        DvsMotionOrientationEvent.Dir d1, d2;
        int dt1, dt2, n1, n2, s;
        float speed1, speed2;
        byte motionDir;
        setupFilter(in);

        // <editor-fold defaultstate="collapsed" desc="Comment">
        /**
         * If the input is ON/OFF type, then motion detection doesn't make much
         * sense because you are likely to detect the nearest event from along
         * the same edge, not from where the edge moved from. Therefore, this
         * filter only really makes sense to use with an oriented input.
         *
         * When the input is oriented (e.g. the events have an orientation type)
         * then motion estimation consists of just checking in a direction
         * *perpindicular to the edge* for the nearest event of the same input
         * orientation type. For each event write out an event of type according
         * to the direction of the most recent previous event in neighbors. Only
         * write the event if the delta time is within two-sided threshold.
         */
        // </editor-fold>
         // following awkward block needed to deal with DVS/DAVIS and IMU/APS events
        // block STARTS
        Iterator i = null;
        if (in instanceof ApsDvsEventPacket) {
            i = ((ApsDvsEventPacket) in).fullIterator();
        } else {
            i = ((EventPacket) in).inputIterator();
        }

        while (i.hasNext()) {
            Object o=i.next();
             if (o == null) {
                log.warning("null event passed in, returning input packet");
                return in;
            }
             if ((o instanceof ApsDvsEvent) && ((ApsDvsEvent)o).isApsData()) {
                continue;
            }
            PolarityEvent ein = (PolarityEvent)o;
           
            if (!extractEventInfo(o)) {
                continue;
            }
            if ( measureAccuracy || discardOutliersForStatisticalMeasurementEnabled) {
                if(imuFlowEstimator.calculateImuFlow(o)) continue;
            }
            // block ENDS

            if (!extractEventInfo(ein)) {
                continue;
            }<commit_msg>fixed DS filter to work properly again<commit_after>package ch.unizh.ini.jaer.projects.rbodo.opticalflow;

import java.util.Iterator;
import net.sf.jaer.Description;
import net.sf.jaer.DevelopmentStatus;
import net.sf.jaer.chip.AEChip;
import net.sf.jaer.event.ApsDvsEvent;
import net.sf.jaer.event.ApsDvsEventPacket;
import net.sf.jaer.event.orientation.ApsDvsMotionOrientationEvent;
import net.sf.jaer.event.orientation.ApsDvsOrientationEvent;
import net.sf.jaer.event.EventPacket;
import net.sf.jaer.event.orientation.OrientationEventInterface;
import net.sf.jaer.event.PolarityEvent;
import net.sf.jaer.event.orientation.DvsMotionOrientationEvent;
import static net.sf.jaer.eventprocessing.EventFilter.log;
import net.sf.jaer.eventprocessing.label.AbstractOrientationFilter;
import net.sf.jaer.eventprocessing.label.SimpleOrientationFilter;

/**
 * Outputs local motion events derived from time of flight of orientation events
 * from DVS sensors. Output cells type has values 0-7, 0 being upward motion,
 * increasing by 45 deg CCW to 7 being motion up and to right.
 * <p>
 * This class was originally DirectionSelectiveFilter (ca 2007 and later
 * DvsDirectionSelectiveFilter (ca 2014) in the package
 * net.sf.jaer.eventprocessing.label. These original classes have been deleted
 * and replaced by this class. The original source code is available by version
 * control reversion of the project.
 *
 * @author tobi
 */
@Description("Local motion optical flow by time-of-travel of orientation events for APSDVS (DAVIS) sensor")
@DevelopmentStatus(DevelopmentStatus.Status.Experimental)
public class DirectionSelectiveFlow extends AbstractMotionFlow {

    // min 100us to filter noise or multiple spikes.
    private int minDtThreshold = getInt("minDtThreshold", 100);

    private final AbstractOrientationFilter oriFilter;
    private byte ori;
    private int polValue;

    public DirectionSelectiveFlow(AEChip chip) {
        super(chip);
        numInputTypes = 8; // 4 orientations * 2 polarities
        oriFilter = new SimpleOrientationFilter(chip);
        oriFilter.setAnnotationEnabled(false);
        oriFilter.setShowRawInputEnabled(false); // So that the orientation filter 
        // returns the orientation events, 
        // not the input packet.
        setEnclosedFilter(oriFilter);
        resetFilter();
        setPropertyTooltip("Dir. Selective", "minDtThreshold", "min delta time (us) "
                + "for past events allowed for selecting a particular direction. "
                + "E.g. 100 us filter out speeds higher than 10 cm/s (for a pixelWidth of 10 um)");
    }

    @Override
    synchronized public boolean extractEventInfo(Object ein) {
        if (!super.extractEventInfo(ein)) {
            return false;
        }
        if (!(ein instanceof OrientationEventInterface)) {
            return false;
        }
        polValue = e.getPolarity() == PolarityEvent.Polarity.On ? 0 : 4;
        ori = ((OrientationEventInterface) ein).getOrientation();
        // Type information here is mixture of input orientation and polarity, 
        // in order to match both characteristics.
        type = (byte) (ori + polValue);
        return true;
    }

    synchronized void writeOutputEvent(byte motionDir, Object ein) {
        super.processGoodEvent();
        eout.copyFrom((ApsDvsOrientationEvent) ein);
        eout.direction = motionDir;
        eout.dir = ApsDvsMotionOrientationEvent.unitDirs[motionDir];
    }

    @Override
    synchronized public EventPacket filterPacket(EventPacket in) {
        in = oriFilter.filterPacket(in);  // compute orientation events.
        DvsMotionOrientationEvent.Dir d1, d2;
        int dt1, dt2, n1, n2, s;
        float speed1, speed2;
        byte motionDir;
        setupFilter(in);

        // <editor-fold defaultstate="collapsed" desc="Comment">
        /**
         * If the input is ON/OFF type, then motion detection doesn't make much
         * sense because you are likely to detect the nearest event from along
         * the same edge, not from where the edge moved from. Therefore, this
         * filter only really makes sense to use with an oriented input.
         *
         * When the input is oriented (e.g. the events have an orientation type)
         * then motion estimation consists of just checking in a direction
         * *perpindicular to the edge* for the nearest event of the same input
         * orientation type. For each event write out an event of type according
         * to the direction of the most recent previous event in neighbors. Only
         * write the event if the delta time is within two-sided threshold.
         */
        // </editor-fold>
         // following awkward block needed to deal with DVS/DAVIS and IMU/APS events
        // block STARTS
        Iterator i = null;
        if (in instanceof ApsDvsEventPacket) {
            i = ((ApsDvsEventPacket) in).fullIterator();
        } else {
            i = ((EventPacket) in).inputIterator();
        }

        while (i.hasNext()) {
            Object o=i.next();
             if (o == null) {
                log.warning("null event passed in, returning input packet");
                return in;
            }
             if ((o instanceof ApsDvsEvent) && ((ApsDvsEvent)o).isApsData()) {
                continue;
            }
            PolarityEvent ein = (PolarityEvent)o;
           
            if ( measureAccuracy || discardOutliersForStatisticalMeasurementEnabled) {
                if(imuFlowEstimator.calculateImuFlow(o)) continue;
            }
            // block ENDS

            if (!extractEventInfo(ein)) {
                continue;
            }
{'fraction_non_alphanumeric': 0.08275261324041812, 'fraction_numerical': 0.006968641114982578, 'mean_word_length': 2.6286346396965867, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 9, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4558004', 'n_tokens_mistral': 3201, 'n_tokens_neox': 3006, 'n_words': 985}