Exemplo n.º 1
0
int main()
{
	locationInVariableArray=0;
	previousToken=-1;
	while ((currentToken=getToken()) != EOF)
	{
		if (currentToken==' ')
		{
			continue;
		}

		printf(" previous Token %c\n", previousToken);
			printf("%c\n", currentToken);
			if (currentToken=='?')
			{
				checkForVariable();
			}else if (isalpha(currentToken))
			{
				int locationOfVariableInArray;
				locationOfVariableInArray=enterAValueToAVariable();
				if (currentToken=='=')
				{
					
					sum1=0;
					while((currentToken=getToken())!= EOF)
					{
						if (isdigit(currentToken))
						{
							printf("inside number" );
							sum1 = number();
						}else if (isalpha(currentToken))
						{
							sum1 = getVariableValue();
						}else if (currentToken=='+')
						{
							currentToken=getToken();
							if (isdigit(currentToken))
							{
								sum1 = sum1 + number();
							}else if (isalpha(currentToken))
							{
								sum1 = sum1 + getVariableValue();
							}
						}
					}
					valuesOfVariables[locationOfVariableInArray]=sum1;
				}

			}


		
	}
}
Exemplo n.º 2
0
/** Calculates a number-operator-number sequence.
  * operatorLine is the line in the middle.
  * Replaces the three lines with a single Line containing the result of the calculation.
  */
 void Calculator::calculateSubExpression(QStringList & expressionParts, int operatorLine)
 {
    double number1 = 0.0;
    double number2 = 0.0;
    double result = 0.0;
    bool ok = true;

    //check expression syntax
    if(operatorLine == 0 || operatorLine >= expressionParts.size())
        throw ExExpressionError(tr("Invalid expression. Wrong operator position."));
    QString op = expressionParts[operatorLine];

    // check numbers
    QString operand1 = expressionParts[operatorLine -1];
    if(isVariable(operand1))
        number1 = getVariableValue(operand1);
    else number1 = operand1.toDouble( &ok );
    if(!ok)
        throw ExExpressionError(tr("Invalid number format:") + " " + expressionParts[operatorLine - 1]);

    QString operand2 = expressionParts[operatorLine + 1];
    if(isVariable(operand2))
        number2 = getVariableValue(operand2);
    else number2 = operand2.toDouble( &ok );
    if(!ok)
        throw ExExpressionError(tr("Invalid number format:") + " " + expressionParts[operatorLine + 1]);

    //perform calculation
    if(op == "+")
        result = number1 + number2;
    else if(op == "-")
        result = number1 - number2;
    else if(op == "-")
        result = number1 - number2;
    else if(op == "*")
        result = number1 * number2;
    else if(op == "/")
    {
        if(number2 == 0.0)
           throw ExExpressionError(tr("Can not divide by zero."));
        else result = number1 / number2;
        if(abs(result) > 1e12)
            throw ExExpressionError(tr("Can not divide by zero."));
    }
    else if(op == "^")
       result = pow(number1, number2);
    //convert to string, copy to first line and remove line 2 and 3
    QString sResult = QString::number(result, 'G');
    expressionParts[operatorLine - 1] = sResult;
    expressionParts.removeAt(operatorLine);
    expressionParts.removeAt(operatorLine);
 }
Exemplo n.º 3
0
int getVariableValue()
{
	if (!isalpha(currentToken))
	{
		printf("inside not is alpha" );
		locationInVariableArray++;
		tempVariableName[locationInVariableArray]='\0';
		if((isVariableInArray(tempVariableName))!=-1)
		{
			printf("inside is variable" );
			printf("%s\n",tempVariableName );
			return(isVariableInArray(tempVariableName));
		}
		else
		{
			printf("no such variab");
			exit(1);
		}
	}else
	{
		printf("inside is alpah" );
		tempVariableName[locationInVariableArray]=currentToken;
		locationInVariableArray++;
		getToken();
		return(getVariableValue());
	}
}
Exemplo n.º 4
0
/** Parse the expression in m_ExpressionText
  * and calculate result.
  * Return the result as a double.
  * If quiet ist true, no signals will be emitted and m_Expressiontext will not be modified.
  * If quiet is false, Log will be updated and m_Expressiontext will be set to the result of the calculation.
  * A logTextChanged and an expressionTextChanged signal will be emitted.
  */
double Calculator::parseExpression(bool quiet)
{
    QStringList expressionParts = m_ExpressionParts; //work on a copy, keep the original
    int partCount = expressionParts.size();
    double result = 0.0;
    try{
        //Parse the expression
        while(partCount >  1)
        {
            parseSubexpression(expressionParts);
            partCount = expressionParts.size();
        }
        if(expressionParts.size() == 0)
            throw ExExpressionError(tr("Expression could not be evaluated."));
        if( ! quiet)
        {
            m_ExpressionText = m_ExpressionParts.join("") + ( "= " + expressionParts[0]);
            //Log the expression and its result
            m_LogText += m_ExpressionText + "\n";
            emit logTextChanged(m_LogText);
            //replace the expression with its result
            m_ExpressionParts.clear();
            m_ExpressionParts.append(expressionParts[0]);
            m_ExpressionText = expressionParts[0];
            emit expressionTextChanged(m_ExpressionText);
            result = m_ExpressionText.toDouble();
        }
        else //keep m_ExpressionParts and m_Expressiontext as they are
        {
            if(isVariable(expressionParts[0]))
                result = getVariableValue(expressionParts[0]);
           else result = expressionParts[0].toDouble();
        }
    }    
    catch(ExExpressionError & e)
    {
        qDebug("Calculator::parseExpression caught ExExpressionError: %s", e.what());
        if(quiet)
            throw e;
        else emit errorMessage(tr("Error"), e.what());
    }
    catch(std::exception &e)
    {
        qDebug("Calculator::parseExpression caught std::exception: %s", e.what());
        if(quiet)
            throw e;
        else emit errorMessage(tr("Error"), e.what());
    }
    catch(...)
    {
        qDebug("Calculator::parseExpression caught unknown exception.");
        if(quiet)
            throw std::exception();
        else emit errorMessage(tr("Error"),"Calculator::parseExpression caught unknown exception.");
    }
    return result;
}
Exemplo n.º 5
0
	void KeyMagicKeyboard::variablesToStrings(BinaryStringList * variables, StringList * strings) {

		for (BinaryStringList::iterator i = variables->begin(); i != variables->end(); i++) {

			const unsigned short * binString = *i;
			KeyMagicString value;

			while(*binString) {
				switch(*binString) {
				case opVARIABLE:
					binString++;
					value += getVariableValue(*binString++, variables);
					break;
				default:
					value += *binString++;
				}
			}
			strings->push_back(value);
		}
	}
Exemplo n.º 6
0
	KeyMagicString KeyMagicKeyboard::getVariableValue(int index, BinaryStringList * binStrings) {
		KeyMagicString value;

		index--;

		if (index > binStrings->size()) {
			return KeyMagicString();
		}

		const unsigned short * binRule = binStrings->at(index);

		while (*binRule) {
			if (*binRule == opVARIABLE) {
				binRule++;
				KeyMagicString value2 = getVariableValue(*binRule++, binStrings);
				value += value2;
			} else {
				value += *binRule++;
			}
		}

		return value;
	}
Exemplo n.º 7
0
void HardwareController::update(float delta)
{
    if (channels.size() < 1)
        return;
    for(float& value : channels)
        value = 0.0;
    for(HardwareMappingState& state : states)
    {
        float value;
        bool active = false;
        if (getVariableValue(state.variable, value))
        {
            switch(state.compare_operator)
            {
            case HardwareMappingState::Less: active = value < state.compare_value; break;
            case HardwareMappingState::Greater: active = value > state.compare_value; break;
            case HardwareMappingState::Equal: active = value == state.compare_value; break;
            case HardwareMappingState::NotEqual: active = value != state.compare_value; break;
            }
        }
        
        if (active && state.channel_nr < int(channels.size()))
        {
            channels[state.channel_nr] = state.effect->onActive();
        }else{
            state.effect->onInactive();
        }
    }
    for(HardwareMappingEvent& event : events)
    {
        float value;
        bool trigger = false;
        if (getVariableValue(event.trigger_variable, value))
        {
            if (event.previous_valid)
            {
                switch(event.compare_operator)
                {
                case HardwareMappingEvent::Change:
                    if (fabs(event.previous_value - value) > 0.1)
                        trigger = true;
                    break;
                case HardwareMappingEvent::Increase:
                    if (value > event.previous_value + 0.1)
                        trigger = true;
                    break;
                case HardwareMappingEvent::Decrease:
                    if (value < event.previous_value - 0.1)
                        trigger = true;
                    break;
                }
            }
            event.previous_value = value;
            event.previous_valid = true;
        }else{
            event.previous_valid = false;
        }
        if (trigger)
        {
            event.triggered = true;
            event.start_time.restart();
        }
        if (event.triggered && event.channel_nr < int(channels.size()))
        {
            channels[event.channel_nr] = event.effect->onActive();
            if (event.start_time.getElapsedTime().asSeconds() > event.runtime)
                event.triggered = false;
        }else{
            event.effect->onInactive();
        }
    }

    int idx = 0;
    for(HardwareOutputDevice* device : devices)
    {
        for(int n=0; n<device->getChannelCount(); n++)
            device->setChannelData(n, channels[idx++]);
    }
}
void analysisClass::Loop()
{
  //STDOUT("analysisClass::Loop() begins");

  if (fChain == 0) return;

  /*//------------------------------------------------------------------
   *
   *
   *      
   *      Get all Pre-cut values!
   *
   *
   *
   *///-----------------------------------------------------------------
  
   //--------------------------------------------------------------------------
   // Decide which plots to save (default is to save everything)
   //--------------------------------------------------------------------------
   
   fillSkim                         ( !true  ) ;
   fillAllPreviousCuts              ( !true  ) ;
   fillAllOtherCuts                 ( !true  ) ;
   fillAllSameLevelAndLowerLevelCuts( !true  ) ;
   fillAllCuts                      ( !true  ) ;


  //-----------------------------------------------------------------
  // Electron cut values
  //-----------------------------------------------------------------
  
  double ele_PtCut_STORE = getPreCutValue2("ele_PtCut");
  double ele_PtCut_ANA   = getPreCutValue1("ele_PtCut");
  
  double eleEta_bar      = getPreCutValue1("eleEta_bar");
  double eleEta_end_min  = getPreCutValue1("eleEta_end");
  double eleEta_end_max  = getPreCutValue2("eleEta_end");
  
  if ( ele_PtCut_STORE > ele_PtCut_ANA ) {
    STDOUT("ERROR in Electron cut values: all storage cuts must be looser or equal to analysis cuts.");
    exit(0) ;
  }

  // For WP80

  double eleMissingHitsWP             = getPreCutValue1("eleMissingHitsWP"        );
  double eleDistWP                    = getPreCutValue1("eleDistWP"               );
  double eleDCotThetaWP               = getPreCutValue1("eleDCotThetaWP"          );
  double eleCombRelIsoWP_bar          = getPreCutValue1("eleCombRelIsoWP"         );
  double eleCombRelIsoWP_end          = getPreCutValue2("eleCombRelIsoWP"         );
  double eleSigmaIetaIetaWP_bar       = getPreCutValue1("eleSigmaIetaIetaWP"      );
  double eleSigmaIetaIetaWP_end       = getPreCutValue2("eleSigmaIetaIetaWP"      );
  double eleDeltaPhiTrkSCWP_bar       = getPreCutValue1("eleDeltaPhiTrkSCWP"      );
  double eleDeltaPhiTrkSCWP_end       = getPreCutValue2("eleDeltaPhiTrkSCWP"      );
  double eleDeltaEtaTrkSCWP_bar       = getPreCutValue1("eleDeltaEtaTrkSCWP"      );
  double eleDeltaEtaTrkSCWP_end       = getPreCutValue2("eleDeltaEtaTrkSCWP"      );
  double eleUseEcalDrivenWP           = getPreCutValue1("eleUseEcalDrivenWP"      );
  double eleUseHasMatchConvWP         = getPreCutValue1("eleUseHasMatchConvWP"    );

  // For HEEP 3.1

  double eleDeltaEtaTrkSCHeep_bar     = getPreCutValue1("eleDeltaEtaTrkSCHeep"    );
  double eleDeltaEtaTrkSCHeep_end     = getPreCutValue2("eleDeltaEtaTrkSCHeep"    );
  double eleDeltaPhiTrkSCHeep_bar     = getPreCutValue1("eleDeltaPhiTrkSCHeep"    );
  double eleDeltaPhiTrkSCHeep_end     = getPreCutValue2("eleDeltaPhiTrkSCHeep"    );
  double eleHoEHeep_bar               = getPreCutValue1("eleHoEHeep"              );
  double eleHoEHeep_end               = getPreCutValue2("eleHoEHeep"              );
  double eleE2x5OverE5x5Heep_bar      = getPreCutValue1("eleE2x5OverE5x5Heep"     );
  double eleE1x5OverE5x5Heep_bar      = getPreCutValue1("eleE1x5OverE5x5Heep"     );
  double eleSigmaIetaIetaHeep_end     = getPreCutValue2("eleSigmaIetaIetaHeep"    );
  double eleEcalHcalIsoHeep_1_bar     = getPreCutValue1("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_2_bar     = getPreCutValue2("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_1_end     = getPreCutValue3("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_2_end     = getPreCutValue4("eleEcalHcalIsoHeep"      );
  double eleEcalHcalIsoHeep_PTthr_end = getPreCutValue2("eleEcalHcalIsoHeep_PTthr");
  double eleHcalIsoD2Heep_end         = getPreCutValue2("eleHcalIsoD2Heep"        );
  double eleTrkIsoHeep_bar            = getPreCutValue1("eleTrkIsoHeep"           );
  double eleTrkIsoHeep_end            = getPreCutValue2("eleTrkIsoHeep"           );
  double eleMissingHitsHeep           = getPreCutValue1("eleMissingHitsHeep"      );
  double eleUseEcalDrivenHeep         = getPreCutValue1("eleUseEcalDrivenHeep"    );

  // For HEEP 3.2

  double eleDeltaEtaTrkSCHeep32_bar     = getPreCutValue1("eleDeltaEtaTrkSCHeep32"    );
  double eleDeltaEtaTrkSCHeep32_end     = getPreCutValue2("eleDeltaEtaTrkSCHeep32"    );
  double eleDeltaPhiTrkSCHeep32_bar     = getPreCutValue1("eleDeltaPhiTrkSCHeep32"    );
  double eleDeltaPhiTrkSCHeep32_end     = getPreCutValue2("eleDeltaPhiTrkSCHeep32"    );
  double eleHoEHeep32_bar               = getPreCutValue1("eleHoEHeep32"              );
  double eleHoEHeep32_end               = getPreCutValue2("eleHoEHeep32"              );
  double eleE2x5OverE5x5Heep32_bar      = getPreCutValue1("eleE2x5OverE5x5Heep32"     );
  double eleE1x5OverE5x5Heep32_bar      = getPreCutValue1("eleE1x5OverE5x5Heep32"     );
  double eleSigmaIetaIetaHeep32_end     = getPreCutValue2("eleSigmaIetaIetaHeep32"    );
  double eleEcalHcalIsoHeep32_1_bar     = getPreCutValue1("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_2_bar     = getPreCutValue2("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_1_end     = getPreCutValue3("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_2_end     = getPreCutValue4("eleEcalHcalIsoHeep32"      );
  double eleEcalHcalIsoHeep32_PTthr_end = getPreCutValue2("eleEcalHcalIsoHeep32_PTthr");
  //double eleHcalIsoD2Heep32_end         = getPreCutValue2("eleHcalIsoD2Heep32"        );
  double eleTrkIsoHeep32_bar            = getPreCutValue1("eleTrkIsoHeep32"           );
  double eleTrkIsoHeep32_end            = getPreCutValue2("eleTrkIsoHeep32"           );
  double eleMissingHitsHeep32           = getPreCutValue1("eleMissingHitsHeep32"      );
  double eleUseEcalDrivenHeep32         = getPreCutValue1("eleUseEcalDrivenHeep32"    );

  //-----------------------------------------------------------------
  // Vertex cut values
  //-----------------------------------------------------------------

  double vertexMinimumNDOF = getPreCutValue1("vertexMinimumNDOF");
  double vertexMaxAbsZ     = getPreCutValue1("vertexMaxAbsZ");
  double vertexMaxd0       = getPreCutValue1("vertexMaxd0");

  //-----------------------------------------------------------------
  // Which algorithms to use?
  //-----------------------------------------------------------------

  int    eleAlgorithm = (int) getPreCutValue1("eleAlgorithm");

  //-----------------------------------------------------------------
  // Counters
  //-----------------------------------------------------------------
  int    N_probe_PassEleOffline = 0;
  int    N_probe_PassEleOfflineAndWP80 = 0;
  int    N_probe_PassEleOfflineAndTag = 0;  

  int    N_probe_PassEleOffline_bar = 0;
  int    N_probe_PassEleOfflineAndWP80_bar = 0;
  int    N_probe_PassEleOfflineAndTag_bar = 0;  

  int    N_probe_PassEleOffline_end = 0;
  int    N_probe_PassEleOfflineAndWP80_end = 0;
  int    N_probe_PassEleOfflineAndTag_end = 0;  

  //Histograms
  CreateUserTH1D("eta_recoEleMatchProbe_PassEleOffline", 50, -5, 5);
  CreateUserTH1D("pt_recoEleMatchProbe_PassEleOffline", 40, 0, 200);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOffline", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOffline_bar", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOffline_end", 50, 0, 50);			

  CreateUserTH1D("eta_recoEleMatchProbe_PassEleOfflineAndWP80", 50, -5, 5);
  CreateUserTH1D("pt_recoEleMatchProbe_PassEleOfflineAndWP80", 40, 0, 200);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80_bar", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80_end", 50, 0, 50);			

  CreateUserTH1D("eta_recoEleMatchProbe_PassEleOfflineAndTag", 50, -5, 5);
  CreateUserTH1D("pt_recoEleMatchProbe_PassEleOfflineAndTag", 40, 0, 200);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag_bar", 50, 0, 50);			
  CreateUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag_end", 50, 0, 50);			

  /*//------------------------------------------------------------------
   *
   *
   *      
   *      Start analysis loop!
   *
   *
   *
   *///-----------------------------------------------------------------


  Long64_t nentries = fChain->GetEntries();
  //Long64_t nentries = 100000;
  STDOUT("analysisClass::Loop(): nentries = " << nentries);

  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) { // Begin of loop over events
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    if(jentry < 10 || jentry%1000 == 0) STDOUT("analysisClass::Loop(): jentry = " << jentry << "/" << nentries );
    
    //-----------------------------------------------------------------
    // Do pileup re-weighting, if necessary
    //  --> To be done after the skim, so commented out for now
    //-----------------------------------------------------------------
    
    // double event_weight = getPileupWeight ( PileUpInteractions, isData ) ;
    
    //-----------------------------------------------------------------
    // Get trigger information, if necessary
    //-----------------------------------------------------------------

    if ( isData ) { 
      getTriggers ( HLTKey, HLTInsideDatasetTriggerNames, HLTInsideDatasetTriggerDecisions,  HLTInsideDatasetTriggerPrescales ) ;
    }
    
    //-----------------------------------------------------------------
    // Selection: Electrons
    //-----------------------------------------------------------------    

    vector<int> v_idx_ele_PtCut_IDISO_STORE;
    vector<int> v_idx_ele_PtCut_IDISO_ANA;
    vector<int> v_idx_ele_IDISO;

    //Loop over electrons
    for(int iele=0; iele<ElectronPt->size(); iele++){
      
      int passEleSel = 0;
      int isBarrel = 0;
      int isEndcap = 0;
      
      if( fabs( ElectronSCEta->at(iele) ) < eleEta_bar )       isBarrel = 1;
      if( fabs( ElectronSCEta->at(iele) ) > eleEta_end_min &&
	  fabs( ElectronSCEta->at(iele) ) < eleEta_end_max )   isEndcap = 1;

      //-----------------------------------------------------------------    
      // HEEP ID application 3.1
      //-----------------------------------------------------------------    

      if ( eleAlgorithm == 1 ) { 
	
	if(isBarrel) {		

	  if(   fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep_bar 
		&& fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep_bar 
		&& ElectronHoE->at(iele) < eleHoEHeep_bar 
		&& (ElectronE2x5OverE5x5->at(iele) >eleE2x5OverE5x5Heep_bar || ElectronE1x5OverE5x5->at(iele) > eleE1x5OverE5x5Heep_bar ) 
		&& ( ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele) ) < eleEcalHcalIsoHeep_1_bar + eleEcalHcalIsoHeep_2_bar*ElectronPt->at(iele)
		&& ElectronTrkIsoDR03->at(iele) <eleTrkIsoHeep_bar 
		&& ElectronMissingHits->at(iele) == 0 
		&& ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;		

	}//end barrel
	
	if(isEndcap) {		
	  
	  int passEcalHcalIsoCut=0;
	  if(ElectronPt->at(iele) < eleEcalHcalIsoHeep_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep_1_end) 
	    passEcalHcalIsoCut=1;
	  if(ElectronPt->at(iele) > eleEcalHcalIsoHeep_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep_1_end+eleEcalHcalIsoHeep_2_end*(ElectronPt->at(iele)-eleEcalHcalIsoHeep_PTthr_end) ) 
	    passEcalHcalIsoCut=1;
	  
	  if(fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep_end 
	     && fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep_end 
	     && ElectronHoE->at(iele) < eleHoEHeep_end 
	     && ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaHeep_end 
	     && passEcalHcalIsoCut == 1
	     && ElectronHcalIsoD2DR03->at(iele) < eleHcalIsoD2Heep_end 
	     && ElectronTrkIsoDR03->at(iele) < eleTrkIsoHeep_end 
	     && ElectronMissingHits->at(iele) == 0 
	     && ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;
	  
	}//end endcap
      }

      //-----------------------------------------------------------------    
      // WP80 ID application
      //-----------------------------------------------------------------    

      else if ( eleAlgorithm == 2 ) { 
	// ecal driven	    
	if( eleUseEcalDrivenWP && !ElectronHasEcalDrivenSeed->at(iele) ) continue;
	
	// isolation
	double ElectronCombRelIsoWP_bar  =  ( ElectronTrkIsoDR03->at(iele) 
					    + max( 0., ElectronEcalIsoDR03->at(iele) - 1. ) 
					    + ElectronHcalIsoDR03FullCone->at(iele) 
					    - rhoIso*TMath::Pi()*0.3*0.3 
					    ) / ElectronPt->at(iele) ;
	
	double ElectronCombRelIsoWP_end  =  ( ElectronTrkIsoDR03->at(iele) 
					      + ElectronEcalIsoDR03->at(iele) 
					      + ElectronHcalIsoDR03FullCone->at(iele) 
					      - rhoIso*TMath::Pi()*0.3*0.3 
					      ) / ElectronPt->at(iele) ;
	
	// conversions
	int isPhotConv = 0;
	if(eleUseHasMatchConvWP) {
	  if( ElectronHasMatchedConvPhot->at(iele) ) 
	    isPhotConv = 1;
	}
	else {
	  if( ElectronDist->at(iele) < eleDistWP && ElectronDCotTheta->at(iele) < eleDCotThetaWP )	
	    isPhotConv = 1;
	}

	if(isBarrel) {
	  
	  if( ElectronMissingHits->at(iele) <= eleMissingHitsWP              && 
	      isPhotConv == 0					             && 
	      ElectronCombRelIsoWP_bar < eleCombRelIsoWP_bar		     && 
	      ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaWP_bar       && 
	      fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCWP_bar && 
	      fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCWP_bar  )
	    passEleSel = 1;		
	  
	}//end barrel
	
	if(isEndcap) {		
	    
	  if( ElectronMissingHits->at(iele) == eleMissingHitsWP              && 
	      isPhotConv == 0						     && 
	      ElectronCombRelIsoWP_end < eleCombRelIsoWP_end		     && 
	      ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaWP_end 	     && 
	      fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCWP_end && 
	      fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCWP_end  )
	    passEleSel = 1;		
	  
	}//end endcap	
      }

      //-----------------------------------------------------------------    
      // HEEP ID application 3.2
      //-----------------------------------------------------------------    

      else if ( eleAlgorithm == 3 ) { 
	
	if(isBarrel) {
		
	  if(   fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep32_bar 
		&& fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep32_bar 
		&& ElectronHoE->at(iele) < eleHoEHeep32_bar 
		&& (ElectronE2x5OverE5x5->at(iele) >eleE2x5OverE5x5Heep32_bar || ElectronE1x5OverE5x5->at(iele) > eleE1x5OverE5x5Heep32_bar ) 
		&& ( ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele) ) < eleEcalHcalIsoHeep32_1_bar + eleEcalHcalIsoHeep32_2_bar*ElectronPt->at(iele)
		&& ElectronTrkIsoDR03->at(iele) <eleTrkIsoHeep32_bar 
		&& ElectronMissingHits->at(iele) == 0 
		&& ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;		

	}//end barrel
	
	if(isEndcap) {		
	  
	  int passEcalHcalIsoCut=0;
	  if(ElectronPt->at(iele) < eleEcalHcalIsoHeep32_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep32_1_end) 
	    passEcalHcalIsoCut=1;
	  if(ElectronPt->at(iele) > eleEcalHcalIsoHeep32_PTthr_end && 
	     (ElectronEcalIsoDR03->at(iele)+ElectronHcalIsoD1DR03->at(iele)) < eleEcalHcalIsoHeep32_1_end+eleEcalHcalIsoHeep32_2_end*(ElectronPt->at(iele)-eleEcalHcalIsoHeep32_PTthr_end) ) 
	    passEcalHcalIsoCut=1;
	  
	  if(fabs(ElectronDeltaEtaTrkSC->at(iele)) < eleDeltaEtaTrkSCHeep32_end 
	     && fabs(ElectronDeltaPhiTrkSC->at(iele)) < eleDeltaPhiTrkSCHeep32_end 
	     && ElectronHoE->at(iele) < eleHoEHeep32_end 
	     && ElectronSigmaIEtaIEta->at(iele) < eleSigmaIetaIetaHeep32_end 
	     && passEcalHcalIsoCut == 1
	     //&& ElectronHcalIsoD2DR03->at(iele) < eleHcalIsoD2Heep32_end 
	     && ElectronTrkIsoDR03->at(iele) < eleTrkIsoHeep32_end 
	     && ElectronMissingHits->at(iele) == 0 
	     && ElectronHasEcalDrivenSeed->at(iele)
	     )
	    passEleSel = 1;
	  
	}//end endcap
      }
      
      if ( passEleSel ) { 
	v_idx_ele_IDISO.push_back ( iele ) ;
	if ( ElectronPt -> at (iele) >= ele_PtCut_STORE ) v_idx_ele_PtCut_IDISO_STORE.push_back ( iele ) ;
	if ( ElectronPt -> at (iele) >= ele_PtCut_ANA   ) v_idx_ele_PtCut_IDISO_ANA  .push_back ( iele ) ;
      }

    }
    

    //-----------------------------------------------------------------
    // Selection: vertices
    //-----------------------------------------------------------------

    vector<int> v_idx_vertex_good;
    // loop over vertices
    for(int ivertex = 0; ivertex<VertexChi2->size(); ivertex++){
      if ( !(VertexIsFake->at(ivertex))
    	   && VertexNDF->at(ivertex) > vertexMinimumNDOF
    	   && fabs( VertexZ->at(ivertex) ) <= vertexMaxAbsZ
    	   && fabs( VertexRho->at(ivertex) ) <= vertexMaxd0 )
    	{
    	  v_idx_vertex_good.push_back(ivertex);
    	  //STDOUT("v_idx_vertex_good.size = "<< v_idx_vertex_good.size() );
    	}
    }

    //-----------------------------------------------------------------
    // Fill your single-object variables with values
    //-----------------------------------------------------------------

    // Set the evaluation of the cuts to false and clear the variable values and filled status
    resetCuts();
    
    fillVariableWithValue( "PassJSON", passJSON(run, ls, isData) );    
    // Set the value of the variableNames listed in the cutFile to their current value

    //event info
    fillVariableWithValue( "isData"   , isData     ) ;
    fillVariableWithValue( "bunch"    , bunch      ) ;
    fillVariableWithValue( "event"    , event      ) ;
    fillVariableWithValue( "ls"       , ls         ) ;
    fillVariableWithValue( "orbit"    , orbit      ) ;
    fillVariableWithValue( "run"      , run        ) ;

    // nVertex and pile-up
    fillVariableWithValue( "nVertex", VertexChi2->size() ) ;
    fillVariableWithValue( "nVertex_good", v_idx_vertex_good.size() ) ;

    // Trigger (L1 and HLT)
    if(isData==true)
      {
	fillVariableWithValue( "PassBPTX0", isBPTX0 ) ;
	fillVariableWithValue( "PassPhysDecl", isPhysDeclared ) ;

	bool PassHLT = false;
	if( triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v1") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v2") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v3") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v4") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v5") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v6") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v7") 
	    || triggerFired ("HLT_Ele32_CaloIdT_CaloIsoT_TrkIdT_TrkIsoT_SC17_v8") 
	    )
	  {
	    PassHLT = true;
	  }
	fillVariableWithValue( "PassHLT", PassHLT ) ;
      }
    else
      {
	fillVariableWithValue( "PassBPTX0", true ) ;
	fillVariableWithValue( "PassPhysDecl", true ) ;
	fillVariableWithValue( "PassHLT", true ) ;
      }


    //Event filters at RECO level
    fillVariableWithValue( "PassBeamScraping", !isBeamScraping ) ;
    fillVariableWithValue( "PassPrimaryVertex", isPrimaryVertex ) ;
    fillVariableWithValue( "PassHBHENoiseFilter", passHBHENoiseFilter ) ;
    fillVariableWithValue( "PassBeamHaloFilterLoose", passBeamHaloFilterLoose ) ;
    fillVariableWithValue( "PassBeamHaloFilterTight", passBeamHaloFilterTight ) ;
    fillVariableWithValue( "PassTrackingFailure", !isTrackingFailure ) ;
    fillVariableWithValue( "PassCaloBoundaryDRFilter", passCaloBoundaryDRFilter ) ;
    fillVariableWithValue( "PassEcalMaskedCellDRFilter", passEcalMaskedCellDRFilter ) ;
    
    // Evaluate cuts (but do not apply them)
    evaluateCuts();


    //Basic Event Selection
    if( passedCut("PassJSON") 
	&& passedCut("run")
	&& passedCut("PassBPTX0") 
	&& passedCut("PassBeamScraping") 
	&& passedCut("PassPrimaryVertex")
	&& passedCut("PassHBHENoiseFilter")
	&& passedCut("PassBeamHaloFilterTight") 
	&& passedCut("PassHLT")
	)
      {      
	//Loop over probes
	for(int iprobe=0; iprobe<HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTSC17HEDoubleFilterPt->size(); iprobe++)
	  {

	    TLorentzVector probe;
	    probe.SetPtEtaPhiE(HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTSC17HEDoubleFilterPt->at(iprobe),
			       HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTSC17HEDoubleFilterEta->at(iprobe),
			       HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTSC17HEDoubleFilterPhi->at(iprobe),
			       HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTSC17HEDoubleFilterEnergy->at(iprobe)
			       );

	    int isProbeBarrel = 0;
	    int isProbeEndcap = 0;
	    
	    if( fabs( probe.Eta() ) < eleEta_bar )       isProbeBarrel = 1;
	    if( fabs( probe.Eta() ) > eleEta_end_min &&
		fabs( probe.Eta() ) < eleEta_end_max )   isProbeEndcap = 1;


	    CreateAndFillUserTH1D("Pt_Probe", 200, 0, 200, probe.Pt() );

	    //Loop over tags
 	    for(int itag=0; itag<HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPt->size(); itag++)
	      {

		TLorentzVector tag;
		tag.SetPtEtaPhiE(HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPt->at(itag),
				 HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterEta->at(itag),
				 HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPhi->at(itag),
				 HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterEnergy->at(itag)
				 );	    

		CreateAndFillUserTH1D("DR_ProbeVsTag", 100, 0, 10, probe.DeltaR(tag) );

		//-----------------
		//if the tag matches in DR with the probe --> move to the next tag candidate
		if( probe.DeltaR(tag) < 0.5) 
		  continue;
		//-----------------


		//Now we should have a good (tag-probe) pair

		bool IsProbeMatchedWithOfflineEle = false;
		bool IsProbeMatchedWithTriggerWP80 = false;
		bool IsProbeMatchedWithTriggerTag = false;
		bool IsTagMatchedWithOfflineEle = false;

		//Loop over offline electrons
		TLorentzVector RecoEleMatchedWithProbe;
		TLorentzVector RecoEleMatchedWithTag;
		for(int iele=0; iele<v_idx_ele_PtCut_IDISO_ANA.size(); iele++)
		  {
		    TLorentzVector ele;
		    ele.SetPtEtaPhiE( ElectronPt->at(v_idx_ele_PtCut_IDISO_ANA[iele]),
				      ElectronEta->at(v_idx_ele_PtCut_IDISO_ANA[iele]),
				      ElectronPhi->at(v_idx_ele_PtCut_IDISO_ANA[iele]),
				      ElectronEnergy->at(v_idx_ele_PtCut_IDISO_ANA[iele])
				      );	    
		    
		    CreateAndFillUserTH1D("DR_ProbeVsEle", 100, 0, 10, probe.DeltaR(ele) );
		    CreateAndFillUserTH1D("DR_TagVsEle", 100, 0, 10, tag.DeltaR(ele) );

		    if( probe.DeltaR(ele) < 0.2 )
		      {
			IsProbeMatchedWithOfflineEle = true;
			RecoEleMatchedWithProbe = ele;
		      }

		    if( tag.DeltaR(ele) < 0.2 ) 
		      {
			IsTagMatchedWithOfflineEle = true;		    
			RecoEleMatchedWithTag = ele;
		      }

		  }

		//Loop over trigger WP80 electrons
		for(int iwp80=0; iwp80<HLTEle27WP80TrackIsoFilterPt->size(); iwp80++)
		  {
		    TLorentzVector wp80;
		    wp80.SetPtEtaPhiE(HLTEle27WP80TrackIsoFilterPt->at(iwp80),
				      HLTEle27WP80TrackIsoFilterEta->at(iwp80),
				      HLTEle27WP80TrackIsoFilterPhi->at(iwp80),
				      HLTEle27WP80TrackIsoFilterEnergy->at(iwp80)
				      );	    
		    
		    CreateAndFillUserTH1D("DR_ProbeVsWP80", 100, 0, 10, probe.DeltaR(wp80) );

		    if( probe.DeltaR(wp80) < 0.2 ) 
		      IsProbeMatchedWithTriggerWP80 = true;
		  }

		//Loop over trigger tag
		for(int itag2=0; itag2<HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPt->size(); itag2++)
		  {
		    TLorentzVector tag2;
		    tag2.SetPtEtaPhiE(HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPt->at(itag2),
				      HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterEta->at(itag2),
				      HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterPhi->at(itag2),
				      HLTEle32CaloIdTCaloIsoTTrkIdTTrkIsoTEle17TrackIsolFilterEnergy->at(itag2)
				      );	    

		    CreateAndFillUserTH1D("DR_ProbeVsTag2", 100, 0, 10, probe.DeltaR(tag2) );

		    if( probe.DeltaR(tag2) < 0.2 ) 
		      IsProbeMatchedWithTriggerTag = true;
		  }				

		TLorentzVector tag_probe_system;
		tag_probe_system = tag + probe;
		double mass = tag_probe_system.M();

		CreateAndFillUserTH1D("Mass_TagProbeSystem_NoCutOnProbe", 200, 0, 200, mass );

		if( IsProbeMatchedWithOfflineEle && IsTagMatchedWithOfflineEle )
		  {
		    CreateAndFillUserTH1D("Mass_TagProbeSystem_ProbeMatchedOfflineEle", 200, 0, 200, mass );

		    if( mass > 75 && mass < 95)
		      {
			CreateAndFillUserTH1D("Mass_TagProbeSystem_ForEfficiencyCalculation", 200, 0, 200, mass );

			FillUserTH1D("eta_recoEleMatchProbe_PassEleOffline", RecoEleMatchedWithProbe.Eta() );
			FillUserTH1D("pt_recoEleMatchProbe_PassEleOffline", RecoEleMatchedWithProbe.Pt() );			
			FillUserTH1D("NPV_recoEleMatchProbe_PassEleOffline", getVariableValue("nVertex") );			

			N_probe_PassEleOffline++;
			if( isProbeBarrel )
			  {
			    N_probe_PassEleOffline_bar++;
			    FillUserTH1D("NPV_recoEleMatchProbe_PassEleOffline_bar", getVariableValue("nVertex") );			
			  }
			if( isProbeEndcap )
			  {
			    N_probe_PassEleOffline_end++;
			    FillUserTH1D("NPV_recoEleMatchProbe_PassEleOffline_end", getVariableValue("nVertex") );			
			  }			

			if(IsProbeMatchedWithTriggerWP80)
			  {
			    FillUserTH1D("eta_recoEleMatchProbe_PassEleOfflineAndWP80", RecoEleMatchedWithProbe.Eta() );
			    FillUserTH1D("pt_recoEleMatchProbe_PassEleOfflineAndWP80", RecoEleMatchedWithProbe.Pt() );			
			    FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80", getVariableValue("nVertex") );			

			    N_probe_PassEleOfflineAndWP80++;
			    if( isProbeBarrel )
			      {
				N_probe_PassEleOfflineAndWP80_bar++;
				FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80_bar", getVariableValue("nVertex") );			
			      }
			    if( isProbeEndcap )
			      {
				N_probe_PassEleOfflineAndWP80_end++;
				FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndWP80_end", getVariableValue("nVertex") );			
			      }
			  }
			
			if(IsProbeMatchedWithTriggerTag)
			  {
			    FillUserTH1D("eta_recoEleMatchProbe_PassEleOfflineAndTag", RecoEleMatchedWithProbe.Eta() );
			    FillUserTH1D("pt_recoEleMatchProbe_PassEleOfflineAndTag", RecoEleMatchedWithProbe.Pt() );			
			    FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag", getVariableValue("nVertex") );			

			    N_probe_PassEleOfflineAndTag++;
			    if( isProbeBarrel )
			      {
				N_probe_PassEleOfflineAndTag_bar++;
				FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag_bar", getVariableValue("nVertex") );			
			      }
			    if( isProbeEndcap )
			      {
				N_probe_PassEleOfflineAndTag_end++;
				FillUserTH1D("NPV_recoEleMatchProbe_PassEleOfflineAndTag_end", getVariableValue("nVertex") );			
			      }
			  }
			
		      }//mass cut

		  }//IsProbeMatchedWithOfflineEle
		
	      }//end loop over tag


	  }//end loop over probe
	  


	//	fillVariableWithValue( "PassEcalMaskedCellDRFilter", passEcalMaskedCellDRFilter ) ;

	//triggerFired ("HLT_Photon30_CaloIdVL_v1") 


	//v_idx_ele_PtCut_IDISO_ANA.size()

	//CreateAndFillUserTH1D("ElePt_AfterPhoton30", 100, 0, 1000, ElectronPt -> at (v_idx_ele_PtCut_IDISO_ANA[0]) );

      }//end Basic Event Selection


  } // End of loop over events

  //##################################################

  /*//------------------------------------------------------------------
   *
   *
   *      
   *      End analysis loop!
   *
   *
   *
   *///-----------------------------------------------------------------

  //Printout
  double eff_WP80 = double(N_probe_PassEleOfflineAndWP80)/double(N_probe_PassEleOffline);
  double eff_Tag = double(N_probe_PassEleOfflineAndTag)/double(N_probe_PassEleOffline);

  cout << "*** ALL ***" << endl;
  cout << "N_probe_PassEleOffline: " << N_probe_PassEleOffline << endl;
  cout << "N_probe_PassEleOfflineAndWP80: " << N_probe_PassEleOfflineAndWP80 << endl;
  cout << "N_probe_PassEleOfflineAndTag: " << N_probe_PassEleOfflineAndTag << endl;
  cout << endl;
  cout << "eff_WP80: " << eff_WP80 << " +/- " << sqrt(eff_WP80 * (1- eff_WP80) / N_probe_PassEleOffline ) << endl;  
  cout << "eff_Tag: " << eff_Tag << " +/- " << sqrt(eff_Tag * (1- eff_Tag) / N_probe_PassEleOffline ) << endl;  
  cout << endl;

  double eff_WP80_bar = double(N_probe_PassEleOfflineAndWP80_bar)/double(N_probe_PassEleOffline_bar);
  double eff_Tag_bar = double(N_probe_PassEleOfflineAndTag_bar)/double(N_probe_PassEleOffline_bar);

  cout << "*** BARREL ***" << endl;
  cout << "N_probe_PassEleOffline_bar: " << N_probe_PassEleOffline_bar << endl;
  cout << "N_probe_PassEleOfflineAndWP80_bar: " << N_probe_PassEleOfflineAndWP80_bar << endl;
  cout << "N_probe_PassEleOfflineAndTag_bar: " << N_probe_PassEleOfflineAndTag_bar << endl;
  cout << endl;
  cout << "eff_WP80_bar: " << eff_WP80_bar << " +/- " << sqrt(eff_WP80_bar * (1- eff_WP80_bar) / N_probe_PassEleOffline_bar ) << endl;  
  cout << "eff_Tag_bar: " << eff_Tag_bar << " +/- " << sqrt(eff_Tag_bar * (1- eff_Tag_bar) / N_probe_PassEleOffline_bar ) << endl;  
  cout << endl;

  double eff_WP80_end = double(N_probe_PassEleOfflineAndWP80_end)/double(N_probe_PassEleOffline_end);
  double eff_Tag_end = double(N_probe_PassEleOfflineAndTag_end)/double(N_probe_PassEleOffline_end);

  cout << "*** ENDCAP ***" << endl;
  cout << "N_probe_PassEleOffline_end: " << N_probe_PassEleOffline_end << endl;
  cout << "N_probe_PassEleOfflineAndWP80_end: " << N_probe_PassEleOfflineAndWP80_end << endl;
  cout << "N_probe_PassEleOfflineAndTag_end: " << N_probe_PassEleOfflineAndTag_end << endl;
  cout << endl;
  cout << "eff_WP80_end: " << eff_WP80_end << " +/- " << sqrt(eff_WP80_end * (1- eff_WP80_end) / N_probe_PassEleOffline_end ) << endl;  
  cout << "eff_Tag_end: " << eff_Tag_end << " +/- " << sqrt(eff_Tag_end * (1- eff_Tag_end) / N_probe_PassEleOffline_end ) << endl;  
  cout << endl;


  STDOUT("analysisClass::Loop() ends");
}
Exemplo n.º 9
0
double mathexpr_eval(MathExpr *expr, double (*getVariableValue) (int))
//  Mathematica expression evaluation using a stack
{
    
// --- Note: the ExprStack array must be declared locally and not globally
//     since this function can be called recursively.

    double ExprStack[MAX_STACK_SIZE];
	MathExpr *node = expr;
	double r1, r2;
	int stackindex = 0;
    ExprStack[0] = 0.0;

	while(node != NULL)
	{
		switch (node->opcode)
		{
			case 3:  
				r1 = ExprStack[stackindex];
				stackindex--;
				r2 = ExprStack[stackindex];
				ExprStack[stackindex] = r2 + r1;
				break;
			case 4:  
				r1 = ExprStack[stackindex];
				stackindex--;
				r2 = ExprStack[stackindex];
				ExprStack[stackindex] = r2 - r1;
				break;
			case 5:  
				r1 = ExprStack[stackindex];
				stackindex--;
				r2 = ExprStack[stackindex];
				ExprStack[stackindex] = r2 * r1;
				break;
			case 6:  
				r1 = ExprStack[stackindex];
				stackindex--;
				r2 = ExprStack[stackindex];
				ExprStack[stackindex] = r2 / r1;
				break;				
			case 7:  
				stackindex++;
				ExprStack[stackindex] = node->fvalue;
				break;
			case 8:
                if (getVariableValue != NULL)
                   r1 = getVariableValue(node->ivar);
                else r1 = 0.0;
				stackindex++;
				ExprStack[stackindex] = r1;
				break;
			case 9: 
				ExprStack[stackindex] = -ExprStack[stackindex];
				break;
			case 10: 
				r1 = ExprStack[stackindex];
				r2 = cos(r1);
				ExprStack[stackindex] = r2;
				break;
			case 11: 
				r1 = ExprStack[stackindex];
				r2 = sin(r1);
				ExprStack[stackindex] = r2;
				break;
			case 12: 
				r1 = ExprStack[stackindex];
				r2 = tan(r1);
				ExprStack[stackindex] = r2;
				break;
			case 13: 
				r1 = ExprStack[stackindex];
				r2 = 1.0/tan( r1 );    
				ExprStack[stackindex] = r2;
				break;
			case 14: 
				r1 = ExprStack[stackindex];
				r2 = fabs( r1 );       
				ExprStack[stackindex] = r2;
				break;
			case 15: 
				r1 = ExprStack[stackindex];
				if (r1 < 0.0) r2 = -1.0;
				else if (r1 > 0.0) r2 = 1.0;
				else r2 = 0.0;
				ExprStack[stackindex] = r2;
				break;
			case 16: 
				r1 = ExprStack[stackindex];
				r2 = sqrt( r1 );     
				ExprStack[stackindex] = r2;
				break;
			case 17: 
				r1 = ExprStack[stackindex];
				r2 = log(r1);
				ExprStack[stackindex] = r2;
				break;
			case 18: 
				r1 = ExprStack[stackindex];
				r2 = exp(r1);
				ExprStack[stackindex] = r2;
				break;
			case 19: 
				r1 = ExprStack[stackindex];
				r2 = asin( r1 );
				ExprStack[stackindex] = r2;
				break;
			case 20: 
				r1 = ExprStack[stackindex];
				r2 = acos( r1 );      
				ExprStack[stackindex] = r2;
				break;
			case 21: 
				r1 = ExprStack[stackindex];
				r2 = atan( r1 );      
				ExprStack[stackindex] = r2;
				break;
			case 22: 
				r1 = ExprStack[stackindex];
				r2 = 1.57079632679489661923 - atan(r1);  
				ExprStack[stackindex] = r2;
				break;
			case 23:
				r1 = ExprStack[stackindex];
				r2 = (exp(r1)-exp(-r1))/2.0;
				ExprStack[stackindex] = r2;
				break;
			case 24: 
				r1 = ExprStack[stackindex];
				r2 = (exp(r1)+exp(-r1))/2.0;
				ExprStack[stackindex] = r2;
				break;
			case 25: 
				r1 = ExprStack[stackindex];
				r2 = (exp(r1)-exp(-r1))/(exp(r1)+exp(-r1));
				ExprStack[stackindex] = r2;
				break;
			case 26: 
				r1 = ExprStack[stackindex];
				r2 = (exp(r1)+exp(-r1))/(exp(r1)-exp(-r1));
				ExprStack[stackindex] = r2;
				break;
			case 27: 
				r1 = ExprStack[stackindex];
				r2 = log10( r1 );     
				ExprStack[stackindex] = r2;
				break;
            case 28:
 				r1 = ExprStack[stackindex];
				if (r1 <= 0.0) r2 = 0.0;
				else           r2 = 1.0;
				ExprStack[stackindex] = r2;
				break;
               
			case 31: 
				r1 = ExprStack[stackindex];
				r2 = ExprStack[stackindex-1];
				r2 = exp(r1*log(r2));
				ExprStack[stackindex-1] = r2;
				stackindex--;
				break;
		}
        node = node->next;
    }
    r1 = ExprStack[stackindex];
    return r1;
}
void analysisClass::Loop()
{
  //STDOUT("analysisClass::Loop() begins");
  
  if (fChain == 0) return;
   
  ////////////////////// User's code to book histos - BEGIN ///////////////////////

  TH1F *h_Mej_PAS = new TH1F ("h_Mej_PAS","h_Mej_PAS",200,0,2000);  h_Mej_PAS->Sumw2();

  ////////////////////// User's code to book histos - END ///////////////////////

  ////////////////////// User's code to get preCut values - BEGIN ///////////////

  double eleEta_bar = getPreCutValue1("eleEta_bar");
  double eleEta_end_min = getPreCutValue1("eleEta_end");
  double eleEta_end_max = getPreCutValue2("eleEta_end");

  double EleEnergyScale_EB=getPreCutValue1("EleEnergyScale_EB");
  double EleEnergyScale_EE=getPreCutValue1("EleEnergyScale_EE");
  double JetEnergyScale=getPreCutValue1("JetEnergyScale");

  // Not used when using ElectronHeepID and heepBitMask // int eleIDType = (int) getPreCutValue1("eleIDType");
  int heepBitMask_EB  =  getPreCutValue1("heepBitMask_EBGapEE") ;
  int heepBitMask_GAP =  getPreCutValue2("heepBitMask_EBGapEE") ;

  int heepBitMask_EE  =  getPreCutValue3("heepBitMask_EBGapEE") ;

  int looseBitMask_EB       =  getPreCutValue1("looseBitMask_EBGapEE") ;
  int looseBitMask_GAP      =  getPreCutValue2("looseBitMask_EBGapEE") ;
  int looseBitMask_EE       =  getPreCutValue3("looseBitMask_EBGapEE") ;
  int looseBitMask_enabled  =  getPreCutValue4("looseBitMask_EBGapEE") ;

  double muon_PtCut = getPreCutValue1("muon_PtCut");
  double muFidRegion = getPreCutValue1("muFidRegion"); // currently unused !!!
  double muNHits_minThresh = getPreCutValue1("muNHits_minThresh");
  double muTrkD0Maximum = getPreCutValue1("muTrkD0Maximum");

  double BarrelCross = getPreCutValue1("fakeRate_Barrel");
  double BarrelSlope = getPreCutValue2("fakeRate_Barrel");
  double EndcapCross = getPreCutValue1("fakeRate_Endcap");
  double EndcapSlope = getPreCutValue2("fakeRate_Endcap");

  ////////////////////// User's code to get preCut values - END /////////////////
    
  Long64_t nentries = fChain->GetEntriesFast();
  STDOUT("analysisClass::Loop(): nentries = " << nentries);   
  
  ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
  ////// If the root version is updated and rootNtupleClass regenerated,     /////
  ////// these lines may need to be updated.                                 /////    
  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) { // Begin of loop over events
    //for (Long64_t jentry=0; jentry<10000;jentry++) { // Begin of loop over events
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    if(jentry < 10 || jentry%1000 == 0) STDOUT("analysisClass::Loop(): jentry = " << jentry);   
    // if (Cut(ientry) < 0) continue;
    
    ////////////////////// User's code to be done for every event - BEGIN ///////////////////////

    //if (PtHat>=30) continue;

    // EES and JES
    if( EleEnergyScale_EB != 1 || EleEnergyScale_EE != 1 )
      {
	for(int iele=0; iele<SuperClusterPt->size(); iele++)
	  {
	    if( fabs(SuperClusterEta->at(iele)) < eleEta_bar )
	      SuperClusterPt->at(iele) *= EleEnergyScale_EB;
	    if( fabs(SuperClusterEta->at(iele)) > eleEta_end_min && fabs(SuperClusterEta->at(iele)) < eleEta_end_max )
	      SuperClusterPt->at(iele) *= EleEnergyScale_EE;
	  }
      }
    if( JetEnergyScale != 1 )
      {
	for(int ijet=0; ijet<CaloJetPt->size(); ijet++)
	  {
	    CaloJetPt->at(ijet) *= JetEnergyScale;
	  }
      }

    //## HLT
    int PassTrig = 0;
    int HLTFromRun[4] = {getPreCutValue1("HLTFromRun"),
			 getPreCutValue2("HLTFromRun"),
			 getPreCutValue3("HLTFromRun"),
			 getPreCutValue4("HLTFromRun")};
    int HLTTrigger[4] = {getPreCutValue1("HLTTrigger"),
			 getPreCutValue2("HLTTrigger"),
			 getPreCutValue3("HLTTrigger"),
			 getPreCutValue4("HLTTrigger")};
    int HLTTrgUsed;
    for (int i=0; i<4; i++) {
      if ( !isData && i != 0) continue; // For MC use HLTPhoton15 as the cleaned trigger is not in MC yet as of July 20, 2010
      if ( HLTFromRun[i] <= run ) {
 	//if(jentry == 0 ) STDOUT("run, i, HLTTrigger[i], HLTFromRun[i] = "<<run<<"\t"<<i<<"\t"<<"\t"<<HLTTrigger[i]<<"\t"<<HLTFromRun[i]);
	if (HLTTrigger[i] > 0 && HLTTrigger[i] < HLTResults->size() ) {
	  PassTrig=HLTResults->at(HLTTrigger[i]);
	  HLTTrgUsed=HLTTrigger[i];
	} else {
	  STDOUT("ERROR: HLTTrigger out of range of HLTResults: HLTTrigger = "<<HLTTrigger[i] <<"and HLTResults size = "<< HLTResults->size());
	}
      }
    }
    if(jentry == 0 ) STDOUT("Run = "<<run <<", HLTTrgUsed is number = "<<HLTTrgUsed<<" of the list HLTPathsOfInterest");
    
    // Superclusters
    vector<int> v_idx_sc_all;
    vector<int> v_idx_sc_PtCut;
    vector<int> v_idx_sc_Iso;
    
    //Create vector with indices of supercluster ordered by pT
    vector<pair<size_t, myiter> > order(SuperClusterPt->size());
    size_t n = 0;
    for (myiter it = SuperClusterPt->begin(); it != SuperClusterPt->end(); ++it, ++n)
      order[n] = make_pair(n, it);
    sort(order.begin(), order.end(), ordering());
    
    for(int isc=0; isc<order.size(); isc++)
      {
	// 	cout << "index , pT: " 
	// 	     << order[isc].first 
	// 	     << " , " 
	// 	     << *order[isc].second 
	// 	     << endl;
	v_idx_sc_all.push_back(order[isc].first); //### All superclusters ordered by pT
      }
    
    for(int isc=0;isc<v_idx_sc_all.size();isc++){

      //pT cut + ECAL acceptance cut + remove spikes (all together)
      if ( 1 - SuperClusterS4S1->at(v_idx_sc_all[isc]) > 0.95 ) continue;  

      bool Barrel = false;
      bool Endcap = false;
      if (fabs(SuperClusterEta->at(v_idx_sc_all[isc]))<eleEta_bar) Barrel = true;
      if ((fabs(SuperClusterEta->at(v_idx_sc_all[isc]))<eleEta_end_max)
	  &&(fabs(SuperClusterEta->at(v_idx_sc_all[isc]))>eleEta_end_min)) Endcap = true;
      if ( !Barrel && !Endcap) continue;

      bool PassPt = false;
      if ( SuperClusterPt->at(v_idx_sc_all[isc]) > getPreCutValue1("ele_PtCut") ) PassPt=true;
      if ( !PassPt ) continue;

      v_idx_sc_PtCut.push_back(v_idx_sc_all[isc]); //### Pt cut (+ no gaps + no spikes)

      //ID+Isolation together
      bool PassHoE = false;
      if ( SuperClusterHoE->at(v_idx_sc_all[isc])<0.05) PassHoE=true;
      if ( !PassHoE ) continue;

      bool PassEcalIso = false;
      if (Barrel && SuperClusterHEEPEcalIso->at(v_idx_sc_all[isc]) <(6+(0.01*SuperClusterPt->at(v_idx_sc_all[isc])))) 
	PassEcalIso=true;
      if (Endcap && SuperClusterPt->at(v_idx_sc_all[isc])<50 
	  && SuperClusterHEEPEcalIso->at(v_idx_sc_all[isc])<(6+(0.01*SuperClusterPt->at(v_idx_sc_all[isc])))) 
	PassEcalIso=true;
      if (Endcap && SuperClusterPt->at(v_idx_sc_all[isc])>=50 
	  && SuperClusterHEEPEcalIso->at(v_idx_sc_all[isc])<(6+(0.01*(SuperClusterPt->at(v_idx_sc_all[isc])-50)))) 
	PassEcalIso=true;
      if ( !PassEcalIso ) continue;

      v_idx_sc_Iso.push_back(v_idx_sc_all[isc]); //### Pt cut + ID+ISO

    }

    // Electrons
    vector<int> v_idx_ele_all;
    vector<int> v_idx_ele_PtCut;
    vector<int> v_idx_ele_PtCut_IDISO_noOverlap;
    int heepBitMask;

    //Loop over electrons
    for(int iele=0; iele<ElectronPt->size(); iele++)
      {

	// Reject ECAL spikes
	if ( 1 - ElectronSCS4S1->at(iele) > 0.95 ) continue; 

	//no cut on reco electrons
	v_idx_ele_all.push_back(iele); 

	//pT pre-cut on ele
	if( ElectronPt->at(iele) < getPreCutValue1("ele_PtCut") ) continue; 
	v_idx_ele_PtCut.push_back(iele);

	// get heepBitMask for EB, GAP, EE 
	if( fabs(ElectronEta->at(iele)) < eleEta_bar ) 
	  {
	    heepBitMask = heepBitMask_EB;
	  }
	else if ( fabs(ElectronEta->at(iele)) > eleEta_end_min && fabs(ElectronEta->at(iele)) < eleEta_end_max ) 
	  {
	    heepBitMask = heepBitMask_EE;
	  }
	else {
	  heepBitMask = heepBitMask_GAP;
	}

	//ID + ISO + NO overlap with good muons 
	// int eleID = ElectronPassID->at(iele);
	// if ( (eleID & 1<<eleIDType) > 0  && ElectronOverlaps->at(iele)==0 )
	if ( (ElectronHeepID->at(iele) & ~heepBitMask)==0x0  && ElectronOverlaps->at(iele)==0 )
	  {
	    //STDOUT("ElectronHeepID = " << hex << ElectronHeepID->at(iele) << " ; ElectronPassID = " << ElectronPassID->at(iele) )
	    v_idx_ele_PtCut_IDISO_noOverlap.push_back(iele);
	  }

      } // End loop over electrons

    // tight-loose electrons, if enabled from cut file
    if ( looseBitMask_enabled == 1 && v_idx_ele_PtCut_IDISO_noOverlap.size() == 1 )
      {
	//STDOUT("v_idx_ele_PtCut_IDISO_noOverlap[0] = "<<v_idx_ele_PtCut_IDISO_noOverlap[0] << " - Pt = "<<ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]));
	bool loosePtLargerThanTightPt = true;
	for(int iele=0; iele<v_idx_ele_PtCut.size(); iele++)
	  {
	    
	    if (v_idx_ele_PtCut[iele] == v_idx_ele_PtCut_IDISO_noOverlap[0])
	      {
		loosePtLargerThanTightPt = false;
		continue;
	      }
	    // get looseBitMask for EB, GAP, EE 

	    int looseBitMask;
	    if( fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) < eleEta_bar ) 
	      {
		looseBitMask = looseBitMask_EB;
	      }
	    else if ( fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) > eleEta_end_min && fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) < eleEta_end_max ) 
	      {
		looseBitMask = looseBitMask_EE;
	      }
	    else {
	      looseBitMask = looseBitMask_GAP;
	    }
	    if ( (ElectronHeepID->at(v_idx_ele_PtCut[iele]) & ~looseBitMask)==0x0  && ElectronOverlaps->at(v_idx_ele_PtCut[iele])==0 )
	      {
		if ( loosePtLargerThanTightPt )
		  {
		    v_idx_ele_PtCut_IDISO_noOverlap.insert(v_idx_ele_PtCut_IDISO_noOverlap.begin(),1,v_idx_ele_PtCut[iele]);
		  }
		else 
		  {
		    v_idx_ele_PtCut_IDISO_noOverlap.push_back(v_idx_ele_PtCut[iele]);
		  }
		break; // happy with one loose electron - Note: if you want more than 1 loose, pt sorting will not be OK with the code as is. 
	      }
	  }	
	// 	for ( int i=0; i<v_idx_ele_PtCut_IDISO_noOverlap.size(); i++)
	// 	  {
	// 	    STDOUT("i="<<i<<", v_idx_ele_PtCut_IDISO_noOverlap[i] = "<<v_idx_ele_PtCut_IDISO_noOverlap[i] << ", Pt = "<<ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[i]));
	// 	  }
      } // tight-loose electrons, if enabled from cut file

    // Jets
    vector<int> v_idx_jet_all;
    vector<int> v_idx_jet_PtCut;
    vector<int> v_idx_jet_PtCut_noOverlap;
    vector<int> v_idx_jet_PtCut_noOverlap_ID;
    vector<int> v_idx_jet_PtCut_noOverlap_ID_EtaCut;

    // Loop over jets
    for(int ijet=0; ijet<CaloJetPt->size(); ijet++)
      {
	//no cut on reco jets
	v_idx_jet_all.push_back(ijet);

	//pT pre-cut on reco jets
	if ( CaloJetPt->at(ijet) < getPreCutValue1("jet_PtCut") ) continue;
	v_idx_jet_PtCut.push_back(ijet);
      }

    vector <int> jetFlags(v_idx_jet_PtCut.size(), 0);
    int Njetflagged = 0;
    for (int isc=0; isc<v_idx_sc_Iso.size(); isc++)
      {
	TLorentzVector sc;
        sc.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[isc]),
			SuperClusterEta->at(v_idx_sc_Iso[isc]),
			SuperClusterPhi->at(v_idx_sc_Iso[isc]),0);
	TLorentzVector jet;
	double minDR=9999.;
	int ijet_minDR = -1;    
        for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++)
          {
	    if ( jetFlags[ijet] == 1 ) 
	      continue;
            jet.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut[ijet]),
			     CaloJetEta->at(v_idx_jet_PtCut[ijet]),
			     CaloJetPhi->at(v_idx_jet_PtCut[ijet]),0);
	    double DR = jet.DeltaR(sc);
	    if (DR<minDR) 
	      {
		minDR = DR;
		ijet_minDR = ijet;
	      }
	  }
	if ( minDR < getPreCutValue1("jet_ele_DeltaRcut") && ijet_minDR > -1)
	  {
	    jetFlags[ijet_minDR] = 1;
	    Njetflagged++;
	  }
      }

    //     // printouts for jet cleaning
    //     STDOUT("CLEANING ----------- v_idx_ele_PtCut_IDISO_noOverlap.size = "<< v_idx_ele_PtCut_IDISO_noOverlap.size() <<", Njetflagged = "<< Njetflagged<<", diff="<< v_idx_ele_PtCut_IDISO_noOverlap.size()-Njetflagged );
    //     if( (v_idx_ele_PtCut_IDISO_noOverlap.size()-Njetflagged) == 1 ) 
    //       {
    // 	TLorentzVector thisele;
    // 	for(int iele=0; iele<v_idx_ele_PtCut_IDISO_noOverlap.size(); iele++)
    // 	  {
    // 	    thisele.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
    // 				 ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
    // 				 ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),0);
    // 	    STDOUT("CLEANING: e"<<iele+1<<" Pt, eta, phi = "  << ", "<<thisele.Pt()<<", "<< thisele.Eta() <<", "<< thisele.Phi());
    // 	  }
    // 	TLorentzVector thisjet;
    // 	for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++)
    // 	  {
    // 	    thisjet.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut[ijet]),
    // 				 CaloJetEta->at(v_idx_jet_PtCut[ijet]),
    // 				 CaloJetPhi->at(v_idx_jet_PtCut[ijet]),0);
    // 	    STDOUT("CLEANING: j"<<ijet+1<<" Pt, eta, phi = " << ", "<<thisjet.Pt()<<", "<< thisjet.Eta() <<", "<< thisjet.Phi()<<" jetFlags="<<jetFlags[ijet] );
    // 	  }
    //       } // printouts for jet cleaning
    
    
    float JetEtaCutValue = getPreCutValue1("jet_EtaCut");
    for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++) //pT pre-cut + no overlaps with electrons + jetID
      {	
	bool passjetID = JetIdloose(CaloJetresEMF->at(v_idx_jet_PtCut[ijet]),CaloJetfHPD->at(v_idx_jet_PtCut[ijet]),CaloJetn90Hits->at(v_idx_jet_PtCut[ijet]), CaloJetEta->at(v_idx_jet_PtCut[ijet]));
	// ---- use the flag stored in rootTuples
	//if( (CaloJetOverlaps->at(v_idx_jet_PtCut[ijet]) & 1 << eleIDType) == 0  /* NO overlap with electrons */  
	// ----

	if( jetFlags[ijet] == 0  )                         /* NO overlap with electrons */  
	  //  && passjetID == true )                            /* pass JetID */
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap.push_back(v_idx_jet_PtCut[ijet]);

	if( jetFlags[ijet] == 0                           /* NO overlap with electrons */  
	    && passjetID == true )                            /* pass JetID */
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap_ID.push_back(v_idx_jet_PtCut[ijet]);

	if( jetFlags[ijet] == 0                           /* NO overlap with electrons */  
	    && passjetID == true                             /* pass JetID */
	    && fabs( CaloJetEta->at(v_idx_jet_PtCut[ijet]) ) < JetEtaCutValue )
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap_ID_EtaCut.push_back(v_idx_jet_PtCut[ijet]);

	
	//NOTE: We should verify that caloJetOverlaps match with the code above
      } // End loop over jets
    

    // Muons
    vector<int> v_idx_muon_all;
    vector<int> v_idx_muon_PtCut;
    vector<int> v_idx_muon_PtCut_IDISO;
    
    // Loop over muons  
    for(int imuon=0; imuon<MuonPt->size(); imuon++){

      // no cut on reco muons
      v_idx_muon_all.push_back(imuon);

      if ( (*MuonPt)[imuon] < muon_PtCut) continue;

      // pT pre-cut on muons
      v_idx_muon_PtCut.push_back(imuon);
      
      if ( ((*MuonTrkHits)[imuon]  >= muNHits_minThresh  )
	   &&( fabs((*MuonTrkD0)[imuon]) < muTrkD0Maximum ) 
	   &&((*MuonPassIso)[imuon]==1 ) 
	   &&((*MuonPassID)[imuon]==1) ) 
	{
	  v_idx_muon_PtCut_IDISO.push_back(imuon);
	}

    }// end loop over muons


    /////  Define the fake rate for QCD and calculate prob. for each sc to be an ele

    double p1 = 0, p2 = 0, p3 = 0;
    if (v_idx_sc_Iso.size()>=1){
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[0]))<eleEta_bar) p1 = BarrelCross + BarrelSlope*SuperClusterPt->at(v_idx_sc_Iso[0]);
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[0]))>eleEta_end_min) p1 = EndcapCross + EndcapSlope*SuperClusterPt->at(v_idx_sc_Iso[0]) ;
    }
    if (v_idx_sc_Iso.size()>=2){
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[1]))<eleEta_bar) p2 = BarrelCross + BarrelSlope*SuperClusterPt->at(v_idx_sc_Iso[1]);
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[1]))>eleEta_end_min) p2 = EndcapCross + EndcapSlope*SuperClusterPt->at(v_idx_sc_Iso[1]);
    }
    if (v_idx_sc_Iso.size()>=3){
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[2]))<eleEta_bar) p3 = BarrelCross + BarrelSlope*SuperClusterPt->at(v_idx_sc_Iso[2]);
      if (fabs(SuperClusterEta->at(v_idx_sc_Iso[2]))>eleEta_end_min) p3 = EndcapCross + EndcapSlope*SuperClusterPt->at(v_idx_sc_Iso[2]);
    }

    // Set the evaluation of the cuts to false and clear the variable values and filled status
    resetCuts();
    
    //-----

    // Set the value of the variableNames listed in the cutFile to their current value


    //     //-------------- EXAMPLE OF RESET-EVALUATE LOOP -
    //     //TEST : loop reset-evaluate cuts    
    //     fillVariableWithValue("Test",0,0.5);    
    //     evaluateCuts();
    //     resetCuts();    
    //     fillVariableWithValue("Test",0,0.25);    
    //     evaluateCuts();
    //     resetCuts();
    //     fillVariableWithValue("Test",1,1);
    //     evaluateCuts();
    //     resetCuts();
    //     fillVariableWithValue("Test",1,0.2);
    //     //---------------


    // original code from Ellie available at 
    // http://cmssw.cvs.cern.ch/cgi-bin/cmssw.cgi/UserCode/Leptoquarks/rootNtupleMacrosV2/src/analysisClass_eejjSample_QCD.C?revision=1.8&view=markup
    //here we report only the code to fill correctly the "nEle_PtCut_IDISO_noOvrlp" variable
    
    //## fill bin Nele=0
    
    //     if (v_idx_sc_Iso.size()==0) fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp", v_idx_sc_Iso.size()) ;
    //     else if (v_idx_sc_Iso.size()==1) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",0, 1-p1 ) ;
    //     }
    //     else if (v_idx_sc_Iso.size()==2) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",0, (1-p1)*(1-p2) ) ;
    //     }
    //     else if (v_idx_sc_Iso.size()>2) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",0, (1-p1)*(1-p2)*(1-p3) ) ;
    //     }

    //     evaluateCuts();
    //     resetCuts();

    //## fill bin Nele=1

    //     if (v_idx_sc_Iso.size()==1) fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",1, p1 ) ;
    //     else if (v_idx_sc_Iso.size()==2) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",1, p1 + p2 - 2*p1*p2 ) ;
    //     }
    //     else if (v_idx_sc_Iso.size()>2) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",1, p1 + p2 + p3 - 2*p1*p2 - 2*p2*p3 - 2*p1*p3   ) ;
    //     }

    //     evaluateCuts();
    //     resetCuts();

    //## fill bin Nele=2

    //     if (v_idx_sc_Iso.size()==2) fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",2, p1*p2) ;
    //     else if (v_idx_sc_Iso.size()>2) {
    //       fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",2, p1*p3 + p1*p2 + p3*p2 ) ;
    //     }

    //     evaluateCuts();
    //     resetCuts();

    //## fill bin Nele=3

    //     if (v_idx_sc_Iso.size()>2) fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp",3, p1*p2*p3) ;


    //-----

    ///  Just fill all histograms assuming exactly 2 superclusters.
    //     if (v_idx_sc_all.size()>=2) fillVariableWithValue( "nEle_all",v_idx_sc_all.size() , p1*p2 ) ;
    //     if (v_idx_sc_PtCut.size()>=2) fillVariableWithValue( "nEle_PtCut",v_idx_sc_PtCut.size(), p1*p2) ;
    if (v_idx_sc_Iso.size()>=2) fillVariableWithValue("nEle_PtCut_IDISO_noOvrlp",v_idx_sc_Iso.size(), p1*p2) ;


    /// Now fill all variables that are filled just once
    // Trigger (L1 and HLT)
    if(isData==true)
      {
	fillVariableWithValue( "PassBPTX0", isBPTX0 ) ;
	fillVariableWithValue( "PassPhysDecl", isPhysDeclared ) ;       
      }
    else
      {
	fillVariableWithValue( "PassBPTX0", true ) ;
	fillVariableWithValue( "PassPhysDecl", true ) ;       
      }

    fillVariableWithValue( "PassHLT", PassTrig ) ;

    //Event filters at RECO level
    fillVariableWithValue( "PassBeamScraping", !isBeamScraping ) ;
    fillVariableWithValue( "PassPrimaryVertex", isPrimaryVertex ) ;
    //fillVariableWithValue( "PassHBHENoiseFilter", passLooseNoiseFilter ) ;

    // nJet
    fillVariableWithValue( "nJet_all", v_idx_jet_all.size(), p1*p2 ) ;
    fillVariableWithValue( "nJet_PtCut", v_idx_jet_PtCut.size(), p1*p2 ) ;
    fillVariableWithValue( "nJet_PtCut_noOvrlp", v_idx_jet_PtCut_noOverlap.size(), p1*p2 ) ;
    fillVariableWithValue( "nJet_PtCut_noOvrlp_ID", v_idx_jet_PtCut_noOverlap_ID.size(), p1*p2 ) ;
    //TwoEleOnly
    fillVariableWithValue( "nJet_TwoEleOnly_All", v_idx_jet_PtCut_noOverlap_ID.size() , p1*p2) ;
    fillVariableWithValue( "nJet_TwoEleOnly_EtaCut", v_idx_jet_PtCut_noOverlap_ID_EtaCut.size(), p1*p2 ) ;
    //PAS June 2010
    fillVariableWithValue( "nJet_PAS_All", v_idx_jet_PtCut_noOverlap_ID.size(), p1*p2 ) ;
    fillVariableWithValue( "nJet_PAS_EtaCut", v_idx_jet_PtCut_noOverlap_ID_EtaCut.size(), p1*p2 ) ;

    // MET
    //PAS June 2010
    fillVariableWithValue( "pfMET_PAS", PFMET->at(0), p1*p2 ) ;
    fillVariableWithValue( "tcMET_PAS", TCMET->at(0), p1*p2 ) ;
    fillVariableWithValue( "caloMET_PAS", CaloMET->at(0), p1*p2 ) ;

    //ele Pt
    if( v_idx_sc_Iso.size() >= 2 ) 
      {
	fillVariableWithValue( "Pt1stEle_IDISO_NoOvrlp", SuperClusterPt->at(v_idx_sc_Iso[0]), p1*p2 );
	fillVariableWithValue( "Eta1stEle_IDISO_NoOvrlp", SuperClusterEta->at(v_idx_sc_Iso[0]), p1*p2 );
	fillVariableWithValue( "mEta1stEle_IDISO_NoOvrlp", fabs(SuperClusterEta->at(v_idx_sc_Iso[0])), p1*p2 );
	//PAS June 2010
	fillVariableWithValue( "Pt1stEle_PAS", SuperClusterPt->at(v_idx_sc_Iso[0]), p1*p2 );
	fillVariableWithValue( "Eta1stEle_PAS", SuperClusterEta->at(v_idx_sc_Iso[0]), p1*p2 );

	fillVariableWithValue( "Pt2ndEle_IDISO_NoOvrlp", SuperClusterPt->at(v_idx_sc_Iso[1]), p1*p2 );
	fillVariableWithValue( "Eta2ndEle_IDISO_NoOvrlp", SuperClusterEta->at(v_idx_sc_Iso[1]), p1*p2 );
	fillVariableWithValue( "mEta2ndEle_IDISO_NoOvrlp", fabs(SuperClusterEta->at(v_idx_sc_Iso[1])), p1*p2 );
	fillVariableWithValue( "maxMEtaEles_IDISO_NoOvrl", max( getVariableValue("mEta1stEle_IDISO_NoOvrlp"), getVariableValue("mEta2ndEle_IDISO_NoOvrlp") ) , p1*p2);
	//PAS June 2010
	fillVariableWithValue( "Pt2ndEle_PAS", SuperClusterPt->at(v_idx_sc_Iso[1]), p1*p2 );
	fillVariableWithValue( "Eta2ndEle_PAS", SuperClusterEta->at(v_idx_sc_Iso[1]), p1*p2 );
      }

    // 1st jet
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stJet_noOvrlp_ID", CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]), p1*p2 );
	fillVariableWithValue( "Eta1stJet_noOvrlp_ID", CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]) , p1*p2);
	fillVariableWithValue( "mEta1stJet_noOvrlp_ID", fabs(CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[0])), p1*p2 );
	//PAS June 2010
	fillVariableWithValue( "Pt1stJet_PAS", CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]), p1*p2 );
	fillVariableWithValue( "Eta1stJet_PAS", CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]), p1*p2 );
      }


    //cout << "2nd Jet" << endl;
    //## 2nd jet
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 2 ) 
      {
	fillVariableWithValue( "Pt2ndJet_noOvrlp_ID", CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]), p1*p2 );
	fillVariableWithValue( "Eta2ndJet_noOvrlp_ID", CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]), p1*p2 );
	fillVariableWithValue( "mEta2ndJet_noOvrlp_ID", fabs(CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[1])), p1*p2 );
	fillVariableWithValue( "maxMEtaJets_noOvrlp_ID", max( getVariableValue("mEta1stJet_noOvrlp_ID"), getVariableValue("mEta2ndJet_noOvrlp_ID") ), p1*p2 );
	//PAS June 2010
	fillVariableWithValue( "Pt2ndJet_PAS", CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]), p1*p2 );
	fillVariableWithValue( "Eta2ndJet_PAS", CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]), p1*p2 );
      }

    //## define "2ele" and "2jets" booleans
    bool TwoEle=false;
    bool TwoJets=false;
    if( v_idx_sc_Iso.size() >= 2 ) TwoEle = true;
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 2 ) TwoJets = true;

    // ST
    double calc_sT=-999.; 
    if ( (TwoEle) && (TwoJets) ) 
      {
	calc_sT = 
	  SuperClusterPt->at(v_idx_sc_Iso[0]) +
	  SuperClusterPt->at(v_idx_sc_Iso[1]) +
	  CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) +
	  CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]);
	fillVariableWithValue("sT", calc_sT, p1*p2);
	fillVariableWithValue("sT_MLQ100", calc_sT, p1*p2);
	fillVariableWithValue("sT_MLQ200", calc_sT, p1*p2);
	fillVariableWithValue("sT_MLQ250", calc_sT, p1*p2);
	fillVariableWithValue("sT_MLQ300", calc_sT, p1*p2);
	fillVariableWithValue("sT_MLQ400", calc_sT, p1*p2);       
	//PAS June 2010
	fillVariableWithValue("sT_PAS", calc_sT, p1*p2);
      }

    // ST jets
    if (TwoJets)
      {
	double calc_sTjet=-999.;
	calc_sTjet =
	  CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) + 
	  CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]) ;
	fillVariableWithValue("sTjet_PAS", calc_sTjet, p1*p2);
      }

    // Mjj
    if (TwoJets)
      {
	TLorentzVector jet1, jet2, jj;
	jet1.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[0]),0);
	jet2.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[1]),0);
	jj = jet1+jet2;
	//PAS June 2010
	fillVariableWithValue("Mjj_PAS", jj.M(), p1*p2);
      }


    // Mee
    if (TwoEle)
      {
	TLorentzVector ele1, ele2, ee;
	ele1.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[0]),
			  SuperClusterEta->at(v_idx_sc_Iso[0]),
			  SuperClusterPhi->at(v_idx_sc_Iso[0]),0);
	ele2.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[1]),
			  SuperClusterEta->at(v_idx_sc_Iso[1]),
			  SuperClusterPhi->at(v_idx_sc_Iso[1]),0);
	ee = ele1+ele2;
	fillVariableWithValue("Mee", ee.M(), p1*p2);
	//TwoEleOnly
	fillVariableWithValue("Mee_TwoEleOnly", ee.M(), p1*p2);
	fillVariableWithValue("Mee_presel", ee.M(), p1*p2);
	//
	//PAS June 2010
	fillVariableWithValue("Mee_PAS", ee.M(), p1*p2);

	double calc_sTele=-999.;
        calc_sTele =
	  SuperClusterPt->at(v_idx_sc_Iso[0]) +
	  SuperClusterPt->at(v_idx_sc_Iso[1]) ;
	fillVariableWithValue("sTele_PAS", calc_sTele, p1*p2);

	// 	if(isData==true) 
	// 	  {
	// 	    STDOUT("Two electrons: Run, LS, Event = "<<run<<", "<<ls<<", "<<event);
	// 	    STDOUT("Two electrons: M_ee, Pt_ee, Eta_ee, Phi_ee = "<<ee.M() <<", "<< ee.Pt() <<", "<< ee.Eta() <<", "<< ee.Phi());
	// 	    STDOUT("Two electrons: 1st ele Pt, eta, phi = "<< ele1.Pt() <<", "<< ele1.Eta() <<", "<< ele1.Phi() );
	// 	    STDOUT("Two electrons: 2nd ele Pt, eta, phi = "<< ele2.Pt() <<", "<< ele2.Eta() <<", "<< ele2.Phi() );
	// 	  }
      }

    // Mej 
    double Me1j1, Me1j2, Me2j1, Me2j2 = -999;
    double deltaM_e1j1_e2j2 = 9999;
    double deltaM_e1j2_e2j1 = 9999;
    double Mej_1stPair = 0;
    double Mej_2ndPair = 0;
    double deltaR_e1j1 ;
    double deltaR_e2j2 ;
    double deltaR_e1j2 ;
    double deltaR_e2j1 ;
    if ( (TwoEle) && (TwoJets) ) // TwoEle and TwoJets
      {
	TLorentzVector jet1, jet2, ele1, ele2;
	ele1.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[0]),
			  SuperClusterEta->at(v_idx_sc_Iso[0]),
			  SuperClusterPhi->at(v_idx_sc_Iso[0]),0);
	ele2.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[1]),
			  SuperClusterEta->at(v_idx_sc_Iso[1]),
			  SuperClusterPhi->at(v_idx_sc_Iso[1]),0);
	jet1.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[0]),0);
	jet2.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[1]),0);
	TLorentzVector e1j1, e1j2, e2j1, e2j2;
	e1j1 = ele1 + jet1;
	e2j2 = ele2 + jet2;
	e2j1 = ele2 + jet1;
	e1j2 = ele1 + jet2;
	Me1j1 = e1j1.M();
	Me2j2 = e2j2.M();
	Me1j2 = e1j2.M();
	Me2j1 = e2j1.M();

	deltaM_e1j1_e2j2 = Me1j1 - Me2j2;
	deltaM_e1j2_e2j1 = Me1j2 - Me2j1;


	double deltaR_e1j1 = ele1.DeltaR(jet1);
	double deltaR_e2j2 = ele2.DeltaR(jet2);
	double deltaR_e1j2 = ele1.DeltaR(jet2);
	double deltaR_e2j1 = ele2.DeltaR(jet1);

	// 	// Fill min DR between any of the 2 selected eles and any of the 2 selected jets
	// 	double minDR_2ele_2jet = min ( min(deltaR_e1j1,deltaR_e2j2) , min(deltaR_e1j2,deltaR_e2j1) );
	// 	fillVariableWithValue("minDR_2ele_2jet", minDR_2ele_2jet);

	if(fabs(deltaM_e1j1_e2j2) > fabs(deltaM_e1j2_e2j1))
	  {
	    Mej_1stPair = Me1j2;
	    Mej_2ndPair = Me2j1;
	    fillVariableWithValue("minDRej_selecPairs", min(deltaR_e1j2,deltaR_e2j1), p1*p2 );
	    fillVariableWithValue("minDRej_unselPairs", min(deltaR_e1j1,deltaR_e2j2), p1*p2 );
	  }
	else
	  {
	    Mej_1stPair = Me1j1;
	    Mej_2ndPair = Me2j2;
	    fillVariableWithValue("minDRej_selecPairs", min(deltaR_e1j1,deltaR_e2j2), p1*p2 );
	    fillVariableWithValue("minDRej_unselPairs", min(deltaR_e1j2,deltaR_e2j1), p1*p2 );
	  } 
	fillVariableWithValue("Mej_1stPair", Mej_1stPair, p1*p2);       
	fillVariableWithValue("Mej_2ndPair", Mej_2ndPair, p1*p2);
	//PAS June 2010
	h_Mej_PAS->Fill(Mej_1stPair);
	h_Mej_PAS->Fill(Mej_2ndPair);
	fillVariableWithValue("Mej_1stPair_PAS", Mej_1stPair, p1*p2);       
	fillVariableWithValue("Mej_2ndPair_PAS", Mej_2ndPair, p1*p2);

	// min and max DeltaR between electrons and any jet
	double minDeltaR_ej = 999999;
	double maxDeltaR_ej = -1;
	double thisMinDR, thisMaxDR, DR_thisjet_e1, DR_thisjet_e2;
	TLorentzVector thisjet;
	for(int ijet=0; ijet<v_idx_jet_PtCut_noOverlap_ID.size(); ijet++)
	  {
	    thisjet.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				 CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				 CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),0);
	    DR_thisjet_e1 = thisjet.DeltaR(ele1);
	    DR_thisjet_e2 = thisjet.DeltaR(ele2);
	    thisMinDR = min(DR_thisjet_e1, DR_thisjet_e2);
	    thisMaxDR = max(DR_thisjet_e1, DR_thisjet_e2);
	    if(thisMinDR < minDeltaR_ej)
	      minDeltaR_ej = thisMinDR;
	    if(thisMaxDR > maxDeltaR_ej)
	      maxDeltaR_ej = thisMaxDR;
	  } 
	fillVariableWithValue("minDeltaR_ej", minDeltaR_ej, p1*p2);
	fillVariableWithValue("maxDeltaR_ej", maxDeltaR_ej, p1*p2);

	// 	// printouts for small Mej
	// 	if(isData==true && ( Mej_1stPair<20 || Mej_2ndPair<20 ) ) // printouts for low Mej 
	// 	  {
	// 	    STDOUT("Mej<20GeV: Run, LS, Event = "<<run<<",\t"<<ls<<",\t"<<event);
	// 	    STDOUT("Mej<20GeV: Mej_1stPair = "<<Mej_1stPair <<", Mej_2ndPair = "<< Mej_2ndPair );
	// 	    STDOUT("Mej<20GeV: e1j1.M = "<<e1j1.M() <<", e2j2.M = "<<e2j2.M() <<", e1j2.M = "<<e1j2.M()  <<", e2j1.M = "<<e2j1.M()  );
	// 	    STDOUT("Mej<20GeV: deltaM_e1j1_e2j2 = "<<deltaM_e1j1_e2j2 <<", deltaM_e1j2_e2j1 = "<<deltaM_e1j2_e2j1  );
	// 	    STDOUT("Mej<20GeV: deltaR_e1j1 = "<<deltaR_e1j1 <<", deltaR_e2j2 = "<<deltaR_e2j2 <<", deltaR_e1j2 = "<<deltaR_e1j2  <<", deltaR_e2j1 = "<<deltaR_e2j1  );
	// // 	    STDOUT("Mej<20GeV: 1st ele Pt, eta, phi = "<< ele1.Pt() <<",\t"<< ele1.Eta() <<",\t"<< ele1.Phi() );
	// // 	    STDOUT("Mej<20GeV: 2nd ele Pt, eta, phi = "<< ele2.Pt() <<",\t"<< ele2.Eta() <<",\t"<< ele2.Phi() );
	// // 	    STDOUT("Mej<20GeV: 1st jet Pt, eta, phi = "<< jet1.Pt() <<",\t"<< jet1.Eta() <<",\t"<< jet1.Phi() );
	// // 	    STDOUT("Mej<20GeV: 2nd jet Pt, eta, phi = "<< jet2.Pt() <<",\t"<< jet2.Eta() <<",\t"<< jet2.Phi() );
	// 	    TLorentzVector thisele;
	// 	    for(int iele=0; iele<v_idx_sc_Iso.size(); iele++)
	// 	      {
	// 		thisele.SetPtEtaPhiM(SuperClusterPt->at(v_idx_sc_Iso[iele]),
	// 				     SuperClusterEta->at(v_idx_sc_Iso[iele]),
	// 				     SuperClusterPhi->at(v_idx_sc_Iso[iele]),0);
	// 		STDOUT("Mej<20GeV: e"<<iele+1<<" Pt, eta, phi = " 
	// 		       << ", "<<thisele.Pt()<<", "<< thisele.Eta() <<", "<< thisele.Phi()<<"; DR_j1, DR_j2 = "<< thisele.DeltaR(jet1)<<", "<<thisele.DeltaR(jet2));
	// 	      }
	// 	    TLorentzVector thisjet;
	// 	    TLorentzVector thisjet_e1, thisjet_e2;
	// 	    for(int ijet=0; ijet<v_idx_jet_PtCut_noOverlap_ID.size(); ijet++)
	// 	      {
	// 		thisjet.SetPtEtaPhiM(CaloJetPt->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
	// 				     CaloJetEta->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
	// 				     CaloJetPhi->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),0);
	// 		thisjet_e1 = thisjet + ele1;
	// 		thisjet_e2 = thisjet + ele2;
	// 		STDOUT("Mej<20GeV: j"<<ijet+1<<" Pt, eta, phi = " << ", "<<thisjet.Pt()<<", "<< thisjet.Eta() <<", "<< thisjet.Phi()<<"; DR_e1, DR_e2 = "<< thisjet.DeltaR(ele1)<<", "<<thisjet.DeltaR(ele2) << "; M_e1, M_e2 = " <<thisjet_e1.M() <<", "<<thisjet_e2.M() );
	// 	      }
	// 	  } // printouts for low Mej 

      } // TwoEle and TwoJets



    // Evaluate cuts (but do not apply them)
    evaluateCuts();

    // Fill histograms and do analysis based on cut evaluation
    //h_nEleFinal->Fill( ElectronPt->size() );
     

    //     //Large MET events passing pre-selection
    //     float METcut = 60;
    //     if( variableIsFilled("pfMET_PAS") && passedAllPreviousCuts("pfMET_PAS") && isData==true) 
    //       {

    // 	if( getVariableValue("pfMET_PAS") > METcut )
    // 	  {

    // 	    STDOUT("pfMET>60GeV: ----------- START ------------");

    // 	    STDOUT("pfMET>60GeV: Run, LS, Event = "<<run<<",\t"<<ls<<",\t"<<event);	    
    // 	    if( variableIsFilled("Pt1stEle_PAS") && variableIsFilled("Eta1stEle_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Pt1stEle_PAS,Eta1stEle_PAS = "******"Pt1stEle_PAS")<<",\t"<<getVariableValue("Eta1stEle_PAS"));
    // 	    if( variableIsFilled("Pt2ndEle_PAS") && variableIsFilled("Eta2ndEle_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Pt2ndEle_PAS,Eta2ndEle_PAS = "******"Pt2ndEle_PAS")<<",\t"<<getVariableValue("Eta2ndEle_PAS"));
    // 	    if( variableIsFilled("Pt1stJet_PAS") && variableIsFilled("Eta1stJet_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Pt1stJet_PAS,Eta1stJet_PAS = "******"Pt1stJet_PAS")<<",\t"<<getVariableValue("Eta1stJet_PAS"));
    // 	    if( variableIsFilled("Pt2ndJet_PAS") && variableIsFilled("Eta2ndJet_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Pt2ndJet_PAS,Eta2ndJet_PAS = "******"Pt2ndJet_PAS")<<",\t"<<getVariableValue("Eta2ndJet_PAS"));
    // 	    if( variableIsFilled("Mee_PAS") && variableIsFilled("Mjj_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Mee_PAS,Mjj_PAS = "******"Mee_PAS")<<",\t"<<getVariableValue("Mjj_PAS"));
    // 	    if( variableIsFilled("Mej_1stPair_PAS") && variableIsFilled("Mej_2ndPair_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: Mej_1stPair_PAS,Mej_2ndPair_PAS = "******"Mej_1stPair_PAS")
    // 		     <<",\t"<<getVariableValue("Mej_2ndPair_PAS"));
    // 	    if( variableIsFilled("pfMET_PAS") && variableIsFilled("caloMET_PAS") )	      
    // 	      STDOUT("pfMET>60GeV: pfMET_PAS,caloMET_PAS = "******"pfMET_PAS")<<",\t"<<getVariableValue("caloMET_PAS"));

    // 	    STDOUT("pfMET>60GeV: ------------ END -------------");

    // 	  }
    //       }


    //INFO
    //      // retrieve value of previously filled variables (after making sure that they were filled)
    //      double totpTEle;
    //      if ( variableIsFilled("pT1stEle") && variableIsFilled("pT2ndEle") ) 
    //        totpTEle = getVariableValue("pT1stEle")+getVariableValue("pT2ndEle");
    //      // reject events that did not pass level 0 cuts
    //      if( !passedCut("0") ) continue;
    //      // ......

        
    ////////////////////// User's code to be done for every event - END ///////////////////////
    
  } // End of loop over events
  

  ////////////////////// User's code to write histos - BEGIN ///////////////////////

  h_Mej_PAS->Write();

  ////////////////////// User's code to write histos - END ///////////////////////
  
  
  //STDOUT("analysisClass::Loop() ends");   
}
Exemplo n.º 11
0
static struct value_defn getExpressionValue(char * assembled, unsigned int * currentPoint, unsigned int length, int threadId) {
#else
static struct value_defn getExpressionValue(char * assembled, unsigned int * currentPoint, unsigned int length) {
#endif
    struct value_defn value;

    unsigned char expressionId=getUChar(&assembled[*currentPoint]);
    *currentPoint+=sizeof(unsigned char);
    if (expressionId == INTEGER_TOKEN) {
        value.type=INT_TYPE;
        value.dtype=SCALAR;
        cpy(value.data, &assembled[*currentPoint], sizeof(int));
        *currentPoint+=sizeof(int);
    } else if (expressionId == REAL_TOKEN) {
        value.type=REAL_TYPE;
        value.dtype=SCALAR;
        cpy(value.data, &assembled[*currentPoint], sizeof(float));
        *currentPoint+=sizeof(float);
    } else if (expressionId == BOOLEAN_TOKEN) {
        value.type=BOOLEAN_TYPE;
        value.dtype=SCALAR;
        cpy(value.data, &assembled[*currentPoint], sizeof(int));
        *currentPoint+=sizeof(int);
    } else if (expressionId == STRING_TOKEN) {
        value.type=STRING_TYPE;
        char * strPtr=assembled + *currentPoint;
        cpy(&value.data, &strPtr, sizeof(char*));
        *currentPoint+=(slength(strPtr)+1);
        value.dtype=SCALAR;
    } else if (expressionId == NONE_TOKEN) {
        value.type=NONE_TYPE;
        value.dtype=SCALAR;
    } else if (expressionId ==FN_ADDR_TOKEN) {
        value.type=FN_ADDR_TYPE;
        value.dtype=SCALAR;
        cpy(value.data, &assembled[*currentPoint], sizeof(unsigned short));
        *currentPoint+=sizeof(unsigned short);
    } else if (expressionId == LET_TOKEN) {
#ifdef HOST_INTERPRETER
        *currentPoint=handleLet(assembled, *currentPoint, length, 0, threadId);
        value=getExpressionValue(assembled, currentPoint, length, threadId);
#else
        *currentPoint=handleLet(assembled, *currentPoint, length, 0);
        value=getExpressionValue(assembled, currentPoint, length);
#endif
    } else if (expressionId == ARRAY_TOKEN) {
        int i, j, repetitionMultiplier=1, numItems=getInt(&assembled[*currentPoint]), totalSize=numItems;
        *currentPoint+=sizeof(int);
        unsigned char hasRepetition=getUChar(&assembled[*currentPoint]), ndims=1;
        *currentPoint+=sizeof(unsigned char);
        if (hasRepetition) {
#ifdef HOST_INTERPRETER
            struct value_defn repetitionV=getExpressionValue(assembled, currentPoint, length, threadId);
#else
            struct value_defn repetitionV=getExpressionValue(assembled, currentPoint, length);
#endif
            cpy(&repetitionMultiplier, repetitionV.data, sizeof(int));
            totalSize*=repetitionMultiplier;
        }
#ifdef HOST_INTERPRETER
        char * address=getHeapMemory(sizeof(unsigned char) + (sizeof(int)*(totalSize+1)), 0, threadId);
#else
        char * address=getHeapMemory(sizeof(unsigned char) + (sizeof(int)*(totalSize+1)), 0, currentSymbolEntries, symbolTable);
#endif
        cpy(value.data, &address, sizeof(char*));
        ndims=ndims | (1 << 4);
        cpy(address, &ndims, sizeof(unsigned char));
        address+=sizeof(unsigned char);
        cpy(address, &totalSize, sizeof(int));
        unsigned int prevCP=*currentPoint;
        for (j=0; j<repetitionMultiplier; j++) {
            *currentPoint=prevCP;
            for (i=0; i<numItems; i++) {
#ifdef HOST_INTERPRETER
                struct value_defn itemV=getExpressionValue(assembled, currentPoint, length, threadId);
#else
                struct value_defn itemV=getExpressionValue(assembled, currentPoint, length);
#endif
                cpy(address+((i+(j*numItems)+1) * sizeof(int)), itemV.data, sizeof(int));
                value.type=itemV.type;
            }
        }
        value.dtype=ARRAY;
    } else if (expressionId == FNCALL_TOKEN || expressionId == FNCALL_BY_VAR_TOKEN) {
#ifdef HOST_INTERPRETER
        unsigned int fnAddr;
        *currentPoint=handleFnCall(assembled, *currentPoint, &fnAddr, length, expressionId == FNCALL_BY_VAR_TOKEN ? 1:0, threadId);
        fnLevel[threadId]++;
        value=processAssembledCode(assembled, fnAddr, length, threadId);
        clearVariablesToLevel(fnLevel[threadId], threadId);
        fnLevel[threadId]--;
#else
        unsigned int fnAddr;
        *currentPoint=handleFnCall(assembled, *currentPoint, &fnAddr, length, expressionId == FNCALL_BY_VAR_TOKEN ? 1:0);
        fnLevel++;
        value=processAssembledCode(assembled, fnAddr, length);
        clearVariablesToLevel(fnLevel);
        fnLevel--;
#endif
    } else if (expressionId == NATIVE_TOKEN) {
#ifdef HOST_INTERPRETER
        *currentPoint=handleNative(assembled, *currentPoint, length, &value, threadId);
#else
        *currentPoint=handleNative(assembled, *currentPoint, length, &value);
#endif
    } else if (expressionId == IDENTIFIER_TOKEN || expressionId == ARRAYACCESS_TOKEN) {
        unsigned short variable_id=getUShort(&assembled[*currentPoint]);
        *currentPoint+=sizeof(unsigned short);
#ifdef HOST_INTERPRETER
        struct symbol_node* variableSymbol=getVariableSymbol(variable_id, fnLevel[threadId], threadId, 1);
#else
        struct symbol_node* variableSymbol=getVariableSymbol(variable_id, fnLevel, 1);
#endif
        if (expressionId == IDENTIFIER_TOKEN) {
            if (variableSymbol->value.dtype==SCALAR) {
                value=getVariableValue(variableSymbol, -1);
            } else if (variableSymbol->value.dtype==ARRAY) {
                value.dtype=ARRAY;
                value.type=variableSymbol->value.type;
                cpy(value.data, variableSymbol->value.data, sizeof(char*));
            }
        } else if (expressionId == ARRAYACCESS_TOKEN) {
#ifdef HOST_INTERPRETER
            int targetIndex=getArrayAccessorIndex(variableSymbol, assembled, currentPoint, length, threadId);
#else
            int targetIndex=getArrayAccessorIndex(variableSymbol, assembled, currentPoint, length);
#endif
            value=getVariableValue(variableSymbol, targetIndex);
        }
    } else if (expressionId == ADD_TOKEN || expressionId == SUB_TOKEN || expressionId == MUL_TOKEN ||
               expressionId == DIV_TOKEN || expressionId == MOD_TOKEN || expressionId == POW_TOKEN) {
#ifdef HOST_INTERPRETER
        value=computeExpressionResult(expressionId, assembled, currentPoint, length, threadId);
#else
        value=computeExpressionResult(expressionId, assembled, currentPoint, length);
#endif
    } else if (expressionId == EQ_TOKEN || expressionId == NEQ_TOKEN || expressionId == GT_TOKEN || expressionId == GEQ_TOKEN ||
               expressionId == LT_TOKEN || expressionId == LEQ_TOKEN || expressionId == IS_TOKEN) {
        *currentPoint-=sizeof(unsigned char);
#ifdef HOST_INTERPRETER
        int retVal=determine_logical_expression(assembled, currentPoint, length, threadId);
#else
        int retVal=determine_logical_expression(assembled, currentPoint, length);
#endif
        value.type=BOOLEAN_TYPE;
        value.dtype=SCALAR;
        cpy(value.data, &retVal, sizeof(int));
    }
    return value;
}

/**
 * Computes the result of a simple mathematical expression, if one is a real and the other an integer
 * then raises to be a real
 */
#ifdef HOST_INTERPRETER
static struct value_defn computeExpressionResult(unsigned char operator, char * assembled, unsigned int * currentPoint,
        unsigned int length, int threadId) {
#else
static struct value_defn computeExpressionResult(unsigned char operator, char * assembled, unsigned int * currentPoint,
        unsigned int length) {
#endif
    struct value_defn value;
#ifdef HOST_INTERPRETER
    struct value_defn v1=getExpressionValue(assembled, currentPoint, length, threadId);
    struct value_defn v2=getExpressionValue(assembled, currentPoint, length, threadId);
#else
    struct value_defn v1=getExpressionValue(assembled, currentPoint, length);
    struct value_defn v2=getExpressionValue(assembled, currentPoint, length);
#endif
    value.type=v1.type==INT_TYPE && v2.type==INT_TYPE ? INT_TYPE : v1.type==STRING_TYPE || v2.type==STRING_TYPE ? STRING_TYPE : REAL_TYPE;
    value.dtype=SCALAR;
    if (value.type==INT_TYPE) {
        int i, value1=getInt(v1.data), value2=getInt(v2.data), result;
        if (operator==ADD_TOKEN) result=value1+value2;
        if (operator==SUB_TOKEN) result=value1-value2;
        if (operator==MUL_TOKEN) result=value1*value2;
        if (operator==DIV_TOKEN) result=value1/value2;
        if (operator==MOD_TOKEN) result=value1%value2;
        if (operator==POW_TOKEN) {
            result=value2 == 0 ? 1 : value1;
            for (i=1; i<value2; i++) result=result*value1;
        }
        cpy(&value.data, &result, sizeof(int));
    } else if (value.type==REAL_TYPE) {
        float value1=getFloat(v1.data);
        float value2=getFloat(v2.data);
        float result;
        if (v1.type==INT_TYPE) value1=(float) getInt(v1.data);
        if (v2.type==INT_TYPE) {
            value2=(float) getInt(v2.data);
            if (operator == POW_TOKEN) {
                int i;
                result=value2 == 0 ? 1 : value1;
                for (i=1; i<(int) value2; i++) result=result*value1;
            }
        }
        if (operator == ADD_TOKEN) result=value1+value2;
        if (operator == SUB_TOKEN) result=value1-value2;
        if (operator == MUL_TOKEN) result=value1*value2;
        if (operator == DIV_TOKEN) result=value1/value2;
        cpy(&value.data, &result, sizeof(float));
    } else if (value.type==STRING_TYPE) {
        if (operator == ADD_TOKEN) {
#ifdef HOST_INTERPRETER
            return performStringConcatenation(v1, v2, threadId);
#else
            return performStringConcatenation(v1, v2, currentSymbolEntries, symbolTable);
#endif
        } else {
            raiseError(ERR_ONLY_ADDITION_STR);
        }
    }
    return value;
}

/**
 * Retrieves the absolute array target index based upon the provided index expression(s) and dimensions of the array itself. Does some error checking
 * to ensure that the configured values do not exceed the size
 */
#ifdef HOST_INTERPRETER
static int getArrayAccessorIndex(struct symbol_node* variableSymbol, char * assembled, unsigned int * currentPoint, unsigned int length, int threadId) {
#else
static int getArrayAccessorIndex(struct symbol_node* variableSymbol, char * assembled, unsigned int * currentPoint, unsigned int length) {
#endif
    struct value_defn index;
    int i, j, runningWeight, spec_weight, num_weights, specificIndex=0, provIdx;
    unsigned int totSize=1;
    unsigned char num_dims=getUChar(&assembled[*currentPoint]), array_dims, needsExtension=0, allowedExtension;
    *currentPoint+=sizeof(unsigned char);

    char * arraymemory;
    cpy(&arraymemory, variableSymbol->value.data, sizeof(char*));
    cpy(&array_dims, arraymemory, sizeof(unsigned char));
    allowedExtension=(array_dims >> 4) & 1;
    array_dims=array_dims&0xF;
    arraymemory+=sizeof(unsigned char);

    if (num_dims > array_dims) raiseError(ERR_TOO_MANY_ARR_INDEX);

    for (i=0; i<num_dims; i++) {
        num_weights=array_dims-(i+1);
        runningWeight=1;
        for (j=num_weights; j<0; j--) {
            cpy(&spec_weight, &arraymemory[sizeof(int) * (array_dims-j)], sizeof(int));
            runningWeight*=spec_weight;
        }
#ifdef HOST_INTERPRETER
        index=getExpressionValue(assembled, currentPoint, length, threadId);
#else
        index=getExpressionValue(assembled, currentPoint, length);
#endif
        cpy(&spec_weight, &arraymemory[sizeof(int) * i], sizeof(int));
        totSize*=spec_weight;
        provIdx=getInt(index.data);
        if (provIdx < 0) {
            raiseError(ERR_NEG_ARR_INDEX);
        } else if (provIdx >= spec_weight) {
            if (!allowedExtension) raiseError(ERR_ARR_INDEX_EXCEED_SIZE);
            spec_weight=provIdx+1;
            cpy(&arraymemory[sizeof(int) * i], &spec_weight, sizeof(int));
            needsExtension=1;
        }
        specificIndex+=(runningWeight * provIdx);
    }
    if (needsExtension) {
        unsigned int newSize=1;
        for (i=0; i<num_dims; i++) {
            cpy(&spec_weight, &arraymemory[sizeof(int) * i], sizeof(int));
            newSize*=spec_weight;
        }
#ifdef HOST_INTERPRETER
        char * newmem=getHeapMemory((sizeof(int) * newSize) + (sizeof(int) * num_dims) + sizeof(unsigned char), 0, threadId);
#else
        char * newmem=getHeapMemory((sizeof(int) * newSize) + (sizeof(int) * num_dims) + sizeof(unsigned char), 0, currentSymbolEntries, symbolTable);
#endif
        arraymemory-=sizeof(unsigned char);
        cpy(newmem, arraymemory, (sizeof(int) * totSize) + (sizeof(int) * num_dims) + sizeof(unsigned char));
#ifdef HOST_INTERPRETER
        freeMemoryInHeap(arraymemory, threadId);
#else
        freeMemoryInHeap(arraymemory);
#endif
        cpy(variableSymbol->value.data, &newmem, sizeof(char*));
    }
    return specificIndex;
}

/**
 * Retrieves the symbol entry of a variable based upon its id
 */
#ifdef HOST_INTERPRETER
static struct symbol_node* getVariableSymbol(unsigned short id, unsigned char lvl, int threadId, int followAlias) {
#else
static struct symbol_node* getVariableSymbol(unsigned short id, unsigned char lvl, int followAlias) {
#endif
    int i;
#ifdef HOST_INTERPRETER
    for (i=0; i<=currentSymbolEntries[threadId]; i++) {
        if (symbolTable[threadId][i].id == id && symbolTable[threadId][i].state != UNALLOCATED && (symbolTable[threadId][i].level == 0 || symbolTable[threadId][i].level==lvl)) {
            if (followAlias && symbolTable[threadId][i].state == ALIAS) {
                return getVariableSymbol(symbolTable[threadId][i].alias, lvl-1, threadId, 1);
            } else {
                return &(symbolTable[threadId])[i];
            }
        }
#else
    for (i=0; i<=currentSymbolEntries; i++) {
        if (symbolTable[i].id == id && symbolTable[i].state != UNALLOCATED && (symbolTable[i].level == 0 || symbolTable[i].level==lvl)) {
            if (followAlias && symbolTable[i].state == ALIAS) {
                return getVariableSymbol(symbolTable[i].alias, lvl-1, 1);
            } else {
                return &symbolTable[i];
            }
        }
#endif
    }
    int zero=0;
#ifdef HOST_INTERPRETER
    int newEntryLocation=getSymbolTableEntryId(threadId);
    symbolTable[threadId][newEntryLocation].id=id;
    symbolTable[threadId][newEntryLocation].state=ALLOCATED;
    symbolTable[threadId][newEntryLocation].level=lvl;
    symbolTable[threadId][newEntryLocation].value.type=INT_TYPE;
    cpy(symbolTable[threadId][newEntryLocation].value.data, &zero, sizeof(int));
    return &symbolTable[threadId][newEntryLocation];
#else
    int newEntryLocation=getSymbolTableEntryId();
    symbolTable[newEntryLocation].id=id;
    symbolTable[newEntryLocation].level=lvl;
    symbolTable[newEntryLocation].state=ALLOCATED;
    symbolTable[newEntryLocation].value.type=INT_TYPE;
    symbolTable[newEntryLocation].value.dtype=SCALAR;
    cpy(symbolTable[newEntryLocation].value.data, &zero, sizeof(int));
    return &symbolTable[newEntryLocation];
#endif
}
#ifdef HOST_INTERPRETER
static int getSymbolTableEntryId(int threadId) {
#else
static int getSymbolTableEntryId(void) {
#endif
    int i;
#ifdef HOST_INTERPRETER
    for (i=0; i<=currentSymbolEntries[threadId]; i++) {
        if (symbolTable[threadId][i].state == UNALLOCATED) return i;
    }
    return ++currentSymbolEntries[threadId];
#else
    for (i=0; i<=currentSymbolEntries; i++) {
        if (symbolTable[i].state == UNALLOCATED) return i;
    }
    return ++currentSymbolEntries;
#endif
}

#ifdef HOST_INTERPRETER
static void clearVariablesToLevel(unsigned char clearLevel, int threadId) {
#else
static void clearVariablesToLevel(unsigned char clearLevel) {
#endif
    int i;
    char * smallestMemoryAddress=0, *ptr;
#ifdef HOST_INTERPRETER
    for (i=0; i<=currentSymbolEntries[threadId]; i++) {
        if (symbolTable[threadId][i].level >= clearLevel && symbolTable[threadId][i].state != UNALLOCATED) {
            symbolTable[threadId][i].state=UNALLOCATED;
            if (symbolTable[threadId][i].value.dtype==SCALAR && symbolTable[threadId][i].value.type != STRING_TYPE) {
                cpy(&ptr, symbolTable[threadId][i].value.data, sizeof(int*));
                if (ptr != 0 && (smallestMemoryAddress == 0 || smallestMemoryAddress > ptr)) smallestMemoryAddress=ptr;
            }
        }
    }
#else
    for (i=0; i<=currentSymbolEntries; i++) {
        if (symbolTable[i].level >= clearLevel && symbolTable[i].state != UNALLOCATED) {
            symbolTable[i].state=UNALLOCATED;
            if (symbolTable[i].value.dtype==SCALAR && symbolTable[i].value.type != STRING_TYPE) {
                cpy(&ptr, symbolTable[i].value.data, sizeof(char*));
                if (ptr != 0 && (smallestMemoryAddress == 0 || smallestMemoryAddress > ptr)) smallestMemoryAddress=ptr;
            }
        }
    }
#endif
    if (smallestMemoryAddress != 0) clearFreedStackFrames(smallestMemoryAddress);
}

/**
 * Sets a variables value in memory as pointed to by symbol table
 */
void setVariableValue(struct symbol_node* variableSymbol, struct value_defn value, int index) {
    variableSymbol->value.type=value.type;
    if (value.type == STRING_TYPE) {
        cpy(&variableSymbol->value.data, &value.data, sizeof(char*));
    } else {
        int currentAddress=getInt(variableSymbol->value.data);
        if (currentAddress == 0) {
            char * address=getStackMemory(sizeof(int) * index, 0);
            cpy(variableSymbol->value.data, &address, sizeof(char*));
            cpy(address+((index+1) *4), value.data, sizeof(int));
        } else {
            char * ptr;
            cpy(&ptr, variableSymbol->value.data, sizeof(char*));
            if (variableSymbol->value.dtype == ARRAY) {
                unsigned char num_dims;
                cpy(&num_dims, ptr, sizeof(unsigned char));
                num_dims=num_dims & 0xF;
                ptr+=((index+num_dims)*sizeof(int)) + sizeof(unsigned char);
            } else {
                ptr+=(index+1)*sizeof(int);
            }
            cpy(ptr, value.data, sizeof(int));
        }
    }
}

/**
 * Retrieves a variable value from memory, which the symbol table points to
 */
struct value_defn getVariableValue(struct symbol_node* variableSymbol, int index) {
    struct value_defn val;
    val.type=variableSymbol->value.type;
    val.dtype=SCALAR;
    if (variableSymbol->value.type == STRING_TYPE) {
        cpy(&val.data, &variableSymbol->value.data, sizeof(int*));
    } else {
        char * ptr;
        cpy(&ptr, variableSymbol->value.data, sizeof(char*));
        if (variableSymbol->value.dtype == ARRAY) {
            unsigned char num_dims;
            cpy(&num_dims, ptr, sizeof(unsigned char));
            num_dims=num_dims & 0xF;
            ptr+=((index+num_dims)*sizeof(int)) + sizeof(unsigned char);
        } else {
            ptr+=(index+1)*sizeof(int);
        }
        cpy(val.data, ptr, sizeof(char*));
    }
    return val;
}

static unsigned char getUChar(void* data) {
    unsigned char v;
    cpy(&v, data, sizeof(unsigned char));
    return v;
}

/**
 * Helper method to get an unsigned short from data (needed as casting to integer directly requires 4 byte alignment
 * which we do not want to enforce as it wastes memory.)
 */
static unsigned short getUShort(void* data) {
    unsigned short v;
    cpy(&v, data, sizeof(unsigned short));
    return v;
}
Exemplo n.º 12
0
static int determine_logical_expression(char * assembled, unsigned int * currentPoint, unsigned int length, int threadId) {
#else
static int determine_logical_expression(char * assembled, unsigned int * currentPoint, unsigned int length) {
#endif
    unsigned char expressionId=getUChar(&assembled[*currentPoint]);
    *currentPoint+=sizeof(unsigned char);
    if (expressionId == AND_TOKEN || expressionId == OR_TOKEN) {
#ifdef HOST_INTERPRETER
        int s1=determine_logical_expression(assembled, currentPoint, length, threadId);
        int s2=determine_logical_expression(assembled, currentPoint, length, threadId);
#else
        int s1=determine_logical_expression(assembled, currentPoint, length);
        int s2=determine_logical_expression(assembled, currentPoint, length);
#endif
        if (expressionId == AND_TOKEN) return s1 && s2;
        if (expressionId == OR_TOKEN) return s1 || s2;
    } else if (expressionId == NOT_TOKEN) {
#ifdef HOST_INTERPRETER
        struct value_defn expression=getExpressionValue(assembled, currentPoint, length, threadId);
#else
        struct value_defn expression=getExpressionValue(assembled, currentPoint, length);
#endif
        int value=getInt(expression.data);
        if (value > 0) return 0;
        return 1;
    } else if (expressionId == EQ_TOKEN || expressionId == NEQ_TOKEN || expressionId == GT_TOKEN || expressionId == GEQ_TOKEN ||
               expressionId == LT_TOKEN || expressionId == LEQ_TOKEN || expressionId == IS_TOKEN) {
#ifdef HOST_INTERPRETER
        struct value_defn expression1=getExpressionValue(assembled, currentPoint, length, threadId);
        struct value_defn expression2=getExpressionValue(assembled, currentPoint, length, threadId);
#else
        struct value_defn expression1=getExpressionValue(assembled, currentPoint, length);
        struct value_defn expression2=getExpressionValue(assembled, currentPoint, length);
#endif
        if (expressionId == IS_TOKEN) {
            if (expression1.type == NONE_TYPE && expression2.type == NONE_TYPE) return 1;
            if (expression1.type != expression2.type) return 0;
            char *ptr1, *ptr2;
            cpy(&ptr1, expression1.data, sizeof(char*));
            cpy(&ptr2, expression2.data, sizeof(char*));
            return ptr1 == ptr2;
        }
        if (expression1.type == expression2.type && expression1.type == INT_TYPE) {
            int value1=getInt(expression1.data);
            int value2=getInt(expression2.data);
            if (expressionId == EQ_TOKEN) return value1 == value2;
            if (expressionId == NEQ_TOKEN) return value1 != value2;
            if (expressionId == GT_TOKEN) return value1 > value2;
            if (expressionId == GEQ_TOKEN) return value1 >= value2;
            if (expressionId == LT_TOKEN) return value1 < value2;
            if (expressionId == LEQ_TOKEN) return value1 <= value2;
        } else if ((expression1.type == REAL_TYPE || expression1.type == INT_TYPE) &&
                   (expression2.type == REAL_TYPE || expression2.type == INT_TYPE)) {
            float value1=getFloat(expression1.data);
            float value2=getFloat(expression2.data);
            if (expression1.type==INT_TYPE) value1=(float) getInt(expression1.data);
            if (expression2.type==INT_TYPE) value2=(float) getInt(expression2.data);
            if (expressionId == EQ_TOKEN) return value1 == value2;
            if (expressionId == NEQ_TOKEN) return value1 != value2;
            if (expressionId == GT_TOKEN) return value1 > value2;
            if (expressionId == GEQ_TOKEN) return value1 >= value2;
            if (expressionId == LT_TOKEN) return value1 < value2;
            if (expressionId == LEQ_TOKEN) return value1 <= value2;
        } else if (expression1.type == expression2.type && expression1.type == STRING_TYPE) {
            if (expressionId == EQ_TOKEN) {
                return checkStringEquality(expression1, expression2);
            } else if (expressionId == NEQ_TOKEN) {
                return !checkStringEquality(expression1, expression2);
            } else {
                raiseError(ERR_STR_ONLYTEST_EQ);
            }
        } else if (expression1.type == expression2.type && expression1.type == NONE_TYPE) {
            if (expressionId == EQ_TOKEN || expressionId == IS_TOKEN) {
                return 1;
            } else if (expressionId == NEQ_TOKEN) {
                return 0;
            } else {
                raiseError(ERR_NONE_ONLYTEST_EQ);
            }
        }
    } else if (expressionId == BOOLEAN_TOKEN) {
        struct value_defn value;
        cpy(value.data, &assembled[*currentPoint], sizeof(int));
        *currentPoint+=sizeof(int);
        return getInt(value.data) > 0;
    } else if (expressionId == IDENTIFIER_TOKEN || expressionId == ARRAYACCESS_TOKEN) {
        struct value_defn value;
        unsigned short variable_id=getUShort(&assembled[*currentPoint]);
        *currentPoint+=sizeof(unsigned short);
#ifdef HOST_INTERPRETER
        struct symbol_node* variableSymbol=getVariableSymbol(variable_id, fnLevel[threadId], threadId, 1);
#else
        struct symbol_node* variableSymbol=getVariableSymbol(variable_id, fnLevel, 1);
#endif
        value=getVariableValue(variableSymbol, -1);
        if (expressionId == ARRAYACCESS_TOKEN) {
#ifdef HOST_INTERPRETER
            int targetIndex=getArrayAccessorIndex(variableSymbol, assembled, currentPoint, length, threadId);
#else
            int targetIndex=getArrayAccessorIndex(variableSymbol, assembled, currentPoint, length);
#endif
            value=getVariableValue(variableSymbol, targetIndex);
        }
        if (value.type == BOOLEAN_TYPE) {
            return getInt(value.data) > 0;
        }
        return 0;
    } else {
        *currentPoint-=sizeof(unsigned char);
        struct value_defn expValue;
#ifdef HOST_INTERPRETER
        expValue=getExpressionValue(assembled, currentPoint, length, threadId);
#else
        expValue=getExpressionValue(assembled, currentPoint, length);
#endif
        if (expValue.type == BOOLEAN_TYPE || expValue.type == INT_TYPE) {
            return getInt(expValue.data) > 0;
        }
    }
    return 0;
}
Exemplo n.º 13
0
static unsigned int handleGoto(char * assembled, unsigned int currentPoint, unsigned int length, int threadId) {
#else
static unsigned int handleGoto(char * assembled, unsigned int currentPoint, unsigned int length) {
#endif
    return getUShort(&assembled[currentPoint]);
}

#ifdef HOST_INTERPRETER
static unsigned int handleNative(char * assembled, unsigned int currentPoint, unsigned int length, struct value_defn * returnValue, int threadId) {
#else
static unsigned int handleNative(char * assembled, unsigned int currentPoint, unsigned int length, struct value_defn * returnValue) {
#endif
    unsigned char fnCode=getUChar(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned char);
    unsigned short numArgs=getUShort(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned short);

    struct value_defn toPassValues[numArgs];
    int i;
    for (i=0; i<numArgs; i++) {
#ifdef HOST_INTERPRETER
        toPassValues[i]=getExpressionValue(assembled, &currentPoint, length, threadId);
#else
        toPassValues[i]=getExpressionValue(assembled, &currentPoint, length);
#endif
    }
    if (returnValue != NULL) {
#ifdef HOST_INTERPRETER
        callNativeFunction(returnValue, fnCode, numArgs, toPassValues, numActiveCores[threadId], localCoreId[threadId], currentSymbolEntries[threadId], symbolTable[threadId], threadId);
#else
        callNativeFunction(returnValue, fnCode, numArgs, toPassValues, numActiveCores, localCoreId, currentSymbolEntries, symbolTable);
#endif
    } else {
        struct value_defn dummy;
#ifdef HOST_INTERPRETER
        callNativeFunction(&dummy, fnCode, numArgs, toPassValues, numActiveCores[threadId], localCoreId[threadId], currentSymbolEntries[threadId], symbolTable[threadId], threadId);
#else
        callNativeFunction(&dummy, fnCode, numArgs, toPassValues, numActiveCores, localCoreId, currentSymbolEntries, symbolTable);
#endif
    }
    return currentPoint;
}

/**
 * Calls some function and stores the call point in the function call stack for returning from this function
 */
#ifdef HOST_INTERPRETER
static unsigned int handleFnCall(char * assembled, unsigned int currentPoint, unsigned int * functionAddress, unsigned int length, char calledByVar, int threadId) {
#else
static unsigned int handleFnCall(char * assembled, unsigned int currentPoint, unsigned int * functionAddress, unsigned int length, char calledByVar) {
#endif
    unsigned short fnAddress;
    if (calledByVar) {
#ifdef HOST_INTERPRETER
        struct symbol_node* callVar=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel[threadId], threadId, 1);
#else
        struct symbol_node* callVar=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel, 1);
#endif
        if (callVar->value.type != FN_ADDR_TYPE) raiseError(ERR_FNCALL_VAR_NOT_CONTAINING_FN_PTR);
        char *ptr;
        cpy(&ptr, callVar->value.data, sizeof(char*));
        fnAddress=getUShort(ptr);
    } else {
        fnAddress=getUShort(&assembled[currentPoint]);
    }
    currentPoint+=sizeof(unsigned short);

    unsigned short fnNumArgs=getUShort(&assembled[fnAddress]);
    fnAddress+=sizeof(unsigned short);

    unsigned short callerNumArgs=getUShort(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned short);
    struct symbol_node* srcSymbol, *targetSymbol;
    int i, numArgs;
    numArgs=fnNumArgs > callerNumArgs ? fnNumArgs : callerNumArgs;
    for (i=0; i<numArgs; i++) {
        if (i<callerNumArgs && i<fnNumArgs) {
#ifdef HOST_INTERPRETER
            srcSymbol=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel[threadId], threadId, 0);
            targetSymbol=getVariableSymbol(getUShort(&assembled[fnAddress]), fnLevel[threadId]+1, threadId, 0);
#else
            srcSymbol=getVariableSymbol(getUShort(&assembled[currentPoint]), fnLevel, 0);
            targetSymbol=getVariableSymbol(getUShort(&assembled[fnAddress]), fnLevel+1, 0);
#endif
            targetSymbol->state=ALIAS;
            targetSymbol->alias=srcSymbol->id;
        }
        if (i<callerNumArgs) currentPoint+=sizeof(unsigned short);
        if (i<fnNumArgs) fnAddress+=sizeof(unsigned short);
    }
    *functionAddress=fnAddress;
    return currentPoint;
}

/**
 * Loop iteration
 */
#ifdef HOST_INTERPRETER
static unsigned int handleFor(char * assembled, unsigned int currentPoint, unsigned int length, int threadId) {
#else
static unsigned int handleFor(char * assembled, unsigned int currentPoint, unsigned int length) {
#endif
    unsigned short loopIncrementerId=getUShort(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned short);
    unsigned short loopVariantId=getUShort(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned short);
#ifdef HOST_INTERPRETER
    struct symbol_node* incrementVarSymbol=getVariableSymbol(loopIncrementerId, fnLevel[threadId], threadId, 1);
    struct symbol_node* variantVarSymbol=getVariableSymbol(loopVariantId, fnLevel[threadId], threadId, 1);
    struct value_defn expressionVal=getExpressionValue(assembled, &currentPoint, length, threadId);
#else
    struct symbol_node* incrementVarSymbol=getVariableSymbol(loopIncrementerId, fnLevel, 1);
    struct symbol_node* variantVarSymbol=getVariableSymbol(loopVariantId, fnLevel, 1);
    struct value_defn expressionVal=getExpressionValue(assembled, &currentPoint, length);
#endif
    unsigned short blockLen=getUShort(&assembled[currentPoint]);
    currentPoint+=sizeof(unsigned short);

    char * ptr;
    int singleSize, arrSize=1, i, headersize;
    unsigned char numDims;
    cpy(&ptr, expressionVal.data, sizeof(char*));
    cpy(&numDims, ptr, sizeof(unsigned char));
    numDims=numDims & 0xF;
    for (i=0; i<numDims; i++) {
        cpy(&singleSize, &ptr[1+(i*sizeof(unsigned int))], sizeof(unsigned int));
        arrSize*=singleSize;
    }
    headersize=sizeof(unsigned char) + (sizeof(unsigned int) * numDims);
    struct value_defn varVal=getVariableValue(incrementVarSymbol, -1);
    int incrementVal=getInt(varVal.data);
    if (incrementVal < arrSize) {
        struct value_defn nextElement;
        nextElement.type=expressionVal.type;
        cpy(&nextElement.data, ptr+((incrementVal*sizeof(int)) + headersize), sizeof(int));
        setVariableValue(variantVarSymbol, nextElement, -1);
        return currentPoint;
    }
    currentPoint+=(blockLen+sizeof(unsigned short)+sizeof(unsigned char));
    return currentPoint;
}

/**
 * Conditional, with or without else block
 */
#ifdef HOST_INTERPRETER
static unsigned int handleIf(char * assembled, unsigned int currentPoint, unsigned int length, int threadId) {
    int conditionalResult=determine_logical_expression(assembled, &currentPoint, length, threadId);
#else
static unsigned int handleIf(char * assembled, unsigned int currentPoint, unsigned int length) {
    int conditionalResult=determine_logical_expression(assembled, &currentPoint, length);
#endif
    if (conditionalResult) return currentPoint+sizeof(unsigned short);
    unsigned short blockLen=getUShort(&assembled[currentPoint]);
    return currentPoint+sizeof(unsigned short)+blockLen;
}
void analysisClass::Loop()
{
  //STDOUT("analysisClass::Loop() begins");
  
  if (fChain == 0) return;
   
  ////////////////////// User's code to book histos - BEGIN ///////////////////////

  TH1F *h_Mlj_PAS = new TH1F ("h_Mlj_PAS","h_Mlj_PAS",200,0,2000);  h_Mlj_PAS->Sumw2();

  ////////////////////// User's code to book histos - END ///////////////////////

  ////////////////////// User's code to get preCut values - BEGIN ///////////////

  double eleEta_bar = getPreCutValue1("eleEta_bar");
  double eleEta_end_min = getPreCutValue1("eleEta_end");
  double eleEta_end_max = getPreCutValue2("eleEta_end");

  double EleEnergyScale_EB=getPreCutValue1("EleEnergyScale_EB");
  double EleEnergyScale_EE=getPreCutValue1("EleEnergyScale_EE");
  double JetEnergyScale=getPreCutValue1("JetEnergyScale");

  // Not used when using ElectronHeepID and heepBitMask // int eleIDType = (int) getPreCutValue1("eleIDType");
  int heepBitMask_EB  =  getPreCutValue1("heepBitMask_EBGapEE") ;
  int heepBitMask_GAP =  getPreCutValue2("heepBitMask_EBGapEE") ;

  int heepBitMask_EE  =  getPreCutValue3("heepBitMask_EBGapEE") ;

  int looseBitMask_EB       =  getPreCutValue1("looseBitMask_EBGapEE") ;
  int looseBitMask_GAP      =  getPreCutValue2("looseBitMask_EBGapEE") ;
  int looseBitMask_EE       =  getPreCutValue3("looseBitMask_EBGapEE") ;
  int looseBitMask_enabled  =  getPreCutValue4("looseBitMask_EBGapEE") ;

  double muon_PtCut = getPreCutValue1("muon_PtCut");
  double muFidRegion = getPreCutValue1("muFidRegion"); // currently unused !!!
  double muNHits_minThresh = getPreCutValue1("muNHits_minThresh");
  double muTrkD0Maximum = getPreCutValue1("muTrkD0Maximum");

  int jetAlgorithm = getPreCutValue1("jetAlgorithm");
  int metAlgorithm = getPreCutValue1("metAlgorithm");

  ////////////////////// User's code to get preCut values - END /////////////////
    
  Long64_t nentries = fChain->GetEntriesFast();
  STDOUT("analysisClass::Loop(): nentries = " << nentries);   
  
  ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
  ////// If the root version is updated and rootNtupleClass regenerated,     /////
  ////// these lines may need to be updated.                                 /////    
  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) { // Begin of loop over events
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    if(jentry < 10 || jentry%1000 == 0) STDOUT("analysisClass::Loop(): jentry = " << jentry);   
    // if (Cut(ientry) < 0) continue;
    
    ////////////////////// User's code to be done for every event - BEGIN ///////////////////////

    //## Define new jet collection
    std::auto_ptr<std::vector<double> >  JetPt  ( new std::vector<double>()  );
    std::auto_ptr<std::vector<double> >  JetPtRaw  ( new std::vector<double>()  );
    std::auto_ptr<std::vector<double> >  JetEnergy  ( new std::vector<double>()  );
    std::auto_ptr<std::vector<double> >  JetEta  ( new std::vector<double>()  );
    std::auto_ptr<std::vector<double> >  JetPhi  ( new std::vector<double>()  );
    std::auto_ptr<std::vector<int> >     JetPassID  ( new std::vector<int>()  );
    std::auto_ptr<std::vector<double> >  JetTCHE  ( new std::vector<double>()  );

    if(jetAlgorithm==1) //PF jets
      {
	for (int ijet=0 ; ijet< PFJetPt->size() ; ijet++)
	  {
	    JetPt->push_back( PFJetPt->at(ijet) );
	    JetPtRaw->push_back( PFJetPtRaw->at(ijet) );
	    JetEnergy->push_back( PFJetEnergy->at(ijet) );
	    JetEta->push_back( PFJetEta->at(ijet) );
	    JetPhi->push_back( PFJetPhi->at(ijet) );
            JetPassID->push_back( PFJetPassLooseID->at(ijet) );
	    //     JetPassID->push_back(
	    //  PFJetIdloose(PFJetChargedHadronEnergyFraction->at(ijet),
	    //       PFJetChargedEmEnergyFraction->at(ijet),
	    //       PFJetNeutralHadronEnergyFraction->at(ijet),
	    //       PFJetNeutralEmEnergyFraction->at(ijet),
	    //       PFJetEta->at(ijet) )
	    //  );
            JetTCHE->push_back( PFJetTrackCountingHighEffBTag->at(ijet) );
	  }//end loop over pf jets
      }//end if "pf jets"

    if(jetAlgorithm==2) //Calo jets
      {
	for (int ijet=0 ; ijet < CaloJetPt->size() ; ijet++)
	  {
	    JetPt->push_back( CaloJetPt->at(ijet) );
	    JetPtRaw->push_back( CaloJetPtRaw->at(ijet) );
	    JetEnergy->push_back( CaloJetEnergy->at(ijet) );
	    JetEta->push_back( CaloJetEta->at(ijet) );
	    JetPhi->push_back( CaloJetPhi->at(ijet) );
            JetPassID->push_back( CaloJetPassLooseID->at(ijet) );
	    //     JetPassID->push_back(
	    //  JetIdloose(CaloJetresEMF->at(ijet),
	    //     CaloJetfHPD->at(ijet),
	    //     CaloJetn90Hits->at(ijet),
	    //     CaloJetEta->at(ijet) )
	    //  );
            JetTCHE->push_back( CaloJetTrackCountingHighEffBTag->at(ijet) );
	  }//end loop over calo jets
      }//end if "calo jets"

    //## Define new met collection
    double thisMET;
    double thisMETPhi;
    double thisSumET;
    double thisGenSumET;

    if(isData==0)
      thisGenSumET = GenSumETTrue->at(0);
    else
      thisGenSumET = -1;

    if(metAlgorithm==1) // --> PFMET
      {
	thisMET = PFMET->at(0);
	thisMETPhi = PFMETPhi->at(0);
	thisSumET = PFSumET->at(0);
      }
    if(metAlgorithm==2) // --> CaloMET
      {
	thisMET = CaloMET->at(0);
	thisMETPhi = CaloMETPhi->at(0);
	thisSumET = CaloSumET->at(0);
      }
    if(metAlgorithm==3) // --> PFMET (with type-1 corrections)
      {
	thisMET = PFMETType1Cor->at(0);
	thisMETPhi = PFMETPhiType1Cor->at(0);
	thisSumET = PFSumETType1Cor->at(0);
      }


    // EES and JES
    if( EleEnergyScale_EB != 1 || EleEnergyScale_EE != 1 )
      {
	for(int iele=0; iele<ElectronPt->size(); iele++)
	  {
	    if( fabs(ElectronEta->at(iele)) < eleEta_bar )
	      ElectronPt->at(iele) *= EleEnergyScale_EB;
	    if( fabs(ElectronEta->at(iele)) > eleEta_end_min && fabs(ElectronEta->at(iele)) < eleEta_end_max )
	      ElectronPt->at(iele) *= EleEnergyScale_EE;
	  }
      }
    if( JetEnergyScale != 1 )
      {
	for(int ijet=0; ijet<JetPt->size(); ijet++)
	  {
	    JetPt->at(ijet) *= JetEnergyScale;
	    JetEnergy->at(ijet) *= JetEnergyScale;
	  }
      }

    //## HLT
    int PassTrig = 0;
    int HLTFromRun[4] = {getPreCutValue1("HLTFromRun"),
			 getPreCutValue2("HLTFromRun"),
			 getPreCutValue3("HLTFromRun"),
			 getPreCutValue4("HLTFromRun")};
    int HLTTrigger[4] = {getPreCutValue1("HLTTrigger"),
			 getPreCutValue2("HLTTrigger"),
			 getPreCutValue3("HLTTrigger"),
			 getPreCutValue4("HLTTrigger")};
    int HLTTrgUsed;
    for (int i=0; i<4; i++) {
      if ( !isData && i != 0) continue; // For MC use HLTPhoton15 as the cleaned trigger is not in MC yet as of July 20, 2010
      if ( HLTFromRun[i] <= run ) {
 	//if(jentry == 0 ) STDOUT("run, i, HLTTrigger[i], HLTFromRun[i] = "<<run<<"\t"<<i<<"\t"<<"\t"<<HLTTrigger[i]<<"\t"<<HLTFromRun[i]);
	if (HLTTrigger[i] > 0 && HLTTrigger[i] < HLTResults->size() ) {
	  PassTrig=HLTResults->at(HLTTrigger[i]);
	  HLTTrgUsed=HLTTrigger[i];
	} else {
	  STDOUT("ERROR: HLTTrigger out of range of HLTResults: HLTTrigger = "<<HLTTrigger[i] <<"and HLTResults size = "<< HLTResults->size());
	}
      }
    }
    if(jentry == 0 ) STDOUT("Run = "<<run <<", HLTTrgUsed is number = "<<HLTTrgUsed<<" of the list HLTPathsOfInterest");

    // Electrons
    vector<int> v_idx_ele_all;
    vector<int> v_idx_ele_PtCut;
    vector<int> v_idx_ele_PtCut_IDISO_noOverlap;
    int heepBitMask;

    //Loop over electrons
    for(int iele=0; iele<ElectronPt->size(); iele++)
      {

	// Reject ECAL spikes
	if ( 1 - ElectronSCS4S1->at(iele) > 0.95 ) continue; 

	//no cut on reco electrons
	v_idx_ele_all.push_back(iele); 

	//pT pre-cut on ele
	if( ElectronPt->at(iele) < getPreCutValue1("ele_PtCut") ) continue; 
	v_idx_ele_PtCut.push_back(iele);

	// get heepBitMask for EB, GAP, EE 
	if( fabs(ElectronEta->at(iele)) < eleEta_bar ) 
	  {
	    heepBitMask = heepBitMask_EB;
	  }
	else if ( fabs(ElectronEta->at(iele)) > eleEta_end_min && fabs(ElectronEta->at(iele)) < eleEta_end_max ) 
	  {
	    heepBitMask = heepBitMask_EE;
	  }
	else {
	    heepBitMask = heepBitMask_GAP;
	}

	//ID + ISO + NO overlap with good muons 
	// int eleID = ElectronPassID->at(iele);
	// if ( (eleID & 1<<eleIDType) > 0  && ElectronOverlaps->at(iele)==0 )
	if ( (ElectronHeepID->at(iele) & ~heepBitMask)==0x0  && ElectronOverlaps->at(iele)==0 )
	  {
	    //STDOUT("ElectronHeepID = " << hex << ElectronHeepID->at(iele) << " ; ElectronPassID = " << ElectronPassID->at(iele) )
	    v_idx_ele_PtCut_IDISO_noOverlap.push_back(iele);
	  }

      } // End loop over electrons

    // tight-loose electrons, if enabled from cut file
    if ( looseBitMask_enabled == 1 && v_idx_ele_PtCut_IDISO_noOverlap.size() == 1 )
      {
	//STDOUT("v_idx_ele_PtCut_IDISO_noOverlap[0] = "<<v_idx_ele_PtCut_IDISO_noOverlap[0] << " - Pt = "<<ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]));
	bool loosePtLargerThanTightPt = true;
	for(int iele=0; iele<v_idx_ele_PtCut.size(); iele++)
	  {
	    
	    if (v_idx_ele_PtCut[iele] == v_idx_ele_PtCut_IDISO_noOverlap[0])
	      {
		loosePtLargerThanTightPt = false;
		continue;
	      }
	    // get looseBitMask for EB, GAP, EE 

	    int looseBitMask;
	    if( fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) < eleEta_bar ) 
	      {
		looseBitMask = looseBitMask_EB;
	      }
	    else if ( fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) > eleEta_end_min && fabs(ElectronEta->at(v_idx_ele_PtCut[iele])) < eleEta_end_max ) 
	      {
		looseBitMask = looseBitMask_EE;
	      }
	    else {
	      looseBitMask = looseBitMask_GAP;
	    }
	    if ( (ElectronHeepID->at(v_idx_ele_PtCut[iele]) & ~looseBitMask)==0x0  && ElectronOverlaps->at(v_idx_ele_PtCut[iele])==0 )
	      {
		if ( loosePtLargerThanTightPt )
		  {
		    v_idx_ele_PtCut_IDISO_noOverlap.insert(v_idx_ele_PtCut_IDISO_noOverlap.begin(),1,v_idx_ele_PtCut[iele]);
		  }
		else 
		  {
		    v_idx_ele_PtCut_IDISO_noOverlap.push_back(v_idx_ele_PtCut[iele]);
		  }
		break; // happy with one loose electron - Note: if you want more than 1 loose, pt sorting will not be OK with the code as is. 
	      }
	  }	
// 	for ( int i=0; i<v_idx_ele_PtCut_IDISO_noOverlap.size(); i++)
// 	  {
// 	    STDOUT("i="<<i<<", v_idx_ele_PtCut_IDISO_noOverlap[i] = "<<v_idx_ele_PtCut_IDISO_noOverlap[i] << ", Pt = "<<ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[i]));
// 	  }
      } // tight-loose electrons, if enabled from cut file


    // Muons
    vector<int> v_idx_muon_all;
    vector<int> v_idx_muon_PtCut;
    vector<int> v_idx_muon_PtCut_IDISO;
    
    // Loop over muons  
    for(int imuon=0; imuon<MuonPt->size(); imuon++){

      // no cut on reco muons
      v_idx_muon_all.push_back(imuon);

      if ( (*MuonPt)[imuon] < muon_PtCut) continue;

      // pT pre-cut on muons
      v_idx_muon_PtCut.push_back(imuon);
      
      if ( ((*MuonTrkHits)[imuon]  >= muNHits_minThresh  )&&( fabs((*MuonTrkD0)[imuon]) < muTrkD0Maximum ) &&((*MuonPassIso)[imuon]==1 ) &&((*MuonPassID)[imuon]==1) ) 
	{
	  v_idx_muon_PtCut_IDISO.push_back(imuon);
	}
    }// end loop over muons


    // Jets
    vector<int> v_idx_jet_all;
    vector<int> v_idx_jet_PtCut;
    vector<int> v_idx_jet_PtCut_noOverlap;
    vector<int> v_idx_jet_PtCut_noOverlap_ID;
    vector<int> v_idx_jet_PtCut_noOverlap_ID_EtaCut;

    // Loop over jets
    for(int ijet=0; ijet<JetPt->size(); ijet++)
      {
	//no cut on reco jets
	v_idx_jet_all.push_back(ijet);

	//pT pre-cut on reco jets
	if ( JetPt->at(ijet) < getPreCutValue1("jet_PtCut") ) continue;
	v_idx_jet_PtCut.push_back(ijet);
      }

// 	//Checking overlap between electrons and jets
// 	int JetOverlapsWithEle = 0; //don't change the default (0) 
// 	float minDeltaR=9999.;
// 	TVector3 jet_vec;
// 	jet_vec.SetPtEtaPhi(JetPt->at(ijet),JetEta->at(ijet),JetPhi->at(ijet));
// 	for (int i=0; i < v_idx_ele_PtCut_IDISO_noOverlap.size(); i++){
// 	  TVector3 ele_vec;	  
// 	  ele_vec.SetPtEtaPhi(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[i])
// 			      ,ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[i])
// 			      ,ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[i]));
// 	  double distance = jet_vec.DeltaR(ele_vec);
// 	  if (distance<minDeltaR) minDeltaR=distance;
// 	}
// 	if ( minDeltaR < getPreCutValue1("jet_ele_DeltaRcut") )
// 	  JetOverlapsWithEle = 1; //this jet overlaps with a good electron --> remove it from the analysis

// 	//pT pre-cut + no overlaps with electrons
// 	// ---- use the flag stored in rootTuples
// 	//if( ( JetOverlaps->at(ijet) & 1 << eleIDType) == 0)/* NO overlap with electrons */  
// 	// && (caloJetOverlaps[ijet] & 1 << 5)==0 )/* NO overlap with muons */   
// 	// ----
// 	if( JetOverlapsWithEle == 0 )  /* NO overlap with electrons */  
// 	  v_idx_jet_PtCut_noOverlap.push_back(ijet);

    vector <int> jetFlags(v_idx_jet_PtCut.size(), 0);
    int Njetflagged = 0;
    for (int iele=0; iele<v_idx_ele_PtCut_IDISO_noOverlap.size(); iele++)
      {
	TLorentzVector ele;
        ele.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
			 ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
			 ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),0);
	TLorentzVector jet;
	double minDR=9999.;
	int ijet_minDR = -1;    
        for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++)
          {
	    if ( jetFlags[ijet] == 1 ) 
	      continue;
            jet.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut[ijet]),
			     JetEta->at(v_idx_jet_PtCut[ijet]),
			     JetPhi->at(v_idx_jet_PtCut[ijet]),0);
	    double DR = jet.DeltaR(ele);
	    if (DR<minDR) 
	      {
		minDR = DR;
		ijet_minDR = ijet;
	      }
	  }
	if ( minDR < getPreCutValue1("jet_ele_DeltaRcut") && ijet_minDR > -1)
	  {
	    jetFlags[ijet_minDR] = 1;
	    Njetflagged++;
	  }
      }

//     // printouts for jet cleaning
//     STDOUT("CLEANING ----------- v_idx_ele_PtCut_IDISO_noOverlap.size = "<< v_idx_ele_PtCut_IDISO_noOverlap.size() <<", Njetflagged = "<< Njetflagged<<", diff="<< v_idx_ele_PtCut_IDISO_noOverlap.size()-Njetflagged );
//     if( (v_idx_ele_PtCut_IDISO_noOverlap.size()-Njetflagged) == 1 ) 
//       {
// 	TLorentzVector thisele;
// 	for(int iele=0; iele<v_idx_ele_PtCut_IDISO_noOverlap.size(); iele++)
// 	  {
// 	    thisele.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
// 				 ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
// 				 ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),0);
// 	    STDOUT("CLEANING: e"<<iele+1<<" Pt, eta, phi = "  << ", "<<thisele.Pt()<<", "<< thisele.Eta() <<", "<< thisele.Phi());
// 	  }
// 	TLorentzVector thisjet;
// 	for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++)
// 	  {
// 	    thisjet.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut[ijet]),
// 				 JetEta->at(v_idx_jet_PtCut[ijet]),
// 				 JetPhi->at(v_idx_jet_PtCut[ijet]),0);
// 	    STDOUT("CLEANING: j"<<ijet+1<<" Pt, eta, phi = " << ", "<<thisjet.Pt()<<", "<< thisjet.Eta() <<", "<< thisjet.Phi()<<" jetFlags="<<jetFlags[ijet] );
// 	  }
//       } // printouts for jet cleaning
    
    // Flagging jets if they overlap with muons
    vector <int> jetFlags_muon(v_idx_jet_PtCut.size(), 0);
    int Njetflagged_muon = 0;
    for (int imuon=0; imuon<v_idx_muon_PtCut_IDISO.size(); imuon++)
      {
	TLorentzVector muon;
        muon.SetPtEtaPhiM(MuonPt->at(v_idx_muon_PtCut_IDISO[imuon]),
			  MuonEta->at(v_idx_muon_PtCut_IDISO[imuon]),
			  MuonPhi->at(v_idx_muon_PtCut_IDISO[imuon]),0);
	TLorentzVector jet;
	double minDR=9999.;
	int ijet_minDR = -1;    
        for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++)
          {
	    if ( jetFlags_muon[ijet] == 1 ) 
	      continue;
            jet.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut[ijet]),
			     JetEta->at(v_idx_jet_PtCut[ijet]),
			     JetPhi->at(v_idx_jet_PtCut[ijet]),0);
	    double DR = jet.DeltaR(muon);
	    if (DR<minDR) 
	      {
		minDR = DR;
		ijet_minDR = ijet;
	      }
	  }
	if ( minDR < getPreCutValue1("jet_muon_DeltaRcut") && ijet_minDR > -1)
	  {
	    jetFlags_muon[ijet_minDR] = 1;
	    Njetflagged_muon++;
	  }
      }

    
    float JetEtaCutValue = getPreCutValue1("jet_EtaCut");
    for(int ijet=0; ijet<v_idx_jet_PtCut.size(); ijet++) //pT pre-cut + no overlaps with electrons + jetID
      {	
	bool passjetID = JetPassID->at(v_idx_jet_PtCut[ijet]);
	//bool passjetID = JetIdloose(CaloJetresEMF->at(v_idx_jet_PtCut[ijet]),CaloJetfHPD->at(v_idx_jet_PtCut[ijet]),CaloJetn90Hits->at(v_idx_jet_PtCut[ijet]), CaloJetEta->at(v_idx_jet_PtCut[ijet]));
	// ---- use the flag stored in rootTuples
	//if( (JetOverlaps->at(v_idx_jet_PtCut[ijet]) & 1 << eleIDType) == 0  /* NO overlap with electrons */  
	// ----

	if( jetFlags[ijet] == 0                            /* NO overlap with electrons */  
	    && jetFlags_muon[ijet] == 0 )                  /* NO overlap with muons */
	  //  && passjetID == true )                            /* pass JetID */
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap.push_back(v_idx_jet_PtCut[ijet]);

	if( jetFlags[ijet] == 0                            /* NO overlap with electrons */  
	    && jetFlags_muon[ijet] == 0                    /* NO overlap with muons */
	    && passjetID == true )                            /* pass JetID */
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap_ID.push_back(v_idx_jet_PtCut[ijet]);

	if( jetFlags[ijet] == 0                           /* NO overlap with electrons */  
	    && jetFlags_muon[ijet] == 0                   /* NO overlap with muons */
	    && passjetID == true                             /* pass JetID */
	    && fabs( JetEta->at(v_idx_jet_PtCut[ijet]) ) < JetEtaCutValue )
	  // && (caloJetOverlaps[ijet] & 1 << 5)==0 )         /* NO overlap with muons */      
	  v_idx_jet_PtCut_noOverlap_ID_EtaCut.push_back(v_idx_jet_PtCut[ijet]);

	
	//NOTE: We should verify that caloJetOverlaps match with the code above
      } // End loop over jets
    


    // Set the evaluation of the cuts to false and clear the variable values and filled status
    resetCuts();
    

    // Set the value of the variableNames listed in the cutFile to their current value
    
    // Trigger (L1 and HLT)
    if(isData==true)
      {
	fillVariableWithValue( "PassBPTX0", isBPTX0 ) ;
	fillVariableWithValue( "PassPhysDecl", isPhysDeclared ) ;       
      }
    else
      {
	fillVariableWithValue( "PassBPTX0", true ) ;
	fillVariableWithValue( "PassPhysDecl", true ) ;       
      }

    fillVariableWithValue( "PassHLT", PassTrig ) ;

    //Event filters at RECO level
    fillVariableWithValue( "PassBeamScraping", !isBeamScraping ) ;
    fillVariableWithValue( "PassPrimaryVertex", isPrimaryVertex ) ;
    //    fillVariableWithValue( "PassHBHENoiseFilter", passLooseNoiseFilter ) ;

    // nMu
    fillVariableWithValue( "nMu_all", MuonPt->size() ) ;
    fillVariableWithValue( "nMu_PtCut", v_idx_muon_PtCut.size() ) ;
    fillVariableWithValue( "nMu_PtCut_IDISO", v_idx_muon_PtCut_IDISO.size() ) ;

    // nEle
    fillVariableWithValue( "nEle_all", v_idx_ele_all.size() ) ;
    fillVariableWithValue( "nEle_PtCut", v_idx_ele_PtCut.size() ) ;
    fillVariableWithValue( "nEle_PtCut_IDISO_noOvrlp", v_idx_ele_PtCut_IDISO_noOverlap.size() ) ;

    // nLeptons
    fillVariableWithValue( "nLept_PtCut_IDISO", v_idx_ele_PtCut_IDISO_noOverlap.size()+v_idx_muon_PtCut_IDISO.size() ) ;
     
    // nJet
    fillVariableWithValue( "nJet_all", v_idx_jet_all.size() ) ;
    fillVariableWithValue( "nJet_PtCut", v_idx_jet_PtCut.size() ) ;
    fillVariableWithValue( "nJet_PtCut_noOvrlp", v_idx_jet_PtCut_noOverlap.size() ) ;
    fillVariableWithValue( "nJet_PtCut_noOvrlp_ID", v_idx_jet_PtCut_noOverlap_ID.size() ) ;
    //OneEleOneMu
    fillVariableWithValue( "nJet_OneEleOneMu_All", v_idx_jet_PtCut_noOverlap_ID.size() ) ;
    fillVariableWithValue( "nJet_OneEleOneMu_EtaCut", v_idx_jet_PtCut_noOverlap_ID_EtaCut.size() ) ;
    //PAS June 2010
    fillVariableWithValue( "nJet_PAS_All", v_idx_jet_PtCut_noOverlap_ID.size() ) ;
    fillVariableWithValue( "nJet_PAS_EtaCut", v_idx_jet_PtCut_noOverlap_ID_EtaCut.size() ) ;

    // MET
    //PAS June 2010
    fillVariableWithValue( "MET_PAS", thisMET ) ;
    fillVariableWithValue( "METPhi_PAS", thisMETPhi);
    fillVariableWithValue( "pfMET_PAS", PFMET->at(0) ) ;
    fillVariableWithValue( "tcMET_PAS", TCMET->at(0) ) ;
    fillVariableWithValue( "caloMET_PAS", CaloMET->at(0) ) ;
    TVector2 v_MET;
    v_MET.SetMagPhi( thisMET , thisMETPhi);

    // 1st ele
    if( v_idx_ele_PtCut_IDISO_noOverlap.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stEle_IDISO_NoOvrlp", ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
	fillVariableWithValue( "Eta1stEle_IDISO_NoOvrlp", ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
	fillVariableWithValue( "mEta1stEle_IDISO_NoOvrlp", fabs(ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[0])) );
	//PAS June 2010
	fillVariableWithValue( "Pt1stEle_PAS", ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
	fillVariableWithValue( "Eta1stEle_PAS", ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
        fillVariableWithValue( "Phi1stEle_PAS", ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
	// transverse mass ele+MET
	TVector2 v_ele;
	v_ele.SetMagPhi( ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) , ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) );
	double deltaphi = v_MET.DeltaPhi(v_ele);
	double MT_eleMET = sqrt(2 * v_ele.Mod() * thisMET * (1 - cos(deltaphi)) );
	fillVariableWithValue("MT_eleMET", MT_eleMET);
      }

    // 1st muon
    if( v_idx_muon_PtCut_IDISO.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stMu_IDISO", MuonPt->at(v_idx_muon_PtCut_IDISO[0]) );
	fillVariableWithValue( "Eta1stMu_IDISO", MuonEta->at(v_idx_muon_PtCut_IDISO[0]) );
	fillVariableWithValue( "mEta1stMu_IDISO", fabs(MuonEta->at(v_idx_muon_PtCut_IDISO[0])) );
	//PAS June 2010
	fillVariableWithValue( "Pt1stMu_PAS", MuonPt->at(v_idx_muon_PtCut_IDISO[0]) );
	fillVariableWithValue( "Eta1stMu_PAS", MuonEta->at(v_idx_muon_PtCut_IDISO[0]) );
        fillVariableWithValue( "Phi1stMu_PAS", MuonPhi->at(v_idx_muon_PtCut_IDISO[0]) );
	// transverse mass ele+MET
	TVector2 v_muon;
	v_muon.SetMagPhi( MuonPt->at(v_idx_muon_PtCut_IDISO[0]) , MuonPhi->at(v_idx_muon_PtCut_IDISO[0]) );
	double deltaphi = v_MET.DeltaPhi(v_muon);
	double MT_muonMET = sqrt(2 * v_muon.Mod() * thisMET * (1 - cos(deltaphi)) );
	fillVariableWithValue("MT_muonMET", MT_muonMET);
      }

    // 1st jet
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stJet_noOvrlp_ID", JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) );
	fillVariableWithValue( "Eta1stJet_noOvrlp_ID", JetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]) );
	fillVariableWithValue( "mEta1stJet_noOvrlp_ID", fabs(JetEta->at(v_idx_jet_PtCut_noOverlap_ID[0])) );
	//PAS June 2010
	fillVariableWithValue( "Pt1stJet_PAS", JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) );
	fillVariableWithValue( "Eta1stJet_PAS", JetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]) );
        fillVariableWithValue( "Phi1stJet_PAS", JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[0]) );
      }


    //cout << "2nd Jet" << endl;
    //## 2nd jet
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 2 ) 
      {
	fillVariableWithValue( "Pt2ndJet_noOvrlp_ID", JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]) );
	fillVariableWithValue( "Eta2ndJet_noOvrlp_ID", JetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]) );
	fillVariableWithValue( "mEta2ndJet_noOvrlp_ID", fabs(JetEta->at(v_idx_jet_PtCut_noOverlap_ID[1])) );
	fillVariableWithValue( "maxMEtaJets_noOvrlp_ID", max( getVariableValue("mEta1stJet_noOvrlp_ID"), getVariableValue("mEta2ndJet_noOvrlp_ID") ) );
	//PAS June 2010
	fillVariableWithValue( "Pt2ndJet_PAS", JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]) );
	fillVariableWithValue( "Eta2ndJet_PAS", JetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]) );
        fillVariableWithValue( "Phi2ndJet_PAS", JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[1]) );
      }

    //## define "1ele+1muon" and "2jets" booleans
    bool OneEleOneMu=false;
    bool TwoJets=false;
    if( v_idx_ele_PtCut_IDISO_noOverlap.size() >= 1 && v_idx_muon_PtCut_IDISO.size() >= 1 ) OneEleOneMu = true;
    if( v_idx_jet_PtCut_noOverlap_ID.size() >= 2 ) TwoJets = true;

    // ST
    double calc_sT=-999.; 
    if ( (OneEleOneMu) && (TwoJets) ) 
      {
	calc_sT = 
	  ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) +
	  MuonPt->at(v_idx_muon_PtCut_IDISO[0]) +
	  JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) +
	  JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]);
	fillVariableWithValue("sT", calc_sT);
	fillVariableWithValue("sT_MLQ250", calc_sT);
	fillVariableWithValue("sT_MLQ280", calc_sT);
	fillVariableWithValue("sT_MLQ300", calc_sT);
	fillVariableWithValue("sT_MLQ320", calc_sT);
	fillVariableWithValue("sT_MLQ340", calc_sT);
	fillVariableWithValue("sT_MLQ400", calc_sT);       
	//PAS June 2010
	fillVariableWithValue("sT_PAS", calc_sT);
      }

    // ST jets
    if (TwoJets)
      {
	double calc_sTjet=-999.;
	calc_sTjet =
	  JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]) + 
	  JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]) ;
	fillVariableWithValue("sTjet_PAS", calc_sTjet);
      }

    // Mjj
    if (TwoJets)
      {
	TLorentzVector jet1, jet2, jj;
	jet1.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  JetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[0]),0);
	jet2.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  JetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[1]),0);
	jj = jet1+jet2;
	//PAS June 2010
	fillVariableWithValue("Mjj_PAS", jj.M());
      }


    // Memu
    if (OneEleOneMu)
      {
	fillVariableWithValue( "maxMEtaEleMu_IDISO", max( getVariableValue("mEta1stEle_IDISO_NoOvrlp"), getVariableValue("mEta1stMu_IDISO") ) );
	TLorentzVector ele1, mu1, emu;
	ele1.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),
			  ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),
			  ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),0);
	mu1.SetPtEtaPhiM(MuonPt->at(v_idx_muon_PtCut_IDISO[0]),
			 MuonEta->at(v_idx_muon_PtCut_IDISO[0]),
			 MuonPhi->at(v_idx_muon_PtCut_IDISO[0]),0);
	emu = ele1+mu1;
	fillVariableWithValue("Memu", emu.M());
	//OneEleOneMu
	fillVariableWithValue("Memu_OneEleOneMu", emu.M());
	fillVariableWithValue("Memu_presel", emu.M());
	//
	//PAS June 2010
	fillVariableWithValue("Memu_PAS", emu.M());

	double calc_sTemu=-999.;
        calc_sTemu =
	   ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]) +
	   MuonPt->at(v_idx_muon_PtCut_IDISO[0]) ;
	fillVariableWithValue("sTemu_PAS", calc_sTemu);

	if(isData==true) 
	  {
	    STDOUT("OneEleOneMu: Run, LS, Event = "<<run<<", "<<ls<<", "<<event);
	    STDOUT("OneEleOneMu: M_emu, Pt_emu, Eta_emu, Phi_emu = "<<emu.M() <<", "<< emu.Pt() <<", "<< emu.Eta() <<", "<< emu.Phi());
	    STDOUT("OneEleOneMu: 1st ele  Pt, eta, phi = "<< ele1.Pt() <<", "<< ele1.Eta() <<", "<< ele1.Phi() );
	    STDOUT("OneEleOneMu: 1st muon Pt, eta, phi = "<< mu1.Pt() <<", "<< mu1.Eta() <<", "<< mu1.Phi() );
	  }
      }

    // Mlj 
    double Me1j1, Me1j2, Mm1j1, Mm1j2 = -999;
    double deltaM_e1j1_m1j2 = 9999;
    double deltaM_e1j2_m1j1 = 9999;
    double Mlj_1stPair = 0;
    double Mlj_2ndPair = 0;
    double deltaR_e1j1 ;
    double deltaR_m1j2 ;
    double deltaR_e1j2 ;
    double deltaR_m1j1 ;
    if ( (OneEleOneMu) && (TwoJets) ) // OneEleOneMu and TwoJets
      {
	TLorentzVector jet1, jet2, ele1, mu1;
	ele1.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),
			  ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),
			  ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[0]),0);
	mu1.SetPtEtaPhiM(MuonPt->at(v_idx_muon_PtCut_IDISO[0]),
			 MuonEta->at(v_idx_muon_PtCut_IDISO[0]),
			 MuonPhi->at(v_idx_muon_PtCut_IDISO[0]),0);
	jet1.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  JetEta->at(v_idx_jet_PtCut_noOverlap_ID[0]),
			  JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[0]),0);
	jet2.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  JetEta->at(v_idx_jet_PtCut_noOverlap_ID[1]),
			  JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[1]),0);
	TLorentzVector e1j1, e1j2, m1j1, m1j2;
	e1j1 = ele1 + jet1;
	m1j2 =  mu1 + jet2;
	m1j1 =  mu1 + jet1;
	e1j2 = ele1 + jet2;
	Me1j1 = e1j1.M();
	Mm1j2 = m1j2.M();
	Me1j2 = e1j2.M();
	Mm1j1 = m1j1.M();

	deltaM_e1j1_m1j2 = Me1j1 - Mm1j2;
	deltaM_e1j2_m1j1 = Me1j2 - Mm1j1;


	double deltaR_e1j1 = ele1.DeltaR(jet1);
	double deltaR_m1j2 =  mu1.DeltaR(jet2);
	double deltaR_e1j2 = ele1.DeltaR(jet2);
	double deltaR_m1j1 =  mu1.DeltaR(jet1);

// 	// Fill min DR between any of the 2 selected eles and any of the 2 selected jets
// 	double minDR_2ele_2jet = min ( min(deltaR_e1j1,deltaR_m1j2) , min(deltaR_e1j2,deltaR_m1j1) );
// 	fillVariableWithValue("minDR_2ele_2jet", minDR_2ele_2jet);

	if(fabs(deltaM_e1j1_m1j2) > fabs(deltaM_e1j2_m1j1))
	  {
	    Mlj_1stPair = Me1j2;
	    Mlj_2ndPair = Mm1j1;
	    fillVariableWithValue("minDRlj_selecPairs", min(deltaR_e1j2,deltaR_m1j1) );
	    fillVariableWithValue("minDRlj_unselPairs", min(deltaR_e1j1,deltaR_m1j2) );
	  }
	else
	  {
	    Mlj_1stPair = Me1j1;
	    Mlj_2ndPair = Mm1j2;
	    fillVariableWithValue("minDRlj_selecPairs", min(deltaR_e1j1,deltaR_m1j2) );
	    fillVariableWithValue("minDRlj_unselPairs", min(deltaR_e1j2,deltaR_m1j1) );
	  } 
	fillVariableWithValue("Mlj_1stPair", Mlj_1stPair);       
	fillVariableWithValue("Mlj_2ndPair", Mlj_2ndPair);
	//PAS June 2010
	h_Mlj_PAS->Fill(Mlj_1stPair);
	h_Mlj_PAS->Fill(Mlj_2ndPair);
	fillVariableWithValue("Mlj_1stPair_PAS", Mlj_1stPair);       
	fillVariableWithValue("Mlj_2ndPair_PAS", Mlj_2ndPair);

	// min and max DeltaR between electrons and any jet
	double minDeltaR_lj = 999999;
	double maxDeltaR_lj = -1;
	double thisMinDR, thisMaxDR, DR_thisjet_e1, DR_thisjet_m1;
	TLorentzVector thisjet;
	for(int ijet=0; ijet<v_idx_jet_PtCut_noOverlap_ID.size(); ijet++)
	  {
	    thisjet.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				 JetEta->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				 JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),0);
	    DR_thisjet_e1 = thisjet.DeltaR(ele1);
	    DR_thisjet_m1 = thisjet.DeltaR(mu1);
	    thisMinDR = min(DR_thisjet_e1, DR_thisjet_m1);
	    thisMaxDR = max(DR_thisjet_e1, DR_thisjet_m1);
	    if(thisMinDR < minDeltaR_lj)
	      minDeltaR_lj = thisMinDR;
	    if(thisMaxDR > maxDeltaR_lj)
	      maxDeltaR_lj = thisMaxDR;
	  } 
	fillVariableWithValue("minDeltaR_lj", minDeltaR_lj);
	fillVariableWithValue("maxDeltaR_lj", maxDeltaR_lj);

	// printouts for small Mlj
	if(isData==true && ( Mlj_1stPair<20 || Mlj_2ndPair<20 ) ) // printouts for low Mlj 
	  {
	    STDOUT("Mlj<20GeV: Run, LS, Event = "<<run<<",\t"<<ls<<",\t"<<event);
	    STDOUT("Mlj<20GeV: Mlj_1stPair = "<<Mlj_1stPair <<", Mlj_2ndPair = "<< Mlj_2ndPair );
	    STDOUT("Mlj<20GeV: e1j1.M = "<<e1j1.M() <<", m1j2.M = "<<m1j2.M() <<", e1j2.M = "<<e1j2.M()  <<", m1j1.M = "<<m1j1.M()  );
	    STDOUT("Mlj<20GeV: deltaM_e1j1_m1j2 = "<<deltaM_e1j1_m1j2 <<", deltaM_e1j2_m1j1 = "<<deltaM_e1j2_m1j1  );
	    STDOUT("Mlj<20GeV: deltaR_e1j1 = "<<deltaR_e1j1 <<", deltaR_m1j2 = "<<deltaR_m1j2 <<", deltaR_e1j2 = "<<deltaR_e1j2  <<", deltaR_m1j1 = "<<deltaR_m1j1  );
	    TLorentzVector thisele;
	    // Add printout for muons?
	    for(int iele=0; iele<v_idx_ele_PtCut_IDISO_noOverlap.size(); iele++)
	      {
		thisele.SetPtEtaPhiM(ElectronPt->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
				     ElectronEta->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),
				     ElectronPhi->at(v_idx_ele_PtCut_IDISO_noOverlap[iele]),0);
		STDOUT("Mlj<20GeV: e"<<iele+1<<" Pt, eta, phi = " 
		       << ", "<<thisele.Pt()<<", "<< thisele.Eta() <<", "<< thisele.Phi()<<"; DR_j1, DR_j2 = "<< thisele.DeltaR(jet1)<<", "<<thisele.DeltaR(jet2));
	      }
	    TLorentzVector thisjet;
	    TLorentzVector thisjet_e1, thisjet_m1;
	    for(int ijet=0; ijet<v_idx_jet_PtCut_noOverlap_ID.size(); ijet++)
	      {
		thisjet.SetPtEtaPhiM(JetPt->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				     JetEta->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),
				     JetPhi->at(v_idx_jet_PtCut_noOverlap_ID[ijet]),0);
		thisjet_e1 = thisjet + ele1;
		thisjet_m1 = thisjet +  mu1;
		STDOUT("Mlj<20GeV: j"<<ijet+1<<" Pt, eta, phi = " << ", "<<thisjet.Pt()<<", "<< thisjet.Eta() <<", "<< thisjet.Phi()<<"; DR_e1, DR_m1 = "<< thisjet.DeltaR(ele1)<<", "<<thisjet.DeltaR(mu1) << "; M_e1, M_m1 = " <<thisjet_e1.M() <<", "<<thisjet_m1.M() );
	      }
	  } // printouts for low Mlj 

      } // OneEleOneMu and TwoJets



    // Evaluate cuts (but do not apply them)
    evaluateCuts();

    // Fill histograms and do analysis based on cut evaluation
    //h_nEleFinal->Fill( ElectronPt->size() );
     

    // printouts for OneEleOneMuTwoJets
    if( isData==true && passedAllPreviousCuts("Memu") ) 
      {
	STDOUT("OneEleOneMuTwoJets: Run, LS, Event = "<<run<<",\t"<<ls<<",\t"<<event);
	STDOUT("OneEleOneMuTwoJets: sT, Memu, Mjj_PAS = "******"sT") <<", "<< getVariableValue("Memu")<<", "<< getVariableValue("Mjj_PAS") );
	STDOUT("OneEleOneMuTwoJets: Mlj_1stPair, Mlj_2ndPair = "<< getVariableValue("Mlj_1stPair")<<", "<< getVariableValue("Mlj_2ndPair") );
	STDOUT("OneEleOneMuTwoJets: 1stEle Pt, eta, phi = "<<getVariableValue("Pt1stEle_PAS") <<", "<< getVariableValue("Eta1stEle_PAS") <<", "<< getVariableValue("Phi1stEle_PAS") );
	STDOUT("OneEleOneMuTwoJets: 1stMu  Pt, eta, phi = "<<getVariableValue("Pt1stMu_PAS") <<", "<< getVariableValue("Eta1stMu_PAS") <<", "<< getVariableValue("Phi1stMu_PAS") );
	STDOUT("OneEleOneMuTwoJets: 1stJet Pt, eta, phi = "<<getVariableValue("Pt1stJet_PAS") <<", "<< getVariableValue("Eta1stJet_PAS") <<", "<< getVariableValue("Phi1stJet_PAS") );
	STDOUT("OneEleOneMuTwoJets: 2ndJet Pt, eta, phi = "<<getVariableValue("Pt2ndJet_PAS") <<", "<< getVariableValue("Eta2ndJet_PAS") <<", "<< getVariableValue("Phi2ndJet_PAS") );
	STDOUT("OneEleOneMuTwoJets: minDRlj_selecPairs, minDRlj_unselPairs = "<<getVariableValue("minDRlj_selecPairs") <<", "<< getVariableValue("minDRlj_unselPairs") );
// 	if ( passedCut("Mee") )
// 	  {
// 	    STDOUT("PassedMeeAndAllPrevious: Run, LS, Event = "<<run<<",\t"<<ls<<",\t"<<event<<", sT = "<< getVariableValue("sT"));
// 	  }
      } // printouts for OneEleOneMuTwoJets:

    
    //INFO
    //      // retrieve value of previously filled variables (after making sure that they were filled)
    //      double totpTEle;
    //      if ( variableIsFilled("pT1stEle") && variableIsFilled("pT2ndEle") ) 
    //        totpTEle = getVariableValue("pT1stEle")+getVariableValue("pT2ndEle");
    //      // reject events that did not pass level 0 cuts
    //      if( !passedCut("0") ) continue;
    //      // ......

        
    ////////////////////// User's code to be done for every event - END ///////////////////////
    
  } // End of loop over events
  

  ////////////////////// User's code to write histos - BEGIN ///////////////////////

  h_Mlj_PAS->Write();

  ////////////////////// User's code to write histos - END ///////////////////////
  
  
  //STDOUT("analysisClass::Loop() ends");   
}
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   
    
   if (fChain == 0) return;
   
   //////////book histos here

   // TH1F *h_nJetFinal = new TH1F ("h_nJetFinal","",10,0,10);
   // h_nJetFinal->Sumw2();      
   // TH1F *h_nVtx = new TH1F ("h_nVtx","",30,0,30);
   // h_nVtx->Sumw2(); 
   // TH1F *h_trueVtx = new TH1F ("h_trueVtx","",40,0,40);
   // h_trueVtx->Sumw2();  
   // TH1F *h_pT1stJet = new TH1F ("h_pT1stJet","",100,0,3000);
   // h_pT1stJet->Sumw2();
   // TH1F *h_pT2ndJet = new TH1F ("h_pT2ndJet","",100,0,3000);
   // h_pT2ndJet->Sumw2();
   // TH1F *h_eta1stJet = new TH1F ("h_eta1stJet","",5,-2.5,2.5);
   // h_eta1stJet->Sumw2();
   // TH1F *h_eta2ndJet = new TH1F ("h_eta2ndJet","",5,-2.5,2.5);
   // h_eta2ndJet->Sumw2();
   // TH1F *h_DijetMass = new TH1F ("h_DijetMass","",600,0,6000);
   // h_DijetMass->Sumw2();
   // TH1F *h_DeltaETAjj = new TH1F ("h_DeltaETAjj","",120,0,3.);
   // h_DeltaETAjj->Sumw2();

   // variable binning for mjj trigger efficiency plots
   const int nMassBins = 103;

   double massBoundaries[nMassBins+1] = {1, 3, 6, 10, 16, 23, 31, 40, 50, 61, 74, 88, 103, 119, 137, 156, 176, 197, 220, 244, 270, 296, 325,
     354, 386, 419, 453, 489, 526, 565, 606, 649, 693, 740, 788, 838, 890, 944, 1000, 1058, 1118, 1181, 1246, 1313, 1383, 1455, 1530, 1607, 1687,
     1770, 1856, 1945, 2037, 2132, 2231, 2332, 2438, 2546, 2659, 2775, 2895, 3019, 3147, 3279, 3416, 3558, 3704, 3854, 4010, 4171, 4337, 4509,
     4686, 4869, 5058, 5253, 5455, 5663, 5877, 6099, 6328, 6564, 6808, 7060, 7320, 7589, 7866, 8152, 8447, 8752, 9067, 9391, 9726, 10072, 10430, 
     10798, 11179, 11571, 11977, 12395, 12827, 13272, 13732, 14000};

   // char* HLTname[50] = {"noTrig","PFHT475","PFHT800","PFHT650MJJ900","PFHT800_OR_PFHT650MJJ900","PFHT800_noPFHT475", 
   //                      "Mu45Eta2p1", "PFHT800AndMu45Eta2p1"};
   // TH1F* h_mjj_HLTpass[8];
   // char name_histoHLT[50];
   // for (int i=0; i<8; i++){  
   //   sprintf(name_histoHLT,"h_mjj_HLTpass_%s",HLTname[i]);
   //   h_mjj_HLTpass[i]= new TH1F(name_histoHLT,"",103,massBoundaries);
   // }

   //For trigger efficiency measurements
   //No trigger selection applied (full offline selection applied)
   TH1F* h_mjj_NoTrigger_1GeVbin = new TH1F("h_mjj_NoTrigger_1GeVbin","",14000,0,14000);
   TH1F* h_mjj_NoTrigger = new TH1F("h_mjj_NoTrigger","",103,massBoundaries);
   //L1
   //TH1F* h_mjj_HLTpass_ZeroBias = new TH1F("h_mjj_HLTpass_ZeroBias","",103,massBoundaries);
   //TH1F* h_mjj_HLTpass_ZeroBias_L1HTT150 = new TH1F("h_mjj_HLTpass_ZeroBias_L1HTT150","",103,massBoundaries);  
   //HLT
   //TH1F* h_mjj_HLTpass_L1HTT150 = new TH1F("h_mjj_HLTpass_L1HTT150","",103,massBoundaries);
   //TH1F* h_mjj_HLTpass_L1HTT150_HT450 = new TH1F("h_mjj_HLTpass_L1HTT150_HT450","",103,massBoundaries);


   /////////initialize variables

   Long64_t nentries = fChain->GetEntriesFast();
   std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl;   

   ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
   ////// If the root version is updated and rootNtupleClass regenerated,     /////
   ////// these lines may need to be updated.                                 /////    
   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
   //for (Long64_t jentry=0; jentry<2000;jentry++) {
     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
     // if (Cut(ientry) < 0) continue;

     ////////////////////// User's code starts here ///////////////////////

     ///Stuff to be done for every event

     size_t no_jets_ak4=jetPtAK4->size();

     vector<TLorentzVector> widejets;
     TLorentzVector wj1, wj2, wdijet; 
     TLorentzVector wj1_shift, wj2_shift, wdijet_shift; 

     vector<TLorentzVector> AK4jets;
     TLorentzVector ak4j1, ak4j2, ak4dijet;      

     resetCuts();

     // //find intime BX
     // int idx_InTimeBX=-1;
     // for(size_t j=0; j<PileupOriginBX->size(); ++j)
     //   {
     // 	 //cout << PileupOriginBX->at(j) << endl;	 
     // 	 if(PileupOriginBX->at(j)==0)
     // 	   {
     // 	     idx_InTimeBX = j;
     // 	     //cout << "idx_InTimeBX: " << idx_InTimeBX << endl; 
     // 	   }
     //   }

     std::vector<double> jecFactors;
     std::vector<double> jecUncertainty;
     // new JECs could change the jet pT ordering. the vector below
     // holds sorted jet indices after the new JECs had been applied
     std::vector<unsigned> sortedJetIdx;

     if( int(getPreCutValue1("useJECs"))==1 )
       {
	 // sort jets by increasing pT
	 std::multimap<double, unsigned> sortedJets;
	 for(size_t j=0; j<no_jets_ak4; ++j)
	   {
	     JetCorrector->setJetEta(jetEtaAK4->at(j));
	     JetCorrector->setJetPt(jetPtAK4->at(j)/jetJecAK4->at(j)); //pTraw
	     JetCorrector->setJetA(jetAreaAK4->at(j));
	     JetCorrector->setRho(rho);

  	     JetCorrector_data->setJetEta(jetEtaAK4->at(j));
	     JetCorrector_data->setJetPt(jetPtAK4->at(j)/jetJecAK4->at(j)); //pTraw
	     JetCorrector_data->setJetA(jetAreaAK4->at(j));
	     JetCorrector_data->setRho(rho);


  	     //nominal value of JECs
	     double correction;//, old_correction, nominal_correction;
	     //if( int(getPreCutValue1("shiftJECs"))==0 ){
	     if (isData == 1) correction = JetCorrector_data->getCorrection();
	     else correction = JetCorrector->getCorrection();
	     //nominal_correction=correction;
	     //old_correction = jetJecAK4->at(j);
	     //}
	     //JEC uncertainties
	     unc->setJetEta(jetEtaAK4->at(j));
	     unc->setJetPt(jetPtAK4->at(j)/jetJecAK4->at(j)*correction);
	     double uncertainty = unc->getUncertainty(true);
	     jecUncertainty.push_back(uncertainty); 

	     // std::cout << "run:" << runNo << "    lumi:" << lumi << "   event:" << evtNo << "   jet pt:" << jetPtAK4->at(j)/jetJecAK4->at(j)*correction << "   correction:" << correction <<   "   uncertainty:" <<  uncertainty  << "  nominal correction:" << nominal_correction  << " old correction: " << old_correction << std::endl;
	     //use "shifted" JECs for study of systematic uncertainties 
	     if( int(getPreCutValue1("shiftJECs"))==1 ){
	       //flat shift
	       //if (isData == 1) correction = JetCorrector_data->getCorrection() * getPreCutValue2("shiftJECs");
	       //else correction = JetCorrector->getCorrection() * getPreCutValue2("shiftJECs");
	       //shift of the corresponding unc
	       correction = correction + getPreCutValue2("shiftJECs")*uncertainty*correction;
	       //  std::cout << "run:" << runNo << "    lumi:" << lumi << "   event:" << evtNo << "   jet pt:" << jetPtAK3->at(j)/jetJecAK4->at(j)*correction << "   correction:" << correction << "   uncertainty:" <<  uncertainty  << std::endl << std::endl;
	       
	   }

	 jecFactors.push_back(correction);
	 sortedJets.insert(std::make_pair((jetPtAK4->at(j)/jetJecAK4->at(j))*correction, j));

       }
     // get jet indices in decreasing pT order
     for(std::multimap<double, unsigned>::const_reverse_iterator it = sortedJets.rbegin(); it != sortedJets.rend(); ++it)
	 sortedJetIdx.push_back(it->second);
     
     }
     else if( int(getPreCutValue1("noJECs"))==1  )
       {
	 // sort jets by increasing pT
	 std::multimap<double, unsigned> sortedJets;
	 for(size_t j=0; j<no_jets_ak4; ++j) //same ordering of original root trees
	   {
	     jecUncertainty.push_back(0.); 
	     jecFactors.push_back(1.);
	     sortedJets.insert(std::make_pair((jetPtAK4->at(j)/jetJecAK4->at(j)), j)); //raw
	   }       
	 // get jet indices in decreasing pT order
	 for(std::multimap<double, unsigned>::const_reverse_iterator it = sortedJets.rbegin(); it != sortedJets.rend(); ++it)
	   sortedJetIdx.push_back(it->second);
       }
     else
       {
	 for(size_t j=0; j<no_jets_ak4; ++j) //same ordering of original root trees
	   {
	     jecFactors.push_back(jetJecAK4->at(j));
	     jecUncertainty.push_back(0.); 
	     sortedJetIdx.push_back(j);
	   }
       }


     //#############################################################
     //########## NOTE: from now on sortedJetIdx[ijet] should be used
     //#############################################################

     // if(no_jets_ak4>=2){
     //  if(!(fabs(jetEtaAK4->at(0)) < getPreCutValue1("jetFidRegion") && idTAK4->at(0) == getPreCutValue1("tightJetID"))){
     //    std::cout << " JET 0 FAIL " << jetEtaAK4->at(0) << " JET 0  ID " << idTAK4->at(0) << std::endl;
     //  }
     //  if(!(fabs(jetEtaAK4->at(1)) < getPreCutValue1("jetFidRegion") && idTAK4->at(1) == getPreCutValue1("tightJetID"))){
     //    std::cout << " JET 1 FAIL " << jetEtaAK4->at(1) << " JET 1  ID " << idTAK4->at(1) << std::endl;
     //  }  
     // }

     //count ak4 jets passing pt threshold and id criteria
     int Nak4 = 0;
     double HTak4 = 0;

     for(size_t ijet=0; ijet<no_jets_ak4; ++ijet)
       {	 
	 //cout << "evtNo: " << evtNo << endl;	 
	 // cout << "ijet=" << ijet << " , sortedJetIdx[ijet]=" << sortedJetIdx[ijet] 
	 //      << " , raw pT=" << jetPtAK4->at(sortedJetIdx[ijet])/jetJecAK4->at(sortedJetIdx[ijet]) 
	 //      << " , final corrected pT - old =" << jetPtAK4->at(sortedJetIdx[ijet] ) 
	 //      << " , final corrected pT - new =" << (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet]))*jetPtAK4->at(sortedJetIdx[ijet])
	 //      << endl;

	 //////////////cout << "id Tight jet" << sortedJetIdx[1] << " = " << idTAK4->at(sortedJetIdx[1]) << endl;
	 if(fabs(jetEtaAK4->at(sortedJetIdx[ijet])) < getPreCutValue1("jetFidRegion")
	    && idTAK4->at(sortedJetIdx[ijet]) == getPreCutValue1("tightJetID")
	    && (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet]))*jetPtAK4->at(sortedJetIdx[ijet]) > getPreCutValue1("ptCut"))
	   {
	     Nak4 += 1;
	     HTak4 += (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet]))*jetPtAK4->at(sortedJetIdx[ijet]);
	   }
       }


     if( int(getPreCutValue1("useFastJet"))==1 )
     {
       // vector of ak4 jets used for wide jet clustering
       std::vector<fastjet::PseudoJet> fjInputs, fjInputs_shift;

       for(size_t j=0; j<no_jets_ak4; ++j)
       {
	 if( !(jetEtaAK4->at(sortedJetIdx[j]) < getPreCutValue1("jetFidRegion")
	       && idTAK4->at(sortedJetIdx[j]) == getPreCutValue1("tightJetID")) ) continue;

	 double rescale = (jecFactors[sortedJetIdx[j]]/jetJecAK4->at(sortedJetIdx[j]));

	 if( j==0 && !( rescale*jetPtAK4->at(sortedJetIdx[j]) > getPreCutValue1("pt0Cut")) ) continue;
	 else if( j==1 && !( rescale*jetPtAK4->at(sortedJetIdx[j]) > getPreCutValue1("pt1Cut")) ) continue;
	 else if( !( rescale*jetPtAK4->at(sortedJetIdx[j]) > getPreCutValue1("ptCut")) ) continue;

	 TLorentzVector tempJet, tempJet_shift;

	 tempJet.SetPtEtaPhiM( rescale*jetPtAK4->at(sortedJetIdx[j]) , jetEtaAK4->at(sortedJetIdx[j]) , jetPhiAK4->at(sortedJetIdx[j]) , rescale*jetMassAK4->at(sortedJetIdx[j]));
	 tempJet_shift.SetPtEtaPhiM( (1+jecUncertainty[sortedJetIdx[j]])* rescale*jetPtAK4->at(sortedJetIdx[j]) , jetEtaAK4->at(sortedJetIdx[j]) , jetPhiAK4->at(sortedJetIdx[j]) ,  (1+jecUncertainty[sortedJetIdx[j]])* rescale*jetMassAK4->at(sortedJetIdx[j]));

	 fjInputs.push_back(fastjet::PseudoJet(tempJet.Px(),tempJet.Py(),tempJet.Pz(),tempJet.E()));
	 fjInputs_shift.push_back(fastjet::PseudoJet(tempJet_shift.Px(),tempJet_shift.Py(),tempJet_shift.Pz(),tempJet_shift.E()));
       }

       fjClusterSeq = ClusterSequencePtr( new fastjet::ClusterSequence( fjInputs, *fjJetDefinition ) );
       fjClusterSeq_shift = ClusterSequencePtr( new fastjet::ClusterSequence( fjInputs_shift, *fjJetDefinition ) );

       std::vector<fastjet::PseudoJet> inclusiveWideJets = fastjet::sorted_by_pt( fjClusterSeq->inclusive_jets(0.) );
       std::vector<fastjet::PseudoJet> inclusiveWideJets_shift = fastjet::sorted_by_pt( fjClusterSeq_shift->inclusive_jets(0.) );

       if( inclusiveWideJets.size()>1 )
       {
	 wj1.SetPxPyPzE(inclusiveWideJets.at(0).px(), inclusiveWideJets.at(0).py(), inclusiveWideJets.at(0).pz(), inclusiveWideJets.at(0).e());
	 wj2.SetPxPyPzE(inclusiveWideJets.at(1).px(), inclusiveWideJets.at(1).py(), inclusiveWideJets.at(1).pz(), inclusiveWideJets.at(1).e());
	 wj1_shift.SetPxPyPzE(inclusiveWideJets_shift.at(0).px(), inclusiveWideJets_shift.at(0).py(), inclusiveWideJets_shift.at(0).pz(), inclusiveWideJets_shift.at(0).e());
	 wj2_shift.SetPxPyPzE(inclusiveWideJets_shift.at(1).px(), inclusiveWideJets_shift.at(1).py(), inclusiveWideJets_shift.at(1).pz(), inclusiveWideJets_shift.at(1).e());
       }
     }
     else
     {
       TLorentzVector wj1_tmp, wj2_tmp;
       TLorentzVector wj1_shift_tmp, wj2_shift_tmp;
       double wideJetDeltaR_ = getPreCutValue1("DeltaR");

       if(no_jets_ak4>=2)
	 {
	   if(fabs(jetEtaAK4->at(sortedJetIdx[0])) < getPreCutValue1("jetFidRegion") 
	      && (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0]))*jetPtAK4->at(sortedJetIdx[sortedJetIdx[0]]) > getPreCutValue1("pt0Cut"))
	     {
	       if(fabs(jetEtaAK4->at(sortedJetIdx[1])) < getPreCutValue1("jetFidRegion") 
		  && (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1]))*jetPtAK4->at(sortedJetIdx[1]) > getPreCutValue1("pt1Cut"))
		 {
		   TLorentzVector jet1, jet2, jet1_shift, jet2_shift;
		   jet1.SetPtEtaPhiM( (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetPtAK4->at(sortedJetIdx[0])
				      ,jetEtaAK4->at(sortedJetIdx[0]),jetPhiAK4->at(sortedJetIdx[0])
				      , (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) * jetMassAK4->at(sortedJetIdx[0]));
		   jet2.SetPtEtaPhiM( (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) *jetPtAK4->at(sortedJetIdx[1])
				      ,jetEtaAK4->at(sortedJetIdx[1]),jetPhiAK4->at(sortedJetIdx[1])
				      , (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) * jetMassAK4->at(sortedJetIdx[1]));
		   jet1_shift.SetPtEtaPhiM( (1+jecUncertainty[sortedJetIdx[0]])*(jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetPtAK4->at(sortedJetIdx[0])
				      ,jetEtaAK4->at(sortedJetIdx[0]),jetPhiAK4->at(sortedJetIdx[0])
				      , (1+jecUncertainty[sortedJetIdx[0]])*(jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) * jetMassAK4->at(sortedJetIdx[0]));
		   jet2_shift.SetPtEtaPhiM( (1+jecUncertainty[sortedJetIdx[1]])* (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) *jetPtAK4->at(sortedJetIdx[1])
				      ,jetEtaAK4->at(sortedJetIdx[1]),jetPhiAK4->at(sortedJetIdx[1])
				      , (1+jecUncertainty[sortedJetIdx[0]])*(jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) * jetMassAK4->at(sortedJetIdx[1]));
		   
		   for(Long64_t ijet=0; ijet<no_jets_ak4; ijet++)
		     { //jet loop for ak4
		       TLorentzVector currentJet;
		       
		       if(fabs(jetEtaAK4->at(sortedJetIdx[ijet])) < getPreCutValue1("jetFidRegion") 
			  && idTAK4->at(sortedJetIdx[ijet]) == getPreCutValue1("tightJetID") 
			  && (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet]))*jetPtAK4->at(sortedJetIdx[ijet]) > getPreCutValue1("ptCut"))
			 {
			   TLorentzVector currentJet, currentJet_shift;
			   currentJet.SetPtEtaPhiM( (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet])) *jetPtAK4->at(sortedJetIdx[ijet])
						    ,jetEtaAK4->at(sortedJetIdx[ijet]),jetPhiAK4->at(sortedJetIdx[ijet])
						    , (jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet])) *jetMassAK4->at(sortedJetIdx[ijet]));   
			   currentJet_shift.SetPtEtaPhiM( (1+jecUncertainty[sortedJetIdx[ijet]])*(jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet])) *jetPtAK4->at(sortedJetIdx[ijet])
						    ,jetEtaAK4->at(sortedJetIdx[ijet]),jetPhiAK4->at(sortedJetIdx[ijet])
						    , (1+jecUncertainty[sortedJetIdx[ijet]])*(jecFactors[sortedJetIdx[ijet]]/jetJecAK4->at(sortedJetIdx[ijet])) *jetMassAK4->at(sortedJetIdx[ijet]));   
			   
			   double DeltaR1 = currentJet.DeltaR(jet1);
			   double DeltaR2 = currentJet.DeltaR(jet2);
			   
			   if(DeltaR1 < DeltaR2 && DeltaR1 < wideJetDeltaR_)
			     {
			       wj1_tmp += currentJet;
			       wj1_shift_tmp += currentJet_shift;
			     }
			   else if(DeltaR2 < wideJetDeltaR_)
			     {
			       wj2_tmp += currentJet;
			       wj2_shift_tmp += currentJet_shift;
			     }			 
			 } // if AK4 jet passes fid and jetid.
		     } //end of ak4 jet loop		     

		   // if(wj1_tmp.Pt()==0 && wj2_tmp.Pt() ==0) 
		   // std::cout << " wj1_tmp.Pt() IN  " <<wj1_tmp.Pt()  << " wj2_tmp.Pt() " <<  wj2_tmp.Pt()  << std::endl;		     

		 } //fid, jet id, pt cut
	     } //fid, jet id, pt cut
	 } // end of two jets.
	 
       // Re-order the wide jets in pt
       if( wj1_tmp.Pt() > wj2_tmp.Pt())
	 {
	   wj1 = wj1_tmp;
	   wj2 = wj2_tmp;
	   wj1_shift = wj1_shift_tmp;
	   wj2_shift = wj2_shift_tmp;
	 }
       else
	 {
	   wj1 = wj2_tmp;
	   wj2 = wj1_tmp;
	   wj1_shift = wj2_shift_tmp;
	   wj2_shift = wj1_shift_tmp;
	 }
     }


     double MJJWide = 0; 
     double DeltaEtaJJWide = 0;
     double DeltaPhiJJWide = 0;
     double MJJWide_shift = 0; 
     if( wj1.Pt()>0 && wj2.Pt()>0 )
     {
       // Create dijet system
       wdijet = wj1 + wj2;
       MJJWide = wdijet.M();
       DeltaEtaJJWide = fabs(wj1.Eta()-wj2.Eta());
       DeltaPhiJJWide = fabs(wj1.DeltaPhi(wj2));
       
       wdijet_shift = wj1_shift + wj2_shift;
       MJJWide_shift = wdijet_shift.M();

       // Put widejets in the container
       widejets.push_back( wj1 );
       widejets.push_back( wj2 );
     }

     //AK4 jets
     if(no_jets_ak4>=2)
       //cout << "eta j1 " << jetEtaAK4->at(sortedJetIdx[0]) << endl;
       //cout << "pt j1 " << (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetPtAK4->at(sortedJetIdx[0]) << endl;
       {
	 if(fabs(jetEtaAK4->at(sortedJetIdx[0])) < getPreCutValue1("jetFidRegion") 
	    && (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0]))*jetPtAK4->at(sortedJetIdx[0]) > getPreCutValue1("pt0Cut"))
	   {
	     if(fabs(jetEtaAK4->at(sortedJetIdx[1])) < getPreCutValue1("jetFidRegion") 
		&& (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1]))*jetPtAK4->at(sortedJetIdx[1]) > getPreCutValue1("pt1Cut"))
	       {
		 //cout << "filling ak4j1 and ak4j2" << endl;
		 //cout << "pt ak4 j1 = " << (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetPtAK4->at(sortedJetIdx[0]) << endl;
		 ak4j1.SetPtEtaPhiM( (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetPtAK4->at(sortedJetIdx[0])
				     ,jetEtaAK4->at(sortedJetIdx[0])
				     ,jetPhiAK4->at(sortedJetIdx[0])
				     , (jecFactors[sortedJetIdx[0]]/jetJecAK4->at(sortedJetIdx[0])) *jetMassAK4->at(sortedJetIdx[0]));
		 ak4j2.SetPtEtaPhiM( (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) *jetPtAK4->at(sortedJetIdx[1])
				     ,jetEtaAK4->at(sortedJetIdx[1])
				     ,jetPhiAK4->at(sortedJetIdx[1])
				     , (jecFactors[sortedJetIdx[1]]/jetJecAK4->at(sortedJetIdx[1])) *jetMassAK4->at(sortedJetIdx[1]));
	       }
	   }
       }   

     double MJJAK4 = 0; 
     double DeltaEtaJJAK4 = 0;
     double DeltaPhiJJAK4 = 0;
     
     //std::cout << "ak4j1.Pt()=" << ak4j1.Pt() << "   ak4j2.Pt()=" << ak4j2.Pt() << std::endl;
     if( ak4j1.Pt()>0 && ak4j2.Pt()>0 )
     {
       // Create dijet system
       ak4dijet = ak4j1 + ak4j2;
       MJJAK4 = ak4dijet.M();
       DeltaEtaJJAK4 = fabs(ak4j1.Eta()-ak4j2.Eta());
       DeltaPhiJJAK4 = fabs(ak4j1.DeltaPhi(ak4j2));

       // Put widejets in the container
       AK4jets.push_back( ak4j1 );
       AK4jets.push_back( ak4j2 );
     }

     // GenJets
     double gen_mjj = -9999.0;
     double gen_deltaETAjj = -9999.0;
     TLorentzVector gen_wj1, gen_wj2;
     double pTGenAK4_j1 = -9999.0;
     double pTGenAK4_j2 = -9999.0;
     if (!isData) {
         double gen_wideJetDeltaR_ = getPreCutValue1("DeltaR");
         if (nGenJetsAK4 >= 2) {
             if (fabs(jetEtaGenAK4->at(0)) < getPreCutValue1("jetFidRegion")
                 && jetPtGenAK4->at(0) > getPreCutValue1("pt0Cut")
                 && fabs(jetEtaGenAK4->at(1)) < getPreCutValue1("jetFidRegion")
                 && jetPtGenAK4->at(1) > getPreCutValue1("pt1Cut")) {
                 TLorentzVector jet1, jet2;
                 jet1.SetPtEtaPhiM(jetPtGenAK4->at(0), jetEtaGenAK4->at(0),
                                   jetPhiGenAK4->at(0), jetMassGenAK4->at(0));
                 jet2.SetPtEtaPhiM(jetPtGenAK4->at(1), jetEtaGenAK4->at(1),
                                   jetPhiGenAK4->at(1), jetMassGenAK4->at(1));
                 for (int i=0; i<nGenJetsAK4; ++i) {
                     if(fabs(jetEtaGenAK4->at(i)) < getPreCutValue1("jetFidRegion")
                        && jetPtGenAK4->at(i) > getPreCutValue1("ptCut")) {
                         TLorentzVector currentJet;
                         currentJet.SetPtEtaPhiM(jetPtGenAK4->at(i),
                                                 jetEtaGenAK4->at(i),
                                                 jetPhiGenAK4->at(i),
                                                 jetMassGenAK4->at(i));
                         double DeltaR1 = currentJet.DeltaR(jet1);
                         double DeltaR2 = currentJet.DeltaR(jet2);

                         if (DeltaR1 < DeltaR2 && DeltaR1 < gen_wideJetDeltaR_)
                             gen_wj1 += currentJet;
                         else if (DeltaR2 < gen_wideJetDeltaR_)
                             gen_wj2 += currentJet;
                     }
                 }
             }
         }

         if (gen_wj1.Pt() > 0.0 && gen_wj2.Pt() > 0.0) {
             TLorentzVector gen_wdijet = gen_wj1 + gen_wj2;
             gen_mjj = gen_wdijet.M();
             gen_deltaETAjj = fabs(gen_wj1.Eta() - gen_wj2.Eta());
         }

         double gen_minDeltaR_j1 = 9999.0;
         double gen_minDeltaR_j2 = 9999.0;
         double gen_maxDeltaR = 0.4;
         if (AK4jets.size() > 1) {
             for (int i=0; i<nGenJetsAK4; ++i) {
                 TLorentzVector currentJet;
                 currentJet.SetPtEtaPhiM(jetPtGenAK4->at(i), jetEtaGenAK4->at(i),
                                         jetPhiGenAK4->at(i), jetMassGenAK4->at(i));
                 double DeltaR1 = currentJet.DeltaR(AK4jets[0]);
                 double DeltaR2 = currentJet.DeltaR(AK4jets[1]);

                 if (DeltaR1 < DeltaR2 && DeltaR1 < gen_maxDeltaR) {
                     if (DeltaR1 < gen_minDeltaR_j1) {
                         pTGenAK4_j1 = currentJet.Pt();
                         gen_minDeltaR_j1 = DeltaR1;
                     } else if (DeltaR2 < gen_minDeltaR_j2 && DeltaR2 < gen_maxDeltaR) {
                         pTGenAK4_j2 = currentJet.Pt();
                         gen_minDeltaR_j2 = DeltaR2;
                     }
                 } else { // DeltaR2 > DeltaR1
                     if (DeltaR2 < gen_maxDeltaR && DeltaR2 < gen_minDeltaR_j2) {
                         pTGenAK4_j2 = currentJet.Pt();
                         gen_minDeltaR_j2 = DeltaR2;
                     } else if (DeltaR1 < gen_minDeltaR_j1 && DeltaR1 < gen_maxDeltaR) {
                         pTGenAK4_j1 = currentJet.Pt();
                         gen_minDeltaR_j1 = DeltaR1;
                     }
                 }
             }
         }
     }

     //== Fill Variables ==
     fillVariableWithValue("isData",isData);     
     fillVariableWithValue("run",runNo);     
     fillVariableWithValue("event",evtNo);     
     fillVariableWithValue("lumi",lumi);     
     fillVariableWithValue("nVtx",nvtx);     
     fillVariableWithValue("nJet",widejets.size());
     fillVariableWithValue("Nak4",Nak4);
     fillVariableWithValue ( "PassJSON", passJSON (runNo, lumi, isData));

     //directly taken from big root tree (i.e. jec not reapplied)
     fillVariableWithValue("htAK4",htAK4); // summing all jets with minimum pT cut and no jetid cut (jec not reapplied)
     fillVariableWithValue("mhtAK4",mhtAK4); //summing all jets with minimum pT cut and no jetid cut (jec not reapplied)
     fillVariableWithValue("mhtAK4Sig",mhtAK4Sig); // mhtAK4/htAK4 summing all jets with minimum pT cut and no jetid cut (jec not reapplied)
     fillVariableWithValue("offMet",offMet); //recomputed from PF candidates (off=offline)
     fillVariableWithValue("offMetSig",offMetSig); // offMet/offSumEt recomputed from PF candidates (off=offline)
     fillVariableWithValue("met",met); //directly taken from event
     fillVariableWithValue("metSig",metSig); // met/offMetSig (to be substituted with met/SumEt from event in future)

     if( AK4jets.size() >=1 ){
       //cout << "AK4jets.size() " <<  AK4jets.size() << endl;
       //cout << "IdTight_j1 : " << idTAK4->at(sortedJetIdx[0]) << endl;
       fillVariableWithValue( "IdTight_j1",idTAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "pTAK4_j1", AK4jets[0].Pt());
       fillVariableWithValue( "etaAK4_j1", AK4jets[0].Eta());
       fillVariableWithValue( "phiAK4_j1", AK4jets[0].Phi());
       //fillVariableWithValue( "jetPtAK4matchCaloJet_j1", jetPtAK4matchCaloJet->at(sortedJetIdx[0]));
       fillVariableWithValue( "jetJecAK4_j1", jecFactors[sortedJetIdx[0]] );
       fillVariableWithValue( "jetJecUncAK4_j1", jecUncertainty[sortedJetIdx[0]] );
       //jetID
       fillVariableWithValue( "neutrHadEnFrac_j1", jetNhfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "chargedHadEnFrac_j1", jetChfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "photonEnFrac_j1", jetPhfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "eleEnFract_j1", jetElfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "muEnFract_j1", jetMufAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "neutrElectromFrac_j1", jetNemfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "chargedElectromFrac_j1", jetCemfAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "chargedMult_j1", chMultAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "neutrMult_j1", neMultAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "photonMult_j1", phoMultAK4->at(sortedJetIdx[0]));
       fillVariableWithValue( "jetCSVAK4_j1", jetCSVAK4->at(sortedJetIdx[0]) );
     }
     if( AK4jets.size() >=2 ){
       //cout << "IdTight_j2 : " << idTAK4->at(sortedJetIdx[1]) << endl << endl;
       fillVariableWithValue( "IdTight_j2",idTAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "pTAK4_j2", AK4jets[1].Pt() );
       fillVariableWithValue( "etaAK4_j2", AK4jets[1].Eta());
       fillVariableWithValue( "phiAK4_j2", AK4jets[1].Phi());
       //fillVariableWithValue( "jetPtAK4matchCaloJet_j2", jetPtAK4matchCaloJet->at(sortedJetIdx[1]));
       fillVariableWithValue( "jetJecAK4_j2", jecFactors[sortedJetIdx[1]]); 
       fillVariableWithValue( "jetJecUncAK4_j2", jecUncertainty[sortedJetIdx[1]] );
       //jetID
       fillVariableWithValue( "neutrHadEnFrac_j2", jetNhfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "chargedHadEnFrac_j2", jetChfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "photonEnFrac_j2", jetPhfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "eleEnFract_j2", jetElfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "muEnFract_j2", jetMufAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "neutrElectromFrac_j2", jetNemfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "chargedElectromFrac_j2", jetCemfAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "chargedMult_j2", chMultAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "neutrMult_j2", neMultAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "photonMult_j2", phoMultAK4->at(sortedJetIdx[1]));
       fillVariableWithValue( "jetCSVAK4_j2", jetCSVAK4->at(sortedJetIdx[1]) );
       //dijet
       fillVariableWithValue( "Dijet_MassAK4", MJJAK4) ; 
       fillVariableWithValue( "CosThetaStarAK4", TMath::TanH( (AK4jets[0].Eta()-AK4jets[1].Eta())/2 )); 
       fillVariableWithValue( "deltaETAjjAK4", DeltaEtaJJAK4 ) ;
       fillVariableWithValue( "deltaPHIjjAK4", DeltaPhiJJAK4 ) ;
     }

     if( widejets.size() >= 1 ){
         fillVariableWithValue( "pTWJ_j1", widejets[0].Pt() );
         fillVariableWithValue( "etaWJ_j1", widejets[0].Eta());
	 //no cuts on these variables, just to store in output
         fillVariableWithValue( "massWJ_j1", widejets[0].M());
         fillVariableWithValue( "phiWJ_j1", widejets[0].Phi());
       }

     if( widejets.size() >= 2 ){
         fillVariableWithValue( "pTWJ_j2", widejets[1].Pt() );
         fillVariableWithValue( "etaWJ_j2", widejets[1].Eta());
	 fillVariableWithValue( "deltaETAjj", DeltaEtaJJWide ) ;
         fillVariableWithValue( "mjj", MJJWide ) ;
         fillVariableWithValue( "mjj_shiftJEC", MJJWide_shift ) ;
	 //no cuts on these variables, just to store in output
         fillVariableWithValue( "massWJ_j2", widejets[1].M());
         fillVariableWithValue( "phiWJ_j2", widejets[1].Phi());	
	 //dijet
         fillVariableWithValue( "CosThetaStarWJ", TMath::TanH( (widejets[0].Eta()-widejets[1].Eta())/2 )); 
	 fillVariableWithValue( "deltaPHIjj", DeltaPhiJJWide ) ;
	 //fillVariableWithValue( "Dijet_MassAK8", mjjAK8 ) ;  
	 //fillVariableWithValue( "Dijet_MassC", mjjCA8 ) ;
	 // if(wdijet.M()<1){
	 //    std::cout << " INV MASS IS " << wdijet.M() << std::endl;
	 //    std::cout << " Delta Eta IS " << DeltaEtaJJWide << " n is  " << widejets.size() << std::endl;
	 //    std::cout << " INV MASS FROM NTUPLE AK8 " << mjjAK8 << std::endl;
	 //    //std::cout << " INV MASS FROM NTUPLE CA8 " << mjjCA8 << std::endl;
       }

     if (!isData) {
         fillVariableWithValue("gen_mjj", gen_mjj);
         fillVariableWithValue("gen_deltaETAjj", gen_deltaETAjj);
         fillVariableWithValue("pTGenAK4_j1", pTGenAK4_j1);
         fillVariableWithValue("pTGenAK4_j2", pTGenAK4_j2);
     }

     //no cuts on these variables, just to store in output
     // if(!isData)
     //   fillVariableWithValue("trueVtx",PileupInteractions->at(idx_InTimeBX));
     // else if(isData)
     //   fillVariableWithValue("trueVtx",999);     

     // Trigger
     //int NtriggerBits = triggerResult->size();
     /*if (isData)
       {
	 fillVariableWithValue("passHLT_ZeroBias_BtagSeq",triggerResult->at(8));// DST_ZeroBias_BTagScouting_v* (run>=259636)
	 fillVariableWithValue("passHLT_ZeroBias",triggerResult->at(7));// DST_ZeroBias_PFScouting_v* (run>=259636)

	 fillVariableWithValue("passHLT_L1DoubleMu_BtagSeq",triggerResult->at(9));// DST_L1DoubleMu_BTagScouting_v* (run>=259636)
	 fillVariableWithValue("passHLT_L1DoubleMu",triggerResult->at(10));// DST_L1DoubleMu_PFScouting_v* (run>=259636)

	 fillVariableWithValue("passHLT_CaloJet40_BtagSeq",triggerResult->at(0));//  DST_CaloJet40_PFReco_PFBTagCSVReco_PFScouting_v* (257933<=run<259636) 
	                                                                        //  OR DST_CaloJet40_BTagScouting_v* (run>=259636)
	 fillVariableWithValue("passHLT_CaloJet40",triggerResult->at(1));// DST_CaloJet40_CaloScouting_PFScouting_v*  (run>=259636)

	 fillVariableWithValue("passHLT_L1HTT150_BtagSeq",triggerResult->at(2));// DST_L1HTT125ORHTT150ORHTT175_PFReco_PFBTagCSVReco_PFScouting_v* (257933<=run<259636) 
	                                                                        // OR DST_L1HTT_BTagScouting_v* (run>=259636)    
	 fillVariableWithValue("passHLT_L1HTT150",triggerResult->at(3));// DST_L1HTT_CaloScouting_PFScouting_v* (run>=259636)

	 fillVariableWithValue("passHLT_HT450_BtagSeq",triggerResult->at(5));// DST_HT450_PFReco_PFBTagCSVReco_PFScouting_v* (257933<=run<259636) 
	                                                                     // OR DST_HT450_BTagScouting_v* (run>=259636)    
	 fillVariableWithValue("passHLT_HT450",triggerResult->at(6));// DST_HT450_PFScouting_v* (run>=259636)        

	 fillVariableWithValue("passHLT_PFHT800",triggerResult->at(13));// HLT_PFHT800_v* (all runs)   
	 fillVariableWithValue("passHLT_PFHT650MJJ950",triggerResult->at(22));// HLT_PFHT650_WideJetMJJ950DEtaJJ1p5_v* (all runs)        
	 fillVariableWithValue("passHLT_PFHT650MJJ900",triggerResult->at(23));// HLT_PFHT650_WideJetMJJ900DEtaJJ1p5_v* (all runs)        
       }*/

     // Evaluate cuts (but do not apply them)
     evaluateCuts();
     
     // optional call to fill a skim with the full content of the input roottuple
     //if( passedCut("nJetFinal") ) fillSkimTree();
     if( passedCut("PassJSON")
	 && passedCut("nVtx") 
	 && passedCut("IdTight_j1")
	 && passedCut("IdTight_j2")
	 && passedCut("nJet")
	 && passedCut("pTWJ_j1")
	 && passedCut("etaWJ_j1")
	 && passedCut("pTWJ_j2")
	 && passedCut("etaWJ_j2")
	 && getVariableValue("deltaETAjj") <  getPreCutValue1("DetaJJforTrig") ){

       h_mjj_NoTrigger_1GeVbin -> Fill(MJJWide); 
       h_mjj_NoTrigger -> Fill(MJJWide); 
       
       /*if( (getVariableValue("passHLT_ZeroBias_BtagSeq")||getVariableValue("passHLT_ZeroBias")) )
	 h_mjj_HLTpass_ZeroBias -> Fill(MJJWide);  

       if( (getVariableValue("passHLT_ZeroBias_BtagSeq")||getVariableValue("passHLT_ZeroBias")) 
	   && (getVariableValue("passHLT_L1HTT150_BtagSeq")||getVariableValue("passHLT_L1HTT150")) )
	 h_mjj_HLTpass_ZeroBias_L1HTT150 -> Fill(MJJWide);  

       if( (getVariableValue("passHLT_L1HTT150_BtagSeq")||getVariableValue("passHLT_L1HTT150")) )
	 h_mjj_HLTpass_L1HTT150 -> Fill(MJJWide);  

       if( (getVariableValue("passHLT_L1HTT150_BtagSeq")||getVariableValue("passHLT_L1HTT150")) 
	   && (getVariableValue("passHLT_HT450_BtagSeq")||getVariableValue("passHLT_HT450")) )
           h_mjj_HLTpass_L1HTT150_HT450 -> Fill(MJJWide);  */
       
     }

     // optional call to fill a skim with a subset of the variables defined in the cutFile (use flag SAVE)
     if( passedAllPreviousCuts("mjj") && passedCut("mjj") ) 
       {
	 fillReducedSkimTree();

	 // ===== Take a look at this =====
	 // //Example on how to investigate quickly the data
	 // if(getVariableValue("mjj")>4000)
	 //   {
	 //     //fast creation and filling of histograms
	 //     CreateAndFillUserTH1D("h_dphijj_mjjgt4000", 100, 0, 3.15, getVariableValue("deltaPHIjj"));
	 //     CreateAndFillUserTH1D("h_htak4_mjjgt4000", 1000, 0, 10000, getVariableValue("HTAK4"));
	 //     CreateAndFillUserTH1D("h_nvtx_mjjgt4000", 31, -0.5, 30.5, getVariableValue("nVtx"));
	 //   }

       }

     // ===== Example of mjj spectrum after HLT selection =====
     // if( passedAllPreviousCuts("mjj") )
     //   {
     // 	 if(getVariableValue("passHLT")>0)
     // 	   {
     // 	     //fast creation and filling of histograms
     // 	     CreateAndFillUserTH1D("h_mjj_passHLT", getHistoNBins("mjj"), getHistoMin("mjj"), getHistoMax("mjj"), getVariableValue("mjj"));
     // 	   }
     //   }

     // reject events that did not pass level 0 cuts
     //if( !passedCut("0") ) continue;
     // ......
     
     // reject events that did not pass level 1 cuts
     //if( !passedCut("1") ) continue;
     // ......

     // reject events that did not pass the full cut list
     //if( !passedCut("all") ) continue;
     // ......

     // if( widejets.size() >= 2) {
     //  h_nJetFinal->Fill(widejets.size());
     //  h_DijetMass->Fill(wdijet.M());
     //  h_pT1stJet->Fill(widejets[0].Pt());
     //  h_pT2ndJet->Fill(widejets[1].Pt());
     //  h_eta1stJet->Fill(widejets[0].Eta());
     //  h_eta2ndJet->Fill(widejets[1].Eta());
     // }
     ////////////////////// User's code ends here ///////////////////////

   } // End loop over events

   //////////write histos 

   h_mjj_NoTrigger_1GeVbin -> Write();
   h_mjj_NoTrigger -> Write();
   /*h_mjj_HLTpass_ZeroBias -> Write();
   h_mjj_HLTpass_ZeroBias_L1HTT150 -> Write();
   h_mjj_HLTpass_L1HTT150 -> Write();
   h_mjj_HLTpass_L1HTT150_HT450 -> Write();*/

   // h_nVtx->Write();
   // h_trueVtx->Write();
   // h_nJetFinal->Write();
   // h_pT1stJet->Write();
   // h_pT2ndJet->Write();
   // h_DijetMass->Write();
   // h_eta1stJet->Write();
   // h_eta2ndJet->Write();

   // //pT of both jets, to be built using the histograms produced automatically by baseClass
   // TH1F * h_pTJets = new TH1F ("h_pTJets","", getHistoNBins("pT1stJet"), getHistoMin("pT1stJet"), getHistoMax("pT1stJet"));
   // h_pTJets->Add( & getHisto_noCuts_or_skim("pT1stJet") ); // all histos can be retrieved, see other getHisto_xxxx methods in baseClass.h
   // h_pTJets->Add( & getHisto_noCuts_or_skim("pT2ndJet") );
   // //one could also do:  *h_pTJets = getHisto_noCuts_or_skim("pT1stJet") + getHisto_noCuts_or_skim("pT2ndJet");
   // h_pTJets->Write();
   // //one could also do:   const TH1F& h = getHisto_noCuts_or_skim// and use h

   std::cout << "analysisClass::Loop() ends" <<std::endl;   
   }
void analysisClass::Loop()
{
   std::cout << "analysisClass::Loop() begins" <<std::endl;   
    
   if (fChain == 0) return;
   
   //////////book histos here

#ifdef USE_EXAMPLE
   STDOUT("WARNING: using example code. In order NOT to use it, comment line that defines USE_EXAMPLE flag in Makefile.");   
   // number of electrons
   TH1F *h_nEleFinal = new TH1F ("h_nEleFinal","",11,-0.5,10.5);
   h_nEleFinal->Sumw2();
   //pT 1st ele
   TH1F *h_pT1stEle = new TH1F ("h_pT1stEle","",100,0,1000);
   h_pT1stEle->Sumw2();
   //pT 2nd ele
   TH1F *h_pT2ndEle = new TH1F ("h_pT2ndEle","",100,0,1000);
   h_pT2ndEle->Sumw2();

#endif //end of USE_EXAMPLE

   /////////initialize variables

   Long64_t nentries = fChain->GetEntriesFast();
   std::cout << "analysisClass::Loop(): nentries = " << nentries << std::endl;   

   ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
   ////// If the root version is updated and rootNtupleClass regenerated,     /////
   ////// these lines may need to be updated.                                 /////    
   Long64_t nbytes = 0, nb = 0;
   for (Long64_t jentry=0; jentry<nentries;jentry++) {
     Long64_t ientry = LoadTree(jentry);
     if (ientry < 0) break;
     nb = fChain->GetEntry(jentry);   nbytes += nb;
     if(jentry < 10 || jentry%1000 == 0) std::cout << "analysisClass::Loop(): jentry = " << jentry << std::endl;   
     // if (Cut(ientry) < 0) continue;

     ////////////////////// User's code starts here ///////////////////////

     ///Stuff to be done every event

#ifdef USE_EXAMPLE
     // Electrons
     vector<int> v_idx_ele_final;
     for(int iele=0;iele<eleCount;iele++)
       {
	 // ECAL barrel fiducial region
	 bool pass_ECAL_FR=false;
	 if( fabs(eleEta[iele]) < getPreCutValue1("eleFidRegion") )	v_idx_ele_final.push_back(iele);
       }     

     // Set the evaluation of the cuts to false and clear the variable values and filled status
     resetCuts();
     
     // Set the value of the variableNames listed in the cutFile to their current value
     fillVariableWithValue("nEleFinal", v_idx_ele_final.size()) ;
     if( v_idx_ele_final.size() >= 1 ) 
       {
	 fillVariableWithValue( "pT1stEle", elePt[v_idx_ele_final[0]] );
       }
     if( v_idx_ele_final.size() >= 2 ) 
       {
	 fillVariableWithValue( "pT2ndEle", elePt[v_idx_ele_final[1]] );
	 // Calculate Mee
	 TLorentzVector v_ee, ele1, ele2;
	 ele1.SetPtEtaPhiM(elePt[v_idx_ele_final[0]],eleEta[v_idx_ele_final[0]],elePhi[v_idx_ele_final[0]],0);
	 ele2.SetPtEtaPhiM(elePt[v_idx_ele_final[1]],eleEta[v_idx_ele_final[1]],elePhi[v_idx_ele_final[1]],0);
	 v_ee = ele1 + ele2;
	 fillVariableWithValue( "invMass_ee", v_ee.M() ) ;
       }

     // Evaluate cuts (but do not apply them)
     evaluateCuts();
     
     // Fill histograms and do analysis based on cut evaluation
     h_nEleFinal->Fill(v_idx_ele_final.size());
     //if( v_idx_ele_final.size()>=1 ) h_pT1stEle->Fill(elePt[v_idx_ele_final[0]]);
     //if( v_idx_ele_final.size()>=2 && (elePt[v_idx_ele_final[0]])>85 ) h_pT2ndEle->Fill(elePt[v_idx_ele_final[1]]);
     if( passedCut("pT1stEle") ) h_pT1stEle->Fill(elePt[v_idx_ele_final[0]]);
     if( passedCut("pT2ndEle") ) h_pT2ndEle->Fill(elePt[v_idx_ele_final[1]]);
     
     // retrieve value of previously filled variables (after making sure that they were filled)
     double totpTEle;
     if ( variableIsFilled("pT1stEle") && variableIsFilled("pT2ndEle") ) 
       totpTEle = getVariableValue("pT1stEle")+getVariableValue("pT2ndEle");

     // reject events that did not pass level 0 cuts
     if( !passedCut("0") ) continue;
     // ......
     
     // reject events that did not pass level 1 cuts
     if( !passedCut("1") ) continue;
     // ......

     // reject events that did not pass the full cut list
     if( !passedCut("all") ) continue;
     // ......

#endif  // end of USE_EXAMPLE


     ////////////////////// User's code ends here ///////////////////////

   } // End loop over events

   //////////write histos 

#ifdef USE_EXAMPLE
   STDOUT("WARNING: using example code. In order NOT to use it, comment line that defines USE_EXAMPLE flag in Makefile.");   

   h_nEleFinal->Write();
   h_pT1stEle->Write();
   h_pT2ndEle->Write();

   //pT of both electrons, to be built using the histograms produced automatically by baseClass
   TH1F * h_pTElectrons = new TH1F ("h_pTElectrons","", getHistoNBins("pT1stEle"), getHistoMin("pT1stEle"), getHistoMax("pT1stEle"));
   h_pTElectrons->Add( & getHisto_noCuts_or_skim("pT1stEle") ); // all histos can be retrieved, see other getHisto_xxxx methods in baseClass.h
   h_pTElectrons->Add( & getHisto_noCuts_or_skim("pT2ndEle") );
   //one could also do:  *h_pTElectrons = getHisto_noCuts_or_skim("pT1stEle") + getHisto_noCuts_or_skim("pT2ndEle");
   h_pTElectrons->Write();
   //one could also do:   const TH1F& h = getHisto_noCuts_or_skim// and use h
#endif // end of USE_EXAMPLE
   std::cout << "analysisClass::Loop() ends" <<std::endl;   
}
Exemplo n.º 17
0
 /** Evaluates a function-number sequence.
   * Replaces the two lines with a single line containing the result of the evaluation.
   */
  void Calculator::evaluateFunction(QStringList & expressionParts, int functionLine)
  {
      double result =0.0;
      bool ok = true;
      QString sArgument = expressionParts[functionLine + 1];
      double argument = 0.0;

      if(isVariable(sArgument))
          argument = getVariableValue(sArgument);
      else argument = sArgument.toDouble(&ok);

      if(!ok)
          throw ExExpressionError(tr("Function name must be followed by a number."));
      QString function = expressionParts[functionLine].toLower();
      if(!isFunction(function))
          throw ExExpressionError(tr("Unknown function:") + function);

      if(function == "sin")
          result = sin(toRad(argument));
      else if(function == "arcsin")
      {
          if(argument < -1.0 || argument > 1.0)
              throw ExExpressionError(tr("Argument of arcsin must be in the range from -1 to 1. Found:") + " "
                                      + expressionParts[functionLine + 1] );
          result = fromRad(asin(argument));
      }
      else if(function == "cos")
          result = cos(toRad(argument));
      else if(function == "arccos")
      {
          if(argument < -1.0 || argument > 1.0)
              throw ExExpressionError(tr("Argument of arccos must be in the range from -1 to 1. Found:") + " "
                                      + expressionParts[functionLine+1] );
          result = fromRad(acos(argument));
      }
      else if(function == "tan")
          result = tan(toRad(argument));
      else if(function == "arctan")
      {
          result = fromRad(atan(argument));
      }
      else if(function == "sinh")
          result = sinh(argument);
      else if(function == "arsinh")
      {
          result = asinh(argument);
      }
      else if(function == "cosh")
          result = cosh(argument);
      else if(function == "arcosh")
      {
          if(argument < 1.0 )
              throw ExExpressionError(tr("Argument of arcosh must be >= 1. Found:") + " "
                                      + QString::number(argument) );
          result = acosh(argument);
      }
      else if(function == "tanh")
          result = tanh(argument);
      else if(function == "artanh")
      {
          if(argument < -1.0 || argument > 1.0 )
              throw ExExpressionError(tr("Argument of artanh must be in the range from -1 to 1. Found:") + " "
                                      + QString::number(argument) );
          result = atanh(argument);
      }
      else if(function == "exp")
          result = exp(argument);
      else if(function == "ln")
      {
          if(argument <= 0.0)
              throw ExExpressionError(tr("Argument of ln must be > 0. Found:") + " "
                                      + QString::number(argument) );
          result = log(argument);
      }
      else if(function == "log")
      {
          if(argument < 0.0)
              throw ExExpressionError(tr("Argument of log must be > 0. Found:") + " "
                                      + QString::number(argument) );
          result = log10(argument);
      }
      else if(function == "sqrt" || function == textSqrt())
      {
          if(argument < 0.0)
              throw ExExpressionError(tr("Argument of sqrt must be > 0. Found:") + " "
                                      + QString::number(argument) );
          result = sqrt(argument);
      }
      if(function != textPi()) //Pi has no argument
         expressionParts.removeAt(functionLine +1);
      expressionParts[functionLine] = QString::number(result, 'G');
  }
void analysisClass::Loop()
{
  //STDOUT("analysisClass::Loop() begins");
  
  if (fChain == 0) return;

   TH1F *h_TrigDiff = new TH1F("TrigDiff","TrigDiff",3.0,-1.5,1.5);
   TH2F *h2_DebugTrig = new TH2F("DebugTrig","DebugTrig;HLTResults;HLTBits",2,0,2,2,0,2);
   
   TH1F *h_dPhi_JetSC = new TH1F("dPhi_JetSC","dPhi_JetSC",650,0,6.5); h_dPhi_JetSC->Sumw2();
   TH1F *h_dR_JetSC = new TH1F("dR_JetSC","dR_JetSC",600,0,3.0); h_dR_JetSC->Sumw2();
   TH1F *h_NisoSC = new TH1F ("NisoSC","NisoSC",6,-0.5,5.5);  h_NisoSC->Sumw2();

   TH1F *h_goodEleSCPt = new TH1F ("goodEleSCPt","goodEleSCPt",100,0,100); h_goodEleSCPt->Sumw2();
   TH1F *h_goodEleSCEta = new TH1F ("goodEleSCEta","goodEleSCEta",100,-3.,3.); h_goodEleSCEta->Sumw2();
   TH1F *h_goodEleSCPt_Barrel = new TH1F ("goodEleSCPt_Barrel","goodEleSCPt_Barrel",100,0,100); h_goodEleSCPt_Barrel->Sumw2();
   TH1F *h_goodEleSCPt_Endcap = new TH1F ("goodEleSCPt_Endcap","goodEleSCPt_Endcap",100,0,100); h_goodEleSCPt_Endcap->Sumw2();

   TH1F *h_goodSCPt = new TH1F ("goodSCPt","goodSCPt",100,0,100); h_goodSCPt->Sumw2();
   TH1F *h_goodSCEta = new TH1F ("goodSCEta","goodSCEta",100,-3.,3.); h_goodSCEta->Sumw2();
   TH1F *h_goodSCPt_Barrel = new TH1F ("goodSCPt_Barrel","goodSCPt_Barrel",100,0,100); h_goodSCPt_Barrel->Sumw2();
   TH1F *h_goodSCPt_Endcap = new TH1F ("goodSCPt_Endcap","goodSCPt_Endcap",100,0,100); h_goodSCPt_Endcap->Sumw2();

   TH1F *h_eta_failHLT = new TH1F("eta_failHLT","eta_failHLT",500,-3.0,3.0);
   TH1F *h_phi_failHLT = new TH1F("phi_failHLT","phi_failHLT",100,-3.5,3.5);

   /////////initialize variables
   double FailRate = 0;
   double NFailHLT = 0;
   double HasSC = 0;

  
  ////////////////////// User's code to book histos - END ///////////////////////
    
  Long64_t nentries = fChain->GetEntriesFast();
  STDOUT("analysisClass::Loop(): nentries = " << nentries);   
  
  ////// The following ~7 lines have been taken from rootNtupleClass->Loop() /////
  ////// If the root version is updated and rootNtupleClass regenerated,     /////
  ////// these lines may need to be updated.                                 /////    
  Long64_t nbytes = 0, nb = 0;
  for (Long64_t jentry=0; jentry<nentries;jentry++) { // Begin of loop over events
  //for (Long64_t jentry=0; jentry<10000;jentry++) { // Begin of loop over events
    Long64_t ientry = LoadTree(jentry);
    if (ientry < 0) break;
    nb = fChain->GetEntry(jentry);   nbytes += nb;
    if(jentry < 10 || jentry%10000 == 0) STDOUT("analysisClass::Loop(): jentry = " << jentry);   
    // if (Cut(ientry) < 0) continue;
    
    ////////////////////// User's code to be done for every event - BEGIN ///////////////////////

    //## HLT

    bool PassTrig=HLTResults->at(1); // results of HLTPhoton15 
    //bool PassTrig=HLTBits->at(71); // results of HLTPhoton15 
    int TrigDiff = HLTBits->at(71) - HLTResults->at(1);
    h_TrigDiff->Fill(TrigDiff);
    h2_DebugTrig->Fill(HLTResults->at(1),HLTBits->at(71));

    // Electrons
    vector<int> v_idx_ele_all;
    vector<int> v_idx_ele_PtCut;
    vector<int> v_idx_ele_HEEP;
    int eleIDType = (int) getPreCutValue1("eleIDType");
     
    //Loop over electrons
    for(int iele=0; iele<ElectronPt->size(); iele++)
      {
	//no cut on reco electrons
	v_idx_ele_all.push_back(iele); 

	//pT pre-cut on ele
	if( ElectronPt->at(iele) < getPreCutValue1("ele_PtCut") ) continue; 
	v_idx_ele_PtCut.push_back(iele);

	//ID + ISO + NO overlap with good muons 
	int eleID = ElectronPassID->at(iele);
	if ( (eleID & 1<<eleIDType) > 0  && ElectronOverlaps->at(iele)==0 )
	  {
	    v_idx_ele_HEEP.push_back(iele);
	  }

// 	bool HEEP = false;
// 	if (fabs(ElectronEta->at(iele))<1.442){
// 	if (fabs(ElectronDeltaEtaTrkSC->at(iele))<0.005){
// 	  if (fabs(ElectronDeltaPhiTrkSC->at(iele))<0.09){
// 	    if (ElectronHoE->at(iele)<0.05){
// 		if ((ElectronE2x5OverE5x5->at(iele)>0.94)||(ElectronE1x5OverE5x5->at(iele)>0.83)){
// 		  if ((ElectronEcalIsoHeep->at(iele) + ElectronHcalIsoD1Heep->at(iele))<(2+0.03*ElectronPt->at(iele))){
// 		    if (ElectronTrkIsoHeep->at(iele)<7.5){
// 		      HEEP = true;
// 		    }
// 		  }
// 		}
// 	      }
// 	    }
// 	  }
// 	}

// 	double eleEt = ElectronPt->at(iele);
// 	if ((fabs(ElectronEta->at(iele))>1.56) && (fabs(ElectronEta->at(iele))<2.5)){
// 	if (fabs(ElectronDeltaEtaTrkSC->at(iele))<0.007){
// 	  if (fabs(ElectronDeltaPhiTrkSC->at(iele))<0.09){
// 	    if (ElectronHoE->at(iele)<0.05){
// 	      if (ElectronSigmaIEtaIEta->at(iele)<0.03){
// 		if (((ElectronEcalIsoHeep->at(iele) + ElectronHcalIsoD1Heep->at(iele))<2.5) || 
// 		    ((eleEt>50)&&(ElectronEcalIsoHeep->at(iele) + ElectronHcalIsoD1Heep->at(iele))< ((0.03*(eleEt-50))+2.5))){
// 		    if (ElectronTrkIsoHeep->at(iele)<15){
// 		      if (ElectronHcalIsoD2Heep->at(iele)<0.5){
// 		      HEEP = true;
// 		      }
// 		    }
// 		}
// 	      }
// 	    }
// 	  }
// 	}
// 	}

// 	if ( HEEP  && ElectronOverlaps->at(iele)==0 )
// 	  {
// 	    v_idx_ele_HEEP.push_back(iele);
// 	  }

      } // End loop over electrons

    
    //////// Fill SC histos

     vector<int> v_idx_sc_iso;

    for(int isc=0;isc<SuperClusterPt->size();isc++){
      if ( SuperClusterPt->at(isc) < getPreCutValue1("ele_PtCut") ) continue;
      if (SuperClusterHoE->at(isc)<0.05) {
	v_idx_sc_iso.push_back(isc);
      }
    }

    // Jets
    vector<int> v_idx_jet_all;
    vector<int> v_idx_jet_PtCut;
 
    // Loop over jets
    for(int ijet=0; ijet<CaloJetPt->size(); ijet++)
      {

	//no cut on reco jets
	v_idx_jet_all.push_back(ijet);

	//pT pre-cut on reco jets
	if ( CaloJetPt->at(ijet) < getPreCutValue1("jet_PtCut") ) continue;

	if( ( CaloJetOverlaps->at(ijet) & 1 << eleIDType) == 0 )/* NO overlap with electrons */  
	  v_idx_jet_PtCut.push_back(ijet);

      } // End loop over jets


    // Set the evaluation of the cuts to false and clear the variable values and filled status
    resetCuts();
    

    // Set the value of the variableNames listed in the cutFile to their current value
    
    // HLT
    fillVariableWithValue( "HLT", PassTrig ) ;

    //## SC
    fillVariableWithValue( "nIsoSC", v_idx_sc_iso.size() );
    //fillVariableWithValue( "nIsoSC",v_idx_sc_iso_barrel.size() );

    // nJet
    fillVariableWithValue( "nJet_all", v_idx_jet_all.size() ) ;
    fillVariableWithValue( "nJet_PtCut", v_idx_jet_PtCut.size() ) ;
    fillVariableWithValue( "nJet_PtCut_noOvrlpSC", v_idx_jet_PtCut.size() ) ;

    // 1st SC
    if( v_idx_sc_iso.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stSC_ISO", SuperClusterPt->at(v_idx_sc_iso[0]) );
	fillVariableWithValue( "Eta1stSC_ISO", SuperClusterEta->at(v_idx_sc_iso[0]) );
	fillVariableWithValue( "mEta1stSC_ISO", fabs(SuperClusterEta->at(v_idx_sc_iso[0])) );
      }

    // 2nd SC
    if( v_idx_sc_iso.size() >= 2 ) 
      {
	fillVariableWithValue( "Pt2ndSC_ISO", SuperClusterPt->at(v_idx_sc_iso[1]) );
	fillVariableWithValue( "Eta2ndSC_ISO", SuperClusterEta->at(v_idx_sc_iso[1]) );
	fillVariableWithValue( "mEta2ndSC_ISO", fabs(SuperClusterEta->at(v_idx_sc_iso[1])) );
	fillVariableWithValue( "maxMEtaSC_ISO", max( getVariableValue("mEta1stSC_ISO"), getVariableValue("mEta2ndSC_ISO") ) );
      }

    // 1st jet
    if( v_idx_jet_PtCut.size() >= 1 ) 
      {
	fillVariableWithValue( "Pt1stJet_noOvrlpSC", CaloJetPt->at(v_idx_jet_PtCut[0]) );
	fillVariableWithValue( "Eta1stJet_noOvrlpSC", CaloJetEta->at(v_idx_jet_PtCut[0]) );
	fillVariableWithValue( "mEta1stJet_noOvrlpSC", fabs(CaloJetEta->at(v_idx_jet_PtCut[0])) );
      }


    //cout << "2nd Jet" << endl;
    //## 2nd jet
    if( v_idx_jet_PtCut.size() >= 2 ) 
      {
	fillVariableWithValue( "Pt2ndJet_noOvrlpSC", CaloJetPt->at(v_idx_jet_PtCut[1]) );
	fillVariableWithValue( "Eta2ndJet_noOvrlpSC", CaloJetEta->at(v_idx_jet_PtCut[1]) );
	fillVariableWithValue( "mEta2ndJet_noOvrlpSC", fabs(CaloJetEta->at(v_idx_jet_PtCut[1])) );
	fillVariableWithValue( "maxMEtaJets_noOvrlpSC", max( getVariableValue("mEta1stJet_noOvrlpSC"), getVariableValue("mEta2ndJet_noOvrlpSC") ) );
      }


    // Evaluate cuts (but do not apply them)
    evaluateCuts();

     if (passedCut("nIsoSC")){
       HasSC++;
     }

     // Fill histograms and do analysis based on cut evaluation
     if (v_idx_sc_iso.size()>0 && !passedCut("HLT")){
       NFailHLT++;
       h_eta_failHLT->Fill(SuperClusterEta->at(v_idx_sc_iso[0]));
       h_phi_failHLT->Fill(SuperClusterPhi->at(v_idx_sc_iso[0]));
     }


     if ( v_idx_ele_PtCut.size()>1) continue; // require at most one loose ele to reject Zs
     if (PFMET->at(0) > 10) continue; // get rid of Ws
	 for(int isc=0;isc<v_idx_sc_iso.size();isc++)
	   {
	     //Require dR>2.6 between SC and JET
	     TVector3 sc_vec;
	     sc_vec.SetPtEtaPhi(SuperClusterPt->at(v_idx_sc_iso[isc]),
			   SuperClusterEta->at(v_idx_sc_iso[isc]),
			   SuperClusterPhi->at(v_idx_sc_iso[isc]));
	     double dPhi_SC_Jet=0;
	     for (int ijet=0;ijet<v_idx_jet_PtCut.size();ijet++){
	       TVector3 jet_vec;
	       jet_vec.SetPtEtaPhi(CaloJetPt->at(v_idx_jet_PtCut[ijet]),
			    CaloJetEta->at(v_idx_jet_PtCut[ijet]),
			    CaloJetPhi->at(v_idx_jet_PtCut[ijet]));
	       double deltaPhi=fabs(jet_vec.DeltaPhi(sc_vec));
	       if (deltaPhi>dPhi_SC_Jet)dPhi_SC_Jet=deltaPhi;
	     }
	     if (dPhi_SC_Jet<2.6) continue;
	     h_dPhi_JetSC->Fill(dPhi_SC_Jet);	

	     h_goodSCPt->Fill(SuperClusterPt->at(v_idx_sc_iso[isc]));
	     h_goodSCEta->Fill(SuperClusterEta->at(v_idx_sc_iso[isc]));

	     bool Barrel = false;
	     bool Endcap = false;
	     if (fabs(SuperClusterEta->at(v_idx_sc_iso[isc]))<1.45) Barrel = true;
	     if (fabs(SuperClusterEta->at(v_idx_sc_iso[isc]))>1.56 && fabs(SuperClusterEta->at(v_idx_sc_iso[isc]))<2.5) Endcap = true;

	     if (Barrel) h_goodSCPt_Barrel->Fill(SuperClusterPt->at(v_idx_sc_iso[isc]));
	     if (Endcap) h_goodSCPt_Endcap->Fill(SuperClusterPt->at(v_idx_sc_iso[isc]));

	     ///  see if there is a HEEP ele to match this
	     double deltaR_ele_sc = 99;
	     int idx_HEEP = -1;
	     for(int iele=0;iele<v_idx_ele_HEEP.size();iele++){
	       TVector3 ele_vec;
	       ele_vec.SetPtEtaPhi(ElectronPt->at(v_idx_ele_HEEP[iele]),
			   ElectronEta->at(v_idx_ele_HEEP[iele]),
			   ElectronPhi->at(v_idx_ele_HEEP[iele]));
	       double tmp_deltaR = ele_vec.DeltaR(sc_vec);
	       if (tmp_deltaR<deltaR_ele_sc){
		 deltaR_ele_sc = tmp_deltaR;
		 idx_HEEP = iele;
	       }
	     }
	     if (deltaR_ele_sc<0.3){
		h_goodEleSCPt->Fill(ElectronSCPt->at(v_idx_ele_HEEP[idx_HEEP]));
		h_goodEleSCEta->Fill(ElectronSCEta->at(v_idx_ele_HEEP[idx_HEEP]));
		
		bool Barrel = false;
		bool Endcap = false;
		if (fabs(ElectronSCEta->at(v_idx_ele_HEEP[idx_HEEP]))<1.45) Barrel = true;
		if (fabs(ElectronSCEta->at(v_idx_ele_HEEP[idx_HEEP]))>1.56 && fabs(ElectronSCEta->at(v_idx_ele_HEEP[idx_HEEP]))<2.5) Endcap = true;
		
		if (Barrel) h_goodEleSCPt_Barrel->Fill(ElectronSCPt->at(v_idx_ele_HEEP[idx_HEEP]));
		if (Endcap) h_goodEleSCPt_Endcap->Fill(ElectronSCPt->at(v_idx_ele_HEEP[idx_HEEP]));
		}
	   } // for sc


    ////////////////////// User's code to be done for every event - END ///////////////////////
    
  } // End of loop over events
  

  ////////////////////// User's code to write histos - BEGIN ///////////////////////

   h_TrigDiff->Write();
   h2_DebugTrig->Write();

   h_dPhi_JetSC->Write();
   h_dR_JetSC->Write();
   h_NisoSC->Write();
   h_goodEleSCPt->Write();
   h_goodEleSCEta->Write();
   h_goodEleSCPt_Barrel->Write();
   h_goodEleSCPt_Endcap->Write();
   h_goodSCPt->Write();
   h_goodSCEta->Write();
   h_goodSCPt_Barrel->Write();
   h_goodSCPt_Endcap->Write();

   h_eta_failHLT->Write();
   h_phi_failHLT->Write();

   FailRate = 100 * NFailHLT/HasSC;
   //cout << "NFail: " << NFailHLT << "\t" << "FailRate: " << FailRate << " %" << endl;
  
  //STDOUT("analysisClass::Loop() ends");   
}