(Debug) In[1]:=
halitevideo=
(Debug) Out[1]=
(Debug) In[7]:=
halitevideo=Import["C:\\Users\\Manu\\Documents\\Mathematica programs\\Th Bergen Holocene\\Pictures_Bergen\\bubble_nucleation_WillArnuk.m4v"]
(Debug) Out[7]=
(Debug) In[3]:=
Export["C:\\Users\\Manu\\Documents\\Wolfram Summer School\\Project\\haliteimgfromvideo.jpeg",halitevideo]
(Debug) Out[3]=
C:\Users\Manu\Documents\Wolfram Summer School\Project\haliteimgfromvideo.jpeg
Video of an initially all-liquid halite fluid inclusion, in which a vapor bubble is nucleated by means of a femtosecond laser pulse.
Background​
​
Fluid inclusions are tiny water pockets (~1 - 100 µm) trapped in crystals. Their density informs on the temperature of the parent water at the moment of crystal formation. Fluid inclusions in minerals formed at the Earth’s surface could be used to unravel the evolution of the Earth’s climate throughout geological time. Attempts to recover paleo-temperatures (“paleo” meaning “past”) from halite (NaCl) fluid inclusions have been led for 30+ years, but, until recently, techniques that were applied tended to alter the fluid inclusions and yield spurious results. Collaborative work between the University of Lyon, France, the University of Bergen, Norway and Binghamton University, USA, has led to major experimental developments. These breakthroughs now allow to circumvent the issue of fluid inclusion alteration, opening the way to physically-based reconstructions of paleo-temperatures.
​
Halite fluid inclusion paleothermometry relies on finding the temperature at which the vapor-saturated liquid fills the cavity. From the temperature obtained in the lab
T
obs
to the actual paleo-temperature of the parent water
T
f
, correction terms accounting for (i) the liquid surface tension and (ii) the weight of the parent water column must be applied. Before this project, we created a model to calculate these corrections. However, as these corrections depend on the chemical composition of the parent water, the corrections are different for every halite sample. Moreover, the model includes relatively numerous and long equations that are not easily handled.
​
​Project description
​​
We develop a code that automatizes the formatting of the input data, the calculation of the corrections and the generation of a notebook containing the output dataset and various graphs necessary for halite fluid inclusion paleo-thermometry. The input is a series of spreadsheet (csv) containing the information of each fluid inclusion (
T
obs
, size, composition, water column height) for each sample. The computational result is a standardized data structure including the input data and the analysis results.

Input Data

To make this code work, you need to import one or more csv files with the following structure:
(Debug) Out[12]//TableForm=
Fluid inclusion
NaCl (molal)
KCl (molal)
MgCl2 (molal)
CaCl2 (molal)
Na2SO4 (molal)
NaHCO3 (molal)
water column height (m)
length (?m)
width (?m)
Tobs (°C)
1
1.93
0.2
2
0.45
0
0
250
11
10
45
7
1.93
0.2
2
0.45
0
0
250
12
11
19
foo
1.93
0.2
2
0.45
0
0
250
16
10
2
bar
1.93
0.2
2
0.45
0
0
250
10
8
26
All elements must be numbers except the first column (fluid inclusion name) and the first line (headers). The file(s) must contain “Brillouin” or “Microthermometry” in its (their) name(s). Several files can be imported in the same run, but a mix of “Brillouin” and “Microthermometry” cannot be processed.

Import Button

We created a button that imports the files. Error messages are returned if the files do not have the correct structure, correct names, and numbers at the expected locations. Two different types of experimental data can be imported, depending on what technique was used to obtain the data (Brillouin spectroscopy or Microthermometry). They are processed differently in the remainder of this notebook.
(Debug) In[1]:=
ClearAll[{file,data,importButton,haliteFIdataset,haliteFIsamplenames}]​​importButton[textbutton_String,filefmt:{___String}(*":"means"only in the case of the following pattern"*)]:=Button[textbutton,​​​​nCol=11;​​errorDim=Quantity[1,"Micrometers"];​​​​(file=SystemDialogInput["FileOpen",{Directory[],{"Data files"->filefmt}}]);​​filedepth=Depth[file];​​​​If[file=!=$Canceled,​​data=If[filedepth>1,Table[Import[file[[i]]],{i,1,Length[file]}],Import[file]];​​​​If[filedepth>1,​​fileNcol=Map[Length,data,{2}],​​fileNcol=Map[Length,data,{1}]];​​​​If[MatchQ[fileNcol,{{nCol..}..}|{nCol..}],​​​​haliteFIsamplenames=​​If[filedepth>1,​​Map[StringTake[#,StringPosition[#,"\\"][[-1,1]]+1;;-5]&,file],​​{StringTake[file,StringPosition[file,"\\"][[-1,1]]+1;;-5]}​​]//Echo;​​​​brillouinQ=AllTrue[StringContainsQ[haliteFIsamplenames,"Brillouin"],TrueQ,1];​​microthermoQ=AllTrue[StringContainsQ[haliteFIsamplenames,"Microthermometry"],TrueQ,1];​​If[TrueQ[brillouinQ]||TrueQ[microthermoQ],​​​​If[AllTrue[If[filedepth>1,data[[All,2;;,2;;]],data[[2;;,2;;]]],NumberQ,If[filedepth>1,3,2]],​​​​,​​​​Print[​​Style["File data error. All but one columns and all but one lines must contain numbers. Exception: first line (headers) and first column (fluid inclusions name).",Directive[Red]]]​​],​​​​Print[​​Style["File name error. All files must contain the mention 'Brillouin' or 'Microthermometry'. Note that the program cannot process a mix of 'Brillouin' and 'Microthermometry' files.",Directive[Red]]]​​],​​​​Print[​​Style["File structure error. All imported files must have "<>ToString[nCol]<>" columns.",Directive[Red]]]​​],​​Print["Canceled"]​​],​​Method->"Queued"​​]
(Debug) In[3]:=
importButton["Import sample files (csv)",{"*.csv"}]
(Debug) Out[3]=
Import sample files (csv)
»
{MicrothermometrySample7,MicrothermometrySample6,MicrothermometrySample5,MicrothermometrySample4,MicrothermometrySample3,MicrothermometrySample2,MicrothermometrySample1}

Define Keys

We defined headers (to become association “Keys”) for the input and output data
(Debug) In[4]:=
keyslvl1=​​If[Depth[data]>3,​​Table[""<>ToString[i],{j,1,Length@data},{i,1,Length@data[[j]]-1}],​​Table[""<>ToString[i],{i,1,Length@data-1}]​​];​​Switch[microthermoQ,​​True,​​keyslvl2=<|"FluidInclusion"->"Fluid inclusion",Entity["Chemical","SodiumChloride"]->Identity,Entity["Chemical","PotassiumChloride"]->Identity,Entity["Chemical","MagnesiumChloride"]->Identity,Entity["Chemical","CalciumChloride"]->Identity,Entity["Chemical","SodiumSulfate"]->Identity,Entity["Chemical","SodiumHydrogencarbonate"]->Identity,"WaterColumnHeight"->"Water column height","Length"->Identity,"Width"->Identity,"ObservedHomogenizationTemperature"->"Th,obs","Size"->"Size","Area"->"Area","Volume"->"Volume","deltaTLaplacePressure"->"ΔTL","InfiniteHomogenizationTemperature"->"Th,inf","deltaTHydrostaticPressure"->"ΔTP","FormationTemperature"->"Tf"|>,​​False,​​keyslvl2=<|"FluidInclusion"->"Fluid inclusion",Entity["Chemical","SodiumChloride"]->Identity,Entity["Chemical","PotassiumChloride"]->Identity,Entity["Chemical","MagnesiumChloride"]->Identity,Entity["Chemical","CalciumChloride"]->Identity,Entity["Chemical","SodiumSulfate"]->Identity,Entity["Chemical","SodiumHydrogencarbonate"]->Identity,"WaterColumnHeight"->"Water column height","Length"->Identity,"Width"->Identity,"BrillouinIntersectionTemperature"->"Tx","Size"->"Size","Area"->"Area","Volume"->"Volume","InfiniteHomogenizationTemperature"->"Th,inf","deltaTHydrostaticPressure"->"ΔTP","FormationTemperature"->"Tf"|>​​];

Make Association

We created an association with three levels: level 1: samples level 2: fluid inclusions level 3: fluid inclusion characteristics
(Debug) In[6]:=
ifMicrothermoBrillouin:=If[microthermoQ,"ObservedHomogenizationTemperature","BrillouinIntersectionTemperature"];​​inputAssociation0=​​With[{pos=Keys[keyslvl2]//Position[#,ifMicrothermoBrillouin][[1,1]]&},​​If[Depth[data]>3,​​AssociationThread[​​haliteFIsamplenames->Table[​​AssociationThread[​​keyslvl1[[i]]->Map[Association[Thread[Keys[keyslvl2[[;;pos]]]->#]]&,Rest[data[[i]]]]​​],​​{i,1,Length[data]}]​​],​​<|haliteFIsamplenames->AssociationThread[​​keyslvl1->Map[Association[Thread[Keys[keyslvl2[[;;pos]]]->#]]&,Rest[data]]​​]|>​​]​​];

Create Fourth Level in the Association

The concentrations of every salt in the fluid inclusion make up a group of characteristics that can be gathered in an overarching one: “Concentration”. We created a fourth level of association.
(Debug) In[8]:=
inputAssociation=​​Map[​​Insert[KeySelect[#,StringQ],{"Concentration"->KeySelect[#,Not@*StringQ(*sameasNot[StringQ[#]]&*)]},"WaterColumnHeight"]&,​​inputAssociation0,​​{2}​​];

Define Quantities and Uncertainties

Each datum has a quantity that can be defined with the
Quantity
function of the Wolfram Language. Similarly, some data have an uncertainty, that we defined with the
Around
function. We defined and applied functions that map these quantities and uncertainties to all the input data.
(Debug) In[9]:=
ErrorDim=Quantity[1,"Micrometers"];​​mapDegreeCelsius[association3lvl_?AssociationQ]:=MapAt[Quantity[#,"DegreesCelsius"]&,association3lvl,{All,All,ifMicrothermoBrillouin}];​​mapLength[association3lvl_?AssociationQ]:=MapAt[Around[Quantity[#,"Micrometers"],errorDim]&,association3lvl,{All,All,"Length"}];​​mapWidth[association3lvl_?AssociationQ]:=MapAt[Around[Quantity[#,"Micrometers"],errorDim]&,association3lvl,{All,All,"Width"}];​​mapWaterHeight[association3lvl_?AssociationQ]:=MapAt[Quantity[#,"Meters"]&,association3lvl,{All,All,"WaterColumnHeight"}];​​mapCompo[association4lvl_?AssociationQ]:=MapAt[Quantity[#,"Molal"]&,association4lvl,{All,All,"Concentration",All}];​​inputAssociation2=mapCompo@mapDegreeCelsius@mapLength@mapWidth@mapWaterHeight@inputAssociation;

Process Data

Calculate Fluid Inclusion Dimensions (Average Size, Area, Volume)

(Debug) In[16]:=
FISize=Map[<|"Size"->#|>&,Map[N@Sqrt[#["Length"]*#["Width"]]&,inputAssociation2,{2}],{2}];​​FIArea=Map[<|"Area"->#|>&,Map[N@(#["Length"]*#["Width"])&,inputAssociation2,{2}],{2}];​​FIVolume=Map[<|"Volume"->#|>&,Map[N@((#["Length"]*#["Width"])^(3/2))&,inputAssociation2,{2}],{2}];

Laplace Pressure Correction Term

The surface tension between a vapor bubble and the surrounding liquid induces a pressure differential (Laplace pressure) that forces the disappearance of the bubble at a temperature lower than if this effect did not exist. This effect must be corrected. For that we use the function
deltaTLaplacePressure
. The deltaTLaplacePressure term is added to the experimental temperature. The resulting temperature is called “Infinite homogenization temperature”. Note that this correction is only needed if the experimental data were obtained via microthermometry (observation of vapour bubble disappearance).
The use of the real
deltaTLaplacePressure
function would involve several packages dependencies; as this community post’s purpose is purely illustrative, here we just define a simple, non accurate
deltaTLaplacePressure
function.
We append the calculated values to the input association.
(Debug) In[19]:=
deltaTLaplacePressure[T_,deltaSolubility_,mNaCl_,mKCl_,mMgCl2_,mCaCl2_,mNa2SO4_,mNaHCO3_,mSrCl2_,volume_]:=1000^0.3/volume^0.3
(Debug) In[20]:=
If[microthermoQ,​​deltaTLaplacePressureTerm=Map[<|"deltaTLaplacePressure"->#|>&,​​Map[​​Quantity[​​deltaTLaplacePressure[Delete[Thread[QuantityMagnitude[{#["ObservedHomogenizationTemperature"],0.005(*thinkthisfurther*),#["Concentration"][Entity["Chemical","SodiumChloride"]],#["Concentration"][Entity["Chemical","PotassiumChloride"]],#["Concentration"][Entity["Chemical","MagnesiumChloride"]],#["Concentration"][Entity["Chemical","CalciumChloride"]],#["Concentration"][Entity["Chemical","SodiumSulfate"]],#["Concentration"][Entity["Chemical","SodiumHydrogencarbonate"]],0,​​(QuantityMagnitude@(#["Length"]*#["Width"]))^(3/2)}]],0]​​],​​"DegreesCelsiusDifference"]&,​​inputAssociation2,​​{2}],​​{2}];​​outputAssociation=​​Map[​​Append[#,​​With[{pos1=Position[inputAssociation2,#][[1,1]][[1]],pos2=Position[inputAssociation2,#][[1,2]][[1]]},​​<|FISize[pos1,pos2],FIArea[pos1,pos2],FIVolume[pos1,pos2],deltaTLaplacePressureTerm[pos1,pos2]|>](*#isthesecondlevelofinputAssociation2,[[1,1]]picksthelevel1key,[[1,2]]picksthelevel2keyand[[1]]spitsthekeystring*)]&,​​inputAssociation2,{2}];​​Thinf=Map[<|"InfiniteHomogenizationTemperature"->#|>&,Map[UnitConvert[(#["ObservedHomogenizationTemperature"]+#["deltaTLaplacePressure"]),"DegreesCelsius"]&,outputAssociation,{2}],{2}],​​​​outputAssociation=​​Map[​​Append[#,​​With[{pos1=Position[inputAssociation2,#][[1,1]][[1]],pos2=Position[inputAssociation2,#][[1,2]][[1]]},​​<|FISize[pos1,pos2],FIArea[pos1,pos2],FIVolume[pos1,pos2]|>](*#isthesecondlevelofinputAssociation2,[[1,1]]picksthelevel1key,[[1,2]]picksthelevel2keyand[[1]]spitsthekeystring*)]&,​​inputAssociation2,{2}];​​​​Thinf=Map[<|"InfiniteHomogenizationTemperature"->#|>&,Map[UnitConvert[Around[#["BrillouinIntersectionTemperature"],Quantity[10^-3,"DegreesCelsius"]],"DegreesCelsius"]&,outputAssociation,{2}],{2}];​​];​​​​outputAssociation=​​Map[Append[#,​​With[{pos1=Position[outputAssociation,#][[1,1]][[1]],pos2=Position[outputAssociation,#][[1,2]][[1]]},​​Thinf[pos1,pos2]](*#isthesecondlevelofoutputAssociation,[[1,1]]picksthelevel1key,[[1,2]]picksthelevel2keyand[[1]]spitsthekeystring*)]&,​​outputAssociation,{2}];​​Short[outputAssociation,20]
(Debug) Out[22]//Short=
MicrothermometrySample71FluidInclusion2,Concentration
sodium chloride

1.5
molal
,
potassium chloride

0.3
molal
,
magnesium chloride

1
molal
,
calcium chloride

0.4
molal
,
sodium sulfate

0.2
molal
,
sodium bicarbonate

0.5
molal
,WaterColumnHeight
100.1
m
,Length
(50.2
±
1.0
)
μm
,Width
(40.0
±
1.0
)
μm
,ObservedHomogenizationTemperature
15.2
°C
,Size
(44.8
±
0.7
)
μm
,Area
(2008.
±
64.
)
2
μm
,Volume
(9.0
±
0.4
)×
4
10
3
μm
,deltaTLaplacePressure
(0.259
±
0.004
)
◦
Δ
C
,InfiniteHomogenizationTemperature
(15.459
±
0.004
)
°C
,5,7FluidInclusionix,Concentration
sodium chloride

1.5
molal
,
potassium chloride

0.3
molal
,
magnesium chloride

1
molal
,
calcium chloride

0.4
molal
,
sodium sulfate

0.2
molal
,
sodium bicarbonate

0.5
molal
,WaterColumnHeight
100.1
m
,Length
(20.0
±
1.0
)
μm
,Width
(15.0
±
1.0
)
μm
,ObservedHomogenizationTemperature
17.65
°C
,Size
(17.3
±
0.7
)
μm
,Area
(300.
±
25.
)
2
μm
,Volume
(5196.
±
650.
)
3
μm
,deltaTLaplacePressure
(0.610
±
0.023
)
◦
Δ
C
,InfiniteHomogenizationTemperature
(18.260
±
0.023
)
°C
,5,MicrothermometrySample11

Water Column Pressure Correction Term

The we calculate the temperature correction to take into account the effect of the weight of the water column during the entrapment of the fluid inclusion.
Same as for deltaTLaplacePressure: The use of the real deltaTHydrostaticPressureNum function would involve several packages dependencies; as this community post’s purpose is purely illustrative, here we just define a simple, non accurate deltaTHydrostaticPressureNum function.
(Debug) In[23]:=
deltaTHydrostaticPressureNum[Tinf_,h_,g_,deltaSolubility_,mNaCl_,mKCl_,mMgCl2_,mCaCl2_,mNa2SO4_,mNaHCO3_,mSrCl2_]=0.01*h;
(Debug) In[24]:=
ClearAll[meanDeltaTHydrostaticPressureTerm];​​meanDeltaTHydrostaticPressureTerm[dataset_?AssociationQ]:=meanDeltaTHydrostaticPressureTerm[dataset]=​​Quantity[​​deltaTHydrostaticPressureNum[​​Delete[​​Thread[​​QuantityMagnitude[{(QuantityMagnitude@Mean@Values[Lookup["InfiniteHomogenizationTemperature"]/@dataset])["Value"],dataset[[1]]["WaterColumnHeight"],9.8,0.005(*thinkthisfurther*),dataset[[1]]["Concentration"][Entity["Chemical","SodiumChloride"]],dataset[[1]]["Concentration"][Entity["Chemical","PotassiumChloride"]],dataset[[1]]["Concentration"][Entity["Chemical","MagnesiumChloride"]],dataset[[1]]["Concentration"][Entity["Chemical","CalciumChloride"]],dataset[[1]]["Concentration"][Entity["Chemical","SodiumSulfate"]],dataset[[1]]["Concentration"][Entity["Chemical","SodiumHydrogencarbonate"]],0}]​​],​​0]​​],​​"DegreesCelsiusDifference"];​​​​ClearAll[appendMeanDeltaTHydrostaticPressureTerm];​​appendMeanDeltaTHydrostaticPressureTerm[dataset_?AssociationQ]:=Append[#,"deltaTHydrostaticPressure"->meanDeltaTHydrostaticPressureTerm[dataset]]&/@dataset;​​outputAssociation2=appendMeanDeltaTHydrostaticPressureTerm/@outputAssociation;​​Tf=Map[<|"FormationTemperature"->#|>&,Map[UnitConvert[(#["InfiniteHomogenizationTemperature"]+#["deltaTHydrostaticPressure"]),"DegreesCelsius"]&,outputAssociation2,{2}],{2}];​​outputAssociation3=​​Map[​​Append[#,​​With[{pos1=Position[outputAssociation2,#][[1,1]][[1]],pos2=Position[outputAssociation2,#][[1,2]][[1]]},​​Tf[pos1,pos2]](*#isthesecondlevelofoutputAssociation2,[[1,1]]picksthelevel1key,[[1,2]]picksthelevel2keyand[[1]]spitsthekeystring*)]&,​​outputAssociation2,{2}];

Output Dataset

The dataset structure of Mathematica can be easily obtained from an association by means of the
Dataset
function. Here, the association has 4 levels, which can be explored by clicking headers (“keys”) to expand parts of the table.
The first level is the samples
The second level is the fluid inclusions.
The third level is the characteristics of the fluid inclusions.
A fourth level is used for the Concentration, which breaks down into several salts.
(Debug) In[31]:=
outputDataset=Dataset@outputAssociation3
(Debug) Out[31]=
FluidInclusion
Concentration
WaterColumnHeight
Length
Width
ObservedHomogenizationTemperature
Size
Area
Volume
deltaTLaplacePressure
MicrothermometrySample7
1
2
sodium chloride
1.5molal
100.1m
(50.2
±
1.0
)μm
(40.0
±
1.0
)μm
15.2°C
(44.8
±
0.7
)μm
(2008.
±
64.
)
2
μm
(9.0
±
0.4
)×
4
10
3
μm
(0.259
±
0.004
)
◦
Δ
C
potassium chloride
0.3molal
6 total ›
2
2
sodium chloride
1.5molal
100.1m
(12.0
±
1.0
)μm
(10.0
±
1.0
)μm
16.4°C
(11.0
±
0.7
)μm
(120.
±
16.
)
2
μm
(1315.
±
257.
)
3
μm
(0.92
±
0.05
)
◦
Δ
C
potassium chloride
0.3molal
6 total ›
7 total ›
MicrothermometrySample6
1
oui
sodium chloride
3.2molal
10.5m
(2.0
±
1.0
)μm
(2.0
±
1.0
)μm
30.5°C
(2.0
±
0.7
)μm
(4.0
±
2.8
)
2
μm
(8.
±
8.
)
3
μm
(4.3
±
1.4
)
◦
Δ
C
potassium chloride
0.3molal
6 total ›
2
non
sodium chloride
3.2molal
10.5m
(9.0
±
1.0
)μm
(15.0
±
1.0
)μm
35.4°C
(11.6
±
0.8
)μm
(135.
±
17.
)
2
μm
(1569.
±
305.
)
3
μm
(0.87
±
0.05
)
◦
Δ
C
potassium chloride
0.3molal
6 total ›
7 total ›
MicrothermometrySample5
1
2
sodium chloride
1.5molal
100.1m
(50.2
±
1.0
)μm
(40.0
±
1.0
)μm
15.2°C
(44.8
±
0.7
)μm
(2008.
±
64.
)
2
μm
(9.0
±
0.4
)×
4
10
3
μm
(0.259
±
0.004
)
◦
Δ
C
potassium chloride
0.3molal
6 total ›
2
2
sodium chloride
1.5molal
100.1m
(12.0
±
1.0
)μm
(10.0
±
1.0
)μm
16.4°C
(11.0
±
0.7
)μm
(120.
±
16.
)
2
μm
(1315.
±
257.
)
3
μm
(0.92
±
0.05
)
◦
Δ
C
potassium chloride
0.3molal
6 total ›
7 total ›
MicrothermometrySample4
1
x
sodium chloride
1.8molal
310m
(15.0
±
1.0
)μm
(12.0
±
1.0
)μm
25.1°C
(13.4
±
0.7
)μm
(180.
±
19.
)
2
μm
(2415.
±
387.
)
3
μm
(0.77
±
0.04
)
◦
Δ
C
potassium chloride
0.18molal
6 total ›
2
5
sodium chloride
1.8molal
310m
(20.0
±
1.0
)μm
(18.0
±
1.0
)μm
24°C
(19.0
±
0.7
)μm
(360.
±
27.
)
2
μm
(6831.
±
766.
)
3
μm
(0.562
±
0.019
)
◦
Δ
C
potassium chloride
0.18molal
6 total ›
12 total ›
MicrothermometrySample3
1
1
sodium chloride
6molal
150m
(5.0
±
1.0
)μm
(5.0
±
1.0
)μm
10°C
(5.0
±
0.7
)μm
(25.
±
7.
)
2
μm
(125.
±
53.
)
3
μm
(1.87
±
0.24
)
◦
Δ
C
potassium chloride
0molal
6 total ›
2
2
sodium chloride
6molal
150m
(2.0
±
1.0
)μm
(2.0
±
1.0
)μm
20°C
(2.0
±
0.7
)μm
(4.0
±
2.8
)
2
μm
(8.
±
8.
)
3
μm
(4.3
±
1.4
)
◦
Δ
C
potassium chloride
0molal
6 total ›
45 total ›
rows 1–5 of
7
columns 1–10 of
13

Output Graphs

The output graphs show Tf vs. size. In halite fluid inclusion paleo-thermometry, Tf-size trends are indicative of damage or wrong surface tension correction.
(Debug) In[32]:=
datalist=Values[Map[QuantityMagnitude,Map[Values,outputAssociation3[[All,All,{"Size","FormationTemperature"}]],2]]];​​If[Depth@datalist<5,datalist={datalist}];​​tickSize=0.02;​​GraphPartition=5;​​Ngraphs=Length[datalist];​​MinMaxSizeTf=Table[{​​{Min[datalist[[Sample,All,1]]]["Value"],Max[datalist[[Sample,All,1]]]["Value"]},​​{Min[datalist[[Sample,All,2]]]["Value"],Max[datalist[[Sample,All,2]]]["Value"]}},{Sample,1,Ngraphs}];​​MinMaxSizeTffloorceiling=Table[{​​{Floor[MinMaxSizeTf[[Sample,1,1]],5],Ceiling[MinMaxSizeTf[[Sample,1,2]],5]},​​{Floor[MinMaxSizeTf[[Sample,2,1]],1],Ceiling[MinMaxSizeTf[[Sample,2,2]],1]}},{Sample,1,Ngraphs}];​​rangeSizeTf=Table[{​​MinMaxSizeTffloorceiling[[Sample,1,2]]-MinMaxSizeTffloorceiling[[Sample,1,1]],​​MinMaxSizeTffloorceiling[[Sample,2,2]]-MinMaxSizeTffloorceiling[[Sample,2,1]]},{Sample,1,Ngraphs}];​​TfSizePlots=​​Grid[{{Rotate[Style["Formation temperature (°C)",FontFamily->"Helvetica",FontSize->8],Pi/2],​​Grid[{{Style["Fluid inclusion size (µm)",FontFamily->"Helvetica",FontSize->8]},​​{Grid[​​Partition[​​Table[​​ListPlot[datalist[[Sample]],​​
],​​{Sample,1,Ngraphs}],​​UpTo[GraphPartition]],​​Spacings->{0.1,0.08},Alignment->{Center,Top}]}}​​]}}​​]
(Debug) Out[40]=
Formation temperature (°C)
Fluid inclusion size (µm)
​
​
​

Output Notebook

The output notebook contains all the output data (dataset + graphs) as well as the input file names.
(Debug) In[94]:=
notebookCreate=CreateDocument[{​​TextCell["Halite fluid inclusion paleotemperature analysis - "<>StringReplace[ToString[DateObject[Now,"Minute"][[1]]],{", "->"-","{"->"","}"->""}],"Title"],​​TextCell["Imported files","Section"],​​TextCell["Imported files:\n"<>If[filedepth>1,Table[ToString[file[[Sample]]]<>"\n",{Sample,1,Length[file]}],file]],​​TextCell["Output dataset","Section"],​​ExpressionCell[outputDataset],​​TextCell["Reconstructed paleotemperature vs. fluid inclusion size","Section"],​​TextCell["The following graphs (one per sample) show the fluid inclusions reconstructed Tf as a function of size. Fluid inclusion dimension uncertainty is assumed 1 µm in both length and width, and size is defined as the square root of the product of length and width. Tf uncertainty originates from the uncertainty on the Laplace pressure correction through the fluid inclusion volume uncertainty. The mean and standard deviation of the sample are also indicated."],​​ExpressionCell[TfSizePlots]}];

Concluding Remarks

The purpose of this work is too facilitate the processing of halite fluid inclusion temperature data and the production of standardized datasets. In a later phase, the code will be deployed to the cloud to allow anyone working on halite fluid inclusion paleo-thermometry to easily generate standardized and corrected paleo-temperature data.

Acknowledgments

This project would not have been possible without the constant support and help of my mentors, Bob Nachbar and Eric James Parfitt. They taught me countless tricks, gave me numerous ideas and greatly improved my coding and Wolfram Language abilities. This project has also largely benefitted from the insightful advice of Stephen Wolfram. I thank all the lecturers of the Wolfram Summer School 2024, I have learnt more in three weeks than I had ever learnt in several years of using Mathematica. This study is part of the CROSSROADS project and has received funding from the European Union’s Horizon 2020 research and innovation programme under the Marie Skłodowska-Curie Action grant agreement No 101029939.

Access the Full Code

These are a short URL and a QR code used to condense large blocks of code. They will lead to the Wolfram Community version of your project where the full code can be found. Our publishing team will provide these for you. They can be placed anywhere in your project where we want to condense code for print.

Cite This Notebook

“Automated experimental data processing - example of halite fluid inclusion paleo-temperatures”
​by Emmanuel Guillerm​
​https://community.wolfram.com/groups/-/m/t/3209864