001/*- 002 * Copyright 2016 Diamond Light Source Ltd. 003 * 004 * All rights reserved. This program and the accompanying materials 005 * are made available under the terms of the Eclipse Public License v1.0 006 * which accompanies this distribution, and is available at 007 * http://www.eclipse.org/legal/epl-v10.html 008 */ 009 010package org.eclipse.january.dataset; 011 012import java.util.Arrays; 013 014/** 015 * Base class for boolean iterators for pairs of dataset where the second dataset could be broadcast to the first and 016 * is used to select where {{@link #hasNext()} returns true. An optional third dataset can specify the output. 017 * For speed, there are public members. 018 */ 019public abstract class BooleanIterator extends IndexIterator { 020 021 /** 022 * Create a boolean iterator that stops at every position in the choice dataset with a true value 023 * @param a primary dataset 024 * @param c choice dataset, can be null to choose all 025 * @since 2.1 026 */ 027 public static BooleanIterator createIterator(Dataset a, Dataset c) { 028 return createIterator(true, a, c, null, false); 029 } 030 031 /** 032 * Create a boolean iterator that stops at every position in the choice dataset with a true value 033 * @param a primary dataset 034 * @param c choice dataset, can be null to choose all 035 * @param o output dataset, can be null 036 * @since 2.1 037 */ 038 public static BooleanIterator createIterator(Dataset a, Dataset c, Dataset o) { 039 return createIterator(true, a, c, o, false); 040 } 041 042 /** 043 * Create a boolean iterator that stops at every position in the choice dataset where its value matches 044 * the given boolean 045 * @param v boolean value 046 * @param a primary dataset 047 * @param c choice dataset, can be null to choose all 048 * @param o output dataset, can be null 049 * @since 2.1 050 */ 051 public static BooleanIterator createIterator(boolean v, Dataset a, Dataset c, Dataset o) { 052 return createIterator(v, a, c, o, false); 053 } 054 055 /** 056 * Create a boolean iterator that stops at every position in the choice dataset where its value matches 057 * the given boolean 058 * @param v boolean value 059 * @param a primary dataset 060 * @param c choice dataset, can be null to choose all 061 * @param o output dataset, can be null 062 * @param createIfNull if true create the output dataset if that is null 063 * @since 2.1 064 */ 065 public static BooleanIterator createIterator(boolean v, Dataset a, Dataset c, Dataset o, boolean createIfNull) { 066 if (c == null) { 067 return new BooleanNullIterator(a, o, createIfNull); 068 } 069 if (Arrays.equals(a.getShapeRef(), c.getShapeRef()) && a.getStrides() == null && c.getStrides() == null) { 070 if (o == null || (o.getStrides() == null && Arrays.equals(a.getShapeRef(), o.getShapeRef()))) { 071 return new BooleanContiguousIterator(v, a, c, o, createIfNull); 072 } 073 } 074 return new BooleanBroadcastIterator(v, a, c, o, createIfNull); 075 } 076 077 protected final boolean value; 078 079 /** 080 * Index in choice dataset 081 */ 082 public int cIndex; 083 084 /** 085 * Index in output dataset 086 */ 087 public int oIndex; 088 089 /** 090 * Output dataset 091 */ 092 protected Dataset oDataset; 093 094 final protected boolean outputA; 095 096 protected int[] maxShape; 097 098 protected final int aStep; // step over items 099 protected int oStep; 100 protected int aMax; // maximum index in array 101 protected int aStart, oStart; 102 103 protected Dataset aDataset; 104 protected Dataset cDataset; 105 106 /** 107 * @return choice 108 * @since 2.1 109 */ 110 public Dataset getChoice() { 111 return cDataset; 112 } 113 114 @Override 115 public int[] getShape() { 116 return maxShape; 117 } 118 119 /** 120 * Construct a boolean iterator that stops at the given boolean value in choice dataset 121 * @param v boolean value 122 * @param a primary dataset 123 * @param c choice dataset 124 * @param o output dataset, can be null 125 */ 126 protected BooleanIterator(boolean v, Dataset a, Dataset c, Dataset o) { 127 value = v; 128 aDataset = a; 129 aStep = a.getElementsPerItem(); 130 cDataset = c; 131 oDataset = o; 132 outputA = a == o; 133 if (c != null && c == o) { 134 throw new IllegalArgumentException("Output dataset must not be same as mask dataset"); 135 } 136 137 if (c != null) { 138 BroadcastUtils.checkItemSize(a, c, o); 139 } else if (o != null) { 140 BroadcastUtils.checkItemSize(a, o); 141 } 142 if (o != null) { 143 o.setDirty(); 144 } 145 } 146 147 /** 148 * @return output dataset (can be null) 149 * @since 2.1 150 */ 151 public Dataset getOutput() { 152 return oDataset; 153 } 154}