Ejemplo n.º 1
0
int
Proto2ShowerCalib::process_event(PHCompositeNode *topNode)
{

  if (verbosity > 2)
    cout << "Proto2ShowerCalib::process_event() entered" << endl;

  // init eval objects
  _eval_run.reset();
  _eval_3x3_raw.reset();
  _eval_5x5_raw.reset();
  _eval_3x3_prod.reset();
  _eval_5x5_prod.reset();
  _eval_3x3_temp.reset();
  _eval_5x5_temp.reset();
  _eval_3x3_recalib.reset();
  _eval_5x5_recalib.reset();

  Fun4AllHistoManager *hm = get_HistoManager();
  assert(hm);

  if (not _is_sim)
    {
      PdbParameterMap *info = findNode::getClass<PdbParameterMap>(topNode,
          "RUN_INFO");

      assert(info);

      PHG4Parameters run_info_copy("RunInfo");
      run_info_copy.FillFrom(info);

      _eval_run.beam_mom = run_info_copy.get_double_param("beam_MTNRG_GeV");

      TH1F * hBeam_Mom = dynamic_cast<TH1F *>(hm->getHisto("hBeam_Mom"));
      assert(hBeam_Mom);

      hBeam_Mom->Fill(_eval_run.beam_mom);
    }

  EventHeader* eventheader = findNode::getClass<EventHeader>(topNode,
      "EventHeader");
  if (not _is_sim)
    {
      assert(eventheader);

      _eval_run.run = eventheader->get_RunNumber();
      if (verbosity > 4)
        cout << __PRETTY_FUNCTION__ << _eval_run.run << endl;

      _eval_run.event = eventheader->get_EvtSequence();
    }

  if (_is_sim)
    {

      PHG4TruthInfoContainer* truthInfoList = findNode::getClass<
          PHG4TruthInfoContainer>(topNode, "G4TruthInfo");

      assert(truthInfoList);

      _eval_run.run = -1;

      const PHG4Particle * p = truthInfoList->GetPrimaryParticleRange().first->second;
      assert(p);

      const PHG4VtxPoint * v = truthInfoList->GetVtx(p->get_vtx_id());
      assert(v);

      _eval_run.beam_mom = sqrt(
          p->get_px() * p->get_px() + p->get_py() * p->get_py()
              + p->get_pz() * p->get_pz());
      _eval_run.truth_y = v->get_y();
      _eval_run.truth_z = v->get_z();

    }

  // normalization
  TH1F * hNormalization = dynamic_cast<TH1F *>(hm->getHisto("hNormalization"));
  assert(hNormalization);

  hNormalization->Fill("ALL", 1);

  RawTowerContainer* TOWER_RAW_CEMC = findNode::getClass<RawTowerContainer>(
      topNode, _is_sim ? "TOWER_RAW_LG_CEMC" : "TOWER_RAW_CEMC");
  assert(TOWER_RAW_CEMC);
  RawTowerContainer* TOWER_CALIB_CEMC = findNode::getClass<RawTowerContainer>(
      topNode, _is_sim ? "TOWER_CALIB_LG_CEMC" : "TOWER_CALIB_CEMC");
  assert(TOWER_CALIB_CEMC);

  // other nodes
  RawTowerContainer* TOWER_CALIB_TRIGGER_VETO = findNode::getClass<
      RawTowerContainer>(topNode, "TOWER_CALIB_TRIGGER_VETO");
  if (not _is_sim)
    {
      assert(TOWER_CALIB_TRIGGER_VETO);
    }

  RawTowerContainer* TOWER_CALIB_HODO_HORIZONTAL = findNode::getClass<
      RawTowerContainer>(topNode, "TOWER_CALIB_HODO_HORIZONTAL");
  if (not _is_sim)
    {
      assert(TOWER_CALIB_HODO_HORIZONTAL);
    }
  RawTowerContainer* TOWER_CALIB_HODO_VERTICAL = findNode::getClass<
      RawTowerContainer>(topNode, "TOWER_CALIB_HODO_VERTICAL");
  if (not _is_sim)
    {
      assert(TOWER_CALIB_HODO_VERTICAL);
    }

  RawTowerContainer* TOWER_TEMPERATURE_EMCAL = findNode::getClass<
      RawTowerContainer>(topNode, "TOWER_TEMPERATURE_EMCAL");
  if (not _is_sim)
    {
      assert(TOWER_TEMPERATURE_EMCAL);
    }

  RawTowerContainer* TOWER_CALIB_C1 = findNode::getClass<RawTowerContainer>(
      topNode, "TOWER_CALIB_C1");
  if (not _is_sim)
    {
      assert(TOWER_CALIB_C1);
    }
  RawTowerContainer* TOWER_CALIB_C2 = findNode::getClass<RawTowerContainer>(
      topNode, "TOWER_CALIB_C2");
  if (not _is_sim)
    {
      assert(TOWER_CALIB_C2);
    }

  // Cherenkov
  bool cherekov_e = false;
  if (not _is_sim)
    {
      RawTower * t_c2_in = NULL;
      RawTower * t_c2_out = NULL;

      assert(eventheader);
      if (eventheader->get_RunNumber() >= 2105)
        {
          t_c2_in = TOWER_CALIB_C2->getTower(10);
          t_c2_out = TOWER_CALIB_C2->getTower(11);
        }
      else
        {
          t_c2_in = TOWER_CALIB_C2->getTower(0);
          t_c2_out = TOWER_CALIB_C2->getTower(1);
        }
      assert(t_c2_in);
      assert(t_c2_out);

      const double c2_in = t_c2_in->get_energy();
      const double c2_out = t_c2_out->get_energy();
      const double c1 = TOWER_CALIB_C1->getTower(0)->get_energy();

      _eval_run.C2_sum = c2_in + c2_out;
      cherekov_e = (_eval_run.C2_sum) > 100;
      hNormalization->Fill("C2-e", cherekov_e);

      TH2F * hCheck_Cherenkov = dynamic_cast<TH2F *>(hm->getHisto(
          "hCheck_Cherenkov"));
      assert(hCheck_Cherenkov);
      hCheck_Cherenkov->Fill(c1, "C1", 1);
      hCheck_Cherenkov->Fill(c2_in, "C2 in", 1);
      hCheck_Cherenkov->Fill(c2_out, "C2 out", 1);
      hCheck_Cherenkov->Fill(c2_in + c2_out, "C2 sum", 1);
    }

  // veto
  TH1F * hCheck_Veto = dynamic_cast<TH1F *>(hm->getHisto("hCheck_Veto"));
  assert(hCheck_Veto);
  bool trigger_veto_pass = true;
  if (not _is_sim)
    {
      auto range = TOWER_CALIB_TRIGGER_VETO->getTowers();
      for (auto it = range.first; it != range.second; ++it)
        {
          RawTower* tower = it->second;
          assert(tower);

          hCheck_Veto->Fill(tower->get_energy());

          if (abs(tower->get_energy()) > 15)
            trigger_veto_pass = false;
        }
    }
  hNormalization->Fill("trigger_veto_pass", trigger_veto_pass);
  _eval_run.trigger_veto_pass = trigger_veto_pass;

  // hodoscope
  TH1F * hCheck_Hodo_H = dynamic_cast<TH1F *>(hm->getHisto("hCheck_Hodo_H"));
  assert(hCheck_Hodo_H);
  int hodo_h_count = 0;
  if (not _is_sim)
    {
      auto range = TOWER_CALIB_HODO_HORIZONTAL->getTowers();
      for (auto it = range.first; it != range.second; ++it)
        {
          RawTower* tower = it->second;
          assert(tower);

          hCheck_Hodo_H->Fill(tower->get_energy());

          if (abs(tower->get_energy()) > 30)
            {
              hodo_h_count++;
              _eval_run.hodo_h = tower->get_id();
            }
        }
    }
  const bool valid_hodo_h = hodo_h_count == 1;
  hNormalization->Fill("valid_hodo_h", valid_hodo_h);
  _eval_run.valid_hodo_h = valid_hodo_h;

  TH1F * hCheck_Hodo_V = dynamic_cast<TH1F *>(hm->getHisto("hCheck_Hodo_V"));
  assert(hCheck_Hodo_V);
  int hodo_v_count = 0;
  if (not _is_sim)
    {
      auto range = TOWER_CALIB_HODO_VERTICAL->getTowers();
      for (auto it = range.first; it != range.second; ++it)
        {
          RawTower* tower = it->second;
          assert(tower);

          hCheck_Hodo_V->Fill(tower->get_energy());

          if (abs(tower->get_energy()) > 30)
            {
              hodo_v_count++;
              _eval_run.hodo_v = tower->get_id();
            }
        }
    }
  const bool valid_hodo_v = hodo_v_count == 1;
  _eval_run.valid_hodo_v = valid_hodo_v;
  hNormalization->Fill("valid_hodo_v", valid_hodo_v);

  const bool good_e = (valid_hodo_v and valid_hodo_h and cherekov_e
      and trigger_veto_pass) and (not _is_sim);
  hNormalization->Fill("good_e", good_e);

  // simple clustering
  pair<int, int> max_3x3 = find_max(TOWER_CALIB_CEMC, 3);
  pair<int, int> max_5x5 = find_max(TOWER_CALIB_CEMC, 5);

  _eval_3x3_raw.max_col = max_3x3.first;
  _eval_3x3_raw.max_row = max_3x3.second;
  _eval_3x3_prod.max_col = max_3x3.first;
  _eval_3x3_prod.max_row = max_3x3.second;
  _eval_3x3_temp.max_col = max_3x3.first;
  _eval_3x3_temp.max_row = max_3x3.second;
  _eval_3x3_recalib.max_col = max_3x3.first;
  _eval_3x3_recalib.max_row = max_3x3.second;

  _eval_5x5_raw.max_col = max_5x5.first;
  _eval_5x5_raw.max_row = max_5x5.second;
  _eval_5x5_prod.max_col = max_5x5.first;
  _eval_5x5_prod.max_row = max_5x5.second;
  _eval_5x5_temp.max_col = max_5x5.first;
  _eval_5x5_temp.max_row = max_5x5.second;
  _eval_5x5_recalib.max_col = max_5x5.first;
  _eval_5x5_recalib.max_row = max_5x5.second;

  // tower
  bool good_temp = true;
  double sum_energy_calib = 0;
  double sum_energy_T = 0;
  TH1F * hTemperature = dynamic_cast<TH1F *>(hm->getHisto("hTemperature"));
  assert(hTemperature);

  stringstream sdata;

  if (good_e)
    sdata << abs(_eval_run.beam_mom) << "\t";

  // tower temperature and recalibration
    {
      auto range = TOWER_CALIB_CEMC->getTowers();
      for (auto it = range.first; it != range.second; ++it)
        {

          RawTowerDefs::keytype key = it->first;
          RawTower* tower = it->second;
          assert(tower);

          const int col = tower->get_bineta();
          const int row = tower->get_binphi();

          if (col < 0 or col >= 8)
            continue;
          if (row < 0 or row >= 8)
            continue;

          const double energy_calib = tower->get_energy();
          sum_energy_calib += energy_calib;

          RawTower* tower_raw = TOWER_RAW_CEMC->getTower(key);
          assert(tower_raw);

          double energy_T = 0;
          if (not _is_sim)
            {
              RawTower_Temperature * temp_t =
                  dynamic_cast<RawTower_Temperature *>(TOWER_TEMPERATURE_EMCAL->getTower(
                      tower->get_row(), tower->get_column())); // note swap of col/row in temperature storage
              assert(temp_t);

              const double T = temp_t->get_temperature_from_time(
                  eventheader->get_TimeStamp());
              hTemperature->Fill(T);

              if (T < 25 or T > 35)
                good_temp = false;

              energy_T = TemperatureCorrection::Apply(energy_calib, T);
            }

          // recalibration
          assert(
              _recalib_const.find(make_pair(col, row)) != _recalib_const.end());
          const double energy_recalib = energy_T
              * _recalib_const[make_pair(col, row)];

          // energy sums
          sum_energy_T += energy_T;

          // calibration file
//          sdata << tower->get_energy() << "\t";
          // calibration file - only output 5x5 towers
          if (col >= max_5x5.first - 2 and col <= max_5x5.first + 2
              and row >= max_5x5.second - 2 and row <= max_5x5.second + 2)
            {
              sdata << tower->get_energy() << "\t";
            }
          else
            {
              sdata << 0 << "\t";
            }

          // cluster 3x3
          if (col >= max_3x3.first - 1 and col <= max_3x3.first + 1)
            if (row >= max_3x3.second - 1 and row <= max_3x3.second + 1)
              {
                // in cluster

                _eval_3x3_raw.average_col += abs(tower_raw->get_energy()) * col;
                _eval_3x3_raw.average_row += abs(tower_raw->get_energy()) * row;
                _eval_3x3_raw.sum_E += abs(tower_raw->get_energy());

                _eval_3x3_prod.average_col += energy_calib * col;
                _eval_3x3_prod.average_row += energy_calib * row;
                _eval_3x3_prod.sum_E += energy_calib;

                _eval_3x3_temp.average_col += energy_T * col;
                _eval_3x3_temp.average_row += energy_T * row;
                _eval_3x3_temp.sum_E += energy_T;

                _eval_3x3_recalib.average_col += energy_recalib * col;
                _eval_3x3_recalib.average_row += energy_recalib * row;
                _eval_3x3_recalib.sum_E += energy_recalib;
              }

          // cluster 5x5
          if (col >= max_5x5.first - 2 and col <= max_5x5.first + 2)
            if (row >= max_5x5.second - 2 and row <= max_5x5.second + 2)
              {
                // in cluster

                _eval_5x5_raw.average_col += abs(tower_raw->get_energy()) * col;
                _eval_5x5_raw.average_row += abs(tower_raw->get_energy()) * row;
                _eval_5x5_raw.sum_E += abs(tower_raw->get_energy());

                _eval_5x5_prod.average_col += energy_calib * col;
                _eval_5x5_prod.average_row += energy_calib * row;
                _eval_5x5_prod.sum_E += energy_calib;

                _eval_5x5_temp.average_col += energy_T * col;
                _eval_5x5_temp.average_row += energy_T * row;
                _eval_5x5_temp.sum_E += energy_T;

                _eval_5x5_recalib.average_col += energy_recalib * col;
                _eval_5x5_recalib.average_row += energy_recalib * row;
                _eval_5x5_recalib.sum_E += energy_recalib;
              }
        }
    }

  _eval_3x3_raw.reweight_clus_pol();
  _eval_5x5_raw.reweight_clus_pol();
  _eval_3x3_prod.reweight_clus_pol();
  _eval_5x5_prod.reweight_clus_pol();
  _eval_3x3_temp.reweight_clus_pol();
  _eval_5x5_temp.reweight_clus_pol();
  _eval_3x3_recalib.reweight_clus_pol();
  _eval_5x5_recalib.reweight_clus_pol();

  const double EoP = sum_energy_T / abs(_eval_run.beam_mom);
  hNormalization->Fill("good_temp", good_temp);

  bool good_data = good_e and good_temp;
  hNormalization->Fill("good_data", good_data);

  _eval_run.good_temp = good_temp;
  _eval_run.good_e = good_e;
  _eval_run.good_data = good_data;
  _eval_run.sum_energy_T = sum_energy_T;
  _eval_run.EoP = EoP;

  // E/p
  if (good_data)
    {
      if (verbosity >= 3)
        cout << __PRETTY_FUNCTION__ << " sum_energy_calib = "
            << sum_energy_calib << " sum_energy_T = " << sum_energy_T
            << " _eval_run.beam_mom = " << _eval_run.beam_mom << endl;

      TH2F * hEoP = dynamic_cast<TH2F *>(hm->getHisto("hEoP"));
      assert(hEoP);

      hEoP->Fill(EoP, abs(_eval_run.beam_mom));
    }

  // calibration file
  if (good_data and abs(_eval_run.beam_mom) >= 4
      and abs(_eval_run.beam_mom) <= 8)
    {
      assert(fdata.is_open());

      fdata << sdata.str();

      fdata << endl;
    }

  TTree * T = dynamic_cast<TTree *>(hm->getHisto("T"));
  assert(T);
  T->Fill();

  return Fun4AllReturnCodes::EVENT_OK;
}
Ejemplo n.º 2
0
//____________________________________
int EventInfoSummary::process_event(PHCompositeNode* topNode)
{
  Event* event = findNode::getClass<Event>(topNode, "PRDF");
  if (event == NULL)
  {
    if (Verbosity() >= VERBOSITY_SOME)
      cout << "EventInfoSummary::Process_Event - Event not found" << endl;
    return Fun4AllReturnCodes::DISCARDEVENT;
  }

  // search for run info
  if (event->getEvtType() != DATAEVENT)
    return Fun4AllReturnCodes::EVENT_OK;
  else  // DATAEVENT
  {
    if (verbosity >= VERBOSITY_SOME)
    {
      cout << "EventInfoSummary::process_event - with DATAEVENT events ";
      event->identify();
    }

    map<int, Packet*> packet_list;

    PHParameters Params("EventInfo");

    // spill indicator
    {
      RawTowerContainer* TOWER_RAW_SPILL_WARBLER = findNode::getClass<
          RawTowerContainer>(topNode, "TOWER_RAW_SPILL_WARBLER");
      assert(TOWER_RAW_SPILL_WARBLER);

      RawTower_Prototype4* raw_tower =
          dynamic_cast<RawTower_Prototype4*>(TOWER_RAW_SPILL_WARBLER->getTower(0));
      assert(raw_tower);

      accumulator_set<double, features<tag::variance>> acc;

      vector<double> vec_signal_samples;
      for (int i = 0; i < RawTower_Prototype4::NSAMPLES; i++)
      {
        acc(raw_tower->get_signal_samples(i));
      }

      const double warbler_rms = variance(acc);
      const bool is_in_spill = warbler_rms > (1000 * 1000);
      Params.set_double_param("beam_SPILL_WARBLER_RMS", warbler_rms);
      Params.set_double_param("beam_Is_In_Spill", is_in_spill);
      Params.set_int_param("beam_Is_In_Spill", is_in_spill);
    }

    // energy sums
    {
      RawTowerContainer* TOWER_CALIB_CEMC = findNode::getClass<
          RawTowerContainer>(topNode, "TOWER_CALIB_CEMC");
      assert(TOWER_CALIB_CEMC);

      RawTowerContainer* TOWER_CALIB_LG_HCALIN = findNode::getClass<
          RawTowerContainer>(topNode, "TOWER_CALIB_LG_HCALIN");

      RawTowerContainer* TOWER_CALIB_LG_HCALOUT = findNode::getClass<
          RawTowerContainer>(topNode, "TOWER_CALIB_LG_HCALOUT");

      // process inner HCAL
      if (TOWER_CALIB_CEMC)
      {
        double sum_energy_calib = 0;

        auto range = TOWER_CALIB_CEMC->getTowers();
        for (auto it = range.first; it != range.second; ++it)
        {
          RawTower* tower = it->second;
          assert(tower);

          const int col = tower->get_bineta();
          const int row = tower->get_binphi();

          if (col < 0 or col >= 8)
            continue;
          if (row < 0 or row >= 8)
            continue;

          const double energy_calib = tower->get_energy();
          sum_energy_calib += energy_calib;

        }  //       for (auto it = range.first; it != range.second; ++it)
        Params.set_double_param("CALIB_CEMC_Sum", sum_energy_calib);
      }  // process inner HCAL

      // process inner HCAL
      if (TOWER_CALIB_LG_HCALIN)
      {
        double sum_energy_calib = 0;

        auto range = TOWER_CALIB_LG_HCALIN->getTowers();
        for (auto it = range.first; it != range.second; ++it)
        {
          RawTower* tower = it->second;
          assert(tower);

          const int col = tower->get_bineta();
          const int row = tower->get_binphi();

          if (col < 0 or col >= 4)
            continue;
          if (row < 0 or row >= 4)
            continue;

          const double energy_calib = tower->get_energy();
          sum_energy_calib += energy_calib;

        }  //       for (auto it = range.first; it != range.second; ++it)
        Params.set_double_param("CALIB_LG_HCALIN_Sum", sum_energy_calib);
      }  // process inner HCAL

      // process outer HCAL
      if (TOWER_CALIB_LG_HCALOUT)
      {
        double sum_energy_calib = 0;

        auto range = TOWER_CALIB_LG_HCALOUT->getTowers();
        for (auto it = range.first; it != range.second; ++it)
        {
          RawTower* tower = it->second;
          assert(tower);

          const int col = tower->get_bineta();
          const int row = tower->get_binphi();

          if (col < 0 or col >= 4)
            continue;
          if (row < 0 or row >= 4)
            continue;

          const double energy_calib = tower->get_energy();
          sum_energy_calib += energy_calib;

        }  //       for (auto it = range.first; it != range.second; ++it)

        Params.set_double_param("CALIB_LG_HCALOUT_Sum", sum_energy_calib);
      }  // process outer HCAL
    }

    // generic packets
    for (typ_channel_map::const_iterator it = channel_map.begin();
         it != channel_map.end(); ++it)
    {
      const string& name = it->first;
      const channel_info& info = it->second;

      if (packet_list.find(info.packet_id) == packet_list.end())
      {
        packet_list[info.packet_id] = event->getPacket(info.packet_id);
      }

      Packet* packet = packet_list[info.packet_id];

      if (!packet)
      {
        //          if (Verbosity() >= VERBOSITY_SOME)
        cout
            << "EventInfoSummary::process_event - failed to locate packet "
            << info.packet_id << " from ";
        event->identify();

        Params.set_double_param(name, NAN);
        continue;
      }

      const int ivalue = packet->iValue(info.offset);

      const double dvalue = ivalue * info.calibration_const;

      if (verbosity >= VERBOSITY_SOME)
      {
        cout << "EventInfoSummary::process_event - " << name << " = "
             << dvalue << ", raw = " << ivalue << " @ packet "
             << info.packet_id << ", offset " << info.offset << endl;
      }

      Params.set_double_param(name, dvalue);
    }

    for (map<int, Packet*>::iterator it = packet_list.begin();
         it != packet_list.end(); ++it)
    {
      if (it->second)
        delete it->second;
    }

    Params.SaveToNodeTree(topNode, eventinfo_node_name);

    if (verbosity >= VERBOSITY_SOME)
      Params.Print();
  }
  return Fun4AllReturnCodes::EVENT_OK;
}
Ejemplo n.º 3
0
void CaloEvaluator::fillOutputNtuples(PHCompositeNode *topNode) {
  
  if (verbosity > 2) cout << "CaloEvaluator::fillOutputNtuples() entered" << endl;

  CaloRawClusterEval* clustereval = _caloevalstack->get_rawcluster_eval();
  CaloRawTowerEval*     towereval = _caloevalstack->get_rawtower_eval();
  CaloTruthEval*        trutheval = _caloevalstack->get_truth_eval();
  
  //----------------------
  // fill the Event NTuple
  //----------------------

  if (_do_gpoint_eval) {
    // need things off of the DST...
    PHG4TruthInfoContainer* truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode,"G4TruthInfo");
    if (!truthinfo) {
      cerr << PHWHERE << " ERROR: Can't find G4TruthInfo" << endl;
      exit(-1);
    }

    // need things off of the DST...
    SvtxVertexMap* vertexmap = findNode::getClass<SvtxVertexMap>(topNode,"SvtxVertexMap");

    PHG4VtxPoint *gvertex = truthinfo->GetPrimaryVtx( truthinfo->GetPrimaryVertexIndex() );
    float gvx = gvertex->get_x();
    float gvy = gvertex->get_y();
    float gvz = gvertex->get_z();

    float vx = NAN;
    float vy = NAN;
    float vz = NAN;
    if (vertexmap) {
      if (!vertexmap->empty()) {
	SvtxVertex* vertex = (vertexmap->begin()->second);
	
	vx = vertex->get_x();
	vy = vertex->get_y();
	vz = vertex->get_z();
      }
    }
	
    float gpoint_data[7] = {_ievent,
			    gvx,
			    gvy,
			    gvz,
			    vx,
			    vy,
			    vz
    };

    _ntp_gpoint->Fill(gpoint_data);   
  }
  
  //------------------------
  // fill the Gshower NTuple
  //------------------------
  
  if (_ntp_gshower) {

    if (verbosity > 1) cout << "CaloEvaluator::filling gshower ntuple..." << endl;
    
    PHG4TruthInfoContainer* truthinfo = findNode::getClass<PHG4TruthInfoContainer>(topNode,"G4TruthInfo");   
    if (!truthinfo) {
      cerr << PHWHERE << " ERROR: Can't find G4TruthInfo" << endl;
      exit(-1);
    }

    PHG4TruthInfoContainer::ConstRange range = truthinfo->GetPrimaryParticleRange();
    for (PHG4TruthInfoContainer::ConstIterator iter = range.first;
	 iter != range.second; 
	 ++iter) {
    
      PHG4Particle* primary = iter->second;

      if (primary->get_e() < _truth_e_threshold) continue;
      
      if (!_truth_trace_embed_flags.empty()) {
	if (_truth_trace_embed_flags.find(trutheval->get_embed(primary)) ==
	    _truth_trace_embed_flags.end()) continue;
      }
      
      float gparticleID = primary->get_track_id();
      float gflavor     = primary->get_pid();
      
      std::set<PHG4Hit*> g4hits = trutheval->get_shower_from_primary(primary);     
      float gnhits   = g4hits.size();	
      float gpx      = primary->get_px();
      float gpy      = primary->get_py();
      float gpz      = primary->get_pz();
      float ge       = primary->get_e();

      float gpt = sqrt(gpx*gpx+gpy*gpy);
      float geta = NAN;
      if (gpt != 0.0) geta = asinh(gpz/gpt);
      float gphi = atan2(gpy,gpx);
      
      PHG4VtxPoint* vtx = trutheval->get_vertex(primary);	
      float gvx      = vtx->get_x();
      float gvy      = vtx->get_y();
      float gvz      = vtx->get_z();
      
      float gembed   = trutheval->get_embed(primary);
      float gedep    = trutheval->get_shower_energy_deposit(primary);
      float gmrad    = trutheval->get_shower_moliere_radius(primary);

      RawCluster* cluster = clustereval->best_cluster_from(primary);

      float clusterID = NAN;
      float ntowers   = NAN;
      float eta       = NAN;
      float phi       = NAN;
      float e         = NAN;
      
      float efromtruth     = NAN;

      if (cluster) {      
	clusterID = cluster->get_id();
	ntowers   = cluster->getNTowers();
	eta       = cluster->get_eta();
	phi       = cluster->get_phi();
	e         = cluster->get_energy();
	
	efromtruth     = clustereval->get_energy_contribution(cluster, primary);
      }
      
      float shower_data[20] = {_ievent,
			       gparticleID,
			       gflavor,
			       gnhits,
			       geta,
			       gphi,
			       ge,
			       gpt,
			       gvx,
			       gvy,
			       gvz,
			       gembed,
			       gedep,
			       gmrad,
			       clusterID,
			       ntowers,
			       eta,
			       phi,
			       e,
			       efromtruth
      };

      _ntp_gshower->Fill(shower_data);
    }
  }

  //----------------------
  // fill the Tower NTuple
  //----------------------
 
  if (_do_tower_eval) {

    if (verbosity > 1) cout << "CaloEvaluator::filling tower ntuple..." << endl;
    
    string towernode = "TOWER_CALIB_" + _caloname;
    RawTowerContainer* towers = findNode::getClass<RawTowerContainer>(topNode,towernode.c_str());
    if (!towers) {
      cerr << PHWHERE << " ERROR: Can't find " << towernode << endl;
      exit(-1);
    }
    
    string towergeomnode = "TOWERGEOM_" + _caloname;
    RawTowerGeomContainer* towergeom = findNode::getClass<RawTowerGeomContainer>(topNode,towergeomnode.c_str());
    if (!towergeom) {
      cerr << PHWHERE << " ERROR: Can't find " << towergeomnode << endl;
      exit(-1);
    }
  
    RawTowerContainer::ConstRange begin_end = towers->getTowers();
    RawTowerContainer::ConstIterator rtiter;
    for (rtiter = begin_end.first; rtiter !=  begin_end.second; ++rtiter) {
      RawTower *tower = rtiter->second;

      if (tower->get_energy() < _reco_e_threshold) continue;
      
      float towerid = tower->get_id();
      float ieta    = tower->get_bineta();
      float iphi    = tower->get_binphi();
      float eta     = towergeom->get_etacenter(tower->get_bineta());
      float phi     = towergeom->get_phicenter(tower->get_binphi());
      float e       = tower->get_energy();

      PHG4Particle* primary = towereval->max_truth_primary_by_energy(tower);

      float gparticleID = NAN;
      float gflavor     = NAN;
      float gnhits   = NAN;
      float gpx      = NAN;
      float gpy      = NAN;
      float gpz      = NAN;
      float ge       = NAN;

      float gpt = NAN;
      float geta = NAN;
      float gphi = NAN;

      float gvx      = NAN;
      float gvy      = NAN;
      float gvz      = NAN;

      float gembed   = NAN;
      float gedep    = NAN;
      float gmrad    = NAN;

      float efromtruth = NAN;

      if (primary) {

	gparticleID = primary->get_track_id();
	gflavor = primary->get_pid();

	std::set<PHG4Hit*> g4hits = trutheval->get_shower_from_primary(primary);
	gnhits = g4hits.size();
	gpx = primary->get_px();
	gpy = primary->get_py();
	gpz = primary->get_pz();
	ge = primary->get_e();

	gpt = sqrt(gpx * gpx + gpy * gpy);
	if (gpt != 0.0) geta = asinh(gpz / gpt);
	gphi = atan2(gpy, gpx);

	PHG4VtxPoint* vtx = trutheval->get_vertex(primary);

	if (vtx) {
	  gvx = vtx->get_x();
	  gvy = vtx->get_y();
	  gvz = vtx->get_z();
	}

	gembed = trutheval->get_embed(primary);
	gedep = trutheval->get_shower_energy_deposit(primary);
	gmrad = trutheval->get_shower_moliere_radius(primary);

	efromtruth = towereval->get_energy_contribution(tower, primary);
      }

      float tower_data[21] = {_ievent,
			      towerid,
			      ieta,
			      iphi,
			      eta,
			      phi,
			      e,
			      gparticleID,
			      gflavor,
			      gnhits,
			      geta,
			      gphi,
			      ge,
			      gpt,
			      gvx,
			      gvy,
			      gvz,
			      gembed,
			      gedep,
			      gmrad,
			      efromtruth
      };
      
      _ntp_tower->Fill(tower_data);
    }
  }

  //------------------------
  // fill the Cluster NTuple
  //------------------------

  if (_do_cluster_eval) {
    if (verbosity > 1) cout << "CaloEvaluator::filling gcluster ntuple..." << endl;

    string clusternode = "CLUSTER_" + _caloname;
    RawClusterContainer* clusters = findNode::getClass<RawClusterContainer>(topNode,clusternode.c_str());
    if (!clusters) {
      cerr << PHWHERE << " ERROR: Can't find " << clusternode << endl;
      exit(-1);
    }
  
    // for every cluster
    for (unsigned int icluster = 0; icluster < clusters->size(); icluster++) {
      RawCluster *cluster = clusters->getCluster(icluster);

      if (cluster->get_energy() < _reco_e_threshold) continue;
      
      float clusterID = cluster->get_id();
      float ntowers   = cluster->getNTowers();
      float eta       = cluster->get_eta();
      float phi       = cluster->get_phi();
      float e         = cluster->get_energy();
      
      PHG4Particle* primary = clustereval->max_truth_primary_by_energy(cluster);

      float gparticleID = NAN;
      float gflavor     = NAN;

      float gnhits   = NAN;
      float gpx      = NAN;
      float gpy      = NAN;
      float gpz      = NAN;
      float ge       = NAN;

      float gpt = NAN;
      float geta = NAN;
      float gphi = NAN;
      
      float gvx      = NAN;
      float gvy      = NAN;
      float gvz      = NAN;
      
      float gembed   = NAN;
      float gedep    = NAN;
      float gmrad    = NAN;

      float efromtruth = NAN;

      if (primary) {
	gparticleID = primary->get_track_id();
	gflavor = primary->get_pid();
	
	std::set<PHG4Hit*> g4hits = trutheval->get_shower_from_primary(primary);
	gnhits = g4hits.size();
	gpx = primary->get_px();
	gpy = primary->get_py();
	gpz = primary->get_pz();
	ge = primary->get_e();

	gpt = sqrt(gpx * gpx + gpy * gpy);
	if (gpt != 0.0) geta = asinh(gpz / gpt);
	gphi = atan2(gpy, gpx);

	PHG4VtxPoint* vtx = trutheval->get_vertex(primary);

	if (vtx) {
	  gvx = vtx->get_x();
	  gvy = vtx->get_y();
	  gvz = vtx->get_z();
	}
	
	gembed = trutheval->get_embed(primary);
	gedep = trutheval->get_shower_energy_deposit(primary);
	gmrad = trutheval->get_shower_moliere_radius(primary);

	efromtruth = clustereval->get_energy_contribution(cluster,
							  primary);
      }
      
      float cluster_data[20] = {_ievent,
				clusterID,
				ntowers,
				eta,
				phi,
				e,
				gparticleID,
				gflavor,
				gnhits,
				geta,
				gphi,
				ge,
				gpt,
				gvx,
				gvy,
				gvz,
				gembed,
				gedep,
				gmrad,
				efromtruth
      };

      _ntp_cluster->Fill(cluster_data);
    }
  }

  return;
}