001package com.astrolabsoftware.FinkBrowser.Januser;
002
003import com.Lomikel.Utils.Pair;
004import com.Lomikel.Utils.LomikelException;
005import com.astrolabsoftware.FinkBrowser.FinkPortalClient.FPC;
006
007// Java
008import java.util.Map;
009import java.util.HashMap;
010
011/** <code>Classifier</code> classifies <em>objects</em>.
012  * @opt attributes
013  * @opt operations
014  * @opt types
015  * @opt visibility
016  * @author <a href="mailto:Julius.Hrivnac@cern.ch">J.Hrivnac</a> */
017public abstract class Classifier {
018   
019  /** Give singleton {@link Classifier} for each type, survey and flavor.
020    * @param type   The {@link Classifier} type.
021    * @param survey The {@link Classifier} survey.
022    * @param flavor The {@link Classifier} flavor. May be empty.
023    * @throws LomikelException If {@link Classifier} cannot be created. */
024  public static Classifier instance(String type,
025                                    String survey, 
026                                    String flavor) throws LomikelException {
027    return instance(Type.valueOf(type), Survey.valueOf(survey), flavor);
028    }
029    
030  /** Give singleton {@link Classifier} for each type, survey and flavor.
031    * @param type   The {@link Classifier} {@link Type}.
032    * @param survey The {@link Classifier} {@link Survey}.
033    * @param flavor The {@link Classifier} flavor. May ber empty.
034    * @throws LomikelException If {@link Classifier} cannot be created. */
035  public static Classifier instance(Type   type,
036                                    Survey survey,
037                                    String flavor) throws LomikelException {
038    Pair<Type, String> signature = Pair.of(type, flavor);
039    if (!_classifiers.containsKey(signature)) {
040      Classifier cl;
041      switch (type) {
042        case FINK_PORTAL:
043          cl = new FinkPortalClassifier();
044          break;
045        case FINK:
046          switch (survey) {
047            case ZTF:
048              cl = new FinkZTFClassifier();
049              break;
050            case LSST:
051              cl = new FinkLSSTClassifier();
052              break;
053            default:
054              throw new LomikelException("Unknown Classifier Type " + type + " for survey " + survey);      
055            }
056          break;
057        case XMATCH:
058          cl = new XMatchClassifier();
059          break;
060        case FEATURES:
061          cl = new FeaturesClassifier();
062          break;
063        case LIGHTCURVES:
064          cl = new LightCurvesClassifier();
065          break;
066        case TAG:
067          cl = new TagClassifier();
068          break;
069        default:
070          throw new LomikelException("Unknown Classifier Type " + type);
071        }
072      cl.setType(type);
073      cl.setFlavor(flavor);
074      classifiers().put(signature, cl);
075      }
076    return classifiers().get(signature);
077    }
078    
079  /** Classify <em>object</em> and expand them to <em>source</em>s (if requested).
080    * It should register classes corresponding to specified <tt>objectId</tt>
081    * using {@link FinkGremlinRecipies#registerOCol(Classifiers, String, String, double, String, String, boolean, String)}.
082    * @param recipies   The {@link FinkGremlinRecipies} caller.
083    * @param oid        The <tt>objectId</tt> of <em>object</em> to be added.
084    * @throws LomikelException If anything fails. */
085  public abstract void classify(FinkGremlinRecipies recipies,
086                                String              oid) throws LomikelException;
087  
088  /** Set {@link Classifier} flavor.
089    * @param flavor The {@link Classifier} flavor. */
090  protected void setFlavor(String flavor) {
091    _flavor = flavor;
092    }  
093    
094  /** Set {@link Classifier} {@link Type}.
095    * @param flavor The {@link Classifier} {@link Type}. */
096  protected void setType(Type type) {
097    _type = type;
098    }    
099  
100  /** Give {@link Classifier} flavor.
101    * @return flavor The {@link Classifier} flavor. */
102  public String flavor() {
103    return _flavor;
104    }
105  
106  /** Give {@link Classifier} {@link Type} name.
107    * @param flavor The {@link Classifier} {@link Type} name. */
108  public String name() {
109    return _type.name();
110    }
111    
112  /** Give {@link Classifier} {@link Survey} name.
113    * @return flavor The {@link Classifier} {@link Survey} name. */
114  public abstract String survey();
115  
116  /** Give {@link Classifier} {@link FPC}
117    * @return flavor The {@link Classifier} {@link FPC} (<tt>null</tt> if doesn't apply). */
118  public abstract FPC fpc() throws LomikelException;
119    
120  @Override
121  public String toString() {
122    String ts = name();
123    if (_flavor != null && !_flavor.equals("")) {
124      ts += "=" + _flavor;
125      }
126    ts += "[" + survey() + "]";
127    return ts;
128    }
129    
130  private Type _type;  
131    
132  private String _flavor;
133    
134  protected static Map<Pair<Type, String>, Classifier> classifiers() {
135    return _classifiers;
136    }
137  
138  private static Map<Pair<Type, String>, Classifier> _classifiers = new HashMap<>();
139  
140  /** The survey of {@link Classifier}. */
141  public static enum Survey {
142    ZTF,
143    LSST
144    }
145    
146  /** The type of {@link Classifier}. Each {@link Type} can exist in many flavors. */
147  public static enum Type {
148    FINK_PORTAL,
149    FINK,
150    XMATCH,
151    FEATURES,
152    LIGHTCURVES,
153    TAG
154    }
155
156  }