package org.das2.datum; import java.util.ArrayList; /** * A DomainDivider which divides logarithmically (base 10), with linear subdivisions. * It provides divisions such as * @author ed */ public class LogLinDomainDivider implements DomainDivider { /** * linear divisions within the decade 1.0 to 10.0. */ private LinearDomainDivider linearDivider; /** * create a way to access this class directly. * @return */ public static LogLinDomainDivider create() { return new LogLinDomainDivider(); } /** * create one directly, useful for debugging. * @param significand 1, 2, or 5. * @param exponent 0 or -1 for many per cycle. * @return new LoglinDomainDivider */ public static LogLinDomainDivider create( int significand, int exponent ) { LinearDomainDivider lin= new LinearDomainDivider(significand,exponent); return new LogLinDomainDivider(lin); } protected LogLinDomainDivider() { this(new LinearDomainDivider()); } private LogLinDomainDivider(LinearDomainDivider linearDivider) { this.linearDivider = linearDivider; int significand= linearDivider.getSignificand(); if ( significand!=1 && significand!=2 && significand!=5 ) { throw new IllegalArgumentException("significand must be 1, 2, or 5."); } } @Override public DomainDivider coarserDivider(boolean superset) { LinearDomainDivider d = (LinearDomainDivider) linearDivider.coarserDivider(superset); if (d.boundaryCount(Datum.create(1.0), Datum.create(10.0 )) < 1) { // revert to straight log division return new LogDomainDivider(); } else return new LogLinDomainDivider(d); } @Override public DomainDivider finerDivider(boolean superset) { // Make the linear subdivision finer. LinearDomainDivider lin = (LinearDomainDivider)linearDivider.finerDivider(superset); return new LogLinDomainDivider(lin); } @Override public DatumVector boundaries(Datum min, Datum max) { if ( !min.isFinite() || !max.isFinite() ) { System.err.println("min and max must be finite"); // throw new IllegalArgumentException("min and max must be finite" ); } ArrayList bb= new ArrayList<>(); double decade = Math.pow(10, Math.floor(Math.log10(min.doubleValue()))); double nextDecade= decade*10; DatumRange current= linearDivider.rangeContaining(min.divide(decade)); current= DatumRange.newRange( current.min().multiply(decade), current.max().multiply(decade) ); Datum m=current.min(); Units u= m.getUnits(); while ( m.le(max) ) { while ( m.value()