Set a variable to the last value of iteration

Hello Experts,

Sorry this problem is a little cpp based and I ask for help because I dont have much experience with it.
Inside this for loop

for (size_t i = 0; i < diphotons->size(); ++i){
edm::Ptrflashgg::DiPhotonCandidate dipho = diphotons->ptrAt(i);
edm::Ptrreco::Vertex vtx = diphotons->ptrAt(i)->vtx();
const flashgg::Photon * pho1 = dipho->leadingPhoton();
const flashgg::Photon * pho2 = dipho->subLeadingPhoton();

    float leadmva_    = pho1->phoIdMvaDWrtVtx(vtx);
    std::cout << "the photon MVA is " << leadmva_ << std::endl;
    float subleadmva_ = pho2->phoIdMvaDWrtVtx(vtx);
    std::cout << "the second photon MVA is " << subleadmva_ << std::endl;
       
    // ---- conside only di-photon candidates with photons pt>15 GeV
    if( pho1->pt() < 15 || pho2->pt() < 15)
        continue;
    
    // ---- conside only di-photon candidates with photon eta in ECAL acceptance
    if( fabs(pho1->superCluster()->eta()) > 2.5 || fabs(pho2->superCluster()->eta()) > 2.5 )
        continue;
    
    // ---- create the list of photons, unique list from all the di-photon candidates
    if ( phosTemp.size() == 0 ){
        phosTemp.push_back(pho1);
        phosTemp.push_back(pho2);
        n_pho+=2;
        continue;
    }
    else {
        float minDR1 = 999, minDR2 = 999;
        for ( size_t p = 0; p < phosTemp.size(); p++){
            float deltar1 = deltaR(phosTemp[p]->p4(), pho1->p4());
            if(deltar1 < minDR1) minDR1 = deltar1;
            
            float deltar2 = deltaR(phosTemp[p]->p4(), pho2->p4());
            if(deltar2 < minDR2) minDR2 = deltar2;
        }
        
        if ( minDR1 > 0.0001){
            n_pho++;
            phosTemp.push_back(pho1);
        }
        
        if ( minDR2 > 0.0001){
            n_pho++;
            phosTemp.push_back(pho2);
        }
    }
    
I am creating  a variable called leadmva_ and I need to access it outside this for loop.

I tried to declare it outside this for loop and then if I print out the value of leadmva_ outside the loop it is always showing to be equal to 0. I think this maybe because it is not getting set to a specified value and is just going back to its initial value.
Can anyone please help me and rectify this so that the last time leadmva_ is set inside the for loop I can somehow access it outside the loop?

Many thanks!

you should read a bit about scopes in C++:
http://en.cppreference.com/w/cpp/language/scope

your problem boils down to:

int ok = -1;
for (int i = 0; i < N; i++) {
    if (array[i] > value) {
        ok = i;
    }
}

hth,
-s

Thanks Sebastien.

I tried to implement the same

//declare outside
edm::Ptrreco::Vertex vtx_to_use;
float mva_to_use = 0;

//loop starts
for (size_t i = 0; i < diphotons->size(); ++i){
edm::Ptrflashgg::DiPhotonCandidate dipho = diphotons->ptrAt(i);
edm::Ptrreco::Vertex vtx = diphotons->ptrAt(i)->vtx();
const flashgg::Photon * pho1 = dipho->leadingPhoton();
const flashgg::Photon * pho2 = dipho->subLeadingPhoton();

    float leadmva_    = pho1->phoIdMvaDWrtVtx(vtx);
    std::cout << "the photon MVA is " << leadmva_ << std::endl;
    float subleadmva_ = pho2->phoIdMvaDWrtVtx(vtx);
    std::cout << "the second photon MVA is " << subleadmva_ << std::endl;
       
    // ---- conside only di-photon candidates with photons pt>15 GeV
    if( pho1->pt() < 15 || pho2->pt() < 15)
        continue;
    
    // ---- conside only di-photon candidates with photon eta in ECAL acceptance
    if( fabs(pho1->superCluster()->eta()) > 2.5 || fabs(pho2->superCluster()->eta()) > 2.5 )
        continue;
    
    // ---- create the list of photons, unique list from all the di-photon candidates
    if ( phosTemp.size() == 0 ){
        phosTemp.push_back(pho1);
        phosTemp.push_back(pho2);
        n_pho+=2;
        continue;
    }
    else {
        float minDR1 = 999, minDR2 = 999;
        for ( size_t p = 0; p < phosTemp.size(); p++){
            float deltar1 = deltaR(phosTemp[p]->p4(), pho1->p4());
            if(deltar1 < minDR1) minDR1 = deltar1;
            
            float deltar2 = deltaR(phosTemp[p]->p4(), pho2->p4());
            if(deltar2 < minDR2) minDR2 = deltar2;
        }
        
        if ( minDR1 > 0.0001){
            n_pho++;
            phosTemp.push_back(pho1);
        }
        
        if ( minDR2 > 0.0001){
            n_pho++;
            phosTemp.push_back(pho2);
        }
    }
    if ( i==diphotons->size()-1 || pho1->pt() > 15 || pho2->pt() > 15){
      vtx_to_use = diphotons->ptrAt(i)->vtx();
      mva_to_use = pho1->phoIdMvaDWrtVtx(vtx_to_use);
       }
}

//print outside the loop

std::cout << "MVA Value " << mva_to_use <<std::endl;

But the “MVA Value” still prints out the initial value of 0.

from the snippet you’ve posted, it doesn’t seem like mva_to_use is filled anywhere. only vtx_to_use is.

Sorry for the typo! I edited it and it still gives me values of zero.

then, either:

  • you never enter the if block where mva_to_use is filled,
  • or the value filled with is - for some reason - 0
  • or the diphotons container is empty ?
  • or the pho1 Pt-s are not in GeVs but in MeVs (so you exit the loop after the printouts) (I am not familiar with CMS edm classes and conventions)

Thanks!

I think the problem could be that I am never entering the “if” block where mva_to_use is being filled.

Can you suggest how I can check the same?

I added print statements

if ( i==diphotons->size()-1 || pho1->pt() > 15 || pho2->pt() > 15){
std::cout << “HERE 1” << std::endl;
vtx_to_use = diphotons->ptrAt(i)->vtx();
std::cout << “HERE 2” <<std::endl;
mva_to_use = pho1->phoIdMvaDWrtVtx(vtx_to_use); }

and it looks like the MVA value is being filled with a non zero number sometimes, but not always.
Could the problem lie in the i==diphotons->size()-1 statement? What I was trying to do with this was to set the value of mva_to_use to that of the last iteration

if I recap:

//declare outside
edm::Ptr<reco::Vertex> vtx_to_use;
float mva_to_use = 0;

//loop starts
for (size_t i = 0; i < diphotons->size(); ++i){
    edm::Ptr<flashgg::DiPhotonCandidate> dipho = diphotons->ptrAt(i);
    edm::Ptr<reco::Vertex> vtx = diphotons->ptrAt(i)->vtx();
    const flashgg::Photon * pho1 = dipho->leadingPhoton();
    const flashgg::Photon * pho2 = dipho->subLeadingPhoton();

    float leadmva_    = pho1->phoIdMvaDWrtVtx(vtx);
    std::cout << "the photon MVA is " << leadmva_ << std::endl;
    float subleadmva_ = pho2->phoIdMvaDWrtVtx(vtx);
    std::cout << "the second photon MVA is " << subleadmva_ << std::endl;
       
    // ---- conside only di-photon candidates with photons pt>15 GeV
    if( pho1->pt() < 15 || pho2->pt() < 15)
        continue;
    
    // ---- conside only di-photon candidates with photon eta in ECAL acceptance
    if( fabs(pho1->superCluster()->eta()) > 2.5 || fabs(pho2->superCluster()->eta()) > 2.5 )
        continue;
    
    // ---- create the list of photons, unique list from all the di-photon candidates
    if ( phosTemp.size() == 0 ){
        phosTemp.push_back(pho1);
        phosTemp.push_back(pho2);
        n_pho+=2;
        continue;
    }
    else {
        float minDR1 = 999, minDR2 = 999;
        for ( size_t p = 0; p < phosTemp.size(); p++){
            float deltar1 = deltaR(phosTemp[p]->p4(), pho1->p4());
            if(deltar1 < minDR1) minDR1 = deltar1;
            
            float deltar2 = deltaR(phosTemp[p]->p4(), pho2->p4());
            if(deltar2 < minDR2) minDR2 = deltar2;
        }
        
        if ( minDR1 > 0.0001){
            n_pho++;
            phosTemp.push_back(pho1);
        }
        
        if ( minDR2 > 0.0001){
            n_pho++;
            phosTemp.push_back(pho2);
        }
    }
    if ( i==diphotons->size()-1 || pho1->pt() > 15 || pho2->pt() > 15){
        vtx_to_use = diphotons->ptrAt(i)->vtx();
        mva_to_use = pho1->phoIdMvaDWrtVtx(vtx_to_use);
    }
}

inside the for-loop, there are 3 if-statements, one else-block and one last if-statement.

the first if is:

if( pho1->pt() < 15 || pho2->pt() < 15) { continue; }

so, right there, it could very well happen that the last item in your diphotons container doesn’t fullfil that condition, so even if you put i==diphotons->size()-1 in your last if-statement, you’ve already exited the loop so never reach that last if-statement.

at this point, there is no issue with C++.
it’s doing exactly what you told it to do. just the logic is perhaps a bit faulty.

so…
review carefully the logic in your code, decide exactly what you want to do and implement it :slight_smile:

Hi Sebastien,

Yes that was it! Thanks so much. It works now :slight_smile:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.