PK
����d]Y������������	��META-INF/����PK
����d]Y(F�bh���h������META-INF/MANIFEST.MFManifest-Version: 1.0
Ant-Version: Apache Ant 1.9.4
Created-By: 1.8.0_181-b13 (Oracle Corporation)

PK
����d]Y���������������org/PK
����d]Y������������
���org/autoplot/PK
����d]Y���������������org/autoplot/cefdatasource/PK
����d]Y���������������test/PK
����d]YT�K������������META-INF/build.txtbuild.timestamp: 
build.user.name: 
build.svnurl: $URL: https://svn.code.sf.net/p/autoplot/code/autoplot/trunk/CefDataSource/src/META-INF/build.txt $
build.svnrevision: $Revision: 595 $
PK
����d]Yn�#�4���4���=���META-INF/org.autoplot.datasource.DataSourceFactory.extensionsorg.autoplot.cefdatasource.CefDataSourceFactory cef
PK
����d]Yvv=�������$���org/autoplot/cefdatasource/Cef.class�������3�1
�
�$	�	�%	�	�&	�	�'�(
��$	�	�)	�	�*�+�,�nglobal�I�nparam�eor�B�
parameters�Ljava/util/Map;�	Signature�.�ParamStruct�InnerClasses�[Ljava/util/Map<Ljava/lang/String;Lorg/autoplot/cefdatasource/CefReaderHeader$ParamStruct;>;�globals�/�GlobalStruct�\Ljava/util/Map<Ljava/lang/String;Lorg/autoplot/cefdatasource/CefReaderHeader$GlobalStruct;>;�<init>�()V�Code�LineNumberTable�LocalVariableTable�this� Lorg/autoplot/cefdatasource/Cef;�
SourceFile�Cef.java�����
����java/util/LinkedHashMap�����org/autoplot/cefdatasource/Cef�java/lang/Object�0�6org/autoplot/cefdatasource/CefReaderHeader$ParamStruct�7org/autoplot/cefdatasource/CefReaderHeader$GlobalStruct�*org/autoplot/cefdatasource/CefReaderHeader�!�	�
������������
��������������������������������������i�����+*��*��*��*
��*��Y����*��Y�������������������	���������������+� �!����"����#�������-����-��PK
����d]Y�&i�9��9��.���org/autoplot/cefdatasource/CefDataSource.class�������3]
��(
)*
+,	+-	+.
�/
�01
�2
�3	��4	��56
�
7
)89
�:
;<=
�>
?@
�AB
�7
�C	��D
��EFGHI
��J
�K	LMN
��OP
�$7Q	�"RS
�(7T
�(U
�(V
�(WX
�YGZG[\]
�2^	_`
_abc
_def
gY
hijk
�?7���@
�?l
��m
�?n	�"op��q	�"rs
�>^
tuv
hwxy
��z
��{x|	�"}~
�T
�T�
��
��
�yx/�
�[�
t�
��	_�
���	��
���x��&/
���
���G�x�
���
��
��������y��
����
�x7
�x�
���
�|���
t�
���&�x�
t�x�
t�x�
t�
���
�?���
��	����
��
��
��
_�
����
�����cef� Lorg/autoplot/cefdatasource/Cef;�dsid�Ljava/lang/String;�<init>�(Ljava/net/URI;)V�Code�LineNumberTable�LocalVariableTable�this�*Lorg/autoplot/cefdatasource/CefDataSource;�uri�Ljava/net/URI;�split�"Lorg/autoplot/datasource/URISplit;�file�i�I�
StackMapTable���I�
getDataSet�@(Lorg/das2/util/monitor/ProgressMonitor;)Lorg/das2/qds/QDataSet;�mon�'Lorg/das2/util/monitor/ProgressMonitor;�f�Ljava/io/File;�c�'Ljava/nio/channels/ReadableByteChannel;�cmon�5Lorg/das2/util/DasProgressMonitorReadableByteChannel;�readerh�,Lorg/autoplot/cefdatasource/CefReaderHeader;�var�ds�%Lorg/das2/qds/MutablePropertyDataSet;�dsvar�Lorg/das2/qds/QDataSet;�
Exceptions�getMetadata�8(Lorg/das2/util/monitor/ProgressMonitor;)Ljava/util/Map;�param�ParamStruct�InnerClasses�8Lorg/autoplot/cefdatasource/CefReaderHeader$ParamStruct;�	Signature�^(Lorg/das2/util/monitor/ProgressMonitor;)Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;�getMetaData�p(Lorg/autoplot/cefdatasource/CefReaderHeader$ParamStruct;Lorg/das2/util/monitor/ProgressMonitor;)Ljava/util/Map;�depMeta�Ljava/util/Map;�dep�entries�LocalVariableTypeTable�5Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;���(Lorg/autoplot/cefdatasource/CefReaderHeader$ParamStruct;Lorg/das2/util/monitor/ProgressMonitor;)Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;�
createDataSet��(Ljava/lang/String;Lorg/das2/qds/MutablePropertyDataSet;ZLorg/das2/util/DasProgressMonitorReadableByteChannel;)Lorg/das2/qds/MutablePropertyDataSet;�ceffill�D�ex�!Ljava/lang/NumberFormatException;�readerd�*Lorg/autoplot/cefdatasource/CefReaderData;�data�[Ljava/lang/String;�ddata�[D�rank0�result�"Lorg/das2/qds/util/DataSetBuilder;�sizes�[I�ndim�dds�Lorg/das2/qds/ArrayDataSet;�dp01�dp02�newDim�dep0ds�s�units�!Lorg/das2/datum/EnumerationUnits;�dep1�Lorg/das2/qds/WritableDataSet;�type�size�m�props�e�Ljava/lang/Exception;�tds�doDeps�Z�collapseDim�u�Lorg/das2/datum/Units;�fill�sceffill�su�qubeN�=�jk���������
makeMonotonic�d(Lorg/das2/qds/MutablePropertyDataSet;ILorg/das2/qds/QDataSet;)Lorg/das2/qds/MutablePropertyDataSet;�d�k�j�idim�sort�cds�Lorg/das2/qds/DDataSet;��	setDsName�:(Ljava/lang/String;Lorg/das2/qds/MutablePropertyDataSet;)V�
setParseFlags�_(Lorg/autoplot/cefdatasource/Cef;Ljava/lang/String;Lorg/autoplot/cefdatasource/CefReaderData;)V��getMetadataModel�)()Lorg/autoplot/datasource/MetadataModel;�getDeltaPlusDeltaMinus��(Lorg/autoplot/cefdatasource/CefReaderHeader$ParamStruct;Lorg/das2/qds/MutablePropertyDataSet;Lorg/das2/qds/MutablePropertyDataSet;)V�mds�p1�
sdeltaPlus�sdeltaMinus�
SourceFile�CefDataSource.java����������������������__�������������)org/das2/util/monitor/NullProgressMonitor������java/io/FileInputStream�������3org/das2/util/DasProgressMonitorReadableByteChannel���������*org/autoplot/cefdatasource/CefReaderHeader���������arg_0����java/lang/String�����������6org/autoplot/cefdatasource/CefReaderHeader$ParamStruct�����java/util/LinkedHashMap�org/das2/qds/QDataSet�����java/lang/StringBuilder�DEPEND_���������������"java/lang/IllegalArgumentException�no such dataset: ���������FILLVAL�UNITS�
VALUE_TYPE�ISO_TIME�java/lang/NumberFormatException�(org/autoplot/cefdatasource/CefReaderData	
���DATA�#format error in data of param.name=
���: ��
FILL_VALUE� !������ org/das2/qds/util/DataSetBuilder������(org/autoplot/cefdatasource/ReformDataSet�� !"#$%�	MONOTONIC&'()*�DEPEND_0+,- �	CONTEXT_0.�COORDINATE_SYSTEM/��0123�X456789:;�Y�COORDINATE_FRAME�DEPEND_1�����+org/autoplot/cefdatasource/CefMetadataModel<=>?�java/lang/Exception@��idim must be <=2 �
rank limit2ABCDEDF:GDH:IJK�NAMEL	�
DELTA_PLUS�DELTA_MINUSMNOPQ�handling DELTA_PLUS DELTA_MINUSRS�TUKVWXYZ[�/handling DELTA_PLUS DELTA_MINUS for time series�<unable to locate DELTA_PLUS and/or DELTA_MINUS variable for \��(org/autoplot/cefdatasource/CefDataSource�*org/autoplot/datasource/AbstractDataSource�java/net/URI� org/autoplot/datasource/URISplit�
java/util/Map�#org/das2/qds/MutablePropertyDataSet�org/das2/datum/Units�org/das2/qds/ArrayDataSet�java/io/IOException�java/text/ParseException�org/das2/qds/DDataSet�org/autoplot/cefdatasource/Cef�"org/autoplot/datasource/DataSetURI�fromUri�"(Ljava/net/URI;)Ljava/lang/String;�parse�6(Ljava/lang/String;)Lorg/autoplot/datasource/URISplit;�path�length�()I�	substring�(I)Ljava/lang/String;�indexOf�(Ljava/lang/String;)I�(II)Ljava/lang/String;�()V�getFile�E(Ljava/net/URI;Lorg/das2/util/monitor/ProgressMonitor;)Ljava/io/File;�(Ljava/io/File;)V�java/nio/channels/Channels�
newChannel�>(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;�Q(Ljava/nio/channels/ReadableByteChannel;Lorg/das2/util/monitor/ProgressMonitor;)V�java/io/File�()J�setStreamLength�(J)V�read�I(Ljava/nio/channels/ReadableByteChannel;)Lorg/autoplot/cefdatasource/Cef;�	getParams�()Ljava/util/Map;�get�&(Ljava/lang/Object;)Ljava/lang/Object;�close�
parameters�append�-(Ljava/lang/String;)Ljava/lang/StringBuilder;�(I)Ljava/lang/StringBuilder;�toString�()Ljava/lang/String;�equals�(Ljava/lang/Object;)Z�put�8(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;�putAll�(Ljava/util/Map;)V�(Ljava/lang/String;)V�
dimensionless�
getFillDouble�()D�lookupUnits�*(Ljava/lang/String;)Lorg/das2/datum/Units;�java/lang/Object�java/lang/Double�parseDouble�(Ljava/lang/String;)D�	skipParse�(I)V�cefReadData�n(Ljava/nio/channels/ReadableByteChannel;Lorg/autoplot/cefdatasource/Cef;)Lorg/das2/qds/MutablePropertyDataSet;�cefFieldPos�name�wrap�([D)Lorg/das2/qds/DDataSet;�valueOf�(D)Ljava/lang/Double;�putProperty�'(Ljava/lang/String;Ljava/lang/Object;)V�rank�(III)V�()Lorg/das2/qds/DDataSet;�org/das2/qds/DataSetOps�leafTrim�@(Lorg/das2/qds/QDataSet;II)Lorg/das2/qds/MutablePropertyDataSet;�copy�4(Lorg/das2/qds/QDataSet;)Lorg/das2/qds/ArrayDataSet;�(Lorg/das2/qds/QDataSet;[I)V�createRank1�(I)Lorg/das2/qds/DDataSet;�slice1�?(Lorg/das2/qds/QDataSet;I)Lorg/das2/qds/MutablePropertyDataSet;�us2000�"Lorg/das2/datum/TimeLocationUnits;�org/das2/qds/DataSetUtil�isMonotonic�(Lorg/das2/qds/QDataSet;)Z�java/lang/Boolean�TRUE�Ljava/lang/Boolean;�qubeDims�(Lorg/das2/qds/QDataSet;)[I�property�&(Ljava/lang/String;)Ljava/lang/Object;�slice0�trim�containsKey�(I)I�org/das2/datum/EnumerationUnits�create�5(Ljava/lang/Object;)Lorg/das2/datum/EnumerationUnits;�createDatum�*(Ljava/lang/Object;)Lorg/das2/datum/Datum;�org/das2/datum/Datum�doubleValue�(Lorg/das2/datum/Units;)D�org/das2/qds/WritableDataSet�putValue�(ID)V�
properties� (Ljava/util/Map;)Ljava/util/Map;�
putProperties�7(Ljava/util/Map;Lorg/das2/qds/MutablePropertyDataSet;)V�printStackTrace�([I)Lorg/das2/qds/DDataSet;�
getProperties�((Lorg/das2/qds/QDataSet;)Ljava/util/Map;�value�(I)D�(III)D�(IIID)V�(II)D�(IID)V�endsWith�(Ljava/lang/String;)Z�doParse�org/das2/qds/SemanticOps�getUnits�/(Lorg/das2/qds/QDataSet;)Lorg/das2/datum/Units;�logger�Ljava/util/logging/Logger;�java/util/logging/Logger�finest�&org/autoplot/datasource/DataSourceUtil�isJavaDouble�org/das2/qds/ops/Ops�	replicate�"(DI)Lorg/das2/qds/WritableDataSet;�getOffsetUnits�()Lorg/das2/datum/Units;�b(Lorg/das2/qds/QDataSet;Ljava/lang/String;Ljava/lang/Object;)Lorg/das2/qds/MutablePropertyDataSet;�fine�!������������������������
�����������������>*+��+����M,��,������N-��	6��*-��
����*�����������"����3��4�
�5��6�$�7�*�8�8�:�=�<�����4����>���������>������
�1�������"������$��������������8������������!���������
��	���k*����
Y����M��Y,����N��Y-+��:,������Y��:*����*�������::*��:�� ���������.����@��A��C�&�D�/�F�8�H�C�J�S�L�V�N�c�P�h�R�����\�	���k���������k�������\�������P������&�E������8�3������S�������V�������c�������������|�!����������w�����'*�������M*����!,�����"N*-+��#�������������W��X� �Z�����*����'���������'������������� �������������|��������!���������F��������$Y��%N6��u+��'��(Y��)*��+��,��-�����:��H.��/��>**����!�����"��
Y����#:-��(Y��)*��+��,��-��0�W����-+��'��1�-���������&�	���_��a��b�3�c�B�d�`�e�}�a���i���w�����H��`�������3�J�������x������������������������������������������������`��������������������������q���������|�����������������
Y�����*����!+�����":����2Y��(Y��)3��++��+��-��4��6��5:��69	��'7�����:��'8�����:��
��9:��':���;��<�� ����=��	9
��:	9
��	9
,��:��?Y��@:6A����B����**��+��C*����DM��E.�����'F�����G��G:��:6���G2��=R��1:��>Y��(Y��)H��+��I��+J��+2��+��-��K�������L:M
��N��O�8��O�*,��P*+��Q��R�6�@��S�����S.���,��)��TY��E.��E.d`��U:��V:��,��E.��E.`��W:��X:8��YM
��N��Y:*,��P*+��Q��S���[��S�`�
:��Z�O�66�����Sdd.O�����[Y��\:��R�6����R�6��M,����]:��,��E.��^:��R�6��X:8��YM
��N��Y:*+��Q��':���;��<��#8��_��O���`��a��b��O���c:���6�����'��(Y��)*��+��,��-�����Y:���6��d6�����6*,��:��R���hd��e���&:d��e���&:��G��B��f���f���1��g:h��O���Z�.��.��i:��(Y��)*��+��,��-��O������'j��k������l������'j�����:6��m��m:��]:n��o��p��q�r��o��p��q�s��o��p��q�8��t�u��t�v��O�*��
Y����w:��xY��y��z:��{��
:��}���������>"�>����|�������t�����������2���7���<���C���T���e���j���q�����������������������������������������������������������������������"��$��P��V��]��k��v���������������������������������������������!��-��8��=��H��Z��`��m��v��y����������������������������������������������
���?CJSZ^
ju�
���������), 2!9"?#S$g%{&�'�(�-�.�/�4�0�1�6������2��������
����������������
�����������.�����$�,�����
�L���������������������������]�5�������������������@� �����-�I�����=�9�����v�������������������������������������� �������W�������I�����C�������j�������<��������������9�c�����?�]�����)�s�����,�p���������������������������������������������������������������������������7�������#������<�������C������	�Tw�����ef�����%�����
�,�����
���������������������~�$��2��>������������ AD����������(������������G	��W-����;)����X����������
����������������������
���������������/�����������3��
���A�������������
��{�������d������
�>��������������
��2Y~��4�+��R���
��2Y��4�+��c:-��f�O���:+�����{���6.���+��R���w6.��h+��R���:6.��++-���������9		������ҧ�!+-���������9���������+-���������9������\������6.��z6.��h+��R���:6.��++-���������9		������ҧ�!+-���������9�������������`��[6.��O6.��=6.��++-���������9		������҄������������������-��F�G�I�J�#M�)N�3P�:Q�CS�GT�SU�]V�iW�sX�Y��Z��X��]��^��V��b��c��T��f��ghij'k<lIjRoepphvgt�u�v�w�x�y�w�v�u�����������
���	�v�1����������`�n������	����J�������<�
���	�1���e�����n��������������
���	��1�����C�����U�����������������������������������)�����:�������Q���&������0������������0������������0�����������������L*����>+��(Y��)��+*����+��-�����!,�++��*����`d��
��O���,�+��O���������������$��B��K������ ����L���������L��������L�������������B������D�����|+��!,�����":��E.��&��E.6��E.`��-�������6��8��'��(Y��)*��+��,��-�����Y:��*+-��C���ȱ��������*�
��������1��7��=��F��m��u��{������R��#�������j�������@�;��������|���������|��������|��������|�������m����������.���#�������4������������������2�������xY��y����������������������������� !��������	���+��'������:+��'������:-���:��a��\������������L�����D-���=-��Z����8��������O�-���=-��Z����8��������O���������������*����!�����":��E.�����E.���,��E.��E.`��W:��'8��k���8��'8�������9��O�-���O�*����!�����":,��E.��E.`��W:��'8��k���8��'8�������9��O�-���O��������(Y��)���++��I��+��-������������f������� ��&��0��8��H��h���������������������������!�7�F�a�k�n��������\�	����"�������#�������������������������������������{$���� k%����&e���������� ����������z��\�����&���'�����
��"����PK
����d]Y+a��a��5���org/autoplot/cefdatasource/CefDataSourceFactory.class�������3��
�0����
���
������
���
������
���
���	������
��������������������������	�������������
����������	�$��	�$��	�$��
�$��
����
�/����������
�$������
�(������
���
���
��������<init>�()V�Code�LineNumberTable�LocalVariableTable�this�1Lorg/autoplot/cefdatasource/CefDataSourceFactory;�
getDataSource�4(Ljava/net/URI;)Lorg/autoplot/datasource/DataSource;�uri�Ljava/net/URI;�
Exceptions���getPlottable�G(Ljava/net/URI;Lorg/das2/util/monitor/ProgressMonitor;)Ljava/util/List;�h1�ParamStruct�InnerClasses�8Lorg/autoplot/cefdatasource/CefReaderHeader$ParamStruct;�
parameterType�Ljava/lang/String;�ee�Entry�Ljava/util/Map$Entry;�mon�'Lorg/das2/util/monitor/ProgressMonitor;�f�Ljava/io/File;�in�'Ljava/nio/channels/ReadableByteChannel;�reader�,Lorg/autoplot/cefdatasource/CefReaderHeader;�cef� Lorg/autoplot/cefdatasource/Cef;�h�Ljava/util/Map;�result�Ljava/util/List;�LocalVariableTypeTable�aLjava/util/Map$Entry<Ljava/lang/String;Lorg/autoplot/cefdatasource/CefReaderHeader$ParamStruct;>;�[Ljava/util/Map<Ljava/lang/String;Lorg/autoplot/cefdatasource/CefReaderHeader$ParamStruct;>;�$Ljava/util/List<Ljava/lang/String;>;�
StackMapTable���������������������������	Signature�[(Ljava/net/URI;Lorg/das2/util/monitor/ProgressMonitor;)Ljava/util/List<Ljava/lang/String;>;�getCompletions�d(Lorg/autoplot/datasource/CompletionContext;Lorg/das2/util/monitor/ProgressMonitor;)Ljava/util/List;�s�surl�	plottable�ex� Ljava/net/MalformedURLException;�Ljava/io/IOException;�cc�+Lorg/autoplot/datasource/CompletionContext;�=Ljava/util/List<Lorg/autoplot/datasource/CompletionContext;>;��������(Lorg/autoplot/datasource/CompletionContext;Lorg/das2/util/monitor/ProgressMonitor;)Ljava/util/List<Lorg/autoplot/datasource/CompletionContext;>;�reject�L(Ljava/lang/String;Ljava/util/List;Lorg/das2/util/monitor/ProgressMonitor;)Z�problems�`(Ljava/lang/String;Ljava/util/List<Ljava/lang/String;>;Lorg/das2/util/monitor/ProgressMonitor;)Z�
SourceFile�CefDataSourceFactory.java�1�2�(org/autoplot/cefdatasource/CefDataSource�1���������java/io/FileInputStream�1���������*org/autoplot/cefdatasource/CefReaderHeader���������T�java/util/ArrayList�����������������������java/util/Map$Entry�����6org/autoplot/cefdatasource/CefReaderHeader$ParamStruct���T�PARAMETER_TYPE�����java/lang/String�Data�����������������������������������>�?�)org/autoplot/datasource/CompletionContext�arg_0�1���java/net/MalformedURLException�java/lang/RuntimeException�1���java/io/IOException�?�������������/org/autoplot/cefdatasource/CefDataSourceFactory�1org/autoplot/datasource/AbstractDataSourceFactory�java/lang/Exception�java/net/URI�%org/das2/util/monitor/ProgressMonitor�java/io/File�%java/nio/channels/ReadableByteChannel�org/autoplot/cefdatasource/Cef�
java/util/Map�java/util/List�java/util/Iterator�(Ljava/net/URI;)V�"org/autoplot/datasource/DataSetURI�getFile�E(Ljava/net/URI;Lorg/das2/util/monitor/ProgressMonitor;)Ljava/io/File;�(Ljava/io/File;)V�java/nio/channels/Channels�
newChannel�>(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;�read�I(Ljava/nio/channels/ReadableByteChannel;)Lorg/autoplot/cefdatasource/Cef;�
parameters�entrySet�()Ljava/util/Set;�
java/util/Set�iterator�()Ljava/util/Iterator;�hasNext�()Z�next�()Ljava/lang/Object;�getValue�entries�get�&(Ljava/lang/Object;)Ljava/lang/Object;�equals�(Ljava/lang/Object;)Z�getKey�add�context�Ljava/lang/Object;�CONTEXT_PARAMETER_NAME�CONTEXT_FILE�Q(Ljava/lang/Object;Lorg/autoplot/datasource/CompletionContext;)Ljava/lang/String;�getResourceURI�"(Ljava/lang/String;)Ljava/net/URI;��(Ljava/lang/Object;Ljava/lang/String;Lorg/autoplot/datasource/DataSourceFactory;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Z)V�(Ljava/lang/Throwable;)V�contains�(Ljava/lang/CharSequence;)Z�indexOf�(Ljava/lang/String;)I�length�()I�!�/�0�������1�2��3���/�����*�������4��������5��������6�7����8�9��3���=�����	��Y+�������4�������"�5�������	�6�7�����	�:�;��<�����=��>�?��3��u��
����+,��N��Y-����:��Y��	:��
:��:��Y��
:������:		�����M	�����:

�����:�������:������
������W���������:		�����M	�����:

�����:�������:��
����
������W��������4���N����&��'��(��)�%�*�,�+�5�,�Y�-�e�.�v�/���0���2���3���4���5���6���7���9���:�5������e�/�@�C��v��D�E��Y�;�F�H�
���/�@�C�����D�E����;�F�H�
�����6�7�������:�;������I�J�����K�L�����M�N�����O�P��%���Q�R��,���S�T��5���U�V��W���*��Y�;�F�X�
���;�F�X�
�,���S�Y��5���U�Z��[���E���C�
�\�]�^�_�`�a�b�c�d�e����P����
�e��A�f�g�h�����<�����*�i����j��k�l��3����
������Y��
N+������n��+�� :*��!,��":��#�:�����+�����:-��$Y��*%��&���W��ѧ�:��(Y��)�:��(Y��)�-����b�e�'��b�q�*��4���6�
���?��A��C��D�'�E�F�F�_�G�b�M�e�I�g�J�q�K�s�L�}�P�5���\�	�F��m�E���G�n�E��'�;�o�V��g�
�p�q��s�
�p�r�����6�7������s�t�����I�J���w�U�V��W�����'�;�o�Z���w�U�u��[���*���0��\�v�^�d�h�d�e����1B�wK�x�i����y��z�{��3���������++��,��++��-+��.d���������4�������U�5���*�����6�7������n�E�����|�V�����I�J��W��������|�Z��[����@�i����}��~�����B�������A�����G	PK
����d]Y}������1���org/autoplot/cefdatasource/CefMetadataModel.class�������3��
�I����
���
�������
�����
����
����������
�
����
�
��
�
��
�
��
�������
����
����
���������
�H����
���
�'������������
�H��
���@�������
�'����
�����
�+��������
�+��������������
���	����
�H����
�'����
�'��
�H��������	�H��	����
��������
���������logger�Ljava/util/logging/Logger;�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�-Lorg/autoplot/cefdatasource/CefMetadataModel;�doubleValue�<(Ljava/lang/Object;Lorg/das2/datum/Units;)Ljava/lang/Double;�ex�Ljava/text/ParseException;�o�Ljava/lang/Object;�units�Lorg/das2/datum/Units;�
StackMapTable���
getValidRange�B(Ljava/util/Map;Lorg/das2/datum/Units;)Lorg/das2/datum/DatumRange;�attrs�Ljava/util/Map;�max�Ljava/lang/Double;�min���getRange�range�Lorg/das2/datum/DatumRange;�D�getScaleType�#(Ljava/util/Map;)Ljava/lang/String;�type�Ljava/lang/String;�
properties� (Ljava/util/Map;)Ljava/util/Map;�sfill�$Ljava/lang/IllegalArgumentException;�Ljava/util/HashMap;�LocalVariableTypeTable�5Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;�9Ljava/util/HashMap<Ljava/lang/String;Ljava/lang/Object;>;�������������	Signature�l(Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;)Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;�getLabel�()Ljava/lang/String;�<clinit>�
SourceFile�CefMetadataModel.java�L�M�java/lang/Float�S�������java/lang/Double�java/lang/Short�java/lang/String���������S���java/text/ParseException�"java/lang/IllegalArgumentException�java/lang/StringBuilder�unable to parse �����������~�L���java/lang/RuntimeException�Unsupported Data Type: �����������~�VALIDMAX�������S�T�VALIDMIN�����SCALEMIN�����SCALEMAX�log�i�j�����org/das2/datum/DatumRange�L���SCALETYP���~�java/util/HashMap�LABLAXIS�org/das2/qds/QDataSet�LABEL�����CATDESC�TITLE�DISPLAY_TYPE�RENDER_TYPE�FILLVAL�
FILL_VALUE�������Z�e�^�TYPICAL_MIN�c���TYPICAL_MAX�a���]�^�	VALID_MIN�	VALID_MAX�
SCALE_TYPE�J�K�������������CEF�	apdss.cef�������+org/autoplot/cefdatasource/CefMetadataModel�%org/autoplot/datasource/MetadataModel�org/das2/datum/Units�
java/util/Map�()D�valueOf�(D)Ljava/lang/Double;�parse�*(Ljava/lang/String;)Lorg/das2/datum/Datum;�org/das2/datum/Datum�(Lorg/das2/datum/Units;)D�append�-(Ljava/lang/String;)Ljava/lang/StringBuilder;�-(Ljava/lang/Object;)Ljava/lang/StringBuilder;�toString�(Ljava/lang/String;)V�java/lang/Object�getClass�()Ljava/lang/Class;�java/lang/Class�getName�get�&(Ljava/lang/Object;)Ljava/lang/Object;�
newDatumRange�5(DDLorg/das2/datum/Units;)Lorg/das2/datum/DatumRange;�containsKey�(Ljava/lang/Object;)Z�equals�(DDLorg/das2/datum/Units;)V�toLowerCase�put�8(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;�parseDouble�(Ljava/lang/String;)D�
dimensionless�()Lorg/das2/datum/Datum;�java/util/logging/Level�WARNING�Ljava/util/logging/Level;�java/util/logging/Logger�C(Ljava/util/logging/Level;Ljava/lang/String;Ljava/lang/Throwable;)V�org/das2/util/LoggerManager�	getLogger�.(Ljava/lang/String;)Ljava/util/logging/Logger;�!�H�I�����J�K�����L�M��N���/�����*�������O��������P��������Q�R����S�T��N��������+���+����+�������+����+���+����+�������+����/,+����	,��
���N��Y��
Y����+���������Y��
Y����+�������������=�L�M���O���2����"��#�
�$��%��&�$�'�+�(�6�)�=�+�M�,�N�-�i�0�P���*��N��U�V������Q�R�������W�X������Y�Z��[����V�\��]�^��N���������6*+���,��N*+���,��:-�������-��,�������O�������;��<��=�(�>�P���4����6�Q�R�����6�_�`����6�Y�Z���(�a�b����c�b��[������&�d�d��e�^��N��{������99+�� ���5+!�� ���**+!���,����9*+���,����9��U+!�� ���*+!���,����99��2+�� ���'*+���,����9*+���,����9"*+��#��$������%o9���������'Y,��(N-�����O���B����H��I��J�.�K�C�M�N�N�`�O�f�R�q�S���T���X���Y���\���]���_���`�P���>������Q�R�������_�`������Y�Z�����f�g�����c�h�����a�h��[������C�".��i�j��N���q�����+)�� ���+)�����M,��*������O�������e��f��g��i�P��� ����k�l�����Q�R������_�`��[������m�n��N��/����	��+Y��,M+-�� ���,/+-�����0W+1�� ���,2+1�����0W+3�� ���+3�����N,4-��0W+5�� ���+5�����N,6-��7����0W��8N*+-��9:��),:��;-��
����0W,<��=-��
����0W*+-��>:��),?��;-��
����0W,@��=-��
����0W,A*+��#��0W��:��B��C��D,�����������O���f����p��r��s�"�v�-�w�<�z�G�{�S�|�[��f���r���������������������������������������������������������P���R��S��k�l��r��o�l����j�f�g�����U�p���	�Q�R����	�_�`���m�q������Y�Z��r������	�_�s���m�t��[���,���"�u$��6�v�w2����x�y�u�v��z
�{����|��}�~��N���-�����E�����O���������P��������Q�R�����M��N���!������	F��G��B�����O���������������PK
����d]Y�]/��/��.���org/autoplot/cefdatasource/CefReaderData.class�������3��
�4��	���	����	��������@	���
����	���
����	����)��
�'��
����
�����
�����
���	������
����	�����
����	�����
@
����
��������
����
����
���
�������
�#��
�����
�'����
���
���
����
�'��
����
������
�'����
�������logger�Ljava/util/logging/Logger;�parsers�)[Lorg/autoplot/cefdatasource/FieldParser;�eor�B�comma�u�Lorg/das2/datum/Units;�
MAX_FIELDS�I�
ConstantValue�doParse�[Z�<init>�()V�Code�LineNumberTable�LocalVariableTable�i�this�*Lorg/autoplot/cefdatasource/CefReaderData;�
StackMapTable���	skipParse�(I)V�countFields�(Ljava/nio/ByteBuffer;)I�k�work_buffer�Ljava/nio/ByteBuffer;�n_fields�
getLastEor�pos_eor�parseRecord�=(Ljava/nio/ByteBuffer;I[ILorg/das2/qds/util/DataSetBuilder;)V�bbuf�irec�
fieldDelim�[I�builder�"Lorg/das2/qds/util/DataSetBuilder;�
Exceptions�����removeComments�(Ljava/nio/ByteBuffer;I)V�j�ch�	work_size�comment�eol�pos_comment�
getParsers�B(Ljava/nio/ByteBuffer;I[Lorg/autoplot/cefdatasource/FieldParser;)V�
timeParser�(Lorg/autoplot/cefdatasource/FieldParser;�\���splitRecord�(Ljava/nio/ByteBuffer;II[I)I�recPos�ifield�cefReadData�n(Ljava/nio/channels/ReadableByteChannel;Lorg/autoplot/cefdatasource/Cef;)Lorg/das2/qds/MutablePropertyDataSet;�	read_size�pos�lun�'Ljava/nio/channels/ReadableByteChannel;�cef� Lorg/autoplot/cefdatasource/Cef;�buffer_size�work_buf�[B�read_buffer�trflag�eof�Z�����~���������<clinit>�
SourceFile�CefReaderData.java�C�D�;�:�������<�=�(org/autoplot/cefdatasource/CefReaderData�A�B�������9�:�����7�8�������������p�q�,org/autoplot/cefdatasource/DoubleFieldParser�(org/autoplot/cefdatasource/IsoTimeParser�C�N�������here232�������5�6�$Reading data records, please wait...���������������������P���������U�P�b�c�"java/lang/IllegalArgumentException�:the entire work buffer was a comment, this is not handled.�C���O�P� org/das2/qds/util/DataSetBuilder�C���&org/autoplot/cefdatasource/FieldParser�j�k�W�X�������D���������Reading of data complete�����	apdss.cef�������java/lang/Object�)java/nio/charset/CharacterCodingException�java/text/ParseException�%java/nio/channels/ReadableByteChannel�org/autoplot/cefdatasource/Cef�java/nio/ByteBuffer�org/das2/qds/DDataSet�java/io/IOException�org/das2/datum/Units�us2000�"Lorg/das2/datum/TimeLocationUnits;�get�(I)B�limit�()I�
parseField�(Ljava/nio/ByteBuffer;II)D�putValue�(IID)V�put�(IB)Ljava/nio/ByteBuffer;�java/lang/System�err�Ljava/io/PrintStream;�java/io/PrintStream�println�(Ljava/lang/String;)V�java/util/logging/Logger�fine�wrap�([B)Ljava/nio/ByteBuffer;�rewind�()Ljava/nio/Buffer;�read�flip�,(Ljava/nio/ByteBuffer;)Ljava/nio/ByteBuffer;�(III)V�position�(I)Ljava/nio/Buffer;�
nextRecord�compact�()Ljava/nio/ByteBuffer;�
getDataSet�()Lorg/das2/qds/DDataSet;�org/das2/util/LoggerManager�	getLogger�.(Ljava/lang/String;)Ljava/util/logging/Logger;�!��4�����5�6�����7�8�����9�:�����;�:����<�=����>�?��@�������A�B�����C�D��E���������2*��*,��*����*���<*�����*��T���������F�������%���
� ��#��(�1�)�G�������H�?����2�I�J���K��������L������M�N��E���@�����*��T�����F���
����,��-�G��������I�J������H�?���A�N��E���@�����*��T�����F���
����0��1�G��������I�J������H�?���O�P��E���������-=>+��*����	���+��*��	����	���������F���"����4��5��7��8��9�"�:�%�5�+�=�G���*���'�Q�?����-�I�J�����-�R�S���+�T�?��K����������U�P��E���~�����"+��
d=��+��*��	����	����������F�������G��H��I��G� �L�G��� ����"�I�J�����"�R�S����V�?��K��������W�X��E�����	����C6-�d��9*��2��)*��2+-.-`.-.dd�����
���ı����F�������P��Q��R�<�P�B�U�G���>���?�H�?����C�I�J�����C�Y�S����C�Z�?����C�[�\����C�]�^��K���
���8���_�����`�a��b�c��E��I������!>
66��s+��6��:6�� +����+ ��W`6���+ ��W6��(��*��	��+ ��W��*��	�����������F���B����[��\��_��`��a��b�"�c�3�d�<�e�E�g�N�h�R�i�e�j�q�k�z�_���o�G���R��"�0�d�?���b�e�:������I�J�������R�S������f�?���~�g�:���z�h�:��
�w�i�?��K������
��"������j�k��E��(�����j-�6`�
:*+��W6��&*��3��-��Y��S��-S����.����Y��:��
��Y��:-S�����F���.����z��{��|��}� �~�=�}�C���L���Z���d���i���G���\�	��*�H�?��W��l�m����j�I�J�����j�R�S����j�f�?����j�7�8���f�T�?���^�[�\��d��l�m��K�������n����	�o��p�q��E���������N6O��/+��*��	���� +��*�����`O����..�����������F���2������������
���������(���+���3���9���D���L���G���>����N�I�J�����N�R�S����N�r�?����N�f�?����N�[�\���K�s�?��K���
�����t�u��E�������u����*,����	>h�:���:��:666
6:
�$���W+���6

��	6
�
����W�� W��W
`6*��!6���6*��"*��!6��
6��
��#Y$��%�*��&6	��&��'Yd	��(:*	��)��**����*	`�
:O6��M6*��6��4	`O*��+`6��,W��-`6�����.W��/6
����ݲ�0��������1�����F�����7�����������������"���)���,���/���2���5���8���B���H���R���X���[���^���c���i���q���w���~�������������������������������������������
�������� ,2:?EH!N"U%[)^0f2�G������C�r�?��R	�v�?�
�����V�?����l�[�\����d�w�?������T�?�	��u�I�J����u�x�y���u�z�{��b�|�?��[�}�~��"S��S��)L�R�S��,I�f�?��/F���?��2C�����
�5@�Z�?��8=�]�^��K�������8�
�L�����������������%��5	��/��L�����������������n��P���
�L�����������������
�L���������������D���_�������a����D��E���!������	2��3�������F���������������PK
����d]Y��,g��g��2���org/autoplot/cefdatasource/CefReaderHeader$1.class�������3�-
��	��	��
���	��	����!�;$SwitchMap$org$autoplot$cefdatasource$CefReaderHeader$State�[I�<clinit>�()V�Code�LineNumberTable�LocalVariableTable�
StackMapTable��
SourceFile�CefReaderHeader.java�EnclosingMethod�"�#�%�&�
��'�(�)�*�java/lang/NoSuchFieldError�+�(�,�(�,org/autoplot/cefdatasource/CefReaderHeader$1�InnerClasses�java/lang/Object�*org/autoplot/cefdatasource/CefReaderHeader�0org/autoplot/cefdatasource/CefReaderHeader$State�State�values�5()[Lorg/autoplot/cefdatasource/CefReaderHeader$State;�TOP�2Lorg/autoplot/cefdatasource/CefReaderHeader$State;�ordinal�()I�GLOBAL�PARAM ��	����
�������
�����������7����
��������O��K������O��K������O��K���	�����#�&��'�2�5����������������������W��M��M���������������� ������������$@PK
����d]Y���������=���org/autoplot/cefdatasource/CefReaderHeader$GlobalStruct.class�������3�
�����	valueType�Ljava/lang/String;�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�GlobalStruct�InnerClasses�9Lorg/autoplot/cefdatasource/CefReaderHeader$GlobalStruct;�
SourceFile�CefReaderHeader.java����7org/autoplot/cefdatasource/CefReaderHeader$GlobalStruct�java/lang/Object�*org/autoplot/cefdatasource/CefReaderHeader�!��������������������/�����*�������	�������'�
������������������
���
�����PK
����d]Y���(������9���org/autoplot/cefdatasource/CefReaderHeader$KeyValue.class�������3�
�����key�Ljava/lang/String;�val�[Ljava/lang/String;�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�KeyValue�InnerClasses�5Lorg/autoplot/cefdatasource/CefReaderHeader$KeyValue;�
SourceFile�CefReaderHeader.java��	��3org/autoplot/cefdatasource/CefReaderHeader$KeyValue�java/lang/Object�*org/autoplot/cefdatasource/CefReaderHeader�!���������������������	��
���/�����*��������������!���������
�������������
�����PK
����d]Y�$������<���org/autoplot/cefdatasource/CefReaderHeader$ParamStruct.class�������3�$
���
��	���!�"�name�Ljava/lang/String;�sizes�[I�recType�I�cefFieldPos�entries�Ljava/util/Map;�	Signature�5Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�ParamStruct�InnerClasses�8Lorg/autoplot/cefdatasource/CefReaderHeader$ParamStruct;�
SourceFile�CefReaderHeader.java���java/util/LinkedHashMap���#�6org/autoplot/cefdatasource/CefReaderHeader$ParamStruct�java/lang/Object�*org/autoplot/cefdatasource/CefReaderHeader�!��������������	�
�����������
�
���������������������>�����*��*��Y������������
����.��4����������������������
��� ��PK
����d]Y�\?<������7���org/autoplot/cefdatasource/CefReaderHeader$Record.class�������3�
�����data�Ljava/lang/String;�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�Record�InnerClasses�3Lorg/autoplot/cefdatasource/CefReaderHeader$Record;�
SourceFile�CefReaderHeader.java����1org/autoplot/cefdatasource/CefReaderHeader$Record�java/lang/Object�*org/autoplot/cefdatasource/CefReaderHeader�!��������������������/�����*�������	��������
������������������
���
�����PK
����d]Y�Z�;��;��6���org/autoplot/cefdatasource/CefReaderHeader$State.class�������3�@	��/
�0�1��3
��4
��5�
��5	��6�	��7�	��8�	��9�	��:�;�TOP�State�InnerClasses�2Lorg/autoplot/cefdatasource/CefReaderHeader$State;�END�	DATA_READ�GLOBAL�PARAM�$VALUES�3[Lorg/autoplot/cefdatasource/CefReaderHeader$State;�values�5()[Lorg/autoplot/cefdatasource/CefReaderHeader$State;�Code�LineNumberTable�valueOf�F(Ljava/lang/String;)Lorg/autoplot/cefdatasource/CefReaderHeader$State;�LocalVariableTable�name�Ljava/lang/String;�<init>�(Ljava/lang/String;I)V�this�	Signature�()V�<clinit>�DLjava/lang/Enum<Lorg/autoplot/cefdatasource/CefReaderHeader$State;>;�
SourceFile�CefReaderHeader.java����<�=�>�0org/autoplot/cefdatasource/CefReaderHeader$State�!�?�&�'�����������java/lang/Enum�clone�()Ljava/lang/Object;�*org/autoplot/cefdatasource/CefReaderHeader�5(Ljava/lang/Class;Ljava/lang/String;)Ljava/lang/Enum;@0�����@����@����@����@����@����������	�������"������
����������� ��������	�!�"�����4�����
*��������� ��������#�������
�$�%����&�'�����1�����*+������� ��������#��������(����)����*��+�*������������g��Y����	��Y
������Y����
��Y������Y������Y��	SY��SY��
SY��SY��S������� ���
�����A���)����,�-����.����
���2�@PK
����d]Y|!�������0���org/autoplot/cefdatasource/CefReaderHeader.class�������3s
�]����
���
����
��������
�����
���
���
���
���
���
���
���	�"����
���
���
���	�$��
�����
���������
���	�$������
���	�l����
�"����
�$��	�l��	�l��
�����
�����
���
���	�f��
�l��
�����
���������������	�l����
�:����	�:��	�l����
�?��	�?��	�?���
�C	�	
	�	�
	�?	�?	�	�	�?	�	

 
!"#
$%&
'()�InnerClasses�ParamStruct�GlobalStruct�KeyValue�Record*�State�logger�Ljava/util/logging/Logger;�EOL�B�
ConstantValue���
�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�,Lorg/autoplot/cefdatasource/CefReaderHeader;�cefReadHeadRec�](Ljava/nio/channels/ReadableByteChannel;Lorg/autoplot/cefdatasource/CefReaderHeader$Record;)Z�sbuf�Ljava/lang/StringBuilder;�
tempRecord�Ljava/lang/String;�c�'Ljava/nio/channels/ReadableByteChannel;�record�3Lorg/autoplot/cefdatasource/CefReaderHeader$Record;�status�Z�readFlag�	recordBuf�
eofReached�buf�[B�b1�Ljava/nio/ByteBuffer;�
StackMapTable��+������,���
Exceptions-�cefSplitRec�J(Ljava/lang/String;Lorg/autoplot/cefdatasource/CefReaderHeader$KeyValue;)Z�tab�i�I�val�kv�5Lorg/autoplot/cefdatasource/CefReaderHeader$KeyValue;�pos�read�I(Ljava/nio/channels/ReadableByteChannel;)Lorg/autoplot/cefdatasource/Cef;�data_idx�[I�n�sizes�k�rev�[Ljava/lang/String;�isizes�key�value�cef� Lorg/autoplot/cefdatasource/Cef;�state�2Lorg/autoplot/cefdatasource/CefReaderHeader$State;�pdata�eCount�gStru�9Lorg/autoplot/cefdatasource/CefReaderHeader$GlobalStruct;�gName�pStru�8Lorg/autoplot/cefdatasource/CefReaderHeader$ParamStruct;�pName��*�����������<clinit>�
SourceFile�CefReaderHeader.java�t�u�java/lang/StringBuilder,./01+��234�*org/autoplot/cefdatasource/CefReaderHeader567689:;<=3>?����@ABAC6����<D�java/lang/String�tE�"[ �]*,[ �]*"FG�����,�org/autoplot/cefdatasource/CefH���1org/autoplot/cefdatasource/CefReaderHeader$Record�3org/autoplot/cefdatasource/CefReaderHeader$KeyValueI��J���{�|�19KL�20����M6N��O9P9�
START_METAQR�START_VARIABLE�INCLUDE�
DATA_UNTIL�	FILE_NAME�FILE_FORMAT_VERSION�END_OF_RECORD_MARKERS���7org/autoplot/cefdatasource/CefReaderHeader$GlobalStruct�CHART��U���6org/autoplot/cefdatasource/CefReaderHeader$ParamStructV��W���"java/lang/IllegalArgumentException�not yet supported�tXY�q�Unsupported key �5Global entry not allowed multiple values per entry : �END_META�
VALUE_TYPE�ENTRY�END_VARIABLE expected �  got Z��[\]^_�Unsupported global key �END_VARIABLE����`��a��b\�DATA�SIZESc\�n�odef�{0}={1}�java/lang/Objectg5hijklmn�bad state, check codeoX�
Bad record?  �	apdss.cefpqr�,org/autoplot/cefdatasource/CefReaderHeader$1�0org/autoplot/cefdatasource/CefReaderHeader$State�%java/nio/channels/ReadableByteChannel�java/nio/ByteBuffer�java/io/IOException�wrap�([B)Ljava/nio/ByteBuffer;�rewind�()Ljava/nio/Buffer;�(Ljava/nio/ByteBuffer;)I�append�(C)Ljava/lang/StringBuilder;�toString�()Ljava/lang/String;�trim�length�()I�charAt�(I)C�	substring�(II)Ljava/lang/String;�-(Ljava/lang/String;)Ljava/lang/StringBuilder;�data�lastIndexOf�(I)I�indexOf�toUpperCase�(I)Ljava/lang/String;�([B)V�split�'(Ljava/lang/String;)[Ljava/lang/String;�TOP�	DATA_READ�END�
startsWith�(Ljava/lang/String;)Z�intern�;$SwitchMap$org$autoplot$cefdatasource$CefReaderHeader$State�ordinal�hashCode�equals�(Ljava/lang/Object;)Z�GLOBAL�	valueType�PARAM�name�recType�(Ljava/lang/String;)V�eor�nglobal�globals�Ljava/util/Map;�
java/util/Map�put�8(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;�cefFieldPos�nparam�
parameters�entries�java/util/logging/Level�FINER�Ljava/util/logging/Level;�java/util/Arrays�'([Ljava/lang/Object;)Ljava/lang/String;�java/util/logging/Logger�log�A(Ljava/util/logging/Level;Ljava/lang/String;[Ljava/lang/Object;)V�java/lang/Integer�parseInt�(Ljava/lang/String;)I�warning�org/das2/util/LoggerManager�	getLogger�.(Ljava/lang/String;)Ljava/util/logging/Logger;�!��]�����n�o����p�q��r����s���t�u��v���/�����*�������w��������x��������y�z����{�|��v��������>6��Y��:6�:��:��������Y��:	��W+�����	6��	3���W3
��ק�	��	:

��
:

����
��!����Y
����*

��d��\��

��d��
��W��*
��W����6>,��	����	,����D�����w���r����;��<��=��?��A��B��E�'�G�0�K�6�L�B�M�E�N�H�Q�S�R�\�S�_�V�f�X�m�[���]���^���`���b���c���d���e���g���k���m�x���p��0���}�~�	�f�s����
�����y�z������������������������������������������~������������������������������2�	���	��������������������#��. �����������������v���������>+!��6��+��
L+=��6���>,+��
��
����+`����
:��"��N��Y�Y	T��:,��d��
��Y��������������	������2,����6,�����,��,��2��
S���������w���J����r��u�
�v��w��{� �|�&�}�(���9���F���Q���b���������������������������x���R��b�7��������!������F������������y�z�����������������������������
����������������������
�� �������v��	8�������Y�� M��!N66:::	:
��"Y��#:��$Y��%:-��&�]-��'�V*+��(���I������ ��)��*�0��+��*��� *����,������-:
��:��.-��/.�������������������
:6��0������������������d�(�i���t��S����D4������TOK������YcKn����w�������1��2��g6��a3��2��W6��Q4��2��G6��A5��2��76��16��2��'6��!7��2��6��8��2��6������������������,���L���q���{��������������9N��:Y��;:2:<��=6��k��>N2:
��?Y��@:		2��A	��B��F��CYD��E���&N��5��2��/,2�����F����CY��Y��G��
����	��E��G�����CY��Y��H������	��E�
:6��0�����O����?w	���"�w�h���2�R���BI��2��&6�� J��2��6��K��2��6�������������������������!N��2��2��.��CY��Y��L����M����2����	��E�,,��N`��N��=<��2��,��O��P�W��J,��O��P�W��92��=��-��`6����CY��Y��Q��
����	��E���
R��2���	��S:��	�
YO��S	��B���
YOYO:��I	��S:	��S.66���.h6�����
YOY`dO:`6	��T��!N2	��A��2��+��CY��Y��L��
��M��2����	��E�,,��U`��U,��V
	��P�W�
:6��0������8���������(r���+W��2��6��X��2��6���������������������1	��Y
��P�W	��B�����Z��[\��]Y
SY��^S��_���0���:6����dd2S����:	��Y
��P�W��
:6���2��`O����	��S��	��Y
2��P�W��Za��b�����CY��Y��c��������	��E�,�����w����f�����������������������������'���0���>���H���K���q���t������������������������������������������������������������������������	����(��+��2��N�����������*8;DGLRUqt!~#�$�%�(�)�+�,�-�.�-�0�1�3�5�786<@>N@QB�D�E�K�M�N�O�P�QPSU'V.W9XFWLZS[V]gdohri�n�x���������������������6���������������d��������������%�����1������.�(�������������
������������y�z���������������������������������������~������{������x�����	�u�����
�'l������0c����������:��0�
�����������������������(��?������O��
-$	��"��-��='����!�����������������������������������������A��������������������������������&����-��������������	����������������u��v���!������	d��e��Z�����w����������������g���2��f�����?��h��:��i��$��j��"��k��l��m@PK
����d]Y ���*��*��+���org/autoplot/cefdatasource/DataSetOps.class�������3��
�#�J
�K�L�M�N��O�P�Q�������
��R��S
�T�U��V�W��X��Y��Z��[
��\
�T�]�^�_
��`
�K�a
�K�b
�T�c
�T�d�e�f
�T�O
�T�g�h�i�j�k�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�'Lorg/autoplot/cefdatasource/DataSetOps;�collapse�0(Lorg/das2/qds/QDataSet;)Lorg/das2/qds/DDataSet;�d�D�w�l�I�ssum�wsum�k�j�slice�Lorg/das2/qds/QDataSet;�i�result�Lorg/das2/qds/DDataSet;�ds�qube�[I�u�Lorg/das2/datum/Units;�fill�
StackMapTable�=�P�M�l�	collapse3�	collapse2�
SourceFile�DataSetOps.java�$�%�m�n�o�org/das2/qds/QDataSet�UNITS�p�q�org/das2/datum/Units�java/lang/Double�r�s�t�u�l�v�w�x�u�org/das2/qds/RankNDataSet�6�y�x�z�x�{�|�}�~������"java/lang/IllegalArgumentException�only rank 4 supported�$�������������������DEPEND_1�DEPEND_2�����only rank 3 supported�DEPEND_3�%org/autoplot/cefdatasource/DataSetOps�java/lang/Object�org/das2/qds/DDataSet�org/das2/qds/DataSetUtil�qubeDims�(Lorg/das2/qds/QDataSet;)[I�property�&(Ljava/lang/String;)Ljava/lang/Object;�
getFillDouble�()D�rank�()I�createRank3�(III)Lorg/das2/qds/DDataSet;�length�(I)Lorg/das2/qds/QDataSet;�(I)I�(II)I�value�(III)D�isValid�(D)Z�putValue�(IIID)V�(Ljava/lang/String;)V�
getProperties�((Lorg/das2/qds/QDataSet;)Ljava/util/Map;�
putProperties�7(Ljava/util/Map;Lorg/das2/qds/MutablePropertyDataSet;)V�createRank2�(II)Lorg/das2/qds/DDataSet;�(IID)V�putProperty�'(Ljava/lang/String;Ljava/lang/Object;)V�!�"�#�������$�%��&���/�����*�������'��������(��������)�*���	�+�,��&�������*��M*�����N-��	���-��
9*������,.,.,.��L6*��
����*�����:6��
����6		�����y9
96*�����<*	���9-��-������9
kc9
c9���������
o9
+	
���	�����j���I��
��Y���*��+��+�����'���f���������!��+� �8�!�F�"�S�#�b�$�s�%�v�&�y�'���(���)���*���+���'���-���.���$���#���!���3�6
�8�(��������%�-�.�����/�.��|�H�0�1��v�m�2�.�
�y�j�3�.��e���4�1�	�V���5�1��S���6�7��;���8�1��8���9�:����;�7���
�9�:���<�=�����>�?��!���@�.��A���p�����B�CC����D�E�B�C�����D������)@��D����������D��B�C����	��D�E�B�C���	�F�,��&��T������*��M*�����N-��	���-��
9*������,.,.��L6*��
����6*�����t99
6*�����<*���9
-��-
������9
kc9
c9
����
�����
o9+���������p*��+��++������
��Y ���+�����'���^����B��C��D�!�F�+�G�5�H�C�I�T�J�W�K�Z�L�i�M�w�N���O���P���L���R���S���I���H���V���W���Z���\�(�����
�w�%�-�.�
����/�.��]�E�5�1��W�h�2�.��Z�e�3�.�
�F��4�1��8���8�1��5���9�:������;�7������9�:�����<�=�����>�?��!���@�.��A���f�����B�CC����D�E�B�C����
����&@��D��������D��B�C����	��D�E�B�C���	�G�,��&�������*��M*�����N-��	���-��
9*������,.,.,.��L6*��
����*�����:6��
����6		�����y9
96�����=	���9-��-������9
kc9
c9���������
o9
+	
���	��}���h���G*��+��++!������
��Y���+�����'���j����f��g��h�!�j�+�k�8�l�F�m�S�n�b�o�u�p�x�q�{�r���s���t���u���v���r���x���y���o���n���l���}���~�����(��������%�-�.�����/�.��~�H�4�1��x�m�2�.�
�{�j�3�.��e���0�1�	�V���5�1��S���6�7��;���8�1��8���9�:����;�7����9�:���<�=��	�>�?��!���@�.��A���p�����B�CC����D�E�B�C�����D������)@��D����������D��B�C����	��D�E�B�C����H����IPK
����d]Y���������2���org/autoplot/cefdatasource/DoubleFieldParser.class�������3�
��
������<init>�()V�Code�LineNumberTable�LocalVariableTable�this�.Lorg/autoplot/cefdatasource/DoubleFieldParser;�
parseField�(Ljava/nio/ByteBuffer;II)D�bbuf�Ljava/nio/ByteBuffer;�offset�I�length�
SourceFile�DoubleFieldParser.java������,org/autoplot/cefdatasource/DoubleFieldParser�java/lang/Object�&org/autoplot/cefdatasource/FieldParser�'org/autoplot/cefdatasource/DoubleParser�parseDoubleByteArray�!���������������/�����*�������	��������
�������������
������O�����+�������	��������
���*��������������������������������PK
����d]Y]H�Ԉ�����-���org/autoplot/cefdatasource/DoubleParser.class�������3�a
��?
�@�A
�B�C
�@�D
�E�F�G
��H�I��������J����������������������
�K�L
��M�N@$������
�O�P�Q�R�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�)Lorg/autoplot/cefdatasource/DoubleParser;�match�,(Ljava/lang/String;Ljava/nio/ByteBuffer;II)Z�i�I�str�Ljava/lang/String;�csq�Ljava/nio/ByteBuffer;�start�length�
StackMapTable�parseDoubleByteArray�(Ljava/nio/ByteBuffer;II)D�tmp�J�digit�
isNegativeExp�Z�fin�c�C�
isNegative�decimal�decimalPoint�fractionLength�exp�
Exceptions�
SourceFile�DoubleParser.java���S�+�T�U�V�W�X�Y�Z�[�\�NaN�"�#�java/lang/Double�Infinity�java/lang/NumberFormatException�Too many digits - Overflow��]�Exponent Overflow�^�_�`�'org/autoplot/cefdatasource/DoubleParser�java/lang/Object�java/lang/String�()I�java/nio/ByteBuffer�get�(I)B�charAt�(I)C�java/lang/Character�isWhitespace�(C)Z�(Ljava/lang/String;)V�java/lang/Math�pow�(DD)D�!���������������/�����*��������������
��������� �!���
�"�#�����������/6*����$`��+`��*������������������������%��'��-�����4���*�$�%����/�&�'�����/�(�)����/�*�%����/�+�%��,������!���	�-�.����������>`6*���6������*����6���N��*�����	�-����6��
+�����*���6I��*������	�����	76	0d6

��/

��(�i
�a7���
��Y���7��.��"	��6	�����*���6�����u7	��	dd��6
6���E��
e���*����6-����6��
+�����*���60d6

��@

��9
h
`6��
��Y���6�����*���6�����t6��
d���k����������/��������� �+�#�=�$�A�(�O�)�d�*�l�.��0���4���5���7���8���9���:���;���>���?���@���E���F���I���J���L���M���P
�S�T$�U/�V=�WR�XZ�\a�]m�^w�_~�`��c��h��i��l��m��o��p��u����������/�0����T�1�%�
w��/�%�a�?�1�%�
=�p�2�3�����(�)������*�%�����+�%����$�%����4�%����5�6��Oo�7�3���-�8�0���*�9�%�	
���:�%�
���;�%��,���G���
@��
B�����0����
	
@��@��
��-����
��	�<�������=����>PK
����d]Y1K�|��������,���org/autoplot/cefdatasource/FieldParser.class�������3��	�
�
parseField�(Ljava/nio/ByteBuffer;II)D�
Exceptions��
SourceFile�FieldParser.java�&org/autoplot/cefdatasource/FieldParser�java/lang/Object�java/text/ParseException����������������������PK
����d]Y�Ϝآ�����.���org/autoplot/cefdatasource/IsoTimeParser.class�������3�l
��L	��M	��N@$������
�O�P	��Q�B��%hY����`�
�R�S
�T�U�V�W
��X
��Y
��Z
��[	��\����֓��������������B@�]�^�_�
decimalPlaces�I�
microsMult�cacheTag�[B�cacheMicros�J�<init>�(I)V�Code�LineNumberTable�LocalVariableTable�this�*Lorg/autoplot/cefdatasource/IsoTimeParser;�readPositiveInt�([BII)I�i�buf�offset�length�result�
StackMapTable�microsSince2000�(III)J�year�month�day�jd�
parseField�(Ljava/nio/ByteBuffer;II)D�bbuf�Ljava/nio/ByteBuffer;�useCache�Z�fin�hour�minute�second�micros�microsOffset�"�]�`�
Exceptions�
SourceFile�IsoTimeParser.java�%�a�!�"���b�c�d� ��`�e�f�g�h�i�java/text/ParseException�java/lang/String�%�j�%�k�,�-�4�5�#�$�(org/autoplot/cefdatasource/IsoTimeParser�java/lang/Object�&org/autoplot/cefdatasource/FieldParser�java/nio/ByteBuffer�()V�java/lang/Math�pow�(DD)D�array�()[B�java/lang/Character�isWhitespace�(I)Z�([BII)V�(Ljava/lang/String;I)V�!�������������� ������!�"�����#�$�����%�&��'���f�����"*��*
���*��*�d�����������(��������������!��)�������"�*�+�����"�����,�-��'���������&66��
h+`30d`6���������(��������������#� �)���>����.�����&�*�+�����&�/�"����&�0�����&�1����#�2���3���
�������4�5��'���������Boh	`l`hld	dl`dl`hldh	l```	d6��
i�����(���
����$�:�'�)���4����B�*�+�����B�6�����B�7�����B�8���:��9���!�:�;��'�����
��%+��:6`6��3��
��	����`*��`����Y��Y�����6��$
��`3*��3��6������R*��6*`��6*`��6	6


��*��

`3T�
���**	����*`��6*`��6*`��6	*��*`*����h6
��i��ia	��ia
�a7*��a������(���f����+��-�	�0��1�$�3�2�4�F�7�U�9�f�:�i�8�o�=�t�>�~�?���@���A���B���A���D���E���H���I���J���K���L�N�)������I�&�.������.��
�~�E�6�����9�7�����,�8��	��%�*�+����%�<�=���%�0����%�1����/�"��	�>�?���@�����U�A�����H�B�����;�C��	���&�D��
�	�E�$��3���2�	���F!������*��G�H�F������
�I�������J����KPK
����d]YQز*����.���org/autoplot/cefdatasource/ReformDataSet.class�������3��
�,�m
�/�n	�,�o��p	�,�q	�,�r��s�t�u
��v	�w�x�y�z��{
�w�|�}	�,�~
���	�,����
���
�����
�������
���
����
����	�,��	�,��	�,��	�,�������
�,��
����
���������	�,��
����
������
����
���������dsLen1�I�n0�n1�n2�n3�sizes�[I�offset�rank�ds�Lorg/das2/qds/QDataSet;�<init>�(Lorg/das2/qds/QDataSet;[I)V�Code�LineNumberTable�LocalVariableTable�this�*Lorg/autoplot/cefdatasource/ReformDataSet;�(Lorg/das2/qds/QDataSet;I[I)V�i�ssizes�Ljava/lang/StringBuilder;�dep0�
StackMapTable���y�8���()I�value�(I)D�(II)D�i0�i1�(III)D�i2�(IIII)D�i3�property�&(Ljava/lang/String;)Ljava/lang/Object;�name�Ljava/lang/String;�length�(I)I�(II)I�j�(III)I�k�slice�(I)Lorg/das2/qds/QDataSet;�dim�newSizes�result�props�Ljava/util/Map;�LocalVariableTypeTable�5Ljava/util/Map<Ljava/lang/String;Ljava/lang/Object;>;�
SourceFile�ReformDataSet.java�=�D�=���;�<�\�]�1�2�9�2�:�N�"java/lang/IllegalArgumentException�input rank must==2�=���������org/das2/qds/QDataSet�QUBE�X�Y�����dataset must be marked as QUBE�:�2�������7�8�java/lang/StringBuilder�=�������,�����Hsizes=[%s] imply dataset with rank %d, which is not currently supported.�java/lang/Object�����������������3�2�4�2�5�2�6�2�DEPEND_0�\�N���������������DEPEND_1�O�Q���������������(org/autoplot/cefdatasource/ReformDataSet�����������org/das2/qds/AbstractDataSet�org/das2/qds/RankNDataSet�()V�(Ljava/lang/String;)V�java/lang/Boolean�TRUE�Ljava/lang/Boolean;�equals�(Ljava/lang/Object;)Z�java/util/Arrays�copyOf�([II)[I�(I)V�append�(I)Ljava/lang/StringBuilder;�-(Ljava/lang/String;)Ljava/lang/StringBuilder;�toString�()Ljava/lang/String;�java/lang/Integer�valueOf�(I)Ljava/lang/Integer;�java/lang/String�format�9(Ljava/lang/String;[Ljava/lang/Object;)Ljava/lang/String;�putProperty�'(Ljava/lang/String;Ljava/lang/Object;)V�org/das2/qds/DataSetUtil�
getProperties�((Lorg/das2/qds/QDataSet;)Ljava/util/Map;�
putProperties�7(Ljava/util/Map;Lorg/das2/qds/MutablePropertyDataSet;)V�
properties�Ljava/util/HashMap;�java/util/HashMap�containsKey�get�&(Ljava/lang/Object;)Ljava/lang/Object;�org/das2/qds/DataSetOps�sliceProperties0�!(ILjava/util/Map;)Ljava/util/Map;�sliceProperties�8(Lorg/das2/qds/QDataSet;ILjava/util/Map;)Ljava/util/Map;�!�,�/��0�	���1�2�����3�2�����4�2�����5�2�����6�2�����7�8�����9�2����:�2����;�<���
��=�>��?���J�����*+,�������@���
����#��$�A��� �����B�C������;�<�����7�8���=�D��?��!����*��*+��*+�����*��+�����
��Y	��
���+
�������
��Y��
�*-���*--�����*����X��Y
��-.��:6*������-.��W�����Y��Y��SY*����S����
�*-.��*����
*-.��*����
*-.�� *����
*-.��!+"�����:��-.+��#���*"��$+��%*��&*'��$�����@���r����&��(�	�)��+��-�#�.�-�1�>�2�H�5�N�6�X�8�`�9�q�:���;���>���?���@���B���C���E���F���J���K���L�M�Q�R�S�A���H��t��E�2��q�D�F�G����B�C�����;�<����9�2����7�8����)�H�<��I���*�	��-��J�K�L����+�M����"��%�K��:�N��?���/�����*�������@�������V�A��������B�C����O�P��?���J�����*��*��p*��l��(������@�������[�A��������B�C������E�2���O�Q��?���p�����$*��*��h``>*��*��l*��p��(������@���
����`��a�A���*����$�B�C�����$�R�2����$�S�2����E�2���O�T��?���������3*��*��h*�� h`*�� h``6*��*��l*��p��(������@���
����f��g�A���4����3�B�C�����3�R�2����3�S�2����3�U�2����E�2���O�V��?���������E*��*��h*�� h*��!h`*�� h*��!h`*��!h``6*��*��l*��p��(������@���
����l�-�m�A���>����E�B�C�����E�R�2����E�S�2����E�U�2����E�W�2��-��E�2���X�Y��?���d�����*��)+��*��*��)+��+�*��+��������@�������r��s��u�A��������B�C������Z�[��I������\�N��?���/�����*�������@�������{�A��������B�C����\�]��?���9�����*�������@���������A��������B�C������E�2���\�^��?���C�����*�� �����@���������A��� �����B�C������E�2�����_�2���\�`��?���M�����*��!�����@���������A���*�����B�C������E�2�����_�2�����a�2���b�c��?�������h*��d�
M*��>*��d��%,*��`.O*Y��*��`.h�����׻�,Y*��*��,��N*��%��-:*��.:-��&-�����@���.������	���������%���6���<���M���W���`���f���A���>���,�E�2����h�B�C�����h�d�2��	�_�e�8��M��f�C��W��g�h��i�����W��g�j��I�������L��+��k����lPK
����d]Y�Q�K/��/��.���org/autoplot/cefdatasource/TestCefReader.class�������3��
�'�O	�P�Q�R�S
��T
��U
�V�W
�X�Y
�Z�[�\�]�^�_�`�a
��O�b
��c
��Y
��d�e
��f
�g�h
�P�i�j
��O
��k�l
��m�n
��O
��o�p�q�r
�Z�s
�t�u�v�w�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�*Lorg/autoplot/cefdatasource/TestCefReader;�main�([Ljava/lang/String;)V�args�[Ljava/lang/String;�file1�Ljava/lang/String;�file2�file3�file4�file5�file�Ljava/io/File;�fileSize�J�in�Ljava/io/InputStream;�channel�'Ljava/nio/channels/ReadableByteChannel;�t0�reader�,Lorg/autoplot/cefdatasource/CefReaderHeader;�cef� Lorg/autoplot/cefdatasource/Cef;�result�Lorg/das2/qds/QDataSet;�dt�ds�
Exceptions�x�y�
SourceFile�TestCefReader.java�(�)�z�{�|�java/io/File�../..�(�}�~������������������}�C1_CP_EDI_EGD__20050212_V03.cef�C1_CP_EDI_EGD__20050217_V03.cef�C1_PP_CIS__20020707_V03.cef�EC1_CP_PEA_CP3DXPH_DNFlux__20020811_140000_20020811_150000_V061018.cef�EC1_CP_PEA_CP3DXPH_DNFlux__20020811_140000_20020811_141000_V061018.cef�java/lang/StringBuilder�../../../data/cef/���������java/io/FileInputStream�(�������������*org/autoplot/cefdatasource/CefReaderHeader�����time to read Cef header (ms): �����(org/autoplot/cefdatasource/CefReaderData�����time to read Cef data (ms): �  (� KB/sec)�����������(org/autoplot/cefdatasource/TestCefReader�java/lang/Object�java/io/IOException�java/text/ParseException�java/lang/System�err�Ljava/io/PrintStream;�(Ljava/lang/String;)V�toURI�()Ljava/net/URI;�java/net/URI�toURL�()Ljava/net/URL;�java/net/URL�toString�()Ljava/lang/String;�java/io/PrintStream�println�append�-(Ljava/lang/String;)Ljava/lang/StringBuilder;�length�()J�(Ljava/io/File;)V�java/nio/channels/Channels�
newChannel�>(Ljava/io/InputStream;)Ljava/nio/channels/ReadableByteChannel;�currentTimeMillis�read�I(Ljava/nio/channels/ReadableByteChannel;)Lorg/autoplot/cefdatasource/Cef;�(J)Ljava/lang/StringBuilder;�cefReadData�n(Ljava/nio/channels/ReadableByteChannel;Lorg/autoplot/cefdatasource/Cef;)Lorg/das2/qds/MutablePropertyDataSet;�(Ljava/lang/Object;)V�org/das2/qds/DataSetOps�slice1�?(Lorg/das2/qds/QDataSet;I)Lorg/das2/qds/MutablePropertyDataSet;�!�&�'�������(�)��*���/�����*�������+��������,��������-�.���	�/�0��*������������Y����������	
LMN
::��Y��Y����������:��7��Y��:		��:
��7��Y��:


��:����Y������e������	��Y��
�� :��e7����Y��!����"��m��#������	����$��%:�����+���R���������� �!�!�%�"�)�$�F�%�M�'�X�(�_�*�d�,�m�.�v�0���2���4���5���7���9���<�,����������1�2������3�4�����5�4��!���6�4��%���7�4��)���8�4��F���9�:��M���;�<��X���=�>�	�_���?�@�
�d���A�<��m�|�B�C�
�v�s�D�E����E�F�G����=�H�<�����I�G��J�����K�L��M����NPK
����d]Y�	M�;��;��4���org/autoplot/cefdatasource/caa_cef_read_20070820.BAK; *******************************************************************
; PROJECT:      ESA Cluster Active Archive
; COMPONENT:    Cluster Exchange Format
; MODULE:       IDL CEF Reader
; LANGUAGE:     IDL 6.3
; AUTHOR:       c.h.perry@rl.ac.uk
; DATE:         2007-08-16
;
; Description:
; This is a preliminary simple IDL based reader for CAA data downloaded
; in the Cluster Exchange Format (CEF-2). This is an ALPHA release and
; there are some known limitations which mean that it may fall over
; when reading some correctly formatted CEF files.
;
; To try and maximise the speed little syntax checking is performed,
; and if you supply an invalid CEF the most likely outcome is that
; the software will fall over! If you are only using CEF files 
; obtained from the CAA then these should already have been syntax
; checked and you should not encounter problems with the majority
; of data sets.
;
; The software is 100% IDL so has the advantage that it should run 
; on any platform that supports IDL. Of course the disadvantage of
; an IDL only solution is performance when reading the ASCII CEF
; format. Some testing has been performed on Linux and PC but not 
; yet on Mac or other platforms. As a benchmark, on the test systems
; the software will read CEF files at about 1-2 MB/s so if you have
; a 20 MB file it will take about 10-20s to read.

; This is is still an Alpha release so you may encounter problems. 
; If you do, PLEASE REPORT THEM so that we can try and resolve them 
; for all users!
;
; Usage:
;   result = cef_read( [filename], [/NODATA], [/JULDAY], [/CDFEPOCH] )
;
; If filename is not supplied then a file selection widget will be
; displayed.
; The result is an array of pointers to parameter structure containing
; the data and associated global and variable metadata.
; If /NODATA is used then the global metadata as a top level structure.
; If the /NODATA flag is not used then the global metadata is copied
; into each of the indivdual parameter sub-structures along with a
; DATA element that contains the actual data values. The result
; array therefore only consists of a set of pointers to a parameter
; structures.
; By default time will be returned as the source ASCII time string
; but you can use the /JULDAY or /CDFEPOCH keywords in which case
; the DATA element will be returned as a DOUBLE and contain the
; converted time.
;
; Example:
;   result = cef_read('fgm.cef.gz')
;    (time to read 93MB compressed file on test system 3m09s)
;
;    then:
;   FOR i=0, N_ELEMENTS(result)-1 DO PRINT, i,': ',(*result(i)).VARNAME
;    gives:
;       0: time_tags__C1_CP_FGM_FULL
;       1: half_interval__C1_CP_FGM_FULL
;       2: B_vec_xyz_gse__C1_CP_FGM_FULL
;       3: B_mag__C1_CP_FGM_FULL
;       4: sc_pos_xyz_gse__C1_CP_FGM_FULL
;       5: range__C1_CP_FGM_FULL
;       6: tm__C1_CP_FGM_FULL
;
;       HELP, (*result(0)).DATA, (*result(2)).DATA
;       <Expression>    DOUBLE    = Array[1, 5122157]
;       <Expression>    FLOAT     = Array[3, 5122157]
;
; *******************************************************************
; $Id: caa_cef_read.pro,v 2.6 2007/08/22 08:54:54 cperry Exp cperry $
; *******************************************************************
; *******************************************************************
; $Log: caa_cef_read.pro,v $
; Revision 2.6  2007/08/22 08:54:54  cperry
; Fixed problem with dimensioning of multi-dimensional arrays.
; See TN-0016 for details on how multi-dimensional arrays
; should be accessed using this software.
;
; *******************************************************************

; *************************************************************************************
;+
; NAME:
;   CaaNotify
;
; PURPOSE:
;   Currently this is just a dummy error message handling routine.
;   It just prints out the supplied string and if the error flag
;   was raised then it STOPs allowing the developer to investigate
;   the problem.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   CaaNotify, <Err String>, [ /ERROR ], [ /WARN ], [/DEBUG], [ /QUIET ]
;
; INPUTS:
;   <Err String>    The string to be printed on stdout
;
; KEYWORD PARAMETERS:
;   /ERROR   Halt the program
;   /WARN     (not currently used)
;   /DEBUG   Debugging message (need to set QUIET=-1 to view
;   /QUIET   /QUIET switches off all but ERR and WARN
;      use QUIET=0 to re-enable standard messages
;
; OUTPUTS:
;   None
;
; EXAMPLE:
;
;   CaaNotify, 'File not found', /ERROR
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
PRO caanotify, message, ERROR=err, WARN=warn, DEBUG=dbug, QUIET=ql

    COMMON caanotify_cb, quiet_level

    IF ( N_ELEMENTS(quiet_level) EQ 0 ) THEN quiet_level = 0
    IF ( N_ELEMENTS(ql) GT 0 ) THEN quiet_level = ql

    IF ( N_ELEMENTS(message) GT 0 ) THEN BEGIN
    	IF ( quiet_level LE 2 AND KEYWORD_SET(err) )      THEN PRINT, "ERROR: "+message $
    	ELSE IF ( quiet_level LE 1 AND KEYWORD_SET(warn) ) THEN PRINT, "WARN:  "+message $
    	ELSE IF ( quiet_level LE -1 AND KEYWORD_SET(dbug)) THEN PRINT, "DEBUG: "+systime()+" - "+message $
    	ELSE IF ( quiet_level LE 0 AND NOT KEYWORD_SET(dbug))   THEN PRINT, "INFO:  "+message
    ENDIF

    IF (KEYWORD_SET(err)) THEN message, message
END


; *************************************************************************************
;+
; NAME:
;   Iso2CdfEpoch
;
; PURPOSE:
;   Function to convert a STRARR of standard ISO times into a
;   corresponding DOUBLE array containing CDFepoch times.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   result = Iso2CdfEpoch( <input> )
;
; INPUTS:
;   <input>         A STRARR of ISO times (YYYY-MM-DDTHH:MM:SS.sssZ)
;
; KEYWORD PARAMETERS:
;   None
;
; OUTPUTS:
;   <result>       A DBLARR of CDFepoch times
;
; EXAMPLE:
;
;   epoch = Iso2CdfEpoch( [ '2001-01-01T00:00:00', '2001-05-14T23:45:01' ] )
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
FUNCTION iso2cdfepoch, iso

    ; *** Get the number of elements in the input array ***
    n  = N_ELEMENTS(iso)

    ; *** Create a DBL array to hold the result CDF epoch values
    epoch = DBLARR(1,n)

    ; *** Convert each input string to the corresponding CDF epoch value
    FOR i=0L, n-1 DO BEGIN
       READS, iso(i), y, m, d, hr, mn, sc, $
         FORMAT="(I4.4,X,I2.2,X,I2.2,X,I2.2,X,I2.2,X,F)"
       ms = ((hr*60.0+mn)*60.0+sc)*1000.0
       CDF_EPOCH, ep, y, m, d, 0, 0, 0, ms, /COMPUTE
       epoch(0,i) = ep
    ENDFOR

    ; *** Return the result ***
    RETURN, epoch
END


; *************************************************************************************
;+
; NAME:
;   Iso2Julday
;
; PURPOSE:
;   Function to convert and STRARR of standard ISO times into a
;   corresponding DOUBLE array containing Julian Dates.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   result = Iso2Julday( <input> )
;
; INPUTS:
;   <input>             A STRARR of ISO times (YYYY-MM-DDTHH:MM:SS.sssZ)
;
; KEYWORD PARAMETERS:
;   None
;
; OUTPUTS:
;   <result>            A DBLARR of Julian Days
;
; EXAMPLE:
;
;   epoch = Iso2Julday( [ '2001-01-01T00:00:00', '2001-05-14T23:45:01' ] )
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
FUNCTION iso2julday, iso

        ; *** Get the number of elements in the input array ***
        n  = N_ELEMENTS(iso)

        ; *** We are assuming that we have a fully specified time! ***
        nf = N_ELEMENTS(STRSPLIT(iso(0),'-:TZ'))

        ; *** Join and then split array into required elements ***
        iso1 = REFORM(STRSPLIT(STRJOIN(iso,',',/SINGLE),'-:TZ,',/EXTRACT),nf,n)

        ; *** Convert to Julian day. NB: Month, Day, Year, Hour, Min, Sec
        RETURN, JULDAY(iso1(1,*),iso1(2,*),iso1(0,*),iso1(3,*),iso1(4,*),iso1(5,*))
END


; *************************************************************************************
;+
; NAME:
;   FilterNames
;
; PURPOSE:
;   Procedure to select which var names are to be extracted from the file.
;   By default the search is done on the var name but an alternative
;   metadata item can be specified (e.g. CATDESC) by using the SEARCHTAG
;   keyword. By default any variables referenced (e.g. DEPEND_0) are also
;   selected. This can be switched off with the /NODEPEND keyword.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   FilterNames, cef, varnames, /NODEPEND, SEARCHTAG='CATDESC'
;
; INPUTS:
;   cef             The cef structure that contains the metadata
;   varnames        A STRARR that contains a set of search terms
;                   used to select variables. Standard wildcards
;                   can be specified.
;
; KEYWORD PARAMETERS:
;   /NODEPEND       Don't try to include dependent variables
;   SEARCHTAG       The metadata item to search instead of varname
;
; OUTPUTS:
;   None            The REC_TYPE parameter attribute is updated in the
;                   cef structure
;
; EXAMPLE:
;
;   FilterNames, cef, ['B*']
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
PRO FilterNames, cef, varnames, NODEPEND=nr_flag, SEARCHTAG=stag

    IF (N_ELEMENTS(stag) NE 1) THEN stag='VARNAME'
    stag = STRUPCASE(STRTRIM(stag,2))

    tags = TAG_NAMES(cef)
    vidx = WHERE(STRMID(tags,0,6) EQ 'PARAM_', nvar)

    dep_tags = ['DEPEND_0', 'DEPEND_1', 'DEPEND_2', 'DEPEND_3', $
       'DELTA_PLUS', 'DELTA_MINUS' ]
    ndtags = N_ELEMENTS(dep_tags)

    ;*** If no variables detected then no point in continuing
    IF (nvar EQ 0 ) THEN RETURN

    ;*** Initialise the table var names
    vars  = STRARR(nvar)
    varsd = STRARR(nvar)
    flags = INTARR(nvar)

    FOR i=0,nvar-1 DO BEGIN
       vtags = TAG_NAMES(cef.(vidx(i)))
       sidx  = WHERE(vtags EQ stag, sc)
       IF (sc EQ 1) THEN vars(i) = cef.(vidx(i)).(sidx(0))
       varsd(i) = cef.(vidx(i)).VARNAME
    ENDFOR

    ;*** Search for vars that match requested input
    FOR i=0,N_ELEMENTS(varnames)-1 DO $
       flags = flags + STRMATCH(vars, varnames(i), /FOLD_CASE)

    ;*** Check if we need to look for dependencies
    IF ( NOT KEYWORD_SET(nr_flag) ) THEN BEGIN
       ;*** Take the vars that match our request
       nmatch1 = 0
       idx = WHERE(flags GT 0, nmatch)
       WHILE( nmatch1 LT nmatch ) DO BEGIN
          ;*** For each of these matches
          FOR j=0,nmatch-1 DO BEGIN

              ;*** Check the metadata items
              vtags = TAG_NAMES(cef.(vidx(idx(j))))

              ;*** For each of the tags that may contain a reference
              FOR k=0,ndtags-1 DO BEGIN

                  ;*** See if this tag is included for this var
                  didx = WHERE( vtags EQ dep_tags(k), dn )
                  IF ( dn GT 0 ) THEN BEGIN

                      ;*** Check that its a simple string attribute
                      ;*** If so then check it against our var list
                      IF (N_ELEMENTS(cef.(vidx(idx(j))).(didx[0])) EQ 1 $
                          AND SIZE(cef.(vidx(idx(j))).(didx[0]),/TYPE) EQ 7 ) THEN $
                          flags = flags + STRMATCH(varsd, cef.(vidx(idx(j))).(didx[0]), /FOLD_CASE)
                  ENDIF
              ENDFOR
          ENDFOR
          nmatch1 = nmatch
          idx = WHERE(flags GT 0, nmatch)
       ENDWHILE
    ENDIF

    ;*** Disable parameters that we don't want to keep
    FOR i=0,nvar-1 DO IF (flags(i) LE 0) THEN cef.(vidx(i)).REC_TYPE=-99

END

; *************************************************************************************
;+
; NAME:
;   FindInclude
;
; PURPOSE:
;   Function to try and resolve an include file name by checking
;   the ':' seperated list of include directories given by the
;   environment variable CEF_INCLUDE. If no match is found then
;   an error is generated.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   result = FindInclude( <input> )
;
; INPUTS:
;   <input>             A string containing the include filename
;
; KEYWORD PARAMETERS:
;   None
;
; OUTPUTS:
;   <result>            The fully resolved directory/filename
;
; EXAMPLE:
;
;   epoch = FindInclude( 'test.ceh' )
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************

FUNCTION FindInclude, inc_name

    ; *** Get the list of include directories from the environment variable
    inc_dirs = [STRSPLIT(GETENV('CEF_INCLUDE'),':',/EXTRACT)]

    flag = 0     ; *** =0 if no match, 1 if match is found
    i    = 0     ; *** index into array of includ directories

    ; *** Look for includ file in the include directories

    WHILE( flag EQ 0 AND i LT N_ELEMENTS(inc_dirs) ) DO BEGIN
       fname = FILEPATH( inc_name, ROOT=inc_dirs(i) )
       IF ( inc_dirs(i) NE '' AND FILE_TEST( fname, /READ ) ) THEN $
             flag = 1 $
       ELSE  i = i + 1
    ENDWHILE

    ; *** Found a match!
    IF ( flag EQ 1 ) THEN RETURN, fname

    ; *** Didn't find a match
    CaaNotify, "Include file not found: "+inc_name, /ERR

    RETURN, inc_name
END

; *************************************************************************************
;+
; NAME:
;   CefSplitRec
;
; PURPOSE:
;   Just splits a CEF header record into its key and value parts
;   using the first '=' in the record as the delimiter. The key
;   part is converted to upper case to ease comparison. The value
;   is split into an array of elements separated by ','. If the
;   elements are quoted strings then the quotes are removed.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   <status> = CefSplitRec( <record>, <key>, <value> )
;
; INPUTS:
;   <record>       The CEF header record being processed
;
; KEYWORD PARAMETERS:
;   None.
;
; OUTPUTS:
;   <status>       The function returns 1 if successful and 0 otherwise
;   <key>          The key part of the 'key = value'
;   <value>        The value part of the 'key = value'
;
; EXAMPLE:
;
;   IF ( CefSplitRec( 'VALUE_TYPE = FLOAT', key, value ) ) THEN PRINT, key, value
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
FUNCTION CefSplitRec, record, key, val

    status = 0     ;*** Set default status

    ; *** look for comment
    pos = STRPOS( record, '!', /REVERSE_SEARCH )
    IF ( pos GT -1 ) THEN record = STRMID(record,0,pos-1)

    ; *** look for key/value delimiter ***
    pos = STRPOS( record, '=' )
    IF ( pos GT -1 ) THEN BEGIN
       status = 1

       ;*** Extract the key ***
       key = STRUPCASE(STRTRIM(STRMID(record,0,pos),2))

       ;*** Extract the value ***
       val = STRTRIM(STRMID(record,pos+1),2)

       ;*** Split value into separate array elements
       ;*** Handle quoted string elements

       IF (STRMID(val,0,1) EQ '"') THEN BEGIN
           val = STRSPLIT(STRMID(val,1,STRLEN(val)-2), $
               '"[ '+STRING(9B)+']*,[ '+STRING(9B)+']*"',/REGEX, /EXTRACT)
       ENDIF ELSE BEGIN
           val = STRTRIM(STRSPLIT(val,',',/EXTRACT),2)
       ENDELSE
    ENDIF

    RETURN, status
END


; *************************************************************************************
;+
; NAME:
;   CefReadHeadRec
;
; PURPOSE:
;   Reads the next CEF header line from the specified unit. If a continuation
;   marker is encountered then the next line is read and appended to the
;   the record. Comment lines are ignored.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   <status> = CefReadHeadRec( <logical-unit>, <output-record> )
;
; INPUTS:
;   <logical-unit>        The logical unit which is connected to the input file
;
; KEYWORD PARAMETERS:
;   None.
;
; OUTPUTS:
;   <status>         1 if header record was extracted and 0 if EOF is reached.
;   <output-record>   A string that contains the full header record
;
; EXAMPLE:
;
;   IF ( CefReadHeadRec( lun, record ) ) THEN PRINT, record
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
FUNCTION CefReadHeadRec, lun, record

    status = 0     ; *** Status flag, set to 1 if complete record found
    readFlag = 1     ; *** used to flag multi-line records
    record = ''       ; *** String used to hold input

    ;*** Keep reading unit until got complete entry or end of file ***
    WHILE ( readFlag AND (NOT EOF(lun)) ) DO BEGIN

       ;*** read next record ***
       tempRecord = ''
       READF, lun, tempRecord

       tempRecord = STRTRIM(tempRecord, 2)   ;*** Trim blanks from start/end

       ;*** skip comment lines ***
       IF (STRMID(tempRecord,0,1) EQ '!' ) THEN BEGIN
         ; PRINT, tempRecord
       ENDIF ELSE IF ( STRMID(tempRecord, 0, 1, /REVERSE) EQ '\' ) THEN BEGIN
           record = record + STRMID(tempRecord,0,STRLEN(tempRecord)-1)
       ENDIF ELSE BEGIN
           record = record + tempRecord
           ; *** If not blank then finish read  of this record ***
           IF ( STRTRIM(record, 2) NE '' ) THEN BEGIN
               readFlag = 0
               status = 1
           ENDIF ELSE record = ''
       ENDELSE

    ENDWHILE

    RETURN, status
END


; *************************************************************************************
;+
; NAME:
;   CefReadData
;
; PURPOSE:
;   Reads the data part of a CEF file. It is assumed that the logical unit points
;   to the start of the first record to be read from the file. To maximise performace
;   there is no error checking so if it hits a file that it does not like then it
;   will probably fall over. Note that if it does fall over then there maybe some
;   very large unreferenced heap variables left over. To garbage collect these do a
;   RETALL then HEAP_GC,/VER or exit from IDL and then restart. Use HELP,/MEM if
;   you are unsure as to how much memory IDL is currently using.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   CefReadData, <lun>, <cef>, <param>
;
; INPUTS:
;   <lun>     Logical unit connected to the input file
;   <cef>     The structure containing the header information
;
; KEYWORD PARAMETERS:
;   /JULDAY     Returns times in Julian day rather than string
;   /CDFEPOCH     Returns times in CDF epoch rather than string
;   /NOCONV     No conversion. Leave all data fields as strings.
;
; OUTPUTS:
;   <param>     The output array containing pointers to the parameter data
;
; EXAMPLE:
;
;   CefReadData, lun, cef, param
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
PRO CefReadData, lun, cef, param, TRANGE=trange, $
    JULDAY=jd_flag, CDFEPOCH=ep_flag, NOCONV=nc_flag

    CaaNotify, 'Reading data records, please wait...'

    ; *** Define the read buffer that we'll use to pull in chunks
    ; *** of the file. This is a trade off between memory footprint
    ; *** and speed. Note that the working buffer is twice this size.
    ; *** The buffer size should be much bigger than the typical
    ; *** record size or perfromance will be worse than just reading
    ; *** a records at a time.
    buffer_size = 2000000L
    read_buffer = BYTARR(buffer_size)
    work_buffer = BYTARR(2*buffer_size)
    work_size   = 0L

    ; *** Define the delimeters used in the CEF file
    comment=(BYTE('!'))[0]
    eor=(BYTE(cef.EOR))[0]
    comma=(BYTE(','))[0]
    eol=10B

    ; *** Build a new CEF structure so that we can modify the parameter
    ; *** sub-structures.
    ceftags = TAG_NAMES(cef)
    FOR i=0, N_ELEMENTS(ceftags) - 1 DO BEGIN
       IF ( i EQ 0 ) THEN cef1 = CREATE_STRUCT(ceftags(i), cef.(i)) $
       ELSE IF ( STRMID(ceftags(i),0,6) NE 'PARAM_' ) THEN $
           cef1 = CREATE_STRUCT( cef1, ceftags(i), cef.(i))
    ENDFOR

    cef1.nparam =1        ;*** set nparam to 1 when it is added to the parameter data

    ; *** Set the processing state flag (1=first record, 2=subsequent records, 0 = end of file )
    flag     = 1     ;*** set to 1 for first page, 2 for subsequent pages and 0 when read to end of file
    trflag   = 1     ;*** set to 0 if no more data required in requested time range
    n_rec    = 0     ;*** number of records read
    n_fields = 0     ;*** number of fields per record

    ; *** Keep reading until we reach the end of the file.
    WHILE( NOT EOF(lun) AND trflag GT 0 ) DO BEGIN

       ;*** read the next chunk of the file
       ;*** catch errors to avoid warning message if we read past end of file
       ON_IOERROR, skip
       READU, lun, read_buffer
skip:  ON_IOERROR, NULL

       ;*** calculate how much data we've read
       IF ( read_buffer(buffer_size - 1) NE 0B ) THEN read_size = buffer_size $
       ELSE read_size=(WHERE(read_buffer EQ 0B))[0]

       ;*** transfer this onto the end of the work buffer and update size of work buffer
       IF (read_size GT 0 ) THEN work_buffer[work_size] = $
           read_buffer[0:read_size-1]
       work_size = work_size + read_size

       ;*** look for delimeters, EOR, comments, EOL etc

       pos_eor = WHERE( work_buffer(0:work_size-1) EQ eor, n_eor )
       IF ( n_eor GT 0 ) THEN BEGIN
           pos1 = pos_eor(n_eor-1)+1
           pos2 = work_size-1
           work_size = pos1-1
       ENDIF ELSE BREAK

       pos_comment = WHERE( work_buffer(0:work_size-1) EQ comment, n_comment )

       pos_eol = WHERE( work_buffer(0:work_size-1) EQ eol, n_eol )

       ;*** search for blank lines and remove (only important if eol is also eor)
       ;*** DEBUG - this has not yet been tested and is currently disabled
       ;idx_el = WHERE( idx2(1:c-1)-idx2(0:c-2) LE 10, c1 )
       ;IF (c1 GT 0) THEN $
       ; FOR i=0L, c1-1 DO buf(idx2(idx2a(i)+1)) = 32B

       ;*** remove comment lines by setting to spaces (32B)
       IF (n_comment GT 0 ) THEN BEGIN
           FOR i=0L, n_comment-1 DO BEGIN
               j = pos_comment(i)
               WHILE( work_buffer(j) NE eol ) DO BEGIN
                   work_buffer(j) = 32B
                   j = j+1
               ENDWHILE
               work_buffer(j) = 32B
           ENDFOR
       ENDIF

       ;*** remove eol by setting to spaces (32B)
       IF (n_eol GT 0 ) THEN work_buffer(pos_eol) = 32B

       ;*** we replace all eor with comma so we can quickly split the buffer
       ;*** this assumes that the data is well formed with the same number
       ;*** of fields on every record.
       work_buffer(pos_eor) = comma

       ;*** work out number of fields per record by counting commas up to first eor
       IF ( n_fields EQ 0 ) THEN temp = WHERE( work_buffer(0:pos_eor(0)) EQ comma, n_fields )

       ;*** split the buffer into separate fields
       fields    = STRTRIM(STRSPLIT(STRING(work_buffer(0:work_size-1)), ',', /EXTRACT),2)
        
       nt_fields = N_ELEMENTS(fields)
       if ( fields[nt_fields-1] eq '' ) then begin   ; test_read_caa(2)
          fields= fields[0:nt_fields-2]
          nt_fields = N_ELEMENTS(fields)
       endif
       

       ;*** reform the to a num_fields x num_rec array
       IF ( (nt_fields MOD n_fields) NE 0 ) THEN CaaNotify, "Bad number of fields - truncated file?",/ERR
       fields = REFORM(fields, n_fields, N_ELEMENTS(fields)/n_fields, /OVERWRITE )
       n_recp = N_ELEMENTS(fields)/n_fields

       ;*** see if we want to subset the data range
       IF ( N_ELEMENTS(trange) GT 0 ) THEN BEGIN
            ridx   = LONARR(n_recp)
	    trflag = 0
            FOR it=0,N_ELEMENTS(trange)-1 DO BEGIN
                ts = STRSPLIT(trange[it],'/',/EXTRACT)
                idx1 = WHERE(fields(0,*) GE ts(0) AND fields(0,*) LT ts(1), tcount)
                IF ( tcount GT 0 ) THEN ridx(idx1)=ridx(idx1)+1
		IF ( fields(0,n_recp-1) LT ts(1) ) THEN trflag = trflag + 1
            ENDFOR
            ridx = WHERE( ridx GT 0, tcount )
            IF ( tcount LE 0 ) THEN GOTO, skip1
       ENDIF ELSE ridx = LINDGEN(n_recp)

       n_rec = n_rec + N_ELEMENTS(ridx)
       CaaNotify, "Reading data, "+fields(0,0)+" to "+fields(0,n_recp-1)+" Stored rec #:"+STRING(n_rec), /DEBUG

       tmp_dpa = PTRARR(cef.nparam)

       FOR i = 0, cef.nparam-1 DO BEGIN
           name = STRING('PARAM_',i+1, FORMAT='(A,I3.3)')
           idx  = (WHERE(ceftags EQ name))[0]

           ;IF ( i GT 0 ) THEN cef.(idx).REC_TYPE = -2

           IF ( cef.(idx).REC_TYPE GT 0 ) THEN BEGIN
               IF ( KEYWORD_SET(nc_flag) ) THEN vt = 'CHAR' ELSE vt = cef.(idx).VALUE_TYPE

               s1 = cef.(idx).CEF_FIELD_POS(0)
               s2 = cef.(idx).CEF_FIELD_POS(1)

               CASE vt OF
                   'CHAR':         tmp_dpa(i) = PTR_NEW(fields[s1:s2,ridx])
                   'DOUBLE':       tmp_dpa(i) = PTR_NEW(DOUBLE(fields[s1:s2,ridx]),/NO_COPY)
                   'FLOAT':        tmp_dpa(i) = PTR_NEW(FLOAT(fields[s1:s2,ridx]),/NO_COPY)
                   'INT':          tmp_dpa(i) = PTR_NEW(LONG(fields[s1:s2,ridx]),/NO_COPY)
                   'ISO_TIME':     IF (KEYWORD_SET(jd_flag) ) THEN  $
                                       tmp_dpa(i) = PTR_NEW(iso2julday(fields[s1:s2,ridx]),/NO_COPY)  $
                                   ELSE IF (KEYWORD_SET(ep_flag) ) THEN $
                                       tmp_dpa(i) = PTR_NEW(iso2cdfepoch(fields[s1:s2,ridx]),/NO_COPY)  $
                                   ELSE tmp_dpa(i) = PTR_NEW(fields[s1:s2,ridx])
                   'ISO_TIME_RANGE': tmp_dpa(i) = PTR_NEW(fields[s1:s2,ridx])
                   ELSE:           tmp_dpa(i) = PTR_NEW(fields[s1:s2,ridx])
               ENDCASE
           ENDIF
       ENDFOR

       IF ( flag EQ 2 ) THEN dpa = [ [dpa], [TEMPORARY(tmp_dpa)] ] $
       ELSE BEGIN
           flag = 2
           dpa = REFORM(TEMPORARY(tmp_dpa),cef.nparam,1)
       ENDELSE

       ;*** we want to keep the part of the buffer not yet processed
skip1: IF (pos2-pos1 GE 0 ) THEN BEGIN
           work_buffer(0) = work_buffer(pos1:pos2)
           work_size = pos2-pos1+1
       ENDIF ELSE work_size = 0

       ;*** keep going until there is no more file to read
       IF ( read_size LT buffer_size ) THEN flag = 0

    ENDWHILE

    ;*** Finished with input file
    FREE_LUN, lun

    ;*** Release memory used by the work and read buffers
    work_buffer = 0
    read_buffer = 0

    ;*** Build the result array - we've read all the data so we know how many records there are!
    cef1.nrec = n_rec  ;*** Store the number of records in the metadata structure
    cef.nrec  = n_rec


    ;*** For each parameter build a metadata/data struture
    ;*** In theory we could filter out parameters that we don't want
    ;*** which would save processing time and memory. Ideally we would
    ;*** also do that above when we generate the dpa pointers.
    IF ( N_ELEMENTS(dpa) GT 0 ) THEN npage = (SIZE(dpa,/DIM))[1] ELSE npage =0
    flag = 0

    FOR i = 0, cef.nparam-1 DO BEGIN

        name = STRING('PARAM_',i+1, FORMAT='(A,I3.3)')
        idx  = (WHERE(ceftags EQ name))[0]
        pstru = CREATE_STRUCT(cef1, cef.(idx))

        ;*** Hack so we don't fall over if we get an empty file
        ;*** REC_TYPE: -2=no rec, -1=param disabled, 0=non-record vary, 1=normal
        IF ( n_rec EQ 0 AND pstru.REC_TYPE GT 0 ) THEN BEGIN
            pstru.REC_TYPE = -2
            pstru.nrec = 0
        ENDIF

        IF ( pstru.REC_TYPE GT 0 ) THEN BEGIN ;***For record varying parameters ***

            ;*** Check value type for conversion
            IF ( KEYWORD_SET(nc_flag) ) THEN vt = 'CHAR' ELSE vt = pstru.VALUE_TYPE

            CaaNotify, "Creating data array for "+pstru.VARNAME, /DEBUG
            ;*** Create the DATA array ***
            CASE vt OF

               'CHAR':    pstru = CREATE_STRUCT( pstru, 'DATA', STRARR([pstru.SIZES, n_rec]) )
               'DOUBLE':  pstru = CREATE_STRUCT( psrtu, 'DATA', DBLARR([pstru.SIZES, n_rec]) )
               'FLOAT':   pstru = CREATE_STRUCT( pstru, 'DATA', FLTARR([pstru.SIZES, n_rec]) )
               'INT':     pstru = CREATE_STRUCT( pstru, 'DATA', LONARR([pstru.SIZES, n_rec]) )
               'ISO_TIME':  IF ( KEYWORD_SET(jd_flag) OR KEYWORD_SET(ep_FLAG) ) THEN $
                                  pstru = CREATE_STRUCT( pstru, 'DATA', DBLARR([pstru.SIZES, n_rec]) ) $
                            ELSE  pstru = CREATE_STRUCT( pstru, 'DATA', STRARR([pstru.SIZES, n_rec]) )
               'ISO_TIME_RANGE':pstru = CREATE_STRUCT( pstru, 'DATA', STRARR([pstru.SIZES, n_rec]) )
               ELSE:     pstru = CREATE_STRUCT( pstru, 'DATA', STRARR([pstru.SIZES, n_rec]) )
            ENDCASE

            ;*** Fill the arrays ***
            dpos = 0L         ;*** Current record number
            s    = pstru.CEF_FIELD_POS(1) - pstru.CEF_FIELD_POS(0) + 1

            ;*** Check value type for conversion

            ;*** For each of data pages that we've read
            FOR j=0, npage-1 DO BEGIN
		siz = SIZE(*dpa(i,j),/DIM)
                IF (N_ELEMENTS(siz) EQ 2 ) THEN pn  = siz(1) ELSE pn = 1   ;*** Number of records in this block ***
                p1  = dpos*s        ;*** Start psoition
                p2  = p1 + pn*s - 1   ;*** End position
                pstru.DATA[p1:p2] = *dpa(i,j)
                PTR_FREE, dpa(i,j)

                dpos = dpos+pn       ;*** Update record position

            ENDFOR
        ENDIF

        ;*** Create the output array as a collection of the parameter strutures
        IF ( pstru.REC_TYPE GT -99 ) THEN BEGIN
            IF ( flag EQ 0 ) THEN param = [ PTR_NEW(pstru, /NO_COPY) ] $
            ELSE param = [ param, PTR_NEW(pstru, /NO_COPY) ]
            flag = flag + 1
        ENDIF
    ENDFOR

    ;*** Make sure we don't leave any unwanted storage allocated
    IF (N_ELEMENTS(dpa) GT 0) THEN HEAP_FREE, dpa

    CaaNotify, "Reading of data complete", /DEBUG
END

;==============================================================================================
; *** START OF PUBLIC ROUTINES
;==============================================================================================

; *************************************************************************************
;+
; NAME:
;   cef_get_attr
;
; PURPOSE:
;   Returns the requested attribute from the variable
;
; CATEGORY:
;   Public-Support
;
; CALLING SEQUENCE:
;
;   <result> = cef_get_attr( vararr, varid, attr, STATUS=status )
;
; INPUTS:
;   vararr	The variable pointer array returned from cef_read
;   varid	The variable index. This can be either the index number
;		for the variable array element in vararr or the name of
;		the variable.
;   attr	The attribute name to be searched for
;
; KEYWORD PARAMETERS:
;   STATUS=stat Returns the status of the search 
;		-1 If the variable could not be identified
;		-2 If the attribute was not found
;		1 If a unique match was found
;		2 If multiple attributes match, only the first is returned
;
; OUTPUTS:
;   <results>   Either the attribute from the requested variable or an empty string.
;
; EXAMPLE:
;
;   result = cef_get_attr( vararr, 0, 'VARNAME')
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************

FUNCTION cef_get_attr, varptr, varid, attr, STATUS=status

	status = 0

	; *** If varid given as STRING then need to work out varptr index
	IF ( SIZE(varid,/TYPE) EQ 7 ) THEN BEGIN
		varidx = -1
		FOR i = 0, N_ELEMENTS(varptr)-1 DO BEGIN
			IF ( STRMATCH(cef_get_attr(varptr, i, 'VARNAME'), varid, /FOLD_CASE) ) THEN BEGIN
				varidx = i
				BREAK
			ENDIF
		ENDFOR
	ENDIF ELSE BEGIN
		IF ( varid GE 0 AND varid LT N_ELEMENTS(varptr) ) THEN varidx = varid $
		ELSE varidx = -1
	ENDELSE

	; *** Check if we found a variable
	IF ( varidx LT 0 ) THEN BEGIN
		CaaNotify, 'Request for attribute from unknown variable: '+varid, /DEBUG
		status = -1
		RETURN, ''
	ENDIF

	; *** Now check for attribute
	tags = TAG_NAMES(*varptr(varidx))
	idx  = WHERE(STRMATCH(tags, attr, /FOLD_CASE), count)

	IF ( count EQ 0 ) THEN BEGIN		;*** No matches, return empty string and set status
		status = -2
		RETURN, ''
	ENDIF ELSE IF ( count EQ 1 ) THEN BEGIN	;*** One match
		status = 1
		RETURN, (*varptr(varidx)).(idx(0))
	ENDIF ELSE BEGIN			;*** Multiple matches, just return first but set status
		status = 2
		RETURN, (*varptr(varidx)).(idx(0))
	ENDELSE
END 

; *************************************************************************************
;+
; NAME:
;   cef_read
;
; PURPOSE:
;   Read a CEF file into an IDL struture
;
; CATEGORY:
;   Public-Support
;
; CALLING SEQUENCE:
;
;   <result> cef_read( [filename], [INCLUDE=cef], [/NODATA], [/JULDAY], [/CDFEPOCH] )
;
; INPUTS:
;   filename   Filename of CEF to be read. If not supplied a file selection
;      		widget is displayed. CEF or Gzip'd CEF can be specified.
;
; KEYWORD PARAMETERS:
;   VAR=[names]     Array of regular expression of names to match. By default
;      all variables will be returned.
;   INCLUDE=cef     [PRIVATE] Used for recursive reading of include files.
;   /NODEPEND     Normally any depend variables will be included even if
;      not explicitly requested. Use this option to disable
;      the inclusion of any referenced variables.
;   /NODATA     Only read header information
;   /JULDAY     Returns times in Julian Days rather than the default iso string
;   /CDFEPOCH     Returns times in CDF EPOCH rather than the default iso string
;
; OUTPUTS:
;   <results>     An array (or structure, when /NODATA) that contains the result
;
; EXAMPLE:
;
;   result = cef_read( 'fgm.cef' )
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
FUNCTION cef_read, readFile, INCLUDE=cef, NODATA=nd_flag, VAR=vnames, $
        NODEPEND=nr_flag, SEARCHTAG=stag, _EXTRA=extra

       HEAP_GC,/VER

       ;*** If the header structure is not yet defined then create it
       IF (N_ELEMENTS(cef) EQ 0) THEN cef = { ERROR: 0, NGLOBAL:0, NPARAM:0, NREC:0L, EOR:10B }

       ;*** Check flags
       IF ( NOT KEYWORD_SET(nr_flag) ) THEN nr_flag = 0
       nv_flag = N_ELEMENTS(vnames)

       ;*** If a file is not specified ask user to pick one
       IF ( NOT KEYWORD_SET(readFile)) THEN $
           readFile=DIALOG_PICKFILE(FILTER="*.cef;*.cef.gz", /READ, /MUST_EXIST)

       ;*** Make sure the input file is accessible
       IF (NOT FILE_TEST(readFile, /READ)) THEN BEGIN
            CaaNotify,"Can't open or read file "+readFile+" for import", /ERROR
            cef.ERROR = 1
            RETURN, cef
       ENDIF

       ;*** Set result to dummy value
       param = -1

       CaaNotify, "Reading "+readFile

       ;*** Look at file extension to determine if it is a compressed file
       IF ( STRUPCASE(STRMID(readFile,2,3,/REVERSE)) EQ ".GZ" ) THEN $
            compressFlag = 1 $
       ELSE compressFlag = 0

       ; *** Open the file ***
       OPENR, lun, readFile, /GET_LUN, COMPRESS=compressFlag, ERROR=err
       IF ( err NE 0 ) THEN BEGIN
            dummy = DIALOG_MESSAGE(!ERROR_STATE.MSG, /ERROR)
            cef.ERROR = 1
            RETURN, cef
       ENDIF

       ; *** Set the initial state of the header parser ***
       state  = "TOP"
       state1 = "END"

       ; *** data index
       pdata = 0

       ; *** Keep reading until end of header information or no more records ***
       WHILE( state NE "DATA_READ" AND state NE "END" ) DO BEGIN

            ;*** Try to read header record
            IF ( NOT CefReadHeadRec(lun, record) ) THEN BREAK

            ; *** Get the keyword/value(s) for this record
            IF ( CefSplitRec(record, key, value) ) THEN BEGIN

                ;*** Use the parser state to check what we are looking for
                CASE state OF

                "TOP": BEGIN

                    ;*** Use the keyword to determine the action
                    CASE key OF

                    "START_META": BEGIN     ;*** New global metadata item ***
                        state = "GLOBAL"
                        gName = value[0]
                        gStru = { VALUE_TYPE: "CHAR" }
                        eCount  = 0
                    END


                    "START_VARIABLE": BEGIN     ;*** New parameter ***
                        state = "PARAM"
                        pName = value[0]
                        pStru = { REC_TYPE:1, VARNAME:pName }
                    END

                    "INCLUDE": IF ( value[0] NE readFile ) THEN $
                        param = cef_read(findinclude(value[0]), INCLUDE=cef, _EXTRA=extra)

                    "DATA_UNTIL": BEGIN     ;*** Start of data ***
                        state = "DATA_READ"
                        cef = CREATE_STRUCT( cef, 'DATA_UNTIL', value[0])
                    END

                    ;*** Special CEF defined items at the top level ***

                    "FILE_NAME": cef = CREATE_STRUCT( cef, 'FILE_NAME', value[0] )

                    "FILE_FORMAT_VERSION": cef = CREATE_STRUCT( cef, 'FILE_FORMAT_VERSION', value[0] )

                    "END_OF_RECORD_MARKER": cef.EOR = (BYTE(value[0]))[0]

                    ELSE: CaaNotify, "Unsupported key "+key,/ERR

                    ENDCASE
                END


                "GLOBAL": BEGIN        ;*** Global metadata handling

                    IF (N_ELEMENTS(value) GT 1) THEN $
                        CaaNotify, "Global entry not allowed multiple values per entry : "+gName,/ERR

                    CASE key OF
                    "END_META":   BEGIN
                        state = "TOP"
                        IF (value[0] NE gName) THEN $
                            CaaNotify, "END_VARIABLE expected "+gName+"  got "+value[0],/ERROR
                        IF ( ecount EQ 1 ) THEN gStru = CREATE_STRUCT( gStru, 'ENTRY', element[0] ) $
                        ELSE gStru = CREATE_STRUCT( gStru, 'ENTRY', element )
                        cef.nglobal = cef.nglobal+1
                        IF ( gstru.VALUE_TYPE EQ 'CHAR' ) THEN cef = CREATE_STRUCT( cef, gname, gStru.ENTRY ) $
                        ELSE cef = CREATE_STRUCT( cef, gname, gStru )
                    END
                    ; *** WARNING: In theory CEF allows a different VALUE_TYPE for each entry
                    ; *** this is a 'feature' from CDF but I can't think of a situation where
                    ; *** it is useful. This feature is not currently supported by this
                    ; *** software and so we just assign a type based on the last specification
                    ; *** of the VALUE_TYPE.
                    "VALUE_TYPE": gStru.VALUE_TYPE = value[0]
                    "ENTRY": BEGIN
                         ; *** If this is the second entry then must be multi entry global ***
                         IF ( eCount EQ 0 ) THEN element = [ value[0] ] $
                         ELSE element = [ element, value[0] ]

                         eCount = eCount + 1
                    END
                    ELSE: CaaNotify, "Unsupported global key "+key  , /ERR
                    ENDCASE
                END

                "PARAM": BEGIN       ;*** Parameter description handling
                    IF ( key EQ "END_VARIABLE") THEN BEGIN
                        ;*** Set some defaults if not provided in the file
                        tags = TAG_NAMES(pStru)
                        id = WHERE( tags EQ 'SIZES', c )
                        IF ( c EQ 0 ) THEN pStru = CREATE_STRUCT( pStru, 'SIZES', 1L )  

                        IF (pStru.REC_TYPE EQ 0) THEN data_idx = [-1L,-1L] $
                        ELSE BEGIN
                            n = LONG(pstru.SIZES[0])
                            FOR i=1, N_ELEMENTS(pstru.SIZES)-1 DO n = n * LONG(pstru.SIZES[i])
                            data_idx = [pdata,pdata+n-1]
                            pdata = pdata+n
                        ENDELSE
                        pStru = CREATE_STRUCT(pStru, 'CEF_FIELD_POS', data_idx)
                        ;*** Change parser state
                        state = "TOP"
                        ;*** Check this is the end of the correct parameter!
                        IF (value[0] NE pName) THEN $
                           CaaNotify, "END_VARIABLE expected "+pName+"  got "+value[0],/ERROR
                        ;*** Update the number of parameters
                        cef.nparam = cef.nparam + 1
                        ;*** Parameter names can be too long for structure element name
                        ;*** so just use a sequential number
                        pname = STRING('PARAM_',cef.nparam, FORMAT='(A,I3.3)')
                        cef = CREATE_STRUCT( cef, pname, pStru )

                    ENDIF ELSE BEGIN
                        IF ( key EQ 'DATA' ) THEN BEGIN
                            pStru.REC_TYPE = 0   ;*** Flag non-record varying data
                            ;********************************
                            ;At the moment we just add non-record varying data as string array
                            ;we should really check SIZES and VALUE_TYPE and reform and retype
                            ;data as we do for the real data fields. Something for the next release?
                            ;********************************
                        ENDIF ELSE IF ( key EQ 'SIZES' AND N_ELEMENTS(value) GT 1 ) THEN BEGIN
				value = REVERSE( value )
			ENDIF

                        IF (N_ELEMENTS(value) GT 1 ) THEN pStru = CREATE_STRUCT( pstru, key, value ) $
                        ELSE pStru = CREATE_STRUCT( pStru, key, value[0] )
                    ENDELSE
                END

                ENDCASE
            ENDIF ELSE CaaNotify, "Bad record?  "+record, /ERROR
       ENDWHILE

       ;*** Finished reading the header in the current file
       ;*** if state is END then we are at the end of the file
       ;*** for example this may be the end of an include file
       ;*** If the state is DATA_READ then we've reached the
       ;*** end of the header and are currently pointed at the
       ;*** start of the actual data!

       IF ( state EQ "DATA_READ" ) THEN BEGIN

            ;*** Check if not all vars are to be returned.
            IF (nv_flag GT 0) THEN filterNames, cef, vnames, NODEPEND=nr_flag, SEARCHTAG=stag

            IF ( KEYWORD_SET(nd_flag) ) THEN param = cef $
            ELSE BEGIN
                CefReadData, lun, cef, param, _EXTRA=extra
            ENDELSE
       ENDIF

       ;*** Done with this file so close it
       FREE_LUN, lun
       CaaNotify, "Finished reading "+readFile

       ;*** Return the result
       RETURN, param
END



;########################## EXAMPLES ############################

PRO example1

    ;*** When using pointers its a good idea garbage collect
    ;*** any allocated memory that is no longer referenced
    HEAP_GC

    ;*** Read the CEF file. The JULDAY flag is used to get the
    ;*** times returned in MJD so that we can use the IDL
    ;*** LABEL_DATE function for easy time axis plotting.
    ;*** The TR lets us specify a time range for the interval
    ;*** to be returned.
    result = cef_read( 'cis.cef.gz', /JULDAY )

    FOR i=0,N_ELEMENTS(result)-1 DO BEGIN
       PRINT, STRTRIM(i,2)+ ':  '+ (*result(i)).VARNAME+ $
         ' ('+STRJOIN(STRTRIM((*result(i)).SIZES,2),',')+')'
       PRINT, '    ', (*result(i)).CATDESC
       PRINT
    ENDFOR

    np=3

    dummy = LABEL_DATE(DATE_FORMAT="%H:%I:%S!C%Y-%N-%D")

    PLOT, (*result(0)).DATA, (*result(np)).DATA,                   $
       YTITLE=(*result(np)).LABLAXIS + '!C' + (*result(np)).UNITS, $
       XSTYLE=1, XTICKUNITS='TIME', XTICKFORMAT='LABEL_DATE', $
       YRANGE=[0.001,1], /YLOG, PSYM=3

    ;*** We've finished with the data so free up the memory 
    HEAP_FREE, result
END



;################

    ;*** This is a slightly more advanced example that tries to plot 
    ;*** time series of all the returned data parameters. 
    ;*** This is just intended as an example! Don't expect it to 
    ;*** to produce sensible results with all products!

PRO example2, filename

	IF ( N_ELEMENTS(filename) EQ 0 ) THEN filename = 'cis.cef.gz'

	;*** Again we start by trying to free any unused space on the heap
	HEAP_GC

	;*** Read the data file
	result = cef_read( filename, /JULDAY )

	;*** Get the number of variables and create some arrays to hold
	;*** the names and status of the parameters
	n_var      = N_ELEMENTS(result)
	var_name   = STRARR(n_var)
	d_var      = INTARR(n_var)

	;*** First pass to extract var names and identify data variables
	;*** Note that we use the PARAMETER_TYPE attribute to ignore
	;*** support variables.
	FOR i = 0, n_var-1 DO BEGIN
		var_name(i) = cef_get_attr( result, i, 'VARNAME' )
		d_var(i)    = STRMATCH(cef_get_attr( result, i, 'PARAMETER_TYPE'),'DATA*',/FOLD_CASE)
		IF ( N_ELEMENTS(cef_get_attr( result, i, 'SIZES')) GT 1 ) THEN d_var(i) = 0
	ENDFOR


	;*** Now we are ready to do a second pass where we will produce the plot
	n_plots = TOTAL(d_var)		; *** Number of panels ***
	dy   = 0.90/n_plots		; *** Height of panels ***
	yoff = 0.05			; *** Vertical offset  ***
	dx   = 0.80			; *** Width of panels  ***
	xoff = 0.10			; *** Horizontal offset **

	;*** Use the DATASET_TITLE to label the plot
	title = cef_get_attr(result,0,'DATASET_TITLE') + '!C'+ $
		cef_get_attr(result,0,'INSTRUMENT_NAME') + '  -  ' + $
		cef_get_attr(result,0,'DATASET_ID')

	;*** Flag used with the NOERASE keyword on PLOT
	ne_flag = 0

	;*** Loop through each of the variables
	FOR i = 0, n_var-1 DO BEGIN

		;*** Check if this is a parameter to be plotted
		IF ( d_var(i) ) THEN BEGIN
			
			n_plots = n_plots - 1		;*** Update the panel count ***

			;*** If we are at the last panel we want a time axis otherwise we don't ***
			IF ( n_plots EQ 0 ) THEN dummy = LABEL_DATE(DATE_FORMAT="%H:%I:%S!C%Y-%N-%D") $
			ELSE dummy = LABEL_DATE(DATE_FORMAT=" ")

			;*** Set the plot position for this panel ***
			!P.POSITION=[ xoff, yoff+n_plots*dy, xoff+dx, yoff+(n_plots+0.98)*dy ]

			;*** Look for the DEPEND_0 - In the previous example we just
			;*** assumed that it was the first variable which should be
			;*** safe most of the time, but here we actually check!
			depend0 = WHERE( var_name EQ cef_get_attr(result,i,'DEPEND_0'), count )

			;*** If not found then skip to the next parameter
			IF ( count EQ 0 ) THEN BREAK

			;*** Look for fill values and replace with NaNs
			fillval = cef_get_attr(result,i,'FILLVAL', STATUS=status)
			IF ( status GT 0 ) THEN BEGIN
				idx = WHERE( (*result(i)).DATA EQ fillval, count )
				IF ( count GT 0 ) THEN (*result(i)).DATA(idx) = !VALUES.F_NAN
			ENDIF

			;*** Use MIN/MAX to determine data range
			v2 = MAX( (*result(i)).DATA, MIN=v1, /NAN )
			IF (v2 EQ v1) THEN v2 = v1 + 1.0

			;*** Based on data range decide if we want to do a log plot
			IF ( v1 GT 0 AND v2/v1 GT 50 AND (*result(i)).VALUE_TYPE EQ 'FLOAT' ) THEN ylog=1 ELSE ylog=0

			;*** Plot the panel
			PLOT, (*result(depend0(0))).DATA, (*result(i)).DATA(0,*), $
				YTITLE=cef_get_attr(result,i,'LABLAXIS') + '!C' + cef_get_attr(result,i,'UNITS'), $
				XTICKUNITS='TIME', XTICKFORMAT='LABEL_DATE', $
				YRANGE=[v1,v2], YLOG=ylog, TITLE=title, $
				NOERASE=ne_flag

			;*** If there are multiple components, overplot in the same panel
			IF ( FIX((*result(i)).SIZES) GT 1 ) THEN BEGIN
				FOR j=1,FIX((*result(i)).SIZES)-1 DO BEGIN
					OPLOT, (*result(depend0(0))).DATA, (*result(i)).DATA(j,*), LINESTYLE=j
				ENDFOR

				lab = cef_get_attr(result,i,'LABEL_1')
				IF ( N_ELEMENTS(lab) EQ 1 ) THEN lab = cef_get_attr(result,i,'REPRESENTATION_1')
				IF ( N_ELEMENTS(lab) EQ 1 ) THEN $
					lab = cef_get_attr(result,cef_get_attr(result,i,'DEPEND_1'),'DATA')
				FOR j=0, N_ELEMENTS(lab)-1 DO BEGIN
					x = xoff+dx+0.01
					y = yoff+(n_plots+1)*dy-(j+1)*0.015
					XYOUTS, x, y, lab(j), /NORM, CHARSIZE=0.75
					PLOTS, [x, x+0.05], [y-0.005,y-0.005], /NORM, LINESTYLE=j 

				ENDFOR
			ENDIF

			title = ''		;*** only want title on first panel      ***
			ne_flag = 1		;*** don't want to erase previous panels ***
		ENDIF
	ENDFOR

	XYOUTS, 0.01, 0.005, 'File ID: '+cef_get_attr(result,0,'LOGICAL_FILE_ID'), CHARSIZE=0.5, /NORM
	XYOUTS, 0.99, 0.005, 'Plotted: '+SYSTIME(), /NORM,ALIGN=1.0,CHARSIZE=0.5

	;*** Finished with the data so free the heap memory
	HEAP_FREE, result

	;*** Put plot position back to the default
	!P.POSITION=0
END

PK
����d]Y�0���������4���org/autoplot/cefdatasource/caa_cef_read_20070820.pro; *******************************************************************
; PROJECT:      ESA Cluster Active Archive
; COMPONENT:    Cluster Exchange Format
; MODULE:       IDL CEF Reader
; LANGUAGE:     IDL 6.3
; AUTHOR:       c.h.perry@rl.ac.uk
; DATE:         2007-08-16
;
; Description:
; This is a preliminary simple IDL based reader for CAA data downloaded
; in the Cluster Exchange Format (CEF-2). This is an ALPHA release and
; there are some known limitations which mean that it may fall over
; when reading some correctly formatted CEF files.
;
; To try and maximise the speed little syntax checking is performed,
; and if you supply an invalid CEF the most likely outcome is that
; the software will fall over! If you are only using CEF files
; obtained from the CAA then these should already have been syntax
; checked and you should not encounter problems with the majority
; of data sets.
;
; The software is 100% IDL so has the advantage that it should run
; on any platform that supports IDL. Of course the disadvantage of
; an IDL only solution is performance when reading the ASCII CEF
; format. Some testing has been performed on Linux and PC but not
; yet on Mac or other platforms. As a benchmark, on the test systems
; the software will read CEF files at about 1-2 MB/s so if you have
; a 20 MB file it will take about 10-20s to read.

; This is is still an Alpha release so you may encounter problems.
; If you do, PLEASE REPORT THEM so that we can try and resolve them
; for all users!
;
; Usage:
;   result = cef_read( [filename], [/NODATA], [/JULDAY], [/CDFEPOCH] )
;
; If filename is not supplied then a file selection widget will be
; displayed.
; The result is an array of pointers to parameter structure containing
; the data and associated global and variable metadata.
; If /NODATA is used then the global metadata as a top level structure.
; If the /NODATA flag is not used then the global metadata is copied
; into each of the indivdual parameter sub-structures along with a
; DATA element that contains the actual data values. The result
; array therefore only consists of a set of pointers to a parameter
; structures.
; By default time will be returned as the source ASCII time string
; but you can use the /JULDAY or /CDFEPOCH keywords in which case
; the DATA element will be returned as a DOUBLE and contain the
; converted time.
;
; Example:
;   result = cef_read('fgm.cef.gz')
;    (time to read 93MB compressed file on test system 3m09s)
;
;    then:
;   FOR i=0, N_ELEMENTS(result)-1 DO PRINT, i,': ',(*result(i)).VARNAME
;    gives:
;       0: time_tags__C1_CP_FGM_FULL
;       1: half_interval__C1_CP_FGM_FULL
;       2: B_vec_xyz_gse__C1_CP_FGM_FULL
;       3: B_mag__C1_CP_FGM_FULL
;       4: sc_pos_xyz_gse__C1_CP_FGM_FULL
;       5: range__C1_CP_FGM_FULL
;       6: tm__C1_CP_FGM_FULL
;
;       HELP, (*result(0)).DATA, (*result(2)).DATA
;       <Expression>    DOUBLE    = Array[1, 5122157]
;       <Expression>    FLOAT     = Array[3, 5122157]
;
; *******************************************************************
; $Id: caa_cef_read.pro,v 2.6 2007/08/22 08:54:54 cperry Exp cperry $
; *******************************************************************
; *******************************************************************
; $Log: caa_cef_read.pro,v $
; Revision 2.6  2007/08/22 08:54:54  cperry
; Fixed problem with dimensioning of multi-dimensional arrays.
; See TN-0016 for details on how multi-dimensional arrays
; should be accessed using this software.
;
; *******************************************************************

; *************************************************************************************
;+
; NAME:
;   CaaNotify
;
; PURPOSE:
;   Currently this is just a dummy error message handling routine.
;   It just prints out the supplied string and if the error flag
;   was raised then it STOPs allowing the developer to investigate
;   the problem.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   CaaNotify, <Err String>, [ /ERROR ], [ /WARN ], [/DEBUG], [ /QUIET ]
;
; INPUTS:
;   <Err String>    The string to be printed on stdout
;
; KEYWORD PARAMETERS:
;   /ERROR   Halt the program
;   /WARN     (not currently used)
;   /DEBUG   Debugging message (need to set QUIET=-1 to view
;   /QUIET   /QUIET switches off all but ERR and WARN
;      use QUIET=0 to re-enable standard messages
;
; OUTPUTS:
;   None
;
; EXAMPLE:
;
;   CaaNotify, 'File not found', /ERROR
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
PRO caanotify, message, ERROR=err, WARN=warn, DEBUG=dbug, QUIET=ql

    COMMON caanotify_cb, quiet_level

    IF ( N_ELEMENTS(quiet_level) EQ 0 ) THEN quiet_level = 0
    IF ( N_ELEMENTS(ql) GT 0 ) THEN quiet_level = ql

    IF ( N_ELEMENTS(message) GT 0 ) THEN BEGIN
        IF ( quiet_level LE 2 AND KEYWORD_SET(err) )      THEN PRINT, "ERROR: "+message $
        ELSE IF ( quiet_level LE 1 AND KEYWORD_SET(warn) ) THEN PRINT, "WARN:  "+message $
        ELSE IF ( quiet_level LE -1 AND KEYWORD_SET(dbug)) THEN PRINT, "DEBUG: "+systime()+" - "+message $
        ELSE IF ( quiet_level LE 0 AND NOT KEYWORD_SET(dbug))   THEN PRINT, "INFO:  "+message
    ENDIF

    IF (KEYWORD_SET(err)) THEN message, message
END


; *************************************************************************************
;+
; NAME:
;   Iso2CdfEpoch
;
; PURPOSE:
;   Function to convert a STRARR of standard ISO times into a
;   corresponding DOUBLE array containing CDFepoch times.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   result = Iso2CdfEpoch( <input> )
;
; INPUTS:
;   <input>         A STRARR of ISO times (YYYY-MM-DDTHH:MM:SS.sssZ)
;
; KEYWORD PARAMETERS:
;   None
;
; OUTPUTS:
;   <result>       A DBLARR of CDFepoch times
;
; EXAMPLE:
;
;   epoch = Iso2CdfEpoch( [ '2001-01-01T00:00:00', '2001-05-14T23:45:01' ] )
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
FUNCTION iso2cdfepoch, iso

    ; *** Get the number of elements in the input array ***
    n  = N_ELEMENTS(iso)

    ; *** Create a DBL array to hold the result CDF epoch values
    epoch = DBLARR(1,n)

    ; *** Convert each input string to the corresponding CDF epoch value
    FOR i=0L, n-1 DO BEGIN
       READS, iso(i), y, m, d, hr, mn, sc, $
         FORMAT="(I4.4,X,I2.2,X,I2.2,X,I2.2,X,I2.2,X,F)"
       ms = ((hr*60.0+mn)*60.0+sc)*1000.0
       CDF_EPOCH, ep, y, m, d, 0, 0, 0, ms, /COMPUTE
       epoch(0,i) = ep
    ENDFOR

    ; *** Return the result ***
    RETURN, epoch
END


; *************************************************************************************
;+
; NAME:
;   Iso2Julday
;
; PURPOSE:
;   Function to convert and STRARR of standard ISO times into a
;   corresponding DOUBLE array containing Julian Dates.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   result = Iso2Julday( <input> )
;
; INPUTS:
;   <input>             A STRARR of ISO times (YYYY-MM-DDTHH:MM:SS.sssZ)
;
; KEYWORD PARAMETERS:
;   None
;
; OUTPUTS:
;   <result>            A DBLARR of Julian Days
;
; EXAMPLE:
;
;   epoch = Iso2Julday( [ '2001-01-01T00:00:00', '2001-05-14T23:45:01' ] )
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
FUNCTION iso2julday, iso

        ; *** Get the number of elements in the input array ***
        n  = N_ELEMENTS(iso)

        ; *** We are assuming that we have a fully specified time! ***
        nf = N_ELEMENTS(STRSPLIT(iso(0),'-:TZ'))

        ; *** Join and then split array into required elements ***
        iso1 = REFORM(STRSPLIT(STRJOIN(iso,',',/SINGLE),'-:TZ,',/EXTRACT),nf,n)

        ; *** Convert to Julian day. NB: Month, Day, Year, Hour, Min, Sec
        RETURN, JULDAY(iso1(1,*),iso1(2,*),iso1(0,*),iso1(3,*),iso1(4,*),iso1(5,*))
END


; *************************************************************************************
;+
; NAME:
;   FilterNames
;
; PURPOSE:
;   Procedure to select which var names are to be extracted from the file.
;   By default the search is done on the var name but an alternative
;   metadata item can be specified (e.g. CATDESC) by using the SEARCHTAG
;   keyword. By default any variables referenced (e.g. DEPEND_0) are also
;   selected. This can be switched off with the /NODEPEND keyword.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   FilterNames, cef, varnames, /NODEPEND, SEARCHTAG='CATDESC'
;
; INPUTS:
;   cef             The cef structure that contains the metadata
;   varnames        A STRARR that contains a set of search terms
;                   used to select variables. Standard wildcards
;                   can be specified.
;
; KEYWORD PARAMETERS:
;   /NODEPEND       Don't try to include dependent variables
;   SEARCHTAG       The metadata item to search instead of varname
;
; OUTPUTS:
;   None            The REC_TYPE parameter attribute is updated in the
;                   cef structure
;
; EXAMPLE:
;
;   FilterNames, cef, ['B*']
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
PRO FilterNames, cef, varnames, NODEPEND=nr_flag, SEARCHTAG=stag

    IF (N_ELEMENTS(stag) NE 1) THEN stag='VARNAME'
    stag = STRUPCASE(STRTRIM(stag,2))

    tags = TAG_NAMES(cef)
    vidx = WHERE(STRMID(tags,0,6) EQ 'PARAM_', nvar)

    dep_tags = ['DEPEND_0', 'DEPEND_1', 'DEPEND_2', 'DEPEND_3', $
       'DELTA_PLUS', 'DELTA_MINUS' ]
    ndtags = N_ELEMENTS(dep_tags)

    ;*** If no variables detected then no point in continuing
    IF (nvar EQ 0 ) THEN RETURN

    ;*** Initialise the table var names
    vars  = STRARR(nvar)
    varsd = STRARR(nvar)
    flags = INTARR(nvar)

    FOR i=0,nvar-1 DO BEGIN
       vtags = TAG_NAMES(cef.(vidx(i)))
       sidx  = WHERE(vtags EQ stag, sc)
       IF (sc EQ 1) THEN vars(i) = cef.(vidx(i)).(sidx(0))
       varsd(i) = cef.(vidx(i)).VARNAME
    ENDFOR

    ;*** Search for vars that match requested input
    FOR i=0,N_ELEMENTS(varnames)-1 DO $
       flags = flags + STRMATCH(vars, varnames(i), /FOLD_CASE)

    ;*** Check if we need to look for dependencies
    IF ( NOT KEYWORD_SET(nr_flag) ) THEN BEGIN
       ;*** Take the vars that match our request
       nmatch1 = 0
       idx = WHERE(flags GT 0, nmatch)
       WHILE( nmatch1 LT nmatch ) DO BEGIN
          ;*** For each of these matches
          FOR j=0,nmatch-1 DO BEGIN

              ;*** Check the metadata items
              vtags = TAG_NAMES(cef.(vidx(idx(j))))

              ;*** For each of the tags that may contain a reference
              FOR k=0,ndtags-1 DO BEGIN

                  ;*** See if this tag is included for this var
                  didx = WHERE( vtags EQ dep_tags(k), dn )
                  IF ( dn GT 0 ) THEN BEGIN

                      ;*** Check that its a simple string attribute
                      ;*** If so then check it against our var list
                      IF (N_ELEMENTS(cef.(vidx(idx(j))).(didx[0])) EQ 1 $
                          AND SIZE(cef.(vidx(idx(j))).(didx[0]),/TYPE) EQ 7 ) THEN $
                          flags = flags + STRMATCH(varsd, cef.(vidx(idx(j))).(didx[0]), /FOLD_CASE)
                  ENDIF
              ENDFOR
          ENDFOR
          nmatch1 = nmatch
          idx = WHERE(flags GT 0, nmatch)
       ENDWHILE
    ENDIF

    ;*** Disable parameters that we don't want to keep
    FOR i=0,nvar-1 DO IF (flags(i) LE 0) THEN cef.(vidx(i)).REC_TYPE=-99

END

; *************************************************************************************
;+
; NAME:
;   FindInclude
;
; PURPOSE:
;   Function to try and resolve an include file name by checking
;   the ':' seperated list of include directories given by the
;   environment variable CEF_INCLUDE. If no match is found then
;   an error is generated.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   result = FindInclude( <input> )
;
; INPUTS:
;   <input>             A string containing the include filename
;
; KEYWORD PARAMETERS:
;   None
;
; OUTPUTS:
;   <result>            The fully resolved directory/filename
;
; EXAMPLE:
;
;   epoch = FindInclude( 'test.ceh' )
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************

FUNCTION FindInclude, inc_name

    ; *** Get the list of include directories from the environment variable
    inc_dirs = [STRSPLIT(GETENV('CEF_INCLUDE'),':',/EXTRACT)]

    flag = 0     ; *** =0 if no match, 1 if match is found
    i    = 0     ; *** index into array of includ directories

    ; *** Look for includ file in the include directories

    WHILE( flag EQ 0 AND i LT N_ELEMENTS(inc_dirs) ) DO BEGIN
       fname = FILEPATH( inc_name, ROOT=inc_dirs(i) )
       IF ( inc_dirs(i) NE '' AND FILE_TEST( fname, /READ ) ) THEN $
             flag = 1 $
       ELSE  i = i + 1
    ENDWHILE

    ; *** Found a match!
    IF ( flag EQ 1 ) THEN RETURN, fname

    ; *** Didn't find a match
    CaaNotify, "Include file not found: "+inc_name, /ERR

    RETURN, inc_name
END

; *************************************************************************************
;+
; NAME:
;   CefSplitRec
;
; PURPOSE:
;   Just splits a CEF header record into its key and value parts
;   using the first '=' in the record as the delimiter. The key
;   part is converted to upper case to ease comparison. The value
;   is split into an array of elements separated by ','. If the
;   elements are quoted strings then the quotes are removed.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   <status> = CefSplitRec( <record>, <key>, <value> )
;
; INPUTS:
;   <record>       The CEF header record being processed
;
; KEYWORD PARAMETERS:
;   None.
;
; OUTPUTS:
;   <status>       The function returns 1 if successful and 0 otherwise
;   <key>          The key part of the 'key = value'
;   <value>        The value part of the 'key = value'
;
; EXAMPLE:
;
;   IF ( CefSplitRec( 'VALUE_TYPE = FLOAT', key, value ) ) THEN PRINT, key, value
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
FUNCTION CefSplitRec, record, key, val

    status = 0     ;*** Set default status

    ; *** look for comment
    pos = STRPOS( record, '!', /REVERSE_SEARCH )
    IF ( pos GT -1 ) THEN record = STRMID(record,0,pos-1)

    ; *** look for key/value delimiter ***
    pos = STRPOS( record, '=' )
    IF ( pos GT -1 ) THEN BEGIN
       status = 1

       ;*** Extract the key ***
       key = STRUPCASE(STRTRIM(STRMID(record,0,pos),2))

       ;*** Extract the value ***
       val = STRTRIM(STRMID(record,pos+1),2)

       ;*** Split value into separate array elements
       ;*** Handle quoted string elements

       IF (STRMID(val,0,1) EQ '"') THEN BEGIN
           val = STRSPLIT(STRMID(val,1,STRLEN(val)-2), $
               '"[ '+STRING(9B)+']*,[ '+STRING(9B)+']*"',/REGEX, /EXTRACT)
       ENDIF ELSE BEGIN
           val = STRTRIM(STRSPLIT(val,',',/EXTRACT),2)
       ENDELSE
    ENDIF

    RETURN, status
END


; *************************************************************************************
;+
; NAME:
;   CefReadHeadRec
;
; PURPOSE:
;   Reads the next CEF header line from the specified unit. If a continuation
;   marker is encountered then the next line is read and appended to the
;   the record. Comment lines are ignored.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   <status> = CefReadHeadRec( <logical-unit>, <output-record> )
;
; INPUTS:
;   <logical-unit>        The logical unit which is connected to the input file
;
; KEYWORD PARAMETERS:
;   None.
;
; OUTPUTS:
;   <status>         1 if header record was extracted and 0 if EOF is reached.
;   <output-record>   A string that contains the full header record
;
; EXAMPLE:
;
;   IF ( CefReadHeadRec( lun, record ) ) THEN PRINT, record
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
FUNCTION CefReadHeadRec, lun, record

    status = 0     ; *** Status flag, set to 1 if complete record found
    readFlag = 1     ; *** used to flag multi-line records
    record = ''       ; *** String used to hold input

    ;*** Keep reading unit until got complete entry or end of file ***
    WHILE ( readFlag AND (NOT EOF(lun)) ) DO BEGIN

       ;*** read next record ***
       tempRecord = ''
       READF, lun, tempRecord

       tempRecord = STRTRIM(tempRecord, 2)   ;*** Trim blanks from start/end

       ;*** skip comment lines ***
       IF (STRMID(tempRecord,0,1) EQ '!' ) THEN BEGIN
         ; PRINT, tempRecord
       ENDIF ELSE IF ( STRMID(tempRecord, 0, 1, /REVERSE) EQ '\' ) THEN BEGIN
           record = record + STRMID(tempRecord,0,STRLEN(tempRecord)-1)
       ENDIF ELSE BEGIN
           record = record + tempRecord
           ; *** If not blank then finish read  of this record ***
           IF ( STRTRIM(record, 2) NE '' ) THEN BEGIN
               readFlag = 0
               status = 1
           ENDIF ELSE record = ''
       ENDELSE

    ENDWHILE

    RETURN, status
END


; *************************************************************************************
;+
; NAME:
;   CefReadData
;
; PURPOSE:
;   Reads the data part of a CEF file. It is assumed that the logical unit points
;   to the start of the first record to be read from the file. To maximise performace
;   there is no error checking so if it hits a file that it does not like then it
;   will probably fall over. Note that if it does fall over then there maybe some
;   very large unreferenced heap variables left over. To garbage collect these do a
;   RETALL then HEAP_GC,/VER or exit from IDL and then restart. Use HELP,/MEM if
;   you are unsure as to how much memory IDL is currently using.
;
; CATEGORY:
;   Private-Support.
;
; CALLING SEQUENCE:
;
;   CefReadData, <lun>, <cef>, <param>
;
; INPUTS:
;   <lun>     Logical unit connected to the input file
;   <cef>     The structure containing the header information
;
; KEYWORD PARAMETERS:
;   /JULDAY     Returns times in Julian day rather than string
;   /CDFEPOCH     Returns times in CDF epoch rather than string
;   /NOCONV     No conversion. Leave all data fields as strings.
;
; OUTPUTS:
;   <param>     The output array containing pointers to the parameter data
;
; EXAMPLE:
;
;   CefReadData, lun, cef, param
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
PRO CefReadData, lun, cef, param, TRANGE=trange, $
    JULDAY=jd_flag, CDFEPOCH=ep_flag, NOCONV=nc_flag

    CaaNotify, 'Reading data records, please wait...'

    ; *** Define the read buffer that we'll use to pull in chunks
    ; *** of the file. This is a trade off between memory footprint
    ; *** and speed. Note that the working buffer is twice this size.
    ; *** The buffer size should be much bigger than the typical
    ; *** record size or perfromance will be worse than just reading
    ; *** a records at a time.
    buffer_size = 2000000L
    read_buffer = BYTARR(buffer_size)
    work_buffer = BYTARR(2*buffer_size)
    work_size   = 0L

    ; *** Define the delimeters used in the CEF file
    comment=(BYTE('!'))[0]
    eor=(BYTE(cef.EOR))[0]
    comma=(BYTE(','))[0]
    eol=10B

    ; *** Build a new CEF structure so that we can modify the parameter
    ; *** sub-structures.
    ceftags = TAG_NAMES(cef)
    FOR i=0, N_ELEMENTS(ceftags) - 1 DO BEGIN
       IF ( i EQ 0 ) THEN cef1 = CREATE_STRUCT(ceftags(i), cef.(i)) $
       ELSE IF ( STRMID(ceftags(i),0,6) NE 'PARAM_' ) THEN $
           cef1 = CREATE_STRUCT( cef1, ceftags(i), cef.(i))
    ENDFOR

    cef1.nparam =1        ;*** set nparam to 1 when it is added to the parameter data

    ; *** Set the processing state flag (1=first record, 2=subsequent records, 0 = end of file )
    flag     = 1     ;*** set to 1 for first page, 2 for subsequent pages and 0 when read to end of file
    trflag   = 1     ;*** set to 0 if no more data required in requested time range
    n_rec    = 0     ;*** number of records read
    n_fields = 0     ;*** number of fields per record

    ; *** Keep reading until we reach the end of the file.
    WHILE( NOT EOF(lun) AND trflag GT 0 ) DO BEGIN

       ;*** read the next chunk of the file
       ;*** catch errors to avoid warning message if we read past end of file
       ON_IOERROR, skip
       READU, lun, read_buffer
skip:  ON_IOERROR, NULL

       ;*** calculate how much data we've read
       IF ( read_buffer(buffer_size - 1) NE 0B ) THEN read_size = buffer_size $
       ELSE read_size=(WHERE(read_buffer EQ 0B))[0]

       ;*** transfer this onto the end of the work buffer and update size of work buffer
       IF (read_size GT 0 ) THEN work_buffer[work_size] = $
           read_buffer[0:read_size-1]
       work_size = work_size + read_size

       ;*** look for delimeters, EOR, comments, EOL etc

       pos_eor = WHERE( work_buffer(0:work_size-1) EQ eor, n_eor )
       IF ( n_eor GT 0 ) THEN BEGIN
           pos1 = pos_eor(n_eor-1)+1
           pos2 = work_size-1
           work_size = pos1-1
       ENDIF ELSE BREAK

       pos_comment = WHERE( work_buffer(0:work_size-1) EQ comment, n_comment )

       pos_eol = WHERE( work_buffer(0:work_size-1) EQ eol, n_eol )

       ;*** search for blank lines and remove (only important if eol is also eor)
       ;*** DEBUG - this has not yet been tested and is currently disabled
       ;idx_el = WHERE( idx2(1:c-1)-idx2(0:c-2) LE 10, c1 )
       ;IF (c1 GT 0) THEN $
       ; FOR i=0L, c1-1 DO buf(idx2(idx2a(i)+1)) = 32B

       ;*** remove comment lines by setting to spaces (32B)
       IF (n_comment GT 0 ) THEN BEGIN
           FOR i=0L, n_comment-1 DO BEGIN
               j = pos_comment(i)
               WHILE( work_buffer(j) NE eol ) DO BEGIN
                   work_buffer(j) = 32B
                   j = j+1
               ENDWHILE
               work_buffer(j) = 32B
           ENDFOR
       ENDIF

       ;*** remove eol by setting to spaces (32B)
       IF (n_eol GT 0 ) THEN work_buffer(pos_eol) = 32B

       ;*** we replace all eor with comma so we can quickly split the buffer
       ;*** this assumes that the data is well formed with the same number
       ;*** of fields on every record.
       work_buffer(pos_eor) = comma

       ;*** work out number of fields per record by counting commas up to first eor
       IF ( n_fields EQ 0 ) THEN temp = WHERE( work_buffer(0:pos_eor(0)) EQ comma, n_fields )

       ;*** split the buffer into separate fields
       fields    = STRTRIM(STRSPLIT(STRING(work_buffer(0:work_size-1)), ',', /EXTRACT),2)

       nt_fields = N_ELEMENTS(fields)
       if ( fields[nt_fields-1] eq '' ) then begin   ; test_read_caa(2)
          fields= fields[0:nt_fields-2]
          nt_fields = N_ELEMENTS(fields)
       endif


       ;*** reform the to a num_fields x num_rec array
       IF ( (nt_fields MOD n_fields) NE 0 ) THEN CaaNotify, "Bad number of fields - truncated file?",/ERR
       fields = REFORM(fields, n_fields, N_ELEMENTS(fields)/n_fields, /OVERWRITE )
       n_recp = N_ELEMENTS(fields)/n_fields

       ;*** see if we want to subset the data range
       IF ( N_ELEMENTS(trange) GT 0 ) THEN BEGIN
            ridx   = LONARR(n_recp)
        trflag = 0
            FOR it=0,N_ELEMENTS(trange)-1 DO BEGIN
                ts = STRSPLIT(trange[it],'/',/EXTRACT)
                idx1 = WHERE(fields(0,*) GE ts(0) AND fields(0,*) LT ts(1), tcount)
                IF ( tcount GT 0 ) THEN ridx(idx1)=ridx(idx1)+1
       IF ( fields(0,n_recp-1) LT ts(1) ) THEN trflag = trflag + 1
            ENDFOR
            ridx = WHERE( ridx GT 0, tcount )
            IF ( tcount LE 0 ) THEN GOTO, skip1
       ENDIF ELSE ridx = LINDGEN(n_recp)

       n_rec = n_rec + N_ELEMENTS(ridx)
       CaaNotify, "Reading data, "+fields(0,0)+" to "+fields(0,n_recp-1)+" Stored rec #:"+STRING(n_rec), /DEBUG

       tmp_dpa = PTRARR(cef.nparam)

       FOR i = 0, cef.nparam-1 DO BEGIN
           name = STRING('PARAM_',i+1, FORMAT='(A,I3.3)')
           idx  = (WHERE(ceftags EQ name))[0]

           ;IF ( i GT 0 ) THEN cef.(idx).REC_TYPE = -2

           IF ( cef.(idx).REC_TYPE GT 0 ) THEN BEGIN
               IF ( KEYWORD_SET(nc_flag) ) THEN vt = 'CHAR' ELSE vt = cef.(idx).VALUE_TYPE

               s1 = cef.(idx).CEF_FIELD_POS(0)
               s2 = cef.(idx).CEF_FIELD_POS(1)

               CASE vt OF
                   'CHAR':         tmp_dpa(i) = PTR_NEW(fields[s1:s2,ridx])
                   'DOUBLE':       tmp_dpa(i) = PTR_NEW(DOUBLE(fields[s1:s2,ridx]),/NO_COPY)
                   'FLOAT':        tmp_dpa(i) = PTR_NEW(FLOAT(fields[s1:s2,ridx]),/NO_COPY)
                   'INT':          tmp_dpa(i) = PTR_NEW(LONG(fields[s1:s2,ridx]),/NO_COPY)
                   'ISO_TIME':     IF (KEYWORD_SET(jd_flag) ) THEN  $
                                       tmp_dpa(i) = PTR_NEW(iso2julday(fields[s1:s2,ridx]),/NO_COPY)  $
                                   ELSE IF (KEYWORD_SET(ep_flag) ) THEN $
                                       tmp_dpa(i) = PTR_NEW(iso2cdfepoch(fields[s1:s2,ridx]),/NO_COPY)  $
                                   ELSE tmp_dpa(i) = PTR_NEW(fields[s1:s2,ridx])
                   'ISO_TIME_RANGE': tmp_dpa(i) = PTR_NEW(fields[s1:s2,ridx])
                   ELSE:           tmp_dpa(i) = PTR_NEW(fields[s1:s2,ridx])
               ENDCASE
           ENDIF
       ENDFOR

       IF ( flag EQ 2 ) THEN dpa = [ [dpa], [TEMPORARY(tmp_dpa)] ] $
       ELSE BEGIN
           flag = 2
           dpa = REFORM(TEMPORARY(tmp_dpa),cef.nparam,1)
       ENDELSE

       ;*** we want to keep the part of the buffer not yet processed
skip1: IF (pos2-pos1 GE 0 ) THEN BEGIN
           work_buffer(0) = work_buffer(pos1:pos2)
           work_size = pos2-pos1+1
       ENDIF ELSE work_size = 0

       ;*** keep going until there is no more file to read
       IF ( read_size LT buffer_size ) THEN flag = 0

    ENDWHILE

    ;*** Finished with input file
    FREE_LUN, lun

    ;*** Release memory used by the work and read buffers
    work_buffer = 0
    read_buffer = 0

    ;*** Build the result array - we've read all the data so we know how many records there are!
    cef1.nrec = n_rec  ;*** Store the number of records in the metadata structure
    cef.nrec  = n_rec


    ;*** For each parameter build a metadata/data struture
    ;*** In theory we could filter out parameters that we don't want
    ;*** which would save processing time and memory. Ideally we would
    ;*** also do that above when we generate the dpa pointers.
    IF ( N_ELEMENTS(dpa) GT 0 ) THEN npage = (SIZE(dpa,/DIM))[1] ELSE npage =0
    flag = 0

    FOR i = 0, cef.nparam-1 DO BEGIN

        name = STRING('PARAM_',i+1, FORMAT='(A,I3.3)')
        idx  = (WHERE(ceftags EQ name))[0]
        pstru = CREATE_STRUCT(cef1, cef.(idx))

        ;*** Hack so we don't fall over if we get an empty file
        ;*** REC_TYPE: -2=no rec, -1=param disabled, 0=non-record vary, 1=normal
        IF ( n_rec EQ 0 AND pstru.REC_TYPE GT 0 ) THEN BEGIN
            pstru.REC_TYPE = -2
            pstru.nrec = 0
        ENDIF

        IF ( pstru.REC_TYPE GT 0 ) THEN BEGIN ;***For record varying parameters ***

            ;*** Check value type for conversion
            IF ( KEYWORD_SET(nc_flag) ) THEN vt = 'CHAR' ELSE vt = pstru.VALUE_TYPE

            CaaNotify, "Creating data array for "+pstru.VARNAME, /DEBUG
            ;*** Create the DATA array ***
            CASE vt OF

               'CHAR':    pstru = CREATE_STRUCT( pstru, 'DATA', STRARR([pstru.SIZES, n_rec]) )
               'DOUBLE':  pstru = CREATE_STRUCT( psrtu, 'DATA', DBLARR([pstru.SIZES, n_rec]) )
               'FLOAT':   pstru = CREATE_STRUCT( pstru, 'DATA', FLTARR([pstru.SIZES, n_rec]) )
               'INT':     pstru = CREATE_STRUCT( pstru, 'DATA', LONARR([pstru.SIZES, n_rec]) )
               'ISO_TIME':  IF ( KEYWORD_SET(jd_flag) OR KEYWORD_SET(ep_FLAG) ) THEN $
                                  pstru = CREATE_STRUCT( pstru, 'DATA', DBLARR([pstru.SIZES, n_rec]) ) $
                            ELSE  pstru = CREATE_STRUCT( pstru, 'DATA', STRARR([pstru.SIZES, n_rec]) )
               'ISO_TIME_RANGE':pstru = CREATE_STRUCT( pstru, 'DATA', STRARR([pstru.SIZES, n_rec]) )
               ELSE:     pstru = CREATE_STRUCT( pstru, 'DATA', STRARR([pstru.SIZES, n_rec]) )
            ENDCASE

            ;*** Fill the arrays ***
            dpos = 0L         ;*** Current record number
            s    = pstru.CEF_FIELD_POS(1) - pstru.CEF_FIELD_POS(0) + 1

            ;*** Check value type for conversion

            ;*** For each of data pages that we've read
            FOR j=0, npage-1 DO BEGIN
       siz = SIZE(*dpa(i,j),/DIM)
                IF (N_ELEMENTS(siz) EQ 2 ) THEN pn  = siz(1) ELSE pn = 1   ;*** Number of records in this block ***
                p1  = dpos*s        ;*** Start psoition
                p2  = p1 + pn*s - 1   ;*** End position
                pstru.DATA[p1:p2] = *dpa(i,j)
                PTR_FREE, dpa(i,j)

                dpos = dpos+pn       ;*** Update record position

            ENDFOR
        ENDIF

        ;*** Create the output array as a collection of the parameter strutures
        IF ( pstru.REC_TYPE GT -99 ) THEN BEGIN
            IF ( flag EQ 0 ) THEN param = [ PTR_NEW(pstru, /NO_COPY) ] $
            ELSE param = [ param, PTR_NEW(pstru, /NO_COPY) ]
            flag = flag + 1
        ENDIF
    ENDFOR

    ;*** Make sure we don't leave any unwanted storage allocated
    IF (N_ELEMENTS(dpa) GT 0) THEN HEAP_FREE, dpa

    CaaNotify, "Reading of data complete", /DEBUG
END

;==============================================================================================
; *** START OF PUBLIC ROUTINES
;==============================================================================================

; *************************************************************************************
;+
; NAME:
;   cef_get_attr
;
; PURPOSE:
;   Returns the requested attribute from the variable
;
; CATEGORY:
;   Public-Support
;
; CALLING SEQUENCE:
;
;   <result> = cef_get_attr( vararr, varid, attr, STATUS=status )
;
; INPUTS:
;   vararr  The variable pointer array returned from cef_read
;   varid   The variable index. This can be either the index number
;     for the variable array element in vararr or the name of
;     the variable.
;   attr    The attribute name to be searched for
;
; KEYWORD PARAMETERS:
;   STATUS=stat Returns the status of the search
;     -1 If the variable could not be identified
;     -2 If the attribute was not found
;     1 If a unique match was found
;     2 If multiple attributes match, only the first is returned
;
; OUTPUTS:
;   <results>   Either the attribute from the requested variable or an empty string.
;
; EXAMPLE:
;
;   result = cef_get_attr( vararr, 0, 'VARNAME')
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************

FUNCTION cef_get_attr, varptr, varid, attr, STATUS=status

    status = 0

    ; *** If varid given as STRING then need to work out varptr index
    IF ( SIZE(varid,/TYPE) EQ 7 ) THEN BEGIN
       varidx = -1
       FOR i = 0, N_ELEMENTS(varptr)-1 DO BEGIN
         IF ( STRMATCH(cef_get_attr(varptr, i, 'VARNAME'), varid, /FOLD_CASE) ) THEN BEGIN
          varidx = i
          BREAK
         ENDIF
       ENDFOR
    ENDIF ELSE BEGIN
       IF ( varid GE 0 AND varid LT N_ELEMENTS(varptr) ) THEN varidx = varid $
       ELSE varidx = -1
    ENDELSE

    ; *** Check if we found a variable
    IF ( varidx LT 0 ) THEN BEGIN
       CaaNotify, 'Request for attribute from unknown variable: '+varid, /DEBUG
       status = -1
       RETURN, ''
    ENDIF

    ; *** Now check for attribute
    tags = TAG_NAMES(*varptr(varidx))
    idx  = WHERE(STRMATCH(tags, attr, /FOLD_CASE), count)

    IF ( count EQ 0 ) THEN BEGIN     ;*** No matches, return empty string and set status
       status = -2
       RETURN, ''
    ENDIF ELSE IF ( count EQ 1 ) THEN BEGIN    ;*** One match
       status = 1
       RETURN, (*varptr(varidx)).(idx(0))
    ENDIF ELSE BEGIN      ;*** Multiple matches, just return first but set status
       status = 2
       RETURN, (*varptr(varidx)).(idx(0))
    ENDELSE
END

; *************************************************************************************
;+
; NAME:
;   cef_read
;
; PURPOSE:
;   Read a CEF file into an IDL struture
;
; CATEGORY:
;   Public-Support
;
; CALLING SEQUENCE:
;
;   <result> cef_read( [filename], [INCLUDE=cef], [/NODATA], [/JULDAY], [/CDFEPOCH] )
;
; INPUTS:
;   filename   Filename of CEF to be read. If not supplied a file selection
;           widget is displayed. CEF or Gzip'd CEF can be specified.
;
; KEYWORD PARAMETERS:
;   VAR=[names]     Array of regular expression of names to match. By default
;      all variables will be returned.
;   INCLUDE=cef     [PRIVATE] Used for recursive reading of include files.
;   /NODEPEND     Normally any depend variables will be included even if
;      not explicitly requested. Use this option to disable
;      the inclusion of any referenced variables.
;   /NODATA     Only read header information
;   /JULDAY     Returns times in Julian Days rather than the default iso string
;   /CDFEPOCH     Returns times in CDF EPOCH rather than the default iso string
;
; OUTPUTS:
;   <results>     An array (or structure, when /NODATA) that contains the result
;
; EXAMPLE:
;
;   result = cef_read( 'fgm.cef' )
;
; MODIFICATION HISTORY:
;   Written by:  c.h.perry@rl.ac.uk.
;   Aug, 2007 CHP: Initial version
;-
; *************************************************************************************
FUNCTION cef_read, readFile, INCLUDE=cef, NODATA=nd_flag, VAR=vnames, $
        NODEPEND=nr_flag, SEARCHTAG=stag, _EXTRA=extra

       HEAP_GC,/VER

       ;*** If the header structure is not yet defined then create it
       IF (N_ELEMENTS(cef) EQ 0) THEN cef = { ERROR: 0, NGLOBAL:0, NPARAM:0, NREC:0L, EOR:10B }

       ;*** Check flags
       IF ( NOT KEYWORD_SET(nr_flag) ) THEN nr_flag = 0
       nv_flag = N_ELEMENTS(vnames)

       ;*** If a file is not specified ask user to pick one
       IF ( NOT KEYWORD_SET(readFile)) THEN $
           readFile=DIALOG_PICKFILE(FILTER="*.cef;*.cef.gz", /READ, /MUST_EXIST)

       ;*** Make sure the input file is accessible
       IF (NOT FILE_TEST(readFile, /READ)) THEN BEGIN
            CaaNotify,"Can't open or read file "+readFile+" for import", /ERROR
            cef.ERROR = 1
            RETURN, cef
       ENDIF

       ;*** Set result to dummy value
       param = -1

       CaaNotify, "Reading "+readFile

       ;*** Look at file extension to determine if it is a compressed file
       IF ( STRUPCASE(STRMID(readFile,2,3,/REVERSE)) EQ ".GZ" ) THEN $
            compressFlag = 1 $
       ELSE compressFlag = 0

       ; *** Open the file ***
       OPENR, lun, readFile, /GET_LUN, COMPRESS=compressFlag, ERROR=err
       IF ( err NE 0 ) THEN BEGIN
            dummy = DIALOG_MESSAGE(!ERROR_STATE.MSG, /ERROR)
            cef.ERROR = 1
            RETURN, cef
       ENDIF

       ; *** Set the initial state of the header parser ***
       state  = "TOP"
       state1 = "END"

       ; *** data index
       pdata = 0

       ; *** Keep reading until end of header information or no more records ***
       WHILE( state NE "DATA_READ" AND state NE "END" ) DO BEGIN

            ;*** Try to read header record
            IF ( NOT CefReadHeadRec(lun, record) ) THEN BREAK

            ; *** Get the keyword/value(s) for this record
            IF ( CefSplitRec(record, key, value) ) THEN BEGIN

                ;*** Use the parser state to check what we are looking for
                CASE state OF

                "TOP": BEGIN

                    ;*** Use the keyword to determine the action
                    CASE key OF

                    "START_META": BEGIN     ;*** New global metadata item ***
                        state = "GLOBAL"
                        gName = value[0]
                        gStru = { VALUE_TYPE: "CHAR" }
                        eCount  = 0
                    END


                    "START_VARIABLE": BEGIN     ;*** New parameter ***
                        state = "PARAM"
                        pName = value[0]
                        pStru = { REC_TYPE:1, VARNAME:pName }
                    END

                    "INCLUDE": IF ( value[0] NE readFile ) THEN $
                        param = cef_read(findinclude(value[0]), INCLUDE=cef, _EXTRA=extra)

                    "DATA_UNTIL": BEGIN     ;*** Start of data ***
                        state = "DATA_READ"
                        cef = CREATE_STRUCT( cef, 'DATA_UNTIL', value[0])
                    END

                    ;*** Special CEF defined items at the top level ***

                    "FILE_NAME": cef = CREATE_STRUCT( cef, 'FILE_NAME', value[0] )

                    "FILE_FORMAT_VERSION": cef = CREATE_STRUCT( cef, 'FILE_FORMAT_VERSION', value[0] )

                    "END_OF_RECORD_MARKER": cef.EOR = (BYTE(value[0]))[0]

                    ELSE: CaaNotify, "Unsupported key "+key,/ERR

                    ENDCASE
                END


                "GLOBAL": BEGIN        ;*** Global metadata handling

                    IF (N_ELEMENTS(value) GT 1) THEN $
                        CaaNotify, "Global entry not allowed multiple values per entry : "+gName,/ERR

                    CASE key OF
                    "END_META":   BEGIN
                        state = "TOP"
                        IF (value[0] NE gName) THEN $
                            CaaNotify, "END_VARIABLE expected "+gName+"  got "+value[0],/ERROR
                        IF ( ecount EQ 1 ) THEN gStru = CREATE_STRUCT( gStru, 'ENTRY', element[0] ) $
                        ELSE gStru = CREATE_STRUCT( gStru, 'ENTRY', element )
                        cef.nglobal = cef.nglobal+1
                        IF ( gstru.VALUE_TYPE EQ 'CHAR' ) THEN cef = CREATE_STRUCT( cef, gname, gStru.ENTRY ) $
                        ELSE cef = CREATE_STRUCT( cef, gname, gStru )
                    END
                    ; *** WARNING: In theory CEF allows a different VALUE_TYPE for each entry
                    ; *** this is a 'feature' from CDF but I can't think of a situation where
                    ; *** it is useful. This feature is not currently supported by this
                    ; *** software and so we just assign a type based on the last specification
                    ; *** of the VALUE_TYPE.
                    "VALUE_TYPE": gStru.VALUE_TYPE = value[0]
                    "ENTRY": BEGIN
                         ; *** If this is the second entry then must be multi entry global ***
                         IF ( eCount EQ 0 ) THEN element = [ value[0] ] $
                         ELSE element = [ element, value[0] ]

                         eCount = eCount + 1
                    END
                    ELSE: CaaNotify, "Unsupported global key "+key  , /ERR
                    ENDCASE
                END

                "PARAM": BEGIN       ;*** Parameter description handling
                    IF ( key EQ "END_VARIABLE") THEN BEGIN
                        ;*** Set some defaults if not provided in the file
                        tags = TAG_NAMES(pStru)
                        id = WHERE( tags EQ 'SIZES', c )
                        IF ( c EQ 0 ) THEN pStru = CREATE_STRUCT( pStru, 'SIZES', 1L )

                        IF (pStru.REC_TYPE EQ 0) THEN data_idx = [-1L,-1L] $
                        ELSE BEGIN
                            n = LONG(pstru.SIZES[0])
                            FOR i=1, N_ELEMENTS(pstru.SIZES)-1 DO n = n * LONG(pstru.SIZES[i])
                            data_idx = [pdata,pdata+n-1]
                            pdata = pdata+n
                        ENDELSE
                        pStru = CREATE_STRUCT(pStru, 'CEF_FIELD_POS', data_idx)
                        ;*** Change parser state
                        state = "TOP"
                        ;*** Check this is the end of the correct parameter!
                        IF (value[0] NE pName) THEN $
                           CaaNotify, "END_VARIABLE expected "+pName+"  got "+value[0],/ERROR
                        ;*** Update the number of parameters
                        cef.nparam = cef.nparam + 1
                        ;*** Parameter names can be too long for structure element name
                        ;*** so just use a sequential number
                        pname = STRING('PARAM_',cef.nparam, FORMAT='(A,I3.3)')
                        cef = CREATE_STRUCT( cef, pname, pStru )

                    ENDIF ELSE BEGIN
                        IF ( key EQ 'DATA' ) THEN BEGIN
                            pStru.REC_TYPE = 0   ;*** Flag non-record varying data
                            ;********************************
                            ;At the moment we just add non-record varying data as string array
                            ;we should really check SIZES and VALUE_TYPE and reform and retype
                            ;data as we do for the real data fields. Something for the next release?
                            ;********************************
                        ENDIF ELSE IF ( key EQ 'SIZES' AND N_ELEMENTS(value) GT 1 ) THEN BEGIN
          value = REVERSE( value )
         ENDIF

                        IF (N_ELEMENTS(value) GT 1 ) THEN pStru = CREATE_STRUCT( pstru, key, value ) $
                        ELSE pStru = CREATE_STRUCT( pStru, key, value[0] )
                    ENDELSE
                END

                ENDCASE
            ENDIF ELSE CaaNotify, "Bad record?  "+record, /ERROR
       ENDWHILE

       ;*** Finished reading the header in the current file
       ;*** if state is END then we are at the end of the file
       ;*** for example this may be the end of an include file
       ;*** If the state is DATA_READ then we've reached the
       ;*** end of the header and are currently pointed at the
       ;*** start of the actual data!

       IF ( state EQ "DATA_READ" ) THEN BEGIN

            ;*** Check if not all vars are to be returned.
            IF (nv_flag GT 0) THEN filterNames, cef, vnames, NODEPEND=nr_flag, SEARCHTAG=stag

            IF ( KEYWORD_SET(nd_flag) ) THEN param = cef $
            ELSE BEGIN
                CefReadData, lun, cef, param, _EXTRA=extra
            ENDELSE
       ENDIF

       ;*** Done with this file so close it
       FREE_LUN, lun
       CaaNotify, "Finished reading "+readFile

       ;*** Return the result
       RETURN, param
END



;########################## EXAMPLES ############################

PRO example1

    ;*** When using pointers its a good idea garbage collect
    ;*** any allocated memory that is no longer referenced
    HEAP_GC

    ;*** Read the CEF file. The JULDAY flag is used to get the
    ;*** times returned in MJD so that we can use the IDL
    ;*** LABEL_DATE function for easy time axis plotting.
    ;*** The TR lets us specify a time range for the interval
    ;*** to be returned.
    result = cef_read( 'cis.cef.gz', /JULDAY )

    FOR i=0,N_ELEMENTS(result)-1 DO BEGIN
       PRINT, STRTRIM(i,2)+ ':  '+ (*result(i)).VARNAME+ $
         ' ('+STRJOIN(STRTRIM((*result(i)).SIZES,2),',')+')'
       PRINT, '    ', (*result(i)).CATDESC
       PRINT
    ENDFOR

    np=3

    dummy = LABEL_DATE(DATE_FORMAT="%H:%I:%S!C%Y-%N-%D")

    PLOT, (*result(0)).DATA, (*result(np)).DATA,                   $
       YTITLE=(*result(np)).LABLAXIS + '!C' + (*result(np)).UNITS, $
       XSTYLE=1, XTICKUNITS='TIME', XTICKFORMAT='LABEL_DATE', $
       YRANGE=[0.001,1], /YLOG, PSYM=3

    ;*** We've finished with the data so free up the memory
    HEAP_FREE, result
END



;################

    ;*** This is a slightly more advanced example that tries to plot
    ;*** time series of all the returned data parameters.
    ;*** This is just intended as an example! Don't expect it to
    ;*** to produce sensible results with all products!

PRO example2, filename

    IF ( N_ELEMENTS(filename) EQ 0 ) THEN filename = 'cis.cef.gz'

    ;*** Again we start by trying to free any unused space on the heap
    HEAP_GC

    ;*** Read the data file
    result = cef_read( filename, /JULDAY )

    ;*** Get the number of variables and create some arrays to hold
    ;*** the names and status of the parameters
    n_var      = N_ELEMENTS(result)
    var_name   = STRARR(n_var)
    d_var      = INTARR(n_var)

    ;*** First pass to extract var names and identify data variables
    ;*** Note that we use the PARAMETER_TYPE attribute to ignore
    ;*** support variables.
    FOR i = 0, n_var-1 DO BEGIN
       var_name(i) = cef_get_attr( result, i, 'VARNAME' )
       d_var(i)    = STRMATCH(cef_get_attr( result, i, 'PARAMETER_TYPE'),'DATA*',/FOLD_CASE)
       IF ( N_ELEMENTS(cef_get_attr( result, i, 'SIZES')) GT 1 ) THEN d_var(i) = 0
    ENDFOR


    ;*** Now we are ready to do a second pass where we will produce the plot
    n_plots = TOTAL(d_var)     ; *** Number of panels ***
    dy   = 0.90/n_plots       ; *** Height of panels ***
    yoff = 0.05         ; *** Vertical offset  ***
    dx   = 0.80         ; *** Width of panels  ***
    xoff = 0.10         ; *** Horizontal offset **

    ;*** Use the DATASET_TITLE to label the plot
    title = cef_get_attr(result,0,'DATASET_TITLE') + '!C'+ $
       cef_get_attr(result,0,'INSTRUMENT_NAME') + '  -  ' + $
       cef_get_attr(result,0,'DATASET_ID')

    ;*** Flag used with the NOERASE keyword on PLOT
    ne_flag = 0

    ;*** Loop through each of the variables
    FOR i = 0, n_var-1 DO BEGIN

       ;*** Check if this is a parameter to be plotted
       IF ( d_var(i) ) THEN BEGIN

         n_plots = n_plots - 1       ;*** Update the panel count ***

         ;*** If we are at the last panel we want a time axis otherwise we don't ***
         IF ( n_plots EQ 0 ) THEN dummy = LABEL_DATE(DATE_FORMAT="%H:%I:%S!C%Y-%N-%D") $
         ELSE dummy = LABEL_DATE(DATE_FORMAT=" ")

         ;*** Set the plot position for this panel ***
         !P.POSITION=[ xoff, yoff+n_plots*dy, xoff+dx, yoff+(n_plots+0.98)*dy ]

         ;*** Look for the DEPEND_0 - In the previous example we just
         ;*** assumed that it was the first variable which should be
         ;*** safe most of the time, but here we actually check!
         depend0 = WHERE( var_name EQ cef_get_attr(result,i,'DEPEND_0'), count )

         ;*** If not found then skip to the next parameter
         IF ( count EQ 0 ) THEN BREAK

         ;*** Look for fill values and replace with NaNs
         fillval = cef_get_attr(result,i,'FILLVAL', STATUS=status)
         IF ( status GT 0 ) THEN BEGIN
          idx = WHERE( (*result(i)).DATA EQ fillval, count )
          IF ( count GT 0 ) THEN (*result(i)).DATA(idx) = !VALUES.F_NAN
         ENDIF

         ;*** Use MIN/MAX to determine data range
         v2 = MAX( (*result(i)).DATA, MIN=v1, /NAN )
         IF (v2 EQ v1) THEN v2 = v1 + 1.0

         ;*** Based on data range decide if we want to do a log plot
         IF ( v1 GT 0 AND v2/v1 GT 50 AND (*result(i)).VALUE_TYPE EQ 'FLOAT' ) THEN ylog=1 ELSE ylog=0

         ;*** Plot the panel
         PLOT, (*result(depend0(0))).DATA, (*result(i)).DATA(0,*), $
          YTITLE=cef_get_attr(result,i,'LABLAXIS') + '!C' + cef_get_attr(result,i,'UNITS'), $
          XTICKUNITS='TIME', XTICKFORMAT='LABEL_DATE', $
          YRANGE=[v1,v2], YLOG=ylog, TITLE=title, $
          NOERASE=ne_flag

         ;*** If there are multiple components, overplot in the same panel
         IF ( FIX((*result(i)).SIZES) GT 1 ) THEN BEGIN
          FOR j=1,FIX((*result(i)).SIZES)-1 DO BEGIN
              OPLOT, (*result(depend0(0))).DATA, (*result(i)).DATA(j,*), LINESTYLE=j
          ENDFOR

          lab = cef_get_attr(result,i,'LABEL_1')
          IF ( N_ELEMENTS(lab) EQ 1 ) THEN lab = cef_get_attr(result,i,'REPRESENTATION_1')
          IF ( N_ELEMENTS(lab) EQ 1 ) THEN $
              lab = cef_get_attr(result,cef_get_attr(result,i,'DEPEND_1'),'DATA')
          FOR j=0, N_ELEMENTS(lab)-1 DO BEGIN
              x = xoff+dx+0.01
              y = yoff+(n_plots+1)*dy-(j+1)*0.015
              XYOUTS, x, y, lab(j), /NORM, CHARSIZE=0.75
              PLOTS, [x, x+0.05], [y-0.005,y-0.005], /NORM, LINESTYLE=j

          ENDFOR
         ENDIF

         title = ''     ;*** only want title on first panel      ***
         ne_flag = 1   ;*** don't want to erase previous panels ***
       ENDIF
    ENDFOR

    XYOUTS, 0.01, 0.005, 'File ID: '+cef_get_attr(result,0,'LOGICAL_FILE_ID'), CHARSIZE=0.5, /NORM
    XYOUTS, 0.99, 0.005, 'Plotted: '+SYSTIME(), /NORM,ALIGN=1.0,CHARSIZE=0.5

    ;*** Finished with the data so free the heap memory
    HEAP_FREE, result

    ;*** Put plot position back to the default
    !P.POSITION=0
END

PK
����d]Y��շ����0���org/autoplot/cefdatasource/test_caa_cef_read.BAKpro test_caa_cef_read
   file= 'C1_CP_EDI_EGD__20050212_V03.cef'
   file4= 'C1_CP_PEA_CP3DXPH_DNFlux__20020811_140000_20020811_150000_V061018.cef'
   t0= systime(1)
   x= cef_read( 'N:/data/cef/' + file4 )
   print, 'read in '+(systime(1)-t0)+' sec'
   help, x
end
PK
����d]Yu�WY����0���org/autoplot/cefdatasource/test_caa_cef_read.propro test_caa_cef_read
   file= 'C1_CP_EDI_EGD__20050212_V03.cef'
   file4= 'C1_CP_PEA_CP3DXPH_DNFlux__20020811_140000_20020811_150000_V061018.cef'
   t0= systime(1)
   x= cef_read( 'N:/data/cef/' + file4, /ep_flag )
   print, 'read in '+(systime(1)-t0)+' sec'
   help, x
end
PK
����d]Y���P��P�����test/TestReformDataSet.class�������3�T
��*
�+�,
�+�-�.
��/	�0�1�2
��*�3
��4
�+�5
��6�7�8�9
��:
�;�<�=�>�<init>�()V�Code�LineNumberTable�LocalVariableTable�this�Ltest/TestReformDataSet;�main�([Ljava/lang/String;)V�j�I�i�args�[Ljava/lang/String;�ds1�Lorg/das2/qds/DDataSet;�val�ds2�Lorg/das2/qds/QDataSet;�
StackMapTable�?�
SourceFile�TestReformDataSet.java���?�@�A�B�C�(org/autoplot/cefdatasource/ReformDataSet��D�E�F�G�java/lang/StringBuilder�
 ds1[2,0]=�H�I�J�K�H�L�
  ds2[2,0,0]=�M�J�N�O�P�Q�R�S�test/TestReformDataSet�java/lang/Object�org/das2/qds/DDataSet�createRank2�(II)Lorg/das2/qds/DDataSet;�putValue�(IID)V�(Lorg/das2/qds/QDataSet;[I)V�java/lang/System�err�Ljava/io/PrintStream;�append�-(Ljava/lang/String;)Ljava/lang/StringBuilder;�value�(II)D�(D)Ljava/lang/StringBuilder;�org/das2/qds/QDataSet�(III)D�toString�()Ljava/lang/String;�java/io/PrintStream�println�(Ljava/lang/String;)V�!���������������/�����*���������������������������	�����������z��L=>��%6��+����������ܻ�Y+�
YOYOYO��N����Y��	��
+����
��
-�����������������*�
������	������&��,��2��J��y�����>��������'������z�� ����s�!�"��	�q�#���J�0�$�%��&�������'��������(����)PK
����d]Y������������	����������A����META-INF/����PK
����d]Y(F�bh���h����������������+���META-INF/MANIFEST.MFPK
����d]Y�����������������������A����org/PK
����d]Y������������
�����������A����org/autoplot/PK
����d]Y�����������������������A��org/autoplot/cefdatasource/PK
����d]Y�����������������������AK��test/PK
����d]YT�K����������������������n��META-INF/build.txtPK
����d]Yn�#�4���4���=�������������\��META-INF/org.autoplot.datasource.DataSourceFactory.extensionsPK
����d]Yvv=�������$����������������org/autoplot/cefdatasource/Cef.classPK
����d]Y�&i�9��9��.���������������org/autoplot/cefdatasource/CefDataSource.classPK
����d]Y+a��a��5�������������u@��org/autoplot/cefdatasource/CefDataSourceFactory.classPK
����d]Y}������1�������������)V��org/autoplot/cefdatasource/CefMetadataModel.classPK
����d]Y�]/��/��.��������������i��org/autoplot/cefdatasource/CefReaderData.classPK
����d]Y��,g��g��2�������������r���org/autoplot/cefdatasource/CefReaderHeader$1.classPK
����d]Y���������=�������������)���org/autoplot/cefdatasource/CefReaderHeader$GlobalStruct.classPK
����d]Y���(������9�������������i���org/autoplot/cefdatasource/CefReaderHeader$KeyValue.classPK
����d]Y�$������<�����������������org/autoplot/cefdatasource/CefReaderHeader$ParamStruct.classPK
����d]Y�\?<������7�������������ڌ��org/autoplot/cefdatasource/CefReaderHeader$Record.classPK
����d]Y�Z�;��;��6�����������������org/autoplot/cefdatasource/CefReaderHeader$State.classPK
����d]Y|!�������0�����������������org/autoplot/cefdatasource/CefReaderHeader.classPK
����d]Y ���*��*��+�������������Ƴ��org/autoplot/cefdatasource/DataSetOps.classPK
����d]Y���������2�������������9���org/autoplot/cefdatasource/DoubleFieldParser.classPK
����d]Y]H�Ԉ�����-����������������org/autoplot/cefdatasource/DoubleParser.classPK
����d]Y1K�|��������,�����������������org/autoplot/cefdatasource/FieldParser.classPK
����d]Y�Ϝآ�����.����������������org/autoplot/cefdatasource/IsoTimeParser.classPK
����d]YQز*����.�����������������org/autoplot/cefdatasource/ReformDataSet.classPK
����d]Y�Q�K/��/��.�����������������org/autoplot/cefdatasource/TestCefReader.classPK
����d]Y�	M�;��;��4�������������E���org/autoplot/cefdatasource/caa_cef_read_20070820.BAKPK
����d]Y�0���������4�������������d��org/autoplot/cefdatasource/caa_cef_read_20070820.proPK
����d]Y��շ����0�������������o{�org/autoplot/cefdatasource/test_caa_cef_read.BAKPK
����d]Yu�WY����0��������������|�org/autoplot/cefdatasource/test_caa_cef_read.proPK
����d]Y���P��P���������������7~�test/TestReformDataSet.classPK���� � ��
�������