예제 #1
0
// Pass 2 of multiplyByMInv.
// Base to tip: temp allA_GB does not need to be initialized before
// beginning the iteration.
template<int dof, bool noR_FM, bool noX_MB, bool noR_PF> void 
RigidBodyNodeSpec<dof, noR_FM, noX_MB, noR_PF>::multiplyByMInvPass2Outward(
    const SBInstanceCache&                  ic,
    const SBTreePositionCache&              pc,
    const SBArticulatedBodyInertiaCache&    abc,
    const Real*                             allEpsilon,
    SpatialVec*                             allA_GB,
    Real*                                   allUDot) const
{
    const Vec<dof>& eps  = fromU(allEpsilon);
    SpatialVec&     A_GB = allA_GB[nodeNum];
    Vec<dof>&       udot = toU(allUDot); // pull out this node's udot

    const bool isPrescribed = isUDotKnown(ic);
    const HType&        H   = getH(pc);
    const PhiMatrix&    phi = getPhi(pc);
    const Mat<dof,dof>& DI  = getDI(abc);
    const HType&        G   = getG(abc);

    // Shift parent's acceleration outward (Ground==0). 12 flops
    const SpatialVec& A_GP  = allA_GB[parent->getNodeNum()]; 
    const SpatialVec  APlus = ~phi * A_GP;

    // For a prescribed mobilizer, set udot==0.
    if (isPrescribed) {
        udot = 0;
        A_GB = APlus;
    } else {
        udot = DI*eps - ~G*APlus;   // 2dof^2 + 11 dof flops
        A_GB = APlus + H*udot;      // 12 dof flops
    }
}
예제 #2
0
float getLFraction(const int nEvtSim, const float planeL)
{
  float nEvtPass = 0;

  std::cout << planeL << std::endl;

  const int fracSize = 10000;
  const float dimPlane = 10.0;
  const float rHemi = dimPlane/2.0*TMath::Sqrt(2.0);

  for(int genIter = 0; genIter < nEvtSim; genIter++){
    float phiHemi = getPhi(fracSize);
    float thetaHemi = getTheta(fracSize);
    float planeX1 = getPlanePos(fracSize, dimPlane);
    float planeY1 = getPlanePos(fracSize, dimPlane);

    float hemiX = rHemi*cos(thetaHemi)*cos(phiHemi);
    float hemiY = rHemi*cos(thetaHemi)*sin(phiHemi);
    float delL = rHemi*sin(thetaHemi);

    float delX = hemiX - planeX1;
    float delY = hemiY - planeY1;
    float delR = TMath::Sqrt(delX*delX + delY*delY);
    float trajPhi = TMath::ATan2(delY, delX);

    float rExit = getRExit(trajPhi, dimPlane, planeX1, planeY1);

    if((delL/delR)*rExit >= planeL) nEvtPass++;
  }

  return nEvtPass/((float)nEvtSim);
}
예제 #3
0
/**
 * Get the theta and phi angles for the given ID. If the detector was part of a
 * group,
 * as defined in the ExperimentInfo object, then the theta/phi are for the whole
 * set.
 * @param detID A reference to a single ID
 * @param exptInfo A reference to the ExperimentInfo that defines that
 * spectrum->detector mapping
 * @param theta [Output] Set to the theta angle for the detector (set)
 * @param phi [Output] Set to the phi angle for the detector (set)
 * @return A poiner to the Detector object for this spectrum as a whole
 *         (may be a single pixel or group)
 */
Geometry::IDetector_const_sptr
MDNormDirectSC::getThetaPhi(const detid_t detID, const ExperimentInfo &exptInfo,
                            double &theta, double &phi) {
  const auto spectrum = exptInfo.getDetectorByID(detID);
  theta = spectrum->getTwoTheta(m_samplePos, m_beamDir);
  phi = spectrum->getPhi();
  return spectrum;
}
예제 #4
0
EulerAngles::EulerAngles(const Dcm &dcm) :
	Vector(3)
{
	setTheta(asinf(-dcm(2, 0)));

	if (fabsf(getTheta() - M_PI_2_F) < 1.0e-3f) {
		setPhi(0.0f);
		setPsi(atan2f(dcm(1, 2) - dcm(0, 1),
			      dcm(0, 2) + dcm(1, 1)) + getPhi());

	} else if (fabsf(getTheta() + M_PI_2_F) < 1.0e-3f) {
		setPhi(0.0f);
		setPsi(atan2f(dcm(1, 2) - dcm(0, 1),
			      dcm(0, 2) + dcm(1, 1)) - getPhi());

	} else {
		setPhi(atan2f(dcm(2, 1), dcm(2, 2)));
		setPsi(atan2f(dcm(1, 0), dcm(0, 0)));
	}
}
예제 #5
0
    void realizeYOutward(
        const SBInstanceCache&,
        const SBTreePositionCache&              pc,
        const SBArticulatedBodyInertiaCache&    abc,
        SBDynamicsCache&                        dc) const
    {
        // This psi actually has the wrong sign, but it doesn't matter since we multiply
        // by it twice.

        SpatialMat psi = getPhi(pc).toSpatialMat();
        updY(dc) = ~psi * parent->getY(dc) * psi;
    }
예제 #6
0
파일: EAM.cpp 프로젝트: Patrick-Louden/2.2
  void EAM::addType(AtomType* atomType){

    EAMAdapter ea = EAMAdapter(atomType);
    EAMAtomData eamAtomData;

    eamAtomData.rho = ea.getRho();
    eamAtomData.F = ea.getF();
    eamAtomData.Z = ea.getZ();
    eamAtomData.rcut = ea.getRcut();
      
    // add it to the map:
    int atid = atomType->getIdent();
    int eamtid = EAMtypes.size();

    pair<set<int>::iterator,bool> ret;    
    ret = EAMtypes.insert( atid );
    if (ret.second == false) {
      sprintf( painCave.errMsg,
               "EAM already had a previous entry with ident %d\n",
               atid);
      painCave.severity = OPENMD_INFO;
      painCave.isFatal = 0;
      simError();         
    }


    EAMtids[atid] = eamtid;
    EAMdata[eamtid] = eamAtomData;
    MixingMap[eamtid].resize(nEAM_);
    
    // Now, iterate over all known types and add to the mixing map:
    
    std::set<int>::iterator it;
    for( it = EAMtypes.begin(); it != EAMtypes.end(); ++it) {
      
      int eamtid2 = EAMtids[ (*it) ];
      AtomType* atype2 = forceField_->getAtomType( (*it) );

      EAMInteractionData mixer;
      mixer.phi = getPhi(atomType, atype2);
      mixer.rcut = mixer.phi->getLimits().second;
      mixer.explicitlySet = false;

      MixingMap[eamtid2].resize( nEAM_ );
      
      MixingMap[eamtid][eamtid2] = mixer;
      if (eamtid2 != eamtid) {
        MixingMap[eamtid2][eamtid] = mixer;
      }
    }      
    return;
  }
예제 #7
0
    // Must set A_GB properly for propagation to children.
    void multiplyByMInvPass2Outward(
        const SBInstanceCache&,
        const SBTreePositionCache&  pc,
        const SBArticulatedBodyInertiaCache&,
        const Real*                 allEpsilon,
        SpatialVec*                 allA_GB,
        Real*                       allUDot) const override
    {
        SpatialVec&      A_GB = allA_GB[nodeNum];
        const PhiMatrix& phi  = getPhi(pc);

        // Shift parent's acceleration outward (Ground==0). 12 flops
        const SpatialVec& A_GP  = allA_GB[parent->getNodeNum()];
        const SpatialVec  APlus = ~phi * A_GP;

        A_GB = APlus;
    }
void AdaptiveSO2CPGSynPlas::updateWeights() {
    const double& phi     = getPhi();
    const double& beta    = getBeta();
    const double& gamma   = getGamma();
    const double& epsilon = getEpsilon();
    const double& mu      = getMu();
    const double& F       = getOutput(2);
    const double& w01     = getWeight(0,1);
    const double& x       = getOutput(0);
    const double& y       = getOutput(1);
    const double& P       = getPerturbation();

    // general approach
    setPhi    ( phi     + mu * gamma * F * w01 * y );
    setBeta   ( beta    + betaHebbRate    * x * F - betaDecayRate    * (beta    - betaZero) );
    setGamma  ( gamma   + gammaHebbRate   * x * F - gammaDecayRate   * (gamma   - gammaZero) );
    setEpsilon( epsilon + epsilonHebbRate * F * P - epsilonDecayRate * (epsilon - epsilonZero) );

}
예제 #9
0
//
// Calculate acceleration in internal coordinates, based on the last set
// of forces that were reduced into epsilon (e.g., see above).
// Base to tip: temp allA_GB does not need to be initialized before
// beginning the iteration.
//
template<int dof, bool noR_FM, bool noX_MB, bool noR_PF> void 
RigidBodyNodeSpec<dof, noR_FM, noX_MB, noR_PF>::calcUDotPass2Outward(
    const SBInstanceCache&                  ic,
    const SBTreePositionCache&              pc,
    const SBArticulatedBodyInertiaCache&    abc,
    const SBTreeVelocityCache&              vc,
    const SBDynamicsCache&                  dc,
    const Real*                             allEpsilon,
    SpatialVec*                             allA_GB,
    Real*                                   allUDot,
    Real*                                   allTau) const
{
    const Vec<dof>& eps  = fromU(allEpsilon);
    SpatialVec&     A_GB = allA_GB[nodeNum];
    Vec<dof>&       udot = toU(allUDot);    // pull out this node's udot

    const bool isPrescribed = isUDotKnown(ic);
    const HType&              H   = getH(pc);
    const PhiMatrix&          phi = getPhi(pc);
    const ArticulatedInertia& P   = getP(abc);
    const SpatialVec&         a   = getMobilizerCoriolisAcceleration(vc);
    const Mat<dof,dof>&       DI  = getDI(abc);
    const HType&              G   = getG(abc);

    // Shift parent's acceleration outward (Ground==0). 12 flops
    const SpatialVec& A_GP  = allA_GB[parent->getNodeNum()]; 
    const SpatialVec  APlus = ~phi * A_GP;

    if (isPrescribed) {
        Vec<dof>& tau = updTau(ic,allTau);  // pull out this node's tau
        // This is f - ~H(P*APlus + z); compare Jain 16.17b. Note sign
        // change since our tau is on the LHS while his is on the RHS.
        tau = eps - ~H*(P*APlus); // 66 + 12*dof flops
    } else {
        udot = DI*eps - ~G*APlus; // 2*dof^2 + 11*dof
    }

    A_GB = APlus + H*udot + a;
}
예제 #10
0
    void calcUDotPass2Outward(
        const SBInstanceCache&,
        const SBTreePositionCache&  pc,
        const SBArticulatedBodyInertiaCache&,
        const SBTreeVelocityCache&  vc,
        const SBDynamicsCache&      dc,
        const Real*                 allEpsilon,
        SpatialVec*                 allA_GB,
        Real*                       allUDot,
        Real*                       allTau) const
    {
        SpatialVec& A_GB = allA_GB[nodeNum];

        const PhiMatrix&    phi = getPhi(pc);
        const SpatialVec&   a   = getMobilizerCoriolisAcceleration(vc);

        // Shift parent's acceleration outward (Ground==0). 12 flops
        const SpatialVec& A_GP  = allA_GB[parent->getNodeNum()];
        const SpatialVec  APlus = ~phi * A_GP;

        A_GB = APlus + a;  // no udot for weld
    }
예제 #11
0
//==============================================================================
//                                  REALIZE Y
//==============================================================================
// To be called base to tip.
// This is calculating what Abhi Jain calls the operational space compliance
// kernel in his 2011 book. This is the inverse of the operational space inertia
// for each body at its body frame. Also, see Equation 20 in Rodriguez,Jain, 
// & Kreutz-Delgado:  A spatial operator algebra 
// for manipulator modeling and control. Intl. J. Robotics Research 
// 10(4):371-381 (1991).
template<int dof, bool noR_FM, bool noX_MB, bool noR_PF> void
RigidBodyNodeSpec<dof, noR_FM, noX_MB, noR_PF>::realizeYOutward
   (const SBInstanceCache&                  ic,
    const SBTreePositionCache&              pc,
    const SBArticulatedBodyInertiaCache&    abc,
    SBDynamicsCache&                        dc) const
{
    if (isUDotKnown(ic)) {
        //TODO: (sherm 090810) is this right?
        assert(false);
        //updY(dc) = (~getPhi(pc) * parent->getY(dc)) * getPhi(pc); // rigid shift
        return;
    }

    // Compute psi. Jain has TauBar=I-G*~H but we're negating that to G*~H-I 
    // because we can save 30 flops by just subtracting 1 from the diagonals 
    // rather than having to negate all the off-diagonals. Then Psi ends up 
    // with the wrong sign here also, which doesn't matter because we multiply 
    // by it twice.

    SpatialMat tauBar = getG(abc)*~getH(pc);// 11*dof^2 flops
    tauBar(0,0) -= 1; // subtract identity matrix (only touches diags: 3 flops)
    tauBar(1,1) -= 1; //    "    (3 flops)
    SpatialMat psi = getPhi(pc)*tauBar; // ~100 flops

    // TODO: this is very expensive (~1000 flops?) Could cut be at least half
    // by exploiting symmetry. Also, does Psi have special structure?
    // And does this need to be computed for every body or only those
    // which are loop "base" bodies or some such?


    // Psi here has the opposite sign from Jain's, but we're multiplying twice
    // by it here so it doesn't matter.
    updY(dc) = (getH(pc) * getDI(abc) * ~getH(pc)) 
                + (~psi * parent->getY(dc) * psi);
}
Bool_t DSelector_checkKFit::Process(Long64_t locEntry)
{
	// The Process() function is called for each entry in the tree. The entry argument
	// specifies which entry in the currently loaded tree is to be processed.
	//
	// This function should contain the "body" of the analysis. It can contain
	// simple or elaborate selection criteria, run algorithms on the data
	// of the event and typically fill histograms.
	//
	// The processing can be stopped by calling Abort().
	// Use fStatus to set the return value of TTree::Process().
	// The return value is currently not used.

	//CALL THIS FIRST
	DSelector::Process(locEntry); //Gets the data from the tree for the entry
	//cout << "RUN " << Get_RunNumber() << ", EVENT " << Get_EventNumber() << endl;
	//TLorentzVector locProductionX4 = Get_X4_Production();

	/******************************************** GET POLARIZATION ORIENTATION ******************************************/

	//Only if the run number changes
	//RCDB environment must be setup in order for this to work! (Will return false otherwise)
	UInt_t locRunNumber = Get_RunNumber();
	if(locRunNumber != dPreviousRunNumber)
	{
		dIsPolarizedFlag = dAnalysisUtilities.Get_IsPolarizedBeam(locRunNumber, dIsPARAFlag);
		dPreviousRunNumber = locRunNumber;
	}

	/********************************************* SETUP UNIQUENESS TRACKING ********************************************/

	//ANALYSIS ACTIONS: Reset uniqueness tracking for each action
	//For any actions that you are executing manually, be sure to call Reset_NewEvent() on them here
	Reset_Actions_NewEvent();

	//PREVENT-DOUBLE COUNTING WHEN HISTOGRAMMING
		//Sometimes, some content is the exact same between one combo and the next
			//e.g. maybe two combos have different beam particles, but the same data for the final-state
		//When histogramming, you don't want to double-count when this happens: artificially inflates your signal (or background)
		//So, for each quantity you histogram, keep track of what particles you used (for a given combo)
		//Then for each combo, just compare to what you used before, and make sure it's unique

	//EXAMPLE 1: Particle-specific info:
	set<Int_t> locUsedSoFar_BeamEnergy; //Int_t: Unique ID for beam particles. set: easy to use, fast to search

	//EXAMPLE 2: Combo-specific info:
		//In general: Could have multiple particles with the same PID: Use a set of Int_t's
		//In general: Multiple PIDs, so multiple sets: Contain within a map
		//Multiple combos: Contain maps within a set (easier, faster to search)
	set<map<Particle_t, set<Int_t> > > locUsedSoFar_Topology;
	bool usedTopology = false;

	//INSERT USER ANALYSIS UNIQUENESS TRACKING HERE

	/**************************************** EXAMPLE: FILL CUSTOM OUTPUT BRANCHES **************************************/
    
	/*
	Int_t locMyInt = 7;
	dTreeInterface->Fill_Fundamental<Int_t>("my_int", locMyInt);

	TLorentzVector locMyP4(4.0, 3.0, 2.0, 1.0);
	dTreeInterface->Fill_TObject<TLorentzVector>("my_p4", locMyP4);

	for(int loc_i = 0; loc_i < locMyInt; ++loc_i)
		dTreeInterface->Fill_Fundamental<Int_t>("my_int_array", 3*loc_i, loc_i); //2nd argument = value, 3rd = array index
	*/

	/************************************************* LOOP OVER COMBOS *************************************************/

	//Loop over combos
	for(UInt_t loc_i = 0; loc_i < Get_NumCombos(); ++loc_i)
	{
		//Set branch array indices for combo and all combo particles
		dComboWrapper->Set_ComboIndex(loc_i);
		
		// Is used to indicate when combos have been cut
		if(dComboWrapper->Get_IsComboCut()) // Is false when tree originally created
			continue; // Combo has been cut previously

		/********************************************** GET PARTICLE INDICES *********************************************/

		//Used for tracking uniqueness when filling histograms, and for determining unused particles

		//Step 0
		Int_t locBeamID = dComboBeamWrapper->Get_BeamID();
		Int_t locPiPlusTrackID = dPiPlusWrapper->Get_TrackID();
		Int_t locPiMinusTrackID = dPiMinusWrapper->Get_TrackID();
		Int_t locProtonTrackID = dProtonWrapper->Get_TrackID();

		/*********************************************** GET FOUR-MOMENTUM **********************************************/

		// Get P4's: //is kinfit if kinfit performed, else is measured
		//dTargetP4 is target p4
		//Step 0
		TLorentzVector locBeamP4 = dComboBeamWrapper->Get_P4();
		TLorentzVector locPiPlusP4 = dPiPlusWrapper->Get_P4();
		TLorentzVector locPiMinusP4 = dPiMinusWrapper->Get_P4();
		TLorentzVector locProtonP4 = dProtonWrapper->Get_P4();

		// Get Measured P4's:
		//Step 0
		TLorentzVector locBeamP4_Measured = dComboBeamWrapper->Get_P4_Measured();
		TLorentzVector locPiPlusP4_Measured = dPiPlusWrapper->Get_P4_Measured();
		TLorentzVector locPiMinusP4_Measured = dPiMinusWrapper->Get_P4_Measured();
		TLorentzVector locProtonP4_Measured = dProtonWrapper->Get_P4_Measured();
		
		//chi2PiPlus = dPiPlusWrapper->Get_Beta_Timing_Measured();
		//chi2Prot = dProtonWrapper->Get_Beta_Timing_Measured();
		
		inVector = locBeamP4_Measured + dTargetP4;
		outVector = locPiPlusP4_Measured + locPiMinusP4_Measured + locProtonP4_Measured;
		
		missingP = (inVector - outVector).P();
		missingE = (inVector - outVector).E();
		mimass_all = (inVector - outVector).M2();
		
		mimassVec = inVector - locProtonP4_Measured;
		imassVec = locPiPlusP4_Measured + locPiMinusP4_Measured;
		
		mimassPipPimVec = inVector - locPiPlusP4_Measured - locPiMinusP4_Measured;
	    mimassPipPim = mimassPipPimVec.M2();
		mimassPipPVec = inVector - locPiPlusP4_Measured - locProtonP4_Measured;
		mimassPipP = mimassPipPVec.M2();
		mimassPimPVec = inVector - locPiMinusP4_Measured - locProtonP4_Measured;
		mimassPimP = mimassPimPVec.M2();
		
		mimass = mimassVec.M();
		imass = imassVec.M();
		
		kfitProb = TMath::Prob(dComboWrapper->Get_ChiSq_KinFit(),dComboWrapper->Get_NDF_KinFit());
		
		pullCollection[0][0] = dComboWrapper->Get_Fundamental<Double_t>("PiPlus__Px_Pull");
		pullCollection[0][1] = dComboWrapper->Get_Fundamental<Double_t>("PiPlus__Py_Pull");
		pullCollection[0][2] = dComboWrapper->Get_Fundamental<Double_t>("PiPlus__Pz_Pull");
		pullCollection[0][3] = dComboWrapper->Get_Fundamental<Double_t>("PiPlus__Vx_Pull");
		pullCollection[0][4] = dComboWrapper->Get_Fundamental<Double_t>("PiPlus__Vy_Pull");
		pullCollection[0][5] = dComboWrapper->Get_Fundamental<Double_t>("PiPlus__Vz_Pull");
		
		pullCollection[1][0] = dComboWrapper->Get_Fundamental<Double_t>("PiMinus__Px_Pull");
		pullCollection[1][1] = dComboWrapper->Get_Fundamental<Double_t>("PiMinus__Py_Pull");
		pullCollection[1][2] = dComboWrapper->Get_Fundamental<Double_t>("PiMinus__Pz_Pull");
		pullCollection[1][3] = dComboWrapper->Get_Fundamental<Double_t>("PiMinus__Vx_Pull");
		pullCollection[1][4] = dComboWrapper->Get_Fundamental<Double_t>("PiMinus__Vy_Pull");
		pullCollection[1][5] = dComboWrapper->Get_Fundamental<Double_t>("PiMinus__Vz_Pull");
		
		pullCollection[2][0] = dComboWrapper->Get_Fundamental<Double_t>("Proton__Px_Pull");
		pullCollection[2][1] = dComboWrapper->Get_Fundamental<Double_t>("Proton__Py_Pull");
		pullCollection[2][2] = dComboWrapper->Get_Fundamental<Double_t>("Proton__Pz_Pull");
		pullCollection[2][3] = dComboWrapper->Get_Fundamental<Double_t>("Proton__Vx_Pull");
		pullCollection[2][4] = dComboWrapper->Get_Fundamental<Double_t>("Proton__Vy_Pull");
		pullCollection[2][5] = dComboWrapper->Get_Fundamental<Double_t>("Proton__Vz_Pull");
		
		//setPullElements(0,0,pullCollection[0][0]);

		/********************************************* COMBINE FOUR-MOMENTUM ********************************************/

		// DO YOUR STUFF HERE

		// Combine 4-vectors
		TLorentzVector locMissingP4_Measured = locBeamP4_Measured + dTargetP4;
		locMissingP4_Measured -= locPiPlusP4_Measured + locPiMinusP4_Measured + locProtonP4_Measured;

		/******************************************** EXECUTE ANALYSIS ACTIONS *******************************************/

		// Loop through the analysis actions, executing them in order for the active particle combo
		if(!Execute_Actions()) //if the active combo fails a cut, IsComboCutFlag automatically set
			continue;

		//if you manually execute any actions, and it fails a cut, be sure to call:
			//dComboWrapper->Set_IsComboCut(true);

		/**************************************** EXAMPLE: FILL CUSTOM OUTPUT BRANCHES **************************************/

		/*
		TLorentzVector locMyComboP4(8.0, 7.0, 6.0, 5.0);
		//for arrays below: 2nd argument is value, 3rd is array index
		//NOTE: By filling here, AFTER the cuts above, some indices won't be updated (and will be whatever they were from the last event)
			//So, when you draw the branch, be sure to cut on "IsComboCut" to avoid these.
		dTreeInterface->Fill_Fundamental<Float_t>("my_combo_array", -2*loc_i, loc_i);
		dTreeInterface->Fill_TObject<TLorentzVector>("my_p4_array", locMyComboP4, loc_i);
		*/

		/**************************************** EXAMPLE: HISTOGRAM BEAM ENERGY *****************************************/

		//Histogram beam energy (if haven't already)
		if(locUsedSoFar_BeamEnergy.find(locBeamID) == locUsedSoFar_BeamEnergy.end())
		{
			locUsedSoFar_BeamEnergy.insert(locBeamID);
		}

		/************************************ EXAMPLE: HISTOGRAM MISSING MASS SQUARED ************************************/

		//Missing Mass Squared
		double locMissingMassSquared = locMissingP4_Measured.M2();

		//Uniqueness tracking: Build the map of particles used for the missing mass
			//For beam: Don't want to group with final-state photons. Instead use "Unknown" PID (not ideal, but it's easy).
		map<Particle_t, set<Int_t> > locUsedThisCombo_Topology;
		locUsedThisCombo_Topology[Unknown].insert(locBeamID); //beam
		locUsedThisCombo_Topology[PiPlus].insert(locPiPlusTrackID);
		locUsedThisCombo_Topology[PiMinus].insert(locPiMinusTrackID);
		locUsedThisCombo_Topology[Proton].insert(locProtonTrackID);
		
		if(locUsedSoFar_Topology.find(locUsedThisCombo_Topology) == locUsedSoFar_Topology.end())
		{
			//unique missing mass combo: histogram it, and register this combo of particles
			//dHist_MissingMassSquared->Fill(locMissingMassSquared);
			
			locUsedSoFar_Topology.insert(locUsedThisCombo_Topology);
			usedTopology = true;
		}else usedTopology = false;
		
        if(usedTopology){
		    missingP_vs_missingE->Fill(missingE,missingP);
		    EM_balance->Fill(missingP-TMath::Abs(missingE));
		    MMALL->Fill(mimass_all);
            MM_vs_IM->Fill(imass,mimass);
            probDist->Fill(kfitProb);
            
            //-----------------------------------------------------------------------------
            if(isInsideDM(missingP-TMath::Abs(missingE),0.0016,0.0106,2)){ //1st cut to reconstruct: gp->pi+pi- p: missing energy and  missing momentum
				probDistCut->Fill(kfitProb);
				missingP_vs_missingE_Cut->Fill(missingE,missingP);
				MM_vs_IM_Cut->Fill(imass,mimass);
				EM_balance_Cut->Fill(missingP-TMath::Abs(missingE));
				MMALL_Cut->Fill(mimass_all);
				
				//-----------------------------------------------------------------------------
				if(mimass_all > -0.005 && mimass_all < 0.005){ //2nd cut to reconstruct: gp->pi+pi- p: overall missing mass --> should be 0
					probDistCut2->Fill(kfitProb);
				    missingP_vs_missingE_Cut2->Fill(missingE,missingP);
				    MM_vs_IM_Cut2->Fill(imass,mimass);
				    EM_balance_Cut2->Fill(missingP-TMath::Abs(missingE));
				    MMALL_Cut2->Fill(mimass_all);	
				     
				     
				     //Angular INDEPENDENT investigation of pulls:
				     //------------------------------------------------------------
		             for(Int_t a=0;a<3;a++){
				        for(Int_t b=0;b<6;b++){
					       Pulls_vs_Prob[a][b]->Fill(kfitProb,pullCollection[a][b]); 
				        }
			         }
			         //------------------------------------------------------------ 
				     
				     
				    fillAngularHists(locPiPlusP4_Measured,locPiMinusP4_Measured,locProtonP4_Measured,Theta_vs_phi_PiPlus,Theta_vs_phi_PiMinus,Theta_vs_phi_Prot);
				       
			         //Angular DEPENDENT investigation of pulls:
				    fillPullHistsPiPlus(getTheta(locPiPlusP4,"deg"),getPhi(locPiPlusP4,"deg"),kfitProb);
				    fillPullHistsPiMinus(getTheta(locPiMinusP4,"deg"),getPhi(locPiMinusP4,"deg"),kfitProb);
				    fillPullHistsProt(getTheta(locProtonP4,"deg"),getPhi(locProtonP4,"deg"),kfitProb);
				}
				//-----------------------------------------------------------------------------
			}
            //-----------------------------------------------------------------------------
		}
    


		//E.g. Cut
		//if((locMissingMassSquared < -0.04) || (locMissingMassSquared > 0.04))
		//{
		//	dComboWrapper->Set_IsComboCut(true);
		//	continue;
		//}

		/****************************************** FILL FLAT TREE (IF DESIRED) ******************************************/

		/*
		//FILL ANY CUSTOM BRANCHES FIRST!!
		Int_t locMyInt_Flat = 7;
		dFlatTreeInterface->Fill_Fundamental<Int_t>("flat_my_int", locMyInt_Flat);

		TLorentzVector locMyP4_Flat(4.0, 3.0, 2.0, 1.0);
		dFlatTreeInterface->Fill_TObject<TLorentzVector>("flat_my_p4", locMyP4_Flat);

		for(int loc_j = 0; loc_j < locMyInt_Flat; ++loc_j)
		{
			dFlatTreeInterface->Fill_Fundamental<Int_t>("flat_my_int_array", 3*loc_j, loc_j); //2nd argument = value, 3rd = array index
			TLorentzVector locMyComboP4_Flat(8.0, 7.0, 6.0, 5.0);
			dFlatTreeInterface->Fill_TObject<TLorentzVector>("flat_my_p4_array", locMyComboP4_Flat, loc_j);
		}
		*/

		//FILL FLAT TREE
		//Fill_FlatTree(); //for the active combo
	} // end of combo loop

	//FILL HISTOGRAMS: Num combos / events surviving actions
	Fill_NumCombosSurvivedHists();

	/******************************************* LOOP OVER THROWN DATA (OPTIONAL) ***************************************/
/*
	//Thrown beam: just use directly
	if(dThrownBeam != NULL)
		double locEnergy = dThrownBeam->Get_P4().E();

	//Loop over throwns
	for(UInt_t loc_i = 0; loc_i < Get_NumThrown(); ++loc_i)
	{
		//Set branch array indices corresponding to this particle
		dThrownWrapper->Set_ArrayIndex(loc_i);

		//Do stuff with the wrapper here ...
	}
*/
	/****************************************** LOOP OVER OTHER ARRAYS (OPTIONAL) ***************************************/
/*
	//Loop over beam particles (note, only those appearing in combos are present)
	for(UInt_t loc_i = 0; loc_i < Get_NumBeam(); ++loc_i)
	{
		//Set branch array indices corresponding to this particle
		dBeamWrapper->Set_ArrayIndex(loc_i);

		//Do stuff with the wrapper here ...
	}

	//Loop over charged track hypotheses
	for(UInt_t loc_i = 0; loc_i < Get_NumChargedHypos(); ++loc_i)
	{
		//Set branch array indices corresponding to this particle
		dChargedHypoWrapper->Set_ArrayIndex(loc_i);

		//Do stuff with the wrapper here ...
	}

	//Loop over neutral particle hypotheses
	for(UInt_t loc_i = 0; loc_i < Get_NumNeutralHypos(); ++loc_i)
	{
		//Set branch array indices corresponding to this particle
		dNeutralHypoWrapper->Set_ArrayIndex(loc_i);

		//Do stuff with the wrapper here ...
	}
*/

	/************************************ EXAMPLE: FILL CLONE OF TTREE HERE WITH CUTS APPLIED ************************************/
/*
	Bool_t locIsEventCut = true;
	for(UInt_t loc_i = 0; loc_i < Get_NumCombos(); ++loc_i) {
		//Set branch array indices for combo and all combo particles
		dComboWrapper->Set_ComboIndex(loc_i);
		// Is used to indicate when combos have been cut
		if(dComboWrapper->Get_IsComboCut())
			continue;
		locIsEventCut = false; // At least one combo succeeded
		break;
	}
	if(!locIsEventCut && dOutputTreeFileName != "")
		Fill_OutputTree();
*/

	return kTRUE;
}
예제 #13
0
double scoreOfEllipse(Line *line, CvBox2D ellipse) {
//	printf("%f, %f, %d\n", getEpsilon(line, ellipse), getTau(ellipse), getPhi(line, ellipse));
	double score = pow(getEpsilon(line, ellipse), 2) * exp(abs(1-getTau(ellipse))) / pow(getPhi(line, ellipse), 2);
//	printf("score : %f\n", score);
	return score;
}
예제 #14
0
double MixingResult::calcEpsilon (double x, 
				  double y, 
				  double deltaKpi, 
				  double deltaKpipi, 
				  double phi, 
				  double rsubdm, 
				  double rsubdp,
				  double qoverp) {

  if (special_alex_fit) {
    // In this case, interpret x, y, phi as underlying x_12, y_12, phi_12,
    // and calculate x, y, phi, q/p from them.
    double mixx = getMixX(x, y, phi);
    double mixy = getMixY(x, y, phi); 
    double qovp = getQoverP(x, y, phi);
    double rphi = getPhi(x, y, phi);
    x = mixx;
    y = mixy;
    qoverp = qovp;
    phi = rphi; 
  }
  else {
    double thing = 0; 
    switch (fit_for_which) {
    case MixingResult::PHI_FREE:
      //qoverp = 1 - (y/x)*tan(phi);
      qoverp = sqrt((x-y*tan(phi))/(x+y*tan(phi))); 
      // This is eqn 20 of Grossman/Nir/Perez. It assumes small CPV, ie |sin(phi_12)|<<1.
      // NB! This function's 'phi' is not the same as 'phi_12'! 
      break;
    case QP_FREE:
      if (fabs(x) > fabs(y)*1e12) phi = sign(x)*sign(y)*M_PI_2; 
      // ie, y approaches zero, tan phi approaches infinity, phi is pi/2.
      else phi = atan(((1-qoverp*qoverp)/(1+qoverp*qoverp))*(x/y)); 
      break;
    case DELTAGAMMA_FREE:
      // Formal parameter qoverp is actually delta^gamma; calculate real qoverp from constraint. 
      thing = (y/x)*tan(phi + qoverp);
      qoverp = pow((1+thing)/(1-thing), 0.25); 
      break; 
    default:
      break;
    }
  }



  static int primeSign = use_hfag_convention ? 1 : -1; 
  double ret = 0; 
  double prime = 0; 
  double poverq = 1.0 / qoverp;
  double a_m = (qoverp*qoverp - poverq*poverq);
  a_m /= (qoverp*qoverp + poverq*poverq);
  switch (myType) {
  case PLAINX: ret = (x - measurement); break;
  case XSQUARE: ret = (x*x - measurement); break;
  case PLAINY: 
  case YCP:    
    ret  = (qoverp + poverq)*y*cos(phi);
    ret -= (qoverp - poverq)*x*sin(phi);
    ret *= 0.5;
    ret -= measurement; 
    break;
  case AGAMMA:
    ret  = (qoverp - poverq)*y*cos(phi);
    ret -= (qoverp + poverq)*x*sin(phi);
    ret *= 0.5;
    ret -= measurement; 
    break;
  case XPRIME: 
    switch (myPrime) {
    case KPI:    prime = pow(x*cos(deltaKpi)   + primeSign*y*sin(deltaKpi), 2); break; // NB squaring - Kpi result is assumed x'^2. 
    case KPIPI0: prime =     x*cos(deltaKpipi) + primeSign*y*sin(deltaKpipi); break;
    default:
    case NOPRIME:
      std::cout << "Error: Measurement " << name << " is not a primed quantity." << std::endl; 
      assert(false); 
      break;
    }
    ret = prime - measurement; 
    break;
  case XPRIME_P:
    switch (myPrime) {
    case KPI:    
      prime  = (x*cos(deltaKpi)   + primeSign*y*sin(deltaKpi)) * cos(phi); 
      prime += (y*cos(deltaKpi)   - primeSign*x*sin(deltaKpi)) * sin(phi); 
      prime *= pow((1+a_m)/(1-a_m), 0.25);
      prime *= prime;
      break;
    case KPIPI0: 
    default:
    case NOPRIME:
      std::cout << "Error: Measurement " << name << " is not a primed quantity." << std::endl; 
      assert(false); 
      break;
    }
    ret = prime - measurement; 
    break;
  case XPRIME_M:
    switch (myPrime) {
    case KPI:    
      prime  = (x*cos(deltaKpi)   + primeSign*y*sin(deltaKpi)) * cos(phi); 
      prime -= (y*cos(deltaKpi)   - primeSign*x*sin(deltaKpi)) * sin(phi); 
      prime *= pow((1-a_m)/(1+a_m), 0.25);
      prime *= prime;
      break;
    case KPIPI0: 
    default:
    case NOPRIME:
      std::cout << "Error: Measurement " << name << " is not a primed quantity." << std::endl; 
      assert(false); 
      break;
    }
    ret = prime - measurement; 
    break;


  case YPRIME:
    switch (myPrime) { 
    case KPI:    prime = y*cos(deltaKpi)   - primeSign*x*sin(deltaKpi); break;
    case KPIPI0: prime = y*cos(deltaKpipi) - primeSign*x*sin(deltaKpipi); break;
    default:
    case NOPRIME:
      std::cout << "Error: Measurement " << name << " is not a primed quantity." << std::endl; 
      assert(false); 
      break;
    }
    ret = prime - measurement; 
    break;
  case YPRIME_P:
    switch (myPrime) {
    case KPI:    
      prime  = (y*cos(deltaKpi)   - primeSign*x*sin(deltaKpi)) * cos(phi); 
      prime -= (x*cos(deltaKpi)   + primeSign*y*sin(deltaKpi)) * sin(phi); 
      prime *= pow((1+a_m)/(1-a_m), 0.25);
      break;
    case KPIPI0: 
    default:
    case NOPRIME:
      std::cout << "Error: Measurement " << name << " is not a primed quantity." << std::endl; 
      assert(false); 
      break;
    }
    ret = prime - measurement; 
    break;
  case YPRIME_M:
    switch (myPrime) {
    case KPI:    
      prime  = (y*cos(deltaKpi)   - primeSign*x*sin(deltaKpi)) * cos(phi); 
      prime += (x*cos(deltaKpi)   + primeSign*y*sin(deltaKpi)) * sin(phi); 
      prime *= pow((1-a_m)/(1+a_m), 0.25);
      break;
    case KPIPI0: 
    default:
    case NOPRIME:
      std::cout << "Error: Measurement " << name << " is not a primed quantity." << std::endl; 
      assert(false); 
      break;
    }
    ret = prime - measurement; 
    break;
  case COSANGLE:
    switch (myPrime) {
    case KPI:    ret = cos(deltaKpi) - measurement; break;
    case KPIPI0: ret = cos(deltaKpipi) - measurement; break;
    default:
      std::cout << "Error: Measurement " << name << " is not a primed quantity." << std::endl;
      assert(false);
      break;
    }
    break;
  case SINANGLE:
    switch (myPrime) {
    case KPI:    ret = sin(deltaKpi) - measurement; break;
    case KPIPI0: ret = sin(deltaKpipi) - measurement; break;
    default:
      std::cout << "Error: Measurement " << name << " is not a primed quantity." << std::endl;
      assert(false);
      break;
    }
    break;
    
  case ANGLE:
    switch (myPrime) {
    case KPI:    ret = deltaKpi - measurement; break;
    case KPIPI0: ret = deltaKpipi - measurement; break; 
    default:
    case NOPRIME:
      std::cout << "Error: Measurement " << name << " is not a primed quantity." << std::endl;
      assert(false);
      break;
    }
    break;

  case NODCPV:
    switch (myPrime) {
      // Eqns 14, 15, 48, 52 in Kagan/Sokoloff Phys Rev D80, 0.6008 (2009)
      // Mixing x in terms of underlying x12, y12, phi12
      // NB 14 and 15 corrected by factor 1/sqrt(2) - email from Alex
      // Note that *formal parameters* x, y are now *variables* x12, y12 - confusing! 
    case KPI: // Mixing x
      ret = getMixX(x, y, phi) - measurement;
      break; 
    case KPIPI0: // y
      ret = getMixY(x, y, phi) - measurement;
      break;
    case QOVERP: // q over p
      ret = getQoverP(x, y, phi) - measurement; 
      break;
    case NOPRIME: // phi
      ret = getPhi(x, y, phi) - measurement; 
      break;
    default:
      std::cout << "Result " << getName() << " has bad prime type; check the input.\n";
      assert(false);
      break;
    }
    break; 

  case RD:  ret = (ALL_CPV == allowcpv ? 0.5*(rsubdm+rsubdp): rsubdm) - measurement; break;
  case RDM: ret = rsubdm - measurement; break;
  case RDP: ret = rsubdp - measurement; break;
  case QP:  ret = qoverp - measurement; break;
  case PHI: ret = phi  - measurement; break;

  case NUMTYPES: 
  default: 
    std::cout << "Error: Unknown result type." << std::endl; 
    assert(false); 
    break;
  }

  if (active) {
    assert(index < (int) epsilon.size()); 
    epsilon[index] = ret;
  }
  return ret; 
}
//w=PI/2
Mat corrector::latitudeCorrection3(Mat imgOrg, Point2i center, int radius, distMapMode distMap, double theta_left, double phi_up, double camerFieldAngle, camMode camProjMode)
{
	if (!(camerFieldAngle > 0 && camerFieldAngle <= PI))
	{
		cout << "The parameter \"camerFieldAngle\" must be in the interval (0,PI]." << endl;
		return Mat();
	}
	double rateOfWindow = 0.9;

	//int width = imgOrg.size().width*rateOfWindow;
	//int height = width;

	int width = max(imgOrg.cols, imgOrg.rows);
	int height = width;
	//int height = imgOrg.rows;


	Size imgSize(width, height);
	int center_x = imgSize.width / 2;
	int center_y = imgSize.height / 2;

	Mat retImg(imgSize, CV_8UC3, Scalar(0, 0, 0));

	double dx = camerFieldAngle / imgSize.width;
	double dy = camerFieldAngle / imgSize.height;

	//coordinate for latitude map
	double latitude;
	double longitude;

	//unity sphere coordinate 
	double x, y, z, r;

	//parameter cooradinate of sphere coordinate
	double Theta_sphere;
	double Phi_sphere;

	//polar cooradinate for fish-eye Image
	double p;
	double theta;

	//cartesian coordinate 
	double x_cart, y_cart;

	//Image cooradinate of imgOrg
	double u, v;
	Point pt, pt1, pt2, pt3, pt4;

	//Image cooradinate of imgRet
	int u_latitude, v_latitude;
	Rect imgArea(0, 0, imgOrg.cols, imgOrg.rows);

	//offset of imgRet Origin
	double longitude_offset, latitude_offset;
	longitude_offset = (PI - camerFieldAngle) / 2;
	latitude_offset = (PI - camerFieldAngle) / 2;

	double foval = 0.0;//焦距


	cv::Mat_<Vec3b> _retImg = retImg;
	cv::Mat_<Vec3b> _imgOrg = imgOrg;

	//according to the camera type to do the calibration
	for (int j = 0; j < imgSize.height; j++)
	{

		for (int i = 0; i < imgSize.width; i++)
		{
			Point3f tmpPt(i - center_x, center_y - j, 600);//最后一个参数用来修改成像面的焦距
			double normPt = norm(tmpPt);

			switch (distMap)
			{
			case PERSPECTIVE:

				tmpPt.x /= normPt;
				tmpPt.y /= normPt;
				tmpPt.z /= normPt;

				x = tmpPt.x;
				y = tmpPt.y;
				z = tmpPt.z;

				break;
			case LATITUDE_LONGTITUDE:

				//latitude = latitude_offset + j*dy;

				latitude = getPhi((double)j*4.0 / imgSize.height);

				longitude = getPhi((double)i * 4 / imgSize.width);

				//latitude = latitude_offset + j*dy;
				//longitude = longitude_offset + i*dx;
				//Convert from latitude cooradinate to the sphere cooradinate
				x = -sin(latitude)*cos(longitude);
				y = cos(latitude);
				z = sin(latitude)*sin(longitude);

				break;
			default:
				break;
			}

			if (distMap == PERSPECTIVE)
			{
				//double theta = PI/4;
				//double phi = -PI/2;
				cv::Mat curPt(cv::Point3f(x, y, z));
				std::vector<cv::Point3f> pts;

				//向东旋转地球
				//pts.push_back(cv::Point3f(cos(theta), 0, -sin(theta)));
				//pts.push_back(cv::Point3f(0, 1, 0));
				//pts.push_back(cv::Point3f(sin(theta), 0, cos(theta)));

				//向南旋转地球
				//pts.push_back(cv::Point3f(1, 0, 0));
				//pts.push_back(cv::Point3f(0, cos(phi), sin(phi)));
				//pts.push_back(cv::Point3f(0, -sin(phi), cos(phi)));

				//两个方向旋转
				pts.push_back(cv::Point3f(cos(theta_left), 0, sin(theta_left)));
				pts.push_back(cv::Point3f(sin(phi_up)*sin(theta_left), cos(phi_up), -sin(phi_up)*cos(theta_left)));
				pts.push_back(cv::Point3f(-cos(phi_up)*sin(theta_left), sin(phi_up), cos(phi_up)*cos(theta_left)));


				cv::Mat revert = cv::Mat(pts).reshape(1).t();

				cv::Mat changed(revert*curPt);

				cv::Mat_<double> changed_double;
				changed.convertTo(changed_double, CV_64F);

				x = changed_double.at<double>(0, 0);
				y = changed_double.at<double>(1, 0);
				z = changed_double.at<double>(2, 0);

				//std::cout << curPt << std::endl
				//	<<revert<<std::endl;
			}

			//Convert from unit sphere cooradinate to the parameter sphere cooradinate
			Theta_sphere = acos(z);
			Phi_sphere = cvFastArctan(y, x);//return value in Angle
			Phi_sphere = Phi_sphere*PI / 180;//Convert from Angle to Radian


			switch (camProjMode)
			{
			case STEREOGRAPHIC:
				foval = radius / (2 * tan(camerFieldAngle / 4));
				p = 2 * foval*tan(Theta_sphere / 2);
				break;
			case EQUIDISTANCE:
				foval = radius / (camerFieldAngle / 2);
				p = foval*Theta_sphere;
				break;
			case EQUISOLID:
				foval = radius / (2 * sin(camerFieldAngle / 4));
				p = 2 * foval*sin(Theta_sphere / 2);
				break;
			case ORTHOGONAL:
				foval = radius / sin(camerFieldAngle / 2);
				p = foval*sin(Theta_sphere);
				break;
			default:
				cout << "The camera mode hasn't been choose!" << endl;
			}
			//Convert from parameter sphere cooradinate to fish-eye polar cooradinate
			//p = sin(Theta_sphere);
			theta = Phi_sphere;

			//Convert from fish-eye polar cooradinate to cartesian cooradinate
			x_cart = p*cos(theta);
			y_cart = p*sin(theta);

			//double R = radius / sin(camerFieldAngle / 2);

			//Convert from cartesian cooradinate to image cooradinate
			u = x_cart + center.x;
			v = -y_cart + center.y;

			pt = Point(u, v);

			if (!pt.inside(imgArea))
			{
				continue;
			}

			_retImg.at<Vec3b>(j, i) = _imgOrg.at<Vec3b>(pt);

		}
	}

	//imshow("org", _imgOrg);
	//imshow("ret", _retImg);
	//cv::waitKey();
#ifdef _DEBUG_
	cv::namedWindow("Corrected Image", CV_WINDOW_AUTOSIZE);
	imshow("Corrected Image", retImg);
	cv::waitKey();
#endif
	//imwrite("ret.jpg", retImg);
	return retImg;
}
예제 #16
0
/**
 * Clear the vector of strings and then add pairs of strings giving information
 * about the specified point, x, y.  The first string in a pair should
 * generally be a string describing the value being presented and the second
 * string should contain the value.
 *
 * @param x    The x-coordinate of the point of interest in the data.
 * @param y    The y-coordinate of the point of interest in the data.
 * @param list Vector that will be filled out with the information strings.
 */
void MatrixWSDataSource::getInfoList( double x,
                                      double y,
                                      std::vector<std::string> &list )
{
  // First get the info that is always available for any matrix workspace
  list.clear();

  int row = (int)y;
  restrictRow( row );

  const ISpectrum* spec = m_matWs->getSpectrum( row );

  double spec_num = spec->getSpectrumNo();
  SVUtils::PushNameValue( "Spec Num", 8, 0, spec_num, list );

  std::string x_label = "";
  Unit_sptr& old_unit = m_matWs->getAxis(0)->unit();
  if ( old_unit != 0 )
  {
    x_label = old_unit->caption();
    SVUtils::PushNameValue( x_label, 8, 3, x, list );
  }

  std::set<detid_t> ids = spec->getDetectorIDs();
  if ( !ids.empty() )
  {
    list.push_back("Det ID");
    const int64_t id = static_cast<int64_t>(*(ids.begin()));
    list.push_back(boost::lexical_cast<std::string>(id));
  }

  /* Now try to do various unit conversions to get equivalent info */
  /* first make sure we can get the needed information */
  if ( !(m_instrument && m_source && m_sample) )
  {
    return;
  }

  try
  {

    if ( old_unit == 0 )
    {
      g_log.debug("No UNITS on MatrixWorkspace X-axis");
      return;
    }

    auto det = m_matWs->getDetector( row );
    if ( det == 0 )
    {
      g_log.debug() << "No DETECTOR for row " << row << " in MatrixWorkspace" << std::endl;
      return;
    }

    double l1        = m_source->getDistance(*m_sample);
    double l2        = 0.0;
    double two_theta = 0.0;
    double azi       = 0.0;
    if ( det->isMonitor() )
    {
      l2 = det->getDistance(*m_source);
      l2 = l2-l1;
    }
    else
    {
      l2 = det->getDistance(*m_sample);
      two_theta = m_matWs->detectorTwoTheta(det);
      azi = det->getPhi();
    }
    SVUtils::PushNameValue( "L2", 8, 4, l2, list );
    SVUtils::PushNameValue( "TwoTheta", 8, 2, two_theta*180./M_PI, list );
    SVUtils::PushNameValue( "Azimuthal", 8, 2, azi*180./M_PI, list );

    /* For now, only support diffractometers and monitors. */
    /* We need a portable way to determine emode and */
    /* and efixed that will work for any matrix workspace! */
    int    emode  = 0;
    double efixed = 0.0;
    double delta  = 0.0;

    // First try to get emode & efixed from the user
    if ( m_emodeHandler != NULL )
    {
      efixed = m_emodeHandler->getEFixed();
      if ( efixed != 0 )
      {
        emode = m_emodeHandler->getEMode();
        if ( emode == 0 )
        {
          g_log.information("EMode invalid, spectrometer needed if emode != 0");
          g_log.information("Assuming Direct Geometry Spectrometer....");
          emode = 1;
        }
      }
    }

    // Did NOT get emode & efixed from user, try getting direct geometry information from the run object
    if ( efixed == 0 )
    {
      const API::Run & run = m_matWs->run();
      if ( run.hasProperty("Ei") )
      {
        Kernel::Property* prop = run.getProperty("Ei");
        efixed = boost::lexical_cast<double,std::string>(prop->value());
        emode  = 1;                         // only correct if direct geometry
      }
      else if ( run.hasProperty("EnergyRequested") )
      {
        Kernel::Property* prop = run.getProperty("EnergyRequested");
        efixed = boost::lexical_cast<double,std::string>(prop->value());
        emode  = 1;
      }
      else if ( run.hasProperty("EnergyEstimate") )
      {
        Kernel::Property* prop = run.getProperty("EnergyEstimate");
        efixed = boost::lexical_cast<double,std::string>(prop->value());
        emode  = 1;
      }
    }

    // Finally, try getting indirect geometry information from the detector object
    if ( efixed == 0 )
    {
      if ( !(det->isMonitor() && det->hasParameter("Efixed")))
      {
        try
        {
          const ParameterMap& pmap = m_matWs->constInstrumentParameters();
          Parameter_sptr par = pmap.getRecursive(det.get(),"Efixed");
          if (par)
          {
            efixed = par->value<double>();
            emode = 2;
          }
        }
        catch ( std::runtime_error& )
        {
          g_log.debug() << "Failed to get Efixed from detector ID: "
                        << det->getID() << " in MatrixWSDataSource" << std::endl;
          efixed = 0;
        }
      }
    }

    if ( efixed == 0 )
      emode = 0;

    if ( m_emodeHandler != NULL )
    {
      m_emodeHandler -> setEFixed( efixed );
      m_emodeHandler -> setEMode ( emode );
    }

    double tof = old_unit->convertSingleToTOF( x, l1, l2, two_theta,
                                               emode, efixed, delta );
    if ( ! (x_label == "Time-of-flight") )
      SVUtils::PushNameValue( "Time-of-flight", 8, 1, tof, list );

    if ( ! (x_label == "Wavelength") )
    {
      const Unit_sptr& wl_unit = UnitFactory::Instance().create("Wavelength");
      double wavelength = wl_unit->convertSingleFromTOF( tof, l1, l2, two_theta,
                                                         emode, efixed, delta );
      SVUtils::PushNameValue( "Wavelength", 8, 4, wavelength, list );
    }

    if ( ! (x_label == "Energy") )
    {
      const Unit_sptr& e_unit = UnitFactory::Instance().create("Energy");
      double energy = e_unit->convertSingleFromTOF( tof, l1, l2, two_theta,
                                                    emode, efixed, delta );
      SVUtils::PushNameValue( "Energy", 8, 4, energy, list );
    }

    if ( (! (x_label == "d-Spacing")) && (two_theta != 0.0) && ( emode == 0 ) )
    {
      const Unit_sptr& d_unit = UnitFactory::Instance().create("dSpacing");
      double d_spacing = d_unit->convertSingleFromTOF( tof, l1, l2, two_theta,
                                                       emode, efixed, delta );
      SVUtils::PushNameValue( "d-Spacing", 8, 4, d_spacing, list );
    }

    if ( (! (x_label == "q")) && (two_theta != 0.0) )
    {
      const Unit_sptr& q_unit=UnitFactory::Instance().create("MomentumTransfer");
      double mag_q = q_unit->convertSingleFromTOF( tof, l1, l2, two_theta,
                                                   emode, efixed, delta );
      SVUtils::PushNameValue( "|Q|", 8, 4, mag_q, list );
    }

    if ( (! (x_label == "DeltaE")) && (two_theta != 0.0) && ( emode != 0 ) )
    {
      const Unit_sptr& deltaE_unit=UnitFactory::Instance().create("DeltaE");
      double delta_E = deltaE_unit->convertSingleFromTOF( tof, l1, l2, two_theta,
                                                          emode, efixed, delta );
      SVUtils::PushNameValue( "DeltaE", 8, 4, delta_E, list );
    }
  }
  catch (std::exception & e)
  {
    g_log.debug() << "Failed to get information from Workspace:" << e.what() << std::endl;
  }
}