1 /*
2  * This file is part of ELKI:
3  * Environment for Developing KDD-Applications Supported by Index-Structures
4  *
5  * Copyright (C) 2018
6  * ELKI Development Team
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU Affero General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU Affero General Public License for more details.
17  *
18  * You should have received a copy of the GNU Affero General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 package de.lmu.ifi.dbs.elki.datasource.filter.transform;
22 
23 import de.lmu.ifi.dbs.elki.data.projection.Projection;
24 import de.lmu.ifi.dbs.elki.data.type.SimpleTypeInformation;
25 import de.lmu.ifi.dbs.elki.data.type.TypeInformation;
26 import de.lmu.ifi.dbs.elki.datasource.filter.AbstractStreamConversionFilter;
27 import de.lmu.ifi.dbs.elki.utilities.optionhandling.AbstractParameterizer;
28 import de.lmu.ifi.dbs.elki.utilities.optionhandling.OptionID;
29 import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameterization.Parameterization;
30 import de.lmu.ifi.dbs.elki.utilities.optionhandling.parameters.ObjectParameter;
31 
32 /**
33  * Apply a projection to the data.
34  *
35  * @author Erich Schubert
36  * @since 0.6.0
37  *
38  * @composed - - - Projection
39  *
40  * @param <I> Input type
41  * @param <O> Output type
42  */
43 public class ProjectionFilter<I, O> extends AbstractStreamConversionFilter<I, O> {
44   /**
45    * Projection to apply.
46    */
47   Projection<I, O> projection;
48 
49   /**
50    * Constructor.
51    *
52    * @param projection Projection
53    */
ProjectionFilter(Projection<I, O> projection)54   public ProjectionFilter(Projection<I, O> projection) {
55     super();
56     this.projection = projection;
57   }
58 
59   @Override
filterSingleObject(I obj)60   protected O filterSingleObject(I obj) {
61     return projection.project(obj);
62   }
63 
64   @Override
getInputTypeRestriction()65   protected TypeInformation getInputTypeRestriction() {
66     return projection.getInputDataTypeInformation();
67   }
68 
69   @Override
convertedType(SimpleTypeInformation<I> in)70   protected SimpleTypeInformation<? super O> convertedType(SimpleTypeInformation<I> in) {
71     projection.initialize(in);
72     return projection.getOutputDataTypeInformation();
73   }
74 
75   /**
76    * Parameterization class.
77    *
78    * @author Erich Schubert
79    *
80    * @hidden
81    *
82    * @param <I> Input type
83    * @param <O> Output type
84    */
85   public static class Parameterizer<I, O> extends AbstractParameterizer {
86     /**
87      * Parameter to specify the projection to use
88      */
89     public static final OptionID PROJ_ID = new OptionID("projection", "Projection to use.");
90 
91     /**
92      * Projection to apply.
93      */
94     Projection<I, O> projection;
95 
96     @Override
makeOptions(Parameterization config)97     protected void makeOptions(Parameterization config) {
98       super.makeOptions(config);
99       ObjectParameter<Projection<I, O>> projP = new ObjectParameter<>(PROJ_ID, Projection.class);
100       if(config.grab(projP)) {
101         projection = projP.instantiateClass(config);
102       }
103     }
104 
105     @Override
makeInstance()106     protected ProjectionFilter<I, O> makeInstance() {
107       return new ProjectionFilter<>(projection);
108     }
109   }
110 }
111