Question: How to remove Float(undefined) from plot structures?

My Maple plots contain strings like this one:

[HFloat(undefined),HFloat(undefined),HFloat(undefined)]

Let's call them "offending strings" or "errors", as they would most likely have been avoided by more experienced users. These errors arise while creating odeplots. I suspect that these errors are produced by the option Events of dsolve each time a halt is triggered. This is mere speculation and besides the point of my post anyhow.

Maple seems to understand the nature of these errors and to ignore them. I wouldn't have known about these errors if I hadn't exported the data with plottools-getdata. My intention then was to use the exported data to produce plots with another software, and I indeed started doing that, not without difficulties I might add (I tried to code directly in PSTricks, not funny).

The timing of John's question was just perfect. Initial tests suggested very nice plots could be produced, especially after font stubstitution and changes to line thickness. I couldn't wait to get started on creating beautiful plots. I knew my plots were filled with these offending strings, but I thought I could remove them using Joe's code.

But a difficulty was lurking. By difficulty I mean that I found it difficult. Joe would have fixed it in no time. But this time I was on a personal quest, I wanted to crack it myself. It cost me a few hours of sleep. Let's hear the story.

While early tests had been successful on testplot (see below), the code could not deal with my real-life plots. To find out what was going on, I decided to reverse engineer Joe's procedure, by breaking it into several steps (see below). It turns out that cmaple could not produce the postscript file from the mpl file, thrown off by so many offending strings. Thus I decided to proceed thus : maple plot --> dirty mpl --> clean mpl --> postscript --> clean postcript, that is to clean the mpl file before feeding it to cmaple. And that wasn't easy (for me anyway).

To understand what I'm going to describe now, refer to "step 2" below. Having created an mpl file from maple (size 11,226,123 bytes! most of it filled with errors) I tried this:

CleanMPL := proc( tmpfile :: string  )
  local str;
  str := FileTools:-Text:-ReadFile(tmpfile);
  str := StringTools:-RegSubs("[HFloat(undefined),HFloat(undefined),HFloat(undefined)]," = "", str);#breaks
  FileTools:-Text:-WriteString(tmpfile, str);
  fclose(tmpfile);
end proc:

CleanMPL("testplot.mpl") :

but it broke the mpl file and cmaple couldn't create an eps file anymore. Having failed to get Maple to do it, I thought it might be easier simply to run a bat file, something I'd done before. But it turns out that the offending strings form lines of thousands of bytes and that this is beyond the capability of simple DOS bat files. A method was found using SED. So this is the method I'm using right now (see code below)

Of course fixing the CleanMPL procedure above would be nice, as it would be more convenient to run one single proc rather than several. Equally convenient would be to insert a line of code inside the procedure that would pause, set off a bat file and resume once the bat file has finished. Is that feasible? It sounds complicated to me.

Below I copy Joe's procedure broken into several steps (this may have introduced imperfections, but apart from the second step involving CleanMPL, it works); and the windows bat file which cleans the MPL file. This is for reference, for information, perhaps someone someday will find it of some use. (but hopefully not if Maple 16 can produce beautiful 3D plots out of the box)

EDIT1: This won't work in general , because the mpl file header contains information about the size of the Arrays, and deleting the offending strings then modifies the size of the arrays. I hadn't noticed because I had tested it on valid mpl files in which I had pasted the offending strings, with the result that removing the offending strings restored the correct size of the Arrays. Stupid me! I think what I need to do is export the data and rebuild the plot from the cleaned up data before exporting it with Joe's procedure. This should be made to work (I'm pretty sure), but it's a few more steps.
EDIT2: Problem solved thanks to Joe's Procedure CleanPlot.

restart;

testplot := plot3d( [4+x*cos((1/2)*y), y, x*sin((1/2)*y)]
  , x = -Pi .. Pi
  , y = 0 .. 2*Pi
  , 'coords' = cylindrical
  , 'style' = patchnogrid
  , 'grid' = [60, 60]
  , 'orientation' = [35, 135]
  , 'lightmodel' = light4
  , 'shading' = zhue
  , 'scaling' = constrained
  , 'transparency' = .3
  , 'axes' = normal
) :


### Step 1


MakeMPL := proc( p :: evaln
  , { plotoutput :: string := cat(convert(p,string),".eps") }
  , { plotoptions :: string := "NULL" }
  , { tmpfile :: string := cat(convert(p,string),".mpl") }
  )
  local fd,opts;
  opts := "color=rgb,landscape,noborder,transparent";
  fd := fopen(tmpfile, 'WRITE', 'TEXT');
  fprintf(fd, "plotsetup('ps', 'plotoutput' = %a, 'plotoptions' = %a);\n"
    , plotoutput
    , cat(opts,",",plotoptions)
  ) ;
  fprintf(fd, "print(%a);\n", eval(p));
  fclose(fd);
end proc:


MakeMPL( testplot, plotoptions="width=400pt,height=400pt") ;

### Step 2

# CleanMPL("testplot.mpl") :
# see bat file below


### Step 3

MakeEPS := proc( mplfile :: string )
  local cmd;
  cmd := cat(kernelopts('bindir','dirsep'),"cmaple");
  cmd := sprintf("%s %s", cmd, mplfile);
  ssystem(cmd);
end proc:



MakeEPS( "testplot.mpl" ) :


### Step 4



EditEPS := proc( p :: evaln
  , { margin :: integer := 0 }
  , { thin :: posint := 8 }
  , { medium :: posint := 12 }
  , { thick :: posint := 20 }
  , { boundarythick :: integer := 20 }
  , { fonttype :: string := "Times-Roman" }
  , { fontsize :: posint := 130 }
  )

    local str, llx, lly, urx, ury, all, bb, regex;
    uses FT = FileTools, ST = StringTools;

    ### Modify the generated postscript file
    str := FT:-Text:-ReadFile(eval(p));
    fclose(eval(p));
    # keyword "thin" controls axis tickmark thickness
    str := ST:-RegSubs("\n/thin ([0-9]+) def" = sprintf("\n/thin %d def", thin), str);
    # keyword "medium" controls axis line thickness
    str := ST:-RegSubs("\n/medium ([0-9]+) def" = sprintf("\n/medium %d def", medium), str);
    # keyword "thick" is unused in examples I tried
    str := ST:-RegSubs("\n/thick ([0-9]+) def" = sprintf("\n/thick %d def", thick), str);
    # keyword "boundarythick" controls border thickness, if any
    str := ST:-RegSubs("\n/boundarythick ([0-9]+) def" = sprintf("\n/boundarythick %d def", boundarythick), str);
    # keyword "fontsize" controls both title and label font sizes, see /defaultFont and /defaultTitleFont
    str := ST:-RegSubs("findfont ([0-9]+) scalefont setfont" = sprintf("findfont %d scalefont setfont", fontsize), str);
    # keyword "fonttype" controls both title and label font types, see /defaultFont and /defaultTitleFont
    str := ST:-RegSubs("Helvetica" = sprintf("%s", fonttype), str);
    # Remove Postscript DSC error
    str := ST:-RegSubs("\n%%Pages:  ([0-9]+)" = "", str);

    ### Adjust bounding box
    if margin <> 0 then
        regex := "(\n%%BoundingBox: )([0-9]+) ([0-9]+) ([0-9]+) ([0-9]+)";
        if not ST:-RegMatch(regex,str,'all,bb,llx,lly,urx,ury') then
            error "problem matching bounding box";
        end if;
        bb := map(parse,[llx,lly,urx,ury]);
        bb := bb + [-margin,-margin,+margin,+margin];
        str := ST:-RegSubs(regex = sprintf("\\1 %d %d %d %d", op(bb)), str);
    end if;

    FT:-Text:-WriteString(eval(p), str);
    fclose(eval(p));

end proc:


EditEPS( "testplot.eps"
  , margin = 20
  , thin = 4
  , medium = 8
  , boundarythick = 1
  , fonttype = "Times"
  , fontsize = 80
) ;



### Step 2 again, requires SED, http://sourceforge.net/projects/unxutils/
author: dbenham, stackoverflow
http://stackoverflow.com/questions/8589054/bat-file-to-replace-string-in-text-file

@echo off
setlocal
cd /d %~dp0
Set "OldString=\[HFloat(undefined),HFloat(undefined),HFloat(undefined)\],"
Set "NewString="
set file="test.mpl"
for %%F in (%file%) do set outFile="%%~nFCleaned%%~xF"
pause
sed -e"s/%OldString%/%NewString%/g" %outfile%

Please Wait...