int DetectorDriver::ThreshAndCal(ChanEvent *chan, RawEvent& rawev) {
    Identifier chanId = chan->GetChanID();
    int id            = chan->GetID();
    string type       = chanId.GetType();
    string subtype    = chanId.GetSubtype();
    map<string, int> tags = chanId.GetTagMap();
    bool hasStartTag  = chanId.HasTag("start");
    Trace &trace      = chan->GetTrace();

    RandomPool* randoms = RandomPool::get();

    double energy = 0.0;

    if (type == "ignore" || type == "")
        return(0);

    if ( !trace.empty() ) {
        plot(D_HAS_TRACE, id);

        for (vector<TraceAnalyzer *>::iterator it = vecAnalyzer.begin();
            it != vecAnalyzer.end(); it++) {
            (*it)->Analyze(trace, type, subtype, tags);
        }

        if (trace.HasValue("filterEnergy") ) {
            if (trace.GetValue("filterEnergy") > 0) {
                energy = trace.GetValue("filterEnergy");
                plot(D_FILTER_ENERGY + id, energy);
                trace.SetValue("filterEnergyCal",
                    cali.GetCalEnergy(chanId, trace.GetValue("filterEnergy")));
            } else {
                energy = 0.0;
            }

            /** Calibrate pulses numbered 2 and forth,
             * add filterEnergyXCal to the trace */
            int pulses = trace.GetValue("numPulses");
            for (int i = 1; i < pulses; ++i) {
                stringstream energyName;
                energyName << "filterEnergy" << i + 1;
                stringstream energyCalName;
                energyCalName << "filterEnergy" << i + 1 << "Cal";
                trace.SetValue(energyCalName.str(),
                    cali.GetCalEnergy(chanId,
                                      trace.GetValue(energyName.str())));
            }
        }

        if (trace.HasValue("calcEnergy") ) {
            energy = trace.GetValue("calcEnergy");
            chan->SetEnergy(energy);
        } else if (!trace.HasValue("filterEnergy")) {
            energy = chan->GetEnergy() + randoms->Get();
        }

        if (trace.HasValue("phase") ) {
	    //Saves the time in ns
            chan->SetHighResTime((trace.GetValue("phase") *
				 Globals::get()->adcClockInSeconds() +
				 chan->GetTrigTime() *
				  Globals::get()->filterClockInSeconds())*1.e9);
        }
    } else {
        /// otherwise, use the Pixie on-board calculated energy
        /// add a random number to convert an integer value to a
        ///   uniformly distributed floating point
        energy = chan->GetEnergy() + randoms->Get();
	chan->SetHighResTime(0.0);
    }

    /** Calibrate energy and apply the walk correction. */
    double time, walk_correction;
    if(chan->GetHighResTime() == 0.0) {
	time = chan->GetTime(); //time is in clock ticks
	walk_correction = walk.GetCorrection(chanId, energy);
    } else {
	time = chan->GetHighResTime(); //time here is in ns
	walk_correction = walk.GetCorrection(chanId, trace.GetValue("tqdc"));
    }

    chan->SetCalEnergy(cali.GetCalEnergy(chanId, energy));
    chan->SetCorrectedTime(time - walk_correction);

    rawev.GetSummary(type)->AddEvent(chan);
    DetectorSummary *summary;

    summary = rawev.GetSummary(type + ':' + subtype, false);
    if (summary != NULL)
        summary->AddEvent(chan);

    if(hasStartTag && type != "logic") {
        summary =
            rawev.GetSummary(type + ':' + subtype + ':' + "start", false);
        if (summary != NULL)
            summary->AddEvent(chan);
    }
    return(1);
}