(* ::Package:: *)

(************************************************************************)
(* This file was generated automatically by the Mathematica front end.  *)
(* It contains Initialization cells from a Notebook file, which         *)
(* typically will have the same name as this file except ending in      *)
(* ".nb" instead of ".m".                                               *)
(*                                                                      *)
(* This file is intended to be loaded into the Mathematica kernel using *)
(* the package loading commands Get or Needs.  Doing so is equivalent   *)
(* to using the Evaluate Initialization Cells menu command in the front *)
(* end.                                                                 *)
(*                                                                      *)
(* DO NOT EDIT THIS FILE.  This entire file is regenerated              *)
(* automatically each time the parent Notebook file is saved in the     *)
(* Mathematica front end.  Any changes you make to this file will be    *)
(* overwritten.                                                         *)
(************************************************************************)



(* ::Input::Initialization:: *)
BeginPackage["DataAnalysis`DataImport`",{
"DataAnalysis`"
}];


(* ::Input::Initialization:: *)
Unprotect[Evaluate[$Context<>"*"]];


(* ::Input::Initialization:: *)
ImportDataTable::usage="ImportDataTable[file,elements] imports data from a file or folder into a DataTable object based on the elements specified.";


(* ::Input::Initialization:: *)



(* ::Input::Initialization:: *)



(* ::Input::Initialization:: *)
Begin["`Private`"];


(* ::Input::Initialization:: *)
SetAttributes[ErrorMessage,HoldFirst];
ErrorMessage[Args___]:=Module[
{},
Message[Args];
Abort[];
];


(* ::Input::Initialization:: *)
SetAttributes[CatchError,HoldAll];
CatchError[Body_]:=(Catch[Body]===$ErrorFlag);


(* ::Input::Initialization:: *)
ImportDataTable[file_,"AgilentCSV"]:=Module[
{RawDat,TmpDat,OutDat},
(
RawDat=Import[file,"CSV"];
RawDat=RawDat[[2;;]];
(*AppendTo[RawDat[[1]],""];
AppendTo[RawDat[[2]],""];
AppendTo[RawDat[[3]],""];*)
RawDat=RawDat//Transpose;

TmpDat=MapThread[
Join[#1[[{1}]],{DateObject[{#1[[2]],{"Day","Month","Year","Hour","Minute"}}]},MapThread[(NDV[#1,#1*ToExpression[StringDrop[#2,-1]]/100])&,{#1[[4;;]],#2[[4;;]]}]]&,
{
Take[RawDat,{2,-1,2}],
Take[RawDat,{3,-1,2}]
}
];

OutDat=Prepend[TmpDat,Drop[RawDat[[1]],{3}]/."Date/Time:"->"Time"];
OutDat=OutDat/.{NDV["<###> ",___]->Missing[]};
OutDat=DataTable[OutDat];

OutDat
)
]


(* ::Input::Initialization:: *)
ElementXRImportASC[file_,isotopes_,multi_:True]:=Module[
{RawDat,OutDat,TblStart,ColPos},
(
RawDat=Import[file,"TSV"];

If[multi,
(
RawDat=RawDat[[Join[{1,2,4},Map[Position[RawDat[[All,1]],s_String/;StringMatchQ[s,#~~__]]&,isotopes]//Flatten]]];

RawDat=RawDat//Transpose;

OutDat={Join[{"ID","Time"},isotopes]};

RawDat=Partition[RawDat[[2;;]],14];

Scan[(
AppendTo[OutDat,Join[{#[[1,1]],AbsoluteTime[#[[1,2]]]},MapThread[NDV[#1,#2]&,{#[[3,4;;]],#[[5,4;;]]}]]];
)&,RawDat];

MakeDataTable[OutDat]
),
(
TblStart=Position[RawDat[[All,1]],"Isotope"]//Flatten//First;

OutDat=Select[RawDat[[TblStart;;]],(Length[#]==Length[RawDat[[TblStart]]]&&StringMatchQ[#[[1]],(Alternatives@@isotopes)~~"(LR)"])&];
PrependTo[OutDat,RawDat[[TblStart]]];
ColPos=Position[OutDat[[1]],Except[""]]//Flatten//Rest;
OutDat=MakeDataTable[OutDat[[All,ColPos]]];
OutDat=OutDat[[All,{"Intensity AVG","Intensity RSD"}]];
OutDat=OutDat//DTBody;

OutDat={#[[1]],NDV[#[[2]],#[[3]]*#[[2]]/100]}&/@OutDat;
PrependTo[OutDat,{"Time",AbsoluteTime[RawDat[[5,3]]]}];
PrependTo[OutDat,{"ID",FileBaseName[file](*StringReplace[FileBaseName[file],StartOfString~~DigitCharacter..~~"-"\[Rule]""]*)}];

OutDat=OutDat//Transpose;
OutDat[[1]]=StringReplace[#,"("~~__~~")"->""]&/@OutDat[[1]];

OutDat
)
]
)
];


(* ::Input::Initialization:: *)
ElementXRImportASCFolder[folder_,isotopes_]:=Module[
{Files,OutDat},
(
Files=FileNames["*.ASC",{folder}];

OutDat=ElementXRImportASC[Files//First,isotopes,False][[{1}]];

Scan[AppendTo[OutDat,ElementXRImportASC[#,isotopes,False]//Last]&,Files];

OutDat//MakeDataTable
)
]


(* ::Input::Initialization:: *)
ImportDataTable[location_,{"ThermoFisherNeptune",isotopes_,dateFormat_:{"Month","Day","Year"},dateFunction_:(#&)}]:=Module[
{Files,OutDat},
(
Files=FileNames["*.exp",{location}];

If[Length@Files>1,
(*(Join@@(ImportNeptuneEXPFile[#,isotopes]&/@Files))[SortBy[#"Time"&]]*)
(
OutDat=DataTable[Association[#[[1,"SampleID"]]->#&/@(Normal@ImportNeptuneEXPFile[#,isotopes,False,dateFormat]&/@Files)]];
QueryTo[OutDat,All,All,KeyDrop[#,{"SampleID"}]&];
QueryTo[OutDat,All,All,dateFunction];
OutDat[SortBy[#[[1,"Time"]]&]]
),
If[Length@Files==1,
ImportNeptuneEXPFile[First@Files,isotopes,dateFormat],
ImportNeptuneEXPFile[location,isotopes,dateFormat]
]
]
)
]


(* ::Input::Initialization:: *)
ImportNeptuneEXPFile[file_,isotopes_,removeOutliers_:False,dateFormat_:{"Month","Day","Year"}]:=Module[
{RawDat,OutDat,TblStart,DateStr,FirstTime,SampleID},
(
RawDat=Import[file,"TSV"];
TblStart=Position[RawDat[[All,1]],"Cycle"]//Flatten//First;

If[Length[Position[StringPosition[RawDat[[;;TblStart-1,1]],"Analysis date:"~~__],{1,__}]//Flatten]>0,
(
DateStr=Position[StringPosition[RawDat[[;;TblStart-1,1]],"Analysis date:"~~__],{1,__}]//Flatten//First;
DateStr=StringDrop[RawDat[[DateStr,1]],15];
DateStr=DateObject[{DateStr,dateFormat}];
),
(
DateStr=DateObject[];
)
];

If[$VersionNumber>=11.1,
DateStr=Normal@DateObject[DateStr,"Day"];
];

If[Length[Position[StringPosition[RawDat[[;;TblStart-1,1]],"Analysis time:"~~__],{1,__}]//Flatten]>0,
(
FirstTime=Position[StringPosition[RawDat[[;;TblStart-1,1]],"Analysis time:"~~__],{1,__}]//Flatten//First;
FirstTime=StringDrop[RawDat[[FirstTime,1]],15];
FirstTime=DateObject[DateStr,TimeObject[DateObject[{FirstTime,{"Hour","Minute","Second"}}]]];
),
(
FirstTime=Position[RawDat[[TblStart]],"Time"]//Flatten//First;
FirstTime=RawDat[[TblStart+1,FirstTime]];
FirstTime=DateObject[DateStr,TimeObject[DateObject[{FirstTime,{"Hour","Minute","Second","Millisecond"}}]]];
)
];

If[
Length[Position[StringPosition[RawDat[[;;TblStart-1,1]],"Sample ID:"~~__],{1,__}]//Flatten]>0,
(
SampleID=Position[StringPosition[RawDat[[;;TblStart-1,1]],"Sample ID:"~~__],{1,__}]//Flatten//First;
SampleID=StringDrop[RawDat[[SampleID,1]],11];
),
(
SampleID=FileBaseName[file];
)
];

OutDat=Select[RawDat[[TblStart;;]],(Length[#]==Length[RawDat[[TblStart]]]&&(!StringQ[#[[1]]]||StringMatchQ[#[[1]],"Cycle"])&&(!Or@@(StringMatchQ[ToString[#],""]&/@#[[;;-2]])))&];
OutDat=OutDat[[All,;;-2]];
OutDat[[1]]=StringReplace[ToString[#],"24.174"->"24Mg"]&/@OutDat[[1]];
OutDat=Map[If[StringQ[#]&&StringMatchQ[#,"X"~~NumberString~~___],Interpreter["Number"][StringDrop[#,1]],#]&,OutDat,{2}];

OutDat=DataTable[OutDat];
QueryTo[OutDat,All,(#/.#"Time"->DateObject[DateStr,TimeObject[DateObject[{#"Time",{"Hour","Minute","Second","Millisecond"}}]]])&];
QueryTo[OutDat,All,(If[#"Time"<FirstTime,#/.#"Time"->(#"Time"+Quantity[1,"Days"]),#])&];
QueryTo[OutDat,All,Prepend[#,"SampleID"->SampleID]&];

OutDat[All,Join[{"SampleID","Time"},isotopes]]
)
]


(* ::Input::Initialization:: *)
ImportDataTable[location_,{"ThermoFisherTriton",isotopes_,dateFormat_:{"Month","Day","Year"}}]:=Module[
{Files,OutDat},
(
Files=FileNames["*.exp",{location}];

If[Length@Files>1,
(
OutDat=DataTable[Association[#[[1,"SampleID"]]->#&/@(Normal@ImportNeptuneEXPFile[#,isotopes,False,dateFormat]&/@Files)]];
QueryTo[OutDat,All,All,KeyDrop[#,{"SampleID"}]&];
OutDat[SortBy[#[[1,"Time"]]&]]
),
If[Length@Files==1,
ImportNeptuneEXPFile[First@Files,isotopes,False,dateFormat],
ImportNeptuneEXPFile[location,isotopes,False,dateFormat]
]
]
)
]


(* ::Input::Initialization:: *)
ImportDataTable[file_,"PerkinElmerAAS"]:=Module[
{RawDat,TmpDat,OutDat,Elements},
(
RawDat=Import[file][[1]];
OutDat={
#[[1]],
DateObject[AbsoluteTime[#[[2]]]+AbsoluteTime[#[[3]]]],
#[[5]],
NDV[Mean[{#[[9]],#[[11]]}],StandardDeviation[{#[[9]],#[[11]]}]/Sqrt[2]]
}&/@RawDat[[2;;]];
Elements=DeleteDuplicates[OutDat[[All,3]]];
PrependTo[OutDat,{"Sample","Time","Element","Absorbance"}];
OutDat=DataTable[OutDat];

QueryTo[OutDat,All,<|"Time"->#"Time",#"Element"->#"Absorbance"|>&];
If[Length[Elements]>1,
QueryTo[OutDat,All,Join[<|"Time"->#"Time"|>,<|#->Missing[]&/@Elements|>,#]&]
];

OutDat
)
];


(* ::Input::Initialization:: *)
SpectroPhotoImportCSV[file_,name_]:=Module[
{RawDat,OutDat,TblEnd,TimeRow},
(
RawDat=Import[file,"CSV"];
TblEnd=(Position[RawDat,{""}]//Flatten//First)-1;
OutDat=RawDat[[3;;TblEnd,2]];

TimeRow=Select[RawDat[[All,1]],If[StringQ[#],StringMatchQ[#,"Collection Time: "~~__],False]&]//First;

OutDat={{name,EV[OutDat//Mean,(OutDat//StandardDeviation)(*/Sqrt[OutDat//Length]*)]}};
PrependTo[OutDat,{"Time",AbsoluteTime[StringTake[TimeRow,18;;]]}];
PrependTo[OutDat,{"ID",FileBaseName[file]}];

OutDat=OutDat//Transpose;

OutDat
)
];


(* ::Input::Initialization:: *)
SpectroPhotoImportCSVFolder[folder_,name_]:=Module[
{Files,OutDat},
(
Files=FileNames["*.csv",{folder}];

OutDat=SpectroPhotoImportCSV[Files//First,name][[{1}]];

Scan[AppendTo[OutDat,SpectroPhotoImportCSV[#,name]//Last]&,Files];

OutDat//MakeDataTable
)
]


(* ::Input::Initialization:: *)
ProcessSchottTitrations[titrs_,nPoints_,iterations_]:=Module[
{OutDat,OutDt},
(
OutDat={Join[{"ID","Analyte / g","C(Titrant) / mol/L"},Table["EQ "<>ToString[i]<>" / ml",{i,nPoints}]]};

OutDat=Join[OutDat,Join[{#[[2]],#[[3]],#[[4]]},ProcessSchottTitration[#[[1]],nPoints,iterations]]&/@titrs];

OutDt=OutDat//MakeDataTable;

SmartMap[OutDt,
Table["EQ "<>ToString[i]<>" / ml"*10^-3*"C(Titrant) / mol/L"/("Analyte / g"*10^-3),{i,nPoints}],
Header->Table["EQ "<>ToString[i]<>" / mol/L",{i,nPoints}]
]
)
];


(* ::Input::Initialization:: *)
ProcessSchottTitration[file_,nPoints_,iterations_]:=Module[
{Dt},
(
Dt=Import[file][[1,;;-2,{2,1,3}]]//MakeDataTable;
Dt=AppendColumns[Dt,Join[{{"dml"},{0}},Differences[Dt[[All,"ml"]]//DTValues]]];
Dt=SmartMap[Dt,{EV["dml",0.02],EV["pH",0.02]},Header->{"dml","pH"}];

ProcessTitrationData[Dt[[All,{"dml","pH"}]],nPoints,iterations]
)
];


(* ::Input::Initialization:: *)
ProcessTitrationData[dt_,nPoints_,iterations_]:=Module[
{Dat,OutDat={},i,j,LL,UL,Points,DL},
(
Dat=dt//DTValues;

LL=Min[(Dat//EVValues)[[All,1]]];
UL=Max[Total[(Dat//EVValues)[[All,1]]]];

DL=((Dat//EVErrors)[[All,1]]//Mean)*30;

Off[NDSolve::evcvmit,InterpolatingFunction::dmval];

Points=FindEQPoints[Dat//EVValues,nPoints,LL,UL,True];
Points=First[FindEQPoints[Dat//EVValues,1,#-DL,#+DL]]&/@Points;

OutDat=Table[FindEQPoints[Dat//RandomData,1,Points[[j]]-DL,Points[[j]]+DL]//First,{i,iterations},{j,nPoints}];

(*For[i=1,i\[LessEqual]nPoints,i++,
For[j=1,j\[LessEqual]iterations,j++,
(
AppendTo[OutDat,FindEQPoints[Dat//RandomData,1,LL,UL]];
)
]
];
*)
On[NDSolve::evcvmit,InterpolatingFunction::dmval];

MapThread[EV[#1,#2]&,{Points,StandardDeviation[OutDat]}]
)
];


(* ::Input::Initialization:: *)
FindEQPoints[dat_,nPoints_,ll_,ul_,smooth_:False]:=Module[
{IP,EQVolumes,OutList,i,Dat,MaxC},
(

Dat=dat;
Dat[[All,1]]=Accumulate[Dat[[All,1]]];

If[smooth==True,
Dat=MovingAverage[Dat,3];
];

IP=Interpolation[Dat];

(*Plot[IP'[x],{x,0,15},PlotRange\[Rule]Full]//Print;
Plot[IP''[x],{x,0,15},PlotRange\[Rule]Full]//Print;*)

EQVolumes=Reap[soln=y[x]/.First[NDSolve[{y'[x]==Evaluate[D[-IP'[x],x]],y[ll]==(-IP'[x]/.x->ll)},y[x],{x,ll,ul},Method->{"EventLocator","Event"->y'[x],"EventAction":>Sow[{x,y[x]}]}]]][[2,1]];
EQVolumes=Sort[EQVolumes,#1[[2]]>#2[[2]]&];

OutList={};

For[i=1,i<=nPoints,i++,
(
AppendTo[OutList,EQVolumes[[i,1]]]
)
];

OutList
)];


(* ::Input::Initialization:: *)
InelXRDImportASCII[file_]:=Module[
{FileDat,CpsList,AngleList,wavelength},
(
FileDat=Import[file,"Table"];
CpsList=FileDat[[10;;]]//Flatten;
AngleList=Table[i,{i,FileDat[[9,1]],FileDat[[9,3]]+5,FileDat[[9,2]]}][[;;(CpsList//Length)]];

wavelength=FileDat[[5,2]];

Prepend[MapThread[{#1,1/2 wavelength Csc[(Degree #1)/2],#2}&,{AngleList,CpsList}],{"2\[Theta] / \[Degree]","d / \[Angstrom]","Int / cps"}]
)
];


(* ::Input::Initialization:: *)
CPIXRDImport[file_]:=Module[
{CpsList,LambdList,Lambda,Filecont},
(
Filecont=Import[file,"Table"];

CpsList=Filecont[[11;;,1]];
LambdList=Table[x,{x,Filecont[[2,1]],Filecont[[3,1]],Filecont[[4,1]]}];
Lambda=Filecont[[6,1]];

Prepend[MapThread[{#1,1/2 Lambda Csc[(Degree #1)/2],#2}&,{LambdList,CpsList}],{"2\[Theta] / \[Degree]","d / \[Angstrom]","Int / cps"}]
)
]


(* ::Input::Initialization:: *)
CryscalXYImport[file_]:=Module[
{Filecont,Lambda},
(
Filecont=Import[file,"Table"];
Lambda=Filecont[[3,4]];

Prepend[{#[[1]],1/2 Lambda Csc[(Degree #[[1]])/2],#[[2]]}&/@Filecont[[12;;]],{"2\[Theta] / \[Degree]","d / \[Angstrom]","Int / cps"}]
)
]


(* ::Input::Initialization:: *)
NewXRDToulouseImport[file_,lambda_]:=Module[
{Filecont},
(
Filecont=Import[file,"Table"]//Rest;

Prepend[{#[[1]],1/2 lambda Csc[(Degree #[[1]])/2],#[[2]]}&/@Filecont,{"2\[Theta] / \[Degree]","d / \[Angstrom]","Int / cps"}]
)
]


(* ::Input::Initialization:: *)
GetAMCSDData[id_]:=Module[
{File},
(
File=Import["http://rruff.geo.arizona.edu/AMS/xtal_data/DIFfiles/"<>ToString[id]<>".txt","Table"];

File[[12;;]]
)
]


(* ::Input::Initialization:: *)
GetCODData[id_]:=Module[
{File,CpsList,LambdList,Lambda},
(
URLSave["http://www.crystallography.net/cif/"<>StringTake[ToString[id],1]<>"/"<>StringTake[ToString[id],{2,3}]<>"/"<>StringTake[ToString[id],{4,5}]<>"/"<>ToString[id]<>".cif",$TemporaryDirectory<>"\\"<>ToString[id]<>".cif"];

Run["cd "<>$TemporaryDirectory<>" & start /B /MIN platon.exe -o -Q "<>ToString[id]<>".cif & PING 1.1.1.1 -n 1 -w 1000 >NUL & TASKKILL /F /IM platon.exe"];

File=Import[$TemporaryDirectory<>"\\"<>ToString[id]<>".cpi","Table"];

DeleteFile[($TemporaryDirectory<>"\\"<>ToString[id]<>#)&/@{".cif",".cpi",".eld",".lis",".ps"}];
DeleteFile[$TemporaryDirectory<>"\\platon.out"];

CpsList=File[[11;;,1]];
LambdList=Table[x,{x,File[[2,1]],File[[3,1]],File[[4,1]]}];
Lambda=File[[6,1]];

Prepend[MapThread[{#1,1/2 Lambda Csc[(Degree #1)/2],#2}&,{LambdList,CpsList}],{"2\[Theta] / \[Degree]","d / \[Angstrom]","Int / cps"}]
)
]


(* ::Input::Initialization:: *)
ConvertXRDTheta[data_,lambda_]:=Module[
{OutData},
(
Join[data[[{1}]],{2ArcSin[lambda/(2#[[2]])]/Degree,#[[2]],#[[3]]}&/@data[[2;;]]]
)
]


(* ::Input::Initialization:: *)
FillICDDXRDData[data_]:=Module[
{},
(
Prepend[Flatten[Map[{
{#[[1]],#[[2]]+0.0001,0},
{#[[1]],#[[2]],#[[3]]},
{#[[1]],#[[2]]-0.0001,0}
}&,data//Rest],1],data//First]
)
]


(* ::Input::Initialization:: *)
XRDProfileFig[data_,labels_,peaks_:{}]:=Module[
{XMax,YMax,XMaxTmp,YMaxTmp,PlotDat},
(
PlotDat=data;

If[TrueQ[Head[data]==List],
(
XMax={};
YMax={};

Scan[(
XMaxTmp=(#//DTValues//EVValues)[[All,1]]//Max;
AppendTo[XMax,Ceiling[XMaxTmp,10^((Log10[XMaxTmp]//Floor))/10]];

YMaxTmp=(#//DTValues//EVValues)[[All,2]]//Max;
AppendTo[YMax,YMaxTmp(*Ceiling[YMaxTmp,10^((Log10[YMaxTmp]//Floor))/5]*)];
)&,data];

PlotDat=MapThread[SmartMap[#1,(#1//DTRightHeader)*{1,100/#2},PreserveDTHeader->True]&,{PlotDat,YMax}];

XMax=Max[XMax];
YMax=100;
),
(
XMax=(data//DTValues//EVValues)[[All,1]]//Max;
XMax=Ceiling[XMax,10^((Log10[XMax]//Floor))/5];

YMax=(data//DTValues//EVValues)[[All,2]]//Max;
YMax=Ceiling[YMax,10^((Log10[YMax]//Floor))];
)
];

DataAnalysis`ListLineFig[PlotDat,PlotRange->{{0,XMax},{0,YMax}},ShowPoints->False,LegendNames->labels,LegendPos->{0.8,0.8},ImageSize->150*{6,3}]
)
]


(* ::Input::Initialization:: *)
RawPeakDetect=Compile[{{data,_Real,1},{width,_Integer},{cut,_Real}},(Table[0,{width}]~Join~UnitStep[Take[data,{1+width,-1-width}]-(Module[{tot=Total[#1[[1;;#2-1]]],last=0.},Table[tot=tot+#1[[j+#2]]-last;
last=#1[[j+1]];
tot,{j,0,Length[#1]-#2}]]/#2)&[data,1+2 width]-cut]~Join~Table[0,{width}]) ({0}~Join~Table[If[Sign[{data[[ii+1]]-data[[ii]],data[[ii+2]]-data[[ii+1]]}]=={1,-1},1,0],{ii,1,Length[data]-2}]~Join~{0})];


(* ::Input::Initialization:: *)
RawPeakDetect2[data_,ther_: .2,min_: 0,cther_: 50]:=Function[peaks,Transpose[{peaks,data[[peaks]]}]][(#[[Ordering[data[[#]],-1][[1]]]]&/@Split[Flatten[Position[Normal[CrossingDetect[If[Abs[#]<ther,0,#]&/@InverseWaveletTransform[DiscreteWaveletTransform[If[#<min,0,#]&/@data,HaarWavelet[],1],HaarWavelet[],{1}]]],1]],Abs[#1-#2]<cther&])]


(* ::Input::Initialization:: *)
XRDPeakDetect[data_,ther_,min_,cther_]:=Module[
{Peaks,Dat},
(
Dat=data//Rest;

(*Peaks=DeleteCases[MapThread[If[#2\[Equal]1,#1,False]&,{Dat,RawPeakDetect[Dat[[All,2]],hw,tt]}],False];
Peaks=Sort[Peaks,#1[[2]]>#2[[2]]&];*)

Peaks=RawPeakDetect2[Dat[[All,2]],ther,min,cther];
Peaks={Dat[[#[[1]],1]],#[[2]]}&/@Peaks;

Prepend[Peaks,data[[1]]]
)
]


(* ::Input::Initialization:: *)
LI820ImportASCII[file_]:=Module[
{FileDat},
(
FileDat=Import[file,"Table"]//Rest;
FileDat[[2;;,1]]=(AbsoluteTime[#]-AbsoluteTime[FileDat[[2,1]]])&/@FileDat[[2;;,1]];
FileDat[[1,1]]="Time / s";
MakeDataTable[FileDat,IDColumnN->0]
)
];


(* ::Input::Initialization:: *)
LI820Fig[dat_]:=Module[
{XMax,YMax},
(
XMax=(dat[[All,"Time / s"]])//DTValues//Flatten//Last;
XMax=Ceiling[XMax,10^((Log10[XMax]//Floor))/10];

YMax=(dat[[All,"CO2(ppm)"]])//DTValues//EVValues//Flatten//Max;
YMax=Ceiling[YMax,10^((Log10[YMax]//Floor))/10];

ListLineFig[
dat[[All,{"Time / s","CO2(ppm)"}]],
PlotRange->{{0,XMax},{-5,YMax}},
ShowPoints->False
]
)
];


(* ::Input::Initialization:: *)
LI820CorrectNoise[dat_,bgRegion_]:=Module[
{ID1,ID2,StdDev,MeanBG},
(
ID1=Position[(dat[[All,"Time / s"]])//DTValues//Flatten,bgRegion[[1]]]//Flatten//First;
ID2=Position[(dat[[All,"Time / s"]])//DTValues//Flatten,bgRegion[[2]]]//Flatten//First;

MeanBG=(dat[[ToString[ID1];;ToString[ID2],"CO2(ppm)"]])//DTValues//Flatten;
StdDev=StandardDeviation[MeanBG];
MeanBG=EV[Mean[MeanBG],StdDev];

SmartMap[dat,{"Time / s",ProcessEVFunction[EV["CO2(ppm)",StdDev]-MeanBG]//Hold},Header->{"Time / s","CO2(ppm)"}]
)
]


(* ::Input::Initialization:: *)
LI820IntegrateArea[dat_,region_,iterations_]:=Module[
{ID1,ID2,TmpDat,F,Areas},
(
ID1=Position[(dat[[All,"Time / s"]])//DTValues//Flatten,region[[1]]]//Flatten//First;
ID2=If[region[[2]]==Infinity,
Position[(dat[[All,"Time / s"]])//DTValues//Flatten,(
(dat[[All,"Time / s"]])//DTValues//Flatten//Last
)]//Flatten//First,
Position[(dat[[All,"Time / s"]])//DTValues//Flatten,region[[2]]]//Flatten//First
];

TmpDat=(dat[[ToString[ID1];;ToString[ID2],{"Time / s","CO2(ppm)"}]])//DTValues;
TmpDat=DeleteDuplicates[TmpDat,(#1[[1]]==#2[[1]])&];

Areas=Table[(
F=Interpolation[TmpDat//RandomData,InterpolationOrder->1];
NIntegrate[F[t],{t,Min@TmpDat[[All,1]],Max@TmpDat[[All,1]]},Method->"LocalAdaptive"]
),{iterations}];

EV[(
F=Interpolation[TmpDat//EVValues,InterpolationOrder->1];
NIntegrate[F[t],{t,Min@TmpDat[[All,1]],Max@TmpDat[[All,1]]},Method->"LocalAdaptive"]
),StandardDeviation[Areas]]
)
]


(* ::Input::Initialization:: *)
End[];


(* ::Input::Initialization:: *)
Protect[Evaluate[$Context<>"*"]];
EndPackage[];
