Esempio n. 1
0
bool NeutronProcessor::Process(RawEvent &event)
{
    if (!EventProcessor::Process(event))
        return false;

    static const vector<ChanEvent*> &scintNeutrEvents =
	event.GetSummary("scint:neutr")->GetList();

    for (vector<ChanEvent*>::const_iterator it = scintNeutrEvents.begin();
	 it != scintNeutrEvents.end(); it++) {

        ChanEvent *chan = *it;
        int loc = chan->GetChanID().GetLocation();
        double neutronEnergy = chan->GetCalEnergy();

        if (TreeCorrelator::get()->place("Beta")->status()) {
            plot(betaGated::D_ENERGY_DETX + loc, neutronEnergy);
        }
        if (TreeCorrelator::get()->place("Gamma")->status()) {
            plot(gammaGated::D_ENERGY_DETX + loc, neutronEnergy);
        }
        if (TreeCorrelator::get()->place("GammaBeta")->status()) {
            plot(betaGammaGated::D_ENERGY_DETX + loc, neutronEnergy);
        }
    }
    EndProcess();
    return true;
}
Esempio n. 2
0
bool IS600GeProcessor::Process(RawEvent &event) {
    using namespace dammIds::ge;

    if (!EventProcessor::Process(event))
        return false;

    // Call base class processing
    GeProcessor::Process(event);

    bool hasBeta = TreeCorrelator::get()->place("Beta")->status();
     double clockInSeconds = Globals::get()->clockInSeconds();
    // plot with 10 ms bins
    const double plotResolution = 10e-3 / clockInSeconds;
    double lastProtonTime =  TreeCorrelator::get()->place("mtc_t1_0")->last().time;

    for (vector<ChanEvent*>::iterator it1 = geEvents_.begin(); 
	 it1 != geEvents_.end(); ++it1) {
        ChanEvent *chan = *it1;
        
        double gEnergy = chan->GetCalEnergy();
        double gTime   = chan->GetCorrectedTime();
        //double decayTime = (gTime - cycleTime) * clockInSeconds;
        if (gEnergy < gammaThreshold_)
            continue;

        plot(neutron::D_ENERGY, gEnergy);
	if(hasBeta)
	  plot(neutron::betaGated::D_ENERGY, gEnergy);

	// granploty(neutron::DD_ENERGY__TIMEX,
        //             gEnergy, decayTime, timeResolution);
     // iteration over events


	plot(neutron::betaGated::DD_PROTONGAMMATDIFF_VS_GAMMAEN, gEnergy ,(gTime - lastProtonTime) / plotResolution) ;
    }
    EndProcess(); 
    return true;
}
Esempio n. 3
0
bool ImplantSsdProcessor::Process(RawEvent &event)
{
    using namespace dammIds::implantSsd;

    if (!EventProcessor::Process(event)) {
        EndProcess();
	return false;
    }

    static bool firstTime = true;
    static LogicProcessor *logProc = NULL;

    static Correlator &corr = event.GetCorrelator();
    static const DetectorSummary *tacSummary  = event.GetSummary("generic:tac", true);
    static DetectorSummary *impSummary  = event.GetSummary("ssd:sum", true);
    static const DetectorSummary *mcpSummary  = event.GetSummary("logic:mcp", true);
    static const DetectorSummary *vetoSummary = event.GetSummary("ssd:veto", true);
    static const DetectorSummary *boxSummary  = event.GetSummary("ssd:box", true);
    DetectorDriver* driver = DetectorDriver::get();

    if (impSummary->GetMult() == 0) {
      EndProcess();
      return false;
    }
    if (firstTime) {
      vector<EventProcessor *> vecProc = driver->GetProcessors("logic");
      for (vector< EventProcessor * >::iterator it = vecProc.begin(); it != vecProc.end(); it++) {
	if ( (*it)->GetName() == "triggerlogic" || (*it)->GetName() == "logic" ) {
	  logProc = reinterpret_cast < LogicProcessor * >(*it);
  	  cout << "Implant SSD processor grabbed logic processor" << endl;
        }
      }
      firstTime=false;
    }

    EventInfo info;
    ChanEvent *ch  = impSummary->GetMaxEvent(true);
    info.hasVeto = ( vetoSummary && vetoSummary->GetMult() > 0 );

    int location = ch->GetChanID().GetLocation();
    if (ch->IsSaturated()) {
	info.energy = 16000; // arbitrary large number
    } else {
	info.energy  = ch->GetCalEnergy();
    }
    if (ch->GetTrace().HasValue("position")) {
	info.position = ch->GetTrace().GetValue("position");
    } // else it defaults to nan

    info.time    = ch->GetTime();
    info.beamOn  = true;

    // recect noise events
    if (info.energy < 10 || ch->GetTrace().HasValue("badqdc")) {
	EndProcess();
	return true;
    }

    if (logProc) {
	info.clockCount = logProc->StartCount(2);
	if (logProc->LogicStatus(3) || logProc->LogicStatus(4) || logProc->LogicStatus(5)) {
	    info.beamOn = true;
	    info.offTime = 0;
	} else {
	    info.beamOn = false;
	    if (!logProc->LogicStatus(3))
		info.offTime = logProc->TimeOff(3, info.time);
	    else if (!logProc->LogicStatus(4))
		info.offTime = logProc->TimeOff(4, info.time) + 300e-6;
	    else if (!logProc->LogicStatus(5))
		info.offTime = logProc->TimeOff(5, info.time) + 600e-6;
	}
	for (int i=0; i < dammIds::logic::MAX_LOGIC; i++) {
	    info.logicBits[i] = (logProc->LogicStatus(i) ? '1' : '0');
	}
    }
    double digitalTof = NAN;
    if (mcpSummary) {
	info.mcpMult = mcpSummary->GetMult();
	vector<ChanEvent*> mcpEvents = mcpSummary->GetList();

	double dtMin = DBL_MAX;

	for (vector<ChanEvent*>::iterator it = mcpEvents.begin();
	     it != mcpEvents.end(); it++) {
	    double dt = info.time - (*it)->GetTime();

	    plot(D_TDIFF_FOIL_IMPLANT, 500 + dt);
	    if (mcpEvents.size() == 1) {
		digitalTof = -10.*dt;
		plot(D_TDIFF_FOIL_IMPLANT_MULT1, 500 + dt);
	    }
	    dtMin = min(dtMin, dt);
	}
	if (dtMin != DBL_MAX)
	    info.foilTime= dtMin;
    } else {
	info.mcpMult  = 0;
	info.foilTime = NAN;
    }
    if (impSummary) {
	info.impMult = impSummary->GetMult();
    } else {
	info.impMult = 0;
    }
    if (boxSummary) {
	info.boxMult = boxSummary->GetMult();

	if (info.boxMult > 0) {
	    const ChanEvent *boxCh = boxSummary->GetMaxEvent();

	    info.energyBox = boxCh->GetCalEnergy(); //raw?
	    info.boxMax = boxCh->GetChanID().GetLocation();
	} else {
	    info.energyBox = 0;
	    info.boxMax = -1;
	}
    } else {
	info.boxMult = 0;
    }
    info.tof = NAN;
    if (tacSummary) {
	const vector<ChanEvent*> events = tacSummary->GetList();
	for (vector<ChanEvent*>::const_iterator it = events.begin(); it != events.end(); it++) {
	    int loc = (*it)->GetChanID().GetLocation();
	    if (loc == 2) {
		info.tof = (*it)->GetCalEnergy();
		info.hasTof = true;
		break;
	    }
	}
    } else {
	info.hasTof = true;
    }

    Trace &trace = ch->GetTrace();
    if (trace.HasValue("filterEnergy2")) {
	info.pileUp = true;
    }

    SetType(info);
    Correlate(corr, info, location);

    // TOF spectra update
    if (tacSummary) {
	const vector<ChanEvent*> events = tacSummary->GetList();
	for (vector<ChanEvent*>::const_iterator it = events.begin();
	     it != events.end(); it++) {
	    double tof  = (*it)->GetCalEnergy();
	    int ntof = (*it)->GetChanID().GetLocation();

	    plot(DD_ALL_ENERGY__TOFX + ntof - 1, info.energy, tof);
	    if (!isnan(digitalTof) && digitalTof > 1500. && digitalTof < 2000)
		plot(DD_ALL_ENERGY__TOFX_GATED + ntof - 1, info.energy, tof);
	    if (info.type == EventInfo::IMPLANT_EVENT) {
		plot(DD_IMPLANT_ENERGY__TOFX + ntof - 1, info.energy, tof);
	    } else if (info.type == EventInfo::PROTON_EVENT) {
		plot(DD_VETO_ENERGY__TOFX + ntof - 1, info.energy, tof);
	    }
	}
	// TAC channel 0 is missing, so use it for the digital tof
	if (!isnan(digitalTof)) {
	    plot(DD_ALL_ENERGY__TOFX, info.energy, digitalTof);
	    if (info.type == EventInfo::IMPLANT_EVENT) {
		plot(DD_IMPLANT_ENERGY__TOFX, info.energy, digitalTof);
	    } else if (info.type == EventInfo::PROTON_EVENT) {
		plot(DD_VETO_ENERGY__TOFX, info.energy, digitalTof);
	    }
	}
    }

    if (info.type == EventInfo::PROTON_EVENT) {
        const ChanEvent *chVeto = vetoSummary->GetMaxEvent();

        unsigned int posVeto = chVeto->GetChanID().GetLocation();
        double vetoEnergy = chVeto->GetCalEnergy();

        plot(DD_LOC_VETO__LOC_SSD, posVeto, location);
        plot(DD_TOTENERGY__ENERGY, vetoEnergy + info.energy, info.energy);
    }

    if (info.pileUp) {
        double trigTime = info.time;

        info.energy = driver->cali.GetCalEnergy(ch->GetChanID(),
                                              trace.GetValue("filterEnergy2"));
        info.time = trigTime + trace.GetValue("filterTime2") - trace.GetValue("filterTime");

        SetType(info);
        Correlate(corr, info, location);

        int numPulses = trace.GetValue("numPulses");

        if ( numPulses > 2 ) {
            corr.Flag(location, 1);
            cout << "Flagging triple event" << endl;
            for (int i=3; i <= numPulses; i++) {
            stringstream str;
            str << "filterEnergy" << i;
            info.energy = driver->cali.GetCalEnergy(ch->GetChanID(),
                                              trace.GetValue(str.str()));
            str.str(""); // clear it
            str << "filterTime" << i;
            info.time   = trigTime + trace.GetValue(str.str()) - trace.GetValue("filterTime");

            SetType(info);
            Correlate(corr, info, location);
            }
        }
        // corr.Flag(location, 1);
#ifdef VERBOSE
        cout << "Flagging for pileup" << endl;

        cout << "fast trace " << fastTracesWritten << " in strip " << location
            << " : " << trace.GetValue("filterEnergy") << " " << trace.GetValue("filterTime")
            << " , " << trace.GetValue("filterEnergy2") << " " << trace.GetValue("filterTime2") << endl;
        cout << "  mcp mult " << info.mcpMult << endl;
#endif // VERBOSE

        if (fastTracesWritten < numTraces) {
            trace.Plot(D_FAST_DECAY_TRACE + fastTracesWritten);
            fastTracesWritten++;
        }
    }

    if (info.energy > 10000 && !ch->IsSaturated() && !isnan(info.position) ) {
	corr.Flag(location, info.position);
    }

    if (info.energy > 8000 && !trace.empty()) {
#ifdef VERBOSE
	cout << "high energy decay of " << info.energy
	     << "(raw energy " << ch->GetEnergy() << ") with beam "
	     << (info.beamOn ? "present" : "absent") << endl;

	cout << "Flagging for high energy " << info.energy << " with trace" << endl;
#endif //VERBOSE
	// corr.Flag(location, 1);

	if (highTracesWritten < numTraces) {
	    trace.Plot(D_HIGH_ENERGY_TRACE + highTracesWritten);
	    highTracesWritten++;
	}
    }

    EndProcess(); // update the processing time
    return true;
}
Esempio n. 4
0
bool IS600Processor::Process(RawEvent &event) {
    if (!EventProcessor::Process(event))
        return(false);
    double plotMult_ = 2;
    double plotOffset_ = 1000;

    BarMap vbars, betas;
    map<unsigned int, pair<double,double> > lrtBetas;
    vector<ChanEvent*> geEvts;
    vector<vector<AddBackEvent> > geAddback;

    if(event.GetSummary("vandle")->GetList().size() != 0)
        vbars = ((VandleProcessor*)DetectorDriver::get()->
            GetProcessor("VandleProcessor"))->GetBars();
    if(event.GetSummary("beta:double")->GetList().size() != 0) {
        betas = ((DoubleBetaProcessor*)DetectorDriver::get()->
            GetProcessor("DoubleBetaProcessor"))->GetBars();
        lrtBetas = ((DoubleBetaProcessor*)DetectorDriver::get()->
            GetProcessor("DoubleBetaProcessor"))->GetLowResBars();
    }
    if(event.GetSummary("ge")->GetList().size() != 0) {
        geEvts = ((GeProcessor*)DetectorDriver::get()->
            GetProcessor("GeProcessor"))->GetGeEvents();
        geAddback = ((GeProcessor*)DetectorDriver::get()->
            GetProcessor("GeProcessor"))->GetAddbackEvents();
    }
    static const vector<ChanEvent*> &labr3Evts =
	event.GetSummary("labr3:mrbig")->GetList();

#ifdef useroot
    vsize_->Fill(vbars.size());
#endif

    //Obtain some useful logic statuses
    double lastProtonTime =
	TreeCorrelator::get()->place("logic_t1_0")->last().time;
    bool isTapeMoving = TreeCorrelator::get()->place("TapeMove")->status();

    int bananaNum = 2;
    bool hasMultOne = vbars.size() == 1;
    bool hasMultTwo = vbars.size() == 2;
    //bool isFirst = true;

    plot(DD_DEBUGGING3, vbars.size());

    //Begin processing for VANDLE bars
    for (BarMap::iterator it = vbars.begin(); it !=  vbars.end(); it++) {
        TimingDefs::TimingIdentifier barId = (*it).first;
        BarDetector bar = (*it).second;

        if(!bar.GetHasEvent() || bar.GetType() == "small")
            continue;

        unsigned int barLoc = barId.first;
        TimingCalibration cal = bar.GetCalibration();

        for(BarMap::iterator itStart = betas.begin();
	    itStart != betas.end(); itStart++) {
	    unsigned int startLoc = (*itStart).first.first;
            BarDetector start = (*itStart).second;
            if(!start.GetHasEvent())
                continue;

            double tofOffset = cal.GetTofOffset(startLoc);
            double tof = bar.GetCorTimeAve() -
                start.GetCorTimeAve() + tofOffset;

            double corTof =
                ((VandleProcessor*)DetectorDriver::get()->
		 GetProcessor("VandleProcessor"))->
		CorrectTOF(tof, bar.GetFlightPath(), cal.GetZ0());

	    bool inPeel = histo.BananaTest(bananaNum,
            corTof*plotMult_+plotOffset_,
            bar.GetQdc());
	    bool isLowStart = start.GetQdc() < 300;

	    *outstream << tof << " " << bar.GetQdc() << endl;
#ifdef useroot
        qdctof_->Fill(tof,bar.GetQdc());
        qdc_ = bar.GetQdc();
        tof_ = tof;
        roottree_->Fill();
        qdc_ = tof_ = -9999;
#endif

	    plot(DD_DEBUGGING1, tof*plotMult_+plotOffset_, bar.GetQdc());
	    if(!isTapeMoving && !isLowStart)
		plot(DD_DEBUGGING0, corTof*plotMult_+plotOffset_,bar.GetQdc());
	    if(hasMultOne)
		plot(DD_DEBUGGING4, corTof*plotMult_+plotOffset_, bar.GetQdc());

	    ///Starting to look for 2n coincidences in VANDLE
	    BarMap::iterator itTemp = it;
	    itTemp++;

	    for (BarMap::iterator it2 = itTemp; it2 !=  vbars.end(); it2++) {
		TimingDefs::TimingIdentifier barId2 = (*it2).first;
		BarDetector bar2 = (*it2).second;

		if(!bar.GetHasEvent())
		    continue;

		unsigned int barLoc2 = barId2.first;

		bool isAdjacent = abs((int)barLoc2 - (int)barLoc) < 1;

		TimingCalibration cal2 = bar2.GetCalibration();

		double tofOffset2 = cal2.GetTofOffset(startLoc);
		double tof2 = bar2.GetCorTimeAve() -
		    start.GetCorTimeAve() + tofOffset2;

		double corTof2 =
		    ((VandleProcessor*)DetectorDriver::get()->
		     GetProcessor("VandleProcessor"))->
		    CorrectTOF(tof2, bar2.GetFlightPath(), cal2.GetZ0());

		bool inPeel2 = histo.BananaTest(bananaNum,
						corTof2*plotMult_+plotOffset_,
						bar2.GetQdc());

		if(hasMultTwo && inPeel && inPeel2 && !isAdjacent) {
		    plot(DD_DEBUGGING5, corTof*plotMult_+plotOffset_,
			 corTof2*plotMult_+plotOffset_);
		    plot(DD_DEBUGGING5, corTof2*plotMult_+plotOffset_,
			 corTof*plotMult_+plotOffset_);
		}
	    }
	    ///End 2n coincidence routine

	    // if (geSummary_ && notPrompt && hasMultOne) {
            //     if (geSummary_->GetMult() > 0) {
            //         const vector<ChanEvent *> &geList = geSummary_->GetList();
            //         for (vector<ChanEvent *>::const_iterator itGe = geList.begin();
            //             itGe != geList.end(); itGe++) {
            //             double calEnergy = (*itGe)->GetCalEnergy();
	    // 		plot(DD_DEBUGGING2, calEnergy, corTof*plotMult_+plotOffset_);
            //         }
            //     } else {
	    // 	  //plot(DD_TQDCAVEVSTOF_VETO+histTypeOffset, tof, bar.GetQdc());
	    // 	  //plot(DD_TOFBARS_VETO+histTypeOffset, tof, barPlusStartLoc);
            //     }
            //}
        } // for(TimingMap::iterator itStart
    } //(BarMap::iterator itBar
    //End processing for VANDLE bars

    //-------------- LaBr3 Processing ---------------
    for(vector<ChanEvent*>::const_iterator it = labr3Evts.begin();
	it != labr3Evts.end(); it++)
	plot(DD_DEBUGGING6, (*it)->GetEnergy());


    //------------------ Double Beta Processing --------------
    for(map<unsigned int, pair<double,double> >::iterator it = lrtBetas.begin();
	it != lrtBetas.end(); it++)
	plot(DD_PROTONBETA2TDIFF_VS_BETA2EN, it->second.second,
	     (it->second.first - lastProtonTime) /
	     (10e-3/Globals::get()->clockInSeconds()) );


    //----------------- GE Processing -------------------
    bool hasBeta = TreeCorrelator::get()->place("Beta")->status();
    double clockInSeconds = Globals::get()->clockInSeconds();
    // plot with 10 ms bins
    const double plotResolution = 10e-3 / clockInSeconds;

    for (vector<ChanEvent*>::iterator it1 = geEvts.begin();
	 it1 != geEvts.end(); ++it1) {
        ChanEvent *chan = *it1;

        double gEnergy = chan->GetCalEnergy();
        double gTime   = chan->GetCorrectedTime();
        if (gEnergy < 10.) //hard coded fix later.
            continue;

        plot(D_ENERGY, gEnergy);
	if(hasBeta)
	    plot(D_ENERGYBETA, gEnergy);
	plot(DD_PROTONGAMMATDIFF_VS_GAMMAEN, gEnergy ,
	     (gTime - lastProtonTime) / plotResolution) ;
    }

    EndProcess();
    return(true);
}
Esempio n. 5
0
bool PspmtProcessor::PreProcess(RawEvent &event){
    if (!EventProcessor::PreProcess(event))
        return false;
    
    static const vector<ChanEvent*> &pspmtEvents = sumMap["pspmt"]->GetList();
    
    data_.Clear();
    
    double q1=0,q2=0,q3=0,q4=0,qd=0;
    double qdc1=0,qdc2=0,qdc3=0,qdc4=0,qdcd=0;
    double tre1=0,tre2=0,tre3=0,tre4=0,tred=0;
    
    double qright=0,qleft=0,qtop=0,qbottom=0,qsum=0;
    double xright=0,xleft=0,ytop=0,ybottom=0;
    
    double qtre_r=0,qtre_l=0,qtre_t=0,qtre_b=0,qtre_s=0;
    double xtre_r=0,xtre_l=0,ytre_t=0,ytre_b=0;
    
    double qqdc_r=0,qqdc_l=0,qqdc_t=0,qqdc_b=0,qqdc_s=0;
    double xqdc_r=0,xqdc_l=0,yqdc_t=0,yqdc_b=0;
    
    double pxright=0,pxleft=0,pytop=0,pybottom=0;
    double pxtre_r=0,pxtre_l=0,pytre_t=0,pytre_b=0;
    
    // tentatively local params //
    double threshold=260;
    double slope=0.0606;
    double intercept=10.13;
    //////////////////////////////
    static int traceNum;
    
    double f=0.1;
    
    for (vector<ChanEvent*>::const_iterator it = pspmtEvents.begin();
         it != pspmtEvents.end(); it++) {
        
        ChanEvent *chan   = *it;
        string subtype    = chan->GetChanID().GetSubtype();
        int    ch         = chan->GetChanID().GetLocation();
        double calEnergy  = chan->GetCalEnergy();
        //double pspmtTime  = chan->GetTime();
        Trace trace       = chan->GetTrace();
        
        double trace_energy;
        double trace_time;
        double baseline;
        double qdc;
        //int    num        = trace.GetValue("numPulses");
        
        if(trace.HasValue("filterEnergy")){
            traceNum++;   	  
            trace_time    = trace.GetValue("filterTime");
            trace_energy  = trace.GetValue("filterEnergy");
            baseline      = trace.DoBaseline(2,20);
            qdc             = trace.DoQDC(5,128);
            
            if(ch==0){
                qdc1 = qdc;
                tre1 = trace_energy;
                plot(D_QDC_TRACE1,qdc1);
                plot(D_ENERGY_TRACE1,tre1);
            }else if(ch==1){
                qdc2 = qdc;
                tre2 = trace_energy; 
                plot(D_QDC_TRACE2,qdc2);
                plot(D_ENERGY_TRACE2,tre2);
            }else if(ch==2){
                qdc3 = qdc;
                tre3 = trace_energy; 
                plot(D_QDC_TRACE3,qdc3);
                plot(D_ENERGY_TRACE3,tre3);
            }else if(ch==3){
                qdc4 = qdc;
                tre4 = trace_energy; 	  
                plot(D_QDC_TRACE4,qdc4);
                plot(D_ENERGY_TRACE4,tre4);
            }else if(ch==4){
                qdcd = qdc;
                tred = trace_energy; 
                plot(D_QDC_TRACED,qdcd);
                plot(D_ENERGY_TRACED,tred);
            }
        }

        if(ch==0){
            q1= calEnergy;
            plot(D_RAW1,q1);
        }else if(ch==1){
            q2= calEnergy;
            plot(D_RAW2,q2);
        }else if(ch==2){
            q3= calEnergy;
            plot(D_RAW3,q3);
        }else if(ch==3){
            q4= calEnergy;
            plot(D_RAW4,q4);
        }else if(ch==4){
            qd= calEnergy;
            plot(D_RAWD,qd);
        }
        
        if(q1>0 && q2>0 && q3>0 && q4>0){
            qtop    = (q1+q2)/2;
            qleft   = (q2+q3)/2;
            qbottom = (q3+q4)/2;
            qright  = (q4+q1)/2;
            
            qsum    = (q1+q2+q3+q4)/2;
            xright  = (qright/qsum)*512+100;
            xleft   = (qleft/qsum)*512+100;
            ytop    = (qtop/qsum)*512+100;
            ybottom = (qbottom/qsum)*512+100;
            plot(D_SUM,qsum);
        }
        
        if(tre1>0 && tre2>0 && tre3>0 && tre4>0 ){
            qtre_t=(tre1+tre2)/2;
            qtre_l=(tre2+tre3)/2;
            qtre_b=(tre3+tre4)/2;
            qtre_r=(tre4+tre1)/2;
            qtre_s=(tre1+tre2+tre3+tre4)/2;
            
            xtre_r=(qtre_r/qtre_s)*512+100;
            xtre_l=(qtre_l/qtre_s)*512+100;
            ytre_t=(qtre_t/qtre_s)*512+100;
            ytre_b=(qtre_b/qtre_s)*512+100;
            
            pxtre_r = trunc(slope*xtre_l-intercept);
            pxtre_l = trunc(slope*xtre_r-intercept);
            pytre_t = trunc(slope*ytre_t-intercept);
            pytre_b = trunc(slope*ytre_b-intercept);
                        
            plot(D_ENERGY_TRACESUM,qtre_s);
            
            if(tre1>threshold && tre2>threshold && tre3>threshold && tre4>threshold ){
                plot(DD_POS1_RAW_TRACE,xtre_r,ytre_t);
                plot(DD_POS2_RAW_TRACE,xtre_l,ytre_b);
                plot(DD_POS1_TRACE,pxtre_r,pytre_t);
                plot(DD_POS2_TRACE,pxtre_l,pytre_b);
            }    
        }
        
        if(qdc1>0 && qdc2>0 && qdc3>0 && qdc4>0 ){
            qqdc_t=(qdc1+qdc2)/2;
            qqdc_l=(qdc2+qdc3)/2;
            qqdc_b=(qdc3+qdc4)/2;
            qqdc_r=(qdc4+qdc1)/2;
            qqdc_s=(qqdc_t+qqdc_l+qqdc_b+qqdc_r)/2;
            
            xqdc_r=(qqdc_r/qqdc_s)*512+100;
            xqdc_l=(qqdc_l/qqdc_s)*512+100;
            yqdc_t=(qqdc_t/qqdc_s)*512+100;
            yqdc_b=(qqdc_b/qqdc_s)*512+100;
            
            plot(D_ENERGY_TRACESUM,qqdc_s);
        }
        
        if(q1>threshold && q2>threshold && q3>threshold && q4>threshold ){
            pxleft   = trunc(slope*xleft-intercept);
            pxright  = trunc(slope*xright-intercept);
            pytop    = trunc(slope*ytop-intercept);
            pybottom = trunc(slope*ybottom-intercept);
            
            plot(DD_POS1_RAW,xright,ytop);
            plot(DD_POS2_RAW,xleft,ybottom);
            plot(DD_POS1,pxright,pytop);
            plot(DD_POS2,pxleft,pybottom);
                        
            if(xright>341 && xright < 356 && ytop>200 && ytop<211){
                plot(D_TEMP0,f*q1);
                plot(D_TEMP1,f*q2);
                plot(D_TEMP2,f*q3);
                plot(D_TEMP3,f*q4);
                plot(D_TEMP4,f*qd);
            }
            
            for(vector<int>::iterator ittr = trace.begin();ittr != trace.end();ittr++)
                plot(DD_SINGLE_TRACE,ittr-trace.begin(),traceNum,*ittr);
        }
    } // end of channel event
    
    EndProcess();
    return(true);
}
/**
 *  Process the QDC data involved in top/bottom side for a strip 
 *  Note QDC lengths are HARD-CODED at the moment for the plots and to determine the position
 */
bool PositionProcessor::Process(RawEvent &event) {
    if (!EventProcessor::Process(event))
        return false;

    static const vector<ChanEvent*> &sumEvents = 
	event.GetSummary("ssd:sum", true)->GetList();
    static const vector<ChanEvent*> &digisumEvents =
	event.GetSummary("ssd:digisum", true)->GetList();
    static const vector<ChanEvent*> &topEvents =
	event.GetSummary("ssd:top", true)->GetList();
    static const vector<ChanEvent*> &bottomEvents =
	event.GetSummary("ssd:bottom", true)->GetList();

    vector<ChanEvent *> allEvents;
    // just add in the digisum events for now
    allEvents.insert(allEvents.begin(), digisumEvents.begin(), digisumEvents.end());
    allEvents.insert(allEvents.begin(), sumEvents.begin(), sumEvents.end());

    for (vector<ChanEvent*>::const_iterator it = allEvents.begin();
	     it != allEvents.end(); ++it) {
         ChanEvent *sumchan   = *it;

        int location = sumchan->GetChanID().GetLocation();

        // Don't waste our time with noise events
        if ( (*it)->GetEnergy() < 10. || (*it)->GetEnergy() > 16374 ) {
            using namespace dammIds::position;

            plot(D_INFO_LOCX + location, INFO_NOISE);
            plot(D_INFO_LOCX + LOC_SUM , INFO_NOISE);
            continue;
        }

        const ChanEvent *top    = FindMatchingEdge(sumchan, topEvents.begin(), topEvents.end());
        const ChanEvent *bottom = FindMatchingEdge(sumchan, bottomEvents.begin(), bottomEvents.end());


        if (top == NULL || bottom == NULL) {
            using namespace dammIds::position;

            if (top == NULL) {
                // [6] -> Missing top
                plot(D_INFO_LOCX + location, INFO_MISSING_TOP);
                plot(D_INFO_LOCX + LOC_SUM, INFO_MISSING_TOP);
            }

            if (bottom == NULL) {
                // [5] -> Missing bottom
                plot(D_INFO_LOCX + location, INFO_MISSING_BOTTOM);
                plot(D_INFO_LOCX + LOC_SUM, INFO_MISSING_BOTTOM);
            }
            continue;
        }

        /* Make sure we get the same match going backwards to insure there is only one in the vector */
        if ( FindMatchingEdge(sumchan, topEvents.rbegin(), topEvents.rend()) != top) {
            using namespace dammIds::position;
            // [4] -> Multiple top
            plot(D_INFO_LOCX + location, INFO_MULTIPLE_TOP);
            plot(D_INFO_LOCX + LOC_SUM, INFO_MULTIPLE_TOP);
            continue;
        }
        if ( FindMatchingEdge(sumchan, bottomEvents.rbegin(), bottomEvents.rend()) != bottom) {
            using namespace dammIds::position;
            // [3] -> Multiple bottom
            plot(D_INFO_LOCX + location, INFO_MULTIPLE_BOTTOM);
            plot(D_INFO_LOCX + LOC_SUM, INFO_MULTIPLE_BOTTOM);
            continue;
        }

        using namespace dammIds::position;
        
        float topQdc[numQdcs];
        float bottomQdc[numQdcs];
        float topQdcTot = 0;
        float bottomQdcTot = 0;
        float position = NAN;
        
        topQdc[0] = top->GetQdcValue(0);
        bottomQdc[0] = bottom->GetQdcValue(0);
        if (bottomQdc[0] == U_DELIMITER || topQdc[0] == U_DELIMITER) {
            // This happens naturally for traces which have double triggers
            //   Onboard DSP does not write QDCs in this case
#ifdef VERBOSE
            cout << "SSD strip edges are missing QDC information for location " << location << endl;
#endif
            if (topQdc[0] == U_DELIMITER) {
                // [2] -> Missing top QDC
                plot(D_INFO_LOCX + location, INFO_MISSING_TOP_QDC);
                plot(D_INFO_LOCX + LOC_SUM, INFO_MISSING_TOP_QDC);
                // Recreate qdc from trace
                if ( !top->GetTrace().empty() ) {
                    topQdc[0] = accumulate(top->GetTrace().begin(), top->GetTrace().begin() + qdcLen[0], 0);
                } else {
                    topQdc[0] = 0;
                }
            }
            if (bottomQdc[0] == U_DELIMITER) {
                // [1] -> Missing bottom QDC
                plot(D_INFO_LOCX + location, INFO_MISSING_BOTTOM_QDC);
                plot(D_INFO_LOCX + LOC_SUM, INFO_MISSING_BOTTOM_QDC);
                // Recreate qdc from trace
                if ( !bottom->GetTrace().empty() ) {
                    bottomQdc[0] = accumulate(bottom->GetTrace().begin(), bottom->GetTrace().begin() + qdcLen[0], 0);
                } else {
                    bottomQdc[0] = 0;
                }
            }
            if ( topQdc[0] == 0 || bottomQdc[0] == 0 ) {
                continue;
            }
        }
        // [0] -> good stuff
        plot(D_INFO_LOCX + location, INFO_OKAY);
        plot(D_INFO_LOCX + LOC_SUM, INFO_OKAY);


        for (int i = 1; i < numQdcs; ++i) {		
            if (top->GetQdcValue(i) == U_DELIMITER) {
                // Recreate qdc from trace
                topQdc[i] = accumulate(top->GetTrace().begin() + qdcPos[i-1],
                top->GetTrace().begin() + qdcPos[i], 0);
            } else {
                topQdc[i] = top->GetQdcValue(i);
            }

            topQdc[i] -= topQdc[0] * qdcLen[i] / qdcLen[0];
            topQdcTot += topQdc[i];
            topQdc[i] /= qdcLen[i];		
            
            if (bottom->GetQdcValue(i) == U_DELIMITER) {
                // Recreate qdc from trace
                bottomQdc[i] = accumulate(bottom->GetTrace().begin() + qdcPos[i-1],
                                          bottom->GetTrace().begin() + qdcPos[i], 0);
            } else {
                bottomQdc[i] = bottom->GetQdcValue(i);
            }

            bottomQdc[i] -= bottomQdc[0] * qdcLen[i] / qdcLen[0];
            bottomQdcTot += bottomQdc[i];
            bottomQdc[i] /= qdcLen[i];
            
            plot(DD_QDCN__QDCN_LOCX + QDC_JUMP * i + location, topQdc[i] + 10, bottomQdc[i] + 10);
            plot(DD_QDCN__QDCN_LOCX + QDC_JUMP * i + LOC_SUM, topQdc[i], bottomQdc[i]);
            
            float frac = topQdc[i] / (topQdc[i] + bottomQdc[i]) * 1000.; // per mil
            
            plot(D_QDCNORMN_LOCX + QDC_JUMP * i + location, frac);
            plot(D_QDCNORMN_LOCX + QDC_JUMP * i + LOC_SUM, frac);
            if (i == whichQdc) {
                position = posScale * (frac - minNormQdc[location]) / 
                    (maxNormQdc[location] - minNormQdc[location]);		
                sumchan->GetTrace().InsertValue("position", position);
                plot(DD_POSITION__ENERGY_LOCX + location, position, sumchan->GetCalEnergy());
                plot(DD_POSITION__ENERGY_LOCX + LOC_SUM, position, sumchan->GetCalEnergy());
            }
            if (i == 6 && !sumchan->IsSaturated()) {
                // compare the long qdc to the energy
                int qdcSum = topQdc[i] + bottomQdc[i];
                
                // MAGIC NUMBERS HERE, move to qdc.txt
                if (qdcSum < 1000 && sumchan->GetCalEnergy() > 15000) {
                    sumchan->GetTrace().InsertValue("badqdc", 1);
                } else if ( !isnan(position) ) {
                    plot(DD_POSITION, location, position);
                }
            }
        } // end loop over qdcs
        // KM QDC - QDC correlations
        double ratio[4] = {0};
        for (int i = 1; i < 5; ++i) {
                ratio[i - 1] = topQdc[i] / (bottomQdc[i] + topQdc[i]) * 1000.0;
        }

        plot(DD_QDCR2__QDCR1_LOCX + location, ratio[1], ratio[0]);
        plot(DD_QDCR2__QDCR3_LOCX + location, ratio[1], ratio[2]);
        plot(DD_QDCR2__QDCR4_LOCX + location, ratio[1], ratio[3]);

        plot(DD_QDC1R__POS_LOCX + location, ratio[0], position * 10.0 + 200.0);
        plot(DD_QDC2R__POS_LOCX + location, ratio[1], position * 10.0 + 200.0);
        plot(DD_QDC3R__POS_LOCX + location, ratio[2], position * 10.0 + 200.0);
        plot(DD_QDC4R__POS_LOCX + location, ratio[3], position * 10.0 + 200.0);

        topQdcTot    /= totLen;
        bottomQdcTot /= totLen;
        
        plot(DD_QDCTOT__QDCTOT_LOCX + location, topQdcTot, bottomQdcTot);
        plot(DD_QDCTOT__QDCTOT_LOCX + LOC_SUM, topQdcTot, bottomQdcTot);
    } // end iteration over sum events

   // test

    EndProcess();

    return true;
}