View Javadoc

1   package org.lcsim.util.aida;
2   
3   import hep.aida.IAnalysisFactory;
4   import hep.aida.IBaseHistogram;
5   import hep.aida.ICloud1D;
6   import hep.aida.ICloud2D;
7   import hep.aida.ICloud3D;
8   import hep.aida.IHistogram1D;
9   import hep.aida.IHistogram2D;
10  import hep.aida.IHistogram3D;
11  import hep.aida.IHistogramFactory;
12  import hep.aida.IManagedObject;
13  import hep.aida.IProfile1D;
14  import hep.aida.IProfile2D;
15  import hep.aida.ITree;
16  import hep.aida.ref.rootwriter.RootFileStore;
17  import hep.aida.ref.xml.AidaXMLStore;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.FileOutputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.io.OutputStream;
25  import java.lang.ref.Reference;
26  import java.lang.ref.WeakReference;
27  
28  import org.freehep.application.Application;
29  import org.freehep.application.studio.Studio;
30  import org.freehep.record.loop.AbstractLoopListener;
31  import org.freehep.record.loop.LoopEvent;
32  import org.freehep.record.loop.RecordLoop;
33  
34  /**
35   * A convenience class for creating and filling histograms.
36   * Histograms created using this class will be automatically
37   * cleared when data is rewound.
38   * @author Tony Johnson
39   */
40  public class AIDA
41  {
42     private int defMax = 10000;
43     private IAnalysisFactory af;
44     private ITree tree;
45     private String compressFormat;
46     private IHistogramFactory hf;
47     private File tempFile;
48     private static AIDA defaultInstance;
49     public static String aidaTreeCompressProperty = "org.lcsim.util.aida.CompressOption";
50  
51     public static AIDA defaultInstance()
52     {
53        if (defaultInstance == null) defaultInstance = new AIDA();
54        return defaultInstance;
55     }
56  
57     private AIDA()
58     {
59        try
60        {
61           compressFormat = System.getProperty(aidaTreeCompressProperty, "gzip");
62           tempFile = File.createTempFile("aida",".aida");
63           tempFile.deleteOnExit();
64           af = IAnalysisFactory.create();
65           tree = af.createTreeFactory().create(tempFile.getAbsolutePath(), "xml", false,true, "compress="+compressFormat);
66           hf = af.createHistogramFactory(tree);
67  
68           Application app = Application.getApplication();
69           if (app instanceof Studio)
70           {
71              RecordLoop loop = (RecordLoop) ((Studio) app).getLookup().lookup(RecordLoop.class);
72              if (loop != null) loop.addLoopListener(new RewindListener(this));
73           }
74        }
75        catch (IOException x)
76        {
77           throw new AIDAException("IOException creating temporary store",x);
78        }
79     }
80  
81     private void checkPath(String path)
82     {
83        int pos = path.lastIndexOf('/');
84        if (pos > 0) tree.mkdirs(path.substring(0, pos));
85     }
86  
87     public ICloud1D cloud1D(String path)
88     {
89        return cloud1D(path, defMax);
90     }
91  
92     public ICloud1D cloud1D(String path, int nMax)
93     {
94        try
95        {
96           IManagedObject obj = tree.find(path);
97           if (obj instanceof ICloud1D) return (ICloud1D) obj;
98           throw new RuntimeException(path +" is not a ICloud1D");
99        }
100       catch (IllegalArgumentException x)
101       {
102          checkPath(path);
103          return hf.createCloud1D(path, path, nMax);
104       }
105    }
106 
107    public ICloud2D cloud2D(String path)
108    {
109       return cloud2D(path, defMax);
110    }
111 
112    public ICloud2D cloud2D(String path, int nMax)
113    {
114       try
115       {
116          IManagedObject obj = tree.find(path);
117          if (obj instanceof ICloud2D) return (ICloud2D) obj;
118          throw new RuntimeException(path +" is not a ICloud2D");
119       }
120       catch (IllegalArgumentException x)
121       {
122          checkPath(path);
123          return hf.createCloud2D(path, path, nMax);
124       }
125    }
126 
127    public ICloud3D cloud3D(String path)
128    {
129       return cloud3D(path, defMax);
130    }
131 
132    public ICloud3D cloud3D(String path, int nMax)
133    {
134       try
135       {
136          IManagedObject obj = tree.find(path);
137          if (obj instanceof ICloud3D) return (ICloud3D) obj;
138          throw new RuntimeException(path +" is not a ICloud3D");
139       }
140       catch (IllegalArgumentException x)
141       {
142          checkPath(path);
143          return hf.createCloud3D(path, path, nMax);
144       }
145    }
146 
147    public IHistogram1D histogram1D(String path)
148    {
149       IManagedObject obj = tree.find(path);
150       if (obj instanceof IHistogram1D) return (IHistogram1D) obj;
151       throw new RuntimeException(path +" is not a IHistogram1D");
152    }
153 
154    public IHistogram1D histogram1D(String path, int bins, double lowerEdge, double upperEdge)
155    {
156       try
157       {
158          IManagedObject obj = tree.find(path);
159          if (obj instanceof IHistogram1D) return (IHistogram1D) obj;
160          throw new RuntimeException(path +" is not a IHistogram1D");
161       }
162       catch (IllegalArgumentException x)
163       {
164          checkPath(path);
165          return hf.createHistogram1D(path, bins, lowerEdge, upperEdge);
166       }
167    }
168    
169    public IHistogram1D histogram1D(String path, int bins, double lowerEdge, double upperEdge, String options)
170    {
171       try
172       {
173          IManagedObject obj = tree.find(path);
174          if (obj instanceof IHistogram1D) return (IHistogram1D) obj;
175          throw new RuntimeException(path +" is not a IHistogram1D");
176       }
177       catch (IllegalArgumentException x)
178       {
179          checkPath(path);
180          return hf.createHistogram1D(path,"", bins, lowerEdge, upperEdge, options);
181       }
182    }
183 
184    public IHistogram2D histogram2D(String path)
185    {
186       IManagedObject obj = tree.find(path);
187       if (obj instanceof IHistogram2D) return (IHistogram2D) obj;
188       throw new RuntimeException(path +" is not a IHistogram2D");
189    }
190 
191    public IHistogram2D histogram2D(String path, int nBinsX, double lowerEdgeX, double upperEdgeX, int nBinsY, double lowerEdgeY, double upperEdgeY)
192    {
193       try
194       {
195          IManagedObject obj = tree.find(path);
196          if (obj instanceof IHistogram2D) return (IHistogram2D) obj;
197          throw new RuntimeException(path +" is not a IHistogram2D");
198       }
199       catch (IllegalArgumentException x)
200       {
201          checkPath(path);
202          return hf.createHistogram2D(path, nBinsX, lowerEdgeX, upperEdgeX, nBinsY, lowerEdgeY, upperEdgeY);
203       }
204    }
205 
206    public IHistogram3D histogram3D(String path)
207    {
208       IManagedObject obj = tree.find(path);
209       if (obj instanceof IHistogram3D) return (IHistogram3D) obj;
210       throw new RuntimeException(path +" is not a IHistogram3D");
211    }
212 
213    public IHistogram3D histogram3D(String path, int nBinsX, double lowerEdgeX, double upperEdgeX, int nBinsY, double lowerEdgeY, double upperEdgeY, int nBinsZ, double lowerEdgeZ, double upperEdgeZ)
214    {
215       try
216       {
217          IManagedObject obj = tree.find(path);
218          if (obj instanceof IHistogram3D) return (IHistogram3D) obj;
219          throw new RuntimeException(path +" is not a IHistogram3D");
220       }
221       catch (IllegalArgumentException x)
222       {
223          checkPath(path);
224          return hf.createHistogram3D(path, nBinsX, lowerEdgeX, upperEdgeX, nBinsY, lowerEdgeY, upperEdgeY, nBinsZ, lowerEdgeZ, upperEdgeZ);
225       }
226 
227    }
228 
229    public IHistogramFactory histogramFactory()
230    {
231       return hf;
232    }
233 
234    public IProfile1D profile1D(String path)
235    {
236       IManagedObject obj = tree.find(path);
237       if (obj instanceof IProfile1D) return (IProfile1D) obj;
238       throw new RuntimeException(path +" is not a IProfile1D");
239    }
240 
241    public IProfile1D profile1D(String path, int nBins, double lowerEdge, double upperEdge)
242    {
243       try
244       {
245          IManagedObject obj = tree.find(path);
246          if (obj instanceof IProfile1D) return (IProfile1D) obj;
247          throw new RuntimeException(path +" is not a IProfile1D");
248       }
249       catch (IllegalArgumentException x)
250       {
251          checkPath(path);
252          return hf.createProfile1D(path, nBins, lowerEdge, upperEdge);
253       }
254    }
255 
256    public IProfile2D profile2D(String path)
257    {
258       IManagedObject obj = tree.find(path);
259       if (obj instanceof IProfile2D) return (IProfile2D) obj;
260       throw new RuntimeException(path +" is not a IProfile2D");
261    }
262 
263    public IProfile2D profile2D(String path, int nBinsX, double lowerEdgeX, double upperEdgeX, int nBinsY, double lowerEdgeY, double upperEdgeY)
264    {
265       try
266       {
267          IManagedObject obj = tree.find(path);
268          if (obj instanceof IProfile2D) return (IProfile2D) obj;
269          throw new RuntimeException(path +" is not a IProfile2D");
270       }
271       catch (IllegalArgumentException x)
272       {
273          checkPath(path);
274          return hf.createProfile2D(path, nBinsX, lowerEdgeX, upperEdgeX, nBinsY, lowerEdgeY, upperEdgeY);
275       }
276    }
277 
278    public IAnalysisFactory analysisFactory()
279    {
280       return af;
281    }
282 
283    public ITree tree()
284    {
285       return tree;
286    }
287 
288    public void saveAs(String name) throws IOException
289    {
290        if (name.toLowerCase().endsWith(".root")) {
291          saveAsRoot(name);
292          return;
293        }
294        if (!name.toLowerCase().endsWith(".aida")) name = name + ".aida";
295        save(new File(name), false);
296    }
297 
298    public void saveAs(File outFile) throws IOException
299    {
300        if (outFile.getName().toLowerCase().endsWith(".root")) {
301          saveAsRoot(outFile.getPath());
302          return;
303        }
304        save(outFile,false);
305    }
306    
307    public void saveAsZip(String name) throws IOException
308    {
309        if (!name.toLowerCase().endsWith(".aida")) name = name + ".aida";
310        save(new File(name), true);
311    }
312 
313    public void saveAsZip(File outFile) throws IOException
314    {
315        save(outFile,true);
316    }
317    void save(File dest, boolean useZip) throws IOException {
318        if (!useZip) {
319            tree.commit();
320            if (dest.exists()) dest.delete();
321            boolean rc = tempFile.renameTo(dest);
322            if (!rc) {
323                byte[] buffer = new byte[32768];
324                OutputStream out = new FileOutputStream(dest);
325                InputStream in = new FileInputStream(tempFile);
326                try {
327                    for (;;) {
328                        int l = in.read(buffer);
329                        if (l<0) break;
330                        out.write(buffer,0,l);
331                    }
332                } finally {
333                    out.close();
334                    in.close();
335                    tempFile.delete();
336                }
337            }
338       } else {
339           AidaXMLStore store = new AidaXMLStore();
340           if (dest.exists()) dest.delete();
341           de.schlichtherle.io.File newFile = new de.schlichtherle.io.File(dest);
342           //if (newFile.exists() && !newFile.isDirectory()) 
343               //throw new IOException("File already exists: "+newFile.getAbsolutePath());
344           store.commit(tree, newFile, null, useZip, false, false);
345       }      
346    }
347    
348    private void saveAsRoot(String path) throws IOException {
349        RootFileStore store = new RootFileStore(path);
350        tree.commit();
351        store.open();
352        store.add(tree);
353        store.close();
354    }
355    
356    private class AIDAException extends RuntimeException
357    {
358       AIDAException(String message, Throwable cause)
359       {
360          super(message,cause);
361       }
362    }
363    public void clearAll()
364    {
365       String[] type = tree.listObjectNames("/",true);
366       for (int i=0; i<type.length; i++)
367       {
368          if (type[i].endsWith("/")) continue;
369          IManagedObject obj = tree.find(type[i]);
370          if (obj instanceof IBaseHistogram) ((IBaseHistogram) obj).reset();
371       }
372    }
373    private static class RewindListener extends AbstractLoopListener
374    {
375       private Reference weak;
376       RewindListener(AIDA aida)
377       {
378          weak = new WeakReference(aida);
379       }
380       public void reset(LoopEvent loopEvent)
381       {
382          AIDA aida = (AIDA) weak.get();
383          if (aida != null)
384          {
385             aida.clearAll();
386          }
387          else
388          {
389             RecordLoop loop = (RecordLoop) loopEvent.getSource();
390             loop.removeLoopListener(this);
391          }
392       }
393    }
394 }