From 3d3eb7f009c29635a1965f9896738e994aa3ca48 Mon Sep 17 00:00:00 2001 From: Janice Date: Wed, 2 Oct 2024 22:38:10 +0530 Subject: [PATCH 1/7] reading file info using pypdf --- data/read.py | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 data/read.py diff --git a/data/read.py b/data/read.py new file mode 100644 index 00000000..9aa72987 --- /dev/null +++ b/data/read.py @@ -0,0 +1,17 @@ +from pypdf import PdfReader + +reader = PdfReader("C:/Users/HP/OneDrive/Desktop/dataprocess/data_preprocessor/data/acetone-acs-l (1).pdf") + +# Print the number of pages in the PDF +print(f"There are {len(reader.pages)} Pages") + +# Get the first page (index 0) +page = reader.pages[0] +# Use extract_text() to get the text of the page +print(page.extract_text()) + +# Go through every page and get the text +for i in range(len(reader.pages)): + page = reader.pages[i] + print(page.extract_text()) + \ No newline at end of file From 09983754d83cdb2ec7e327f498169b56ed89ac59 Mon Sep 17 00:00:00 2001 From: Janice Date: Thu, 3 Oct 2024 00:38:29 +0530 Subject: [PATCH 2/7] pdfplumber --- data/read.py | 2 +- data/read2.py | 31 +++++++++++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) create mode 100644 data/read2.py diff --git a/data/read.py b/data/read.py index 9aa72987..c267b719 100644 --- a/data/read.py +++ b/data/read.py @@ -1,6 +1,6 @@ from pypdf import PdfReader -reader = PdfReader("C:/Users/HP/OneDrive/Desktop/dataprocess/data_preprocessor/data/acetone-acs-l (1).pdf") +reader = PdfReader("C:/Users/HP/OneDrive/Desktop/data_preprocessor/data/acetone-acs-l (1).pdf") # Print the number of pages in the PDF print(f"There are {len(reader.pages)} Pages") diff --git a/data/read2.py b/data/read2.py new file mode 100644 index 00000000..e07ca80e --- /dev/null +++ b/data/read2.py @@ -0,0 +1,31 @@ +import pdfplumber + +# Use raw string format to avoid issues with backslashes +file_path = r"C:\Users\HP\OneDrive\Desktop\data_preprocessor\data\acetone-acs-l (1).pdf" + +# Open the PDF +with pdfplumber.open(file_path) as pdf: + # Iterate through each page of the PDF + for page_num, page in enumerate(pdf.pages): + # Extract text from the page + text = page.extract_text() + print(f"Text from page {page_num + 1}:") + print(text) + + # Extract tables from the page + tables = page.extract_tables() # Use extract_tables() instead of extract_table() + print(f"Tables from page {page_num + 1}:") + for table in tables: + for row in table: + print(row) + + # Extract images from the page + images = page.images # Use page.images to get a list of images on the page + if images: + print(f"Images on page {page_num + 1}:") + for image in images: + print(f"Image on page {page_num + 1}: {image}") + # Note: PDFPlumber does not extract the image data itself, only metadata like its position, width, height, etc. + # For extracting image data, you might need another library like Pillow to render the PDF into an image. + + From aee4ec2f2e68ce3ae1b806e31ba4114f98f6fd78 Mon Sep 17 00:00:00 2001 From: Janice Date: Fri, 4 Oct 2024 15:16:46 +0530 Subject: [PATCH 3/7] paragraph and heading recognition --- data/read.py | 6 +- data/read2.py | 2 + data/read3tables.py | 15 +++ data/read4.py | 80 ++++++++++++ data/read5.py | 62 +++++++++ data/read6.py | 77 +++++++++++ output.json | 311 ++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 552 insertions(+), 1 deletion(-) create mode 100644 data/read3tables.py create mode 100644 data/read4.py create mode 100644 data/read5.py create mode 100644 data/read6.py create mode 100644 output.json diff --git a/data/read.py b/data/read.py index c267b719..8e2296f4 100644 --- a/data/read.py +++ b/data/read.py @@ -1,3 +1,5 @@ +#reading contents of pdf using pypdf + from pypdf import PdfReader reader = PdfReader("C:/Users/HP/OneDrive/Desktop/data_preprocessor/data/acetone-acs-l (1).pdf") @@ -14,4 +16,6 @@ for i in range(len(reader.pages)): page = reader.pages[i] print(page.extract_text()) - \ No newline at end of file + + + diff --git a/data/read2.py b/data/read2.py index e07ca80e..d6e63921 100644 --- a/data/read2.py +++ b/data/read2.py @@ -1,3 +1,5 @@ +#reading contents of the pdf using pdfplumber + import pdfplumber # Use raw string format to avoid issues with backslashes diff --git a/data/read3tables.py b/data/read3tables.py new file mode 100644 index 00000000..2c54a140 --- /dev/null +++ b/data/read3tables.py @@ -0,0 +1,15 @@ +import pdfplumber +import json + +file_path = r"C:\Users\HP\OneDrive\Desktop\data_preprocessor\data\acetone-acs-l (1).pdf" + + + +with pdfplumber.open(file_path) as pdf: + + for page_num, page in enumerate(pdf.pages): + tables = page.extract_tables() # Use extract_tables() instead of extract_table() + print(f"Tables from page {page_num + 1}:") + for table in tables: + for row in table: + print(row) \ No newline at end of file diff --git a/data/read4.py b/data/read4.py new file mode 100644 index 00000000..22e18864 --- /dev/null +++ b/data/read4.py @@ -0,0 +1,80 @@ +import pdfplumber +import json + + + +def process_main_heading(heading): + main_head=heading.strip() + return{heading.strip()} + +#def process_sub_heading1(heading): + # sub_head=heading.strip() + # return{heading.strip()} + +def process_paragraph(h,paragraph): + return{h : paragraph.strip()} + + + +#def process_paragraph(paragraph): + # return {"type": "paragraph", "content": paragraph.strip()} + +#def process_heading(heading): + #return {"type": "heading", "content": heading.strip()} + +def process_table(table): + return {"type": "table", "content": table} + + + +def detect_structure(text): + paragraphs=text.split('\n\n') #to split the paras ig + structured_content=[] #to store the structred content ...empty list is initialised + + for paragraph in paragraphs: + clean_paragraph = paragraph.strip() #to remove leading or trailing whitespaces + + if clean_paragraph: + + if len(clean_paragraph.split()) < 5: # include logic for headers of different font sizes + headd=clean_paragraph + structured_content.append(process_main_heading(clean_paragraph)) + + else: + structured_content.append(process_paragraph(headd,clean_paragraph)) + + return structured_content + + +def extract_tables(page): + tables = page.extract_tables() + table_list = [] + for table in tables: + table_list.append(process_table(table)) + return table_list + + +def main(): + #file_path=input(r"Enter the file path: ") + file_path = r"C:\Users\HP\OneDrive\Desktop\data_preprocessor\data\acetone-acs-l (1).pdf" + + document_structure=[] #empty list to storee doc structure?? + + with pdfplumber.open(file_path) as pdf: + + for page_num,page in enumerate(pdf.pages): + print(f"Processing page {page_num + 1}:") + + text=page.extract_text() + +# Convert the structure to JSON + json_output = json.dumps(document_structure, indent=4) + + # Save to file or print + with open('output.json', 'w') as json_file: + json_file.write(json_output) + + print("PDF content has been converted to JSON.") + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/data/read5.py b/data/read5.py new file mode 100644 index 00000000..1fd1540f --- /dev/null +++ b/data/read5.py @@ -0,0 +1,62 @@ +import pdfplumber +import json + +def process_paragraph(paragraph): + return {"type": "paragraph", "content": paragraph.strip()} + +def process_heading(heading): + return {"type": "heading", "content": heading.strip()} + +def process_table(table): + return {"type": "table", "content": table} + +def detect_structure(text): + paragraphs = text.split('\n\n') + structured_content = [] + + for paragraph in paragraphs: + clean_paragraph = paragraph.strip() + if clean_paragraph: + if len(clean_paragraph.split()) < 5: + structured_content.append(process_heading(clean_paragraph)) + else: + structured_content.append(process_paragraph(clean_paragraph)) + + return structured_content + +def extract_tables(page): + tables = page.extract_tables() + table_list = [] + for table in tables: + table_list.append(process_table(table)) + return table_list + +def main(): + #filepath = input(r"Enter the file path: ") + filepath = r"C:\Users\HP\OneDrive\Desktop\data_preprocessor\data\acetone-acs-l (1).pdf" + + document_structure = [] + + with pdfplumber.open(filepath) as pdf: + for page_num, page in enumerate(pdf.pages): + print(f"Processing page {page_num + 1}:") + + text = page.extract_text() + if text: + structured_text = detect_structure(text) + document_structure.extend(structured_text) + + tables = extract_tables(page) + document_structure.extend(tables) + + # Convert the structure to JSON + json_output = json.dumps(document_structure, indent=4) + + # Save to file or print + with open('output.json', 'w') as json_file: + json_file.write(json_output) + + print("PDF content has been converted to JSON.") + +if __name__ == "__main__": + main() diff --git a/data/read6.py b/data/read6.py new file mode 100644 index 00000000..6f2fbd53 --- /dev/null +++ b/data/read6.py @@ -0,0 +1,77 @@ +import pdfplumber +import json + + + +def process_main_heading(heading): + return{heading.strip()} + +def process_sub_heading(subheading): + return{subheading.strip()} + +def process_paragraph(h,paragraph): + return{h : paragraph.strip()} + +def process_table(table): + return {"type": "table", "content": table} + + +def detect_structure(text): + paragraphs = text.split('\n\n') + structured_content = [] + + for paragraph in paragraphs: + clean_paragraph = paragraph.strip() + if clean_paragraph: + for element in clean_paragraph.extract_words(): # Each element contains text, font-size, bold, etc. + text = element["text"] + font_size = element["size"] # Access font size + is_bold = "Bold" in element["fontname"] + if len(clean_paragraph.split()) < 5 and is_bold: + headd=clean_paragraph + structured_content.append(process_main_heading(clean_paragraph)) + elif len(clean_paragraph.split())<5: + subhead=clean_paragraph + structured_content.append(process_sub_heading(clean_paragraph)) + + else: + structured_content.append(process_paragraph(headd,clean_paragraph)) + + return structured_content + +def extract_tables(page): + tables = page.extract_tables() + table_list = [] + for table in tables: + table_list.append(process_table(table)) + return table_list + +def main(): + #filepath = input(r"Enter the file path: ") + filepath = r"C:\Users\HP\OneDrive\Desktop\data_preprocessor\data\acetone-acs-l (1).pdf" + + document_structure = [] + + with pdfplumber.open(filepath) as pdf: + for page_num, page in enumerate(pdf.pages): + print(f"Processing page {page_num + 1}:") + + text = page.extract_text() + if text: + structured_text = detect_structure(text) + document_structure.extend(structured_text) + + tables = extract_tables(page) + document_structure.extend(tables) + + # Convert the structure to JSON + json_output = json.dumps(document_structure, indent=4) + + # Save to file or print + with open('output.json', 'w') as json_file: + json_file.write(json_output) + + print("PDF content has been converted to JSON.") + +if __name__ == "__main__": + main() diff --git a/output.json b/output.json new file mode 100644 index 00000000..58a3876f --- /dev/null +++ b/output.json @@ -0,0 +1,311 @@ +[ + { + "type": "paragraph", + "content": "SAFETY DATA SHEET\nCreation Date 28-Apr-2009 Revision Date 13-Oct-2023 Revision Number 9\n1. Identification\nProduct Name Acetone\nCat No. : A9-4; A9-20; A9-200; A11-1; A11-4; A11-20; A11-200; A11S-4; A13-20;\nA13-200; A16F-1GAL; A16P-1GAL; A16P-4; A16S-4; A16S-20; A18-1;\nA18-4; A18-20; A18-20LC; A18-200; A18-200LC; A18-500; A18CU1300;\nA18FB-19; A18FB-50; A18FB-115; A18FB-200; A18P-4; A18POP-19;\nA18POPB-50; A18RB-19; A18RB-50; A18RB-115; A18RB-200;\nA18RS-28; A18RS-50; A18RS-115; A18RS-200; A18S-4; A18SK-4;\nA18SS-19; A18SS-28; A18SS-50; A18SS-115; A18SS-200; A19-1;\nA19-4; A19RS-115; A19RS-200; A40-4; A928-4; A929-1; A929-4;\nA929-4LC; A929RS-19; A929RS-50; A929RS-200; A929SK-4;\nA929SS-28; A929SS-50; A929SS-115; A929SS-200; A946-4; A946-4LC;\nA946FB-200; A946RB-19; A946RB-50; A946RB-115; A946RB-200;\nA949-1; A949-4; A949-4LC; A949CU-50; A949N-119; A949N-219;\nA949POP-19; A949RS-28; A949RS-50; A949RS-115; A949SK-1;\nA949SK-4; A949SS-19; A949SS-28; A949SS-50; A949SS-115;\nA949SS-200; BP2403-1; BP2403-4; BP2403-20; BP2403-RS200;\nBP2404-1; BP2404-4; BP2404-SK1; BP2404-SK4; HC300-1GAL;\nS70091; 22050131; 22050295; XXA9ET200LI; NC2396838\nCAS No 67-64-1\nSynonyms 2-Propanone; Dimethyl ketone; (Certified ACS, HPLC, OPTIMA, Histological,\nSpectranalyzed, NF/FCC/EP, Pesticide, Electronic, GC Resolv, SAFE-COTE)\nRecommended Use Laboratory chemicals.\nUses advised against Food, drug, pesticide or biocidal product use.\nDetails of the supplier of the safety data sheet\nCompany\nFisher Scientific Company\nOne Reagent Lane\nFair Lawn, NJ 07410\nTel: (201) 796-7100\nEmergency Telephone Number\nCHEMTREC\u00d2, Inside the USA: 800-424-9300\nCHEMTREC\u00d2, Outside the USA: 001-703-527-3887\n2. Hazard(s) identification\nClassification\n______________________________________________________________________________________________\nPage 1 / 9" + }, + { + "type": "paragraph", + "content": "Acetone Revision Date 13-Oct-2023\n______________________________________________________________________________________________\nThis chemical is considered hazardous by the 2012 OSHA Hazard Communication Standard (29 CFR 1910.1200)\nFlammable liquids Category 2\nSerious Eye Damage/Eye Irritation Category 2\nSpecific target organ toxicity (single exposure) Category 3\nTarget Organs - Central nervous system (CNS).\nSpecific target organ toxicity - (repeated exposure) Category 2\nLabel Elements\nSignal Word\nDanger\nHazard Statements\nHighly flammable liquid and vapor\nCauses serious eye irritation\nMay cause drowsiness or dizziness\nMay cause damage to organs through prolonged or repeated exposure\nPrecautionary Statements\nPrevention\nWash face, hands and any exposed skin thoroughly after handling\nDo not breathe dust/fume/gas/mist/vapors/spray\nUse only outdoors or in a well-ventilated area\nKeep away from heat/sparks/open flames/hot surfaces. - No smoking\nKeep container tightly closed\nGround/bond container and receiving equipment\nUse explosion-proof electrical/ventilating/lighting equipment\nUse only non-sparking tools\nTake precautionary measures against static discharge\nWear protective gloves/protective clothing/eye protection/face protection\nKeep cool\nResponse\nGet medical attention/advice if you feel unwell\nInhalation\nIF INHALED: Remove victim to fresh air and keep at rest in a position comfortable for breathing\nCall a POISON CENTER or doctor/physician if you feel unwell\nSkin\nIF ON SKIN (or hair): Take off immediately all contaminated clothing. Rinse skin with water/shower\nEyes\nIF IN EYES: Rinse cautiously with water for several minutes. Remove contact lenses, if present and easy to do. Continue rinsing\nIf eye irritation persists: Get medical advice/attention\nFire\nIn case of fire: Use CO2, dry chemical, or foam for extinction\nStorage\nStore in a well-ventilated place. Keep container tightly closed\nStore locked up\nDisposal\n______________________________________________________________________________________________\nPage 2 / 9" + }, + { + "type": "paragraph", + "content": "Acetone Revision Date 13-Oct-2023\n______________________________________________________________________________________________\nDispose of contents/container to an approved waste disposal plant\nHazards not otherwise classified (HNOC)\nRepeated exposure may cause skin dryness or cracking\n3. Composition/Information on Ingredients\nComponent CAS No Weight %\nAcetone 67-64-1 >95\n4. First-aid measures\nGeneral Advice If symptoms persist, call a physician.\nEye Contact Rinse immediately with plenty of water, also under the eyelids, for at least 15 minutes. Get\nmedical attention.\nSkin Contact Wash off immediately with plenty of water for at least 15 minutes. If skin irritation persists,\ncall a physician.\nInhalation Remove to fresh air. If not breathing, give artificial respiration. Get medical attention if\nsymptoms occur.\nIngestion Clean mouth with water and drink afterwards plenty of water.\nMost important symptoms and Difficulty in breathing. Symptoms of overexposure may be headache, dizziness, tiredness,\neffects nausea and vomiting: May cause pulmonary edema\nNotes to Physician Treat symptomatically\n5. Fire-fighting measures\nSuitable Extinguishing Media Water spray, carbon dioxide (CO2), dry chemical, alcohol-resistant foam. Water mist may\nbe used to cool closed containers.\nUnsuitable Extinguishing Media Water may be ineffective\nFlash Point -20 \u00b0C / -4 \u00b0F\nMethod - CC (closed cup)\nAutoignition Temperature 465 \u00b0C / 869 \u00b0F\nExplosion Limits\nUpper 12.8 vol %\nLower 2.5 vol %\nOxidizing Properties Not oxidising\nSensitivity to Mechanical ImpactNo information available\nSensitivity to Static Discharge No information available\nSpecific Hazards Arising from the Chemical\nFlammable. Risk of ignition. Containers may explode when heated. Vapors may form explosive mixtures with air. Vapors may\ntravel to source of ignition and flash back.\nHazardous Combustion Products\nCarbon monoxide (CO). Carbon dioxide (CO2). Formaldehyde. Methanol.\nProtective Equipment and Precautions for Firefighters\n______________________________________________________________________________________________\nPage 3 / 9" + }, + { + "type": "table", + "content": [ + [ + "Component", + "CAS No", + "Weight %" + ], + [ + "Acetone", + "67-64-1", + ">95" + ] + ] + }, + { + "type": "paragraph", + "content": "Acetone Revision Date 13-Oct-2023\n______________________________________________________________________________________________\nAs in any fire, wear self-contained breathing apparatus pressure-demand, MSHA/NIOSH (approved or equivalent) and full\nprotective gear.\nNFPA\nHealth Flammability Instability Physical hazards\n2 3 0 N/A\n6. Accidental release measures\nPersonal Precautions Use personal protective equipment as required. Ensure adequate ventilation. Remove all\nsources of ignition. Take precautionary measures against static discharges.\nEnvironmental Precautions Should not be released into the environment.\nMethods for Containment and CleanSoak up with inert absorbent material. Keep in suitable, closed containers for disposal.\nUp Remove all sources of ignition. Use spark-proof tools and explosion-proof equipment.\n7. Handling and storage\nHandling Do not get in eyes, on skin, or on clothing. Wear personal protective equipment/face\nprotection. Ensure adequate ventilation. Avoid ingestion and inhalation. Keep away from\nopen flames, hot surfaces and sources of ignition. Use only non-sparking tools. To avoid\nignition of vapors by static electricity discharge, all metal parts of the equipment must be\ngrounded. Take precautionary measures against static discharges.\nStorage. Flammables area. Keep containers tightly closed in a dry, cool and well-ventilated place.\nKeep away from heat, sparks and flame. Incompatible Materials. Strong oxidizing agents.\nStrong reducing agents. Strong bases. Peroxides. Halogenated compounds. Alkali metals.\nAmines.\n8. Exposure controls / personal protection\nExposure Guidelines\nComponent ACGIH TLV OSHA PEL NIOSH Mexico OEL (TWA)\nAcetone TWA: 250 ppm (Vacated) TWA: 750 ppm IDLH: 2500 ppm TWA: 500 ppm\nSTEL: 500 ppm (Vacated) TWA: 1800 mg/m3 TWA: 250 ppm STEL: 750 ppm\n(Vacated) STEL: 2400 TWA: 590 mg/m3\nmg/m3\n(Vacated) STEL: 1000 ppm\nTWA: 1000 ppm\nTWA: 2400 mg/m3\nLegend\nACGIH - American Conference of Governmental Industrial Hygienists\nOSHA - Occupational Safety and Health Administration\nNIOSH: NIOSH - National Institute for Occupational Safety and Health\nEngineering Measures Ensure adequate ventilation, especially in confined areas. Ensure that eyewash stations\nand safety showers are close to the workstation location. Use explosion-proof\nelectrical/ventilating/lighting equipment.\nPersonal Protective Equipment\nEye/face Protection Wear appropriate protective eyeglasses or chemical safety goggles as described by\nOSHA's eye and face protection regulations in 29 CFR 1910.133 or European Standard\nEN166.\nSkin and body protection Wear appropriate protective gloves and clothing to prevent skin exposure.\nRespiratory Protection Follow the OSHA respirator regulations found in 29 CFR 1910.134 or European Standard\n______________________________________________________________________________________________\nPage 4 / 9" + }, + { + "type": "table", + "content": [ + [ + "Component", + "ACGIH TLV", + "OSHA PEL", + "NIOSH", + "Mexico OEL (TWA)" + ], + [ + "Acetone", + "TWA: 250 ppm\nSTEL: 500 ppm", + "(Vacated) TWA: 750 ppm\n(Vacated) TWA: 1800 mg/m3\n(Vacated) STEL: 2400\nmg/m3\n(Vacated) STEL: 1000 ppm\nTWA: 1000 ppm\nTWA: 2400 mg/m3", + "IDLH: 2500 ppm\nTWA: 250 ppm\nTWA: 590 mg/m3", + "TWA: 500 ppm\nSTEL: 750 ppm" + ] + ] + }, + { + "type": "paragraph", + "content": "Acetone Revision Date 13-Oct-2023\n______________________________________________________________________________________________\nEN 149. Use a NIOSH/MSHA or European Standard EN 149 approved respirator if\nexposure limits are exceeded or if irritation or other symptoms are experienced.\nRecommended Filter type: low boiling organic solvent. Type AX. Brown. conforming to EN371.\nHygiene Measures Handle in accordance with good industrial hygiene and safety practice.\n9. Physical and chemical properties\nPhysical State Liquid\nAppearance Colorless\nOdor sweet\nOdor Threshold 19.8 ppm\npH 7\nMelting Point/Range -95 \u00b0C / -139 \u00b0F\nBoiling Point/Range 56 \u00b0C / 132.8 \u00b0F\nFlash Point -20 \u00b0C / -4 \u00b0F\nMethod - CC (closed cup)\nEvaporation Rate 5.6 (Butyl Acetate = 1.0)\nFlammability (solid,gas) Not applicable\nFlammability or explosive limits\nUpper 12.8 vol %\nLower 2.5 vol %\nVapor Pressure 247 mbar @ 20 \u00b0C\nVapor Density 2.0\nSpecific Gravity 0.790\nSolubility Soluble in water\nPartition coefficient; n-octanol/water No data available\nAutoignition Temperature 465 \u00b0C / 869 \u00b0F\nDecomposition Temperature > 4\u00b0C\nViscosity 0.32 mPa.s @ 20 \u00b0C\nMolecular Formula C3 H6 O\nMolecular Weight 58.08\nVOC Content(%) 100\nRefractive index 1.358 - 1.359\n10. Stability and reactivity\nReactive Hazard None known, based on information available\nStability Stable under normal conditions.\nConditions to Avoid Heat, flames and sparks. Incompatible products. Keep away from open flames, hot\nsurfaces and sources of ignition.\nIncompatible Materials Strong oxidizing agents, Strong reducing agents, Strong bases, Peroxides, Halogenated\ncompounds, Alkali metals, Amines\nHazardous Decomposition ProductsCarbon monoxide (CO), Carbon dioxide (CO2), Formaldehyde, Methanol\nHazardous Polymerization Hazardous polymerization does not occur.\nHazardous Reactions None under normal processing.\n11. Toxicological information\nAcute Toxicity\nProduct Information\nComponent Information\nComponent LD50 Oral LD50 Dermal LC50 Inhalation\n______________________________________________________________________________________________\nPage 5 / 9" + }, + { + "type": "table", + "content": [ + [ + "Component", + "LD50 Oral", + "LD50 Dermal", + "LC50 Inhalation" + ] + ] + }, + { + "type": "paragraph", + "content": "Acetone Revision Date 13-Oct-2023\n______________________________________________________________________________________________\nAcetone 5800 mg/kg ( Rat ) > 15800 mg/kg (rabbit) 76 mg/l, 4 h, (rat)\n> 7400 mg/kg (rat)\nToxicologically Synergistic Carbon tetrachloride; Chloroform; Trichloroethylene; Bromodichloromethane;\nProducts Dibromochloromethane; N-nitrosodimethylamine; 1,1,2-Trichloroethane; Styrene;\nAcetonitrile, 2,5-Hexanedione; Ethanol; 1,2-Dichlorobenzene\nDelayed and immediate effects as well as chronic effects from short and long-term exposure\nIrritation Irritating to eyes\nSensitization No information available\nCarcinogenicity The table below indicates whether each agency has listed any ingredient as a carcinogen.\nComponent CAS No IARC NTP ACGIH OSHA Mexico\nAcetone 67-64-1 Not listed Not listed Not listed Not listed Not listed\nMutagenic Effects No information available\nReproductive Effects No information available.\nDevelopmental Effects No information available.\nTeratogenicity No information available.\nSTOT - single exposure Central nervous system (CNS)\nSTOT - repeated exposure None known\nAspiration hazard No information available\nSymptoms / effects,both acute and Symptoms of overexposure may be headache, dizziness, tiredness, nausea and vomiting:\ndelayed May cause pulmonary edema\nEndocrine Disruptor Information No information available\nOther Adverse Effects The toxicological properties have not been fully investigated.\n12. Ecological information\nEcotoxicity\n.\nComponent Freshwater Algae Freshwater Fish Microtox Water Flea\nAcetone NOEC = 430 mg/l (algae; 96 Oncorhynchus mykiss: LC50 EC50 = 14500 mg/L/15 min EC50 = 8800 mg/L/48h\nh) = 5540 mg/l 96h EC50 = 12700 mg/L/48h\nAlburnus alburnus: LC50 = EC50 = 12600 mg/L/48h\n11000 mg/l 96h\nLeuciscus idus: LC50 =\n11300 mg/L/48h\nSalmo gairdneri: LC50 =\n6100 mg/L/24h\nPersistence and Degradability Persistence is unlikely based on information available.\nBioaccumulation/ Accumulation No information available.\nMobility Will likely be mobile in the environment due to its volatility.\nComponent log Pow\nAcetone -0.24\n13. Disposal considerations\nWaste Disposal Methods Chemical waste generators must determine whether a discarded chemical is classified as a\nhazardous waste. Chemical waste generators must also consult local, regional, and\nnational hazardous waste regulations to ensure complete and accurate classification.\n______________________________________________________________________________________________\nPage 6 / 9" + }, + { + "type": "table", + "content": [ + [ + "Acetone", + "5800 mg/kg ( Rat )", + "> 15800 mg/kg (rabbit)\n> 7400 mg/kg (rat)", + "76 mg/l, 4 h, (rat)" + ] + ] + }, + { + "type": "table", + "content": [ + [ + "Component", + "CAS No", + "IARC", + "NTP", + "ACGIH", + "OSHA", + "Mexico" + ], + [ + "Acetone", + "67-64-1", + "Not listed", + "Not listed", + "Not listed", + "Not listed", + "Not listed" + ] + ] + }, + { + "type": "table", + "content": [ + [ + "Component", + "Freshwater Algae", + "Freshwater Fish", + "Microtox", + "Water Flea" + ], + [ + "Acetone", + "NOEC = 430 mg/l (algae; 96\nh)", + "Oncorhynchus mykiss: LC50\n= 5540 mg/l 96h\nAlburnus alburnus: LC50 =\n11000 mg/l 96h\nLeuciscus idus: LC50 =\n11300 mg/L/48h\nSalmo gairdneri: LC50 =\n6100 mg/L/24h", + "EC50 = 14500 mg/L/15 min", + "EC50 = 8800 mg/L/48h\nEC50 = 12700 mg/L/48h\nEC50 = 12600 mg/L/48h" + ] + ] + }, + { + "type": "table", + "content": [ + [ + "Component", + "log Pow" + ], + [ + "Acetone", + "-0.24" + ] + ] + }, + { + "type": "paragraph", + "content": "Acetone Revision Date 13-Oct-2023\n______________________________________________________________________________________________\nComponent RCRA - U Series Wastes RCRA - P Series Wastes\nAcetone - 67-64-1 U002 -\n14. Transport information\nDOT\nUN-No UN1090\nProper Shipping Name ACETONE\nHazard Class 3\nPacking Group II\nTDG\nUN-No UN1090\nProper Shipping Name ACETONE\nHazard Class 3\nPacking Group II\nIATA\nUN-No UN1090\nProper Shipping Name ACETONE\nHazard Class 3\nPacking Group II\nIMDG/IMO\nUN-No UN1090\nProper Shipping Name ACETONE\nHazard Class 3\nPacking Group II\n15. Regulatory information\nUnited States of America Inventory\nComponent CAS No TSCA TSCA Inventory notification - TSCA - EPA Regulatory\nActive-Inactive Flags\nAcetone 67-64-1 X ACTIVE -\nLegend:\nTSCA US EPA (TSCA) - Toxic Substances Control Act, (40 CFR Part 710)\nX - Listed\n'-' - Not Listed\nTSCA - Per 40 CFR 751, Regulation of Certain Chemical Not applicable\nSubstances & Mixtures, Under TSCA Section 6(h) (PBT)\nTSCA 12(b) - Notices of Export Not applicable\nInternational Inventories\nCanada (DSL/NDSL), Europe (EINECS/ELINCS/NLP), Philippines (PICCS), Japan (ENCS), Japan (ISHL), Australia (AICS), China (IECSC), Korea\n(KECL).\nComponent CAS No DSL NDSL EINECS PICCS ENCS ISHL AICS IECSC KECL\nAcetone 67-64-1 X - 200-662-2 X X X X X KE-29367\nKECL - NIER number or KE number (http://ncis.nier.go.kr/en/main.do)\nU.S. Federal Regulations\nSARA 313 Not applicable\nSARA 311/312 Hazard Categories See section 2 for more information\nCWA (Clean Water Act) Not applicable\n______________________________________________________________________________________________\nPage 7 / 9" + }, + { + "type": "table", + "content": [ + [ + "Component", + "RCRA - U Series Wastes", + "RCRA - P Series Wastes" + ], + [ + "Acetone - 67-64-1", + "U002", + "-" + ] + ] + }, + { + "type": "table", + "content": [ + [ + "Component", + "CAS No", + "TSCA", + "TSCA Inventory notification -\nActive-Inactive", + "TSCA - EPA Regulatory\nFlags" + ], + [ + "Acetone", + "67-64-1", + "X", + "ACTIVE", + "-" + ] + ] + }, + { + "type": "table", + "content": [ + [ + "Component", + "CAS No", + "DSL", + "NDSL", + "EINECS", + "PICCS", + "ENCS", + "ISHL", + "AICS", + "IECSC", + "KECL" + ], + [ + "Acetone", + "67-64-1", + "X", + "-", + "200-662-2", + "X", + "X", + "X", + "X", + "X", + "KE-29367" + ] + ] + }, + { + "type": "paragraph", + "content": "Acetone Revision Date 13-Oct-2023\n______________________________________________________________________________________________\nClean Air Act Not applicable\nOSHA - Occupational Safety and Not applicable\nHealth Administration\nCERCLA This material, as supplied, contains one or more substances regulated as a hazardous\nsubstance under the Comprehensive Environmental Response Compensation and Liability\nAct (CERCLA) (40 CFR 302)\nComponent Hazardous Substances RQs CERCLA EHS RQs\nAcetone 5000 lb -\nCalifornia Proposition 65 This product does not contain any Proposition 65 chemicals.\nU.S. State Right-to-Know\nRegulations\nComponent Massachusetts New Jersey Pennsylvania Illinois Rhode Island\nAcetone X X X - X\nU.S. Department of Transportation\nReportable Quantity (RQ): Y\nDOT Marine Pollutant N\nDOT Severe Marine Pollutant N\nU.S. Department of Homeland This product does not contain any DHS chemicals.\nSecurity\nOther International Regulations\nMexico - Grade Serious risk, Grade 3\nAuthorisation/Restrictions according to EU REACH\nComponent CAS No REACH (1907/2006) - REACH (1907/2006) - REACH Regulation (EC\nAnnex XIV - Substances Annex XVII - Restrictions 1907/2006) article 59 -\nSubject to Authorization on Certain Dangerous Candidate List of\nSubstances Substances of Very High\nConcern (SVHC)\nAcetone 67-64-1 - Use restricted. See item -\n75.\n(see link for restriction\ndetails)\nREACH links\nhttps://echa.europa.eu/substances-restricted-under-reach\nSafety, health and environmental regulations/legislation specific for the substance or mixture\nComponent CAS No OECD HPV Persistent Organic Ozone Depletion Restriction of\nPollutant Potential Hazardous\nSubstances (RoHS)\nAcetone 67-64-1 Listed Not applicable Not applicable Not applicable\nContains component(s) that meet a 'definition' of per & poly fluoroalkyl substance (PFAS)?\nNot applicable\n______________________________________________________________________________________________\nPage 8 / 9" + }, + { + "type": "table", + "content": [ + [ + "Component", + "Hazardous Substances RQs", + "CERCLA EHS RQs" + ], + [ + "Acetone", + "5000 lb", + "-" + ] + ] + }, + { + "type": "table", + "content": [ + [ + "Component", + "Massachusetts", + "New Jersey", + "Pennsylvania", + "Illinois", + "Rhode Island" + ], + [ + "Acetone", + "X", + "X", + "X", + "-", + "X" + ] + ] + }, + { + "type": "table", + "content": [ + [ + "Component", + "CAS No", + "REACH (1907/2006) -\nAnnex XIV - Substances\nSubject to Authorization", + "REACH (1907/2006) -\nAnnex XVII - Restrictions\non Certain Dangerous\nSubstances", + "REACH Regulation (EC\n1907/2006) article 59 -\nCandidate List of\nSubstances of Very High\nConcern (SVHC)" + ], + [ + "Acetone", + "67-64-1", + "-", + "Use restricted. See item\n75.\n(see link for restriction\ndetails)", + "-" + ] + ] + }, + { + "type": "table", + "content": [ + [ + "Component", + "CAS No", + "OECD HPV", + "Persistent Organic\nPollutant", + "Ozone Depletion\nPotential", + "Restriction of\nHazardous\nSubstances (RoHS)" + ], + [ + "Acetone", + "67-64-1", + "Listed", + "Not applicable", + "Not applicable", + "Not applicable" + ] + ] + }, + { + "type": "paragraph", + "content": "Acetone Revision Date 13-Oct-2023\n______________________________________________________________________________________________\nOther International Regulations\nComponent CAS No Seveso III Directive Seveso III Directive Rotterdam Basel Convention\n(2012/18/EC) - (2012/18/EC) - Convention (PIC) (Hazardous Waste)\nQualifying QuantitiesQualifying Quantities\nfor Major Accident for Safety Report\nNotification Requirements\nAcetone 67-64-1 Not applicable Not applicable Not applicable Annex I - Y42\n16. Other information\nPrepared By Regulatory Affairs\nThermo Fisher Scientific\nEmail: EMSDS.RA@thermofisher.com\nCreation Date 28-Apr-2009\nRevision Date 13-Oct-2023\nPrint Date 13-Oct-2023\nRevision Summary This document has been updated to comply with the US OSHA HazCom 2012 Standard\nreplacing the current legislation under 29 CFR 1910.1200 to align with the Globally\nHarmonized System of Classification and Labeling of Chemicals (GHS).\nDisclaimer\nThe information provided in this Safety Data Sheet is correct to the best of our knowledge, information and belief at the\ndate of its publication. The information given is designed only as a guidance for safe handling, use, processing, storage,\ntransportation, disposal and release and is not to be considered a warranty or quality specification. The information\nrelates only to the specific material designated and may not be valid for such material used in combination with any other\nmaterials or in any process, unless specified in the text\nEnd of SDS\n______________________________________________________________________________________________\nPage 9 / 9" + }, + { + "type": "table", + "content": [ + [ + "Component", + "CAS No", + "Seveso III Directive\n(2012/18/EC) -\nQualifying Quantities\nfor Major Accident\nNotification", + "Seveso III Directive\n(2012/18/EC) -\nQualifying Quantities\nfor Safety Report\nRequirements", + "Rotterdam\nConvention (PIC)", + "Basel Convention\n(Hazardous Waste)" + ], + [ + "Acetone", + "67-64-1", + "Not applicable", + "Not applicable", + "Not applicable", + "Annex I - Y42" + ] + ] + } +] \ No newline at end of file From 4c0e1c2de35652436d778188b6f81e6ce68b5a2c Mon Sep 17 00:00:00 2001 From: Janice Date: Fri, 4 Oct 2024 15:56:14 +0530 Subject: [PATCH 4/7] project documentation added --- Project_documentation.pdf | Bin 0 -> 41698 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 Project_documentation.pdf diff --git a/Project_documentation.pdf b/Project_documentation.pdf new file mode 100644 index 0000000000000000000000000000000000000000..de1166a35d4831e76043d12a49f18353c823c0fd GIT binary patch literal 41698 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

P0(m4siD;=hUv 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 literal 0 HcmV?d00001 From 7b2e0682d6dad70d36935068909aafc8cdbc03a5 Mon Sep 17 00:00:00 2001 From: Janice Date: Tue, 8 Oct 2024 01:34:22 +0530 Subject: [PATCH 5/7] regex added to remove headers, dates etc --- data/blah.py | 0 data/read4.py | 2 -- data/read7.py | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 82 insertions(+), 2 deletions(-) create mode 100644 data/blah.py create mode 100644 data/read7.py diff --git a/data/blah.py b/data/blah.py new file mode 100644 index 00000000..e69de29b diff --git a/data/read4.py b/data/read4.py index 22e18864..60ecee4a 100644 --- a/data/read4.py +++ b/data/read4.py @@ -1,8 +1,6 @@ import pdfplumber import json - - def process_main_heading(heading): main_head=heading.strip() return{heading.strip()} diff --git a/data/read7.py b/data/read7.py new file mode 100644 index 00000000..a09594ef --- /dev/null +++ b/data/read7.py @@ -0,0 +1,82 @@ +import pdfplumber +import json +import re + +def process_main_heading(heading): + main_head=heading.strip() + return{heading.strip()} + +#def process_sub_heading1(heading): + # sub_head=heading.strip() + # return{heading.strip()} + +#def process_paragraph(h,paragraph): + # return{h : paragraph.strip()} + +def process_paragraph(paragraph): + return {"type": "paragraph", "content": paragraph.strip()} + +def process_heading(heading): + return {"type": "heading", "content": heading.strip()} + +def process_table(table): + return {"type": "table", "content": table} + +def detect_structure(text): + paragraphs=text.split('\n\n') #to split the paras ig + structured_content=[] #to store the structred content ...empty list is initialised + + sentences_per_paragraph = [paragraph.split('.') for paragraph in paragraphs] + cleaned_sentences_per_paragraph = [[sentence.strip() for sentence in sentences if sentence.strip()] for sentences in sentences_per_paragraph] + + for i, sentences in enumerate(cleaned_sentences_per_paragraph): + #print(f"Paragraph {i + 1}:") + for sentence in sentences: + match = re.search("ThermoFisher",sentence) or re.search("SCIENTIFIC",sentence) or re.search("SAFETY DATA SHEET",sentence) or re.search("Creation Date\s+\d+-[a-zA-Z]{3}-\d+\s+Revision Date\s+\d+-[a-zA-Z]{3}-\d+\s+Revision Number\s+\d",sentence) + print(f" {sentence}.") + +''' for paragraph in paragraphs: + clean_paragraph = paragraph.strip() #to remove leading or trailing whitespaces + + if clean_paragraph: + + if len(clean_paragraph.split()) < 5: # include logic for headers of different font sizes + headd=clean_paragraph + structured_content.append(process_main_heading(clean_paragraph)) + + else: + structured_content.append(process_paragraph(headd,clean_paragraph)) + + return structured_content''' + + +def extract_tables(page): + tables = page.extract_tables() + table_list = [] + for table in tables: + table_list.append(process_table(table)) + return table_list + + +def main(): + #file_path=input(r"Enter the file path: ") + file_path = r"C:\Users\HP\OneDrive\Desktop\data_preprocessor\data\acetone-acs-l (1).pdf" + + document_structure=[] #empty list to storee doc structure?? + + with pdfplumber.open(file_path) as pdf: + + for page_num,page in enumerate(pdf.pages): + print(f"Processing page {page_num + 1}:") + + text=page.extract_text() + + + + json_output = json.dumps(document_structure, indent=4) + with open('output.json', 'w') as json_file: + json_file.write(json_output) + print("PDF content has been converted to JSON.") + +if __name__ == "__main__": + main() \ No newline at end of file From 6fc8e1a4655ef56ab4d9ff6f742d7d948c4132bf Mon Sep 17 00:00:00 2001 From: Janice Date: Tue, 8 Oct 2024 07:22:17 +0530 Subject: [PATCH 6/7] requirements.txt added --- data/read8.py | 44 ++++++++++++++++++++++++++++++++++++++++++++ requirements.txt | Bin 0 -> 898 bytes 2 files changed, 44 insertions(+) create mode 100644 data/read8.py create mode 100644 requirements.txt diff --git a/data/read8.py b/data/read8.py new file mode 100644 index 00000000..2008eff0 --- /dev/null +++ b/data/read8.py @@ -0,0 +1,44 @@ +import pdfplumber + +def process_pdf_with_font_details(pdf_path): + with pdfplumber.open(pdf_path) as pdf: + for page in pdf.pages: + # Extract characters with their properties + chars = page.chars + + # Initialize a variable to hold the current word + current_word = "" + current_font_name = None + current_font_size = None + current_fill = None + + for char in chars: + text = char['text'] + font_size = char['size'] + font_name = char['fontname'] + fill_color = char.get('fill') # Get fill color + + # Check for spaces to identify word boundaries + if text.isspace(): + if current_word: + # Print the accumulated word with font details + print(f"'{current_word}' (Font size: {current_font_size}, Font style: {current_font_name}, Font color: {current_fill})") + current_word = "" + current_font_name = None + current_font_size = None + current_fill = None + else: + current_word += text + # Store the font details of the current character + current_font_name = font_name + current_font_size = font_size + current_fill = fill_color # Store the fill color + + # Print the last word if it exists + if current_word: + print(f"'{current_word}' (Font size: {current_font_size}, Font style: {current_font_name}, Font color: {current_fill})") + +# Example usage +pdf_path = r"C:\Users\HP\OneDrive\Desktop\data_preprocessor\data\acetone-acs-l (1).pdf" + +process_pdf_with_font_details(pdf_path) diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000000000000000000000000000000000000..69514bdd204fb4364a62dc0660939663b71a0fb4 GIT binary patch literal 898 zcmZva-A=+#5QO*I#7BWZLBtDRz{D$`018O8f0m-?!>ixywiXi8oTfc9XJ&Ty{Cuaj zwZ>Y@Y{$CiNo>NJ+SqPbGybma%2M#2A#7^5{tj$!D^xaUwXQJ-oA^4%4~~zlv@C>bl zXXy!Rly+$5UdQ@xCea7EMkO^WIZtIDuB9Hv)S{Qln|iheM>+T1mRBUxROKc_cWmgj zP6w8Gj+lpTlkQcs`8)vtqZ7({hWWgCa g7xzhXjcTQ;3AC*L)Q{A!Ze_Nn0x^c0vG8vE0vKg~`Tzg` literal 0 HcmV?d00001 From d53fafcf3dc06a7ee8da90517a551b14bd88eeb1 Mon Sep 17 00:00:00 2001 From: Janice Date: Tue, 8 Oct 2024 07:37:40 +0530 Subject: [PATCH 7/7] read.py and read3tables.py deleted --- data/read.py | 21 --------------------- data/read3tables.py | 15 --------------- 2 files changed, 36 deletions(-) delete mode 100644 data/read.py delete mode 100644 data/read3tables.py diff --git a/data/read.py b/data/read.py deleted file mode 100644 index 8e2296f4..00000000 --- a/data/read.py +++ /dev/null @@ -1,21 +0,0 @@ -#reading contents of pdf using pypdf - -from pypdf import PdfReader - -reader = PdfReader("C:/Users/HP/OneDrive/Desktop/data_preprocessor/data/acetone-acs-l (1).pdf") - -# Print the number of pages in the PDF -print(f"There are {len(reader.pages)} Pages") - -# Get the first page (index 0) -page = reader.pages[0] -# Use extract_text() to get the text of the page -print(page.extract_text()) - -# Go through every page and get the text -for i in range(len(reader.pages)): - page = reader.pages[i] - print(page.extract_text()) - - - diff --git a/data/read3tables.py b/data/read3tables.py deleted file mode 100644 index 2c54a140..00000000 --- a/data/read3tables.py +++ /dev/null @@ -1,15 +0,0 @@ -import pdfplumber -import json - -file_path = r"C:\Users\HP\OneDrive\Desktop\data_preprocessor\data\acetone-acs-l (1).pdf" - - - -with pdfplumber.open(file_path) as pdf: - - for page_num, page in enumerate(pdf.pages): - tables = page.extract_tables() # Use extract_tables() instead of extract_table() - print(f"Tables from page {page_num + 1}:") - for table in tables: - for row in table: - print(row) \ No newline at end of file