Skip to content
Snippets Groups Projects
static_check.awk 4.83 KiB
Newer Older
Eoin Clerkin's avatar
Eoin Clerkin committed
#!/usr/bin/gawk -f 
#
# Static test to check the atomic number against the atomic mass for inclusions in the geometry media.geo file. Output may be used to spot typos and other human errors.
#
# Author E.Clerkin
# COPYRIGHT: FAIR GMBH 2020
#
#
# Useage: awk -f static_check.awk media.geo
# Must include LIST_ELEMENTS file in same directory.

function abs(x){return (x>=0) ? x : -x}

BEGIN{

ACCEPTABLE_ERROR=0.01 # 1 % ERROR TOLERANCE FOR STATIC CHECK. 

FAIL=0;  # Flag for determining success. If any check fails then this value is changed.

while(getline < "ci_scripts/LIST_ELEMENTS"){
	 ELEMENT_NAME[$1]=$2;
	 ELEMENT_SYMBOL[$1]=$3;
	 ELEMENT_MASS[$1]=$4;
	# Index $1 is the Atomic Number of the Element
	};
};


{
delete datum;

FS="[\t ]*"; # Spaces and tags as field seperators in media.geo

for (i = 1; i<=NF; i++)datum[i]=$i; # Loading in a line from media.geo fle to make it easy to work with.

	RELATIVE_SUM=0;
	content_by="weight"; # The relative content is by number of each atom or by relative weight of each atom.

	if($1!="//" && $1!="0" && $1!="1" && $1!="" ){  # Excluding lines that are not first line in definition of medium
		print "############################################################################################################";
		getline # Obtaining information from subsequent line for additional flags.
		sensflag=$2
		fldflag=$3
		fld=$4
		epsil=$5
		declare sensor;

		if(sensflag==0)  # Is the material active?
		{
		sensor="PASSIVE";
		}
		else
		{
		sensor=" ACTIVE";
		}

		print datum[1], sensor; # Material and Active status.

		if(datum[2]<0){
			content_by="number"  # Relative number
Eoin Clerkin's avatar
Eoin Clerkin committed
			print "Contents by relative number of atoms";
Eoin Clerkin's avatar
Eoin Clerkin committed
			};

		datum[2] = (datum[2]>0)? datum[2] :  -1*datum[2];    # Making the NCOMP parameter always positive. 
		# NCOMP sign controlls the constitutes ratio definitions and is not needed for these tests.

		printf "Number of constitutes: %d\n", datum[2];  # Datum[2] has integer value of number of elements.
			for(i=1;i<=datum[2];++i){  # Skips throw each of the components.
			printf "Atomic Number: %s\tAtomic Mass: %s\n", datum[2+i+datum[2]], datum[2+i]; # See https://fairroot.gsi.de/?q=node/34 for info regarding format ordering.
			printf "AN[%d]=> %s : Mass = %s\n", datum[2+i+datum[2]], ELEMENT_NAME[strtonum(datum[2+i+datum[2]])], ELEMENT_MASS[strtonum(datum[2+i+datum[2]])];

			# datum[2] is the number of components
			# datum[2 + i] is subsequent component's atomic number
			# datum[2 + i + datum[2]] is subsequenct component's atomic weight
			# datum[2 + 2*datum[2] + 1] is the overall density of the material
			# datum[3 + 2*datum[2] + i] is the subsequent relative amount of each compoment.

#			printf "PAUSE: %s %s %s", datum[2+i], ELEMENT_MASS[strtonum(datum[2+i+datum[2]])], ERROR;
			printf "1 MASS ENTERED %s \n",  datum[2+i];
			printf "2 ELEMENT MASS %s \n",  ELEMENT_MASS[strtonum(datum[2+i+datum[2]])];

			if ( length(datum[2+i])!=0 && length(ELEMENT_MASS[strtonum(datum[2+i+datum[2]])])!=0 ){
			ERROR = abs( (datum[2+i] - ELEMENT_MASS[strtonum(datum[2+i+datum[2]])] )/datum[2+i])
			};			
			
			if(datum[2]>1){ # Checks relatavant for more than one component.

					if(content_by~"number"){ # When the elements are per their relative number.
					printf "%s", ELEMENT_SYMBOL[strtonum(datum[2+i+datum[2]])];
					printf "%s\n", datum[3 + 2*datum[2] + i];
					CHEMISTRY[ELEMENT_SYMBOL[strtonum(datum[2+i+datum[2]])]]=datum[3 + 2*datum[2] + i];
					};

					if(content_by~"weight"){ # When the elements are per weight
					printf "RELATIVE AMOUNT: %0.2f%% \n", 100*datum[3 + 2*datum[2] + i];
					RELATIVE_SUM+=datum[3 + 2*datum[2] + i];
					};
			};

			printf "ERROR IS %f \t",  ERROR;
				if (ERROR > ACCEPTABLE_ERROR) {
				FAIL=1;
				printf "CHECK FAILED\n\n"
				} else {
				printf "CHECK PASSED\n\n"
				};
			};

			# Check if the amount of material adds up to 100%
			if(datum[2]>1 && content_by~"weight"){
			printf "TOTAL AMOUNT COUNT RELATIVE SUMS: %0.2f%% \t\t\t", 100*RELATIVE_SUM;
				if (RELATIVE_SUM<=1+ACCEPTABLE_ERROR && RELATIVE_SUM>=1-ACCEPTABLE_ERROR ){
				printf "CHECK PASSED! %s \n\n", RELATIVE_SUM;
				}else{
				printf "CHECK FAILED! %s \n\n", RELATIVE_SUM;
				FAIL=1;
				};
			};


			# Chemical Formula Attempt. For visual inspection by human.
			if(datum[2]>1 && content_by~"number"){
			printf "Contents by the number of atoms: \n"

			for( ele in CHEMISTRY )printf "%s%s", ele, CHEMISTRY[ele];
#			ELEMENT_SYMBOL[strtonum(datum[2+i+datum[2]])]
#			CHEMISTRY[]
			};

Eoin Clerkin's avatar
Eoin Clerkin committed
			# Output the density of the material for human examination
			printf "\nDensity of the material is : %s g/cm3", datum[2 + 2*datum[2] + 1];

Eoin Clerkin's avatar
Eoin Clerkin committed

		print " " # Spacing
		delete CHEMISTRY;
	};
}

END{

print "------------------------------------------------------------------------------------------------------------"

printf "STATIC TEST: "
if ( ! FAIL ) { printf "PASSED\n" }
if ( FAIL ) { printf "FAILED\n"; exit 1 }
}