Mattione GlueX Analysis Factories

From GlueXWiki
Revision as of 16:07, 12 August 2012 by Pmatt (Talk | contribs) (Cutting & Histogramming: DAnalysisAction, DAnalysisResults)

Jump to: navigation, search

Summary

  • In his/her plugin, a user specifies the reactions he/she wants to study (DReaction objects), then just asks JANA for the results (DTrackCombo objects).
    • Creates all possible track combinations for the desired reaction; user then cuts on the likelihood that those combinations represent the hypothesized reaction.

DReaction

  • Will be located in src/libraries/ANALYSIS
  • User creates one of these in their plugin for each reaction they want to analyze (example shown later below) (can analyze more than one at once).
class DReaction : public JObject
{
	private:
		//REACTION AND ANALYSIS:
		string dReactionName; //must be unique: e.g. "Y2175"
		deque<const DReactionStep*> dReactionSteps;
		deque<const DAnalysisAction*> dAnalysisActions;

		//CONTROL VARIABLES:
		unsigned short int dFitTypeFlag; //0 is none, 1 is p4 only, 2 is p4 & v, 3 is p4, v, & t
		deque<size_t> dDecayingParticlesExcludedFromKinfit; //to exclude decaying particles from the kinematic fit (resonances are automatically excluded)
};
class DReactionStep
{
	private:
		Particle_t dInitialParticleID; //e.g. lambda, phi, gamma
		Particle_t dTargetParticleID; //Unknown for no target
		deque<Particle_t> dFinalParticleIDs;

		int dMissingParticleIndex; //-1 for no missing particles, else final state particle at this index is missing (0 -> x)
};

DTrackCombo

  • Will be located in src/libraries/ANALYSIS
  • DTrackCombo_factory_PreKinFit: Generates a DTrackCombo object for each possible combination of detected tracks and DBeamPhotons (configurable time cut used to eliminate way-out-of-time photons).
    • PID is NOT assumed, all possibilities are tested: For each q = +/-/0 particle in a given DReaction, all detected q = +/-/0 tracks are tested as to whether or not they are that particle.
  • DKinFitResults_factory: Performs a single kinematic fit testing whether each DTrackCombo matches the DReaction: includes all mass, vertex, timing constraints if requested.
  • DTrackCombo_factory: Create new DTrackCombo objects, using the kinematic fit track information and results.
class DTrackCombo : public JObject
{
	private:
		//REACTION AND ANALYSIS:
		const DReaction* dReaction;
		deque<const DTrackComboStep*> dTrackComboSteps;
		const DKinFitResults* dKinFitResults;

		//UNUSED TRACKS:
		deque<const DChargedTrack*> dUnusedPositiveTracks;
		deque<const DChargedTrack*> dUnusedNegativeTracks;
		deque<const DNeutralShower*> dUnusedNeutralShowers;
};
class DTrackComboStep
{
	private:
		//PIDS:
		Particle_t dInitialParticleID; //e.g. lambda, phi, gamma
		Particle_t dTargetParticleID; //Unknown for no target
		deque<Particle_t> dFinalParticleIDs;

		//INITIAL PARTICLES:
		DKinematicData* dInitialParticle; //kinfit result, else measured
		DKinematicData* dInitialParticle_Measured; //e.g. DBeamPhoton
		DKinematicData* dTargetParticle; //NULL for no target

		//FINAL PARTICLES:
		deque<const DKinematicData*> dFinalParticles; //kinfit result, else measured //e.g. DChargedTrackHypothesis, DNeutralParticleHypothesis
		deque<const DKinematicData*> dFinalParticles_Measured; //e.g. DChargedTrackHypothesis, DNeutralParticleHypothesis
		deque<const JObject*> dFinalParticleSourceObjects; //original DChargedTrack or DNeutralShower objects

		//CONTROL VARIABLES:
		int dInitialParticleDecayFromStepIndex; //points to which DTrackComboStep represents the production of the initial particle (e.g. Lambda)
		deque<int> dDecayStepIndices; //let's you know whether a final state particle is decaying, missing, or detected.  if decaying, points to which DTrackComboStep represents its decay
};

Cutting & Histogramming: DAnalysisAction, DAnalysisResults

  • DAnalysisAction: virtual base class that encapsulates the setup (e.g. histogram creation) and execution (cut, hist, etc.) of the contained action for each DTrackCombo that has passed all previous cuts.
    • Many common actions (e.g. histogramming kinfit pulls, comparing thrown and reconstructed MC data, etc.) will be pre-defined in src/libraries/ANALYSIS
    • Custom, analysis-specific actions can be created and stored in the plugin, along with any custom factories you need for them (e.g.: studying the background).
  • DAnalysisResults: loops over DReaction objects, executing the DAnalysisAction objects for each one. Returns the cut status of each DTrackCombo (which cut they failed on, if any).
class DAnalysisAction
{
	public:
		//returns true/false if passes/fails cut/hist/etc.
		virtual bool operator()(JEventLoop* locEventLoop, map<const DTrackCombo*, bool>& locTrackCombos) const = 0;
};
  • Simple example: Cutting the confidence level of a kinematic fit.
class DAnalysisAction_KinFitFOM : public DAnalysisAction
{
 	public:
		double dMinimumConfidenceLevel; //e.g. 0.01

		DAnalysisAction_KinFitFOM(double locMinimumConfidenceLevel) : dMinimumConfidenceLevel(locMinimumConfidenceLevel) {} //cut setup upon construction

		bool operator()(JEventLoop* locEventLoop, map<const DTrackCombo*, bool>& locTrackCombos) const
		{
			bool locEventPassedCutFlag = false;
			//loop over all track combos and perform the cut (unless already failed a previous cut)
			for(map<const DTrackCombo*, bool>::iterator locIterator = locTrackCombos.begin(); locIterator != locTrackCombos.end(); ++locIterator)
			{
				if(!locIterator->second)
					continue; //track combo failed a previous cut!

				const DTrackCombo* locTrackCombo = locIterator->first;
				DKinFitResults* locKinFitResults = locTrackCombo->Get_KinFitResults();
				double locConfidenceLevel = locKinFitResults->Get_ConfidenceLevel();

				if(locConfidenceLevel > dMinimumConfidenceLevel)
					locTrackCombos[locTrackCombo] = false; //mark the DTrackCombo as having failed the cut
				else
					locEventPassedCutFlag = true; //at least once DTrackCombo passed the cut 
			}
			return locEventPassedCutFlag;
		}
};

User Plugin DReaction Factory

  • Below shows how to set up DReaction for a Y(2175) analysis.
  • Note that while most of the analysis actions are pre-defined, built-in ones (e.g. histogramming kinfit results), some are custom to the plugin (for now) (e.g. histogramming phi invariant mass).
//------------------
// init
//------------------
jerror_t DReaction_factory::init(void)
{
	// Setting the PERSISTANT prevents JANA from deleting
	// the objects every event so we only create them once.
	SetFactoryFlag(PERSISTANT);

	DReaction* locReaction;
	DReactionStep* locReactionStep;

	// Make as many DReaction objects as desired
	locReaction = new DReaction();
	locReaction->Set_ReactionName("Y2175");
	locReaction->Set_FitTypeFlag(3); //kinfit p4, v, & t simultaneously (0 is no kinfit)
 
 	//SETUP REACTION

	//g, p -> phi(2175), (p)
	locReactionStep = new DReactionStep();
	locReactionStep->Set_InitialParticleID(Gamma);
	locReactionStep->Set_TargetParticleID(Proton);
	locReactionStep->Add_FinalParticleID(Unknown); //phi(2175)
	locReactionStep->Add_FinalParticleID(Proton);
	locReactionStep->Set_MissingParticleIndex(1); //proton missing
	locReaction->Add_ReactionStep(locReactionStep);
	dReactionStepPool.push_back(locReactionStep); //prevent memory leak

	//phi(2175) -> pi+, pi-, phi
	locReactionStep = new DReactionStep();
	locReactionStep->Set_InitialParticleID(Unknown); //phi(2175)
	locReactionStep->Set_TargetParticleID(Unknown); //no target for this step
	locReactionStep->Add_FinalParticleID(PiPlus);
	locReactionStep->Add_FinalParticleID(PiMinus);
	locReactionStep->Add_FinalParticleID(phiMeson);
	locReactionStep->Set_MissingParticleIndex(-1); //none missing
	locReaction->Add_ReactionStep(locReactionStep);
	dReactionStepPool.push_back(locReactionStep); //prevent memory leak

	//phi -> K+, K-
	locReactionStep = new DReactionStep();
	locReactionStep->Set_InitialParticleID(Unknown); //phi(2175)
	locReactionStep->Set_TargetParticleID(Unknown); //no target for this step
	locReactionStep->Add_FinalParticleID(KPlus);
	locReactionStep->Add_FinalParticleID(KMinus);
 	locReactionStep->Set_MissingParticleIndex(-1); //none missing
 	locReaction->Add_ReactionStep(locReactionStep);
	dReactionStepPool.push_back(locReactionStep); //prevent memory leak
 
 	//SETUP ANALYSIS ACTIONS

	//Track reconstruction quality/multiplicity
	dReaction->Add_AnalysisAction(new DHistogramFunctor_TrackMultiplicity());
	dReaction->Add_AnalysisAction(new DHistogramFunctor_GenReconTrackComparison());

	//Vertex reconstruction and cuts of tracks with bogus vertex-z
	dReaction->Add_AnalysisAction(new DHistogramFunctor_TrackComboKinematics(1)); //1: initial data
	dReaction->Add_AnalysisAction(new DCutFunctor_AllVertexZ(45.0, 85.0));
	dReaction->Add_AnalysisAction(new DHistogramFunctor_TrackVertexComparison());

	//PID
	dReaction->Add_AnalysisAction(new DHistogramFunctor_PID());
	dReaction->Add_AnalysisAction(new DCutFunctor_AllPID(0.01, 1)); //1%, all charged tracks
	dReaction->Add_AnalysisAction(new DHistogramFunctor_TruePID());

	//Phi Invariant Mass Cut & PID Check
	dReaction->Add_AnalysisAction(new DHistogramFunctor_PhiMass(1)); //1: initial data
	dReaction->Add_AnalysisAction(new DCutFunctor_InvariantMass(phiMeson, 1, 1.004, 1.04)); //~3sigma
	dReaction->Add_AnalysisAction(new DHistogramFunctor_TruePID());

	//Initial Proton and Y2175 Mass Distributions
	dReaction->Add_AnalysisAction(new DHistogramFunctor_ProtonMass(1)); //1: initial data
	dReaction->Add_AnalysisAction(new DHistogramFunctor_Phi2175Mass(1)); //1: initial data

	//Missing Proton Kinematic Fit
	dReaction->Add_AnalysisAction(new DHistogramFunctor_KinFitResults(0.1));
	dReaction->Add_AnalysisAction(new DCutFunctor_KinFitFOM(0.01); //1%

	//Final Proton and Y2175 Mass Distributions
	dReaction->Add_AnalysisAction(new DHistogramFunctor_ProtonMass(1)); //1: initial data
	dReaction->Add_AnalysisAction(new DHistogramFunctor_Phi2175Mass(1)); //1: initial data
	dReaction->Add_AnalysisAction(new DHistogramFunctor_Phi2175Mass(2)); //2: final data

	//Final track kinematics & PID Check
	dReaction->Add_AnalysisAction(new DHistogramFunctor_TrackComboKinematics(2)); //2: final data
	dReaction->Add_AnalysisAction(new DHistogramFunctor_TruePID());

	_data.push_back(locReaction);

	return NOERROR;
}

User Plugin DEventProcessor

* The DEventProcessor itself is extremely minimal in content:
extern "C" 
{
	void InitPlugin(JApplication *app)
	{
		InitJANAPlugin(app);
		app->AddProcessor(new DEventProcessor_Y2175());
		app->AddFactoryGenerator(new DFactoryGenerator_DReaction());
	}
} // "C"

jerror_t DEventProcessor_Y2175::evnt(JEventLoop *locEventLoop, int eventnumber)
{
	vector<const DAnalysisResults*> locAnalysisResultsVector;
	locEventLoop->Get(locAnalysisResultsVector);

	//SAVE PROGRAM OUTPUT HERE (e.g. surviving DTrackCombo objects, custom tuples, etc. (format undetermined)

	return NOERROR;
}

Tupling

  • Haven't really gotten this far yet...