Print

Print


Commit in lcsim/src/org/lcsim/contrib/SteveMagill on MAIN
PFATemplate2.java+462added 1.1


lcsim/src/org/lcsim/contrib/SteveMagill
PFATemplate2.java added at 1.1
diff -N PFATemplate2.java
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ PFATemplate2.java	8 Sep 2008 14:49:57 -0000	1.1
@@ -0,0 +1,462 @@
+package org.lcsim.contrib.SteveMagill;
+
+import java.util.*;
+import org.lcsim.util.*;
+import org.lcsim.event.*;
+import org.lcsim.event.util.*;
+import org.lcsim.util.hitmap.*;
+
+import org.lcsim.recon.cluster.util.*;
+import org.lcsim.digisim.DigiSimDriver;
+import org.lcsim.digisim.SimCalorimeterHitsDriver;
+import org.lcsim.util.hitmap.HitListToHitMapDriver;
+import org.lcsim.util.hitmap.HitMapToHitListDriver;
+import org.lcsim.event.util.CreateFinalStateMCParticleList;
+import org.lcsim.recon.cluster.cheat.PerfectClusterer;
+import org.lcsim.recon.pfa.cheat.PerfectIdentifier;
+
+import org.lcsim.recon.cluster.cheat.CheatClusterDriver;
+import org.lcsim.recon.tracking.cheat.CheatTrackDriver;
+import org.lcsim.recon.particle.CheatParticleDriver;
+import org.lcsim.contrib.Cassell.recon.analysis.ClusterCollectionEnergies;
+import org.lcsim.contrib.Cassell.recon.Cheat.PPRDriver;
+import org.lcsim.contrib.Cassell.recon.Cheat.CheatReconDriver;
+import org.lcsim.contrib.Cassell.recon.DTPhotons.*;
+
+import org.lcsim.recon.cluster.fixedcone.*;
+import org.lcsim.recon.cluster.nn.*;
+import org.lcsim.recon.cluster.directedtree.DirectedTreeDriver;
+
+// import org.lcsim.recon.cluster.util.HitInECALDecision;
+import org.lcsim.util.hitmap.HitMapFilter;
+import org.lcsim.util.hitmap.HitMapFilterDriver;
+import org.lcsim.util.decision.NotDecisionMakerSingle;
+
+import hep.physics.jet.*;
+
+public class PFATemplate2 extends Driver
+{
+   
+   public PFATemplate2()
+   {
+       
+//  **********************INITIALIZATION****************************************
+       //  use DIGISIM to get hits after timing, threshold, etc. cuts 
+       //  output of DigiSim is hit collections - 
+       //  EcalBarrDigiHits, EcalEndcapDigiHits, HcalBarrDigiHits, HcalEndcapDigiHits
+       add(new CalHitMapDriver());
+       DigiSimDriver digi = new DigiSimDriver();
+       add(digi);
+       add(new SimCalorimeterHitsDriver());
+//  ****************************************************************************
+       
+//  OPTIONAL - make subdetector hitmaps from DigiSim collections so both are available for PFA
+       HitListToHitMapDriver ebhitmap = new HitListToHitMapDriver();
+       ebhitmap.addInputList("EcalBarrDigiHits");
+       ebhitmap.setOutput("EMBarrhitmap");
+       add(ebhitmap);
+       HitListToHitMapDriver hbhitmap = new HitListToHitMapDriver();
+       hbhitmap.addInputList("HcalBarrDigiHits");
+       hbhitmap.setOutput("HADBarrhitmap");
+       add(hbhitmap);
+       HitListToHitMapDriver eehitmap = new HitListToHitMapDriver();
+       eehitmap.addInputList("EcalEndcapDigiHits");
+       eehitmap.setOutput("EMEndcaphitmap");
+       add(eehitmap);
+       HitListToHitMapDriver hehitmap = new HitListToHitMapDriver();
+       hehitmap.addInputList("HcalEndcapDigiHits");
+       hehitmap.setOutput("HADEndcaphitmap"); 
+       add(hehitmap);
+
+//  also OPTIONAL - make a combined hitmap for the digisim output hits 
+//  now have 5 hitmaps, 1 for each cal subdetector and 1 with all hits
+       HitListToHitMapDriver allHitMap = new HitListToHitMapDriver();
+       allHitMap.addInputList("EcalBarrDigiHits");
+       allHitMap.addInputList("EcalEndcapDigiHits");
+       allHitMap.addInputList("HcalBarrDigiHits");
+       allHitMap.addInputList("HcalEndcapDigiHits");
+       allHitMap.setOutput("Allhitmap");
+       add(allHitMap);
+       
+//  also, make combined EM and HAD hitmaps
+       HitListToHitMapDriver emHitMap = new HitListToHitMapDriver();
+       emHitMap.addInputList("EcalBarrDigiHits");
+       emHitMap.addInputList("EcalEndcapDigiHits");
+       emHitMap.setOutput("AllEMhitmap");
+       add(emHitMap);
+       HitListToHitMapDriver hadHitMap = new HitListToHitMapDriver();       
+       hadHitMap.addInputList("HcalBarrDigiHits");
+       hadHitMap.addInputList("HcalEndcapDigiHits");
+       hadHitMap.setOutput("AllHADhitmap");
+       add(hadHitMap);
+       
+//  *****************Perfect PFA definition*************************************
+       //  form Perfect Reconstructed Particles (Perfect PFA) from MC
+       //  Perfect Reconstructed Particle list - PerfectRecoParticles
+       //  also have PerfectCheatClusters and PerfectTracks (FSReconTracks)       
+       String CCname = "PerfectCheatClusters";
+       String CRPname = "CheatReconstructedParticles";
+       String Trname = "PerfectTracks";
+       String PerfRP = "PerfectRecoParticles";
+       
+       //  do cheat reconstruction
+       CheatReconDriver crd = new CheatReconDriver();
+       crd.setCheatReconstructedParticleOutputName(CRPname);
+       crd.setCheatClusterOutputName(CCname);
+       crd.setCheatFSTrackOutputName(Trname);
+       add(crd);
+       
+       //  now make (more realistic) cheated tracks, etc with PPR driver
+       //  use standard calibration for energies
+       PPRDriver pprd = new PPRDriver(CRPname,PerfRP);
+       ClusterEnergyCalculator pcec = new QPhotonClusterEnergyCalculator();
+       pprd.setPhotonClusterEnergyCalculator(pcec);
+       ClusterEnergyCalculator nhcec = new QNeutralHadronClusterEnergyCalculator();
+       pprd.setNeutralHadronClusterEnergyCalculator(nhcec);
+       add(pprd);
+//  ****************************************************************************
+
+//  **************************TRACK Selection Here******************************
+       //  when ready, add real track reconstruction driver here, for now, use
+       //  PerfectTracks
+//       RealTrackDriver realtrack = new RealTrackDriver();
+//       realtrack.setTrackNames("RealTracks");
+//       add(realtrack);
+//  ****************************************************************************
+
+//  ***************PFA Utility Algorithm****************************************
+       //  Utility to get some Track/SpacePoint maps of extrapolated track
+       //  positions - So far, 3 output maps <Track, SpacePoint> 
+       //  TrkXE0Map (Track pos at ECAL layer 0)
+       //  TrkXEShMaxMap (Track pos at ECAL Shower Max)
+       //  TrkXH0Map (Track pos at HCAL layer 0)
+       TrkXPosDriver txpdriver = new TrkXPosDriver();
+       txpdriver.setInputTrackList(Trname);
+       add(txpdriver);       
+       
+//  *******************TRACK-MIP ASSOCIATION algorithm*****************************
+       //  PFA algorithm running on hit collections, corresponding hitmaps are
+       //  modified by the algorithm - mip hits are removed from hitmaps
+       //  outputs are mip clusters (TMClusters)
+       //  maps : TrackMipMap <Track, BasicCluster> Track - mip cluster link
+       //  TrackILMap <Track, Integer> Track - CAL Interaction Layer link
+       //  MipClusILMap <BasicCluster, Integer> Mip cluster - CAL IL link
+       //  TrackILPosMap <Track, SpacePoint> Track - IL pos link
+       //  TrackMipEPMap <Track, SpacePoint> Track - mip cluster endpoint link
+       String mipclusters = "TMClusters";
+       double dminE = 0.005;  // hard-coded now - change to detector independent value
+       double dminH = 3*dminE;  //  same here
+       double dminTrC = 0.01;  // default range is 0.0175 - 0.0225 tuned with muons
+       double mincd = 2.25;  // min density to make mip - default is 3.5 tuned with muons
+       TrackMipClusterDriver TMdriver = new TrackMipClusterDriver(dminE, dminH, dminTrC, mincd);
+       String[] tmcollnames = {"EcalBarrDigiHits","HcalBarrDigiHits","EcalEndcapDigiHits","HcalEndcapDigiHits"};
+//       String[] tmcollnames = {"EBHits","HBHits","EEHits","HEHits"};
+       TMdriver.setCollectionNames(tmcollnames);
+       TMdriver.setClusterNameExtension(mipclusters);
+       add(TMdriver);
+//  ****************************************************************************
+
+//  *******************PFA Diagnostic algorithm************************************
+       //  OPTIONAL - checks purity of mip clusters - diagnostic routine only
+       TrMipCompDriver tmcdriver = new TrMipCompDriver();
+       tmcdriver.setTrMipClusName(mipclusters);
+       add(tmcdriver); 
+//  ****************************************************************************
+       
+       //  Convert modified hitmaps to new hit collections for clustering after mips removed
+       HitMapToHitListDriver embconverter = new HitMapToHitListDriver();
+       embconverter.setInputHitMap("EMBarrhitmap");      
+       embconverter.setOutputList("EBTMHits");
+       add(embconverter);
+       HitMapToHitListDriver emeconverter = new HitMapToHitListDriver();
+       emeconverter.setInputHitMap("EMEndcaphitmap");     
+       emeconverter.setOutputList("EECTMHits");
+       add(emeconverter);
+       HitMapToHitListDriver hadbconverter = new HitMapToHitListDriver();
+       hadbconverter.setInputHitMap("HADBarrhitmap");      
+       hadbconverter.setOutputList("HBTMHits");
+       add(hadbconverter);
+       HitMapToHitListDriver hadeconverter = new HitMapToHitListDriver();
+       hadeconverter.setInputHitMap("HADEndcaphitmap");     
+       hadeconverter.setOutputList("HECTMHits");
+       add(hadeconverter);
+       
+       // modify single hitmap for track cluster matching
+       HitListToHitMapDriver mHitMap = new HitListToHitMapDriver();
+       mHitMap.addInputList("EBTMHits");
+       mHitMap.addInputList("EECTMHits");
+       mHitMap.addInputList("HBTMHits");
+       mHitMap.addInputList("HECTMHits");
+       mHitMap.setOutput("Allhitmap");
+       add(mHitMap);
+       
+       //  modify EM and HAD hitmaps also
+       HitListToHitMapDriver memHitMap = new HitListToHitMapDriver();
+       memHitMap.addInputList("EBTMHits");
+       memHitMap.addInputList("EECTMHits");
+       memHitMap.setOutput("AllEMhitmap");
+       add(memHitMap);       
+       HitListToHitMapDriver mhadHitMap = new HitListToHitMapDriver();
+       mhadHitMap.addInputList("HBTMHits");
+       mhadHitMap.addInputList("HECTMHits");
+       mhadHitMap.setOutput("AllHADhitmap");
+       add(mhadHitMap);       
+       
+//  ************PHOTON FINDER algorithm*****************************************
+       //  add modified Ron's Photon algorithm here - use either all hitmap
+       //  or hitmap after track clusters subtracted
+       String phCl = "DTPhotonClusters";
+       //  modified Ron's SiD01 photon finder to only use input hitmap
+       add(new ModRonDTPhotonFinderSid01("AllEMhitmap", "ARPFhitmap", phCl ));
+//  ****************************************************************************
+       
+       //  Now, modify hitmaps taking out hits in Photons, then make collectons for hadron shower clustering
+       ClusterListToHitMapDriver PhotoHitDriver = new ClusterListToHitMapDriver();
+       PhotoHitDriver.addInputList(phCl);
+       PhotoHitDriver.setOutputHitMap("PhHitMap");
+       add(PhotoHitDriver);
+       HitMapSubtractDriver TMPdriver = new HitMapSubtractDriver();
+       TMPdriver.setFirstHitMap("AllEMhitmap");
+       TMPdriver.setSecondHitMap("PhHitMap");
+       TMPdriver.setOutputHitMap("AllEMhitmap");
+       add(TMPdriver);
+       HitMapToHitListDriver tmpconverter = new HitMapToHitListDriver();
+       tmpconverter.setInputHitMap("AllEMhitmap");
+       tmpconverter.setOutputList("NMPEMHits");
+       add(tmpconverter);       
+             
+       //  modify allhitmap
+       HitMapAddDriver Hdriver = new HitMapAddDriver();
+       Hdriver.addInputHitMap("AllEMhitmap");
+       Hdriver.addInputHitMap("AllHADhitmap");
+       Hdriver.setOutputHitMap("Allhitmap");
+       add(Hdriver);
+       
+//  *****************TRACK-CAL SHOWER ASSOCIATION Algorithm*********************
+       //  first, choose cluster algorithm to form cluster inputs
+       // Directed Tree (DT) clusterer 
+       int allsize = 3;
+       DirectedTreeDriver DTAlldriver = new DirectedTreeDriver();
+       DTAlldriver.setInputHitMap("Allhitmap");
+       DTAlldriver.setOutputClusterList("AllDTClus");
+       DTAlldriver.setMinimumClusterSize(allsize);
+       add(DTAlldriver);
+       
+       //  add TrCAL matching driver here
+       String trshclus = "TrackCALClusters";
+       double dcore = 0.010;  // distance of hits from track for core clusters
+       double minsep = 0.0115; // distance of shower from track - default for scin 0.025
+       int nloop = 8;  // default 5
+       double cres = 0.70;  // cal resolution stoch factor 0.7 for rpc, 0.5 for scint
+       double mintp = 1.0;  // 1 GeV is default (means min eop for rpc is 0.3)
+       //  use full forward track shower driver here (includes core)
+       TSCForDriver TrShdriver = new TSCForDriver(dcore, minsep, nloop, cres, mintp);       
+       String[] shclnames = {"AllDTClus"};  
+       TrShdriver.setClusterNames(shclnames);
+       TrShdriver.setOutputClusterList(trshclus);
+       add(TrShdriver);
+//  ****************************************************************************
+       
+       //  subtract shower clusters only (mips already missing) from input hitmap
+       ClusterListToHitMapDriver TrShowerHitDriver = new ClusterListToHitMapDriver();
+       TrShowerHitDriver.addInputList("TrackShowerClusters");
+       TrShowerHitDriver.setOutputHitMap("TrCALShowHitMap");
+       add(TrShowerHitDriver);
+       HitMapSubtractDriver TSsubdriver = new HitMapSubtractDriver();
+       TSsubdriver.setFirstHitMap("Allhitmap");
+       TSsubdriver.setSecondHitMap("TrCALShowHitMap");
+       TSsubdriver.setOutputHitMap("Allhitmap");
+       add(TSsubdriver);
+              
+       //  separate into ECAL,HCAL hitmaps for additional photon finder
+       MyHitInECALDecision decisionEcal = new MyHitInECALDecision();       
+       HitMapFilter EMFilter = new HitMapFilter();
+       HitMapFilter HADFilter = new HitMapFilter();
+       EMFilter.setDecisionOnHit(decisionEcal);
+       HADFilter.setDecisionOnHit(new NotDecisionMakerSingle(decisionEcal));
+       
+       HitMapFilterDriver emfdriver = new HitMapFilterDriver();
+       emfdriver.setInputHitMap("Allhitmap");
+       emfdriver.setFilter(EMFilter);
+       emfdriver.setOutputHitMap("AllEMhitmap");
+       add(emfdriver);
+       
+       HitMapToHitListDriver ptsemconverter = new HitMapToHitListDriver();
+       ptsemconverter.setInputHitMap("AllEMhitmap");
+       ptsemconverter.setOutputList("NMTSPEMHits");
+       add(ptsemconverter);       
+
+       HitMapFilterDriver hadfdriver = new HitMapFilterDriver();
+       hadfdriver.setInputHitMap("Allhitmap");
+       hadfdriver.setFilter(HADFilter);
+       hadfdriver.setOutputHitMap("AllHADhitmap");
+       add(hadfdriver);
+       
+       HitMapToHitListDriver ptshadconverter = new HitMapToHitListDriver();
+       ptshadconverter.setInputHitMap("AllHADhitmap");
+       ptshadconverter.setOutputList("NMTSPHADHits");
+       add(ptshadconverter);
+       
+//  ****************Low Energy Photon Algorithm*********************************
+       //  cluster EM hits again with DT
+       int nem = 3;
+       DirectedTreeDriver apedriver = new DirectedTreeDriver();
+       apedriver.setMinimumClusterSize(nem);
+       apedriver.setInputHitMap("AllEMhitmap");
+       apedriver.setOutputClusterList("PCandClusters");
+       add(apedriver);
+
+       // add Low Energy Photon Finder PFA algorithm here - takes above clusters as input
+       int minc = 5;  // default is 20-25, clear break in hits vs e at 20-25, 500 MeV
+       double minclE = 0.075;  // see above for mincells
+       double maxclE = 1.0;  // maximum E for cluster 
+       int minl = 9;  // max layer for start of pho shower
+       LEPhoDriver ledriver = new LEPhoDriver(minc,minclE,maxclE,minl);
+       String clname = ("PCandClusters");
+       ledriver.setInputClusterName(clname);
+       ledriver.setOutputClusterName("LEPhotonClusters");
+       add(ledriver); 
+//  ****************************************************************************
+       
+       //  remove LEPho hits from hitmap and continue
+       ClusterListToHitMapDriver lepdriver = new ClusterListToHitMapDriver();
+       lepdriver.addInputList("LEPhotonClusters");
+       lepdriver.setOutputHitMap("LEPHitMap");
+       add(lepdriver);
+       HitMapSubtractDriver LEPdriver = new HitMapSubtractDriver();
+       LEPdriver.setFirstHitMap("AllEMhitmap");
+       LEPdriver.setSecondHitMap("LEPHitMap");
+       LEPdriver.setOutputHitMap("AllEMhitmap");
+       add(LEPdriver);
+       
+       //  modify allhitmap
+       HitMapAddDriver HEMdriver = new HitMapAddDriver();
+       HEMdriver.addInputHitMap("AllEMhitmap");
+       HEMdriver.addInputHitMap("AllHADhitmap");
+       HEMdriver.setOutputHitMap("Allhitmap");
+       add(HEMdriver);
+
+       //  try perfect clusters from PPR list if wanted
+       PPFAPhotonClusterDriver pphodriver = new PPFAPhotonClusterDriver();
+       String pprclname = ("PPRClusters");
+       pphodriver.setInputClusName(pprclname);
+       pphodriver.setOutputClusName("PCPhotonClusters");
+       add(pphodriver);
+              
+//  ********************Photon-Track Comparison Driver**************************
+       //  check photons now with closeness to tracks and eoverp ratio, combine
+       //  final selection into single photon cluster list
+       String phonames = "PhotonClusters";
+       int dsize = 0;  // can make min cell requirement
+       double emin = 0.075;  // min energy requirement
+       double dtc = 0.015;  // dist from track to merge with track
+       DTPhoAcceptDriver dtdriver = new DTPhoAcceptDriver(dsize, dtc, emin);
+//       String[] innames = {"DTPhotonClusters"};
+       String[] innames = {"DTPhotonClusters","LEPhotonClusters"};
+       dtdriver.setInputClusNames(innames);
+       dtdriver.setOutputClusNames(phonames);
+       add(dtdriver);
+//  ****************************************************************************
+       
+//  ********************PFA Diagnostic Algorithm********************************
+       //  OPTIONAL checks purity of photon clusters - diagnostic routine only
+       PhoCompDriver phdriver = new PhoCompDriver();
+       phdriver.setPhoClusNames(phonames);
+       add(phdriver); 
+//  ****************************************************************************
+
+       //  get perfect neutral hadron clusters from PPR list if wanted
+       PPFANeuHClusterDriver pnhdriver = new PPFANeuHClusterDriver();
+       pnhdriver.setInputClusName(pprclname);
+       pnhdriver.setOutputClusName("PNeutralHadronClusters");
+       add(pnhdriver);
+       
+       //  cluster remaining hits with DT for NH algorithm - em and had separately
+       int esize = 5;
+       DirectedTreeDriver dtnemdriver = new DirectedTreeDriver();
+       dtnemdriver.setInputHitMap("AllEMhitmap");
+       dtnemdriver.setOutputClusterList("NHEMCandClusters");
+       dtnemdriver.setMinimumClusterSize(esize);
+       add(dtnemdriver);
+       int hsize = 5;
+       DirectedTreeDriver dtnhaddriver = new DirectedTreeDriver();
+       dtnhaddriver.setInputHitMap("AllHADhitmap");
+       dtnhaddriver.setOutputClusterList("NHHADCandClusters");
+       dtnhaddriver.setMinimumClusterSize(hsize);
+       add(dtnhaddriver);
+       
+//  ***********************PFA Utility algorithm********************************
+       // form a single list after merging clusters - 3 types of merging, EM-EM,
+       //  HAD-HAD, and EM-HAD
+       double mdistee = 0.075;
+       double mdisthh = 0.075;
+       double mdisteh = 0.075;
+       int mhits = 8;
+       ClMergeDriver clmdriver = new ClMergeDriver(mdistee,mdisthh,mdisteh,mhits);
+       clmdriver.setInputEMClusterName("NHEMCandClusters");
+       clmdriver.setInputHADClusterName("NHHADCandClusters");
+       clmdriver.setOutputClusterName("NHCandClusters");
+       add(clmdriver);
+//  ****************************************************************************
+
+//  ****************NEUTRAL HADRON FINDER Algorithm*****************************
+       //  add neutral hadron cluster driver here
+       String nhclusters = "NeutralHadronClusters";
+       int nsize = 8;
+       double nemin = 0.20;
+       double ndtr = 0.05;
+       NHCandClusterDriver nhdriver = new NHCandClusterDriver(nsize, nemin, ndtr);
+       nhdriver.setInputClusterName("NHCandClusters");
+       nhdriver.setOutputClusterName(nhclusters);
+       add(nhdriver);
+//  ****************************************************************************
+       
+       ClusterListToHitMapDriver nhcdriver = new ClusterListToHitMapDriver();
+       nhcdriver.addInputList("NeutralHadronClusters");
+       nhcdriver.setOutputHitMap("NHHitMap");
+       add(nhcdriver);
+       
+//       HitMapToHitListDriver lconverter = new HitMapToHitListDriver();
+//       lconverter.setInputHitMap("AllEMhitmap");
+//       lconverter.setOutputList("LEMHits");
+//       add(lconverter);
+//       HitMapToHitListDriver hconverter = new HitMapToHitListDriver();
+//       hconverter.setInputHitMap("AllHADhitmap");
+//       hconverter.setOutputList("NHADHits");
+//       add(hconverter);       
+//       HitListToHitMapDriver bnhHitMap = new HitListToHitMapDriver();
+//       bnhHitMap.addInputList("LEMHits");
+//       bnhHitMap.addInputList("NHADHits");
+//       bnhHitMap.setOutput("Allhitmap");
+//       add(bnhHitMap);
+
+       HitMapSubtractDriver Ldriver = new HitMapSubtractDriver();
+       Ldriver.setFirstHitMap("Allhitmap");
+       Ldriver.setSecondHitMap("NHHitMap");
+       Ldriver.setOutputHitMap("Allhitmap");
+       add(Ldriver);
+       HitMapToHitListDriver fconverter = new HitMapToHitListDriver();
+       fconverter.setInputHitMap("Allhitmap");
+       fconverter.setOutputList("LeftOverHits");
+       add(fconverter);
+       
+//  *****************Reconstructed Particle List Algorithm**********************
+       //  Make Reconstructed Particle List from tracks, photon clusters, and
+       //  neutral hadron clusters
+       ClusterToReconstructedParticleDriver ClRPdriver = new ClusterToReconstructedParticleDriver();
+       ClRPdriver.setTrackNames("PerfectTracks");
+       ClRPdriver.setPhotonNames("PhotonClusters");
+       ClRPdriver.setNeutralHadNames("NeutralHadronClusters");
+       ClRPdriver.setRecoParticleName("AllRecoParticles");
+       add(ClRPdriver);
+//  ****************************************************************************
+       
+//  ***************PFA Diagnostic algorithm*************************************
+       //  OPTIONAL - checks purity of track shower clusters - diagnostic routine only
+       TrShowCompDriver tscdriver = new TrShowCompDriver();
+       String tsnames = ("TrackCALClusters");
+       tscdriver.setTrShowClusName(tsnames);
+       add(tscdriver);         
+       
+   }
+}
CVSspam 0.2.8