跳转至

如果流星在大气中汽化,它会发出声音吗?

原文链接: https://www.nv5geospatialsoftware.com/Learn/Blogs/Blog-Details/if-a-meteor-vaporizes-in-the-atmosphere-does-it-make-a-sound

5155 为本文评分:

3.9

如果流星在大气中汽化,它会发出声音吗?

Jim Pendleton 2022年11月8日,星期二

Jim Pendleton 是 NV5 Geospatial 的专业服务工程师


Himawari 博客图片

在这张来自 Himawari 8 第 3 波段数据(0.64 微米)的屏幕截图中,大流星或火流星的蒸汽尾迹(据推测在图像拍摄前约 2 分钟消散)在菱形框和放大的插图中突出显示。箭头所指的线性特征要么是蒸汽尾迹在较低层大气云上投下的太阳阴影,要么是留在大气更高处的碎片尾迹的不同部分。观看下面的视频,您自己判断。

继另一篇关于洪阿汤加-洪阿哈阿帕伊火山喷发产生的持久大气压力波的博客之后,我想了解从另一个方向进入大气的物体是否能在气象卫星数据中显示类似的信号会很有趣。

我最近收到了 Nicole Mortillaro 在 2019 年发表的CBC新闻文章链接。它描述了 2018 年 12 月 18 日一颗大流星或火流星在白令海上空撞击地球大气层的事件。英国《每日邮报》的第二篇文章包含了日本气象厅 Himawari 8 气象卫星拍摄的此次事件的视频。两篇文章都指出,科学家估计这颗火流星爆炸释放的能量接近 20 万吨 TNT 当量。这与洪阿汤加火山估计释放的 1000 万吨能量相去甚远,而且大气扰动的机制和方向当然也截然不同。然而,根据这些文章,科学家估计每个世纪只有少数几颗这种大小的火流星撞击地球大气层,并且有这个日期的各种卫星存档数据可用,因此我认为这项调查值得一试。

NASA 喷气推进实验室近地天体研究中心的“火流星”网页提供了此次事件的坐标和日期。估计的日期和时间为 2018 年 12 月 18 日,世界标准时 23:48:20,地点位于北纬 56.9 度,东经 172.4 度,阿拉斯加和俄罗斯之间的白令海上空。

这里距离任何人口中心至少 200 英里。当时是白天,各个方向数百英里都是阴天,而且火流星可能在热层中 70 到 100 公里高处汽化。因此,地球表面不太可能有人直接目睹与此事件相关的现象。

在免费提供的 GOES-16 和 GOES-17 此日期存档数据中没有找到任何相关特征后,我申请了非商业访问 Himawari 存档数据。这个过程需要两个步骤。首先,用户必须向数据集成与分析系统 (DIAS) 提出请求。DIAS 是由日本文部科学省和东京大学支持的项目开发并运营的。

在完成初步注册并接受其使用条款后,用户必须再次专门申请访问存档的 Himawari 8 和 9 数据集。它们并未直接通过 DIAS 数据搜索与发现系统的主页公开。一旦获得访问权限并收到链接,我便能够下载此次事件周围的部分存档数据。

首先,我从第 9 波段下载了原始的“原始数据”,中心波长为 6.9 微米,大约与我早期用于显示洪阿汤加火山喷发冲击波的时差成像所用的波长相匹配。由于我最初的希望是识别一个在空间和时间上扩展的现象,我请求了全盘图像,每次采集“时间线”的所有 10 个“片段”。直到那时,我才意识到 IDL®ENVI® 都没有内置读取原始 Himawari 标准数据格式的功能。

幸运的是,日本气象学会提供了一份描述该格式的用户指南文档。文档内容清晰明了,我编写的用于读取此格式的 IDL 代码如下所示。





; 参考:

;  Himawari-8/9

;  Himawari Standard Data

;  用户指南

;  版本 1.3

;  2017年7月3日

;  日本气象厅

;  1-3-4 Otemachi, Chiyoda-ku, Tokyo, 100-8122 Japan

;

;查找位置:

;  https://www.data.jma.go.jp/mscweb/en/himawari89/space_segment/hsd_sample/HS_D_users_guide_en_v13.pdf

;

; 我们使用固定长度的块定义来从文件读取数据,但在输入后将它们转换为哈希存储。
; 此外,固定长度的字节字符串被转换为 IDL 字符串。



Pro HimawariStandardBlock1Data__Define
; #1 基本信息块
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock1Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0U, $
    TotalHeaderBlocks : 0U, $
    ByteOrder : 0B, $
    SatelliteName_B : BytArr(16), $
    ProcessingCenter_B : BytArr(16), $
    ObservationArea_B : BytArr(4), $
    OtherObservationInfo_B : BytArr(2), $
    ObservationTimeline : 0U, $
    ObservationStartTime : 0D, $
    ObservationEndTime : 0D, $
    FileCreationTime : 0D, $
    TotalHeaderLength : 0UL, $
    TotalDataLength : 0UL, $
    QualityFlag1 : 0B, $
    QualityFlag2 : 0B, $
    QualityFlag3 : 0B, $
    QualityFlag4 : 0B, $
    FileFormatVersion_B : BytArr(32), $
    FileName_B : BytArr(128), $
    Spare : BytArr(40)}
End



Pro HimawariStandardBlock2Data__Define
; #2 数据信息块
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock2Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0U, $
    NumberOfBitsPerPixel : 0U, $
    NumberOfColumns : 0U, $
    NumberOfLines : 0U, $
    CompressFlagForDataBlock12 : 0B, $
    Spare : BytArr(40) $
  }
End



Pro HimawariStandardBlock3Data__Define
; #3 投影信息块
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock3Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0U, $
    Sub_Lon : 0D, $
    CFAC : 0UL, $
    LFAC : 0UL, $
    COFF : 0., $
    LOFF : 0., $
    DistanceFromEarthCenterToVirtualSatellite : 0D, $
    EarthsEquatorialRadius : 0D, $
    EarthsPolarRadius : 0D, $
    F1 : 0D, $
    F2 : 0D, $
    F3 : 0D, $
    Coefficient : 0D, $
    ResamplingTypes : 0U, $
    ResamplingSize : 0U, $
    Spare : BytArr(40) $
  }
End



Pro HimawariStandardBlock4Data__Define
; #4 导航信息块
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock4Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0U, $
    NavigationInformationTime : 0D, $
    SSPLongitude : 0D, $
    SSPLatitude : 0D, $
    DistanceFromEarthsCenterToSatellite : 0D, $
    NadirLongitude : 0D, $
    NadirLatitude : 0D, $
    SunsPosition : DblArr(3), $
    MoonsPosition : DblArr(3), $
    Spare : BytArr(40) $
  }
End



Pro HimawariStandardBlock5Data__Define
; #5 定标信息块
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock5Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0U, $
    BandNumber : 0U, $
    CentralWavelength : 0D, $
    ValidNumberOfBitsPerPixel : 0U, $
    CountValueofErrorPixels : 0U, $
    CountValueOfPixelsOutsideScanArea : 0U, $
    SlopeForCountRadianceConversion : 0D, $
    InterceptForCountRadianceConversion : 0D, $
    CorrectionCoefficientRadianceToBrightnessTemperaturec0 : 0D, $
    CorrectionCoefficientRadianceToBrightnessTemperaturec1 : 0D, $
    CorrectionCoefficientRadianceToBrightnessTemperaturec2 : 0D, $
    CorrectionCoefficientForSensorBrightnessTemperatureToRadiancec0 : 0D, $
    CorrectionCoefficientForSensorBrightnessTemperatureToRadiancec1 : 0D, $
    CorrectionCoefficientForSensorBrightnessTemperatureToRadiancec2 : 0D, $
    SpeedOfLight : 0D, $
    PlanckConstant : 0D, $
    BoltzmannConstant : 0D, $
    Spare : BytArr(40) $
    }
End



Pro HimawariStandardBlock6Data__Define
; #6 交叉定标信息块
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock6Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0U, $
    GSICSCalibrationCoefficientIntercept : 0D, $
    GSICSCalibrationCoefficientSlope : 0D, $
    GSICSCalibrationCoefficienQuadtraticTerm : 0D, $
    RadianceBiasForStandardScene : 0D, $
    UncertaintyOfRadianceBiasForStandardScene : 0D, $
    RadianceForStandardScene : 0D, $
    StartTimeOfGCSICSCorrectionValidityPeriod : 0D, $
    EndTimeOfGSCISCorrectionValidityPeriod: 0D, $
    RaidanceValidityRangeOfGSICSCalibrationCoefficientsUpperLimit : 0., $
    RaidanceValidityRangeOfGSICSCalibrationCoefficientsLowerLimit : 0., $
    FileNameOfGSICSCorrection_B : Bytarr(128), $
    Spare : BytArr(56) $
    }
End



Pro HimawariStandardBlock7Data__Define
; #7 片段信息块
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock7Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0U, $
    TotalNumberOfSegments : 0B, $
    SegmentSequenceNumber : 0B, $
    FirstLineNumberOfImageSegment : 0U, $
    Spare : BytArr(40) $
    }
End



Pro HimawariStandardBlock8Data__Define
; #8 导航校正信息块
; 块 8 有不定数量的额外记录用于存储偏移数据,
; 以及稍后添加的 Spare 向量。
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock8Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0U, $
    CenterColumnOfRotation : 0., $
    CenterLineOfRotation : 0., $
    AmountOfRotationalCorrection : 0D, $
    NumberofCorrectionInformationDataForColumnAndLineDirection : 0U $
    }
End



Pro HimawariStandardBlock8ShiftData__Define
; 块 8 可能有 0 到 N 个这样的偏移数据
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock8ShiftData, $
    LineNumberAfterRotation : 0U, $
    ShiftAmountForColumnDirection : 0., $
    ShiftAmountForLineDirection : 0. $
    }
End



Pro HimawariStandardBlock9Data__Define
; #9 观测时间信息块
; 块 9 有不定数量的额外记录用于存储观测时间数据,
; 以及稍后添加的 Spare 向量。
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock9Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0U, $
    NumberOfObservationTimes : 0U $
    }
End



Pro HimawariStandardBlock9ObservationTimeData__Define
; 块 9 可能有 0 到 N 个这样的观测时间数据
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock9ObservationTimeData, $
    LineNumber : 0U, $
    ObservationTime : 0D $
    }
End



Pro HimawariStandardBlock10Data__Define
; #10 误差信息块
; 块 10 有不定数量的额外记录用于存储误差信息数据,
; 以及稍后添加的 Spare 向量。
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock10Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0L, $
    NumberOfErrorInformationData : 0U $
    }
End



Pro HimawariStandardBlock10ErrorInformationData__Define
; 块 10 可能有 0 到 N 个这样的误差信息数据
Compile_Opt StrictArr, Hidden
!null = {HimawariStandardBlock10ErrorInformationData, $
    LineNumber : 0U, $
    NumberOfErrorPixelsPerLine : 0U $
    }
End



Pro HimawariStandardBlock11Data__Define
; #11 备用块
Compile_Opt Strictarr, Hidden
!null = {HimawariStandardBlock11Data, $
    HeaderBlockNumber : 0B, $
    BlockLength : 0U, $
    Spare : BytArr(256)  $
    }
End



Pro HimawariStandardBlock__Define
Compile_Opt StrictArr
On_Error, 2
!null = {HimawariStandardBlock, $
    Inherits OrderedHash, $
    BlockNumber : 0U $
  }
End



Function HimawariStandardBlock::Init, BlockNumber
Compile_Opt StrictArr
On_Error, 2
If (~self.OrderedHash::Init()) then Return, 0
self.BlockNumber = BlockNumber
Return, 1
End



Function HimawariStandardBlock::Read, LUN, Error = Error
Compile_Opt StrictArr
On_Error, 2
Error = !null
Catch, ErrorNumber
If (ErrorNumber ne 0) then Begin
    Error = !error_state.msg + ', Block ' + self.BlockNumber.ToString()
    Return, !false
EndIf
Case self.BlockNumber of
  1 : Data = {HimawariStandardBlock1Data}
  2 : Data = {HimawariStandardBlock2Data}
  3 : Data = {HimawariStandardBlock3Data}
  4 : Data = {HimawariStandardBlock4Data}
  5 : Data = {HimawariStandardBlock5Data}
  6 : Data = {HimawariStandardBlock6Data}
  7 : Data = {HimawariStandardBlock7Data}
  8 : Data = {HimawariStandardBlock8Data}
  9 : Data = {HimawariStandardBlock9Data}
  10 : Data = {HimawariStandardBlock10Data}
  11 : Data = {HimawariStandardBlock11Data}
  Else : Message, 'Invalid block number ' + self.BlockNumber.ToString(), /Traceback
EndCase
; We're using structures to read the data, then converting the info
; into a hash with key/value pairs, instead.  The lowercase version
; of the tag name in the structure becomes the corresponding key,
; with the slight exception of strings.
ReadU, LUN, Data
Tags = Tag_Names(Data)
ForEach Tag, Tags, Index Do Begin
  If (Tag.EndsWith('_B')) then Begin
    ; Structure tags that are defined as fixed-length byte arrays
    ; are converted to IDL strings, and we strip the "_B" from
    ; the end of the tag name for use as the key.
    self[(Tag.Split('_'))[0].ToLower()] = String(Data.(Index))
  EndIf Else Begin
    self[Tag.ToLower()] = Data.(Index)
  EndElse
EndForEach
; Blocks 8 through 10 have an indeterminate number of additional records, 
; followed by an allocation of spare data.
Case self.BlockNumber of
  8 : Begin
    ShiftData = List()
    Data = {HimawariStandardBlock8ShiftData} 
    Tags = Tag_Names(Data)
    For I = 0L, Long(self['numberofcorrectioninformationdataforcolumnandlinedirection']) - 1 Do Begin
      ReadU, LUN, Data
      Items = OrderedHash()
      ForEach Tag, Tags, Index Do Begin
        Items[Tag.ToLower()] = Data.(Index)
      EndForEach
      ShiftData.Add, Items
    EndFor
    self['shiftdata'] = ShiftData
    Spare = BytArr(40)
    ReadU, LUN, Spare
    self['spare'] = Spare
    End
  9 : Begin
    ObservationTimes = List()
    Data = {HimawariStandardBlock9ObservationTimeData}
    Tags = Tag_Names(Data)
    For I = 0L, Long(self['numberofobservationtimes']) - 1 Do Begin
      ReadU, LUN, Data
      Items = OrderedHash()
      ForEach Tag, Tags, Index Do Begin
        Items[Tag.ToLower()] = Data.(Index)
      EndForEach
      ObservationTimes.Add, Items
    EndFor
    self['observationtimes'] = ObservationTimes
    Spare = BytArr(40)
    ReadU, LUN, Spare
    self['spare'] = Spare
    End
  10 : Begin
    ErrorInformation = List()
    Data = {HimawariStandardBlock10ErrorInformationData}
    Tags = Tag_Names(Data)
    For I = 0L, Long(self['numberoferrorinformationdata']) - 1 Do Begin
      ReadU, LUN, Data
      Items = OrderedHash()
      ForEach Tag, Tags, Index Do Begin
        Items[Tag.ToLower()] = Data.(Index)
      EndForEach
      ErrorInformation.Add, Data
    EndFor
    self['errorinformation'] = ErrorInformation
    Spare = BytArr(40)
    ReadU, LUN, Spare
    self['spare'] = Spare
    End
  Else :
EndCase
Return, !true
End



Pro HimawariStandard::Cleanup
Compile_Opt StrictArr
On_Error, 2
If (self.LUN ne 0) then Begin
    ; Close the data file
    Free_LUN, self.LUN, /Force
    self.LUN = 0
EndIf
End



Pro HimawariStandard::GetProperty, $
  Image_Data = Image_Data, $
  Metadata = Metadata
Compile_Opt StrictArr
On_Error, 2
If (Arg_Present(Image_Data)) then Begin
  ; Return a copy of the image data.
  Image_Data = *self.pImage
EndIf
If (Arg_Present(Metadata)) then Begin
  ; Return the complete hash of blocks 1 through 11
  Metadata = self.Blocks
EndIf
End



Function HimawariStandard::Open, File, Error = Error
Compile_Opt StrictArr
On_Error, 2
Error = !null
If (File ne !null) then Begin
  self.File = File
  Status = self.OpenFile(Error = Error)
  Return, Status
EndIf
Return, !False
End



Function HimawariStandard::Init, $
  File = File, Error = Error
Compile_Opt StrictArr
On_Error, 2
Error = !null
If (File ne !null) then Begin
  Status = self.Open(File, Error = Error)
  Return, Status
EndIf
Return, 1
End



Function HimawariStandard::OpenFile, Error = Error
Compile_Opt StrictArr
On_Error, 2
Error = !null
Catch, ErrorNumber
If (ErrorNumber ne 0) then Begin
  Catch, /Cancel
  Error = !error_state.msg
  If (self.LUN ne 0) then Begin
    Free_LUN, self.LUN, /Force
  EndIf
  self.LUN = 0
  Return, !false
EndIf
If (~File_Test(self.File)) then Begin
  Error = 'File does not exist'
  Return, !false
EndIf
; Check if byte order of the data matches the OS and use SWAP_ENDIAN on OpenR, if necessary.
OpenR, LUN, self.File, /Get_LUN
DummyBuffer = BytArr(5) ; Skip the first 5 bytes
ReadU, LUN, DummyBuffer
ByteOrder = 0B
ReadU, LUN, ByteOrder
If (ByteOrder eq 1 && (!d.name).ToUpper() eq 'WIN') || $
   (ByteOrder eq 0 && (!d.name).ToUpper() eq 'UNIX') then Begin
  Free_LUN, LUN, /Force
  OpenR, LUN, self.File, /Get_LUN, Swap_Endian = 1
EndIf Else Begin
  ; No byte-swapping, rewind the file pointer.
  Point_LUN, LUN, 0
EndElse
self.LUN = LUN
Return, !true
End



Function HimawariStandard::Read, Error = Error
Compile_Opt StrictArr
On_Error, 2
self.Blocks = OrderedHash()
For I = 1, 11 Do Begin
  Block = Obj_New('HimawariStandardBlock', I)
  Status = Block.Read(self.LUN, Error = Error)
  If (~Status) then Return, !false
  ; Notice that we're using a hash rather than a list to store the blocks
  ; so we "index" using 1-based integer key values 1 through 11 corresponding to
  ; the defined block numbers instead of list index values 0 through 10.
  self.Blocks[I] = Block
EndFor
; "Block 12" has no metadata, only image data, so we simply
; put the image into a pointer, instead of constructing more hash info.
Image = UIntArr(self.Blocks[2, 'numberofcolumns'], self.Blocks[2, 'numberoflines'])
; Technically, we should check the compression flag from Block 2 rather than 
; assuming the image in uncompressed.  What is the compression scheme if it
; is compressed?
ReadU, self.LUN, Image
self.pImage = Ptr_New(Image)
Free_LUN, self.LUN, /Force
self.LUN = 0
Return, !true
End





Function HimawariStandard::RadianceToBrightnessTemperature, RadianceData, Metadata, $
  Replace_Bad = ReplaceBad
; Raidance in W/(m^2 steradian micron) to brightness temperature
; Note: This is a static method
Compile_Opt StrictArr, Static
On_Error, 2
Exceptsave = !except
; Radiance data expected to come from ::CountToRadiance where "bad" pixels
; have been replaced set to 0.
Bad = Where(RadianceData eq 0, NBad, Complement = Good)
M = Metadata[5]
!except = 0
Num = (M['planckconstant'] * M['speedoflight'])/(M['boltzmannconstant']*M['centralwavelength'])
Denom = ALog2((2.*M['planckconstant']*M['speedoflight']^2)/((M['centralwavelength']^5)*RadianceData) + 1.d)
Te = Num/Denom
Tb = M['correctioncoefficientradiancetobrightnesstemperaturec0'] + $
     M['correctioncoefficientradiancetobrightnesstemperaturec1']*Te + $
     M['correctioncoefficientradiancetobrightnesstemperaturec2']*Te^2
If (NBad ne 0) then Tb[Bad] = ReplaceBad ne !null ? ReplaceBad : Min(Tb[Good], /NAN)
!null = Check_Math()
!except = ExceptSave
Return, Tb
End





Function HimawariStandard::CountToRadiance, ImageData, Metadata
; counts to W/(m^2 steradian micron)
; Note: this is a static method
Compile_Opt StrictArr, Static
On_Error, 2
Bad = Where(ImageData ge 65534, NBad)
M = Metadata[5]
RadianceData = (ImageData * M['slopeforcountradianceconversion'] + $
  M['interceptforcountradianceconversion']) > 0
If (NBad ne 0) then RadianceData[Bad] = 0
Return, RadianceData
End





Pro HimawariStandard__Define
Compile_Opt StrictArr
On_Error, 2
!null = {HimawariStandard, $
   Inherits IDL_Object, $
   File : '', $
   LUN : 0L, $
   Blocks : Obj_New(), $
   pImage : Ptr_New() $
   }
End



使用这个对象类很简单,例如:





h = himawaristandard(file='path-to-.dat-file')
status = h.read(error = error)
if (~status) then … ; 这是一个错误状态
imagedata = h.image_data
metadata = h.metadata

提供了两个静态方法 HimawariStandard::CountToRadianceHimawariStandard::RadianceToBrightnessTemperature 来从原始计数值进行转换。如果您对这些方法有任何修正建议,请联系作者。

图像元数据存储在一个 IDL 有序哈希中,以用户指南中描述的 1 到 11 块号作为键。

“块 12”,即原始的、无符号整数图像像素数据,则通过对象的 Image_Data 属性返回。原始数据在 Y 方向上是反转的(以 IDL 的方式),元数据中对像素位置的引用则从 Himawari 标准坐标系中的像素 (1,1) 开始。

请注意,每个波段的单独空间分辨率定义为星下点 (SSP) 处 0.5、1 或 2 公里/像素,这意味着在进行重采样以从多个波段生成假彩色图像时必须小心。

DIAS 以 TAR 格式提供下载,单个图像以“bzip2”格式存储,按时间线组织的目录树下。在 Windows 上,我使用 7-Zip 应用程序打开存档并将“.bz2”文件解压到磁盘,然后使用 Cygwin 的“bunzip2”可执行文件将每个“.bz2”文件解压成最终的 Himawari 标准格式。

我编写了一个额外的实用程序,将每个图像片段的计数值数据转换为辐射值,然后将片段组合成一个单一的图像数组,并按“IDL 方式”定向。组合后的全盘辐射值图像,以及一个包含来自各个片段的原始元数据的 IDL List 对象,被写入一个 IDL SAVE 格式的文件中,该文件与 .DAT 文件位于同一目录,并使用原始根文件名的组成部分进行命名。





pro himawari_construct_full_disk, dir_local
compile_opt strictarr
on_error, 2
dir = dir_local ne !null ? dir_local : '\Bering Sea Meteor\Himawari-8\All Bands\bz2s'
files = (file_search(filepath(root = dir, 'HS_*.DAT'))).sort()
bases = file_basename(files)
baselist = list()
foreach base, bases do baselist.add, (base.split('_'))[0:6].join('_')
disks = (baselist.toarray()).uniq()
foreach disk, disks do begin
  outfile = filepath(disk + '.sav', root = dir)
  if (file_test(outfile)) then continue
  imlist = list()
  metadatalist = list()
  ysize = 0L
  files = (file_search(filepath(root = dir, disk + '*.DAT'))).sort()
  foreach file, files, index do begin
    h = himawaristandard(file=file)
    status = h.read()
    if (~status) then continue
    imagedata = h.image_data
    bad = where(imagedata ge 65534, nbad)
    metadata = h.metadata
    metadatalist.add, metadata
    radiancedata = HimawariStandard.CountToRadiance(imagedata, metadata)
    if (nbad ne 0) then radiancedata[bad] = 0
    imlist.add, reverse(radiancedata, 2)
    ysize += (radiancedata.dim)[1]
  endforeach
  radiance = dblarr(((imlist[0]).dim)[0], ysize)
  for i = 0, imlist.count() - 1 do begin
    ; 从技术上讲,这应该通过使用每个图像的元数据中的 yoffset 信息来允许任何缺失的片段,
    ; 但我们处理的是存档数据,因此在所有波段的所有日期,所有片段都应该可用。
    radiance[0, ysize - ((imlist[0]).dim)[1]*(i + 1)] = imlist[i]
  endfor
  save, radiance, metadatalist, /compress, file = outfile
endforeach
end

首先,让我们看看全盘图像。

第 3 波段的空间分辨率是 0.5 公里(导致全尺寸图像每边 22,000 像素!),所以这个屏幕截图的大小大大缩小了。我们感兴趣的区域位于全盘的右上角。大陆轮廓是使用相应的元数据标签以及 IDL 的 MAP_SET 过程针对卫星投影的参数生成的。



 map_set, /cont, /satellite, md4['ssplatitude'], md4['ssplongitude'], $
        sat_p = [md4['distancefromearthscentertosatellite']/ $
        md3['earthsequatorialradius'],0,0], $
        /noborder, /noerase, mlinethick = 8, /isotropic, $
        /horizon, color = 'ff0000'x, /hi, $
        xmargin = [1, 8], ymargin = [10,10] ; dependent on scale

这个投影在缩放较小时还可以,但在放大时有点问题。边距关键字值是不精确的(并且单位是“字符大小”!)。之所以需要这些边距,是因为与地球表面相切的平面并不与包含图像数据的缓冲区的四条边相交。您可能需要进一步调整这些值以获得更美观和准确的结果。

接下来,让我们放大到感兴趣的区域。

在经历了下载数据、编写文件解析器、创建全盘图像以及调整地图覆盖层这些过程之后,我是否发现了任何类似洪阿汤加火山那样的明显“冲击波”信号?不,我没有。

在下面的视频中,显示了辐射差值图像,使用与汤加火山数据相同的技术,从当前时间步长的辐射值中减去前一个时间步长的辐射值。

回想起来,这个结果并不令人惊讶,因为流星汽化高度的大气密度不足以传输声波,所以博客标题所提出的论点问题的答案是“不会”。然而,利用现有数据仍然可以研究一些有趣的课题,包括:

  • 是否可以从多个波段中提取流星化学成分的光谱特征,即使在结合较低空间分辨率波段的情况下?
  • 如果可以,是否有足够的数据来区分碳质球粒陨石和铁陨石?
  • 是否可以通过比较 JPL 的火流星日期和位置数据与存档卫星数据来发现其他火流星?如果可以,其数量和种类是否足以训练一个 AI 模型,以自动在存档甚至近实时图像中定位未报告的流星?
  • 通过研究蒸汽尾迹投射阴影的光谱特征或投影运动可以了解到什么?

访问 ENVI 中的新机器学习功能 2023 年春季学生聚焦