Print

Print


Author: [log in to unmask]
Date: Sun Oct 25 16:13:40 2015
New Revision: 3888

Log:
Some changes to LED stuff

Modified:
    java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java
    java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java

Modified: java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java
 =============================================================================
--- java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java	(original)
+++ java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalEventDisplay.java	Sun Oct 25 16:13:40 2015
@@ -322,19 +322,28 @@
             }
         });
         // Comment this out for now. It is causing problems. --JM
-        /*
-         * int row,column; String hName; //System.out.println("EcalEventDisplay endOfData clear histograms"); for(int ii
-         * = 0; ii < NUM_CHANNELS; ii++) { // The above instruction is a terrible hack, just to fill // the arrayList
-         * with all the elements. They'll be initialized // properly during the event readout, Since we want to account
-         * // for possibly different raw waveform dimensions! //Get the x and y indices for the current channel. row =
-         * EcalMonitoringUtilities.getRowFromHistoID(ii); column = EcalMonitoringUtilities.getColumnFromHistoID(ii);
-         * hName=detectorName + " : " + inputCollection + " : Hit Energy : " + column + " " + row + ": " + ii;
-         * aida.tree().rm(hName); hName=detectorName + " : " + inputCollection + " : Hit Time : " + column + " " + row +
-         * ": " + ii; aida.tree().rm(hName); hName=detectorName+ " : " + inputCollection + " : Hit Time Vs Energy : " +
-         * column + " " + row + ": " + ii; aida.tree().rm(hName); if (isFirstRaw[ii]==false){ hName=detectorName+ " : "
-         * + inputCollectionRaw + " : Raw Waveform : " + column + " " + row + ": " + ii; aida.tree().rm(hName); } }
-         */
-        // System.out.println("EcalEventDisplay endOfData clear histograms done");
+        
+        int row,column; 
+        String hName; 
+        System.out.println("EcalEventDisplay endOfData clear histograms"); 
+        for(int ii = 0; ii < NUM_CHANNELS; ii++) { 
+              row=EcalMonitoringUtilities.getRowFromHistoID(ii);
+        	  column = EcalMonitoringUtilities.getColumnFromHistoID(ii);
+        	  hName=detectorName + " : " + inputCollection + " : Hit Energy : " + column + " " + row + ": " + ii;
+        	  aida.tree().rm(hName);
+        	  hName=detectorName + " : " + inputCollection + " : Hit Time : " + column + " " + row +": " + ii;
+        	  aida.tree().rm(hName);
+        	  hName=detectorName+ " : " + inputCollection + " : Hit Time Vs Energy : " + column + " " + row + ": " + ii; 
+        	  aida.tree().rm(hName); 
+        	  hName=detectorName + " : " + inputCollection +" : Cluster Energy : " + column + " " + row + ": " + ii;
+        	  aida.tree().rm(hName);
+        	  
+        	  
+        	  if (isFirstRaw[ii]==false)          { 
+        		  hName=detectorName+ " : "          + inputCollectionRaw + " : Raw Waveform : " + column + " " + row + ": " + ii; aida.tree().rm(hName); 
+        	  } 
+          }
+          System.out.println("EcalEventDisplay endOfData clear histograms done");
     }
 
     @Override

Modified: java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java
 =============================================================================
--- java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java	(original)
+++ java/trunk/monitoring-drivers/src/main/java/org/hps/monitoring/ecal/plots/EcalLedSequenceMonitor.java	Sun Oct 25 16:13:40 2015
@@ -1,5 +1,8 @@
 package org.hps.monitoring.ecal.plots;
 
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
 
 import hep.aida.IEvaluator;
 import hep.aida.IFitResult;
@@ -55,767 +58,794 @@
  */
 public class EcalLedSequenceMonitor extends Driver{
 
-    private static final int NUM_CHANNELS = 11 * 47;
-    private static final String dbTag = "led";
-    private static final String dbTableName = "ecal_led_calibrations";
-    private static final int runNumberMax = 9999;
-    private static final int nDrivers = 8;
-    private static final int nSteps = 56;
-
-    String inputCollectionRaw = "EcalReadoutHits";
-    String inputCollection = "EcalCalHits";	
-    AIDA aida;
-
-    DatabaseConditionsManager conditionsManager;
-
-    private EcalChannelCollection ChannelCollection;	
-    private EcalLedCollection LedCollection;
-    private EcalConditions ecalConditions;
-
-    Map < Integer,Integer > LedTopMap; //chid (conditions) --> LED id
-    Map < Integer,Integer > LedBotMap; //chid (conditions) --> LED id 
-
-    Map < Integer,Integer > LedTopMapInverted; //LED id --> chid (conditions)
-    Map < Integer,Integer > LedBotMapInverted; //LED id  --> chid (conditions)
-
-    private boolean useRawEnergy=false;
-
-
-
-    private int runNumber = 0;	
-    private int eventN    = 0;
-    private int id,row,column,chid,ledid,driverid;
-    private  int[][] LEDStep = new int[][]{
-            //first 4 are the flasher1 sequence, TOP controller 
-            {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,-1,-1},
-            {56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111},
-            {112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,-1}, //missing 135 is ok
-            {168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223},
-            //second 4 are the flasher2 sequence, BOTTOM controller 
-            {2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,-1,-1},	
-            {56,57,58,59,60,61,62,63,64,65,66,67,68,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,-1}, //missing 69 is OK
-            {112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167},	
-            {168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223},
-    };
-
-    private int[] iStep = new int[nDrivers];
-    private int[] nEvents = new int[NUM_CHANNELS];
-    private double[] mMean = new double[NUM_CHANNELS];
-    private double[] mRMS = new double[NUM_CHANNELS];
-
-    private int nEventsMin=200;
-    private int nMinChannelsWithEvents=350; 
-    private double energy,fillEnergy,fillTime;
-    private double energyCut=2; //we expect very high energy from the LEDs..
-    private double skipInitial=0.05;
-    private double skipMin=0.3;
-    private long cellID;
-    
-    
-    
-    
-    //Histograms-functions-ntuples
-    private ArrayList<ITuple> iTuple;
-
-    private IFunction  fFunction,fFunction1;
-    private IProfile1D   cProfile;
-    private IHistogram2D			hMeanCharge2D;
-    private ArrayList<IHistogram1D> hCharge;
-    private ArrayList<IHistogram2D> hChargeVsEvn;
-    private IPlotterFactory factory;
-    private IPlotter pPlotter=null;
-    private IPlotter pPlotter2=null;
-    private IPlotterStyle style ;
-    private int[] fitStatus = new int[NUM_CHANNELS];
-    
-    private boolean doFullAnalysis=false;
-    private boolean isMonitoringApp=false; 
-    
-    private double[] fPars;    
-    private double[] fPrevPars;
-    private double[] fParErrs;
-    private String[] fParNames; 
-
-    
-    private double fEvnMinDraw=0.;
-    private double fEvnMaxDraw=80000.;
-    private double fChargeMinDraw=0.;
-    private double fChargeMaxDraw=100.;
-
-    /*Components for user interaction*/
-    private JDialog dialog;
-    private JLabel  label;
-    private JFrame frame;
-    private JPanel panel;
-    String  labelString;
-    private JButton okButton,cancelButton;
-    private int m_iteration=0;
-    private int m_ret=0;
-    static Object modalMonitor = new Object();
-    
-    public void setUseRawEnergy(boolean useRawEnergy) {
-        this.useRawEnergy=useRawEnergy;
-    }
-
-    public void setEnergyCut(double energyCut) {
-        this.energyCut=energyCut;
-    }
-    public void setSkipInitial(double skipInitial) {
-        this.skipInitial=skipInitial;
-    }
-    public void setSkipMin(double skipMin) {
-        this.skipMin=skipMin;
-    }
-
-    public void setEvnMinDraw(double evnMinDraw){
-        this.fEvnMinDraw=evnMinDraw;
-    }
-    public void setEvnMaxDraw(double evnMaxDraw){
-        this.fEvnMaxDraw=evnMaxDraw;
-    }
-    public void setChargeMinDraw(double chargeMinDraw){
-        this.fChargeMinDraw=chargeMinDraw;
-    }
-    public void setChargeMaxDraw(double chargeMaxDraw){
-        this.fChargeMaxDraw=chargeMaxDraw;
-    }
-    
-    public void setNEventsMin(int nEeventsMin){
-        this.nEventsMin=nEventsMin;
-    }
-    
-    public void setIsMonitoringApp(boolean app){
-        this.isMonitoringApp=app;
-    }
-
-    public void setDoFullAnalysis(boolean fullAnalysis){
-        this.doFullAnalysis=fullAnalysis;
-    }
-    
-    @Override
-    protected void detectorChanged(Detector detector) {
-        System.out.println("LedAnalysis::Detector changed was called");
-        System.out.println(fEvnMinDraw+" "+fEvnMaxDraw);
-        for (int ii=0;ii<nDrivers;ii++){
-            iStep[ii]=-1;
-        }
-
-        // Setup conditions
-
-        conditionsManager = DatabaseConditionsManager.getInstance();
-
-        LedTopMap = new HashMap< Integer , Integer >(); //key: ecal channel ID. Value:  led id
-        LedBotMap = new HashMap< Integer , Integer >();	
-
-        LedTopMapInverted = new HashMap< Integer , Integer >(); //key: led id. Value: ecal channel id
-        LedBotMapInverted = new HashMap< Integer , Integer >(); 
-
-
-        ChannelCollection = conditionsManager.getCachedConditions(EcalChannelCollection.class, "ecal_channels").getCachedData();	
-        LedCollection = conditionsManager.getCachedConditions(EcalLedCollection.class, "ecal_leds").getCachedData();
-        ecalConditions = conditionsManager.getEcalConditions();		
-
-        for (EcalChannel channel : ChannelCollection){
-            chid = channel.getChannelId();
-            for (EcalLed Led : LedCollection) {    	
-                if (Led.getEcalChannelId()==chid){
-                    if (channel.getY()>0){
-                        LedTopMap.put( chid , Led.getLedNumber() );
-                        LedTopMapInverted.put(  Led.getLedNumber(), chid  );
-                    }
-                    else if (channel.getY()<0){
-                        LedBotMap.put( chid , Led.getLedNumber() );
-                        LedBotMapInverted.put( Led.getLedNumber(), chid );                    
-                    }
-                }
-            }
-        }
-
-    
-        
-        // Setup plots
-        aida = AIDA.defaultInstance();
-        aida.tree().cd("/");
-        hMeanCharge2D = aida.histogram2D("Average LED response", 47, -23.5, 23.5, 11, -5.5, 5.5);
-        
-        factory= aida.analysisFactory().createPlotterFactory("Ecal Led Sequence");
-        pPlotter= factory.create("Drivers");
-        pPlotter.createRegions(4,2);
-        if (isMonitoringApp){
-            pPlotter2=factory.create("Sequence Map");
-            pPlotter2.createRegions(1,1);
-            pPlotter2.region(0).plot(hMeanCharge2D);
-        }   
-        iTuple = new ArrayList<ITuple>(NUM_CHANNELS);   
-        hCharge = new ArrayList<IHistogram1D>(NUM_CHANNELS);
-        hChargeVsEvn = new ArrayList<IHistogram2D>(nDrivers);
-
-
-
-        //pPlotter2.region(0).plot(hMeanCharge2D);
-        
-        for (int ii=0;ii<NUM_CHANNELS;ii++){
-            int row = EcalMonitoringUtilities.getRowFromHistoID(ii);
-            int column = EcalMonitoringUtilities.getColumnFromHistoID(ii);	    
-            iTuple.add(aida.analysisFactory().createTupleFactory(aida.tree()).create("nTuple"+ii,"nTuple"+ii,"int fEvn=0 , double fCharge=0.,double fTime=0.",""));
-        }
-
-        for (int ii=0;ii<nDrivers;ii++){
-            hChargeVsEvn.add(aida.histogram2D("Driver"+ii,100,fEvnMinDraw,fEvnMaxDraw,100,fChargeMinDraw,fChargeMaxDraw));
-            pPlotter.region(ii).plot( hChargeVsEvn.get(ii));
-        }
-
-        pPlotter.show();
-        if (isMonitoringApp) pPlotter2.show();
-
-    }		
-
-    @Override
-    public void process(EventHeader event) {
-        runNumber = event.getRunNumber();
-        eventN++;
-        if (event.hasCollection(CalorimeterHit.class, inputCollection)) {
-            //List<BassRawCalorimeterHit> hits = event.get(BaseRawCalorimeterHit.class, inputCollectionRaw);
-            List<CalorimeterHit> hits = event.get(CalorimeterHit.class, inputCollection);
-            for (CalorimeterHit hit : hits) {
-
-                column = hit.getIdentifierFieldValue("ix");
-                row = hit.getIdentifierFieldValue("iy");
-                id = EcalMonitoringUtilities.getHistoIDFromRowColumn(row, column);
-                cellID=hit.getCellID();        
-                chid = ChannelCollection.findGeometric(cellID).getChannelId();
-
-                energy = hit.getCorrectedEnergy();
-                if (useRawEnergy){
-                    fillEnergy = getRawADCSum(energy,cellID);
-                }
-                else {
-                    fillEnergy = energy;
-                }
-                fillTime = hit.getTime();
-
-
-                //find the LED
-                if (row>0){
-                    ledid=LedTopMap.get(chid);
-                }
-                else if (row<0){
-                    ledid=LedBotMap.get(chid);
-                }
-                driverid=getDriver(ledid);
-                if (row<0) driverid+=4;
-
-
-                                
-                /*Skip the events under thr*/
-                if (energy<energyCut) continue;
-
-                /*First, check if this led is the one in the NEXT step. Therefore, increment by 1 the step*/
-                if (iStep[driverid]<(nSteps-1)){
-                    if (ledid==LEDStep[driverid][iStep[driverid]+1]){   
-                        iStep[driverid]++;
-                        System.out.println("LedAnalysis:: increment step ("+iStep[driverid]+") for driver "+driverid+" . Led ID: "+ledid+" Column: "+column+" Row: "+row);
-                        if (iStep[driverid]>0) drawProfiles(LEDStep[driverid][iStep[driverid]-1],driverid);      
-                    }	
-                }
-
-
-                if (iStep[driverid]==-1) continue;
-                
-                /*Put this code here, since we want to always fill the ntuple*/
-                iTuple.get(id).fill(0,nEvents[id]);
-                iTuple.get(id).fill(1,fillEnergy);
-                iTuple.get(id).fill(2,fillTime);
-                iTuple.get(id).addRow();
-                nEvents[id]++;
-                
-                /*Case 1: this led is the one in the corresponding step*/;
-                if (ledid==LEDStep[driverid][iStep[driverid]]){
-                    
-                }
-                else{	/*Case 2: this led is not one in the corresponding step (but maybe is the neighborhood??Ctalk??)*/;
-
-                }
-
-                /*Add a debug print */
-                if (eventN % 10000==0){
-                    System.out.println("Debug. LED ID: "+ledid+" DRIVER ID: "+driverid+" ECAL ID: "+id+" ROW: "+row+" COLUMN: "+column+ "HISTO ID: "+id);
-                }
-            }
-            if (eventN % 10000==0){
-                System.out.println("\n");
-            }
-        }		
-    }
-
-    /*
-     * The endOfData() method analises each ntuple to find the LED response.
-     * We cannot simply fit a gaussian to the energy distribution, since there is a high-energy tail due to the LED being turned on:
-     * When the LED turns on, it is "cold", and emits more light. Immediately, it starts to heat, and due to temperature effects the
-     * emitted light is less. This is clearly visible if one plots the charge VS the event number: the trend is decreasing, toward a
-     * plateau, that corresponds to the value at thermal equilibrium.
-     * 
-     * For (few) channels, the first charge values are close to 0, then charge grows rapidly, then it returns back to the plateau.
-     * To handle these, I always cut the first 10% events
-     * To properly handle this:
-     * 
-     * 1) First create a profile histogram, charge VS event number.
-     * 2) Fit it with something like "A*exp(-event_number/N0)+C. The function does not need to be extra-accurate at this stage
-     * 3) Cut the events with event_number < 5*N0.
-     * 4) Fit the remaining events with a gaussian.
-     */
-    @Override
-    public void endOfData() {
-        System.out.println("LedAnalysis::end of data");
-        System.out.println("LedAnalysis:: nEventsMin is: "+nEventsMin);
-
-        double e,eMin,eMax;
-        double t;
-        int n,nBins,nFits,nSkip;
-        
-       
-        IFunctionFactory fFactory=aida.analysisFactory().createFunctionFactory(aida.tree());
-
-        IFitResult fResult;
-        IFitter	   fFitter;
-
-        for (int id = 0; id < 11 * 47; id++) {
-
-            eMin=9999;
-            eMax=-9999;
-            row = EcalMonitoringUtilities.getRowFromHistoID(id);
-            column = EcalMonitoringUtilities.getColumnFromHistoID(id);
-            System.out.println("");
-            System.out.println("Doing channel: X= "+column+" Y= "+row);
-            System.out.println("Number of entries in analysis ntuple: "+iTuple.get(id).rows());
-            System.out.println("Number of recognized events: "+nEvents[id]);
-            /*Create the profile. Create it for all the channels, to keep sync.*/
-            nBins=nEvents[id]/100;
-            if (nBins<=0) nBins=1;
-
-            /*Clear previous*/
-
-            if (id>0){
-                aida.tree().rm("strip");
-                aida.tree().rm("fun0");
-                aida.tree().rm("fun1");
-            }
-            /*Create the profile.*/
-            cProfile=aida.profile1D("strip",nBins,-0.5,nEvents[id]*(1-skipInitial)+0.5);
-            cProfile.reset();
-            /*Create the function for the profile fit and the gaus fit*/
-            fFunction=fFactory.createFunctionFromScript("fun0",1,"A*exp(-x[0]/tau)+B","A,tau,B","",null);
-            fFunction1=fFactory.createFunctionByName("fun1","G");
-
-            if (EcalMonitoringUtilities.isInHole(row,column)==true){
-            	System.out.println("Channel X= "+column+" Y= "+row+" is in hole. Skip");
-                hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
-                System.out.println("In hole, skip");
-                continue;
-            }
-            else if (nEvents[id]<nEventsMin) {
-                hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
-                System.err.println("LedAnalysis:: the channel X= "+column+" Y= "+row+" has not enough events "+nEvents[id]+" "+nEventsMin);
-                
-                continue;
-            }			  
-
-            //Fill the profile*/
-            nSkip=(int)(nEvents[id]*skipInitial);
-            if (nSkip>iTuple.get(id).rows()){
-                System.out.println("Can't skip initial events?");
-                nSkip=0;
-            }
-            iTuple.get(id).start();
-            iTuple.get(id).skip(nSkip); //This is the work-around for those channels with charge starting from 0 and rapidly growing//
-            n=0;
-            iTuple.get(id).next(); 
-            while ( iTuple.get(id).next() ){
-                e=iTuple.get(id).getDouble(1);
-                if (e<eMin) eMin=e;           			  
-                if (e>eMax) eMax=e;
-                cProfile.fill(1.*n,e);
-                n++;
-            }			
-            fFitter=aida.analysisFactory().createFitFactory().createFitter("chi2","","v");
-            
-            if (doFullAnalysis){ 
-                //Init function parameters
-                double[] initialPars={eMax-eMin,nEvents[id]/10.,eMin};
-                if (initialPars[0]<0) initialPars[0]=0;
-                fFunction.setParameters(initialPars);
-                
-                //Do the fit      
-                System.out.println("LedAnalysis:: do profile fit "+id+" "+fFitter.engineName()+" "+fFitter.fitMethodName());
-                System.out.println("LedAnalysis:: initial parameters "+initialPars[0]+" "+initialPars[1]+" "+initialPars[2]);
-                fResult=fFitter.fit(cProfile,fFunction);
-                fPars     = fResult.fittedParameters();
-                fParErrs  = fResult.errors();
-                fParNames = fResult.fittedParameterNames();			
-                System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
-                for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
-                    System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
-                }  
-                fFunction.setParameters(fPars);
-                
-                
-                //Do again the fit: it is a terrible work-around
-                nFits=0;
-                if (Double.isNaN(fParErrs[1])){
-                    fPars=fPrevPars;
-                }
-                while (Double.isNaN(fParErrs[1])){
-                    System.out.println("LedAnalysis:: redo fit");
-                    fFunction.setParameters(fPars);
-                    fResult=fFitter.fit(cProfile,fFunction);
-                    fPars     = fResult.fittedParameters();
-                    fParErrs  = fResult.errors();
-                    System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
-                    for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
-                        System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
-                    }  
-                    fFunction.setParameters(fPars);
-                    nFits++;
-                    if (nFits>=10){
-                        System.out.println("LedAnalysis:: Error, too many fits without convergence");
-                        break;
-                    }
-                }
-                fPrevPars=Arrays.copyOf(fPars,fPars.length);
-                System.out.println("LedAnalysis:: fit "+id+" done");  
-                
-                //Now we have the tau parameter. Take ONLY the events that are with N>5*tau/
-                //As a cross-check, also verify that tau > Nevents/10, otherwise skip the first Nevents/2
-                //and emit warning
-                nSkip=(int)( fPars[1]*5);
-                if (nSkip < (nEvents[id]*skipMin)){
-                    System.out.println("LedAnalysis:: Skip number too low: "+nSkip+" Increment it to "+nEvents[id]/2);
-                    nSkip=(int)(nEvents[id]*skipMin);
-                }
-                if (nSkip > nEvents[id]){
-                    System.out.println("LedAnalysis:: Skip number too high, reduce it");
-                    nSkip=(int)(nEvents[id]*skipMin);
-                }
-        
-            }
-            else{
-                nSkip=(int)(nEvents[id]*(skipMin+skipInitial));
-            }
-            
-            System.out.println("LedAnalysis:: gaus fit :: Going to skip "+nSkip+" out of "+nEvents[id]);
-            System.out.println("eMin is: "+eMin+" eMax is: "+eMax);
-            hCharge.add(aida.histogram1D("charge_"+id,200,eMin*0.9,eMax*1.1));
-       
-         
-            iTuple.get(id).start();
-            iTuple.get(id).skip(nSkip); 
-            n=0;
-            while (iTuple.get(id).next()){
-                e=iTuple.get(id).getDouble(1);
-                t=iTuple.get(id).getDouble(2);
-                hCharge.get(id).fill(e);
-                n++;
-            }			
-
-            /*Finally do the fit with the gaussian*/
-            double[] initialPars1={hCharge.get(id).maxBinHeight(),hCharge.get(id).mean(),hCharge.get(id).rms()};
-
-            System.out.println("LedAnalysis:: Gaus fit");
-            System.out.println("LedAnalysis:: initial parameters "+initialPars1[0]+" "+initialPars1[1]+" "+initialPars1[2]);
-
-            fFunction1.setParameters(initialPars1);
-            fResult=fFitter.fit(hCharge.get(id),fFunction1);
-            fPars     = fResult.fittedParameters();
-            fParErrs  = fResult.errors();
-            fParNames = fResult.fittedParameterNames();			
-            System.out.println("Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
-            for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
-                System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
-            }  
-            fFunction1.setParameters(fPars);
-            mMean[id]=fPars[1];
-            mRMS[id]=fPars[2];
-
-            hMeanCharge2D.fill(column,row,mMean[id]);
-            System.out.println("\n");
-        }//End loop on channels
-
-
-
-        if ((pPlotter2!=null)&&(isMonitoringApp)){
-            style = pPlotter2.region(0).style();
-            style.setParameter("hist2DStyle", "colorMap");
-            style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-            style.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); 
-            pPlotter2.region(0).plot(hMeanCharge2D);
-            pPlotter2.region(0).refresh();
-        }
-        else{
-            IPlotterStyle pstyle =  aida.analysisFactory().createPlotterFactory().createPlotterStyle();
-            pPlotter2 = null;
-            pPlotter2 =  aida.analysisFactory().createPlotterFactory().create();
-            pstyle.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
-            pstyle.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString());
-            pstyle.setParameter("hist2DStyle", "colorMap");
-            if (pPlotter2!=null){
-                pPlotter2.createRegion().plot(hMeanCharge2D,pstyle);
-                pPlotter2.show();
-            }
-        }
-
-
-
-        
-        /*
-        Console cc = System.console();
-        if (cc == null) {
-            System.err.println("No console.");
-        }
-        else{
-            String userInput="";
-            System.out.println("Enter 'YES' - case sensitive - to write conditions database for run range "+runNumber+" - "+runNumberMax);
-            System.out.println("Use the monitoring app (Led sequence - Sequence Map) to look at the current sequence");
-            userInput=cc.readLine(String.format("Your choice: YES or NO?"));
-            System.out.println("***********"+userInput+"********");
-            if (userInput!=null && userInput.equals("YES")) {
-                userInput=cc.readLine("Really?");
-                if (userInput!=null && userInput.equals("YES")) {
-                   m_ret=1;
-                }
-            }
-            
-        }*/
-        askUploadToDBDialog();
-        synchronized (modalMonitor) {
-            try{
-            modalMonitor.wait(120000); //wait 2 minutes for user interaction.
-            }
-            catch(InterruptedException excp){
-                System.out.println("Got exception: "+excp);
-            }
-        }
-        if (m_ret==1){
-            System.out.println("OK, upload to DB");
-            try {
-            	uploadToDB();
-            } catch (SQLException | DatabaseObjectException | ConditionsObjectException error) {
-            	throw new RuntimeException("Error uploading to the database.", error);
-            }
-            if (isMonitoringApp){
-                System.out.println("Save an Elog too");
-                uploadToElog();
-            }
-        }
-       System.out.println("endOfData end");
-       System.out.println("The program is not stucked. It is writing the output AIDA file, this takes time!");
-    }/*End endOfData*/
-
-
-    /**
-     * This function returns the driver number (from 0 to 3) given the LED id.
-     * @param led
-     * @return
-     */
-    public int getDriver(int led){
-        int ret=-1;	
-        if ((led>=2)&&(led<56)) ret=0;
-        else if ((led>=56)&&(led<112)) ret=1;
-        else if ((led>=112)&&(led<168)) ret=2;
-        else if ((led>=168)&&(led<224)) ret=3;
-        return ret;
-    }
-
-    /**
-     * Very simple method to retreive the pedestal-subtracted raw Energy.
-     * If the gain changes (because we do a re-calibration), I do not want to include this in the LED analysis
-     * @param energy
-     * @param cellID
-     * @return
-     */
-    public double getRawADCSum(double energy,long cellID){
-        EcalChannelConstants channelData = ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
-        double RawSum=energy / EcalUtils.GeV;
-        double gain=channelData.getGain().getGain();
-        double ret=RawSum/gain;
-        //  System.out.println("A:C "+RawSum+" "+ret);
-
-        return ret;
-
-    }
-
-    private void uploadToDB() throws DatabaseObjectException, ConditionsObjectException, SQLException {
-        int x,y,id;
-        double mean,rms;
-        System.out.println(String.format("Uploading new led data to the database, runMin=%d, runMax=%d, tag=%s ....",
-                runNumber,runNumberMax,dbTag));
-
-        EcalLedCalibrationCollection led_calibrations =  new EcalLedCalibrationCollection();
-
-        TableMetaData tableMetaData = conditionsManager.findTableMetaData(dbTableName);
-        led_calibrations.setTableMetaData(tableMetaData);
-
-        for (int cid = 1; cid <= 442; cid++) {/*This is a loop over the channel ID, as in the conditions system*/
-            EcalChannel cc = findChannel(cid);
-            x = cc.getX(); //This is the column
-            y = cc.getY(); //This is the row
-            id=EcalMonitoringUtilities.getHistoIDFromRowColumn(y,x);
-            mean=mMean[id];
-            rms=mRMS[id];
-            led_calibrations.add(new EcalLedCalibration(cid,mean,rms));
-        }
-
-        int collectionId = -1;
-
-        try {
-            collectionId = conditionsManager.getCollectionId(led_calibrations, "loaded by EcalLedSequenceMonitor");
-        } catch (Exception e) {
-            throw new RuntimeException(e);
-        }
-        System.err.println("CollectionID:  "+collectionId);
-        led_calibrations.insert();
-        ConditionsRecord conditionsRecord = new ConditionsRecord(
-        		led_calibrations.getCollectionId(), runNumber, runNumberMax, dbTableName, dbTableName, 
-        		"Generated by LedAnalysis from Run #"+runNumber, dbTag);
-        conditionsRecord.insert();
-
-        System.out.println("Upload to DB done");
-    }
-    
-    private void uploadToElog(){
-        String path,exe,command,imgpath;
-        path="/home/hpsrun/LedSequenceData";
-        exe=path+"/doElog.csh";
-        imgpath=path+"/screenshots/"+runNumber+".png";
-        
-        File f=new File(path);
-        if (!f.exists()){
-            System.err.println("LedMonitoringSequence:: wrong path");
-            return;
-        }
-        if (pPlotter2==null){
-            System.err.println("LedMonitoringSquence:: no plotter");
-            return;
-        }
-        try{
-            pPlotter2.writeToFile(imgpath);
-        }
-        catch(Exception e){
-            System.err.println("Exception "+e);
-        }
-        File f1=new File(exe);
-        if (!f1.exists()){
-            System.err.println("LedMonitoringSequence:: no script!");
-            return;
-        }   
-        command=exe+" "+imgpath;
-        try{
-            System.out.println("LedMonitoringSequence:: try this command: "+command);
-            Runtime.getRuntime().exec(command);
-        }
-        catch(Exception e){
-            System.err.println("Exception "+e);
-        }
-    }
-    
-    
-    private void drawProfiles(int ledID,int driverID){
-
-        int m_column,m_row,m_ledID,m_chID,m_ID,m_driverID;
-
-        m_ledID = ledID;
-        m_driverID = driverID;
-        m_chID = 0;
-
-
-        if (m_driverID<=3) m_chID = LedTopMapInverted.get(ledID);
-        else m_chID = LedBotMapInverted.get(ledID);
-
-        m_column=findChannel(m_chID).getX();
-        m_row=findChannel(m_chID).getY();
-        m_ID=EcalMonitoringUtilities.getHistoIDFromRowColumn(m_row, m_column);
-        /* 
+	private static final int NUM_CHANNELS = 11 * 47;
+	private static final String dbTag = "led";
+	private static final String dbTableName = "ecal_led_calibrations";
+	private static final int runNumberMax = 9999;
+	private static final int nDrivers = 8;
+	private static final int nSteps = 56;
+
+	String inputCollectionRaw = "EcalReadoutHits";
+	String inputCollection = "EcalCalHits";	
+	AIDA aida;
+
+	DatabaseConditionsManager conditionsManager;
+
+	private EcalChannelCollection ChannelCollection;	
+	private EcalLedCollection LedCollection;
+	private EcalConditions ecalConditions;
+
+	Map < Integer,Integer > LedTopMap; //chid (conditions) --> LED id
+	Map < Integer,Integer > LedBotMap; //chid (conditions) --> LED id 
+
+	Map < Integer,Integer > LedTopMapInverted; //LED id --> chid (conditions)
+	Map < Integer,Integer > LedBotMapInverted; //LED id  --> chid (conditions)
+
+	private boolean useRawEnergy=false;
+
+	String outFileName;
+
+
+	private int runNumber = 0;	
+	private int eventN    = 0;
+	private int id,row,column,chid,ledid,driverid;
+	private  int[][] LEDStep = new int[][]{
+			//first 4 are the flasher1 sequence, TOP controller 
+			{2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,-1,-1},
+			{56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111},
+			{112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167,-1}, //missing 135 is ok
+			{168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223},
+			//second 4 are the flasher2 sequence, BOTTOM controller 
+			{2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,-1,-1},	
+			{56,57,58,59,60,61,62,63,64,65,66,67,68,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110,111,-1}, //missing 69 is OK
+			{112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,162,163,164,165,166,167},	
+			{168,169,170,171,172,173,174,175,176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,216,217,218,219,220,221,222,223},
+	};
+
+	private int[] iStep = new int[nDrivers];
+	private int[] nEvents = new int[NUM_CHANNELS];
+	private double[] mMean = new double[NUM_CHANNELS];
+	private double[] mRMS = new double[NUM_CHANNELS];
+
+	private int nEventsMin=200;
+	private int nMinChannelsWithEvents=350; 
+	private double energy,fillEnergy,fillTime;
+	private double energyCut=2; //we expect very high energy from the LEDs..
+	private double skipInitial=0.05;
+	private double skipMin=0.3;
+	private long cellID;
+
+
+
+
+	//Histograms-functions-ntuples
+	private ArrayList<ITuple> iTuple;
+
+	private IFunction  fFunction,fFunction1;
+	private IProfile1D   cProfile;
+	private IHistogram2D			hMeanCharge2D;
+	private ArrayList<IHistogram1D> hCharge;
+	private ArrayList<IHistogram2D> hChargeVsEvn;
+	private IPlotterFactory factory;
+	private IPlotter pPlotter=null;
+	private IPlotter pPlotter2=null;
+	private IPlotterStyle style ;
+	private int[] fitStatus = new int[NUM_CHANNELS];
+
+	private boolean doFullAnalysis=false;
+	private boolean isMonitoringApp=false; 
+
+	private double[] fPars;    
+	private double[] fPrevPars;
+	private double[] fParErrs;
+	private String[] fParNames; 
+
+
+	private double fEvnMinDraw=0.;
+	private double fEvnMaxDraw=80000.;
+	private double fChargeMinDraw=0.;
+	private double fChargeMaxDraw=100.;
+
+	/*Components for user interaction*/
+	private JDialog dialog;
+	private JLabel  label;
+	private JFrame frame;
+	private JPanel panel;
+	String  labelString;
+	private JButton okButton,cancelButton;
+	private int m_iteration=0;
+	private int m_ret=0;
+	static Object modalMonitor = new Object();
+
+	public void setUseRawEnergy(boolean useRawEnergy) {
+		this.useRawEnergy=useRawEnergy;
+	}
+
+	public void setEnergyCut(double energyCut) {
+		this.energyCut=energyCut;
+	}
+	public void setSkipInitial(double skipInitial) {
+		this.skipInitial=skipInitial;
+	}
+	public void setSkipMin(double skipMin) {
+		this.skipMin=skipMin;
+	}
+
+	public void setEvnMinDraw(double evnMinDraw){
+		this.fEvnMinDraw=evnMinDraw;
+	}
+	public void setEvnMaxDraw(double evnMaxDraw){
+		this.fEvnMaxDraw=evnMaxDraw;
+	}
+	public void setChargeMinDraw(double chargeMinDraw){
+		this.fChargeMinDraw=chargeMinDraw;
+	}
+	public void setChargeMaxDraw(double chargeMaxDraw){
+		this.fChargeMaxDraw=chargeMaxDraw;
+	}
+
+	public void setNEventsMin(int nEeventsMin){
+		this.nEventsMin=nEventsMin;
+	}
+
+	public void setIsMonitoringApp(boolean app){
+		this.isMonitoringApp=app;
+	}
+
+	public void setDoFullAnalysis(boolean fullAnalysis){
+		this.doFullAnalysis=fullAnalysis;
+	}
+
+	@Override
+	protected void detectorChanged(Detector detector) {
+		System.out.println("LedAnalysis::Detector changed was called");
+		System.out.println(fEvnMinDraw+" "+fEvnMaxDraw);
+		for (int ii=0;ii<nDrivers;ii++){
+			iStep[ii]=-1;
+		}
+
+		// Setup conditions
+
+		conditionsManager = DatabaseConditionsManager.getInstance();
+
+		LedTopMap = new HashMap< Integer , Integer >(); //key: ecal channel ID. Value:  led id
+		LedBotMap = new HashMap< Integer , Integer >();	
+
+		LedTopMapInverted = new HashMap< Integer , Integer >(); //key: led id. Value: ecal channel id
+		LedBotMapInverted = new HashMap< Integer , Integer >(); 
+
+
+		ChannelCollection = conditionsManager.getCachedConditions(EcalChannelCollection.class, "ecal_channels").getCachedData();	
+		LedCollection = conditionsManager.getCachedConditions(EcalLedCollection.class, "ecal_leds").getCachedData();
+		ecalConditions = conditionsManager.getEcalConditions();		
+
+		for (EcalChannel channel : ChannelCollection){
+			chid = channel.getChannelId();
+			for (EcalLed Led : LedCollection) {    	
+				if (Led.getEcalChannelId()==chid){
+					if (channel.getY()>0){
+						LedTopMap.put( chid , Led.getLedNumber() );
+						LedTopMapInverted.put(  Led.getLedNumber(), chid  );
+					}
+					else if (channel.getY()<0){
+						LedBotMap.put( chid , Led.getLedNumber() );
+						LedBotMapInverted.put( Led.getLedNumber(), chid );                    
+					}
+				}
+			}
+		}
+
+
+
+		// Setup plots
+		aida = AIDA.defaultInstance();
+		aida.tree().cd("/");
+		hMeanCharge2D = aida.histogram2D("Average LED response", 47, -23.5, 23.5, 11, -5.5, 5.5);
+
+		factory= aida.analysisFactory().createPlotterFactory("Ecal Led Sequence");
+		pPlotter= factory.create("Drivers");
+		pPlotter.createRegions(4,2);
+		if (isMonitoringApp){
+			pPlotter2=factory.create("Sequence Map");
+			pPlotter2.createRegions(1,1);
+			pPlotter2.region(0).plot(hMeanCharge2D);
+		}   
+		iTuple = new ArrayList<ITuple>(NUM_CHANNELS);   
+		hCharge = new ArrayList<IHistogram1D>(NUM_CHANNELS);
+		hChargeVsEvn = new ArrayList<IHistogram2D>(nDrivers);
+
+
+
+		//pPlotter2.region(0).plot(hMeanCharge2D);
+
+		for (int ii=0;ii<NUM_CHANNELS;ii++){
+			int row = EcalMonitoringUtilities.getRowFromHistoID(ii);
+			int column = EcalMonitoringUtilities.getColumnFromHistoID(ii);	    
+			iTuple.add(aida.analysisFactory().createTupleFactory(aida.tree()).create("nTuple"+ii,"nTuple"+ii,"int fEvn=0 , double fCharge=0.,double fTime=0.",""));
+		}
+
+		for (int ii=0;ii<nDrivers;ii++){
+			hChargeVsEvn.add(aida.histogram2D("Driver"+ii,100,fEvnMinDraw,fEvnMaxDraw,100,fChargeMinDraw,fChargeMaxDraw));
+			pPlotter.region(ii).plot( hChargeVsEvn.get(ii));
+		}
+
+		pPlotter.show();
+		if (isMonitoringApp) pPlotter2.show();
+
+	}		
+
+	@Override
+	public void process(EventHeader event) {
+		runNumber = event.getRunNumber();
+		eventN++;
+		if (event.hasCollection(CalorimeterHit.class, inputCollection)) {
+			//List<BassRawCalorimeterHit> hits = event.get(BaseRawCalorimeterHit.class, inputCollectionRaw);
+			List<CalorimeterHit> hits = event.get(CalorimeterHit.class, inputCollection);
+			for (CalorimeterHit hit : hits) {
+
+				column = hit.getIdentifierFieldValue("ix");
+				row = hit.getIdentifierFieldValue("iy");
+				id = EcalMonitoringUtilities.getHistoIDFromRowColumn(row, column);
+				cellID=hit.getCellID();        
+				chid = ChannelCollection.findGeometric(cellID).getChannelId();
+
+				energy = hit.getCorrectedEnergy();
+				if (useRawEnergy){
+					fillEnergy = getRawADCSum(energy,cellID);
+				}
+				else {
+					fillEnergy = energy;
+				}
+				fillTime = hit.getTime();
+
+
+				//find the LED
+				if (row>0){
+					ledid=LedTopMap.get(chid);
+				}
+				else if (row<0){
+					ledid=LedBotMap.get(chid);
+				}
+				driverid=getDriver(ledid);
+				if (row<0) driverid+=4;
+
+
+
+				/*Skip the events under thr*/
+				if (energy<energyCut) continue;
+
+				/*First, check if this led is the one in the NEXT step. Therefore, increment by 1 the step*/
+				if (iStep[driverid]<(nSteps-1)){
+					if (ledid==LEDStep[driverid][iStep[driverid]+1]){   
+						iStep[driverid]++;
+						System.out.println("LedAnalysis:: increment step ("+iStep[driverid]+") for driver "+driverid+" . Led ID: "+ledid+" Column: "+column+" Row: "+row);
+						if (iStep[driverid]>0) drawProfiles(LEDStep[driverid][iStep[driverid]-1],driverid);      
+					}	
+				}
+
+
+				if (iStep[driverid]==-1) continue;
+
+				/*Put this code here, since we want to always fill the ntuple*/
+				iTuple.get(id).fill(0,nEvents[id]);
+				iTuple.get(id).fill(1,fillEnergy);
+				iTuple.get(id).fill(2,fillTime);
+				iTuple.get(id).addRow();
+				nEvents[id]++;
+
+				/*Case 1: this led is the one in the corresponding step*/;
+				if (ledid==LEDStep[driverid][iStep[driverid]]){
+
+				}
+				else{	/*Case 2: this led is not one in the corresponding step (but maybe is the neighborhood??Ctalk??)*/;
+
+				}
+
+				/*Add a debug print */
+				if (eventN % 10000==0){
+					System.out.println("Debug. LED ID: "+ledid+" DRIVER ID: "+driverid+" ECAL ID: "+id+" ROW: "+row+" COLUMN: "+column+ "HISTO ID: "+id);
+				}
+			}
+			if (eventN % 10000==0){
+				System.out.println("\n");
+			}
+		}		
+	}
+
+	/*
+	 * The endOfData() method analises each ntuple to find the LED response.
+	 * We cannot simply fit a gaussian to the energy distribution, since there is a high-energy tail due to the LED being turned on:
+	 * When the LED turns on, it is "cold", and emits more light. Immediately, it starts to heat, and due to temperature effects the
+	 * emitted light is less. This is clearly visible if one plots the charge VS the event number: the trend is decreasing, toward a
+	 * plateau, that corresponds to the value at thermal equilibrium.
+	 * 
+	 * For (few) channels, the first charge values are close to 0, then charge grows rapidly, then it returns back to the plateau.
+	 * To handle these, I always cut the first 10% events
+	 * To properly handle this:
+	 * 
+	 * 1) First create a profile histogram, charge VS event number.
+	 * 2) Fit it with something like "A*exp(-event_number/N0)+C. The function does not need to be extra-accurate at this stage
+	 * 3) Cut the events with event_number < 5*N0.
+	 * 4) Fit the remaining events with a gaussian.
+	 */
+	@Override
+	public void endOfData() {
+		System.out.println("LedAnalysis::end of data");
+		System.out.println("LedAnalysis:: nEventsMin is: "+nEventsMin);
+
+		double e,eMin,eMax;
+		double t;
+		int n,nBins,nFits,nSkip;
+
+		int row, column;
+
+		String hName; 
+		IFunctionFactory fFactory=aida.analysisFactory().createFunctionFactory(aida.tree());
+
+		IFitResult fResult;
+		IFitter	   fFitter;
+
+		for (int id = 0; id < 11 * 47; id++) {
+
+			eMin=9999;
+			eMax=-9999;
+			row = EcalMonitoringUtilities.getRowFromHistoID(id);
+			column = EcalMonitoringUtilities.getColumnFromHistoID(id);
+			System.out.println("");
+			System.out.println("Doing channel: X= "+column+" Y= "+row);
+			System.out.println("Number of entries in analysis ntuple: "+iTuple.get(id).rows());
+			System.out.println("Number of recognized events: "+nEvents[id]);
+			/*Create the profile. Create it for all the channels, to keep sync.*/
+			nBins=nEvents[id]/100;
+			if (nBins<=0) nBins=1;
+
+			/*Clear previous*/
+
+			if (id>0){
+				aida.tree().rm("strip");
+				aida.tree().rm("fun0");
+				aida.tree().rm("fun1");
+			}
+			/*Create the profile.*/
+			cProfile=aida.profile1D("strip",nBins,-0.5,nEvents[id]*(1-skipInitial)+0.5);
+			cProfile.reset();
+			/*Create the function for the profile fit and the gaus fit*/
+			fFunction=fFactory.createFunctionFromScript("fun0",1,"A*exp(-x[0]/tau)+B","A,tau,B","",null);
+			fFunction1=fFactory.createFunctionByName("fun1","G");
+
+			if (EcalMonitoringUtilities.isInHole(row,column)==true){
+				System.out.println("Channel X= "+column+" Y= "+row+" is in hole. Skip");
+				hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
+				System.out.println("In hole, skip");
+				continue;
+			}
+			else if (nEvents[id]<nEventsMin) {
+				hCharge.add(aida.histogram1D("charge_"+id,200,0.,1.)); //create here the histogram to keep sync
+				System.err.println("LedAnalysis:: the channel X= "+column+" Y= "+row+" has not enough events "+nEvents[id]+" "+nEventsMin);
+
+				continue;
+			}			  
+
+			//Fill the profile*/
+			nSkip=(int)(nEvents[id]*skipInitial);
+			if (nSkip>iTuple.get(id).rows()){
+				System.out.println("Can't skip initial events?");
+				nSkip=0;
+			}
+			iTuple.get(id).start();
+			iTuple.get(id).skip(nSkip); //This is the work-around for those channels with charge starting from 0 and rapidly growing//
+			n=0;
+			iTuple.get(id).next(); 
+			while ( iTuple.get(id).next() ){
+				e=iTuple.get(id).getDouble(1);
+				if (e<eMin) eMin=e;           			  
+				if (e>eMax) eMax=e;
+				cProfile.fill(1.*n,e);
+				n++;
+			}			
+			fFitter=aida.analysisFactory().createFitFactory().createFitter("chi2","","v");
+
+			if (doFullAnalysis){ 
+				//Init function parameters
+				double[] initialPars={eMax-eMin,nEvents[id]/10.,eMin};
+				if (initialPars[0]<0) initialPars[0]=0;
+				fFunction.setParameters(initialPars);
+
+				//Do the fit      
+				System.out.println("LedAnalysis:: do profile fit "+id+" "+fFitter.engineName()+" "+fFitter.fitMethodName());
+				System.out.println("LedAnalysis:: initial parameters "+initialPars[0]+" "+initialPars[1]+" "+initialPars[2]);
+				fResult=fFitter.fit(cProfile,fFunction);
+				fPars     = fResult.fittedParameters();
+				fParErrs  = fResult.errors();
+				fParNames = fResult.fittedParameterNames();			
+				System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
+				for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
+					System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
+				}  
+				fFunction.setParameters(fPars);
+
+
+				//Do again the fit: it is a terrible work-around
+				nFits=0;
+				if (Double.isNaN(fParErrs[1])){
+					fPars=fPrevPars;
+				}
+				while (Double.isNaN(fParErrs[1])){
+					System.out.println("LedAnalysis:: redo fit");
+					fFunction.setParameters(fPars);
+					fResult=fFitter.fit(cProfile,fFunction);
+					fPars     = fResult.fittedParameters();
+					fParErrs  = fResult.errors();
+					System.out.println("LedAnalysis:: Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
+					for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
+						System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
+					}  
+					fFunction.setParameters(fPars);
+					nFits++;
+					if (nFits>=10){
+						System.out.println("LedAnalysis:: Error, too many fits without convergence");
+						break;
+					}
+				}
+				fPrevPars=Arrays.copyOf(fPars,fPars.length);
+				System.out.println("LedAnalysis:: fit "+id+" done");  
+
+				//Now we have the tau parameter. Take ONLY the events that are with N>5*tau/
+				//As a cross-check, also verify that tau > Nevents/10, otherwise skip the first Nevents/2
+				//and emit warning
+				nSkip=(int)( fPars[1]*5);
+				if (nSkip < (nEvents[id]*skipMin)){
+					System.out.println("LedAnalysis:: Skip number too low: "+nSkip+" Increment it to "+nEvents[id]/2);
+					nSkip=(int)(nEvents[id]*skipMin);
+				}
+				if (nSkip > nEvents[id]){
+					System.out.println("LedAnalysis:: Skip number too high, reduce it");
+					nSkip=(int)(nEvents[id]*skipMin);
+				}
+
+			}
+			else{
+				nSkip=(int)(nEvents[id]*(skipMin+skipInitial));
+			}
+
+			System.out.println("LedAnalysis:: gaus fit :: Going to skip "+nSkip+" out of "+nEvents[id]);
+			System.out.println("eMin is: "+eMin+" eMax is: "+eMax);
+			hCharge.add(aida.histogram1D("charge_"+id,200,eMin*0.9,eMax*1.1));
+
+
+			iTuple.get(id).start();
+			iTuple.get(id).skip(nSkip); 
+			n=0;
+			while (iTuple.get(id).next()){
+				e=iTuple.get(id).getDouble(1);
+				t=iTuple.get(id).getDouble(2);
+				hCharge.get(id).fill(e);
+				n++;
+			}			
+
+			/*Finally do the fit with the gaussian*/
+			double[] initialPars1={hCharge.get(id).maxBinHeight(),hCharge.get(id).mean(),hCharge.get(id).rms()};
+
+			System.out.println("LedAnalysis:: Gaus fit");
+			System.out.println("LedAnalysis:: initial parameters "+initialPars1[0]+" "+initialPars1[1]+" "+initialPars1[2]);
+
+			fFunction1.setParameters(initialPars1);
+			fResult=fFitter.fit(hCharge.get(id),fFunction1);
+			fPars     = fResult.fittedParameters();
+			fParErrs  = fResult.errors();
+			fParNames = fResult.fittedParameterNames();			
+			System.out.println("Status= "+fResult.fitStatus()+" "+fResult.isValid()+" Chi2 = "+fResult.quality()+" NDF: "+fResult.ndf());
+			for(int i=0; i< fResult.fittedFunction().numberOfParameters(); i++ ){
+				System.out.println(fParNames[i]+" : "+fPars[i]+" +- "+fParErrs[i]);
+			}  
+			fFunction1.setParameters(fPars);
+			mMean[id]=fPars[1];
+			mRMS[id]=fPars[2];
+
+			hMeanCharge2D.fill(column,row,mMean[id]);
+			System.out.println("\n");
+		}//End loop on channels
+
+
+
+		if ((pPlotter2!=null)&&(isMonitoringApp)){
+			style = pPlotter2.region(0).style();
+			style.setParameter("hist2DStyle", "colorMap");
+			style.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+			style.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString()); 
+			pPlotter2.region(0).plot(hMeanCharge2D);
+			pPlotter2.region(0).refresh();
+		}
+		else{
+			IPlotterStyle pstyle =  aida.analysisFactory().createPlotterFactory().createPlotterStyle();
+			pPlotter2 = null;
+			pPlotter2 =  aida.analysisFactory().createPlotterFactory().create();
+			pstyle.dataStyle().fillStyle().setParameter("colorMapScheme", "rainbow");
+			pstyle.dataStyle().fillStyle().setParameter("showZeroHeightBins", Boolean.FALSE.toString());
+			pstyle.setParameter("hist2DStyle", "colorMap");
+			if (pPlotter2!=null){
+				pPlotter2.createRegion().plot(hMeanCharge2D,pstyle);
+				pPlotter2.show();
+			}
+		}
+
+
+		askUploadToDBDialog();
+		synchronized (modalMonitor) {
+			try{
+				modalMonitor.wait(120000); //wait 2 minutes for user interaction.
+			}
+			catch(InterruptedException excp){
+				System.out.println("Got exception: "+excp);
+			}
+		}
+		if (m_ret==1){
+			System.out.println("OK, upload to DB");
+			try {
+				uploadToDB();
+			} catch (SQLException | DatabaseObjectException | ConditionsObjectException error) {
+				throw new RuntimeException("Error uploading to the database.", error);
+			}
+			if (isMonitoringApp){
+				System.out.println("Save an Elog too");
+				uploadToElog();
+			}
+		}
+
+		/*Write a file with the LED values*/
+		try {
+			if (useRawEnergy){
+				outFileName=runNumber+".raw.txt";
+			}
+			else{
+				outFileName=runNumber+".energy.txt";
+			}
+			PrintWriter writer = new PrintWriter(outFileName, "UTF-8");
+
+
+			for (int id = 0; id < 11 * 47; id++) {
+
+				row = EcalMonitoringUtilities.getRowFromHistoID(id);
+				column = EcalMonitoringUtilities.getColumnFromHistoID(id);
+				if (EcalMonitoringUtilities.isInHole(row, column)) continue;
+				if ((row == 0) || (column == 0)) continue;
+
+				writer.print(column+" "+row+" "+" "+ mMean[id]+" "+mRMS[id]+"\r\n");
+
+			}
+			writer.close();
+
+		} 
+		catch (FileNotFoundException fnfe) {
+
+			System.out.println(fnfe.getMessage());
+
+		}
+
+		catch (IOException ioe) {
+
+			System.out.println(ioe.getMessage());
+
+		}
+
+
+		System.out.println("EcalLedSequenceMonitor endOfData clear histograms"); 
+		for(int ii = 0; ii < NUM_CHANNELS; ii++) {   	
+			row=EcalMonitoringUtilities.getRowFromHistoID(ii);
+			column = EcalMonitoringUtilities.getColumnFromHistoID(ii);      	  
+			hName="charge_"+ii;	 
+			aida.tree().rm(hName);
+			/*aida.tree().add(iTuple.get(ii));*/
+		}
+		System.out.println("EcalLedSequenceMonitor endOfData clear histograms done");   
+		System.out.println("endOfData end");
+		System.out.println("The program is not stucked. It is writing the output AIDA file, this takes time!");
+	}/*End endOfData*/
+
+
+	/**
+	 * This function returns the driver number (from 0 to 3) given the LED id.
+	 * @param led
+	 * @return
+	 */
+	public int getDriver(int led){
+		int ret=-1;	
+		if ((led>=2)&&(led<56)) ret=0;
+		else if ((led>=56)&&(led<112)) ret=1;
+		else if ((led>=112)&&(led<168)) ret=2;
+		else if ((led>=168)&&(led<224)) ret=3;
+		return ret;
+	}
+
+	/**
+	 * Very simple method to retreive the pedestal-subtracted raw Energy.
+	 * If the gain changes (because we do a re-calibration), I do not want to include this in the LED analysis
+	 * @param energy
+	 * @param cellID
+	 * @return
+	 */
+	public double getRawADCSum(double energy,long cellID){
+		EcalChannelConstants channelData = ecalConditions.getChannelConstants(ecalConditions.getChannelCollection().findGeometric(cellID));
+		double RawSum=energy / EcalUtils.GeV;
+		double gain=channelData.getGain().getGain();
+		double ret=RawSum/gain;
+		//  System.out.println("A:C "+RawSum+" "+ret);
+		return ret;
+	}
+
+	private void uploadToDB() throws DatabaseObjectException, ConditionsObjectException, SQLException {
+		int x,y,id;
+		double mean,rms;
+		System.out.println(String.format("Uploading new led data to the database, runMin=%d, runMax=%d, tag=%s ....",
+				runNumber,runNumberMax,dbTag));
+
+		EcalLedCalibrationCollection led_calibrations =  new EcalLedCalibrationCollection();
+
+		TableMetaData tableMetaData = conditionsManager.findTableMetaData(dbTableName);
+		led_calibrations.setTableMetaData(tableMetaData);
+
+		for (int cid = 1; cid <= 442; cid++) {/*This is a loop over the channel ID, as in the conditions system*/
+			EcalChannel cc = findChannel(cid);
+			x = cc.getX(); //This is the column
+			y = cc.getY(); //This is the row
+			id=EcalMonitoringUtilities.getHistoIDFromRowColumn(y,x);
+			mean=mMean[id];
+			rms=mRMS[id];
+			led_calibrations.add(new EcalLedCalibration(cid,mean,rms));
+		}
+
+		int collectionId = -1;
+
+		try {
+			collectionId = conditionsManager.getCollectionId(led_calibrations, "loaded by EcalLedSequenceMonitor");
+		} catch (Exception e) {
+			throw new RuntimeException(e);
+		}
+		System.err.println("CollectionID:  "+collectionId);
+		led_calibrations.insert();
+		ConditionsRecord conditionsRecord = new ConditionsRecord(
+				led_calibrations.getCollectionId(), runNumber, runNumberMax, dbTableName, dbTableName, 
+				"Generated by LedAnalysis from Run #"+runNumber, dbTag);
+		conditionsRecord.insert();
+
+		System.out.println("Upload to DB done");
+	}
+
+	private void uploadToElog(){
+		String path,exe,command,imgpath;
+		path="/home/hpsrun/LedSequenceData";
+		exe=path+"/doElog.csh";
+		imgpath=path+"/screenshots/"+runNumber+".png";
+
+		File f=new File(path);
+		if (!f.exists()){
+			System.err.println("LedMonitoringSequence:: wrong path");
+			return;
+		}
+		if (pPlotter2==null){
+			System.err.println("LedMonitoringSquence:: no plotter");
+			return;
+		}
+		try{
+			pPlotter2.writeToFile(imgpath);
+		}
+		catch(Exception e){
+			System.err.println("Exception "+e);
+		}
+		File f1=new File(exe);
+		if (!f1.exists()){
+			System.err.println("LedMonitoringSequence:: no script!");
+			return;
+		}   
+		command=exe+" "+imgpath;
+		try{
+			System.out.println("LedMonitoringSequence:: try this command: "+command);
+			Runtime.getRuntime().exec(command);
+		}
+		catch(Exception e){
+			System.err.println("Exception "+e);
+		}
+	}
+
+
+	private void drawProfiles(int ledID,int driverID){
+
+		int m_column,m_row,m_ledID,m_chID,m_ID,m_driverID;
+
+		m_ledID = ledID;
+		m_driverID = driverID;
+		m_chID = 0;
+
+
+		if (m_driverID<=3) m_chID = LedTopMapInverted.get(ledID);
+		else m_chID = LedBotMapInverted.get(ledID);
+
+		m_column=findChannel(m_chID).getX();
+		m_row=findChannel(m_chID).getY();
+		m_ID=EcalMonitoringUtilities.getHistoIDFromRowColumn(m_row, m_column);
+		/* 
         System.out.println("Going to draw LED id "+m_ledID+" X= "+m_column+" Y= "+m_row+" driver: "+m_driverID);
         System.out.println("Ch_ID: "+m_chID);
         System.out.println("Histo ID:"+m_ID);
         System.out.println("Events: "+iTuple.get(m_ID).rows());
-         */      
-        hChargeVsEvn.get(m_driverID).reset();
-        hChargeVsEvn.get(m_driverID).setTitle("Driver_"+m_driverID+" Led_"+ledID);
-        IEvaluator evaluatorX = aida.analysisFactory().createTupleFactory(aida.analysisFactory().createTreeFactory().create()).createEvaluator("fEvn");
-        IEvaluator evaluatorY = aida.analysisFactory().createTupleFactory(aida.analysisFactory().createTreeFactory().create()).createEvaluator("fCharge");  
-
-        iTuple.get(m_ID).project(hChargeVsEvn.get(m_driverID),evaluatorX,evaluatorY);
-
-        pPlotter.region(m_driverID).clear();  
-        pPlotter.region(m_driverID).plot(hChargeVsEvn.get(m_driverID));
-        pPlotter.region(m_driverID).refresh();
-
-    }
-
-    private EcalChannel findChannel(int channel_id) {
-        return ecalConditions.getChannelCollection().findChannel(channel_id);
-    }
-
-
-    private void askUploadToDBDialog(){
-        m_ret=0;
-
-        okButton = new JButton("OK");
-        cancelButton = new JButton("Cancel");
-        labelString = "<html> Update conditions to DB <br> for run: <br> "+runNumber+" - "+runNumberMax+" <br> ???? <br> "
-                + "Use the monitoring app to look at the map<br>" 
-                + "(Tab LED sequence)<br"
-                +"Reply in 60 seconds<br>"+"</html>";   
-        label = new JLabel( labelString);
-            
-        frame  = new JFrame("Upload to DB?");
-        frame.setSize(500,250);
-        panel = new JPanel();
-        frame.add(panel);
-        
-        
-       // dialog = new JDialog((JFrame)null, "User selection");
-       // dialog.setSize(200,200);
-       // dialog.setLayout(new FlowLayout());
-       // dialog.add(label);
-       // dialog.add(cancelButton);
-       // dialog.add(okButton);
-       // dialog.setVisible(true);
-        //dialog.pack();
-        panel.add(label);
-        panel.add(cancelButton);
-        panel.add(okButton);
-        
-          frame.setVisible(true);
-        okButton.addActionListener(new ActionListener(){
-            public void actionPerformed(ActionEvent event)
-            {
-                m_ret=1;
-                frame.dispose();    
-                synchronized(modalMonitor)
-                {
-                    System.out.println("Ok pressed");
-                    modalMonitor.notify();
-                }
-            }
-        }
-                );
-
-        cancelButton.addActionListener(new ActionListener(){
-            public void actionPerformed(ActionEvent event)
-            {
-                m_ret=0;
-                frame.dispose();   
-                synchronized(modalMonitor)
-                {
-                    System.out.println("Cancel pressed");
-                    modalMonitor.notify();
-                }
-            }
-        }
-        );
-        
-        System.out.println("askUploadDB done");
-    }
-    
+		 */      
+		hChargeVsEvn.get(m_driverID).reset();
+		hChargeVsEvn.get(m_driverID).setTitle("Driver_"+m_driverID+" Led_"+ledID);
+		IEvaluator evaluatorX = aida.analysisFactory().createTupleFactory(aida.analysisFactory().createTreeFactory().create()).createEvaluator("fEvn");
+		IEvaluator evaluatorY = aida.analysisFactory().createTupleFactory(aida.analysisFactory().createTreeFactory().create()).createEvaluator("fCharge");  
+
+		iTuple.get(m_ID).project(hChargeVsEvn.get(m_driverID),evaluatorX,evaluatorY);
+
+		pPlotter.region(m_driverID).clear();  
+		pPlotter.region(m_driverID).plot(hChargeVsEvn.get(m_driverID));
+		pPlotter.region(m_driverID).refresh();
+
+	}
+
+	private EcalChannel findChannel(int channel_id) {
+		return ecalConditions.getChannelCollection().findChannel(channel_id);
+	}
+
+
+	private void askUploadToDBDialog(){
+		m_ret=0;
+
+		okButton = new JButton("OK");
+		cancelButton = new JButton("Cancel");
+		labelString = "<html> Update conditions to DB <br> for run: <br> "+runNumber+" - "+runNumberMax+" <br> ???? <br> "
+				+ "Use the monitoring app to look at the map<br>" 
+				+ "(Tab LED sequence)<br"
+				+"Reply in 60 seconds<br>"+"</html>";   
+		label = new JLabel( labelString);
+
+		frame  = new JFrame("Upload to DB?");
+		frame.setSize(500,250);
+		panel = new JPanel();
+		frame.add(panel);
+
+
+		// dialog = new JDialog((JFrame)null, "User selection");
+		// dialog.setSize(200,200);
+		// dialog.setLayout(new FlowLayout());
+		// dialog.add(label);
+		// dialog.add(cancelButton);
+		// dialog.add(okButton);
+		// dialog.setVisible(true);
+		//dialog.pack();
+		panel.add(label);
+		panel.add(cancelButton);
+		panel.add(okButton);
+
+		frame.setVisible(true);
+		okButton.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent event)
+			{
+				m_ret=1;
+				frame.dispose();    
+				synchronized(modalMonitor)
+				{
+					System.out.println("Ok pressed");
+					modalMonitor.notify();
+				}
+			}
+		}
+				);
+
+		cancelButton.addActionListener(new ActionListener(){
+			public void actionPerformed(ActionEvent event)
+			{
+				m_ret=0;
+				frame.dispose();   
+				synchronized(modalMonitor)
+				{
+					System.out.println("Cancel pressed");
+					modalMonitor.notify();
+				}
+			}
+		}
+				);
+
+		System.out.println("askUploadDB done");
+	}
+
 }