martedì 22 settembre 2026

Microsoft office a dischetti

 Una nuova acquisizione per il mio piccolo museo dell'informatica. Microsoft Office ed Acces con installazione a dischetti

 




 

lunedì 21 settembre 2026

USGS Tetracorder Docker

Non esistono metodi banali per installare Tetracorder (versione moderna) ma una versione comoda e' costituita da un docker non ufficiale

 


git clone https://github.com/jl-0/tetracorder-lite.git

cd tetracorder-lite

 prima di fare la build si deve modificare il file Containerfile aggiungendo la riga evidenziata in giallo

RUN cd tetracorder &&\
    sed -i "398,416 s/^/#/" AAA.INSTALL.spectroscopy-os-setup-linux.sh &&\
    sed -i "231,254 s/^/#/" AAA.INSTALL.spectroscopy-os-setup-linux.sh &&\
    yes "y" | bash AAA.INSTALL.spectroscopy-os-setup-linux.sh install &&\
    cd tetracorder &&\
    chmod +x checkmultmapcompilemode &&\
    make install &&\
    sed -i "137,140 s/^/#/" multmap.h &&\
    sed -i "144,147 s/^#//" multmap.h &&\
    make installsingle 

a questo punto si fa la build

docker build --platform linux/amd64 -f Containerfile -t tetracorder-lite . 

e si creano dei folder di lavoro

mkdir -p ~/tetracorder/input ~/tetracorder/output 

per controllare che tutto sia a posto si puo' lanciare 

docker run --rm tetracorder-lite tetrapy --help
docker run --rm tetracorder-lite tetrapy run --help

a questo punto siamo pronti a lanciare una prima elaborazione.Il problema e' che  Tetracorder accetta immagini in formato Envi mentre le immagini Emit sono distribuite in formato NetCDF (si devono scarivare sia i dati RFL di riflettanza che RFLUNCERT dell'incertezza della riflettanza

Per la conversione si possono le emit utilities 

git clone https://github.com/nasa/emit-utils.git
cd emit-utils
python emit_utils/reformat.py /path/to/EMIT_L2A_RFL_xxx.nc /path/to/output_envi/ --orthorectify 

funzionano ma non sono riuscito ad installare su Debian pip install xarray netCDF4 rioxarray earthaccess ovvero i modulo per orthorectify...si puo' fare a meno per questa prova

cd ~/emit-utils
python -m emit_utils.reformat ./emit_utils/EMIT_L2A_RFL_001_20260825T085423_2623706_045.nc /home/luca/tetracorder/input/ --orthorectify

arrivati a questo punto si puo' lanciare il processing  

docker run --rm \
  -v ~/tetracorder/input:/data \
  -v ~/tetracorder/output:/output \
  tetracorder-lite \
  tetrapy run config.yml \
    --data.rfl /data/EMIT_L2A_RFL_001_20260825T085423_2623706_045_reflectance \
    --data.rfluncert /data/EMIT_L2A_RFLUNCERT_001_20260825T085423_2623706_045_reflectance_uncertainty 

 

al termine del processing avremo una serie di file tipo la seguente dove

  • group.1um, group.1.5um-broad, group.2um, group.2um-broad — minerali (argille, carbonati, solfati, ecc., a seconda della banda di assorbimento)
  • group.ree, group.ree_g21, group.ree_samar — terre rare (rare earth elements)
  • group.ch4gas-2.3um, group.co2gas-2um — gas (metano, CO2)
  • group.veg — vegetazione
  • case.ep-cal-chl — epidoto/calcite/clorite
  • case.red-edge — red edge della vegetazione
  • case.veg.type — tipologia di vegetazione
  •   

    .
    ./test
    ./test/aggregate
    ./test/aggregate/agg.nc
    ./test/aggregate/config.yml
    ./test/aggregate/agg-uncert.nc
    ./test/aggregate/tetrapy.log
    ./test/tetracorder
    ./test/tetracorder/AAAA.license.txt
    ./test/tetracorder/group.1.5um-broad
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_vbroad_br20.fit.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo89_gds70.d.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow-ice-10mm+0.3water-273k.depth.gz
    ./test/tetracorder/group.1.5um-broad/vegetation1.fit.gz
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.2water-273k.depth.gz
    ./test/tetracorder/group.1.5um-broad/water.high.chlorophyll2.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo18_ki3377.fd.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path+chlrph-a.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.1water-273k.fit.gz
    ./test/tetracorder/group.1.5um-broad/water+mont300gpl.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.2water-273k.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont50gpl.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo60_ki3189.fit.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-300cm-path+chlrph-g.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont0.5gpl.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow.melting16+0.5veg.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/anorthite_hs201.3b.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path+chlrph-a.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-10cm-path-model.depth.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path-model.fit.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting.8.fd.gz
    ./test/tetracorder/group.1.5um-broad/snow-ice-10mm-273k.fd.gz
    ./test/tetracorder/group.1.5um-broad/snow.slush.9.depth.gz
    ./test/tetracorder/group.1.5um-broad/water+mont0.5gpl.fd.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo66_ki3054.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo60_ki3189.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_brd.br22c_actinolite.fit.gz
    ./test/tetracorder/group.1.5um-broad/vegetation1.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont50gpl+0.5veg.fit.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-30cm-path-model.fit.gz
    ./test/tetracorder/group.1.5um-broad/anorthite_hs201.3b.fd.gz
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.3water-273k.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.1water-273k.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/rutile_hs126.3b.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.1water-273k.fd.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-30cm-path-model.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting16+0.5veg.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_nrw.cummingtonite.fd.gz
    ./test/tetracorder/group.1.5um-broad/vegetation.dry+green.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-300cm-path+chlrph-g.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo66_ki3054.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow-ice-1mm-273k.fd.gz
    ./test/tetracorder/group.1.5um-broad/water+mont16.5gpl.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_chlorite.clinochlor.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm-273k.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_vbroad_br20.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path+chlrph-g.fit.gz
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.3water-273k.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/microcline_hs103.3b.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-1mm-273k.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow.slush.9.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/bytownite_hs106.3b.depth.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-10cm-path+chlrph-g.depth.gz
    ./test/tetracorder/group.1.5um-broad/organic_dry_long_grass-thick.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-30cm-path-model.fd.gz
    ./test/tetracorder/group.1.5um-broad/water+mont50gpl+0.5veg.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/vegetation.dry+green.fd.gz
    ./test/tetracorder/group.1.5um-broad/water.turquoise-shallow.fd.gz
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_chlor+muscphy.fit.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path+chlrph-a.fit.gz
    ./test/tetracorder/group.1.5um-broad/water.high.chlorophyll2.fit.gz
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.1water-273k.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont50gpl.fd.gz
    ./test/tetracorder/group.1.5um-broad/bytownite_hs106.3b.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/sphalerite_s26-341_1.5um.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/anorthite_hs201.3b.fit.gz
    ./test/tetracorder/group.1.5um-broad/water+mont5.01gpl.fd.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting.1a.depth.gz
    ./test/tetracorder/group.1.5um-broad/water+mont100gpl.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-10mm+0.3water-273k.fit.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting.8.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo18_ki3377.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow.slush.9.fit.gz
    ./test/tetracorder/group.1.5um-broad/rutile_hs126.3b.depth.gz
    ./test/tetracorder/group.1.5um-broad/vegetation.dry+green.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/sphalerite_s26-341_1.5um.fit.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo89_gds70.a.fit.gz
    ./test/tetracorder/group.1.5um-broad/anorthite_hs201.3b.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow.melting.3.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting.1a.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont16.5gpl.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting.3.fit.gz
    ./test/tetracorder/group.1.5um-broad/water+mont5.01gpl.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/organic_dry_long_grass-thick.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.3water-273k.fd.gz
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_brd.br5a_actinolite.fit.gz
    ./test/tetracorder/group.1.5um-broad/rutile_hs126.3b.fit.gz
    ./test/tetracorder/group.1.5um-broad/water.low.chlorophyll-blue1.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.3water-273k.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/organic_white_pvc_pipe.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_chlor+muscphy.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo91_gds71.b.fd.gz
    ./test/tetracorder/group.1.5um-broad/snow.slush.16.fit.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo89_gds70.d.fit.gz
    ./test/tetracorder/group.1.5um-broad/snow.and.ice-170k.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path+chlrph-g.fd.gz
    ./test/tetracorder/group.1.5um-broad/water.low.chlorophyll-blue1.fd.gz
    ./test/tetracorder/group.1.5um-broad/snow.slush.16.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow.slush.16.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting9+0.5veg.fd.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path+chlrph-a.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo66_ki3054.fd.gz
    ./test/tetracorder/group.1.5um-broad/water+mont100gpl+0.5veg.depth.gz
    ./test/tetracorder/group.1.5um-broad/sphalerite_s26-341_1.5um.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow.melting9+0.5veg.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/organic_green_plastic_tarp.fit.gz
    ./test/tetracorder/group.1.5um-broad/vegetation.dry+green.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-10mm+0.3water-273k.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm-273k.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow.and.ice-248k.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_brd.br5a_actinolite.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_brd.br5a_actinolite.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont16.5gpl.fd.gz
    ./test/tetracorder/group.1.5um-broad/water+mont100gpl.fd.gz
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_vbroad_br20.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-30cm-path-model.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo18_ki3377.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/rutile_hs126.3b.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_nrw.cummingtonite.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_vbroad_br20.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting.8.fit.gz
    ./test/tetracorder/group.1.5um-broad/water.low.chlorophyll.fit.gz
    ./test/tetracorder/group.1.5um-broad/water.turquoise-shallow.fit.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo80_hs285.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo89_gds70.c.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow.melting9+0.5veg.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont1.67gpl.fd.gz
    ./test/tetracorder/group.1.5um-broad/water+mont5.01gpl.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow.melting16+0.5veg.fit.gz
    ./test/tetracorder/group.1.5um-broad/water+mont1.67gpl.fit.gz
    ./test/tetracorder/group.1.5um-broad/water.red.algae.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont1.67gpl.depth.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path+chlrph-g.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.2water-273k.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo66_ki3054.fit.gz
    ./test/tetracorder/group.1.5um-broad/water.high.chlorophyll.fd.gz
    ./test/tetracorder/group.1.5um-broad/water+mont0.5gpl.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/magnetite_hs195.3b.or.olivine.fd.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-300cm-path+chlrph-g.fd.gz
    ./test/tetracorder/group.1.5um-broad/water+mont100gpl.fit.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting.1a.fd.gz
    ./test/tetracorder/group.1.5um-broad/water.low.chlorophyll-blue1.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo18_ki3377.fit.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo60_ki3189.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/magnetite_hs195.3b.or.olivine.fit.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo18_ki3377.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont100gpl+0.5veg.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_chlorite.clinochlor.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont100gpl.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_nrw.cummingtonite.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow.slush.16.fd.gz
    ./test/tetracorder/group.1.5um-broad/water.high.chlorophyll.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-10mm+0.3water-273k.fd.gz
    ./test/tetracorder/group.1.5um-broad/organic_green_plastic_tarp.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont0.5gpl.fit.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo91_gds71.b.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont50gpl.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow.and.ice-248k.depth.gz
    ./test/tetracorder/group.1.5um-broad/organic_green_plastic_tarp.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/bytownite_hs106.3b.fd.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo80_hs285.fit.gz
    ./test/tetracorder/group.1.5um-broad/water.high.chlorophyll2.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-300cm-path+chlrph-g.depth.gz
    ./test/tetracorder/group.1.5um-broad/vegetation1.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_nrw.cummingtonite.fit.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo80_hs285.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water.red.algae.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow.slush.9.fd.gz
    ./test/tetracorder/group.1.5um-broad/water+mont1.67gpl.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.1water-273k.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water.turquoise-shallow.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow.and.ice-170k.depth.gz
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_chlor+muscphy.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/vegetation.dry+green.fit.gz
    ./test/tetracorder/group.1.5um-broad/water+mont300gpl.fit.gz
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.2water-273k.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/sphalerite_s26-341_1.5um.fd.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting.8.depth.gz
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_chlor+muscphy.fd.gz
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_brd.br22c_actinolite.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont50gpl.fit.gz
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_chlor+muscphy.depth.gz
    ./test/tetracorder/group.1.5um-broad/bytownite_hs106.3b.fit.gz
    ./test/tetracorder/group.1.5um-broad/water.low.chlorophyll.fd.gz
    ./test/tetracorder/group.1.5um-broad/magnetite_hs195.3b.or.olivine.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-10mm-273k.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-10cm-path-model.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path-model.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water.turquoise-shallow.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water.low.chlorophyll.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-10mm-273k.fit.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path-model.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water.low.chlorophyll-turquoise.depth.gz
    ./test/tetracorder/group.1.5um-broad/water.red.algae.fd.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo89_gds70.d.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/snow-ice-3mm+0.3water-273k.depth.gz
    ./test/tetracorder/group.1.5um-broad/water+mont100gpl+0.5veg.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water.red.algae.fit.gz
    ./test/tetracorder/group.1.5um-broad/water.high.chlorophyll.depth.gz
    ./test/tetracorder/group.1.5um-broad/organic_white_pvc_pipe.fd.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo89_gds70.a.fd.gz
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path+chlrph-a.fd.gz
    ./test/tetracorder/group.1.5um-broad/snow-ice-10mm-273k.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_vbroad_br20.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo89_gds70.c.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo89_gds70.d.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/anorthite_hs201.3b.depth.gz
    ./test/tetracorder/group.1.5um-broad/water.turquoise-shallow.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow.melting.1a.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_brd.br5a_actinolite.fd.gz
    ./test/tetracorder/group.1.5um-broad/olivine_fo91_gds71.b.depth.gz
    ./test/tetracorder/group.1.5um-broad/microcline_hs103.3b.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/organic_white_pvc_pipe.depth.gz
    ./test/tetracorder/group.1.5um-broad/rutile_hs126.3b.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water-20C-100cm-path+chlrph-a.depth.gz
    ./test/tetracorder/group.1.5um-broad/snow.and.ice-170k.fd.gz
    ./test/tetracorder/group.1.5um-broad/water.turquoise-shallow.fd.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo89_gds70.d.fit.gz.hdr
    ./test/tetracorder/group.1.5um-broad/g4-fe2+generic_brd.br22c_actinolite.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/olivine_fo89_gds70.c.depth.gz
    ./test/tetracorder/group.1.5um-broad/water+mont300gpl.depth.gz.hdr
    ./test/tetracorder/group.1.5um-broad/water+mont0.5gpl.depth.gz

     

    rimane il problema della visualizzazione  

    mkdir -p ~/tetracorder_out
    python tetracorder_iron_oxides.py \
        --group-dir group.2um \
        --filter "kaolgrp_|kaol|smectite_|micagrp_illite|micagrp_vermiculite|chlorite|palygorskite|sepiolite|saponite|hectorite|dickite|nacrite|halloysite|pyroph" \
        --output ~/tetracorder_out/argille_map.png \
        --geotiff ~/tetracorder_out/argille_map.tif \
        --title "Minerali argillosi" 

     

    #!/usr/bin/env python3
    """
    tetracorder_visualize.py
    =========================

    Visualizza una mappa di classificazione prodotta da USGS Tetracorder
    (es. results.cluster, results.cluster.sorted, results.group.X, ...)
    colorando ogni classe secondo il file color.keys prodotto dallo stesso run,
    e generando una legenda con i nomi dei materiali.

    USO
    ---
    python tetracorder_visualize.py \
    --cluster /path/results.cluster.sorted \
    --colorkeys /path/color.keys \
    --output mappa_materiali.png

    Se il file .hdr (ENVI) ha lo stesso nome + ".hdr" o si chiama
    "<cluster>.hdr", viene individuato automaticamente. In alternativa
    si può passare esplicitamente con --hdr.

    DIPENDENZE
    ----------
    pip install numpy matplotlib
    # opzionale ma consigliato (lettura ENVI con georeferenziazione):
    pip install rasterio

    NOTE SUL PARSING DI color.keys
    -------------------------------
    Il formato del file color.keys di Tetracorder non è uno standard fisso:
    varia leggermente tra versioni. Questo script prova diversi pattern
    comuni (vedi funzione `parse_color_keys`). Se il parsing fallisce o i
    colori/nomi non tornano, lancia lo script con --debug-colorkeys per
    vedere riga per riga cosa viene interpretato, e poi mandami un estratto
    delle prime ~10 righe del tuo file color.keys così affino il parser.
    """

    import argparse
    import re
    import sys
    from pathlib import Path

    import numpy as np
    import matplotlib.pyplot as plt
    from matplotlib.colors import ListedColormap, BoundaryNorm
    from matplotlib.patches import Patch


    # --------------------------------------------------------------------------
    # Lettura immagine ENVI (results.cluster, results.group.X, ecc.)
    # --------------------------------------------------------------------------

    def find_hdr(cluster_path: Path) -> Path:
    """Cerca l'header ENVI associato al file dati."""
    candidates = [
    cluster_path.with_suffix(cluster_path.suffix + ".hdr"),
    cluster_path.with_suffix(".hdr"),
    Path(str(cluster_path) + ".hdr"),
    ]
    for c in candidates:
    if c.exists():
    return c
    raise FileNotFoundError(
    f"Nessun file .hdr trovato per {cluster_path}. "
    f"Passalo esplicitamente con --hdr."
    )


    def parse_envi_hdr(hdr_path: Path) -> dict:
    """Parser minimale di un header ENVI (testo chiave=valore)."""
    text = hdr_path.read_text(errors="ignore")
    info = {}
    for key in ("samples", "lines", "bands", "data type",
    "interleave", "byte order", "header offset"):
    m = re.search(rf"{key}\s*=\s*(\S+)", text, re.IGNORECASE)
    if m:
    info[key.replace(" ", "_")] = m.group(1)
    required = ("samples", "lines", "data_type")
    missing = [k for k in required if k not in info]
    if missing:
    raise ValueError(f"Header ENVI incompleto, mancano: {missing}")
    return info


    ENVI_DTYPES = {
    "1": np.uint8, "2": np.int16, "3": np.int32, "4": np.float32,
    "5": np.float64, "6": np.complex64, "9": np.complex128,
    "12": np.uint16, "13": np.uint32, "14": np.int64, "15": np.uint64,
    }


    def read_envi_raw(data_path: Path, hdr: dict) -> np.ndarray:
    """Legge un raster ENVI senza dipendenze esterne (fallback)."""
    samples = int(hdr["samples"])
    lines = int(hdr["lines"])
    bands = int(hdr.get("bands", 1))
    dtype = ENVI_DTYPES.get(hdr.get("data_type", "2"), np.int16)
    offset = int(hdr.get("header_offset", 0))
    byte_order = hdr.get("byte_order", "0")
    interleave = hdr.get("interleave", "bsq").lower()

    arr = np.fromfile(data_path, dtype=dtype, offset=offset)
    expected = samples * lines * bands
    arr = arr[:expected]
    if byte_order == "1": # big-endian
    arr = arr.byteswap().newbyteorder()

    if interleave == "bsq":
    arr = arr.reshape(bands, lines, samples)
    elif interleave == "bil":
    arr = arr.reshape(lines, bands, samples).transpose(1, 0, 2)
    elif interleave == "bip":
    arr = arr.reshape(lines, samples, bands).transpose(2, 0, 1)
    else:
    raise ValueError(f"Interleave ENVI non riconosciuto: {interleave}")

    return arr[0] if bands == 1 else arr


    def load_cluster_map(cluster_path: Path, hdr_path: Path | None) -> np.ndarray:
    """Carica la mappa raster, usando rasterio se disponibile."""
    try:
    import rasterio
    with rasterio.open(cluster_path) as src:
    return src.read(1)
    except Exception:
    pass # fallback manuale

    if hdr_path is None:
    hdr_path = find_hdr(cluster_path)
    hdr = parse_envi_hdr(hdr_path)
    band = read_envi_raw(cluster_path, hdr)
    if band.ndim == 3:
    band = band[0]
    return band


    # --------------------------------------------------------------------------
    # Metadati di classificazione incorporati nell'header ENVI
    # (class names / class lookup) - spesso è qui, non in un color.keys esterno
    # --------------------------------------------------------------------------

    def parse_envi_classification(hdr_path: Path) -> dict | None:
    """
    Cerca nel .hdr i campi ENVI standard:
    class names = {Unclassified, Kaolinite, Goethite, ...}
    class lookup = {0,0,0, 255,0,0, 200,120,0, ...}
    e ritorna {id: (r,g,b,nome)} se presenti, altrimenti None.
    """
    text = hdr_path.read_text(errors="ignore")

    def extract_braced(field):
    m = re.search(rf"{field}\s*=\s*\{{([^}}]*)\}}", text,
    re.IGNORECASE | re.DOTALL)
    return m.group(1) if m else None

    names_raw = extract_braced("class names")
    lookup_raw = extract_braced("class lookup")
    if not names_raw or not lookup_raw:
    return None

    names = [n.strip() for n in names_raw.split(",") if n.strip()]
    nums = [int(x) for x in re.findall(r"-?\d+", lookup_raw)]
    if len(nums) < len(names) * 3:
    return None

    result = {}
    for i, name in enumerate(names):
    r, g, b = nums[i * 3], nums[i * 3 + 1], nums[i * 3 + 2]
    result[i] = (r, g, b, name)
    return result


    # --------------------------------------------------------------------------
    # Parsing color.keys (file di testo esterno, se lo trovi separatamente)
    # --------------------------------------------------------------------------

    def parse_color_keys(path: Path, debug: bool = False) -> dict:
    """
    Ritorna {id_materiale: (r, g, b, nome)}.

    Prova più pattern, perché il formato varia tra run Tetracorder:
    1) " 12 255 128 0 Kaolinite_CM9.spc"
    2) "12 Kaolinite_CM9 R=255 G=128 B=0"
    3. CSV-like: "12,255,128,0,Kaolinite"
    """
    patterns = [
    re.compile(r"^\s*(\d+)\s+(\d+)\s+(\d+)\s+(\d+)\s+(\S.*)$"),
    re.compile(r"^\s*(\d+)\s+(\S+).*?R\s*=?\s*(\d+).*?G\s*=?\s*(\d+).*?B\s*=?\s*(\d+)", re.IGNORECASE),
    re.compile(r"^\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*,\s*(\S.*)$"),
    ]

    result = {}
    unmatched = []
    for raw_line in path.read_text(errors="ignore").splitlines():
    line = raw_line.strip()
    if not line or line.startswith("#") or line.startswith(";"):
    continue

    m = patterns[0].match(line)
    if m:
    idx, r, g, b, name = m.groups()
    result[int(idx)] = (int(r), int(g), int(b), name.strip())
    continue

    m = patterns[1].match(line)
    if m:
    idx, name, r, g, b = m.groups()
    result[int(idx)] = (int(r), int(g), int(b), name.strip())
    continue

    m = patterns[2].match(line)
    if m:
    idx, r, g, b, name = m.groups()
    result[int(idx)] = (int(r), int(g), int(b), name.strip())
    continue

    unmatched.append(raw_line)

    if debug:
    print(f"[debug] {len(result)} voci interpretate, "
    f"{len(unmatched)} righe non riconosciute.")
    for u in unmatched[:15]:
    print(" ??", u)

    if not result:
    raise ValueError(
    "Nessuna riga di color.keys è stata interpretata. "
    "Rilancia con --debug-colorkeys e mandami le prime righe del file "
    "cosi' adatto il parser al formato esatto."
    )
    return result


    # --------------------------------------------------------------------------
    # Plot
    # --------------------------------------------------------------------------

    def plot_classification(class_map: np.ndarray, color_keys: dict,
    output: Path, title: str, max_legend_items: int = 40):
    present_ids = sorted(i for i in np.unique(class_map) if i != 0 and i in color_keys)

    if not present_ids:
    print("Attenzione: nessun ID presente nella mappa ha una corrispondenza "
    "in color.keys. Controlla che i due file provengano dallo stesso run.")

    # id 0 = nessun match -> sfondo grigio chiaro
    ids = [0] + present_ids
    colors = [(0.92, 0.92, 0.92)]
    labels = ["(nessun match)"]
    for i in present_ids:
    r, g, b, name = color_keys[i]
    colors.append((r / 255, g / 255, b / 255))
    labels.append(f"{i}: {name}")

    cmap = ListedColormap(colors)
    bounds = ids + [ids[-1] + 1]
    norm = BoundaryNorm(bounds, cmap.N)

    remap = np.zeros_like(class_map, dtype=np.int32)
    for new_i, orig_i in enumerate(ids):
    remap[class_map == orig_i] = new_i

    fig, ax = plt.subplots(figsize=(10, 8))
    ax.imshow(remap, cmap=ListedColormap(colors), interpolation="nearest")
    ax.set_title(title)
    ax.set_xticks([])
    ax.set_yticks([])

    legend_ids = present_ids[:max_legend_items]
    handles = [Patch(facecolor=(color_keys[i][0] / 255,
    color_keys[i][1] / 255,
    color_keys[i][2] / 255),
    label=f"{color_keys[i][3]}")
    for i in legend_ids]
    if len(present_ids) > max_legend_items:
    handles.append(Patch(facecolor="white",
    label=f"... +{len(present_ids) - max_legend_items} altri"))

    ax.legend(handles=handles, bbox_to_anchor=(1.02, 1), loc="upper left",
    fontsize=7, frameon=False, ncol=1)

    fig.tight_layout()
    fig.savefig(output, dpi=200, bbox_inches="tight")
    print(f"Salvato: {output} ({len(present_ids)} materiali distinti trovati)")


    # --------------------------------------------------------------------------
    # Main
    # --------------------------------------------------------------------------

    def main():
    p = argparse.ArgumentParser(description=__doc__,
    formatter_class=argparse.RawDescriptionHelpFormatter)
    p.add_argument("--cluster", required=True, type=Path,
    help="File risultati (es. results.cluster.sorted)")
    p.add_argument("--hdr", type=Path, default=None,
    help="Header ENVI (.hdr), se non individuabile automaticamente")
    p.add_argument("--colorkeys", required=False, type=Path, default=None,
    help="File color.keys testuale (opzionale: se assente, "
    "lo script cerca 'class names'/'class lookup' "
    "direttamente nell'header ENVI del raster)")
    p.add_argument("--output", type=Path, default=Path("tetracorder_map.png"),
    help="File immagine di output (default: tetracorder_map.png)")
    p.add_argument("--title", default="Classificazione Tetracorder")
    p.add_argument("--debug-colorkeys", action="store_true",
    help="Stampa il dettaglio del parsing di color.keys")
    args = p.parse_args()

    class_map = load_cluster_map(args.cluster, args.hdr)

    color_keys = None
    hdr_path = args.hdr or find_hdr(args.cluster)
    if hdr_path.exists():
    color_keys = parse_envi_classification(hdr_path)
    if color_keys:
    print(f"Trovate {len(color_keys)} classi nei metadati ENVI "
    f"dell'header ({hdr_path.name}).")

    if color_keys is None:
    if args.colorkeys is None:
    print("Nessuna classificazione trovata nell'header ENVI e "
    "nessun --colorkeys fornito. Passa un file color.keys "
    "testuale con --colorkeys, oppure mandami un estratto "
    "del .hdr per capire dove sta l'informazione colore/nome.",
    file=sys.stderr)
    sys.exit(1)
    color_keys = parse_color_keys(args.colorkeys, debug=args.debug_colorkeys)

    plot_classification(class_map, color_keys, args.output, args.title)


    if __name__ == "__main__":
    sys.exit(main())


     

     

     

    Microsoft office a dischetti

     Una nuova acquisizione per il mio piccolo museo dell'informatica. Microsoft Office ed Acces con installazione a dischetti