How to reorder/reorganise variable attributes in a netcdf file? - shell

I need to move 'standard_name' to be the first attribute present in all my variables within a netcdf file.
I am yet to find the correct command but I am hoping it will be something fairly straight forward using NCO.
If I ncdump, this is the current output:
short heading(time) ;
heading:data_max = 359.88f ;
heading:long_name = "Ship heading" ;
heading:data_min = 0.f ;
heading:units = "degrees" ;
heading:missing_value = 1.e+38f ;
heading:add_offset = 179.94f ;
heading:standard_name = "ship_heading" ;
heading:scale_factor = -0.005491668f ;
short depth(time, depth) ;
depth:positive = "down" ;
depth:long_name = "Depth" ;
depth:data_min = 20.48f ;
depth:units = "meter" ;
depth:missing_value = 1.e+38f ;
depth:data_max = 572.5f ;
depth:standard_name = "depth" ;
depth:add_offset = 296.49f ;
depth:scale_factor = -0.008423671f ;
I need the output to be :
short heading(time) ;
**heading:standard_name = "ship_heading" ;**
heading:data_max = 359.88f ;
heading:long_name = "Ship heading" ;
heading:data_min = 0.f ;
heading:units = "degrees" ;
heading:missing_value = 1.e+38f ;
heading:add_offset = 179.94f ;
heading:scale_factor = -0.005491668f ;
short depth(time, depth) ;
**depth:standard_name = "depth" ;**
depth:positive = "down" ;
depth:long_name = "Depth" ;
depth:data_min = 20.48f ;
depth:units = "meter" ;
depth:missing_value = 1.e+38f ;
depth:data_max = 572.5f ;
depth:add_offset = 296.49f ;
depth:scale_factor = -0.008423671f ;

I agree that the ideal place for standard_name is as the first or second attribute. Dumps are much more legible that way. You need to understand that attributes are stored and dumped in the order of their creation. NCO has no feature to re-arrange this order. The best solution is to alter the dataset writer so it creates standard_name before all other attributes. Or you can do something crazy like use ncatted to delete all the attributes and then re-add them in your desired order.

Related

Printer Icons in Print Dialog Box

I am using C++ and plain Winapi calls to display Print dialog box and it works fine. However the dialog box I get shows old printer icons compared to similar Print dialogs produced by other software. I wonder why.
Does anyone have an idea how to display the new printer icons as does MSVC dialog
Thanks a lot.
Here is how I display the Print Dialog in my application:
// Initialize the PRINTDLGEX structure
PRINTDLGEX PrnDlgEx ;
PrnDlgEx.lStructSize = sizeof (PRINTDLGEX) ;
PrnDlgEx.hwndOwner = hwnd ;
PrnDlgEx.hDevMode = NULL ;
PrnDlgEx.hDevNames = NULL ;
PrnDlgEx.hDC = NULL ;
PrnDlgEx.Flags = PD_HIDEPRINTTOFILE | PD_NOCURRENTPAGE | PD_NOPAGENUMS |
PD_NOSELECTION | PD_USEDEVMODECOPIESANDCOLLATE ;
PrnDlgEx.Flags2 = 0 ;
PrnDlgEx.ExclusionFlags = 0 ;
PrnDlgEx.nPageRanges = 0 ;
PrnDlgEx.nMaxPageRanges = 0 ;
PrnDlgEx.lpPageRanges = nullptr ;
PrnDlgEx.nMinPage = 1 ;
PrnDlgEx.nMaxPage = 0xFFFF ;
PrnDlgEx.nCopies = 1 ;
PrnDlgEx.hInstance = NULL ;
PrnDlgEx.lpPrintTemplateName = NULL ;
PrnDlgEx.lpCallback = NULL ;
PrnDlgEx.nPropertyPages = 0 ;
PrnDlgEx.lphPropertyPages = NULL ;
PrnDlgEx.nStartPage = START_PAGE_GENERAL ;
PrnDlgEx.dwResultAction = 0 ;
HRESULT Result = PrintDlgEx (&PrnDlgEx) ;
Below is screen shoots for my Print dialog 1 and MS VC dialog 2.
According to Customizing the Print Dialog Box.You can create the custom template by modifying the default template specified in the Prnsetup.dlg file. The control identifiers used in the default Print dialog template are defined in the Dlgs.h file.
Then use the PRINTDLG structure to enable the template.

Find in Files - Number per file

In EMEditor, is there a way to get the number of occurrences of a "find in files" search per file? In other words, it finds 10,000 "hits" across 25 files, I'd like to know that 1200 where in file1 etc.
Notepad++ does a great job of this by allowing you to collapse the results by file and showing a summary for each, but I haven't seen a way to get the information in EMEditor.
After Find in Files, you can run this macro while the results document is active. Save this code as, for instance, statistics.jsee, and then select this file from Select... in the Macros menu. Finally, do Find in Files, and select Run in the Macros menu while the results document is active.
// Creates statistics from Find in Files Results.
// 2020-06-27
Redraw = false;
sOutput = "";
y = 1;
yMax = document.GetLines();
for( ;; ) {
document.selection.SetActivePoint( eePosLogical, 1, y++ );
document.selection.Mode = eeModeStream | eeModeKeyboard;
bFound = document.selection.Find("\\(\\d+?\\)\\:",eeFindNext | eeFindReplaceCase | eeFindReplaceRegExp,0);
document.selection.Mode = eeModeStream;
if( !bFound ) {
break;
}
sFile = document.selection.Text;
n = sFile.lastIndexOf("(");
sFile = sFile.substr( 0, n );
nCount = 1;
for( ;; ) {
document.selection.SetActivePoint( eePosLogical, 1, y );
sLine = document.GetLine( y );
if( sLine.length > sFile.length && sLine.substr( 0, sFile.length ) == sFile ) {
++nCount;
++y;
}
else {
sOutput += sFile + "\t" + nCount + "\n";
break;
}
}
}
document.selection.Mode = eeModeStream;
Redraw = true;
editor.NewFile();
document.write( sOutput );
editor.ExecuteCommandByID(4471); // switch to TSV mode

Stuck filling an array using VBscript and a For Loop

I have created an array to store some excel cell addresses, but while running through a portion of the array with a For Loop (because the values are in order for that portion of the data and its easier than doing each one at a time), but I get an error at line 22,(saData(i,1) = "D" count), right at the "count" variable but I cant figure out why.
'LOADING EXCEL CELL ADDRESS INTO INPUT ARRAY
saData(0,1) = "C3"
saData(1,1) = "F3"
saData(2,1) = "C4"
saData(3,1) = "F4"
saData(4,1) = "F6"
saData(5,1) = "C7"
saData(6,1) = "F7"
saData(7,1) = "C8"
saData(8,1) = "C9"
saData(9,1) = "F9"
saData(10,1) = "C11"
saData(12,1) = "F11"
saData(13,1) = "C13"
saData(14,1) = "F13"
Dim count : count = 16
For i = 15 to 54
saData(i,1) = "D" count
count = count + 1
next'
saData(55,1) = "G59"
saData(56,1) = "F60"
saData(57,1) = "B64"
saData(58,1) = "E64"
For i = 0 to 59
Msgbox saData(i,1)
next
Just try concatenating saData(i,1) = "D"&count

OS X AudioUnit: kAudio_ParamError when setting misc properties on a Generator

I'm building a simple AudioUnit app which should use an AUGraph to connect a generator (which generates, say, a sine wave) to a format converter (because that seems like what I need) to an output device.
Code snippets:
{
AudioComponentDescription desc ;
desc.componentType = kAudioUnitType_Generator ;
desc.componentSubType = kAudioUnitSubType_ScheduledSoundPlayer ;
desc.componentFlags = 0 ;
desc.componentFlagsMask = 0 ;
desc.componentManufacturer = kAudioUnitManufacturer_Apple ;
status = AUGraphAddNode ( mGraph , &desc , &mGeneratorNode ) ;
checkOSStatus ( "creating generator node" , status ) ;
}
I do similarly for mConverterNode with kAudioUnitType_FormatConverter/kAudioUnitSubType_AUConverter and for mOutputNode with kAudioUnitType_Output/kAudioUnitSubType_DefaultOutput.
I then open the graph:
AUGraphOpen ( mGraph ) ; // error checking code omitted from example
I then get references to them:
AUGraphNodeInfo ( mGraph , mGeneratorNode , 0,&mGeneratorRef ) ; // error checking code omitted from example
I then set the format:
{
AudioStreamBasicDescription format ;
format.mSampleRate = mSamplingRate ;
format.mFormatID = kAudioFormatLinearPCM ;
format.mFormatFlags = kAudioFormatFlagIsSignedInteger ;
format.mFramesPerPacket = 1 ;
format.mChannelsPerFrame = 1 ; // mono
format.mBitsPerChannel = 16 ;
format.mBytesPerFrame = format.mBitsPerChannel*format.mChannelsPerFrame/8 ;
format.mBytesPerPacket = format.mBytesPerFrame*format.mFramesPerPacket ;
status = AudioUnitSetProperty ( mGeneratorRef , kAudioUnitProperty_StreamFormat , kAudioUnitScope_Output , kOutputBus , &format,sizeof(format) ) ;
checkOSStatus ( "setting output format" , status ) ;
}
(Note: kOutputBus is an enum to 0; it's an anachronism from a previous example I found. Also, mSamplingRate is a size_t whose value is 48000)
And set the render callback:
{
AURenderCallbackStruct cb ;
cb.inputProc = &_callbackProxy ;
cb.inputProcRefCon = static_cast<void*> ( this ) ;
status = AudioUnitSetProperty ( mGeneratorRef , kAudioUnitProperty_SetRenderCallback , kAudioUnitScope_Output , 0 , &cb,sizeof(cb) ) ;
checkOSStatus ( "setting the generator callback" , status ) ;
}
However, for both the stream format and the render callback I get kAudio_ParamError back as the resultant status.
No matter what I do (mono/stereo, when I place that command, etc), I cannot make it work.
Note: I later do this:
AUGraphConnectNodeInput ( mGraph , mGeneratorNode,0 , mConverterNode,0 ) ;
AUGraphConnectNodeInput ( mGraph , mConverterNode,0 , mOutputNode,0 ) ;
AUGraphInitialize ( mGraph ) ;
AUGraphStart ( mGraph ) ;
// again, error-checking code omitted from example
And it works........ But I can't set those properties and therefore can't generate audio.
What am I missing?
(To people with 1500+ reputation: please make an "osx-sierra" tag; I'm a bit shy of that mark)
From an obscure comment at the end of this:
https://discussions.apple.com/thread/1989797?tstart=0
I ran AUGraphOpen at the very beginning before creating things (why?) and it worked.
But then I was getting invalid format errors, so I set the format on the input of the converter instead of the output of the generator.
But then it wasn't calling the render callback, so I removed the generator altogether and put the render callback on the input of the converter.
At this point, it worked and is generating my sound.
I hope this helps somebody else in the future with this so-horribly-documented API.

Getting an swift class var without Optional("value")

I'm creating a utility to add archival events to a calendar.
example run
./create-events-from-dvd-contents.swift --path /Volumes/ARCHIVE/DVD\ 1255/2451-01_LLA_Assets\ Folder\ Nov\ 2015/
Optional("DVD 1255")
The class is
class Event {
var location: String? ;
var start: String? ;
var notes: String? ;
}
The code to print the dvd location is
let event = Event() ;
let pathArray = path.characters.split {$0 == "/"}.map { String($0) } ;
event.location = pathArray[2] ;
print(event.location) ;
What is the simplest way to get 'DVD 1255' output instead of 'Optional("DVD 1255")'?
you must unwrap the value first into its own (non optional) variable.
let event = Event() ;
let pathArray = path.characters.split {$0 == "/"}.map { String($0) } ;
event.location = pathArray[2];
if let location = event.location {
print(location);
}
or you could put an ! after event.location if you wanted.
let event = Event() ;
let pathArray = path.characters.split {$0 == "/"}.map { String($0) } ;
event.location = pathArray[2] ;
print(event.location!) ;
The nil-coalescing operator is a clean way to do this:
var x: String? = "foo"
print(x) // Optional('foo')
x = nil
var y: String = x ?? "bar" // note y is not an optional
print(y) // Bar
print(x ?? "Not optional") // Not optional
Also, I noticed you are using semi-colons, which are unnecessary in Swift. I mention this, not as an opinion, but because it is a good practice of Swift to not use semi-colons unless necessary (multiple statements on one line or something)

Resources