' ' Celestial Mixmaster -- ' ' Create a new plan document with select objects from other ' plan documents. ' ' By Michael Portuesi (mportuesi@yahoo.com). ' ' Home page: ' http://www.jotabout.com/portuesi/astro/software/mixmaster.html ' ' $Id: CelestialMixmaster.txt 51 2006-12-10 00:08:16Z portuesi $ ' '------------------------------------------------------------------ ' constants ' const scriptVersion = "0.8 beta" ' filtering operands const op_highlight_a = 0 const op_unhighlight_a = 1 const op_intersection_a_b = 2 const op_union_a_b = 3 const op_diff_a_b = 4 const op_diff_b_a = 5 '------------------------------------------------------------------ ' ' Utility function to calculate percentage completion. ' function percentDone( totalObjects as Integer, currentObject as Integer ) as Double Dim total as Double Dim current as Double total = totalObjects current = currentObject ' The task has two halves, compare/copy then create. So at any ' given stage we're only considering half the job. return (current + 1) / total / 2 * 100.0 end function '------------------------------------------------------------------ ' ' Utility function to see if the given plan contains the specified object. ' Optionally performs fuzzy matching (comparing RA and Dec), using the same ' algorithm employed by AstroPlanner to identify synonym entries. ' ' Returns index of found object in target plan, or 0 if not found. ' ' Has the unfortunate side effect of altering the current plan. ' function findObjectInPlan( planIdx as Integer, obj as APPlanObjectData, fuzzyMatch as Boolean ) as Integer Dim i as Integer SelectPlan( planIdx ) ' compare IDs for i = 1 to nObj if obj.ID = Obj(i).ID then return i end if next ' then compare RA/Dec if fuzzy specified. Implemented here as a second loop for efficiency. if ( fuzzyMatch = True ) then for i = 1 to nObj if ( AngleBetween( obj.RA, obj.Dec, Obj(i).RA, Obj(i).Dec) < 0.0083333 ) then return i end if next end if return 0 end function '------------------------------------------------------------------ ' ' Copy all highlighted objects from plan into an array for further ' processing. ' sub GetHighlighted( planA as Integer, Dobj() as APPlanObjectData, Dobs() as APObservationData, Dindex() as Integer, copyObs as Boolean ) Dim i, j as Integer SelectPlan(planA) for i=1 to nObj if ( Obj(i).IsHighlighted ) then Dobj.Append Obj(i).Contents if ( copyObs ) then for j=1 to Obj(i).nObs Dobs.Append Obj(i).Obs(j).Contents Dindex.Append ubound(Dobj) next end if end if if ( UpdateProgress(percentDone( nObj, i )) = True ) then return end if next end sub '------------------------------------------------------------------ ' ' Copy all un-highlighted objects from plan into an array for further ' processing. ' sub GetUnHighlighted( planA as Integer, Dobj() as APPlanObjectData, Dobs() as APObservationData, Dindex() as Integer, copyObs as Boolean ) Dim i, j as Integer SelectPlan(planA) for i=1 to nObj if ( not Obj(i).IsHighlighted ) then Dobj.Append Obj(i).Contents if ( copyObs ) then for j=1 to Obj(i).nObs Dobs.Append Obj(i).Obs(j).Contents Dindex.Append ubound(Dobj) next end if end if if ( UpdateProgress(percentDone( nObj, i )) = True ) then return end if next end sub '------------------------------------------------------------------ ' ' Given two plans, copy all objects in the set intersection of the two plans ' into an array for further processing. ' sub GetIntersection( planA as Integer, planB as Integer, Dobj() as APPlanObjectData, Dobs() as APObservationData, Dindex() as Integer, copyObs as Boolean, fuzzyMatch as Boolean ) Dim i, j as Integer Dim tempObj as APPlanObjectData Dim planBIdx as Integer SelectPlan( planA ) for i = 1 to nObj tempObj = Obj(i).Contents planBIdx = findObjectInPlan( planB, tempObj, fuzzyMatch ) SelectPlan( planA ) if ( planBIdx > 0 ) then Dobj.Append tempObj if ( copyObs ) then ' Copy observations from the instance of the object in Plan A. for j=1 to Obj(i).nObs Dobs.Append Obj(i).Obs(j).Contents Dindex.Append ubound(Dobj) next ' Copy the observations from the instance of the object in Plan B too. SelectPlan( planB ) for j=1 to Obj(planBIdx).nObs Dobs.Append Obj(planBIdx).Obs(j).Contents Dindex.Append ubound(Dobj) next SelectPlan( planA ) end if end if if ( UpdateProgress(percentDone( nObj, i )) = True ) then return end if next end sub '------------------------------------------------------------------ ' ' Given two plans, copy all objects in the set union of the two plans ' into an array for further processing. ' sub GetUnion( planA as Integer, planB as Integer, Dobj() as APPlanObjectData, Dobs() as APObservationData, Dindex() as Integer, copyObs as Boolean, fuzzyMatch as Boolean ) Dim i, j as Integer Dim totalObjs as Integer Dim planAObjs as Integer Dim tempObj, otherObj as APPlanObjectData Dim planAIdx, planBIdx as Integer SelectPlan( planA ) planAObjs = nObj SelectPlan( planB ) totalObjs = planAObjs + nObj ' Add all objects from plan A to list SelectPlan( planA ) for i=1 to nObj tempObj = Obj(i).Contents Dobj.Append tempObj if ( copyObs ) then ' Copy observations from the instance of the object in Plan A. for j=1 to Obj(i).nObs Dobs.Append Obj(i).Obs(j).Contents Dindex.Append ubound(Dobj) next 'If object is also in Plan B, then copy the Plan B observations as well planBIdx = findObjectInPlan( planB, tempObj, fuzzyMatch ) if ( planBIdx > 0 ) then for j=1 to Obj(planBIdx).nObs Dobs.Append Obj(planBIdx).Obs(j).Contents Dindex.Append ubound(Dobj) next end if SelectPlan( planA ) end if if ( UpdateProgress(percentDone( totalObjs, i )) = True ) then return end if next ' Add all objects from plan B not in Plan A to list SelectPlan(planB) for i=1 to nObj tempObj = Obj(i).Contents planAIdx = findObjectInPlan( planA, tempObj, fuzzyMatch ) SelectPlan(planB) if ( planAIdx = 0 ) then Dobj.Append tempObj if ( copyObs ) then ' Copy observations from the instance of the object in Plan B. for j=1 to Obj(i).nObs Dobs.Append Obj(i).Obs(j).Contents Dindex.Append ubound(Dobj) next end if end if if ( UpdateProgress(percentDone( totalObjs, i + planAObjs )) = True ) then return end if next end sub '------------------------------------------------------------------ ' ' Given two plans, copy all objects in plan A but not in plan B ' into an array for further processing. ' sub GetDifference( planA as Integer, planB as Integer, Dobj() as APPlanObjectData, Dobs() as APObservationData, Dindex() as Integer, copyObs as Boolean, fuzzyMatch as Boolean ) Dim i, j as Integer Dim tempObj as APPlanObjectData Dim planBIdx as Integer SelectPlan(planA) for i = 1 to nObj tempObj = Obj(i).Contents planBIdx = findObjectInPlan( planB, tempObj, fuzzyMatch ) SelectPlan(planA) if ( planBIdx = 0 ) then Dobj.Append tempObj if ( copyObs ) then ' Copy observations from the instance of the object in Plan A. for j=1 to Obj(i).nObs Dobs.Append Obj(i).Obs(j).Contents Dindex.Append ubound(Dobj) next end if end if if ( UpdateProgress(percentDone( nObj, i )) = True ) then return end if next end sub '------------------------------------------------------------------ ' ' Copy observations from one or more plan documents into the target ' plan document. The filtering criteria is chosen by the operand ' parameter. User observations are also copied if copyObs is set ' to True. ' sub CopyObjectsAndObservations( operand as Integer, planA as Integer, planB as Integer, planDest as Integer, copyObs as Boolean, fuzzyMatch as Boolean ) Dim Dobj(-1) as APPlanObjectData Dim Dobs(-1) as APObservationData Dim Dindex(-1) as Integer, i,j as Integer Dim Ob as APPlanObject ' Get objects from the source documents select case operand case op_highlight_a GetHighlighted( planA, Dobj, Dobs, Dindex, copyObs ) case op_unhighlight_a GetUnHighlighted( planA, Dobj, Dobs, Dindex, copyObs ) case op_intersection_a_b GetIntersection( planA, planB, Dobj, Dobs, Dindex, copyObs, fuzzyMatch ) case op_union_a_b GetUnion( planA, planB, Dobj, Dobs, Dindex, copyObs, fuzzyMatch ) case op_diff_a_b GetDifference( planA, planB, Dobj, Dobs, Dindex, copyObs, fuzzyMatch ) case op_diff_b_a GetDifference( planB, planA, Dobj, Dobs, Dindex, copyObs, fuzzyMatch ) else Print "unknown operand" return end select ' Copy objects and observations to the new document SelectPlan(planDest) for i=0 to ubound(Dobj) Ob=NewObject Ob.Contents=Dobj(i) for j=0 to ubound(Dobs) if Dindex(j)=i then Ob.NewObservation(CurrentDate).Contents=Dobs(j) end if next if ( UpdateProgress(percentDone( ubound(Dobj), i ) + 50.0 ) = True ) then return end if next end sub '------------------------------------------------------------------ ' ' Get a list of the names of currently open plan documents. ' function getPlanList( ) as String() Dim i as Integer Dim planList(-1) as String for i = 1 to nPlans planList.Append( GetPlanName( i ) ) next i return planList end function '------------------------------------------------------------------ ' ' Main ' try dim sourcePlanAIdx as Integer dim sourcePlanBIdx as Integer dim destPlanIdx as Integer dim copyObs as Boolean dim fuzzyMatch as Boolean dim operand as Integer Dim planList(-1) as String Dim dialogTitle as String ' Dialog defaults planList = getPlanList() sourcePlanAIdx = CurrentPlanNumber() - 1 sourcePlanBIdx = CurrentPlanNumber() - 1 operand = op_highlight_a copyObs = True fuzzyMatch = True dialogTitle = "Celestial Mixmaster " + scriptVersion ' Get parameters from user SetPopupParameter("Plan A:", sourcePlanAIdx, planList) SetPopupParameter("Plan B:", sourcePlanBIdx, planList) SetChoiceParameter("Create new plan with entries:", operand, _ "Highlighted in Plan A (B is ignored)", _ "Un-highlighted in Plan A (B is ignored)", _ "Appearing in both Plan A and Plan B", _ "Appearing in either Plan A or Plan B", _ "Appearing in Plan A but not Plan B", _ "Appearing in Plan B but not Plan A" ) SetBooleanParameter("Copy observing log entries", copyObs) SetBooleanParameter("Use fuzzy matching to compare objects", fuzzyMatch) if ( EditParameters(dialogTitle) ) then sourcePlanAIdx = GetPopupParameter("Plan A:") + 1 sourcePlanBIdx = GetPopupParameter("Plan B:") + 1 operand = GetChoiceParameter("Create new plan with entries:") copyObs = GetBooleanParameter("Copy observing log entries") fuzzyMatch = GetBooleanParameter("Use fuzzy matching to compare objects") ' Don't try to compare a document against itself. if ( ( operand <> op_highlight_a ) and ( operand <> op_unhighlight_a ) ) then if ( sourcePlanAIdx = sourcePlanBIdx ) then Print "Please choose different plans for Plan A and Plan B." return end if end if ' Create a new plan document destPlanIdx = NewPlan( "", false, true ) if ( destPlanIdx <= 0 ) then Print "Error: Could not create new plan document" return end if ' Copy Observations to new plan document StartProgress( "Copying objects to new plan...", True, 100.0 ) CopyObjectsAndObservations( operand, sourcePlanAIdx, sourcePlanBIdx, destPlanIdx, copyObs, fuzzyMatch ) StopProgress() end if catch Print "Celestial Mixmaster encountered an unexpected error while processing." end try