Author Topic: PCL: How to preserve parameters when launch interface via Console?  (Read 5001 times)

Offline NKV

  • PTeam Member
  • PixInsight Guru
  • ****
  • Posts: 677
Hi,
If launch interface via menu > etc > Sandbox, set some parameters, close interface -> parameters stored.
If launch interface via Console: Sandbox --interface -> parameters reset to Default.

How to preserve parameters when launch interface via Console?

BR,
Nikolay.

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: PCL: How to preserve parameters when launch interface via Console?
« Reply #1 on: 2011 September 21 15:55:45 »
Hi Nikolay,

This happens because the Sandbox interface is being launched with a default Sandbox instance. This is the SandboxProcess::ProcessCommandLine() routine excerpted from SandboxProcess.cpp:

Code: [Select]
int SandboxProcess::ProcessCommandLine( const StringList& argv ) const
{
   ArgumentList arguments =
      ExtractArguments( argv, ArgumentItemMode::AsViews, ArgumentOption::AllowWildcards );

   SandboxInstance instance( this );

   bool launchInterface = false;
   int count = 0;

   for ( ArgumentList::const_iterator i = arguments.Begin(); i != arguments.End(); ++i )
   {
      const Argument& arg = *i;

      if ( arg.IsNumeric() )
      {
         throw Error( "Unknown numeric argument: " + arg.Token() );
      }
      else if ( arg.IsString() )
      {
         throw Error( "Unknown string argument: " + arg.Token() );
      }
      else if ( arg.IsSwitch() )
      {
         throw Error( "Unknown switch argument: " + arg.Token() );
      }
      else if ( arg.IsLiteral() )
      {
         // These are standard parameters that all processes should provide.
         if ( arg.Id() == "-interface" )
            launchInterface = true;
         else if ( arg.Id() == "-help" )
         {
            ShowHelp();
            return 0;
         }
         else
            throw Error( "Unknown argument: " + arg.Token() );
      }
      else if ( arg.IsItemList() )
      {
         ++count;

         if ( arg.Items().IsEmpty() )
            throw Error( "No view(s) found: " + arg.Token() );

         for ( StringList::const_iterator j = arg.Items().Begin(); j != arg.Items().End(); ++j )
         {
            View v = View::ViewById( *j );
            if ( v.IsNull() )
               throw Error( "No such view: " + *j );
            instance.LaunchOn( v );
         }
      }
   }

   if ( launchInterface )
      instance.LaunchInterface();
   else if ( count == 0 )
   {
      if ( ImageWindow::ActiveWindow().IsNull() )
         throw Error( "There is no active image window." );
      instance.LaunchOnCurrentView();
   }

   return 0;
}

The instance is initialized in line 174:

   SandboxInstance instance( this );

This creates a default instance, that is, an instance whose parameters have all their default values. Since the above routine is just a skeleton, it does not interpret any command line parameters and hence does not modify the instance. Then on lines 226 and 231, the instance is used to either launch the process interface or to execute it on the current view, respectively:

      instance.LaunchInterface();
      instance.LaunchOnCurrentView();


For a good (and easy to follow) example of a real command-line processing routine, you can see  FastRotationProcess.cpp. As you can see, this routine modifies the instance being launched or executed through several command-line parameters:

Code: [Select]
int FastRotationProcess::ProcessCommandLine( const StringList& argv ) const
{
   ArgumentList arguments =
      ExtractArguments( argv,
                        ArgumentItemMode::AsViews,
                        ArgumentOption::AllowWildcards|ArgumentOption::NoPreviews );

   FastRotationInstance instance( this );

   bool launchInterface = false;
   int count = 0;

   for ( ArgumentList::const_iterator i = arguments.Begin(); i != arguments.End(); ++i )
   {
      const Argument& arg = *i;

      if ( arg.IsNumeric() )
      {
         if ( arg.Id() == "a" || arg.Id() == "angle" )
         {
            if ( arg.NumericValue() == +180 || arg.NumericValue() == -180 )
               instance.mode = FastRotationMode::Rotate180;
            else if ( arg.NumericValue() == 90 )
               instance.mode = FastRotationMode::Rotate90CCW;
            else if ( arg.NumericValue() == -90 )
               instance.mode = FastRotationMode::Rotate90CW;
            else
               throw Error( "Invalid fast rotation angle - must be 180 or +/-90 degrees: " + arg.Token() );
         }
         else
            throw Error( "Unknown numeric argument: " + arg.Token() );
      }
      else if ( arg.IsString() )
         throw Error( "Unknown string argument: " + arg.Token() );
      else if ( arg.IsSwitch() )
         throw Error( "Unknown switch argument: " + arg.Token() );
      else if ( arg.IsLiteral() )
      {
         if ( arg.Id() == "r180" )
            instance.mode = FastRotationMode::Rotate180;
         else if ( arg.Id() == "r90" || arg.Id() == "r90ccw" )
            instance.mode = FastRotationMode::Rotate90CCW;
         else if ( arg.Id() == "r90cw" )
            instance.mode = FastRotationMode::Rotate90CW;
         else if ( arg.Id() == "mh" )
            instance.mode = FastRotationMode::HorizontalMirror;
         else if ( arg.Id() == "mv" )
            instance.mode = FastRotationMode::VerticalMirror;
         else if ( arg.Id() == "-interface" )
            launchInterface = false;
         else if ( arg.Id() == "-help" )
         {
            ShowHelp();
            return 0;
         }
         else
            throw Error( "Unknown argument: " + arg.Token() );
      }
      else if ( arg.IsItemList() )
      {
         ++count;

         if ( arg.Items().IsEmpty() )
         {
            Console().WriteLn( "No view(s) found: " + arg.Token() );
            continue;
         }

         for ( StringList::const_iterator j = arg.Items().Begin(); j != arg.Items().End(); ++j )
         {
            View v = View::ViewById( *j );
            if ( v.IsNull() )
               throw Error( "No such view: " + *j );
            instance.LaunchOn( v );
         }
      }
   }

   if ( launchInterface )
      instance.LaunchInterface();
   else if ( count == 0 )
   {
      if ( ImageWindow::ActiveWindow().IsNull() )
         throw Error( "There is no active image window." );
      instance.LaunchOnCurrentWindow();
   }

   return 0;
}
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline NKV

  • PTeam Member
  • PixInsight Guru
  • ****
  • Posts: 677
Re: PCL: How to preserve parameters when launch interface via Console?
« Reply #2 on: 2011 September 21 22:01:45 »
Juan, sorry, but you not understand me.

I want realize next examples:
Example 1:
Open dialog of some module. Change the parameters in the Dialog window. Close the Dialog. And apply the parameters via console command: "SomeModule *.
( "*" - apply to all images)

Example 2:
Open dialog of some module. Change the parameters in the Dialog window. Close the Dialog. Run dialog of some module via command line (Console: SomeModule --interface) without reseting parameters to default. ( like it opened via menu > Process > SomeModule )

PS: Also I not understand why open GUI via menu and via console should have different results? Where is logic? IMHO it's bug.

Offline Juan Conejero

  • PTeam Member
  • PixInsight Jedi Grand Master
  • ********
  • Posts: 7111
    • http://pixinsight.com/
Re: PCL: How to preserve parameters when launch interface via Console?
« Reply #3 on: 2011 September 22 01:03:38 »
There is no bug here. This behavior is a consequence of how the command-line interface routines have been implemented in standard modules. What I was trying to explain is that when you launch an interface invoking the following member function:

void ProcessImplementation::LaunchInterface() const

the interface is forced to import the instance via ProcessInterface::ImportProcess(). For example:

SandboxInstance instance;
// ...
instance.parameterOne = 0.25;
instance.LaunchInterface();


In this example, TheSandboxInterface will import the 'instance' object and hence the 'One' slider will show 0.25 instead of the default 0.0 value (or instead of the previous value that this control could have).

This behavior is customary in PixInsight: all standard processes do this when you invoke them with the --interface argument. It is not a bug because it has been implemented this way by design. We can discuss why but it is off topic here.

To solve the particular problem that you want to address: You can of course implement your own routine to do just what you need very easily. You can use a custom command-line argument (please don't use --interface to do this) to open the interface with its current parameters. There are some ways to do this, but this is probably the most efficient one:

ProcessImplementation* p = TheSandboxInterface->NewProcess();
p->LaunchInterface();
delete p;


Let me know if this helps.
Juan Conejero
PixInsight Development Team
http://pixinsight.com/

Offline Nocturnal

  • PixInsight Jedi Council Member
  • *******
  • Posts: 2727
    • http://www.carpephoton.com
Re: PCL: How to preserve parameters when launch interface via Console?
« Reply #4 on: 2011 September 22 06:00:57 »
Quote
There is no bug here.

I knew Juan would write that  :P
Best,

    Sander
---
Edge HD 1100
QHY-8 for imaging, IMG0H mono for guiding, video cameras for occulations
ASI224, QHY5L-IIc
HyperStar3
WO-M110ED+FR-III/TRF-2008
Takahashi EM-400
PIxInsight, DeepSkyStacker, PHD, Nebulosity

Offline NKV

  • PTeam Member
  • PixInsight Guru
  • ****
  • Posts: 677
Re: PCL: How to preserve parameters when launch interface via Console?
« Reply #5 on: 2011 September 22 22:16:39 »
ProcessImplementation* p = TheSandboxInterface->NewProcess();
p->LaunchInterface();
delete p;


Let me know if this helps.
Yes!!! Thank you very much.